如何为金融 ohlcv 数据创建自定义提升累加器
how to create custom boost accumulator for financial ohlcv data
我遇到了以下问题。我有一组 OHLCV(开盘价、最高价、最低价、收盘价、交易量)数据,具有以下结构:
struct OHLCV {
double Open{0.0};
double High{0.0};
double Low{0.0};
double Close{0.0};
double Volume{0.0};
};
每个数据涵盖 1 小时的时间范围。我需要取很多,然后计算累积的 OHLCV。例如,如果需要从 24 小时的 OHLCV 计算一天的 OHLCV。
为了从其中的一组中创建累积的 OHLCV,我需要:
- 取第一个Open值;
- 取最后一个收盘价;
- 取最高的High值;
- 取最低Low值;
- 取交易量值的总和
我想知道是否可以使用 boost::accumulator
来达到这个目的,这样我就可以编写如下代码:
using namespace boost::accumulators;
std::vector<OHLCV> rawData;
// creating CustomFeatures and OHLCVCumulative...
accumulator_set<OHLCV, CustomFeatures> ohlcvAcc;
for (const auto& ohlcv : rawData) {
ohlcvAcc(ohlcv);
}
auto cumulativeOHLCV = OHLCVCumulative(ohlcvAcc);
这样可以吗?或者有更好的解决办法?
有趣的问题。示例概念显然可以使用自定义类型进行扩展,但我没有立即看到机制。一方面,如果您可以将 OHLCV
替换为 valarray<double>
,您可能就可以自由回家了:
enum { Open, High, Low, Close, Volume };
using OHLCV = std::valarray<double>;
例如:
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <valarray>
#include <fmt/ranges.h>
namespace ba = boost::accumulators;
namespace bat = ba::tag;
enum { Open, High, Low, Close, Volume };
using OHLCV = std::valarray<double>;
// creating CustomFeatures and OHLCVCumulative...
using CustomFeatures = ba::stats<bat::sum>;
int main()
{
ba::accumulator_set<OHLCV, CustomFeatures> ohlcvAcc(
ba::sample = OHLCV{0, 0, 0, 0, 0});
std::vector<OHLCV> rawData{
{1, 2, 3, 4, 5}, {2, 3, 4, 5, 6}, {3, 4, 5, 6, 7},
{4, 5, 6, 7, 8}, {5, 6, 7, 8, 9}, {6, 7, 8, 9, 10},
};
for (auto const& sample : rawData) {
ohlcvAcc(sample);
}
auto sum = ba::sum(ohlcvAcc);
fmt::print("sum: {}, Close: {}\n", sum, sum[Close]);
}
版画
sum: {21, 27, 33, 39, 45}, Close: 39
(使用 libfmt 7.1.3、boost 1.76、GCC 11 -std=c++2a)
我遇到了以下问题。我有一组 OHLCV(开盘价、最高价、最低价、收盘价、交易量)数据,具有以下结构:
struct OHLCV {
double Open{0.0};
double High{0.0};
double Low{0.0};
double Close{0.0};
double Volume{0.0};
};
每个数据涵盖 1 小时的时间范围。我需要取很多,然后计算累积的 OHLCV。例如,如果需要从 24 小时的 OHLCV 计算一天的 OHLCV。
为了从其中的一组中创建累积的 OHLCV,我需要:
- 取第一个Open值;
- 取最后一个收盘价;
- 取最高的High值;
- 取最低Low值;
- 取交易量值的总和
我想知道是否可以使用 boost::accumulator
来达到这个目的,这样我就可以编写如下代码:
using namespace boost::accumulators;
std::vector<OHLCV> rawData;
// creating CustomFeatures and OHLCVCumulative...
accumulator_set<OHLCV, CustomFeatures> ohlcvAcc;
for (const auto& ohlcv : rawData) {
ohlcvAcc(ohlcv);
}
auto cumulativeOHLCV = OHLCVCumulative(ohlcvAcc);
这样可以吗?或者有更好的解决办法?
有趣的问题。示例概念显然可以使用自定义类型进行扩展,但我没有立即看到机制。一方面,如果您可以将 OHLCV
替换为 valarray<double>
,您可能就可以自由回家了:
enum { Open, High, Low, Close, Volume };
using OHLCV = std::valarray<double>;
例如:
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <valarray>
#include <fmt/ranges.h>
namespace ba = boost::accumulators;
namespace bat = ba::tag;
enum { Open, High, Low, Close, Volume };
using OHLCV = std::valarray<double>;
// creating CustomFeatures and OHLCVCumulative...
using CustomFeatures = ba::stats<bat::sum>;
int main()
{
ba::accumulator_set<OHLCV, CustomFeatures> ohlcvAcc(
ba::sample = OHLCV{0, 0, 0, 0, 0});
std::vector<OHLCV> rawData{
{1, 2, 3, 4, 5}, {2, 3, 4, 5, 6}, {3, 4, 5, 6, 7},
{4, 5, 6, 7, 8}, {5, 6, 7, 8, 9}, {6, 7, 8, 9, 10},
};
for (auto const& sample : rawData) {
ohlcvAcc(sample);
}
auto sum = ba::sum(ohlcvAcc);
fmt::print("sum: {}, Close: {}\n", sum, sum[Close]);
}
版画
sum: {21, 27, 33, 39, 45}, Close: 39
(使用 libfmt 7.1.3、boost 1.76、GCC 11 -std=c++2a)