Skip to main content

rust_okx/ws/model/
account.rs

1//! Trading account channel models (`account`, `positions`, `balance_and_position`, etc.).
2//!
3//! Private channels; login required.
4
5use serde::Deserialize;
6
7use super::ExtraFields;
8use crate::model::NumberString;
9
10/// A close-order algo attached to a position.
11///
12/// Populated in [`PositionUpdate::close_order_algo`] when a close-position
13/// algo order (placed with `closeFraction=1`) is associated with the position.
14///
15/// OKX docs: <https://www.okx.com/docs-v5/en/#trading-account-websocket-positions-channel>
16#[derive(Debug, Clone, Default, Deserialize)]
17#[serde(rename_all = "camelCase")]
18#[non_exhaustive]
19pub struct CloseOrderAlgo {
20    /// Algo order ID.
21    #[serde(default)]
22    pub algo_id: String,
23    /// Stop-loss trigger price.
24    #[serde(default)]
25    pub sl_trigger_px: String,
26    /// Stop-loss trigger price type: `last`, `index`, or `mark`.
27    #[serde(default)]
28    pub sl_trigger_px_type: String,
29    /// Take-profit trigger price.
30    #[serde(default)]
31    pub tp_trigger_px: String,
32    /// Take-profit trigger price type: `last`, `index`, or `mark`.
33    #[serde(default)]
34    pub tp_trigger_px_type: String,
35    /// Fraction of the position to close when the algo is triggered (e.g. `"0.6"`).
36    #[serde(default)]
37    pub close_fraction: String,
38}
39
40/// Private `positions` channel row.
41///
42/// OKX docs: <https://www.okx.com/docs-v5/en/#trading-account-websocket-positions-channel>
43#[derive(Debug, Clone, Default, Deserialize)]
44#[serde(rename_all = "camelCase")]
45#[non_exhaustive]
46pub struct PositionUpdate {
47    /// Instrument type, e.g., `MARGIN`, `SWAP`, `FUTURES`, `OPTION`.
48    #[serde(default)]
49    pub inst_type: String,
50    /// Margin mode: `cross` or `isolated`.
51    #[serde(default)]
52    pub mgn_mode: String,
53    /// OKX-assigned position ID.
54    #[serde(default)]
55    pub pos_id: String,
56    /// Position side: `long`, `short`, or `net`.
57    #[serde(default)]
58    pub pos_side: String,
59    /// Position quantity (contracts for derivatives; base currency for margin).
60    #[serde(default)]
61    pub pos: NumberString,
62    /// Position currency (base currency for MARGIN positions only).
63    #[serde(default)]
64    pub pos_ccy: String,
65    /// Available position (not frozen by closing orders).
66    #[serde(default)]
67    pub avail_pos: NumberString,
68    /// Average entry price of the position.
69    #[serde(default)]
70    pub avg_px: NumberString,
71    /// Non-settlement average entry price (cross FUTURES only).
72    #[serde(default)]
73    pub non_settle_avg_px: NumberString,
74    /// Unrealized profit and loss.
75    #[serde(default)]
76    pub upl: NumberString,
77    /// Unrealized profit and loss ratio.
78    #[serde(default)]
79    pub upl_ratio: NumberString,
80    /// Unrealized PnL calculated using the last traded price.
81    #[serde(default)]
82    pub upl_last_px: NumberString,
83    /// Unrealized PnL ratio calculated using the last traded price.
84    #[serde(default)]
85    pub upl_ratio_last_px: NumberString,
86    /// Leverage.
87    #[serde(default)]
88    pub lever: NumberString,
89    /// Estimated liquidation price.
90    #[serde(default)]
91    pub liq_px: NumberString,
92    /// Mark price.
93    #[serde(default)]
94    pub mark_px: NumberString,
95    /// Initial margin requirement in USD.
96    #[serde(default)]
97    pub imr: NumberString,
98    /// Margin balance (isolated mode only).
99    #[serde(default)]
100    pub margin: NumberString,
101    /// Margin ratio.
102    #[serde(default)]
103    pub mgn_ratio: NumberString,
104    /// Maintenance margin requirement in USD.
105    #[serde(default)]
106    pub mmr: NumberString,
107    /// Liabilities of the position (for cross-margin positions).
108    #[serde(default)]
109    pub liab: NumberString,
110    /// Liability currency.
111    #[serde(default)]
112    pub liab_ccy: String,
113    /// Accrued interest.
114    #[serde(default)]
115    pub interest: NumberString,
116    /// USD price of the instrument's settlement currency.
117    #[serde(default)]
118    pub usd_px: NumberString,
119    /// Quantity of base currency hedged via spot (Portfolio margin mode only).
120    #[serde(default)]
121    pub hedged_pos: NumberString,
122    /// Trade ID of the most recent fill for this position.
123    #[serde(default)]
124    pub trade_id: String,
125    /// Options value in USD (options positions only).
126    #[serde(default)]
127    pub opt_val: NumberString,
128    /// Pending closing-order liability value.
129    #[serde(default)]
130    pub pending_close_ord_liab_val: NumberString,
131    /// Notional value of the position in USD.
132    #[serde(default)]
133    pub notional_usd: NumberString,
134    /// Auto-deleveraging (ADL) indicator level (1–5); higher means higher ADL risk.
135    #[serde(default)]
136    pub adl: String,
137    /// Settlement or margin currency of the position.
138    #[serde(default)]
139    pub ccy: String,
140    /// Last traded price.
141    #[serde(default)]
142    pub last: NumberString,
143    /// Index price.
144    #[serde(default)]
145    pub idx_px: NumberString,
146    /// Breakeven price.
147    #[serde(default)]
148    pub be_px: NumberString,
149    /// Black-Scholes delta (options only).
150    #[serde(default)]
151    pub delta_bs: NumberString,
152    /// PA delta (options only).
153    #[serde(default)]
154    pub delta_pa: NumberString,
155    /// Black-Scholes gamma (options only).
156    #[serde(default)]
157    pub gamma_bs: NumberString,
158    /// PA gamma (options only).
159    #[serde(default)]
160    pub gamma_pa: NumberString,
161    /// Black-Scholes theta (options only).
162    #[serde(default)]
163    pub theta_bs: NumberString,
164    /// PA theta (options only).
165    #[serde(default)]
166    pub theta_pa: NumberString,
167    /// Black-Scholes vega (options only).
168    #[serde(default)]
169    pub vega_bs: NumberString,
170    /// PA vega (options only).
171    #[serde(default)]
172    pub vega_pa: NumberString,
173    /// Spot quantity used for hedging (Portfolio margin mode only).
174    #[serde(default)]
175    pub spot_in_use_amt: NumberString,
176    /// Currency of the spot hedge quantity.
177    #[serde(default)]
178    pub spot_in_use_ccy: String,
179    /// User-defined spot hedge amount.
180    #[serde(default)]
181    pub cl_spot_in_use_amt: NumberString,
182    /// Maximum spot hedge amount calculated by OKX.
183    #[serde(default)]
184    pub max_spot_in_use_amt: NumberString,
185    /// External business reference ID (e.g., copy-trading).
186    #[serde(default)]
187    pub biz_ref_id: String,
188    /// External business reference type.
189    #[serde(default)]
190    pub biz_ref_type: String,
191    /// Instrument ID, e.g., `BTC-USDT-SWAP`.
192    #[serde(default)]
193    pub inst_id: String,
194    /// Position creation time (Unix milliseconds).
195    #[serde(default)]
196    pub c_time: NumberString,
197    /// Last update time (Unix milliseconds).
198    #[serde(default)]
199    pub u_time: NumberString,
200    /// Push time (Unix milliseconds).
201    #[serde(default)]
202    pub p_time: NumberString,
203    /// Realized profit and loss.
204    ///
205    /// `realizedPnl = pnl + fee + fundingFee + liqPenalty + settledPnl`
206    ///
207    /// Only applicable to FUTURES/SWAP/OPTION.
208    #[serde(default)]
209    pub realized_pnl: NumberString,
210    /// Accumulated PnL from closing orders, excluding fees.
211    #[serde(default)]
212    pub pnl: NumberString,
213    /// Accumulated transaction fee. Negative = fee charged; positive = rebate.
214    #[serde(default)]
215    pub fee: NumberString,
216    /// Accumulated funding fee.
217    #[serde(default)]
218    pub funding_fee: NumberString,
219    /// Accumulated liquidation penalty (negative when non-zero).
220    #[serde(default)]
221    pub liq_penalty: NumberString,
222    /// Accumulated settled P&L calculated by settlement price.
223    ///
224    /// Only applicable to cross FUTURES.
225    #[serde(default)]
226    pub settled_pnl: NumberString,
227    /// Close-position algo orders attached to this position.
228    ///
229    /// Non-empty only after placing an algo order with `closeFraction=1`.
230    #[serde(default)]
231    pub close_order_algo: Vec<CloseOrderAlgo>,
232    /// Unrecognized fields retained for forward compatibility.
233    #[serde(flatten, default)]
234    pub extra: ExtraFields,
235}
236
237/// A data row pushed by the private `balance_and_position` WebSocket channel.
238///
239/// This channel provides near-real-time updates for account cash balances and
240/// positions. Updates may be triggered by events such as:
241///
242/// - order fills;
243/// - funding transfers;
244/// - delivery or exercise;
245/// - liquidation or ADL;
246/// - funding-fee deductions;
247/// - margin or leverage adjustments.
248///
249/// A push may contain only [`BalanceAndPositionUpdate::bal_data`] when only a
250/// balance changes, or only [`BalanceAndPositionUpdate::pos_data`] when only a
251/// position changes.
252///
253/// During the initial snapshot, OKX only pushes:
254///
255/// - currencies whose cash balance is non-zero;
256/// - positions whose quantity is non-zero.
257///
258/// OKX docs:
259/// <https://www.okx.com/docs-v5/en/#trading-account-websocket-balance-and-position-channel>
260#[derive(Debug, Clone, Default, Deserialize)]
261#[serde(rename_all = "camelCase")]
262#[non_exhaustive]
263pub struct BalanceAndPositionUpdate {
264    /// Push time of the balance and position information.
265    ///
266    /// Unix timestamp in milliseconds, for example `1597026383085`.
267    #[serde(default)]
268    pub p_time: NumberString,
269
270    /// Event that caused this update.
271    ///
272    /// - Typical values include:
273    ///   `delivered`, `exercised`, `transferred`, `filled`, `liquidation`
274    ///   `claw_back`, `adl`, `funding_fee`, `adjust_margin`,`set_leverage`
275    ///   `interest_deduction`, `settlement`
276    pub event_type: String,
277
278    /// Updated account cash-balance records.
279    ///
280    /// This array may be empty when the push only contains position changes.
281    #[serde(default)]
282    pub bal_data: Vec<BalData>,
283
284    /// Updated position records.
285    ///
286    /// This array may be empty when the push only contains balance changes.
287    #[serde(default)]
288    pub pos_data: Vec<PosData>,
289
290    /// Trades associated with the balance or position update.
291    #[serde(default)]
292    pub trades: Vec<Trade>,
293
294    /// Additional fields added by OKX that are not yet represented explicitly.
295    #[serde(flatten, default)]
296    pub extra: ExtraFields,
297}
298
299/// A currency-balance record from the `balData` array.
300///
301/// OKX docs:
302/// <https://www.okx.com/docs-v5/en/#trading-account-websocket-balance-and-position-channel>
303#[derive(Debug, Clone, Default, Deserialize)]
304#[serde(rename_all = "camelCase")]
305#[non_exhaustive]
306pub struct BalData {
307    /// Currency code, for example `BTC` or `USDT`.
308    #[serde(default)]
309    pub ccy: String,
310
311    /// Cash balance of the currency.
312    ///
313    /// OKX returns numeric values as JSON strings.
314    #[serde(default)]
315    pub cash_bal: NumberString,
316
317    /// Time when this currency balance was last updated.
318    ///
319    /// Unix timestamp in milliseconds, for example `1597026383085`.
320    #[serde(default)]
321    pub u_time: NumberString,
322
323    /// Additional fields added by OKX that are not yet represented explicitly.
324    #[serde(flatten, default)]
325    pub extra: ExtraFields,
326}
327
328/// A position record from the `posData` array.
329///
330/// OKX docs:
331/// <https://www.okx.com/docs-v5/en/#trading-account-websocket-balance-and-position-channel>
332#[derive(Debug, Clone, Default, Deserialize)]
333#[serde(rename_all = "camelCase")]
334#[non_exhaustive]
335pub struct PosData {
336    /// Position ID assigned by OKX.
337    #[serde(default)]
338    pub pos_id: String,
339
340    /// ID of the latest trade associated with the position.
341    ///
342    /// Trade IDs should be treated as opaque identifiers rather than numeric
343    /// values.
344    #[serde(default)]
345    pub trade_id: String,
346
347    /// Instrument ID, for example `BTC-USDT-SWAP`.
348    #[serde(default)]
349    pub inst_id: String,
350
351    /// Instrument type.
352    ///
353    /// Typical values include:
354    ///
355    /// - `MARGIN`;
356    /// - `SWAP`;
357    /// - `FUTURES`;
358    /// - `OPTION`.
359    #[serde(default)]
360    pub inst_type: String,
361
362    /// Margin mode.
363    ///
364    /// Possible values:
365    ///
366    /// - `cross`;
367    /// - `isolated`.
368    #[serde(default)]
369    pub mgn_mode: String,
370
371    /// Position side.
372    ///
373    /// Possible values:
374    ///
375    /// - `long`: long side in long/short mode;
376    /// - `short`: short side in long/short mode;
377    /// - `net`: net position mode.
378    #[serde(default)]
379    pub pos_side: String,
380
381    /// Position quantity.
382    ///
383    /// For derivatives, the unit is normally the number of contracts.
384    ///
385    /// In isolated margin mode, OKX may push a position whose quantity is `0`
386    /// after a manual margin transfer.
387    #[serde(default)]
388    pub pos: NumberString,
389
390    /// Currency used for margin.
391    #[serde(default)]
392    pub ccy: String,
393
394    /// Position currency.
395    ///
396    /// Only applicable to `MARGIN` positions.
397    #[serde(default)]
398    pub pos_ccy: String,
399
400    /// Average entry price of the position.
401    #[serde(default)]
402    pub avg_px: NumberString,
403
404    /// Non-settlement entry price.
405    ///
406    /// This value only reflects the average price at which the position was
407    /// opened or increased.
408    ///
409    /// Only applicable to cross-margin `FUTURES` positions.
410    #[serde(default)]
411    pub non_settle_avg_px: String,
412
413    /// Accumulated settled profit and loss calculated using settlement prices.
414    ///
415    /// Only applicable to cross-margin `FUTURES` positions.
416    #[serde(default)]
417    pub settled_pnl: String,
418
419    /// Time when the position was last updated.
420    ///
421    /// Unix timestamp in milliseconds, for example `1597026383085`.
422    #[serde(default)]
423    pub u_time: NumberString,
424
425    /// Additional fields added by OKX that are not yet represented explicitly.
426    #[serde(flatten, default)]
427    pub extra: ExtraFields,
428}
429
430/// A trade associated with a balance or position update.
431///
432/// The `trades` array identifies fills related to the pushed balance or
433/// position change.
434///
435/// OKX docs:
436/// <https://www.okx.com/docs-v5/en/#trading-account-websocket-balance-and-position-channel>
437#[derive(Debug, Clone, Default, Deserialize)]
438#[serde(rename_all = "camelCase")]
439#[non_exhaustive]
440pub struct Trade {
441    /// Instrument ID, for example `BTC-USDT` or `BTC-USDT-SWAP`.
442    #[serde(default)]
443    pub inst_id: String,
444
445    /// Trade ID assigned by OKX.
446    ///
447    /// This value should be treated as an opaque identifier.
448    #[serde(default)]
449    pub trade_id: String,
450
451    /// Additional fields added by OKX that are not yet represented explicitly.
452    #[serde(flatten, default)]
453    pub extra: ExtraFields,
454}
455
456/// Private `liquidation-warning` channel row.
457///
458/// OKX docs: <https://www.okx.com/docs-v5/en/#trading-account-websocket-liquidation-warning-channel>
459#[derive(Debug, Clone, Default, Deserialize)]
460#[serde(rename_all = "camelCase")]
461#[non_exhaustive]
462pub struct LiquidationWarningUpdate {
463    /// Instrument type, e.g., `MARGIN`, `SWAP`, `FUTURES`, `OPTION`.
464    #[serde(default)]
465    pub inst_type: String,
466    /// Instrument ID, e.g., `BTC-USDT-SWAP`.
467    #[serde(default)]
468    pub inst_id: String,
469    /// Position side: `long`, `short`, or `net`.
470    #[serde(default)]
471    pub pos_side: String,
472    /// Position quantity (contracts for derivatives).
473    #[serde(default)]
474    pub pos: NumberString,
475    /// Margin mode: `cross` or `isolated`.
476    #[serde(default)]
477    pub mgn_mode: String,
478    /// Current margin ratio; liquidation is triggered when this reaches 1.
479    #[serde(default)]
480    pub mgn_ratio: NumberString,
481    /// Current mark price.
482    #[serde(default)]
483    pub mark_px: NumberString,
484    /// Estimated liquidation price.
485    #[serde(default)]
486    pub liq_px: NumberString,
487    /// Settlement or margin currency.
488    #[serde(default)]
489    pub ccy: String,
490    /// Last update time (Unix milliseconds).
491    #[serde(default)]
492    pub u_time: NumberString,
493    /// Push time (Unix milliseconds).
494    #[serde(default)]
495    pub p_time: NumberString,
496    /// Unrecognized fields retained for forward compatibility.
497    #[serde(flatten, default)]
498    pub extra: ExtraFields,
499}
500
501/// Private `account-greeks` channel row.
502///
503/// OKX docs: <https://www.okx.com/docs-v5/en/#trading-account-websocket-account-greeks-channel>
504#[derive(Debug, Clone, Default, Deserialize)]
505#[serde(rename_all = "camelCase")]
506#[non_exhaustive]
507pub struct AccountGreeksUpdate {
508    /// Currency denominating the greeks, e.g., `BTC`.
509    #[serde(default)]
510    pub ccy: String,
511    /// Account-level Black-Scholes delta in this currency.
512    #[serde(default)]
513    pub delta_bs: NumberString,
514    /// Account-level PA delta in this currency.
515    #[serde(default)]
516    pub delta_pa: NumberString,
517    /// Account-level Black-Scholes gamma in this currency.
518    #[serde(default)]
519    pub gamma_bs: NumberString,
520    /// Account-level PA gamma in this currency.
521    #[serde(default)]
522    pub gamma_pa: NumberString,
523    /// Account-level Black-Scholes theta in this currency.
524    #[serde(default)]
525    pub theta_bs: NumberString,
526    /// Account-level PA theta in this currency.
527    #[serde(default)]
528    pub theta_pa: NumberString,
529    /// Account-level Black-Scholes vega in this currency.
530    #[serde(default)]
531    pub vega_bs: NumberString,
532    /// Account-level PA vega in this currency.
533    #[serde(default)]
534    pub vega_pa: NumberString,
535    /// Push time (Unix milliseconds).
536    #[serde(default)]
537    pub ts: NumberString,
538    /// Unrecognized fields retained for forward compatibility.
539    #[serde(flatten, default)]
540    pub extra: ExtraFields,
541}
542
543/// Account data row pushed by the private `account` WebSocket channel.
544///
545/// The account channel provides account-level equity, margin requirements,
546/// liabilities, notional values, risk indicators, and detailed per-currency
547/// balances.
548///
549/// OKX may push account information:
550///
551/// - after account-related events, such as order placement, cancellation or
552///   execution;
553/// - at regular intervals;
554/// - as an initial paginated snapshot.
555///
556/// Only currencies with a non-zero `eq`, `availEq`, or `availBal` are included
557/// in the initial and regular snapshots.
558///
559/// The outer WebSocket message fields `curPage` and `lastPage`
560/// are not part of this structure. They belong to the WebSocket push envelope.
561///
562/// OKX docs:
563/// <https://www.okx.com/docs-v5/en/#trading-account-websocket-account-channel>
564#[derive(Debug, Clone, Default, Deserialize)]
565#[serde(rename_all = "camelCase")]
566#[non_exhaustive]
567pub struct AccountUpdate {
568    /// Adjusted or effective account equity denominated in USD.
569    ///
570    /// This is the net value of assets that can provide margin after applying
571    /// collateral discount rates.
572    ///
573    /// Applicable to Spot mode, Multi-currency margin mode and Portfolio
574    /// margin mode.
575    #[serde(default)]
576    pub adj_eq: NumberString,
577
578    /// Account-level available equity.
579    ///
580    /// Currencies restricted by the collateralized borrowing limit are
581    /// excluded.
582    ///
583    /// Applicable to Multi-currency margin mode and Portfolio margin mode.
584    #[serde(default)]
585    pub avail_eq: NumberString,
586
587    /// Potential borrowing initial margin requirement of the account in USD.
588    ///
589    /// An empty string may be returned when the field is not applicable to the
590    /// current account mode.
591    #[serde(default)]
592    pub borrow_froz: NumberString,
593
594    /// Account delta denominated in USD.
595    #[serde(default)]
596    pub delta: NumberString,
597
598    /// Account-level delta leverage for a delta-neutral strategy.
599    ///
600    /// Calculated by OKX as `delta / totalEq`.
601    #[serde(default)]
602    pub delta_lever: NumberString,
603
604    /// Delta-neutral risk status.
605    ///
606    /// Documented values:
607    ///
608    /// - `"0"`: normal;
609    /// - `"1"`: transfers are restricted;
610    /// - `"2"`: delta-reducing restrictions are active.
611    ///
612    /// This remains a string so newly introduced OKX status values can still
613    /// be decoded.
614    #[serde(default)]
615    pub delta_neutral_status: String,
616
617    /// Detailed account information grouped by currency.
618    #[serde(default)]
619    pub details: Vec<AccountBalanceUpdate>,
620
621    /// Account-level initial margin requirement in USD.
622    ///
623    /// This is the sum of initial margin requirements for cross-margin
624    /// positions and pending orders.
625    #[serde(default)]
626    pub imr: NumberString,
627
628    /// Isolated-margin equity denominated in USD.
629    ///
630    /// Applicable to Futures mode, Multi-currency margin mode and Portfolio
631    /// margin mode.
632    #[serde(default)]
633    pub iso_eq: NumberString,
634
635    /// Account maintenance margin ratio.
636    ///
637    /// Applicable to Spot mode, Multi-currency margin mode and Portfolio
638    /// margin mode.
639    #[serde(default)]
640    pub mgn_ratio: NumberString,
641
642    /// Account-level maintenance margin requirement in USD.
643    ///
644    /// This is the sum of maintenance margin requirements for cross-margin
645    /// positions and pending orders.
646    #[serde(default)]
647    pub mmr: NumberString,
648
649    /// Total notional value of account positions in USD.
650    #[serde(default)]
651    pub notional_usd: NumberString,
652
653    /// Notional value attributed to borrowing in USD.
654    #[serde(default)]
655    pub notional_usd_for_borrow: NumberString,
656
657    /// Notional value of expiry-futures positions in USD.
658    #[serde(default)]
659    pub notional_usd_for_futures: NumberString,
660
661    /// Notional value of option positions in USD.
662    #[serde(default)]
663    pub notional_usd_for_option: NumberString,
664
665    /// Notional value of perpetual-futures positions in USD.
666    #[serde(default)]
667    pub notional_usd_for_swap: NumberString,
668
669    /// Cross-margin amount frozen by pending orders, denominated in USD.
670    #[serde(default)]
671    pub ord_froz: NumberString,
672
673    /// Total account equity denominated in USD.
674    #[serde(default)]
675    pub total_eq: NumberString,
676
677    /// Time when the account information was last updated.
678    ///
679    /// Unix timestamp in milliseconds, for example `1705564223311`.
680    #[serde(default)]
681    pub u_time: NumberString,
682
683    /// Account-level cross-margin unrealized profit and loss in USD.
684    ///
685    /// Applicable to Multi-currency margin mode and Portfolio margin mode.
686    #[serde(default)]
687    pub upl: NumberString,
688
689    /// Additional account fields introduced by OKX that are not yet
690    /// represented explicitly.
691    #[serde(flatten, default)]
692    pub extra: ExtraFields,
693}
694
695/// Per-currency account data contained in [`AccountUpdate::details`].
696///
697/// Fields that do not apply to the current account mode are commonly returned
698/// by OKX as empty strings.
699///
700/// OKX docs:
701/// <https://www.okx.com/docs-v5/en/#trading-account-websocket-account-channel>
702#[derive(Debug, Clone, Default, Deserialize)]
703#[serde(rename_all = "camelCase")]
704#[non_exhaustive]
705pub struct AccountBalanceUpdate {
706    /// Auto-lending status for this currency.
707    ///
708    /// Documented values:
709    ///
710    /// - `unsupported`: auto lending is unsupported;
711    /// - `off`: supported but disabled;
712    /// - `pending`: enabled and waiting for matching;
713    /// - `active`: enabled and matched.
714    #[serde(default)]
715    pub auto_lend_status: String,
716
717    /// Amount of the currency currently matched for auto lending.
718    ///
719    /// Returns zero when [`Self::auto_lend_status`] is `unsupported`, `off`,
720    /// or `pending`.
721    #[serde(default)]
722    pub auto_lend_mt_amt: NumberString,
723
724    /// Available balance of the currency.
725    #[serde(default)]
726    pub avail_bal: NumberString,
727
728    /// Available equity of the currency.
729    ///
730    /// Applicable to Futures mode, Multi-currency margin mode and Portfolio
731    /// margin mode.
732    #[serde(default)]
733    pub avail_eq: NumberString,
734
735    /// Potential borrowing initial margin requirement for this currency in
736    /// USD.
737    #[serde(default)]
738    pub borrow_froz: NumberString,
739
740    /// Cash balance of the currency.
741    #[serde(default)]
742    pub cash_bal: NumberString,
743
744    /// Currency code, for example `BTC` or `USDT`.
745    #[serde(default)]
746    pub ccy: String,
747
748    /// USD price index of the currency.
749    #[serde(default)]
750    pub coin_usd_price: NumberString,
751
752    /// Cross-margin liabilities of the currency.
753    #[serde(default)]
754    pub cross_liab: NumberString,
755
756    /// Platform-level collateral restriction status.
757    ///
758    /// Documented values:
759    ///
760    /// - `"0"`: no restriction;
761    /// - `"1"`: close to the platform collateral limit;
762    /// - `"2"`: restriction enabled; the currency cannot provide margin for
763    ///   new orders.
764    #[serde(default)]
765    pub col_res: String,
766
767    /// Whether this currency is enabled as collateral.
768    ///
769    /// Primarily applicable to Multi-currency margin mode.
770    #[serde(default)]
771    pub collateral_enabled: bool,
772
773    /// Auto-conversion risk indicator.
774    ///
775    /// Documented levels range from `"0"` through `"5"`:
776    ///
777    /// - `"0"`: no current auto-conversion risk;
778    /// - `"1"` to `"3"`: increasing risk;
779    /// - `"4"`: auto conversion may occur soon;
780    /// - `"5"`: auto conversion is in progress.
781    #[serde(default)]
782    pub col_borr_auto_conversion: String,
783
784    /// Discounted equity of the currency in USD.
785    #[serde(default)]
786    pub dis_eq: NumberString,
787
788    /// Total equity of the currency.
789    #[serde(default)]
790    pub eq: NumberString,
791
792    /// Equity of the currency denominated in USD.
793    #[serde(default)]
794    pub eq_usd: NumberString,
795
796    /// Smart-sync equity.
797    ///
798    /// The default is zero and the field is only applicable to copy traders.
799    #[serde(default)]
800    pub smt_sync_eq: NumberString,
801
802    /// Spot smart-sync copy-trading equity.
803    ///
804    /// The default is zero and the field is only applicable to copy traders.
805    #[serde(default)]
806    pub spot_copy_trading_eq: NumberString,
807
808    /// Balance frozen for Dip Sniper and Peak Sniper products.
809    #[serde(default)]
810    pub fixed_bal: NumberString,
811
812    /// Frozen balance of the currency.
813    #[serde(default)]
814    pub frozen_bal: NumberString,
815
816    /// Forced-repayment type.
817    ///
818    /// Documented values:
819    ///
820    /// - `"0"`: no forced repayment;
821    /// - `"1"`: user-based forced repayment;
822    /// - `"2"`: platform-based forced repayment.
823    #[serde(default)]
824    pub frp_type: String,
825
826    /// Currency-level cross initial margin requirement.
827    #[serde(default)]
828    pub imr: NumberString,
829
830    /// Accrued interest for this currency.
831    #[serde(default)]
832    pub interest: NumberString,
833
834    /// Isolated-margin equity of the currency.
835    #[serde(default)]
836    pub iso_eq: NumberString,
837
838    /// Isolated liabilities of the currency.
839    #[serde(default)]
840    pub iso_liab: NumberString,
841
842    /// Isolated unrealized profit and loss of the currency.
843    #[serde(default)]
844    pub iso_upl: NumberString,
845
846    /// Total liabilities of the currency.
847    ///
848    /// OKX represents liabilities as a positive value.
849    #[serde(default)]
850    pub liab: NumberString,
851
852    /// Maximum amount of this currency that can currently be borrowed.
853    #[serde(default)]
854    pub max_loan: NumberString,
855
856    /// Cross-maintenance-margin ratio of the currency.
857    #[serde(default)]
858    pub mgn_ratio: NumberString,
859
860    /// Currency-level cross maintenance margin requirement.
861    #[serde(default)]
862    pub mmr: NumberString,
863
864    /// Leverage calculated at the currency level.
865    ///
866    /// Applicable to Futures mode.
867    #[serde(default)]
868    pub notional_lever: NumberString,
869
870    /// Margin frozen by open orders for this currency.
871    #[serde(default)]
872    pub ord_frozen: NumberString,
873
874    /// Trial-fund balance.
875    #[serde(default)]
876    pub reward_bal: NumberString,
877
878    /// Actual spot-hedging amount currently in use.
879    ///
880    /// Applicable to Portfolio margin mode.
881    #[serde(default)]
882    pub spot_in_use_amt: NumberString,
883
884    /// User-defined spot-hedging amount.
885    ///
886    /// Applicable to Portfolio margin mode.
887    #[serde(default)]
888    pub cl_spot_in_use_amt: NumberString,
889
890    /// Maximum spot-hedging amount calculated by OKX.
891    ///
892    /// Applicable to Portfolio margin mode.
893    ///
894    /// The exact JSON field is `maxSpotInUseAmt`.
895    #[serde(default)]
896    pub max_spot_in_use_amt: NumberString,
897
898    /// Spot balance obtained through copy trading.
899    ///
900    /// This includes amounts currently frozen by copy-trading open orders.
901    #[serde(default)]
902    pub spot_iso_bal: NumberString,
903
904    /// Total equity assigned to trading-bot strategies for this currency.
905    #[serde(default)]
906    pub stgy_eq: NumberString,
907
908    /// Forced-repayment risk indicator.
909    ///
910    /// Values range from zero through five. A larger value indicates a higher
911    /// probability that forced repayment will be triggered.
912    #[serde(default)]
913    pub twap: NumberString,
914
915    /// Time when this currency entry was last updated.
916    ///
917    /// Unix timestamp in milliseconds.
918    #[serde(default)]
919    pub u_time: NumberString,
920
921    /// Unrealized profit and loss for margin and derivative positions of this
922    /// currency.
923    #[serde(default)]
924    pub upl: NumberString,
925
926    /// Liabilities caused by unrealized losses of this currency.
927    #[serde(default)]
928    pub upl_liab: NumberString,
929
930    /// Spot balance.
931    ///
932    /// The unit is the currency itself, for example BTC.
933    #[serde(default)]
934    pub spot_bal: NumberString,
935
936    /// Average acquisition price of the current spot balance in USD.
937    ///
938    /// This is a single JSON string, not an array.
939    #[serde(default)]
940    pub open_avg_px: NumberString,
941
942    /// Accumulated average acquisition price of the spot balance in USD.
943    ///
944    /// This is a single JSON string, not an array.
945    #[serde(default)]
946    pub acc_avg_px: NumberString,
947
948    /// Spot unrealized profit and loss in USD.
949    #[serde(default)]
950    pub spot_upl: NumberString,
951
952    /// Spot unrealized profit and loss ratio.
953    #[serde(default)]
954    pub spot_upl_ratio: NumberString,
955
956    /// Accumulated spot profit and loss in USD.
957    #[serde(default)]
958    pub total_pnl: NumberString,
959
960    /// Accumulated spot profit and loss ratio.
961    #[serde(default)]
962    pub total_pnl_ratio: NumberString,
963
964    /// Additional per-currency fields introduced by OKX that are not yet
965    /// represented explicitly.
966    #[serde(flatten, default)]
967    pub extra: ExtraFields,
968}