#写一个期货交易软件,其中涉及到行情时间,比如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:15,14: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结束时触发的那个时间点。谢谢大家!