Skip to main content

oanda_client/models/
account.rs

1//! OANDA v20 account definitions.
2// Shared imports vary by definition family; unused ones are deliberately allowed.
3#[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/// The full details of a client’s Account. This includes full open Trade, open Position and pending Order
15/// representation.
16#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
17#[serde(rename_all = "camelCase")]
18pub struct Account {
19    /// The Account’s identifier
20    #[serde(rename = "id", default, skip_serializing_if = "Option::is_none")]
21    pub id: Option<AccountID>,
22    /// Client-assigned alias for the Account. Only provided if the Account has an alias set
23    #[serde(rename = "alias", default, skip_serializing_if = "Option::is_none")]
24    pub alias: Option<String>,
25    /// The home currency of the Account
26    #[serde(rename = "currency", default, skip_serializing_if = "Option::is_none")]
27    pub currency: Option<Currency>,
28    /// ID of the user that created the Account.
29    #[serde(
30        rename = "createdByUserID",
31        default,
32        skip_serializing_if = "Option::is_none"
33    )]
34    pub created_by_user_id: Option<i64>,
35    /// The date/time when the Account was created.
36    #[serde(
37        rename = "createdTime",
38        default,
39        skip_serializing_if = "Option::is_none"
40    )]
41    pub created_time: Option<Timestamp>,
42    /// The current guaranteed Stop Loss Order settings of the Account. This field will only be present if the
43    /// guaranteedStopLossOrderMode is not ‘DISABLED’.
44    #[serde(
45        rename = "guaranteedStopLossOrderParameters",
46        default,
47        skip_serializing_if = "Option::is_none"
48    )]
49    pub guaranteed_stop_loss_order_parameters: Option<GuaranteedStopLossOrderParameters>,
50    /// The current guaranteed Stop Loss Order mode of the Account.
51    #[serde(
52        rename = "guaranteedStopLossOrderMode",
53        default,
54        skip_serializing_if = "Option::is_none"
55    )]
56    pub guaranteed_stop_loss_order_mode: Option<GuaranteedStopLossOrderMode>,
57    /// The current guaranteed Stop Loss Order mutability setting of the Account. This field will only be
58    /// present if the guaranteedStopLossOrderMode is not ‘DISABLED’. Deprecated: Will be removed in a future
59    /// API update.
60    #[serde(
61        rename = "guaranteedStopLossOrderMutability",
62        default,
63        skip_serializing_if = "Option::is_none"
64    )]
65    pub guaranteed_stop_loss_order_mutability: Option<GuaranteedStopLossOrderMutability>,
66    /// The date/time that the Account’s resettablePL was last reset.
67    #[serde(
68        rename = "resettablePLTime",
69        default,
70        skip_serializing_if = "Option::is_none"
71    )]
72    pub resettable_pl_time: Option<Timestamp>,
73    /// Client-provided margin rate override for the Account. The effective margin rate of the Account is the
74    /// lesser of this value and the OANDA margin rate for the Account’s division. This value is only provided
75    /// if a margin rate override exists for the Account.
76    #[serde(
77        rename = "marginRate",
78        default,
79        skip_serializing_if = "Option::is_none"
80    )]
81    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
82    pub margin_rate: Option<Decimal>,
83    /// The number of Trades currently open in the Account.
84    #[serde(
85        rename = "openTradeCount",
86        default,
87        skip_serializing_if = "Option::is_none"
88    )]
89    pub open_trade_count: Option<i64>,
90    /// The number of Positions currently open in the Account.
91    #[serde(
92        rename = "openPositionCount",
93        default,
94        skip_serializing_if = "Option::is_none"
95    )]
96    pub open_position_count: Option<i64>,
97    /// The number of Orders currently pending in the Account.
98    #[serde(
99        rename = "pendingOrderCount",
100        default,
101        skip_serializing_if = "Option::is_none"
102    )]
103    pub pending_order_count: Option<i64>,
104    /// Flag indicating that the Account has hedging enabled.
105    #[serde(
106        rename = "hedgingEnabled",
107        default,
108        skip_serializing_if = "Option::is_none"
109    )]
110    pub hedging_enabled: Option<bool>,
111    /// The total unrealized profit/loss for all Trades currently open in the Account.
112    #[serde(
113        rename = "unrealizedPL",
114        default,
115        skip_serializing_if = "Option::is_none"
116    )]
117    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
118    pub unrealized_pl: Option<Decimal>,
119    /// The net asset value of the Account. Equal to Account balance + unrealizedPL.
120    #[serde(rename = "NAV", default, skip_serializing_if = "Option::is_none")]
121    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
122    pub nav: Option<Decimal>,
123    /// Margin currently used for the Account.
124    #[serde(
125        rename = "marginUsed",
126        default,
127        skip_serializing_if = "Option::is_none"
128    )]
129    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
130    pub margin_used: Option<Decimal>,
131    /// Margin available for Account currency.
132    #[serde(
133        rename = "marginAvailable",
134        default,
135        skip_serializing_if = "Option::is_none"
136    )]
137    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
138    pub margin_available: Option<Decimal>,
139    /// The value of the Account’s open positions represented in the Account’s home currency.
140    #[serde(
141        rename = "positionValue",
142        default,
143        skip_serializing_if = "Option::is_none"
144    )]
145    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
146    pub position_value: Option<Decimal>,
147    /// The Account’s margin closeout unrealized PL.
148    #[serde(
149        rename = "marginCloseoutUnrealizedPL",
150        default,
151        skip_serializing_if = "Option::is_none"
152    )]
153    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
154    pub margin_closeout_unrealized_pl: Option<Decimal>,
155    /// The Account’s margin closeout NAV.
156    #[serde(
157        rename = "marginCloseoutNAV",
158        default,
159        skip_serializing_if = "Option::is_none"
160    )]
161    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
162    pub margin_closeout_nav: Option<Decimal>,
163    /// The Account’s margin closeout margin used.
164    #[serde(
165        rename = "marginCloseoutMarginUsed",
166        default,
167        skip_serializing_if = "Option::is_none"
168    )]
169    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
170    pub margin_closeout_margin_used: Option<Decimal>,
171    /// The Account’s margin closeout percentage. When this value is 1.0 or above the Account is in a margin
172    /// closeout situation.
173    #[serde(
174        rename = "marginCloseoutPercent",
175        default,
176        skip_serializing_if = "Option::is_none"
177    )]
178    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
179    pub margin_closeout_percent: Option<Decimal>,
180    /// The value of the Account’s open positions as used for margin closeout calculations represented in the
181    /// Account’s home currency.
182    #[serde(
183        rename = "marginCloseoutPositionValue",
184        default,
185        skip_serializing_if = "Option::is_none"
186    )]
187    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
188    pub margin_closeout_position_value: Option<Decimal>,
189    /// The current WithdrawalLimit for the account which will be zero or a positive value indicating how much
190    /// can be withdrawn from the account.
191    #[serde(
192        rename = "withdrawalLimit",
193        default,
194        skip_serializing_if = "Option::is_none"
195    )]
196    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
197    pub withdrawal_limit: Option<Decimal>,
198    /// The Account’s margin call margin used.
199    #[serde(
200        rename = "marginCallMarginUsed",
201        default,
202        skip_serializing_if = "Option::is_none"
203    )]
204    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
205    pub margin_call_margin_used: Option<Decimal>,
206    /// The Account’s margin call percentage. When this value is 1.0 or above the Account is in a margin call
207    /// situation.
208    #[serde(
209        rename = "marginCallPercent",
210        default,
211        skip_serializing_if = "Option::is_none"
212    )]
213    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
214    pub margin_call_percent: Option<Decimal>,
215    /// The current balance of the account.
216    #[serde(rename = "balance", default, skip_serializing_if = "Option::is_none")]
217    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
218    pub balance: Option<Decimal>,
219    /// The total profit/loss realized over the lifetime of the Account.
220    #[serde(rename = "pl", default, skip_serializing_if = "Option::is_none")]
221    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
222    pub pl: Option<Decimal>,
223    /// The total realized profit/loss for the account since it was last reset by the client.
224    #[serde(
225        rename = "resettablePL",
226        default,
227        skip_serializing_if = "Option::is_none"
228    )]
229    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
230    pub resettable_pl: Option<Decimal>,
231    /// The total amount of financing paid/collected over the lifetime of the account.
232    #[serde(rename = "financing", default, skip_serializing_if = "Option::is_none")]
233    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
234    pub financing: Option<Decimal>,
235    /// The total amount of commission paid over the lifetime of the Account.
236    #[serde(
237        rename = "commission",
238        default,
239        skip_serializing_if = "Option::is_none"
240    )]
241    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
242    pub commission: Option<Decimal>,
243    /// The total amount of dividend adjustment paid over the lifetime of the Account in the Account’s home
244    /// currency.
245    #[serde(
246        rename = "dividendAdjustment",
247        default,
248        skip_serializing_if = "Option::is_none"
249    )]
250    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
251    pub dividend_adjustment: Option<Decimal>,
252    /// The total amount of fees charged over the lifetime of the Account for the execution of guaranteed Stop
253    /// Loss Orders.
254    #[serde(
255        rename = "guaranteedExecutionFees",
256        default,
257        skip_serializing_if = "Option::is_none"
258    )]
259    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
260    pub guaranteed_execution_fees: Option<Decimal>,
261    /// The date/time when the Account entered a margin call state. Only provided if the Account is in a margin
262    /// call.
263    #[serde(
264        rename = "marginCallEnterTime",
265        default,
266        skip_serializing_if = "Option::is_none"
267    )]
268    pub margin_call_enter_time: Option<Timestamp>,
269    /// The number of times that the Account’s current margin call was extended.
270    #[serde(
271        rename = "marginCallExtensionCount",
272        default,
273        skip_serializing_if = "Option::is_none"
274    )]
275    pub margin_call_extension_count: Option<i64>,
276    /// The date/time of the Account’s last margin call extension.
277    #[serde(
278        rename = "lastMarginCallExtensionTime",
279        default,
280        skip_serializing_if = "Option::is_none"
281    )]
282    pub last_margin_call_extension_time: Option<Timestamp>,
283    /// The ID of the last Transaction created for the Account.
284    #[serde(
285        rename = "lastTransactionID",
286        default,
287        skip_serializing_if = "Option::is_none"
288    )]
289    pub last_transaction_id: Option<TransactionID>,
290    /// The details of the Trades currently open in the Account.
291    #[serde(rename = "trades", default, skip_serializing_if = "Option::is_none")]
292    pub trades: Option<Vec<TradeSummary>>,
293    /// The details all Account Positions.
294    #[serde(rename = "positions", default, skip_serializing_if = "Option::is_none")]
295    pub positions: Option<Vec<Position>>,
296    /// The details of the Orders currently pending in the Account.
297    #[serde(rename = "orders", default, skip_serializing_if = "Option::is_none")]
298    pub orders: Option<Vec<Order>>,
299}
300
301/// An AccountState Object is used to represent an Account’s current price-dependent state. Price-dependent
302/// Account state is dependent on OANDA’s current Prices, and includes things like unrealized PL, NAV and
303/// Trailing Stop Loss Order state. Fields will be omitted if their value has not changed since the
304/// specified transaction ID.
305#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
306#[serde(rename_all = "camelCase")]
307pub struct AccountChangesState {
308    /// The total unrealized profit/loss for all Trades currently open in the Account.
309    #[serde(
310        rename = "unrealizedPL",
311        default,
312        skip_serializing_if = "Option::is_none"
313    )]
314    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
315    pub unrealized_pl: Option<Decimal>,
316    /// The net asset value of the Account. Equal to Account balance + unrealizedPL.
317    #[serde(rename = "NAV", default, skip_serializing_if = "Option::is_none")]
318    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
319    pub nav: Option<Decimal>,
320    /// Margin currently used for the Account.
321    #[serde(
322        rename = "marginUsed",
323        default,
324        skip_serializing_if = "Option::is_none"
325    )]
326    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
327    pub margin_used: Option<Decimal>,
328    /// Margin available for Account currency.
329    #[serde(
330        rename = "marginAvailable",
331        default,
332        skip_serializing_if = "Option::is_none"
333    )]
334    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
335    pub margin_available: Option<Decimal>,
336    /// The value of the Account’s open positions represented in the Account’s home currency.
337    #[serde(
338        rename = "positionValue",
339        default,
340        skip_serializing_if = "Option::is_none"
341    )]
342    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
343    pub position_value: Option<Decimal>,
344    /// The Account’s margin closeout unrealized PL.
345    #[serde(
346        rename = "marginCloseoutUnrealizedPL",
347        default,
348        skip_serializing_if = "Option::is_none"
349    )]
350    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
351    pub margin_closeout_unrealized_pl: Option<Decimal>,
352    /// The Account’s margin closeout NAV.
353    #[serde(
354        rename = "marginCloseoutNAV",
355        default,
356        skip_serializing_if = "Option::is_none"
357    )]
358    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
359    pub margin_closeout_nav: Option<Decimal>,
360    /// The Account’s margin closeout margin used.
361    #[serde(
362        rename = "marginCloseoutMarginUsed",
363        default,
364        skip_serializing_if = "Option::is_none"
365    )]
366    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
367    pub margin_closeout_margin_used: Option<Decimal>,
368    /// The Account’s margin closeout percentage. When this value is 1.0 or above the Account is in a margin
369    /// closeout situation.
370    #[serde(
371        rename = "marginCloseoutPercent",
372        default,
373        skip_serializing_if = "Option::is_none"
374    )]
375    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
376    pub margin_closeout_percent: Option<Decimal>,
377    /// The value of the Account’s open positions as used for margin closeout calculations represented in the
378    /// Account’s home currency.
379    #[serde(
380        rename = "marginCloseoutPositionValue",
381        default,
382        skip_serializing_if = "Option::is_none"
383    )]
384    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
385    pub margin_closeout_position_value: Option<Decimal>,
386    /// The current WithdrawalLimit for the account which will be zero or a positive value indicating how much
387    /// can be withdrawn from the account.
388    #[serde(
389        rename = "withdrawalLimit",
390        default,
391        skip_serializing_if = "Option::is_none"
392    )]
393    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
394    pub withdrawal_limit: Option<Decimal>,
395    /// The Account’s margin call margin used.
396    #[serde(
397        rename = "marginCallMarginUsed",
398        default,
399        skip_serializing_if = "Option::is_none"
400    )]
401    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
402    pub margin_call_margin_used: Option<Decimal>,
403    /// The Account’s margin call percentage. When this value is 1.0 or above the Account is in a margin call
404    /// situation.
405    #[serde(
406        rename = "marginCallPercent",
407        default,
408        skip_serializing_if = "Option::is_none"
409    )]
410    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
411    pub margin_call_percent: Option<Decimal>,
412    /// The current balance of the account.
413    #[serde(rename = "balance", default, skip_serializing_if = "Option::is_none")]
414    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
415    pub balance: Option<Decimal>,
416    /// The total profit/loss realized over the lifetime of the Account.
417    #[serde(rename = "pl", default, skip_serializing_if = "Option::is_none")]
418    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
419    pub pl: Option<Decimal>,
420    /// The total realized profit/loss for the account since it was last reset by the client.
421    #[serde(
422        rename = "resettablePL",
423        default,
424        skip_serializing_if = "Option::is_none"
425    )]
426    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
427    pub resettable_pl: Option<Decimal>,
428    /// The total amount of financing paid/collected over the lifetime of the account.
429    #[serde(rename = "financing", default, skip_serializing_if = "Option::is_none")]
430    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
431    pub financing: Option<Decimal>,
432    /// The total amount of commission paid over the lifetime of the Account.
433    #[serde(
434        rename = "commission",
435        default,
436        skip_serializing_if = "Option::is_none"
437    )]
438    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
439    pub commission: Option<Decimal>,
440    /// The total amount of dividend adjustment paid over the lifetime of the Account in the Account’s home
441    /// currency.
442    #[serde(
443        rename = "dividendAdjustment",
444        default,
445        skip_serializing_if = "Option::is_none"
446    )]
447    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
448    pub dividend_adjustment: Option<Decimal>,
449    /// The total amount of fees charged over the lifetime of the Account for the execution of guaranteed Stop
450    /// Loss Orders.
451    #[serde(
452        rename = "guaranteedExecutionFees",
453        default,
454        skip_serializing_if = "Option::is_none"
455    )]
456    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
457    pub guaranteed_execution_fees: Option<Decimal>,
458    /// The date/time when the Account entered a margin call state. Only provided if the Account is in a margin
459    /// call.
460    #[serde(
461        rename = "marginCallEnterTime",
462        default,
463        skip_serializing_if = "Option::is_none"
464    )]
465    pub margin_call_enter_time: Option<Timestamp>,
466    /// The number of times that the Account’s current margin call was extended.
467    #[serde(
468        rename = "marginCallExtensionCount",
469        default,
470        skip_serializing_if = "Option::is_none"
471    )]
472    pub margin_call_extension_count: Option<i64>,
473    /// The date/time of the Account’s last margin call extension.
474    #[serde(
475        rename = "lastMarginCallExtensionTime",
476        default,
477        skip_serializing_if = "Option::is_none"
478    )]
479    pub last_margin_call_extension_time: Option<Timestamp>,
480    /// The price-dependent state of each pending Order in the Account.
481    #[serde(rename = "orders", default, skip_serializing_if = "Option::is_none")]
482    pub orders: Option<Vec<DynamicOrderState>>,
483    /// The price-dependent state for each open Trade in the Account.
484    #[serde(rename = "trades", default, skip_serializing_if = "Option::is_none")]
485    pub trades: Option<Vec<CalculatedTradeState>>,
486    /// The price-dependent state for each open Position in the Account.
487    #[serde(rename = "positions", default, skip_serializing_if = "Option::is_none")]
488    pub positions: Option<Vec<CalculatedPositionState>>,
489}
490
491/// Properties related to an Account.
492#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
493#[serde(rename_all = "camelCase")]
494pub struct AccountProperties {
495    /// The Account’s identifier
496    #[serde(rename = "id", default, skip_serializing_if = "Option::is_none")]
497    pub id: Option<AccountID>,
498    /// The Account’s associated MT4 Account ID. This field will not be present if the Account is not an MT4
499    /// account.
500    #[serde(
501        rename = "mt4AccountID",
502        default,
503        skip_serializing_if = "Option::is_none"
504    )]
505    pub mt4_account_id: Option<i64>,
506    /// The Account’s tags
507    #[serde(rename = "tags", default, skip_serializing_if = "Option::is_none")]
508    pub tags: Option<Vec<String>>,
509}
510
511/// The current mutability and hedging settings related to guaranteed Stop Loss orders.
512#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
513#[serde(rename_all = "camelCase")]
514pub struct GuaranteedStopLossOrderParameters {
515    /// The current guaranteed Stop Loss Order mutability setting of the Account when market is open.
516    #[serde(
517        rename = "mutabilityMarketOpen",
518        default,
519        skip_serializing_if = "Option::is_none"
520    )]
521    pub mutability_market_open: Option<GuaranteedStopLossOrderMutability>,
522    /// The current guaranteed Stop Loss Order mutability setting of the Account when market is halted.
523    #[serde(
524        rename = "mutabilityMarketHalted",
525        default,
526        skip_serializing_if = "Option::is_none"
527    )]
528    pub mutability_market_halted: Option<GuaranteedStopLossOrderMutability>,
529}
530
531/// The overall behaviour of the Account regarding guaranteed Stop Loss Orders.
532#[derive(Debug, Clone, PartialEq, Eq, Hash)]
533#[non_exhaustive]
534pub enum GuaranteedStopLossOrderMode {
535    /// The Account is not permitted to create guaranteed Stop Loss Orders.
536    Disabled,
537    /// The Account is able, but not required to have guaranteed Stop Loss Orders for open Trades.
538    Allowed,
539    /// The Account is required to have guaranteed Stop Loss Orders for all open Trades.
540    Required,
541    /// An unrecognized provider value, preserved for forward compatibility.
542    Unknown(String),
543}
544
545impl GuaranteedStopLossOrderMode {
546    /// Return the exact provider spelling.
547    pub fn as_str(&self) -> &str {
548        match self {
549            Self::Disabled => "DISABLED",
550            Self::Allowed => "ALLOWED",
551            Self::Required => "REQUIRED",
552            Self::Unknown(value) => value,
553        }
554    }
555}
556
557impl Serialize for GuaranteedStopLossOrderMode {
558    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
559        serializer.serialize_str(self.as_str())
560    }
561}
562
563impl<'de> Deserialize<'de> for GuaranteedStopLossOrderMode {
564    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
565        let value = String::deserialize(deserializer)?;
566        Ok(match value.as_str() {
567            "DISABLED" => Self::Disabled,
568            "ALLOWED" => Self::Allowed,
569            "REQUIRED" => Self::Required,
570            _ => Self::Unknown(value),
571        })
572    }
573}
574
575/// For Accounts that support guaranteed Stop Loss Orders, describes the actions that can be performed on
576/// guaranteed Stop Loss Orders.
577#[derive(Debug, Clone, PartialEq, Eq, Hash)]
578#[non_exhaustive]
579pub enum GuaranteedStopLossOrderMutability {
580    /// Once a guaranteed Stop Loss Order has been created it cannot be replaced or cancelled.
581    Fixed,
582    /// An existing guaranteed Stop Loss Order can only be replaced, not cancelled.
583    Replaceable,
584    /// Once a guaranteed Stop Loss Order has been created it can be either replaced or cancelled.
585    Cancelable,
586    /// An existing guaranteed Stop Loss Order can only be replaced to widen the gap from the current price, not
587    /// cancelled.
588    PriceWidenOnly,
589    /// An unrecognized provider value, preserved for forward compatibility.
590    Unknown(String),
591}
592
593impl GuaranteedStopLossOrderMutability {
594    /// Return the exact provider spelling.
595    pub fn as_str(&self) -> &str {
596        match self {
597            Self::Fixed => "FIXED",
598            Self::Replaceable => "REPLACEABLE",
599            Self::Cancelable => "CANCELABLE",
600            Self::PriceWidenOnly => "PRICE_WIDEN_ONLY",
601            Self::Unknown(value) => value,
602        }
603    }
604}
605
606impl Serialize for GuaranteedStopLossOrderMutability {
607    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
608        serializer.serialize_str(self.as_str())
609    }
610}
611
612impl<'de> Deserialize<'de> for GuaranteedStopLossOrderMutability {
613    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
614        let value = String::deserialize(deserializer)?;
615        Ok(match value.as_str() {
616            "FIXED" => Self::Fixed,
617            "REPLACEABLE" => Self::Replaceable,
618            "CANCELABLE" => Self::Cancelable,
619            "PRICE_WIDEN_ONLY" => Self::PriceWidenOnly,
620            _ => Self::Unknown(value),
621        })
622    }
623}
624
625/// A summary representation of a client’s Account. The AccountSummary does not provide a full specification
626/// of pending Orders, open Trades and Positions.
627#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
628#[serde(rename_all = "camelCase")]
629pub struct AccountSummary {
630    /// The Account’s identifier
631    #[serde(rename = "id", default, skip_serializing_if = "Option::is_none")]
632    pub id: Option<AccountID>,
633    /// Client-assigned alias for the Account. Only provided if the Account has an alias set
634    #[serde(rename = "alias", default, skip_serializing_if = "Option::is_none")]
635    pub alias: Option<String>,
636    /// The home currency of the Account
637    #[serde(rename = "currency", default, skip_serializing_if = "Option::is_none")]
638    pub currency: Option<Currency>,
639    /// ID of the user that created the Account.
640    #[serde(
641        rename = "createdByUserID",
642        default,
643        skip_serializing_if = "Option::is_none"
644    )]
645    pub created_by_user_id: Option<i64>,
646    /// The date/time when the Account was created.
647    #[serde(
648        rename = "createdTime",
649        default,
650        skip_serializing_if = "Option::is_none"
651    )]
652    pub created_time: Option<Timestamp>,
653    /// The current guaranteed Stop Loss Order settings of the Account. This field will only be present if the
654    /// guaranteedStopLossOrderMode is not ‘DISABLED’.
655    #[serde(
656        rename = "guaranteedStopLossOrderParameters",
657        default,
658        skip_serializing_if = "Option::is_none"
659    )]
660    pub guaranteed_stop_loss_order_parameters: Option<GuaranteedStopLossOrderParameters>,
661    /// The current guaranteed Stop Loss Order mode of the Account.
662    #[serde(
663        rename = "guaranteedStopLossOrderMode",
664        default,
665        skip_serializing_if = "Option::is_none"
666    )]
667    pub guaranteed_stop_loss_order_mode: Option<GuaranteedStopLossOrderMode>,
668    /// The current guaranteed Stop Loss Order mutability setting of the Account. This field will only be
669    /// present if the guaranteedStopLossOrderMode is not ‘DISABLED’. Deprecated: Will be removed in a future
670    /// API update.
671    #[serde(
672        rename = "guaranteedStopLossOrderMutability",
673        default,
674        skip_serializing_if = "Option::is_none"
675    )]
676    pub guaranteed_stop_loss_order_mutability: Option<GuaranteedStopLossOrderMutability>,
677    /// The date/time that the Account’s resettablePL was last reset.
678    #[serde(
679        rename = "resettablePLTime",
680        default,
681        skip_serializing_if = "Option::is_none"
682    )]
683    pub resettable_pl_time: Option<Timestamp>,
684    /// Client-provided margin rate override for the Account. The effective margin rate of the Account is the
685    /// lesser of this value and the OANDA margin rate for the Account’s division. This value is only provided
686    /// if a margin rate override exists for the Account.
687    #[serde(
688        rename = "marginRate",
689        default,
690        skip_serializing_if = "Option::is_none"
691    )]
692    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
693    pub margin_rate: Option<Decimal>,
694    /// The number of Trades currently open in the Account.
695    #[serde(
696        rename = "openTradeCount",
697        default,
698        skip_serializing_if = "Option::is_none"
699    )]
700    pub open_trade_count: Option<i64>,
701    /// The number of Positions currently open in the Account.
702    #[serde(
703        rename = "openPositionCount",
704        default,
705        skip_serializing_if = "Option::is_none"
706    )]
707    pub open_position_count: Option<i64>,
708    /// The number of Orders currently pending in the Account.
709    #[serde(
710        rename = "pendingOrderCount",
711        default,
712        skip_serializing_if = "Option::is_none"
713    )]
714    pub pending_order_count: Option<i64>,
715    /// Flag indicating that the Account has hedging enabled.
716    #[serde(
717        rename = "hedgingEnabled",
718        default,
719        skip_serializing_if = "Option::is_none"
720    )]
721    pub hedging_enabled: Option<bool>,
722    /// The total unrealized profit/loss for all Trades currently open in the Account.
723    #[serde(
724        rename = "unrealizedPL",
725        default,
726        skip_serializing_if = "Option::is_none"
727    )]
728    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
729    pub unrealized_pl: Option<Decimal>,
730    /// The net asset value of the Account. Equal to Account balance + unrealizedPL.
731    #[serde(rename = "NAV", default, skip_serializing_if = "Option::is_none")]
732    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
733    pub nav: Option<Decimal>,
734    /// Margin currently used for the Account.
735    #[serde(
736        rename = "marginUsed",
737        default,
738        skip_serializing_if = "Option::is_none"
739    )]
740    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
741    pub margin_used: Option<Decimal>,
742    /// Margin available for Account currency.
743    #[serde(
744        rename = "marginAvailable",
745        default,
746        skip_serializing_if = "Option::is_none"
747    )]
748    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
749    pub margin_available: Option<Decimal>,
750    /// The value of the Account’s open positions represented in the Account’s home currency.
751    #[serde(
752        rename = "positionValue",
753        default,
754        skip_serializing_if = "Option::is_none"
755    )]
756    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
757    pub position_value: Option<Decimal>,
758    /// The Account’s margin closeout unrealized PL.
759    #[serde(
760        rename = "marginCloseoutUnrealizedPL",
761        default,
762        skip_serializing_if = "Option::is_none"
763    )]
764    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
765    pub margin_closeout_unrealized_pl: Option<Decimal>,
766    /// The Account’s margin closeout NAV.
767    #[serde(
768        rename = "marginCloseoutNAV",
769        default,
770        skip_serializing_if = "Option::is_none"
771    )]
772    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
773    pub margin_closeout_nav: Option<Decimal>,
774    /// The Account’s margin closeout margin used.
775    #[serde(
776        rename = "marginCloseoutMarginUsed",
777        default,
778        skip_serializing_if = "Option::is_none"
779    )]
780    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
781    pub margin_closeout_margin_used: Option<Decimal>,
782    /// The Account’s margin closeout percentage. When this value is 1.0 or above the Account is in a margin
783    /// closeout situation.
784    #[serde(
785        rename = "marginCloseoutPercent",
786        default,
787        skip_serializing_if = "Option::is_none"
788    )]
789    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
790    pub margin_closeout_percent: Option<Decimal>,
791    /// The value of the Account’s open positions as used for margin closeout calculations represented in the
792    /// Account’s home currency.
793    #[serde(
794        rename = "marginCloseoutPositionValue",
795        default,
796        skip_serializing_if = "Option::is_none"
797    )]
798    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
799    pub margin_closeout_position_value: Option<Decimal>,
800    /// The current WithdrawalLimit for the account which will be zero or a positive value indicating how much
801    /// can be withdrawn from the account.
802    #[serde(
803        rename = "withdrawalLimit",
804        default,
805        skip_serializing_if = "Option::is_none"
806    )]
807    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
808    pub withdrawal_limit: Option<Decimal>,
809    /// The Account’s margin call margin used.
810    #[serde(
811        rename = "marginCallMarginUsed",
812        default,
813        skip_serializing_if = "Option::is_none"
814    )]
815    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
816    pub margin_call_margin_used: Option<Decimal>,
817    /// The Account’s margin call percentage. When this value is 1.0 or above the Account is in a margin call
818    /// situation.
819    #[serde(
820        rename = "marginCallPercent",
821        default,
822        skip_serializing_if = "Option::is_none"
823    )]
824    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
825    pub margin_call_percent: Option<Decimal>,
826    /// The current balance of the account.
827    #[serde(rename = "balance", default, skip_serializing_if = "Option::is_none")]
828    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
829    pub balance: Option<Decimal>,
830    /// The total profit/loss realized over the lifetime of the Account.
831    #[serde(rename = "pl", default, skip_serializing_if = "Option::is_none")]
832    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
833    pub pl: Option<Decimal>,
834    /// The total realized profit/loss for the account since it was last reset by the client.
835    #[serde(
836        rename = "resettablePL",
837        default,
838        skip_serializing_if = "Option::is_none"
839    )]
840    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
841    pub resettable_pl: Option<Decimal>,
842    /// The total amount of financing paid/collected over the lifetime of the account.
843    #[serde(rename = "financing", default, skip_serializing_if = "Option::is_none")]
844    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
845    pub financing: Option<Decimal>,
846    /// The total amount of commission paid over the lifetime of the Account.
847    #[serde(
848        rename = "commission",
849        default,
850        skip_serializing_if = "Option::is_none"
851    )]
852    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
853    pub commission: Option<Decimal>,
854    /// The total amount of dividend adjustment paid over the lifetime of the Account in the Account’s home
855    /// currency.
856    #[serde(
857        rename = "dividendAdjustment",
858        default,
859        skip_serializing_if = "Option::is_none"
860    )]
861    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
862    pub dividend_adjustment: Option<Decimal>,
863    /// The total amount of fees charged over the lifetime of the Account for the execution of guaranteed Stop
864    /// Loss Orders.
865    #[serde(
866        rename = "guaranteedExecutionFees",
867        default,
868        skip_serializing_if = "Option::is_none"
869    )]
870    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
871    pub guaranteed_execution_fees: Option<Decimal>,
872    /// The date/time when the Account entered a margin call state. Only provided if the Account is in a margin
873    /// call.
874    #[serde(
875        rename = "marginCallEnterTime",
876        default,
877        skip_serializing_if = "Option::is_none"
878    )]
879    pub margin_call_enter_time: Option<Timestamp>,
880    /// The number of times that the Account’s current margin call was extended.
881    #[serde(
882        rename = "marginCallExtensionCount",
883        default,
884        skip_serializing_if = "Option::is_none"
885    )]
886    pub margin_call_extension_count: Option<i64>,
887    /// The date/time of the Account’s last margin call extension.
888    #[serde(
889        rename = "lastMarginCallExtensionTime",
890        default,
891        skip_serializing_if = "Option::is_none"
892    )]
893    pub last_margin_call_extension_time: Option<Timestamp>,
894    /// The ID of the last Transaction created for the Account.
895    #[serde(
896        rename = "lastTransactionID",
897        default,
898        skip_serializing_if = "Option::is_none"
899    )]
900    pub last_transaction_id: Option<TransactionID>,
901}
902
903/// The mutable state of a client’s Account.
904#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
905#[serde(rename_all = "camelCase")]
906pub struct AccumulatedAccountState {
907    /// The current balance of the account.
908    #[serde(rename = "balance", default, skip_serializing_if = "Option::is_none")]
909    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
910    pub balance: Option<Decimal>,
911    /// The total profit/loss realized over the lifetime of the Account.
912    #[serde(rename = "pl", default, skip_serializing_if = "Option::is_none")]
913    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
914    pub pl: Option<Decimal>,
915    /// The total realized profit/loss for the account since it was last reset by the client.
916    #[serde(
917        rename = "resettablePL",
918        default,
919        skip_serializing_if = "Option::is_none"
920    )]
921    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
922    pub resettable_pl: Option<Decimal>,
923    /// The total amount of financing paid/collected over the lifetime of the account.
924    #[serde(rename = "financing", default, skip_serializing_if = "Option::is_none")]
925    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
926    pub financing: Option<Decimal>,
927    /// The total amount of commission paid over the lifetime of the Account.
928    #[serde(
929        rename = "commission",
930        default,
931        skip_serializing_if = "Option::is_none"
932    )]
933    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
934    pub commission: Option<Decimal>,
935    /// The total amount of dividend adjustment paid over the lifetime of the Account in the Account’s home
936    /// currency.
937    #[serde(
938        rename = "dividendAdjustment",
939        default,
940        skip_serializing_if = "Option::is_none"
941    )]
942    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
943    pub dividend_adjustment: Option<Decimal>,
944    /// The total amount of fees charged over the lifetime of the Account for the execution of guaranteed Stop
945    /// Loss Orders.
946    #[serde(
947        rename = "guaranteedExecutionFees",
948        default,
949        skip_serializing_if = "Option::is_none"
950    )]
951    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
952    pub guaranteed_execution_fees: Option<Decimal>,
953    /// The date/time when the Account entered a margin call state. Only provided if the Account is in a margin
954    /// call.
955    #[serde(
956        rename = "marginCallEnterTime",
957        default,
958        skip_serializing_if = "Option::is_none"
959    )]
960    pub margin_call_enter_time: Option<Timestamp>,
961    /// The number of times that the Account’s current margin call was extended.
962    #[serde(
963        rename = "marginCallExtensionCount",
964        default,
965        skip_serializing_if = "Option::is_none"
966    )]
967    pub margin_call_extension_count: Option<i64>,
968    /// The date/time of the Account’s last margin call extension.
969    #[serde(
970        rename = "lastMarginCallExtensionTime",
971        default,
972        skip_serializing_if = "Option::is_none"
973    )]
974    pub last_margin_call_extension_time: Option<Timestamp>,
975}
976
977/// The dynamically calculated state of a client’s Account.
978#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
979#[serde(rename_all = "camelCase")]
980pub struct CalculatedAccountState {
981    /// The total unrealized profit/loss for all Trades currently open in the Account.
982    #[serde(
983        rename = "unrealizedPL",
984        default,
985        skip_serializing_if = "Option::is_none"
986    )]
987    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
988    pub unrealized_pl: Option<Decimal>,
989    /// The net asset value of the Account. Equal to Account balance + unrealizedPL.
990    #[serde(rename = "NAV", default, skip_serializing_if = "Option::is_none")]
991    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
992    pub nav: Option<Decimal>,
993    /// Margin currently used for the Account.
994    #[serde(
995        rename = "marginUsed",
996        default,
997        skip_serializing_if = "Option::is_none"
998    )]
999    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
1000    pub margin_used: Option<Decimal>,
1001    /// Margin available for Account currency.
1002    #[serde(
1003        rename = "marginAvailable",
1004        default,
1005        skip_serializing_if = "Option::is_none"
1006    )]
1007    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
1008    pub margin_available: Option<Decimal>,
1009    /// The value of the Account’s open positions represented in the Account’s home currency.
1010    #[serde(
1011        rename = "positionValue",
1012        default,
1013        skip_serializing_if = "Option::is_none"
1014    )]
1015    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
1016    pub position_value: Option<Decimal>,
1017    /// The Account’s margin closeout unrealized PL.
1018    #[serde(
1019        rename = "marginCloseoutUnrealizedPL",
1020        default,
1021        skip_serializing_if = "Option::is_none"
1022    )]
1023    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
1024    pub margin_closeout_unrealized_pl: Option<Decimal>,
1025    /// The Account’s margin closeout NAV.
1026    #[serde(
1027        rename = "marginCloseoutNAV",
1028        default,
1029        skip_serializing_if = "Option::is_none"
1030    )]
1031    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
1032    pub margin_closeout_nav: Option<Decimal>,
1033    /// The Account’s margin closeout margin used.
1034    #[serde(
1035        rename = "marginCloseoutMarginUsed",
1036        default,
1037        skip_serializing_if = "Option::is_none"
1038    )]
1039    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
1040    pub margin_closeout_margin_used: Option<Decimal>,
1041    /// The Account’s margin closeout percentage. When this value is 1.0 or above the Account is in a margin
1042    /// closeout situation.
1043    #[serde(
1044        rename = "marginCloseoutPercent",
1045        default,
1046        skip_serializing_if = "Option::is_none"
1047    )]
1048    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
1049    pub margin_closeout_percent: Option<Decimal>,
1050    /// The value of the Account’s open positions as used for margin closeout calculations represented in the
1051    /// Account’s home currency.
1052    #[serde(
1053        rename = "marginCloseoutPositionValue",
1054        default,
1055        skip_serializing_if = "Option::is_none"
1056    )]
1057    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
1058    pub margin_closeout_position_value: Option<Decimal>,
1059    /// The current WithdrawalLimit for the account which will be zero or a positive value indicating how much
1060    /// can be withdrawn from the account.
1061    #[serde(
1062        rename = "withdrawalLimit",
1063        default,
1064        skip_serializing_if = "Option::is_none"
1065    )]
1066    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
1067    pub withdrawal_limit: Option<Decimal>,
1068    /// The Account’s margin call margin used.
1069    #[serde(
1070        rename = "marginCallMarginUsed",
1071        default,
1072        skip_serializing_if = "Option::is_none"
1073    )]
1074    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
1075    pub margin_call_margin_used: Option<Decimal>,
1076    /// The Account’s margin call percentage. When this value is 1.0 or above the Account is in a margin call
1077    /// situation.
1078    #[serde(
1079        rename = "marginCallPercent",
1080        default,
1081        skip_serializing_if = "Option::is_none"
1082    )]
1083    #[serde(deserialize_with = "crate::decimal_wire::optional_number_or_string")]
1084    pub margin_call_percent: Option<Decimal>,
1085}
1086
1087/// An AccountChanges Object is used to represent the changes to an Account’s Orders, Trades and Positions
1088/// since a specified Account TransactionID in the past.
1089#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1090#[serde(rename_all = "camelCase")]
1091pub struct AccountChanges {
1092    /// The Orders created. These Orders may have been filled, cancelled or triggered in the same period.
1093    #[serde(
1094        rename = "ordersCreated",
1095        default,
1096        skip_serializing_if = "Option::is_none"
1097    )]
1098    pub orders_created: Option<Vec<Order>>,
1099    /// The Orders cancelled.
1100    #[serde(
1101        rename = "ordersCancelled",
1102        default,
1103        skip_serializing_if = "Option::is_none"
1104    )]
1105    pub orders_cancelled: Option<Vec<Order>>,
1106    /// The Orders filled.
1107    #[serde(
1108        rename = "ordersFilled",
1109        default,
1110        skip_serializing_if = "Option::is_none"
1111    )]
1112    pub orders_filled: Option<Vec<Order>>,
1113    /// The Orders triggered.
1114    #[serde(
1115        rename = "ordersTriggered",
1116        default,
1117        skip_serializing_if = "Option::is_none"
1118    )]
1119    pub orders_triggered: Option<Vec<Order>>,
1120    /// The Trades opened.
1121    #[serde(
1122        rename = "tradesOpened",
1123        default,
1124        skip_serializing_if = "Option::is_none"
1125    )]
1126    pub trades_opened: Option<Vec<TradeSummary>>,
1127    /// The Trades reduced.
1128    #[serde(
1129        rename = "tradesReduced",
1130        default,
1131        skip_serializing_if = "Option::is_none"
1132    )]
1133    pub trades_reduced: Option<Vec<TradeSummary>>,
1134    /// The Trades closed.
1135    #[serde(
1136        rename = "tradesClosed",
1137        default,
1138        skip_serializing_if = "Option::is_none"
1139    )]
1140    pub trades_closed: Option<Vec<TradeSummary>>,
1141    /// The Positions changed.
1142    #[serde(rename = "positions", default, skip_serializing_if = "Option::is_none")]
1143    pub positions: Option<Vec<Position>>,
1144    /// The Transactions that have been generated.
1145    #[serde(
1146        rename = "transactions",
1147        default,
1148        skip_serializing_if = "Option::is_none"
1149    )]
1150    pub transactions: Option<Vec<Transaction>>,
1151}
1152
1153/// The financing mode of an Account
1154#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1155#[non_exhaustive]
1156pub enum AccountFinancingMode {
1157    /// No financing is paid/charged for open Trades in the Account
1158    NoFinancing,
1159    /// Second-by-second financing is paid/charged for open Trades in the Account, both daily and when the the
1160    /// Trade is closed
1161    SecondBySecond,
1162    /// A full day’s worth of financing is paid/charged for open Trades in the Account daily at 5pm New York time
1163    Daily,
1164    /// An unrecognized provider value, preserved for forward compatibility.
1165    Unknown(String),
1166}
1167
1168impl AccountFinancingMode {
1169    /// Return the exact provider spelling.
1170    pub fn as_str(&self) -> &str {
1171        match self {
1172            Self::NoFinancing => "NO_FINANCING",
1173            Self::SecondBySecond => "SECOND_BY_SECOND",
1174            Self::Daily => "DAILY",
1175            Self::Unknown(value) => value,
1176        }
1177    }
1178}
1179
1180impl Serialize for AccountFinancingMode {
1181    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1182        serializer.serialize_str(self.as_str())
1183    }
1184}
1185
1186impl<'de> Deserialize<'de> for AccountFinancingMode {
1187    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1188        let value = String::deserialize(deserializer)?;
1189        Ok(match value.as_str() {
1190            "NO_FINANCING" => Self::NoFinancing,
1191            "SECOND_BY_SECOND" => Self::SecondBySecond,
1192            "DAILY" => Self::Daily,
1193            _ => Self::Unknown(value),
1194        })
1195    }
1196}
1197
1198/// Contains the attributes of a user.
1199#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1200#[serde(rename_all = "camelCase")]
1201pub struct UserAttributes {
1202    /// The user’s OANDA-assigned user ID.
1203    #[serde(rename = "userID", default, skip_serializing_if = "Option::is_none")]
1204    pub user_id: Option<i64>,
1205    /// The user-provided username.
1206    #[serde(rename = "username", default, skip_serializing_if = "Option::is_none")]
1207    pub username: Option<String>,
1208    /// The user’s title.
1209    #[serde(rename = "title", default, skip_serializing_if = "Option::is_none")]
1210    pub title: Option<String>,
1211    /// The user’s name.
1212    #[serde(rename = "name", default, skip_serializing_if = "Option::is_none")]
1213    pub name: Option<String>,
1214    /// The user’s email address.
1215    #[serde(rename = "email", default, skip_serializing_if = "Option::is_none")]
1216    pub email: Option<String>,
1217    /// The OANDA division the user belongs to.
1218    #[serde(
1219        rename = "divisionAbbreviation",
1220        default,
1221        skip_serializing_if = "Option::is_none"
1222    )]
1223    pub division_abbreviation: Option<String>,
1224    /// The user’s preferred language.
1225    #[serde(
1226        rename = "languageAbbreviation",
1227        default,
1228        skip_serializing_if = "Option::is_none"
1229    )]
1230    pub language_abbreviation: Option<String>,
1231    /// The home currency of the Account.
1232    #[serde(
1233        rename = "homeCurrency",
1234        default,
1235        skip_serializing_if = "Option::is_none"
1236    )]
1237    pub home_currency: Option<Currency>,
1238}
1239
1240/// The way that position values for an Account are calculated and aggregated.
1241#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1242#[non_exhaustive]
1243pub enum PositionAggregationMode {
1244    /// The Position value or margin for each side (long and short) of the Position are computed independently
1245    /// and added together.
1246    AbsoluteSum,
1247    /// The Position value or margin for each side (long and short) of the Position are computed independently.
1248    /// The Position value or margin chosen is the maximal absolute value of the two.
1249    MaximalSide,
1250    /// The units for each side (long and short) of the Position are netted together and the resulting value
1251    /// (long or short) is used to compute the Position value or margin.
1252    NetSum,
1253    /// An unrecognized provider value, preserved for forward compatibility.
1254    Unknown(String),
1255}
1256
1257impl PositionAggregationMode {
1258    /// Return the exact provider spelling.
1259    pub fn as_str(&self) -> &str {
1260        match self {
1261            Self::AbsoluteSum => "ABSOLUTE_SUM",
1262            Self::MaximalSide => "MAXIMAL_SIDE",
1263            Self::NetSum => "NET_SUM",
1264            Self::Unknown(value) => value,
1265        }
1266    }
1267}
1268
1269impl Serialize for PositionAggregationMode {
1270    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1271        serializer.serialize_str(self.as_str())
1272    }
1273}
1274
1275impl<'de> Deserialize<'de> for PositionAggregationMode {
1276    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1277        let value = String::deserialize(deserializer)?;
1278        Ok(match value.as_str() {
1279            "ABSOLUTE_SUM" => Self::AbsoluteSum,
1280            "MAXIMAL_SIDE" => Self::MaximalSide,
1281            "NET_SUM" => Self::NetSum,
1282            _ => Self::Unknown(value),
1283        })
1284    }
1285}