XLEdoo 2024-11-12 17:16 采纳率: 33.3%
浏览 9
问题最晚将于11月20日00:00点结题

C++行情软件的tick数据如何高效的合成K线

#写一个期货交易软件,其中涉及到行情时间,比如1分钟(还有3分钟 5分钟10分钟15 30 60 120)每天早上9点开盘,09:00-10:15  10:30-11:30 13:30-15:00 21:00-23:00 有很多交易的品种,而且交易的时间段都有所不同,我已经把不同的交易时间段品种进行了分类。
我在一个QTimer里每1秒运行一次函数,通过接受到的tick数据进行K线计算并推送bar的信息。

现在的方案是:
我用map预先把每个周期所对应的时间点手动添加进去,这样的好处是避免了调用时计算时间点的开销,弊端是看起来有点傻,类似下面:

// 定义一个时间段
#define F_1M_21002259 "2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,2110,2111,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,2154,2155,2156,2157,2158,2159,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209,2210,2211,2212,2213,2214,2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228,2229,2230,2231,2232,2233,2234,2235,2236,2237,2238,2239,2240,2241,2242,2243,2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,2259"

// 把时间段合并成某个品种的交易时间点
#define FN2300_M1  _isspace(F_1M_21002259 FSEP F_1M_09001459)

// 加入到map
static std::map<std::string, shine::string>  g_static_session_mapping = {
    {"FN2300_M1", FN2300_M1},
    {"FN0100_M1", FN0100_M1},
    {"FN0230_M1", FN0230_M1},
    {"FD0900_M1", FD0900_M1},
    {"FD1515_M1", FD1515_M1},
    {"SD0930_M1", SD0930_M1},
    //-------------------------
    {"FN2300_M3", FN2300_M3},
    {"FN0100_M3", FN0100_M3},
    {"FN0230_M3", FN0230_M3},
    {"FD0900_M3", FD0900_M3},
    {"FD1515_M3", FD1515_M3},
    {"SD0930_M3", SD0930_M3},

每个元素代表一个1分钟的时间点 还有3分钟 5分钟各个周期都需要单独写出来。
请问有没有更高效的方案?

这里需要说明一下,1分钟 3分钟 5分钟 10 15这些小周期比较好处理,其中还有1小时 2小时这样的周期比较麻烦,因为期货的交易时间段在10:15-10:30是暂停交易的,有的交易软件的1小时周期并不是点对点的,比如文华财经的1小时图就是 10:00-11:15 是一根K线,11:15-14:1514:15-15:00 是一根K线,而2小时的K线又有单独对应2小时的时间点,不规律的。这里看有没有什么办法处理。

共773个合约,每个合约每秒钟2个tick数据,一个小时有 60260*773=5565600个tick(实际的量比这个小,因为非主力合约交易不活跃),这个数据量还是非常恐怖的。

感谢大家的积极回答,已经收到了一些方案,还有一些细节需要处理:

//=============================================================================================
// 这里的时间点定义应该分两种情况:
// 1、判断是否为交易时间时,只需要判断tick的时间是否处于交易时段内即可,需要包含起始时间和结束时间在内
//    仅需要用到1分钟的级别即可。
// 2、Bar的触发因为是在每一个周期的最后一个tick时进行,所以需要计算出每个周期对应的最后一个时间,也就是
//    结束时间,而且因为10:15-10:30休市的情况,10分钟,30分钟,1小时,2小时这种周期就不好通过函数计算
//    目前的解决方案就是通过“硬编码”来定义每个特殊周期的触发时间点来单独控制。
//    例如:10分钟周期到10:10分这里就变成了10:10-10:35,10:35-10:45,10:45-10:55,......11:25-13:35
//    其他特殊周期也是如此处理的,希望能找到更好的解决方案。
//=============================================================================================
std::map<std::string, std::vector<TradingSession>> tradingSessions = {
    {"FN2300", { {9, 0, 10, 15}, {10, 30, 11, 30}, {13, 30, 15, 0}, {21, 0, 23, 0} }},
    {"FN0100", { {9, 0, 10, 15}, {10, 30, 11, 30}, {13, 30, 15, 0}, {21, 0, 1, 0} }},
    {"FN0230", { {9, 0, 10, 15}, {10, 30, 11, 30}, {13, 30, 15, 0}, {21, 0, 2, 30} }},
    {"FD0900", { {9, 0, 10, 15}, {10, 30, 11, 30}, {13, 30, 15, 0} }},
    {"FD1515", { {9, 0, 10, 15}, {10, 30, 11, 30}, {13, 30, 15, 15} }},
    {"SD0930", { {9, 30, 11, 30}, {13, 0, 15, 0} }}
};

std::vector<std::string> generateKLineTimes(const TradingSession& session, TrPeriod period) {
    std::vector<std::string> times;
 
    int period_minutes = static_cast<int>(period);
    int hour = session.startHour;
    int minute = session.startMinute;
 
    while (hour < session.endHour || (hour == session.endHour && minute < session.endMinute)) {
        std::ostringstream oss;
        oss << (hour < 10 ? "0" : "") << hour << (minute < 10 ? "0" : "") << minute;
        times.push_back(oss.str());
        qDebug() << oss.str().c_str();
        minute += period_minutes;
        if (minute >= 60) {
            hour += minute / 60;
            minute %= 60;
        }
    }
    return times;
}

std::vector<std::string> getKLineTimes(const std::string& product, TrPeriod period) {
    std::vector<std::string> allTimes;
    if (tradingSessions.find(product) != tradingSessions.end()) {
        for (const auto& session : tradingSessions[product]) {
            auto times = generateKLineTimes(session, period);
            allTimes.insert(allTimes.end(), times.begin(), times.end());
        }
    }
    return allTimes;
}

// 这里已经可以得到时间点了,问题在于一些特殊的周期该怎么处理才好?需要的是每个周期Bar结束时触发的那个时间点。谢谢大家!
  • 写回答

19条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-11-12 20:05
    关注

    以下回复引自免费微信小程序:皆我百晓生。 如问题解决,还请采纳。如仍有疑问,请回复留言或私信博主,以便获得更精准的帮助。

    在C++中构建一个能够高效合成K线图的时间序列分析工具需要考虑多个方面:数据结构、算法和性能优化等。以下是一个简单的实现思路:

    1. 数据存储

      • 首先,你需要存储每条时间序列的数据,例如价格或成交量。
      • 这可能涉及使用文件系统或其他方式来存储数据。
    2. 时间序列处理

      • 使用C++的标准库或第三方库来处理时间和数据格式。例如,可以使用CHRONO库来处理时区问题。
      • 可以使用窗口函数来处理窗口数据集,例如窗口函数会将连续数据集分为若干个较小的子集,以便于进行合并操作。
    3. 时间序列分析

      • 对于每个时间序列,你可以计算其移动平均值、加权平均值等指标,这些指标可以帮助你了解时间序列的趋势变化。
      • 如果你想比较不同时间段内的趋势,那么你可以创建一个新的数组,用于记录所有时间段内的趋势。
    4. 图形生成

      • 创建图表,展示时间序列中的各个时间段内的价格走势。
    5. 性能优化

      • 使用缓存技术来减少对内存的访问,特别是对于频繁调用的时间序列操作。
      • 考虑使用分布式架构来提高系统的并发能力。
    6. 兼容性

      • 确保你的程序能够在各种平台上运行,包括WINDOWS、MAC OS X和LINUX等。
    7. 用户界面

      • 设计一个友好的用户界面,使用户能够直观地查看和操作时间序列。
    8. 测试与验证

      • 在实际开发环境中进行单元测试和集成测试,确保程序的正确性和稳定性。

    通过上述步骤,你应该能建立一个能够高效合成K线图的时间序列分析工具。请注意,这只是一个基本的框架,具体的实现细节可能需要根据具体需求进行调整。

    评论

报告相同问题?

问题事件

  • 赞助了问题酬金15元 11月13日
  • 修改了问题 11月13日
  • 修改了问题 11月12日
  • 赞助了问题酬金15元 11月12日
  • 展开全部

悬赏问题

  • ¥15 有两个非常“自以为是”烦人的问题急期待大家解决!
  • ¥30 STM32 INMP441无法读取数据
  • ¥15 R语言绘制密度图,一个密度曲线内fill不同颜色如何实现
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥15 pyqt信号槽连接写法
  • ¥500 把面具戴到人脸上,请大家贡献智慧,别用大模型回答,大模型的答案没啥用
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急