k线生成器
#ifndef BAR_GENERATOR_H
#define BAR_GENERATOR_H
#include <algorithm>
#include <chrono>
#include <cstdint>
#include <functional>
#include <vector>
/**
* @brief K线数据结构
*/
struct BarData {
int64_t timestamp; ///< K线时间戳(毫秒)
double open;
double high;
double low;
double close;
double volume;
double turnover;
};
/**
* @brief K线周期类型
*/
enum class BarType {
MINUTE_1 = 1, ///< 1分钟K线
MINUTE_5 = 5, ///< 5分钟K线
MINUTE_15 = 15, ///< 15分钟K线
MINUTE_30 = 30, ///< 30分钟K线
HOUR_1 = 60, ///< 1小时K线
DAY = 1440 ///< 日K线
};
/**
* @brief 高性能K线生成器
*
* 该类用于接收市场tick数据并生成相应周期的K线数据。
*/
class BarGenerator {
public:
/**
* @brief 构造函数
* @param type K线周期类型
* @param callback K线生成回调函数
*/
BarGenerator(BarType type,
std::function<void(const BarData&)> callback) noexcept
: type_(type), callback_(std::move(callback)) {}
/**
* @brief 更新最新的tick数据
* @param timestamp 时间戳(毫秒)
* @param price 最新成交价格
* @param volume 成交量
* @param turnover 成交额
*/
void update(int64_t timestamp, double price, double volume,
double turnover) noexcept {
// 计算当前tick应该属于哪个K线周期
int64_t bar_start_time = calculateBarStartTime(timestamp);
// 如果是新的K线周期
if (!has_current_bar_ || bar_start_time > current_bar_start_time_) {
// 如果存在之前的K线,则完成它
if (has_current_bar_) {
finishCurrentBar();
}
// 创建新的K线
createNewBar(bar_start_time);
}
// 更新当前K线数据
updateCurrentBar(price, volume, turnover);
}
/**
* @brief 强制完成当前K线
*/
void finishCurrentBar() noexcept {
if (has_current_bar_) {
// 调用回调函数,通知K线已完成
callback_(current_bar_);
has_current_bar_ = false;
}
}
/**
* @brief 获取当前正在构建的K线
* @return 当前K线数据的指针,如果不存在则返回nullptr
*/
const BarData* getCurrentBar() const noexcept {
if (has_current_bar_) {
return ¤t_bar_;
}
return nullptr;
}
/**
* @brief 获取K线周期类型
* @return K线周期类型
*/
BarType getType() const noexcept { return type_; }
private:
/**
* @brief 根据时间戳计算K线开始时间
* @param timestamp 时间戳(毫秒)
* @return K线开始时间戳(毫秒)
*/
int64_t calculateBarStartTime(int64_t timestamp) const noexcept {
// 将毫秒时间戳转换为分钟数
int64_t minutes = timestamp / 60000;
// 根据K线类型计算开始时间
int64_t bar_minutes = 0;
switch (type_) {
case BarType::MINUTE_1:
bar_minutes = minutes;
break;
case BarType::MINUTE_5:
bar_minutes = (minutes / 5) * 5;
break;
case BarType::MINUTE_15:
bar_minutes = (minutes / 15) * 15;
break;
case BarType::MINUTE_30:
bar_minutes = (minutes / 30) * 30;
break;
case BarType::HOUR_1:
bar_minutes = (minutes / 60) * 60;
break;
case BarType::DAY:
bar_minutes = (minutes / 1440) * 1440;
break;
}
// 转换回毫秒时间戳
return bar_minutes * 60000;
}
/**
* @brief 创建新的K线
* @param timestamp 时间戳(毫秒)
*/
void createNewBar(int64_t timestamp) noexcept {
current_bar_start_time_ = timestamp;
current_bar_.timestamp = timestamp;
// 其他字段将在updateCurrentBar中更新
has_current_bar_ = true;
}
/**
* @brief 更新当前K线数据
* @param price 最新成交价格
* @param volume 成交量
* @param turnover 成交额
*/
void updateCurrentBar(double price, double volume, double turnover) noexcept {
if (volume == 0 && turnover == 0) {
return; // 没有实际成交,不更新
}
if (current_bar_.volume == 0) {
// 第一笔成交,初始化OHLC
current_bar_.open = price;
current_bar_.high = price;
current_bar_.low = price;
current_bar_.close = price;
} else {
// 更新最高价和最低价
current_bar_.high = std::max(current_bar_.high, price);
current_bar_.low = std::min(current_bar_.low, price);
current_bar_.close = price;
}
// 累加成交量和成交额
current_bar_.volume += volume;
current_bar_.turnover += turnover;
}
private:
BarType type_; ///< K线周期类型
std::function<void(const BarData&)> callback_; ///< K线生成回调函数
BarData current_bar_{}; ///< 当前正在构建的K线
int64_t current_bar_start_time_ = 0; ///< 当前K线开始时间
bool has_current_bar_ = false; ///< 是否存在正在构建的K线
};
#endif // BAR_GENERATOR_H