Skip to main content

rust_okx/api/account/requests/
risk.rs

1use std::borrow::Cow;
2
3use serde::Serialize;
4
5use crate::model::InstType;
6
7/// A simulated position used by position-builder and simulated-margin requests.
8#[derive(Debug, Clone, Serialize)]
9pub struct SimulatedPosition<'a> {
10    #[serde(rename = "instId")]
11    inst_id: Cow<'a, str>,
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pos: Option<Cow<'a, str>>,
14    #[serde(rename = "avgPx", skip_serializing_if = "Option::is_none")]
15    avg_px: Option<Cow<'a, str>>,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    lever: Option<Cow<'a, str>>,
18}
19
20impl<'a> SimulatedPosition<'a> {
21    /// Create a simulated position for an instrument.
22    pub fn new(inst_id: impl Into<Cow<'a, str>>) -> Self {
23        Self {
24            inst_id: inst_id.into(),
25            pos: None,
26            avg_px: None,
27            lever: None,
28        }
29    }
30
31    /// Set the simulated position size.
32    pub fn position(mut self, pos: impl Into<Cow<'a, str>>) -> Self {
33        self.pos = Some(pos.into());
34        self
35    }
36
37    /// Set the simulated average price.
38    pub fn average_price(mut self, avg_px: impl Into<Cow<'a, str>>) -> Self {
39        self.avg_px = Some(avg_px.into());
40        self
41    }
42
43    /// Set the simulated leverage.
44    pub fn leverage(mut self, lever: impl Into<Cow<'a, str>>) -> Self {
45        self.lever = Some(lever.into());
46        self
47    }
48}
49
50/// A simulated asset used by position-builder requests.
51#[derive(Debug, Clone, Serialize)]
52pub struct SimulatedAsset<'a> {
53    ccy: Cow<'a, str>,
54    #[serde(skip_serializing_if = "Option::is_none")]
55    eq: Option<Cow<'a, str>>,
56}
57
58impl<'a> SimulatedAsset<'a> {
59    /// Create a simulated asset for a currency.
60    pub fn new(ccy: impl Into<Cow<'a, str>>) -> Self {
61        Self {
62            ccy: ccy.into(),
63            eq: None,
64        }
65    }
66
67    /// Set the simulated equity.
68    pub fn equity(mut self, eq: impl Into<Cow<'a, str>>) -> Self {
69        self.eq = Some(eq.into());
70        self
71    }
72}
73
74/// Request body for simulated margin calculation.
75#[derive(Debug, Clone, Default, Serialize)]
76pub struct SimulatedMarginRequest<'a> {
77    #[serde(rename = "instType", skip_serializing_if = "Option::is_none")]
78    inst_type: Option<InstType>,
79    #[serde(rename = "inclRealPos", skip_serializing_if = "Option::is_none")]
80    include_real_positions: Option<bool>,
81    #[serde(rename = "spotOffsetType", skip_serializing_if = "Option::is_none")]
82    spot_offset_type: Option<Cow<'a, str>>,
83    #[serde(rename = "simPos", skip_serializing_if = "Option::is_none")]
84    simulated_positions: Option<Vec<SimulatedPosition<'a>>>,
85}
86
87impl<'a> SimulatedMarginRequest<'a> {
88    /// Create an empty simulated-margin request.
89    pub fn new() -> Self {
90        Self::default()
91    }
92
93    /// Set the instrument type.
94    pub fn inst_type(mut self, inst_type: InstType) -> Self {
95        self.inst_type = Some(inst_type);
96        self
97    }
98
99    /// Set whether real positions and equity are included.
100    pub fn include_real_positions(mut self, include_real_positions: bool) -> Self {
101        self.include_real_positions = Some(include_real_positions);
102        self
103    }
104
105    /// Set the spot offset type.
106    pub fn spot_offset_type(mut self, spot_offset_type: impl Into<Cow<'a, str>>) -> Self {
107        self.spot_offset_type = Some(spot_offset_type.into());
108        self
109    }
110
111    /// Set simulated positions.
112    pub fn simulated_positions(mut self, simulated_positions: Vec<SimulatedPosition<'a>>) -> Self {
113        self.simulated_positions = Some(simulated_positions);
114        self
115    }
116}
117
118/// Query parameters for account position tiers.
119#[derive(Debug, Clone, Serialize)]
120pub struct AccountPositionTiersRequest<'a> {
121    #[serde(rename = "instType")]
122    inst_type: InstType,
123    #[serde(rename = "uly", skip_serializing_if = "Option::is_none")]
124    underlying: Option<Cow<'a, str>>,
125    #[serde(rename = "instFamily", skip_serializing_if = "Option::is_none")]
126    inst_family: Option<Cow<'a, str>>,
127}
128
129impl<'a> AccountPositionTiersRequest<'a> {
130    /// Create an account position-tiers query with the documented required instrument type.
131    ///
132    /// Set either [`Self::underlying`] or [`Self::inst_family`]. OKX uses
133    /// `instFamily` first when both are provided.
134    pub fn new(inst_type: InstType) -> Self {
135        Self {
136            inst_type,
137            underlying: None,
138            inst_family: None,
139        }
140    }
141
142    /// Set the underlying filter.
143    pub fn underlying(mut self, underlying: impl Into<Cow<'a, str>>) -> Self {
144        self.underlying = Some(underlying.into());
145        self
146    }
147
148    /// Set the instrument family filter.
149    pub fn inst_family(mut self, inst_family: impl Into<Cow<'a, str>>) -> Self {
150        self.inst_family = Some(inst_family.into());
151        self
152    }
153}
154
155/// Request body for setting the spot risk offset amount.
156#[derive(Debug, Clone, Serialize)]
157pub struct SetRiskOffsetAmountRequest<'a> {
158    ccy: Cow<'a, str>,
159    #[serde(rename = "clSpotInUseAmt")]
160    cl_spot_in_use_amt: Cow<'a, str>,
161}
162
163impl<'a> SetRiskOffsetAmountRequest<'a> {
164    /// Create a risk-offset amount update for a currency.
165    pub fn new(ccy: impl Into<Cow<'a, str>>, cl_spot_in_use_amt: impl Into<Cow<'a, str>>) -> Self {
166        Self {
167            ccy: ccy.into(),
168            cl_spot_in_use_amt: cl_spot_in_use_amt.into(),
169        }
170    }
171}
172
173/// Request body for position builder.
174#[derive(Debug, Clone, Default, Serialize)]
175pub struct PositionBuilderRequest<'a> {
176    #[serde(rename = "acctLv", skip_serializing_if = "Option::is_none")]
177    acct_lv: Option<Cow<'a, str>>,
178    #[serde(rename = "inclRealPosAndEq", skip_serializing_if = "Option::is_none")]
179    include_real_positions_and_equity: Option<bool>,
180    #[serde(skip_serializing_if = "Option::is_none")]
181    lever: Option<Cow<'a, str>>,
182    #[serde(rename = "greeksType", skip_serializing_if = "Option::is_none")]
183    greeks_type: Option<Cow<'a, str>>,
184    #[serde(rename = "simPos", skip_serializing_if = "Option::is_none")]
185    simulated_positions: Option<Vec<SimulatedPosition<'a>>>,
186    #[serde(rename = "simAsset", skip_serializing_if = "Option::is_none")]
187    simulated_assets: Option<Vec<SimulatedAsset<'a>>>,
188    #[serde(rename = "idxVol", skip_serializing_if = "Option::is_none")]
189    index_volatility: Option<Cow<'a, str>>,
190}
191
192impl<'a> PositionBuilderRequest<'a> {
193    /// Create an empty position-builder request.
194    pub fn new() -> Self {
195        Self::default()
196    }
197
198    /// Set the account level.
199    pub fn account_level(mut self, acct_lv: impl Into<Cow<'a, str>>) -> Self {
200        self.acct_lv = Some(acct_lv.into());
201        self
202    }
203
204    /// Set whether real positions and equity are included.
205    pub fn include_real_positions_and_equity(mut self, include: bool) -> Self {
206        self.include_real_positions_and_equity = Some(include);
207        self
208    }
209
210    /// Set leverage.
211    pub fn leverage(mut self, lever: impl Into<Cow<'a, str>>) -> Self {
212        self.lever = Some(lever.into());
213        self
214    }
215
216    /// Set greeks display type.
217    pub fn greeks_type(mut self, greeks_type: impl Into<Cow<'a, str>>) -> Self {
218        self.greeks_type = Some(greeks_type.into());
219        self
220    }
221
222    /// Set simulated positions.
223    pub fn simulated_positions(mut self, simulated_positions: Vec<SimulatedPosition<'a>>) -> Self {
224        self.simulated_positions = Some(simulated_positions);
225        self
226    }
227
228    /// Set simulated assets.
229    pub fn simulated_assets(mut self, simulated_assets: Vec<SimulatedAsset<'a>>) -> Self {
230        self.simulated_assets = Some(simulated_assets);
231        self
232    }
233
234    /// Set index volatility.
235    pub fn index_volatility(mut self, index_volatility: impl Into<Cow<'a, str>>) -> Self {
236        self.index_volatility = Some(index_volatility.into());
237        self
238    }
239}