Line data Source code
1 : /**
2 : * @file order_book.hpp
3 : * @brief 订单簿实现
4 : *
5 : * 管理单个合约的买卖盘,实现价格优先、时间优先的撮合逻辑。
6 : */
7 :
8 : #pragma once
9 :
10 : #include <map>
11 : #include <list>
12 : #include <unordered_map>
13 : #include <vector>
14 : #include <functional>
15 : #include <optional>
16 : #include "app/model/order.hpp"
17 :
18 : namespace fix40 {
19 :
20 : /**
21 : * @struct Trade
22 : * @brief 成交记录
23 : *
24 : * 保存完整的成交信息,包括双方订单的快照,
25 : * 用于生成完整的 ExecutionReport。
26 : */
27 : struct Trade {
28 : std::string tradeID; ///< 成交ID
29 : std::string symbol; ///< 合约代码
30 : double price; ///< 成交价格
31 : int64_t qty; ///< 成交数量
32 : std::chrono::system_clock::time_point timestamp; ///< 成交时间
33 :
34 : // 买方信息
35 : std::string buyOrderID; ///< 买方订单ID
36 : std::string buyClOrdID; ///< 买方客户订单ID
37 : int64_t buyOrderQty; ///< 买方原始订单数量
38 : double buyPrice; ///< 买方订单价格
39 : OrderType buyOrdType; ///< 买方订单类型
40 : int64_t buyCumQty; ///< 买方成交后累计数量
41 : int64_t buyLeavesQty; ///< 买方成交后剩余数量
42 : double buyAvgPx; ///< 买方成交后平均价
43 : OrderStatus buyStatus; ///< 买方成交后状态
44 :
45 : // 卖方信息
46 : std::string sellOrderID; ///< 卖方订单ID
47 : std::string sellClOrdID; ///< 卖方客户订单ID
48 : int64_t sellOrderQty; ///< 卖方原始订单数量
49 : double sellPrice; ///< 卖方订单价格
50 : OrderType sellOrdType; ///< 卖方订单类型
51 : int64_t sellCumQty; ///< 卖方成交后累计数量
52 : int64_t sellLeavesQty; ///< 卖方成交后剩余数量
53 : double sellAvgPx; ///< 卖方成交后平均价
54 : OrderStatus sellStatus; ///< 卖方成交后状态
55 :
56 36 : Trade()
57 72 : : price(0.0), qty(0)
58 36 : , buyOrderQty(0), buyPrice(0.0), buyOrdType(OrderType::LIMIT)
59 36 : , buyCumQty(0), buyLeavesQty(0), buyAvgPx(0.0), buyStatus(OrderStatus::NEW)
60 36 : , sellOrderQty(0), sellPrice(0.0), sellOrdType(OrderType::LIMIT)
61 36 : , sellCumQty(0), sellLeavesQty(0), sellAvgPx(0.0), sellStatus(OrderStatus::NEW)
62 36 : {}
63 : };
64 :
65 : /**
66 : * @struct PriceLevel
67 : * @brief 价格档位
68 : *
69 : * 同一价格的所有订单,按时间顺序排列。
70 : */
71 : struct PriceLevel {
72 : double price; ///< 价格
73 : std::list<Order> orders; ///< 订单队列(时间优先)
74 : int64_t totalQty; ///< 该价位总数量
75 :
76 57 : explicit PriceLevel(double p = 0.0) : price(p), totalQty(0) {}
77 :
78 : bool empty() const { return orders.empty(); }
79 : };
80 :
81 : /**
82 : * @class OrderBook
83 : * @brief 订单簿
84 : *
85 : * 管理单个合约的买卖盘,实现撮合逻辑。
86 : *
87 : * @par 撮合规则
88 : * - 价格优先:买盘价高者优先,卖盘价低者优先
89 : * - 时间优先:同价位先到者优先成交
90 : * - 成交价格:取被动方(挂单方)价格
91 : *
92 : * @par 线程安全
93 : * OrderBook 本身不是线程安全的,应由 MatchingEngine 在单线程中调用。
94 : *
95 : * @par 使用示例
96 : * @code
97 : * OrderBook book("IF2401");
98 : *
99 : * Order buyOrder;
100 : * buyOrder.side = OrderSide::BUY;
101 : * buyOrder.price = 5000.0;
102 : * buyOrder.orderQty = 10;
103 : *
104 : * auto trades = book.addOrder(buyOrder);
105 : * for (const auto& trade : trades) {
106 : * // 处理成交
107 : * }
108 : * @endcode
109 : */
110 : class OrderBook {
111 : public:
112 : /**
113 : * @brief 构造订单簿
114 : * @param symbol 合约代码
115 : */
116 : explicit OrderBook(const std::string& symbol);
117 :
118 : /**
119 : * @brief 获取合约代码
120 : */
121 1 : const std::string& getSymbol() const { return symbol_; }
122 :
123 : // =========================================================================
124 : // 订单操作
125 : // =========================================================================
126 :
127 : /**
128 : * @brief 添加订单并尝试撮合
129 : * @param order 订单(会被修改:设置 orderID、更新状态)
130 : * @return std::vector<Trade> 成交记录列表
131 : *
132 : * 流程:
133 : * 1. 生成 OrderID
134 : * 2. 尝试与对手盘撮合
135 : * 3. 未成交部分挂入订单簿
136 : * 4. 返回成交记录
137 : */
138 : std::vector<Trade> addOrder(Order& order);
139 :
140 : /**
141 : * @brief 撤销订单
142 : * @param clOrdID 客户订单ID
143 : * @return std::optional<Order> 被撤销的订单,不存在返回 nullopt
144 : */
145 : std::optional<Order> cancelOrder(const std::string& clOrdID);
146 :
147 : /**
148 : * @brief 查找订单
149 : * @param clOrdID 客户订单ID
150 : * @return const Order* 订单指针,不存在返回 nullptr
151 : */
152 : const Order* findOrder(const std::string& clOrdID) const;
153 :
154 : // =========================================================================
155 : // 行情查询
156 : // =========================================================================
157 :
158 : /**
159 : * @brief 获取最优买价
160 : * @return std::optional<double> 最高买价,无买盘返回 nullopt
161 : */
162 : std::optional<double> getBestBid() const;
163 :
164 : /**
165 : * @brief 获取最优卖价
166 : * @return std::optional<double> 最低卖价,无卖盘返回 nullopt
167 : */
168 : std::optional<double> getBestAsk() const;
169 :
170 : /**
171 : * @brief 获取买盘深度
172 : * @param levels 档位数量
173 : * @return std::vector<PriceLevel> 买盘各档位(价格降序)
174 : */
175 : std::vector<PriceLevel> getBidLevels(size_t levels = 5) const;
176 :
177 : /**
178 : * @brief 获取卖盘深度
179 : * @param levels 档位数量
180 : * @return std::vector<PriceLevel> 卖盘各档位(价格升序)
181 : */
182 : std::vector<PriceLevel> getAskLevels(size_t levels = 5) const;
183 :
184 : /**
185 : * @brief 获取买盘总订单数
186 : */
187 12 : size_t getBidOrderCount() const { return bidOrderCount_; }
188 :
189 : /**
190 : * @brief 获取卖盘总订单数
191 : */
192 12 : size_t getAskOrderCount() const { return askOrderCount_; }
193 :
194 : /**
195 : * @brief 检查订单簿是否为空
196 : */
197 15 : bool empty() const { return bids_.empty() && asks_.empty(); }
198 :
199 : private:
200 : /**
201 : * @brief 生成订单ID
202 : */
203 : std::string generateOrderID();
204 :
205 : /**
206 : * @brief 生成成交ID
207 : */
208 : std::string generateTradeID();
209 :
210 : /**
211 : * @brief 撮合买单
212 : * @param order 买单
213 : * @return std::vector<Trade> 成交记录
214 : */
215 : std::vector<Trade> matchBuyOrder(Order& order);
216 :
217 : /**
218 : * @brief 撮合卖单
219 : * @param order 卖单
220 : * @return std::vector<Trade> 成交记录
221 : */
222 : std::vector<Trade> matchSellOrder(Order& order);
223 :
224 : /**
225 : * @brief 将订单挂入买盘
226 : */
227 : void addToBids(const Order& order);
228 :
229 : /**
230 : * @brief 将订单挂入卖盘
231 : */
232 : void addToAsks(const Order& order);
233 :
234 : /**
235 : * @brief 从订单簿移除订单
236 : * @param clOrdID 客户订单ID
237 : * @param side 买卖方向
238 : * @return std::optional<Order> 被移除的订单
239 : */
240 : std::optional<Order> removeOrder(const std::string& clOrdID, OrderSide side);
241 :
242 : /**
243 : * @brief 计算订单可成交数量(用于 FOK 预检查)
244 : * @param order 待检查的订单
245 : * @return int64_t 可成交数量
246 : */
247 : int64_t calculateMatchableQty(const Order& order) const;
248 :
249 : std::string symbol_; ///< 合约代码
250 :
251 : /// 买盘:价格降序(greater 使 map 按价格从高到低排列)
252 : std::map<double, PriceLevel, std::greater<double>> bids_;
253 :
254 : /// 卖盘:价格升序(less 使 map 按价格从低到高排列)
255 : std::map<double, PriceLevel, std::less<double>> asks_;
256 :
257 : /// 订单索引:ClOrdID -> (Side, Price) 用于快速查找
258 : struct OrderLocation {
259 : OrderSide side;
260 : double price;
261 : };
262 : std::unordered_map<std::string, OrderLocation> orderIndex_;
263 :
264 : size_t bidOrderCount_ = 0; ///< 买盘订单数
265 : size_t askOrderCount_ = 0; ///< 卖盘订单数
266 : uint64_t nextOrderID_ = 1; ///< 订单ID计数器
267 : uint64_t nextTradeID_ = 1; ///< 成交ID计数器
268 : };
269 :
270 : } // namespace fix40
|