Line data Source code
1 : /**
2 : * @file client_state.hpp
3 : * @brief 客户端状态管理
4 : *
5 : * 管理客户端的账户、持仓、订单等状态数据。
6 : * 线程安全,支持从 FIX 回调更新和 TUI 读取。
7 : */
8 :
9 : #pragma once
10 :
11 : #include <string>
12 : #include <vector>
13 : #include <mutex>
14 : #include <atomic>
15 : #include <functional>
16 : #include <unordered_map>
17 : #include <filesystem>
18 : #include <chrono>
19 :
20 : namespace fix40::client {
21 :
22 : /**
23 : * @brief 连接状态
24 : */
25 : enum class ConnectionState {
26 : DISCONNECTED,
27 : CONNECTING,
28 : CONNECTED,
29 : LOGGING_IN,
30 : LOGGED_IN,
31 : ERROR
32 : };
33 :
34 : /**
35 : * @brief 账户信息
36 : */
37 : struct AccountInfo {
38 : double balance = 0.0; ///< 静态权益
39 : double available = 0.0; ///< 可用资金
40 : double frozenMargin = 0.0; ///< 冻结保证金
41 : double usedMargin = 0.0; ///< 占用保证金
42 : double positionProfit = 0.0; ///< 持仓盈亏
43 : double closeProfit = 0.0; ///< 平仓盈亏
44 : double dynamicEquity = 0.0; ///< 动态权益
45 : double riskRatio = 0.0; ///< 风险度
46 : };
47 :
48 : /**
49 : * @brief 持仓信息
50 : */
51 : struct PositionInfo {
52 : std::string instrumentId;
53 : int64_t longPosition = 0;
54 : double longAvgPrice = 0.0;
55 : int64_t shortPosition = 0;
56 : double shortAvgPrice = 0.0;
57 : double profit = 0.0;
58 : bool quantitiesValid = false; ///< 是否包含多空数量字段(允许数量为0时用于清空持仓)
59 : };
60 :
61 : /**
62 : * @brief 订单状态
63 : */
64 : enum class OrderState {
65 : PENDING_NEW,
66 : NEW,
67 : PARTIALLY_FILLED,
68 : FILLED,
69 : CANCELED,
70 : REJECTED
71 : };
72 :
73 : /**
74 : * @brief 订单信息
75 : */
76 : struct OrderInfo {
77 : std::string clOrdID;
78 : std::string orderId;
79 : std::string symbol;
80 : std::string side; ///< "BUY" or "SELL"
81 : double price = 0.0;
82 : int64_t orderQty = 0;
83 : int64_t filledQty = 0;
84 : double avgPx = 0.0;
85 : OrderState state = OrderState::PENDING_NEW;
86 : std::string text; ///< 拒绝原因等
87 : std::string updateTime;
88 : };
89 :
90 : /**
91 : * @class ClientState
92 : * @brief 客户端状态管理器
93 : *
94 : * 线程安全地管理客户端状态,支持:
95 : * - 从 FIX 回调线程更新状态
96 : * - 从 TUI 渲染线程读取状态
97 : * - 状态变更通知
98 : */
99 : class ClientState {
100 : public:
101 : using StateChangeCallback = std::function<void()>;
102 :
103 4 : ClientState() = default;
104 :
105 : // =========================================================================
106 : // 连接状态
107 : // =========================================================================
108 :
109 : void setConnectionState(ConnectionState state);
110 : ConnectionState getConnectionState() const;
111 : std::string getConnectionStateString() const;
112 :
113 : void setUserId(const std::string& userId);
114 : std::string getUserId() const;
115 :
116 : // =========================================================================
117 : // 账户信息
118 : // =========================================================================
119 :
120 : void updateAccount(const AccountInfo& info);
121 : AccountInfo getAccount() const;
122 :
123 : // =========================================================================
124 : // 持仓信息
125 : // =========================================================================
126 :
127 : void updatePosition(const PositionInfo& pos);
128 : void setPositions(const std::vector<PositionInfo>& positions);
129 : std::vector<PositionInfo> getPositions() const;
130 : void clearPositions();
131 :
132 : // =========================================================================
133 : // 订单信息
134 : // =========================================================================
135 :
136 : void addOrder(const OrderInfo& order);
137 : void updateOrder(const std::string& clOrdID, const OrderInfo& order);
138 : std::vector<OrderInfo> getOrders() const;
139 : std::vector<OrderInfo> getActiveOrders() const;
140 : void clearOrders();
141 :
142 : /**
143 : * @brief 批量设置订单列表
144 : *
145 : * 用于“从服务端持久化历史刷新订单列表”等场景:
146 : * 一次性替换内部订单容器并只触发一次 notifyStateChange(),避免逐条 addOrder 导致的频繁刷新。
147 : *
148 : * @param orders 新的订单列表(按希望展示的顺序排列)
149 : *
150 : * @note clOrdID 为空的订单会被忽略(静默跳过)。
151 : */
152 : void setOrders(const std::vector<OrderInfo>& orders);
153 :
154 : /**
155 : * @brief 保存订单到文件
156 : * @param filepath 文件路径(默认 ~/.fix_client_orders.dat)
157 : */
158 : void saveOrders(const std::string& filepath = "");
159 :
160 : /**
161 : * @brief 从文件加载订单
162 : * @param filepath 文件路径(默认 ~/.fix_client_orders.dat)
163 : */
164 : void loadOrders(const std::string& filepath = "");
165 :
166 : // =========================================================================
167 : // 合约搜索结果
168 : // =========================================================================
169 :
170 : void setSearchResults(const std::vector<std::string>& results);
171 : std::vector<std::string> getSearchResults() const;
172 :
173 : // =========================================================================
174 : // 状态变更通知
175 : // =========================================================================
176 :
177 : void setOnStateChange(StateChangeCallback callback);
178 : void notifyStateChange();
179 :
180 : // =========================================================================
181 : // 消息/错误
182 : // =========================================================================
183 :
184 : void setLastError(const std::string& error);
185 : std::string getLastError() const;
186 :
187 : void addMessage(const std::string& msg);
188 : std::vector<std::string> getMessages() const;
189 :
190 : private:
191 : mutable std::mutex mutex_;
192 :
193 : // 连接状态
194 : std::atomic<ConnectionState> connectionState_{ConnectionState::DISCONNECTED};
195 : std::string userId_;
196 :
197 : // 账户信息
198 : AccountInfo account_;
199 :
200 : // 持仓信息
201 : std::vector<PositionInfo> positions_;
202 :
203 : // 订单信息
204 : std::unordered_map<std::string, OrderInfo> orders_;
205 : // 订单插入顺序(用于稳定展示顺序/保存顺序)
206 : std::vector<std::string> orderSequence_;
207 :
208 : // 合约搜索结果
209 : std::vector<std::string> searchResults_;
210 :
211 : // 消息
212 : std::vector<std::string> messages_;
213 : std::string lastError_;
214 :
215 : // 状态变更回调
216 : StateChangeCallback onStateChange_;
217 :
218 : // 节流:上次通知时间
219 : mutable std::chrono::steady_clock::time_point lastNotifyTime_;
220 : };
221 :
222 : } // namespace fix40::client
|