1use super::{ClientExtensions, StopLossOrder, TakeProfitOrder, TrailingStopLossOrder};
3use crate::ids::{InstrumentName, OrderID, TradeID, TransactionID};
4use crate::timestamp::Timestamp;
5use rust_decimal::Decimal;
6use serde::{Deserialize, Serialize};
7
8provider_enum! {
9 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
11 #[non_exhaustive]
12 pub enum TradeState {
13 Open => "OPEN",
15 Closed => "CLOSED",
17 CloseWhenTradeable => "CLOSE_WHEN_TRADEABLE",
19 ;
20 Unknown(String),
22 }
23}
24
25provider_enum! {
26 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
30 #[non_exhaustive]
31 pub enum TradeStateFilter {
32 Open => "OPEN",
34 Closed => "CLOSED",
36 CloseWhenTradeable => "CLOSE_WHEN_TRADEABLE",
38 All => "ALL",
40 ;
41 Unknown(String),
43 }
44}
45
46#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
49#[serde(rename_all = "camelCase")]
50pub struct Trade {
51 #[serde(rename = "id", default, skip_serializing_if = "Option::is_none")]
53 pub id: Option<TradeID>,
54 #[serde(
56 rename = "instrument",
57 default,
58 skip_serializing_if = "Option::is_none"
59 )]
60 pub instrument: Option<InstrumentName>,
61 #[serde(rename = "price", default, skip_serializing_if = "Option::is_none")]
63 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
64 pub price: Option<Decimal>,
65 #[serde(rename = "openTime", default, skip_serializing_if = "Option::is_none")]
67 pub open_time: Option<Timestamp>,
68 #[serde(rename = "state", default, skip_serializing_if = "Option::is_none")]
70 pub state: Option<TradeState>,
71 #[serde(
74 rename = "initialUnits",
75 default,
76 skip_serializing_if = "Option::is_none"
77 )]
78 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
79 pub initial_units: Option<Decimal>,
80 #[serde(
83 rename = "initialMarginRequired",
84 default,
85 skip_serializing_if = "Option::is_none"
86 )]
87 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
88 pub initial_margin_required: Option<Decimal>,
89 #[serde(
91 rename = "currentUnits",
92 default,
93 skip_serializing_if = "Option::is_none"
94 )]
95 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
96 pub current_units: Option<Decimal>,
97 #[serde(
99 rename = "realizedPL",
100 default,
101 skip_serializing_if = "Option::is_none"
102 )]
103 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
104 pub realized_pl: Option<Decimal>,
105 #[serde(
107 rename = "unrealizedPL",
108 default,
109 skip_serializing_if = "Option::is_none"
110 )]
111 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
112 pub unrealized_pl: Option<Decimal>,
113 #[serde(
115 rename = "marginUsed",
116 default,
117 skip_serializing_if = "Option::is_none"
118 )]
119 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
120 pub margin_used: Option<Decimal>,
121 #[serde(
124 rename = "averageClosePrice",
125 default,
126 skip_serializing_if = "Option::is_none"
127 )]
128 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
129 pub average_close_price: Option<Decimal>,
130 #[serde(
132 rename = "closingTransactionIDs",
133 default,
134 skip_serializing_if = "Option::is_none"
135 )]
136 pub closing_transaction_ids: Option<Vec<TransactionID>>,
137 #[serde(rename = "financing", default, skip_serializing_if = "Option::is_none")]
139 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
140 pub financing: Option<Decimal>,
141 #[serde(
143 rename = "dividendAdjustment",
144 default,
145 skip_serializing_if = "Option::is_none"
146 )]
147 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
148 pub dividend_adjustment: Option<Decimal>,
149 #[serde(rename = "closeTime", default, skip_serializing_if = "Option::is_none")]
151 pub close_time: Option<Timestamp>,
152 #[serde(
154 rename = "clientExtensions",
155 default,
156 skip_serializing_if = "Option::is_none"
157 )]
158 pub client_extensions: Option<ClientExtensions>,
159 #[serde(
161 rename = "takeProfitOrder",
162 default,
163 skip_serializing_if = "Option::is_none"
164 )]
165 pub take_profit_order: Option<TakeProfitOrder>,
166 #[serde(
168 rename = "stopLossOrder",
169 default,
170 skip_serializing_if = "Option::is_none"
171 )]
172 pub stop_loss_order: Option<StopLossOrder>,
173 #[serde(
175 rename = "trailingStopLossOrder",
176 default,
177 skip_serializing_if = "Option::is_none"
178 )]
179 pub trailing_stop_loss_order: Option<TrailingStopLossOrder>,
180}
181
182#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
185#[serde(rename_all = "camelCase")]
186pub struct TradeSummary {
187 #[serde(rename = "id", default, skip_serializing_if = "Option::is_none")]
189 pub id: Option<TradeID>,
190 #[serde(
192 rename = "instrument",
193 default,
194 skip_serializing_if = "Option::is_none"
195 )]
196 pub instrument: Option<InstrumentName>,
197 #[serde(rename = "price", default, skip_serializing_if = "Option::is_none")]
199 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
200 pub price: Option<Decimal>,
201 #[serde(rename = "openTime", default, skip_serializing_if = "Option::is_none")]
203 pub open_time: Option<Timestamp>,
204 #[serde(rename = "state", default, skip_serializing_if = "Option::is_none")]
206 pub state: Option<TradeState>,
207 #[serde(
210 rename = "initialUnits",
211 default,
212 skip_serializing_if = "Option::is_none"
213 )]
214 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
215 pub initial_units: Option<Decimal>,
216 #[serde(
219 rename = "initialMarginRequired",
220 default,
221 skip_serializing_if = "Option::is_none"
222 )]
223 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
224 pub initial_margin_required: Option<Decimal>,
225 #[serde(
227 rename = "currentUnits",
228 default,
229 skip_serializing_if = "Option::is_none"
230 )]
231 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
232 pub current_units: Option<Decimal>,
233 #[serde(
235 rename = "realizedPL",
236 default,
237 skip_serializing_if = "Option::is_none"
238 )]
239 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
240 pub realized_pl: Option<Decimal>,
241 #[serde(
243 rename = "unrealizedPL",
244 default,
245 skip_serializing_if = "Option::is_none"
246 )]
247 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
248 pub unrealized_pl: Option<Decimal>,
249 #[serde(
251 rename = "marginUsed",
252 default,
253 skip_serializing_if = "Option::is_none"
254 )]
255 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
256 pub margin_used: Option<Decimal>,
257 #[serde(
260 rename = "averageClosePrice",
261 default,
262 skip_serializing_if = "Option::is_none"
263 )]
264 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
265 pub average_close_price: Option<Decimal>,
266 #[serde(
268 rename = "closingTransactionIDs",
269 default,
270 skip_serializing_if = "Option::is_none"
271 )]
272 pub closing_transaction_ids: Option<Vec<TransactionID>>,
273 #[serde(rename = "financing", default, skip_serializing_if = "Option::is_none")]
275 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
276 pub financing: Option<Decimal>,
277 #[serde(
279 rename = "dividendAdjustment",
280 default,
281 skip_serializing_if = "Option::is_none"
282 )]
283 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
284 pub dividend_adjustment: Option<Decimal>,
285 #[serde(rename = "closeTime", default, skip_serializing_if = "Option::is_none")]
287 pub close_time: Option<Timestamp>,
288 #[serde(
290 rename = "clientExtensions",
291 default,
292 skip_serializing_if = "Option::is_none"
293 )]
294 pub client_extensions: Option<ClientExtensions>,
295 #[serde(
297 rename = "takeProfitOrderID",
298 default,
299 skip_serializing_if = "Option::is_none"
300 )]
301 pub take_profit_order_id: Option<OrderID>,
302 #[serde(
304 rename = "stopLossOrderID",
305 default,
306 skip_serializing_if = "Option::is_none"
307 )]
308 pub stop_loss_order_id: Option<OrderID>,
309 #[serde(
311 rename = "guaranteedStopLossOrderID",
312 default,
313 skip_serializing_if = "Option::is_none"
314 )]
315 pub guaranteed_stop_loss_order_id: Option<OrderID>,
316 #[serde(
318 rename = "trailingStopLossOrderID",
319 default,
320 skip_serializing_if = "Option::is_none"
321 )]
322 pub trailing_stop_loss_order_id: Option<OrderID>,
323}
324
325#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
327#[serde(rename_all = "camelCase")]
328pub struct CalculatedTradeState {
329 #[serde(rename = "id", default, skip_serializing_if = "Option::is_none")]
331 pub id: Option<TradeID>,
332 #[serde(
334 rename = "unrealizedPL",
335 default,
336 skip_serializing_if = "Option::is_none"
337 )]
338 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
339 pub unrealized_pl: Option<Decimal>,
340 #[serde(
342 rename = "marginUsed",
343 default,
344 skip_serializing_if = "Option::is_none"
345 )]
346 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
347 pub margin_used: Option<Decimal>,
348}
349
350provider_enum! {
351 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
353 #[non_exhaustive]
354 pub enum TradePL {
355 Positive => "POSITIVE",
358 Negative => "NEGATIVE",
361 Zero => "ZERO",
364 ;
365 Unknown(String),
367 }
368}