Line data Source code
1 : /**
2 : * @file position_manager.hpp
3 : * @brief 持仓管理模块
4 : *
5 : * 提供持仓的开仓、平仓、盈亏计算等功能。
6 : * 支持与存储层集成进行持久化。
7 : */
8 :
9 : #pragma once
10 :
11 : #include <string>
12 : #include <unordered_map>
13 : #include <optional>
14 : #include <mutex>
15 : #include <vector>
16 : #include "app/model/position.hpp"
17 : #include "app/model/order.hpp"
18 : #include "app/model/market_data_snapshot.hpp"
19 :
20 : namespace fix40 {
21 :
22 : // 前向声明
23 : class IStore;
24 :
25 : /**
26 : * @class PositionManager
27 : * @brief 持仓管理器
28 : *
29 : * 负责持仓的开仓、平仓、盈亏计算等操作。
30 : * 支持与IStore接口集成进行数据持久化。
31 : *
32 : * @par 线程安全
33 : * 所有公共方法都是线程安全的,使用互斥锁保护内部数据。
34 : *
35 : * @par 持仓计算
36 : * - 开仓:增加持仓量,计算新的持仓均价
37 : * - 平仓:减少持仓量,计算平仓盈亏
38 : * - 浮动盈亏:根据最新价实时计算
39 : *
40 : * @par 使用示例
41 : * @code
42 : * PositionManager mgr;
43 : *
44 : * // 开仓
45 : * mgr.openPosition("user001", "IF2601", OrderSide::BUY, 2, 4000.0, 240000.0);
46 : *
47 : * // 更新浮动盈亏
48 : * MarketDataSnapshot snapshot;
49 : * snapshot.lastPrice = 4050.0;
50 : * mgr.updateAllProfits(snapshot, 300);
51 : *
52 : * // 平仓
53 : * double profit = mgr.closePosition("user001", "IF2601", OrderSide::BUY, 1, 4050.0, 300);
54 : * @endcode
55 : */
56 : class PositionManager {
57 : public:
58 : // -------------------------------------------------------------------------
59 : // 构造函数
60 : // -------------------------------------------------------------------------
61 :
62 : /**
63 : * @brief 默认构造函数
64 : */
65 : PositionManager();
66 :
67 : /**
68 : * @brief 带存储接口的构造函数
69 : *
70 : * @param store 存储接口指针(可为nullptr)
71 : *
72 : * @note 当 store 不为空时,会在构造阶段从存储中加载已存在的持仓,
73 : * 用于服务端重启后的持仓状态恢复。
74 : */
75 : explicit PositionManager(IStore* store);
76 :
77 : /**
78 : * @brief 析构函数
79 : */
80 554 : ~PositionManager() = default;
81 :
82 : // 禁用拷贝
83 : PositionManager(const PositionManager&) = delete;
84 : PositionManager& operator=(const PositionManager&) = delete;
85 :
86 : // -------------------------------------------------------------------------
87 : // 查询方法
88 : // -------------------------------------------------------------------------
89 :
90 : /**
91 : * @brief 获取持仓
92 : *
93 : * @param accountId 账户ID
94 : * @param instrumentId 合约代码
95 : * @return 持仓信息,不存在时返回 std::nullopt
96 : */
97 : std::optional<Position> getPosition(const std::string& accountId,
98 : const std::string& instrumentId) const;
99 :
100 : /**
101 : * @brief 获取账户所有持仓
102 : *
103 : * @param accountId 账户ID
104 : * @return 持仓列表
105 : */
106 : std::vector<Position> getPositionsByAccount(const std::string& accountId) const;
107 :
108 : /**
109 : * @brief 获取所有持仓
110 : *
111 : * @return 所有持仓列表
112 : */
113 : std::vector<Position> getAllPositions() const;
114 :
115 : /**
116 : * @brief 检查是否有持仓
117 : *
118 : * @param accountId 账户ID
119 : * @param instrumentId 合约代码
120 : * @return 有持仓返回 true
121 : */
122 : bool hasPosition(const std::string& accountId, const std::string& instrumentId) const;
123 :
124 : /**
125 : * @brief 获取持仓数量
126 : *
127 : * @return 持仓记录数量
128 : */
129 : size_t size() const;
130 :
131 : // -------------------------------------------------------------------------
132 : // 开仓操作
133 : // -------------------------------------------------------------------------
134 :
135 : /**
136 : * @brief 开仓
137 : *
138 : * 增加持仓量,计算新的持仓均价。
139 : *
140 : * @param accountId 账户ID
141 : * @param instrumentId 合约代码
142 : * @param side 买卖方向(BUY=多头,SELL=空头)
143 : * @param volume 开仓数量
144 : * @param price 开仓价格
145 : * @param margin 占用保证金
146 : *
147 : * @par 均价计算
148 : * 新均价 = (原均价 × 原持仓 + 开仓价 × 开仓量) / (原持仓 + 开仓量)
149 : */
150 : void openPosition(const std::string& accountId,
151 : const std::string& instrumentId,
152 : OrderSide side,
153 : int64_t volume,
154 : double price,
155 : double margin);
156 :
157 : // -------------------------------------------------------------------------
158 : // 平仓操作
159 : // -------------------------------------------------------------------------
160 :
161 : /**
162 : * @brief 平仓
163 : *
164 : * 减少持仓量,计算平仓盈亏。
165 : *
166 : * @param accountId 账户ID
167 : * @param instrumentId 合约代码
168 : * @param side 平仓方向(BUY=平空头,SELL=平多头)
169 : * @param volume 平仓数量
170 : * @param price 平仓价格
171 : * @param volumeMultiple 合约乘数
172 : * @return 平仓盈亏
173 : *
174 : * @par 盈亏计算
175 : * - 平多头:(平仓价 - 持仓均价) × 平仓量 × 合约乘数
176 : * - 平空头:(持仓均价 - 平仓价) × 平仓量 × 合约乘数
177 : */
178 : double closePosition(const std::string& accountId,
179 : const std::string& instrumentId,
180 : OrderSide side,
181 : int64_t volume,
182 : double price,
183 : int volumeMultiple);
184 :
185 : // -------------------------------------------------------------------------
186 : // 盈亏更新
187 : // -------------------------------------------------------------------------
188 :
189 : /**
190 : * @brief 更新指定合约所有持仓的浮动盈亏
191 : *
192 : * @param snapshot 行情快照
193 : * @param volumeMultiple 合约乘数
194 : */
195 : void updateAllProfits(const MarketDataSnapshot& snapshot, int volumeMultiple);
196 :
197 : /**
198 : * @brief 更新指定持仓的浮动盈亏
199 : *
200 : * @param accountId 账户ID
201 : * @param instrumentId 合约代码
202 : * @param lastPrice 最新价
203 : * @param volumeMultiple 合约乘数
204 : * @return 更新后的总浮动盈亏
205 : */
206 : double updateProfit(const std::string& accountId,
207 : const std::string& instrumentId,
208 : double lastPrice,
209 : int volumeMultiple);
210 :
211 : /**
212 : * @brief 获取账户总浮动盈亏
213 : *
214 : * @param accountId 账户ID
215 : * @return 总浮动盈亏
216 : */
217 : double getTotalProfit(const std::string& accountId) const;
218 :
219 : // -------------------------------------------------------------------------
220 : // 清理方法
221 : // -------------------------------------------------------------------------
222 :
223 : /**
224 : * @brief 清空所有持仓
225 : */
226 : void clear();
227 :
228 : private:
229 : /**
230 : * @brief 生成持仓键
231 : *
232 : * @param accountId 账户ID
233 : * @param instrumentId 合约代码
234 : * @return 复合键
235 : */
236 : static std::string makeKey(const std::string& accountId, const std::string& instrumentId);
237 :
238 : /**
239 : * @brief 持久化持仓(内部方法)
240 : *
241 : * @param position 要持久化的持仓
242 : */
243 : void persistPosition(const Position& position);
244 :
245 : /// 持仓映射表:accountId_instrumentId -> Position
246 : std::unordered_map<std::string, Position> positions_;
247 :
248 : /// 存储接口(可为nullptr)
249 : IStore* store_;
250 :
251 : /// 互斥锁,保护 positions_
252 : mutable std::mutex mutex_;
253 : };
254 :
255 : } // namespace fix40
|