nautilus_okx/common/models.rs
1// -------------------------------------------------------------------------------------------------
2// Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3// https://nautechsystems.io
4//
5// Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6// You may not use this file except in compliance with the License.
7// You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Data models representing OKX API payloads consumed by the adapter.
17
18use nautilus_core::serialization::{
19 deserialize_decimal_from_str, deserialize_optional_decimal_from_str, deserialize_string_to_u64,
20 serialize_decimal_as_str, serialize_optional_decimal_as_str,
21};
22use rust_decimal::Decimal;
23use serde::{Deserialize, Serialize, Serializer};
24use ustr::Ustr;
25
26use super::enums::{OKXOptionType, OKXTriggerType};
27use crate::common::{
28 enums::{
29 OKXContractType, OKXInstrumentCategory, OKXInstrumentStatus, OKXInstrumentType,
30 OKXRpiPermission,
31 },
32 parse::{deserialize_empty_ustr_as_none, deserialize_optional_string_to_u64},
33};
34
35/// Attached TP/SL child order metadata returned by OKX on parent orders.
36#[derive(Clone, Debug, Default, Serialize, Deserialize)]
37#[serde(rename_all = "camelCase")]
38pub struct OKXAttachedAlgoOrd {
39 /// Attached algo order ID, if assigned by OKX.
40 #[serde(default)]
41 pub attach_algo_id: String,
42 /// Attached child client order ID.
43 #[serde(default)]
44 pub attach_algo_cl_ord_id: String,
45 /// Stop-loss trigger price.
46 #[serde(default)]
47 pub sl_trigger_px: String,
48 /// Stop-loss order price.
49 #[serde(default)]
50 pub sl_ord_px: String,
51 /// Stop-loss trigger price type.
52 #[serde(default)]
53 pub sl_trigger_px_type: Option<OKXTriggerType>,
54 /// Take-profit trigger price.
55 #[serde(default)]
56 pub tp_trigger_px: String,
57 /// Take-profit order price.
58 #[serde(default)]
59 pub tp_ord_px: String,
60 /// Take-profit trigger price type.
61 #[serde(default)]
62 pub tp_trigger_px_type: Option<OKXTriggerType>,
63 /// Callback ratio for attached trailing stop orders.
64 #[serde(default)]
65 pub callback_ratio: String,
66 /// Callback spread for attached trailing stop orders.
67 #[serde(default)]
68 pub callback_spread: String,
69 /// Activation price for attached trailing stop orders.
70 #[serde(default)]
71 pub active_px: String,
72}
73
74/// Represents a Retail Price Improvement order book level.
75#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
76pub struct OKXRpiBookLevel(
77 /// Price.
78 #[serde(
79 serialize_with = "serialize_decimal_as_str",
80 deserialize_with = "deserialize_decimal_from_str"
81 )]
82 pub Decimal,
83 /// Total quantity, including RPI liquidity.
84 #[serde(
85 serialize_with = "serialize_decimal_as_str",
86 deserialize_with = "deserialize_decimal_from_str"
87 )]
88 pub Decimal,
89 /// Quantity excluding RPI liquidity.
90 #[serde(
91 serialize_with = "serialize_decimal_as_str",
92 deserialize_with = "deserialize_decimal_from_str"
93 )]
94 pub Decimal,
95 /// Number of orders at this price.
96 #[serde(
97 serialize_with = "serialize_u64_as_str",
98 deserialize_with = "deserialize_string_to_u64"
99 )]
100 pub u64,
101);
102
103fn serialize_u64_as_str<S>(value: &u64, serializer: S) -> Result<S::Ok, S::Error>
104where
105 S: Serializer,
106{
107 serializer.serialize_str(&value.to_string())
108}
109
110/// Represents an instrument on the OKX exchange.
111#[derive(Clone, Debug, Serialize, Deserialize)]
112#[serde(rename_all = "camelCase")]
113pub struct OKXInstrument {
114 /// Product type (SPOT, MARGIN, SWAP, FUTURES, OPTION).
115 pub inst_type: OKXInstrumentType,
116 /// Instrument ID, e.g. "BTC-USD-SWAP".
117 pub inst_id: Ustr,
118 /// Instrument ID code (numeric). Required for WebSocket order operations.
119 /// E.g., 10458 for BTC-USD-SWAP.
120 #[serde(default)]
121 pub inst_id_code: Option<u64>,
122 /// Underlying of the instrument, e.g. "BTC-USD". Only applicable to FUTURES/SWAP/OPTION.
123 pub uly: Ustr,
124 /// Instrument family, e.g. "BTC-USD". Only applicable to FUTURES/SWAP/OPTION.
125 pub inst_family: Ustr,
126 /// Event contract series ID. Only applicable to EVENTS.
127 #[serde(default, deserialize_with = "deserialize_empty_ustr_as_none")]
128 pub series_id: Option<Ustr>,
129 /// Instrument category (the OKX `instCategory` field; the deprecated, distinct
130 /// `category` field is intentionally ignored).
131 #[serde(default)]
132 pub inst_category: Option<OKXInstrumentCategory>,
133 /// Initial price-limit band for newly listed contracts.
134 #[serde(default)]
135 pub init_px_lmt_pct: String,
136 /// Floating price-limit band during normal trading.
137 #[serde(default)]
138 pub float_px_lmt_pct: String,
139 /// Maximum price-limit cap.
140 #[serde(default)]
141 pub max_px_lmt_pct: String,
142 /// Base currency, e.g. "BTC" in BTC-USDT. Applicable to SPOT/MARGIN.
143 pub base_ccy: Ustr,
144 /// Quote currency, e.g. "USDT" in BTC-USDT.
145 pub quote_ccy: Ustr,
146 /// Settlement currency, e.g. "BTC" for BTC-USD-SWAP.
147 pub settle_ccy: Ustr,
148 /// Contract value. Only applicable to FUTURES/SWAP/OPTION.
149 pub ct_val: String,
150 /// Contract multiplier. Only applicable to FUTURES/SWAP/OPTION.
151 pub ct_mult: String,
152 /// Contract value currency. Only applicable to FUTURES/SWAP/OPTION.
153 pub ct_val_ccy: String,
154 /// Option type, "C" for call options, "P" for put options. Only applicable to OPTION.
155 pub opt_type: OKXOptionType,
156 /// Strike price. Only applicable to OPTION.
157 pub stk: String,
158 /// Listing time, Unix timestamp format in milliseconds, e.g. "1597026383085".
159 #[serde(deserialize_with = "deserialize_optional_string_to_u64")]
160 pub list_time: Option<u64>,
161 /// Expiry time, Unix timestamp format in milliseconds, e.g. "1597026383085".
162 #[serde(deserialize_with = "deserialize_optional_string_to_u64")]
163 pub exp_time: Option<u64>,
164 /// Leverage. Not applicable to SPOT.
165 pub lever: String,
166 /// Tick size, e.g. "0.1".
167 pub tick_sz: String,
168 /// Lot size, e.g. "1".
169 pub lot_sz: String,
170 /// Minimum order size.
171 pub min_sz: String,
172 /// Contract type. linear: "linear", inverse: "inverse". Only applicable to FUTURES/SWAP.
173 pub ct_type: OKXContractType,
174 /// Instrument status.
175 pub state: OKXInstrumentStatus,
176 /// Rule type, e.g. "DynamicPL", "CT", etc.
177 pub rule_type: String,
178 /// Maximum limit order size.
179 #[serde(default)]
180 pub max_lmt_sz: String,
181 /// Maximum market order size.
182 #[serde(default)]
183 pub max_mkt_sz: String,
184 /// Maximum limit order amount.
185 #[serde(default)]
186 pub max_lmt_amt: String,
187 /// Maximum market order amount.
188 #[serde(default)]
189 pub max_mkt_amt: String,
190 /// Maximum TWAP order size.
191 #[serde(default)]
192 pub max_twap_sz: String,
193 /// Maximum iceberg order size.
194 #[serde(default)]
195 pub max_iceberg_sz: String,
196 /// Maximum trigger order size.
197 #[serde(default)]
198 pub max_trigger_sz: String,
199 /// Maximum stop order size.
200 #[serde(default)]
201 pub max_stop_sz: String,
202 /// RPI maker permission: 0 disabled, 1 enabled without permission, 2 permitted.
203 #[serde(default, alias = "elp")]
204 pub rpi: Option<OKXRpiPermission>,
205 /// Minimum number of price levels between RPI buy and sell orders.
206 #[serde(default, deserialize_with = "deserialize_optional_string_to_u64")]
207 pub rpi_min_level: Option<u64>,
208 /// Minimum distance from the opposite organic best price, in basis points.
209 #[serde(
210 default,
211 serialize_with = "serialize_optional_decimal_as_str",
212 deserialize_with = "deserialize_optional_decimal_from_str"
213 )]
214 pub rpi_min_px_band: Option<Decimal>,
215}