1

我有以下问题。我有一组用于交易品种的 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值;
  • 取 Volume 值的总和

我想知道是否可以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);

有可能做这样的事情吗?还是有更好的解决方案?

4

1 回答 1

1

有趣的问题。看起来 Sample 概念显然可以使用自定义类型进行扩展,但我没有立即看到机制。一方面,如果您可以替换OHLCV witf 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)

于 2021-06-27T18:42:29.210 回答