1#[allow(unused_imports)]
4use super::*;
5#[allow(unused_imports)]
6use crate::ids::*;
7#[allow(unused_imports)]
8use crate::timestamp::Timestamp;
9#[allow(unused_imports)]
10use rust_decimal::Decimal;
11#[allow(unused_imports)]
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash)]
16#[non_exhaustive]
17pub enum TradeState {
18 Open,
20 Closed,
22 CloseWhenTradeable,
24 Unknown(String),
26}
27
28impl TradeState {
29 pub fn as_str(&self) -> &str {
31 match self {
32 Self::Open => "OPEN",
33 Self::Closed => "CLOSED",
34 Self::CloseWhenTradeable => "CLOSE_WHEN_TRADEABLE",
35 Self::Unknown(value) => value,
36 }
37 }
38}
39
40impl Serialize for TradeState {
41 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
42 serializer.serialize_str(self.as_str())
43 }
44}
45
46impl<'de> Deserialize<'de> for TradeState {
47 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
48 let value = String::deserialize(deserializer)?;
49 Ok(match value.as_str() {
50 "OPEN" => Self::Open,
51 "CLOSED" => Self::Closed,
52 "CLOSE_WHEN_TRADEABLE" => Self::CloseWhenTradeable,
53 _ => Self::Unknown(value),
54 })
55 }
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Hash)]
60#[non_exhaustive]
61pub enum TradeStateFilter {
62 Open,
64 Closed,
66 CloseWhenTradeable,
68 All,
70 Unknown(String),
72}
73
74impl TradeStateFilter {
75 pub fn as_str(&self) -> &str {
77 match self {
78 Self::Open => "OPEN",
79 Self::Closed => "CLOSED",
80 Self::CloseWhenTradeable => "CLOSE_WHEN_TRADEABLE",
81 Self::All => "ALL",
82 Self::Unknown(value) => value,
83 }
84 }
85}
86
87impl Serialize for TradeStateFilter {
88 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
89 serializer.serialize_str(self.as_str())
90 }
91}
92
93impl<'de> Deserialize<'de> for TradeStateFilter {
94 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
95 let value = String::deserialize(deserializer)?;
96 Ok(match value.as_str() {
97 "OPEN" => Self::Open,
98 "CLOSED" => Self::Closed,
99 "CLOSE_WHEN_TRADEABLE" => Self::CloseWhenTradeable,
100 "ALL" => Self::All,
101 _ => Self::Unknown(value),
102 })
103 }
104}
105
106#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
109#[serde(rename_all = "camelCase")]
110pub struct Trade {
111 #[serde(rename = "id", default, skip_serializing_if = "Option::is_none")]
113 pub id: Option<TradeID>,
114 #[serde(
116 rename = "instrument",
117 default,
118 skip_serializing_if = "Option::is_none"
119 )]
120 pub instrument: Option<InstrumentName>,
121 #[serde(rename = "price", default, skip_serializing_if = "Option::is_none")]
123 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
124 pub price: Option<Decimal>,
125 #[serde(rename = "openTime", default, skip_serializing_if = "Option::is_none")]
127 pub open_time: Option<Timestamp>,
128 #[serde(rename = "state", default, skip_serializing_if = "Option::is_none")]
130 pub state: Option<TradeState>,
131 #[serde(
134 rename = "initialUnits",
135 default,
136 skip_serializing_if = "Option::is_none"
137 )]
138 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
139 pub initial_units: Option<Decimal>,
140 #[serde(
143 rename = "initialMarginRequired",
144 default,
145 skip_serializing_if = "Option::is_none"
146 )]
147 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
148 pub initial_margin_required: Option<Decimal>,
149 #[serde(
151 rename = "currentUnits",
152 default,
153 skip_serializing_if = "Option::is_none"
154 )]
155 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
156 pub current_units: Option<Decimal>,
157 #[serde(
159 rename = "realizedPL",
160 default,
161 skip_serializing_if = "Option::is_none"
162 )]
163 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
164 pub realized_pl: Option<Decimal>,
165 #[serde(
167 rename = "unrealizedPL",
168 default,
169 skip_serializing_if = "Option::is_none"
170 )]
171 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
172 pub unrealized_pl: Option<Decimal>,
173 #[serde(
175 rename = "marginUsed",
176 default,
177 skip_serializing_if = "Option::is_none"
178 )]
179 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
180 pub margin_used: Option<Decimal>,
181 #[serde(
184 rename = "averageClosePrice",
185 default,
186 skip_serializing_if = "Option::is_none"
187 )]
188 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
189 pub average_close_price: Option<Decimal>,
190 #[serde(
192 rename = "closingTransactionIDs",
193 default,
194 skip_serializing_if = "Option::is_none"
195 )]
196 pub closing_transaction_ids: Option<Vec<TransactionID>>,
197 #[serde(rename = "financing", default, skip_serializing_if = "Option::is_none")]
199 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
200 pub financing: Option<Decimal>,
201 #[serde(
203 rename = "dividendAdjustment",
204 default,
205 skip_serializing_if = "Option::is_none"
206 )]
207 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
208 pub dividend_adjustment: Option<Decimal>,
209 #[serde(rename = "closeTime", default, skip_serializing_if = "Option::is_none")]
211 pub close_time: Option<Timestamp>,
212 #[serde(
214 rename = "clientExtensions",
215 default,
216 skip_serializing_if = "Option::is_none"
217 )]
218 pub client_extensions: Option<ClientExtensions>,
219 #[serde(
221 rename = "takeProfitOrder",
222 default,
223 skip_serializing_if = "Option::is_none"
224 )]
225 pub take_profit_order: Option<TakeProfitOrder>,
226 #[serde(
228 rename = "stopLossOrder",
229 default,
230 skip_serializing_if = "Option::is_none"
231 )]
232 pub stop_loss_order: Option<StopLossOrder>,
233 #[serde(
235 rename = "trailingStopLossOrder",
236 default,
237 skip_serializing_if = "Option::is_none"
238 )]
239 pub trailing_stop_loss_order: Option<TrailingStopLossOrder>,
240}
241
242#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
245#[serde(rename_all = "camelCase")]
246pub struct TradeSummary {
247 #[serde(rename = "id", default, skip_serializing_if = "Option::is_none")]
249 pub id: Option<TradeID>,
250 #[serde(
252 rename = "instrument",
253 default,
254 skip_serializing_if = "Option::is_none"
255 )]
256 pub instrument: Option<InstrumentName>,
257 #[serde(rename = "price", default, skip_serializing_if = "Option::is_none")]
259 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
260 pub price: Option<Decimal>,
261 #[serde(rename = "openTime", default, skip_serializing_if = "Option::is_none")]
263 pub open_time: Option<Timestamp>,
264 #[serde(rename = "state", default, skip_serializing_if = "Option::is_none")]
266 pub state: Option<TradeState>,
267 #[serde(
270 rename = "initialUnits",
271 default,
272 skip_serializing_if = "Option::is_none"
273 )]
274 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
275 pub initial_units: Option<Decimal>,
276 #[serde(
279 rename = "initialMarginRequired",
280 default,
281 skip_serializing_if = "Option::is_none"
282 )]
283 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
284 pub initial_margin_required: Option<Decimal>,
285 #[serde(
287 rename = "currentUnits",
288 default,
289 skip_serializing_if = "Option::is_none"
290 )]
291 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
292 pub current_units: Option<Decimal>,
293 #[serde(
295 rename = "realizedPL",
296 default,
297 skip_serializing_if = "Option::is_none"
298 )]
299 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
300 pub realized_pl: Option<Decimal>,
301 #[serde(
303 rename = "unrealizedPL",
304 default,
305 skip_serializing_if = "Option::is_none"
306 )]
307 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
308 pub unrealized_pl: Option<Decimal>,
309 #[serde(
311 rename = "marginUsed",
312 default,
313 skip_serializing_if = "Option::is_none"
314 )]
315 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
316 pub margin_used: Option<Decimal>,
317 #[serde(
320 rename = "averageClosePrice",
321 default,
322 skip_serializing_if = "Option::is_none"
323 )]
324 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
325 pub average_close_price: Option<Decimal>,
326 #[serde(
328 rename = "closingTransactionIDs",
329 default,
330 skip_serializing_if = "Option::is_none"
331 )]
332 pub closing_transaction_ids: Option<Vec<TransactionID>>,
333 #[serde(rename = "financing", default, skip_serializing_if = "Option::is_none")]
335 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
336 pub financing: Option<Decimal>,
337 #[serde(
339 rename = "dividendAdjustment",
340 default,
341 skip_serializing_if = "Option::is_none"
342 )]
343 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
344 pub dividend_adjustment: Option<Decimal>,
345 #[serde(rename = "closeTime", default, skip_serializing_if = "Option::is_none")]
347 pub close_time: Option<Timestamp>,
348 #[serde(
350 rename = "clientExtensions",
351 default,
352 skip_serializing_if = "Option::is_none"
353 )]
354 pub client_extensions: Option<ClientExtensions>,
355 #[serde(
357 rename = "takeProfitOrderID",
358 default,
359 skip_serializing_if = "Option::is_none"
360 )]
361 pub take_profit_order_id: Option<OrderID>,
362 #[serde(
364 rename = "stopLossOrderID",
365 default,
366 skip_serializing_if = "Option::is_none"
367 )]
368 pub stop_loss_order_id: Option<OrderID>,
369 #[serde(
371 rename = "guaranteedStopLossOrderID",
372 default,
373 skip_serializing_if = "Option::is_none"
374 )]
375 pub guaranteed_stop_loss_order_id: Option<OrderID>,
376 #[serde(
378 rename = "trailingStopLossOrderID",
379 default,
380 skip_serializing_if = "Option::is_none"
381 )]
382 pub trailing_stop_loss_order_id: Option<OrderID>,
383}
384
385#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
387#[serde(rename_all = "camelCase")]
388pub struct CalculatedTradeState {
389 #[serde(rename = "id", default, skip_serializing_if = "Option::is_none")]
391 pub id: Option<TradeID>,
392 #[serde(
394 rename = "unrealizedPL",
395 default,
396 skip_serializing_if = "Option::is_none"
397 )]
398 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
399 pub unrealized_pl: Option<Decimal>,
400 #[serde(
402 rename = "marginUsed",
403 default,
404 skip_serializing_if = "Option::is_none"
405 )]
406 #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
407 pub margin_used: Option<Decimal>,
408}
409
410#[derive(Debug, Clone, PartialEq, Eq, Hash)]
412#[non_exhaustive]
413pub enum TradePL {
414 Positive,
417 Negative,
420 Zero,
423 Unknown(String),
425}
426
427impl TradePL {
428 pub fn as_str(&self) -> &str {
430 match self {
431 Self::Positive => "POSITIVE",
432 Self::Negative => "NEGATIVE",
433 Self::Zero => "ZERO",
434 Self::Unknown(value) => value,
435 }
436 }
437}
438
439impl Serialize for TradePL {
440 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
441 serializer.serialize_str(self.as_str())
442 }
443}
444
445impl<'de> Deserialize<'de> for TradePL {
446 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
447 let value = String::deserialize(deserializer)?;
448 Ok(match value.as_str() {
449 "POSITIVE" => Self::Positive,
450 "NEGATIVE" => Self::Negative,
451 "ZERO" => Self::Zero,
452 _ => Self::Unknown(value),
453 })
454 }
455}