Line data Source code
1 : /**
2 : * @file market_data.hpp
3 : * @brief 行情数据结构定义
4 : *
5 : * 定义内部使用的行情数据 POD 结构体,与外部数据源(如 CTP)解耦。
6 : * 所有外部行情数据都应转换为此格式后再进入系统。
7 : */
8 :
9 : #pragma once
10 :
11 : #include <cstdint>
12 : #include <cstring>
13 : #include <string>
14 :
15 : namespace fix40 {
16 :
17 : /**
18 : * @brief 合约代码最大长度
19 : */
20 : constexpr size_t INSTRUMENT_ID_LEN = 32;
21 :
22 : /**
23 : * @brief 交易所代码最大长度
24 : */
25 : constexpr size_t EXCHANGE_ID_LEN = 16;
26 :
27 : /**
28 : * @brief 日期字符串长度 (YYYYMMDD)
29 : */
30 : constexpr size_t DATE_LEN = 9;
31 :
32 : /**
33 : * @brief 时间字符串长度 (HH:MM:SS)
34 : */
35 : constexpr size_t TIME_LEN = 9;
36 :
37 : /**
38 : * @struct MarketData
39 : * @brief 行情数据结构体
40 : *
41 : * 设计原则:
42 : * - Trivially copyable 类型,可安全地在无锁队列中传递
43 : * - 使用固定长度字符数组,避免动态内存分配
44 : * - 字段命名清晰,与业务含义对应
45 : * - 与外部数据源(CTP 等)解耦
46 : *
47 : * @par 价格精度
48 : * 所有价格字段使用 double 类型,精度由具体合约决定。
49 : * 无效价格使用 0.0 或 DBL_MAX 表示。
50 : *
51 : * @par 线程安全
52 : * 结构体本身是值类型,可安全复制。
53 : * 在多线程环境中通过无锁队列传递。
54 : */
55 : struct MarketData {
56 : // =========================================================================
57 : // 合约标识
58 : // =========================================================================
59 :
60 : char instrumentID[INSTRUMENT_ID_LEN]; ///< 合约代码
61 : char exchangeID[EXCHANGE_ID_LEN]; ///< 交易所代码
62 : char tradingDay[DATE_LEN]; ///< 交易日 (YYYYMMDD)
63 : char updateTime[TIME_LEN]; ///< 更新时间 (HH:MM:SS)
64 : int32_t updateMillisec; ///< 更新毫秒数
65 :
66 : // =========================================================================
67 : // 价格信息
68 : // =========================================================================
69 :
70 : double lastPrice; ///< 最新价
71 : double preSettlementPrice; ///< 昨结算价
72 : double preClosePrice; ///< 昨收盘价
73 : double openPrice; ///< 开盘价
74 : double highestPrice; ///< 最高价
75 : double lowestPrice; ///< 最低价
76 : double closePrice; ///< 收盘价
77 : double settlementPrice; ///< 结算价
78 : double upperLimitPrice; ///< 涨停价
79 : double lowerLimitPrice; ///< 跌停价
80 : double averagePrice; ///< 均价
81 :
82 : // =========================================================================
83 : // 成交信息
84 : // =========================================================================
85 :
86 : int64_t volume; ///< 成交量
87 : double turnover; ///< 成交额
88 : double openInterest; ///< 持仓量
89 : double preOpenInterest; ///< 昨持仓量
90 :
91 : // =========================================================================
92 : // 买卖盘(5档)
93 : // =========================================================================
94 :
95 : double bidPrice1; ///< 买一价
96 : int32_t bidVolume1; ///< 买一量
97 : double askPrice1; ///< 卖一价
98 : int32_t askVolume1; ///< 卖一量
99 :
100 : double bidPrice2; ///< 买二价
101 : int32_t bidVolume2; ///< 买二量
102 : double askPrice2; ///< 卖二价
103 : int32_t askVolume2; ///< 卖二量
104 :
105 : double bidPrice3; ///< 买三价
106 : int32_t bidVolume3; ///< 买三量
107 : double askPrice3; ///< 卖三价
108 : int32_t askVolume3; ///< 卖三量
109 :
110 : double bidPrice4; ///< 买四价
111 : int32_t bidVolume4; ///< 买四量
112 : double askPrice4; ///< 卖四价
113 : int32_t askVolume4; ///< 卖四量
114 :
115 : double bidPrice5; ///< 买五价
116 : int32_t bidVolume5; ///< 买五量
117 : double askPrice5; ///< 卖五价
118 : int32_t askVolume5; ///< 卖五量
119 :
120 : // =========================================================================
121 : // 构造函数
122 : // =========================================================================
123 :
124 : /**
125 : * @brief 默认构造函数,初始化所有字段为零值
126 : */
127 673 : MarketData() {
128 673 : std::memset(this, 0, sizeof(MarketData));
129 673 : }
130 :
131 : /**
132 : * @brief 设置合约代码
133 : * @param id 合约代码字符串
134 : */
135 640 : void setInstrumentID(const char* id) {
136 640 : std::strncpy(instrumentID, id, INSTRUMENT_ID_LEN - 1);
137 640 : instrumentID[INSTRUMENT_ID_LEN - 1] = '\0';
138 640 : }
139 :
140 : /**
141 : * @brief 设置交易所代码
142 : * @param id 交易所代码字符串
143 : */
144 635 : void setExchangeID(const char* id) {
145 635 : std::strncpy(exchangeID, id, EXCHANGE_ID_LEN - 1);
146 635 : exchangeID[EXCHANGE_ID_LEN - 1] = '\0';
147 635 : }
148 :
149 : /**
150 : * @brief 设置交易日
151 : * @param day 交易日字符串 (YYYYMMDD)
152 : */
153 634 : void setTradingDay(const char* day) {
154 634 : std::strncpy(tradingDay, day, DATE_LEN - 1);
155 634 : tradingDay[DATE_LEN - 1] = '\0';
156 634 : }
157 :
158 : /**
159 : * @brief 设置更新时间
160 : * @param time 时间字符串 (HH:MM:SS)
161 : */
162 634 : void setUpdateTime(const char* time) {
163 634 : std::strncpy(updateTime, time, TIME_LEN - 1);
164 634 : updateTime[TIME_LEN - 1] = '\0';
165 634 : }
166 :
167 : /**
168 : * @brief 获取合约代码字符串
169 : */
170 522 : std::string getInstrumentID() const {
171 1044 : return std::string(instrumentID);
172 : }
173 :
174 : /**
175 : * @brief 获取交易所代码字符串
176 : */
177 1 : std::string getExchangeID() const {
178 2 : return std::string(exchangeID);
179 : }
180 : };
181 :
182 : // 静态断言确保 trivially copyable 特性(可安全用于无锁队列)
183 : static_assert(std::is_trivially_copyable<MarketData>::value,
184 : "MarketData must be trivially copyable for lock-free queue");
185 :
186 : } // namespace fix40
|