Skip to main content

rust_okx/ws/model/
block.rs

1//! Block trading channel models (`rfqs`, `quotes`, `struc-block-trades`, `block-tickers`).
2//!
3//! Mixed public and private channels.
4
5use serde::Deserialize;
6use serde_json::Value;
7
8use super::ExtraFields;
9use crate::model::NumberString;
10
11/// A leg embedded in block RFQ, quote, and structure-block-trade messages.
12#[derive(Debug, Clone, Default, Deserialize)]
13#[serde(rename_all = "camelCase")]
14#[non_exhaustive]
15pub struct BlockLeg {
16    /// Instrument ID of this leg, e.g., `BTC-USD-240329-40000-C`.
17    #[serde(default)]
18    pub inst_id: String,
19    /// Trade mode: `cross`, `isolated`, or `cash`.
20    #[serde(default)]
21    pub td_mode: String,
22    /// Margin currency (cross MARGIN orders in Futures mode only).
23    #[serde(default)]
24    pub ccy: String,
25    /// Leg size in base currency or contracts.
26    #[serde(default)]
27    pub sz: NumberString,
28    /// Leg side: `buy` or `sell`.
29    #[serde(default)]
30    pub side: String,
31    /// Position side: `long`, `short`, or `net`.
32    #[serde(default)]
33    pub pos_side: String,
34    /// Leg price.
35    #[serde(default)]
36    pub px: NumberString,
37    /// Trade ID for this leg (only present after execution).
38    #[serde(default)]
39    pub trade_id: String,
40    /// Target currency for the leg quantity (spot only): `base_ccy` or `quote_ccy`.
41    #[serde(default)]
42    pub tgt_ccy: String,
43    /// Fee charged for this leg (negative means deducted; positive means rebate).
44    #[serde(default)]
45    pub fee: NumberString,
46    /// Fee currency for this leg.
47    #[serde(default)]
48    pub fee_ccy: String,
49    /// The quote currency used for trading (spot only).
50    #[serde(default)]
51    pub trade_quote_ccy: String,
52    /// Unrecognized fields retained for forward compatibility.
53    #[serde(flatten, default)]
54    pub extra: ExtraFields,
55}
56
57/// Block-trading `rfqs` channel row.
58///
59/// OKX docs: <https://www.okx.com/docs-v5/en/#block-trading-websocket-rfqs-channel>
60#[derive(Debug, Clone, Default, Deserialize)]
61#[serde(rename_all = "camelCase")]
62#[non_exhaustive]
63pub struct BlockRfqUpdate {
64    /// OKX-assigned RFQ ID.
65    #[serde(default)]
66    pub rfq_id: String,
67    /// Client-supplied RFQ ID (empty for Maker).
68    #[serde(default)]
69    pub cl_rfq_id: String,
70    /// RFQ tag.
71    #[serde(default)]
72    pub tag: String,
73    /// Taker's anonymized trader code.
74    #[serde(default)]
75    pub trader_code: String,
76    /// Time until which this RFQ is valid (Unix milliseconds).
77    #[serde(default)]
78    pub valid_until: NumberString,
79    /// List of counterparty trader codes invited to quote.
80    #[serde(default)]
81    pub counterparties: Vec<String>,
82    /// Legs that make up this RFQ.
83    #[serde(default)]
84    pub legs: Vec<BlockLeg>,
85    /// Whether partial execution is allowed on this RFQ.
86    #[serde(default)]
87    pub allow_partial_execution: bool,
88    /// RFQ state.
89    ///
90    /// Documented values: `active`, `canceled`, `filled`, `expired`, `traded_away`, `failed`.
91    #[serde(default)]
92    pub state: String,
93    /// Flow type; only applicable to Makers (empty for Takers).
94    #[serde(default)]
95    pub flow_type: String,
96    /// Group ID when this RFQ belongs to an RFQ group.
97    #[serde(default)]
98    pub group_id: String,
99    /// Account allocation details (taker only).
100    #[serde(default)]
101    pub acct_alloc: Vec<Value>,
102    /// RFQ creation time (Unix milliseconds).
103    #[serde(default)]
104    pub c_time: NumberString,
105    /// Last update time (Unix milliseconds).
106    #[serde(default)]
107    pub u_time: NumberString,
108    /// Unrecognized fields retained for forward compatibility.
109    #[serde(flatten, default)]
110    pub extra: ExtraFields,
111}
112
113/// Block-trading `quotes` channel row.
114///
115/// OKX docs: <https://www.okx.com/docs-v5/en/#block-trading-websocket-quotes-channel>
116#[derive(Debug, Clone, Default, Deserialize)]
117#[serde(rename_all = "camelCase")]
118#[non_exhaustive]
119pub struct BlockQuoteUpdate {
120    /// OKX-assigned quote ID.
121    #[serde(default)]
122    pub quote_id: String,
123    /// Client-supplied quote ID (empty for Taker).
124    #[serde(default)]
125    pub cl_quote_id: String,
126    /// RFQ ID being responded to.
127    #[serde(default)]
128    pub rfq_id: String,
129    /// Client-supplied RFQ ID (empty for Maker).
130    #[serde(default)]
131    pub cl_rfq_id: String,
132    /// Quote tag.
133    #[serde(default)]
134    pub tag: String,
135    /// Maker's anonymized trader code.
136    #[serde(default)]
137    pub trader_code: String,
138    /// Quote side from the maker's perspective: `buy` or `sell`.
139    #[serde(default)]
140    pub quote_side: String,
141    /// Time until which this quote is valid (Unix milliseconds).
142    #[serde(default)]
143    pub valid_until: NumberString,
144    /// Legs that make up this quote.
145    #[serde(default)]
146    pub legs: Vec<BlockLeg>,
147    /// Quote state.
148    ///
149    /// Documented values: `active`, `canceled`, `filled`, `expired`, `failed`.
150    #[serde(default)]
151    pub state: String,
152    /// Reason for the current state (e.g., `mmp_canceled`).
153    #[serde(default)]
154    pub reason: String,
155    /// Quote creation time (Unix milliseconds).
156    #[serde(default)]
157    pub c_time: NumberString,
158    /// Last update time (Unix milliseconds).
159    #[serde(default)]
160    pub u_time: NumberString,
161    /// Unrecognized fields retained for forward compatibility.
162    #[serde(flatten, default)]
163    pub extra: ExtraFields,
164}
165
166/// Structure-block-trade channel row (private `struc-block-trades`).
167///
168/// OKX docs: <https://www.okx.com/docs-v5/en/#block-trading-websocket-structure-block-trades-channel>
169#[derive(Debug, Clone, Default, Deserialize)]
170#[serde(rename_all = "camelCase")]
171#[non_exhaustive]
172pub struct StructureBlockTradeUpdate {
173    /// Block trade ID that groups one or more legs.
174    #[serde(default)]
175    pub block_td_id: String,
176    /// OKX-assigned RFQ ID.
177    #[serde(default)]
178    pub rfq_id: String,
179    /// Client-supplied RFQ ID.
180    #[serde(default)]
181    pub cl_rfq_id: String,
182    /// OKX-assigned quote ID.
183    #[serde(default)]
184    pub quote_id: String,
185    /// Client-supplied quote ID.
186    #[serde(default)]
187    pub cl_quote_id: String,
188    /// Tag associated with this trade.
189    #[serde(default)]
190    pub tag: String,
191    /// Whether the trade execution was successful.
192    #[serde(default)]
193    pub is_successful: bool,
194    /// Error code when `is_successful` is `false`; empty otherwise.
195    #[serde(default)]
196    pub error_code: String,
197    /// Taker's anonymized trader code.
198    #[serde(default)]
199    pub t_trader_code: String,
200    /// Maker's anonymized trader code.
201    #[serde(default)]
202    pub m_trader_code: String,
203    /// Legs that make up this block trade.
204    #[serde(default)]
205    pub legs: Vec<BlockLeg>,
206    /// Account allocation details for this trade.
207    #[serde(default)]
208    pub acct_alloc: Vec<Value>,
209    /// Trade creation time (Unix milliseconds).
210    #[serde(default)]
211    pub c_time: NumberString,
212    /// Unrecognized fields retained for forward compatibility.
213    #[serde(flatten, default)]
214    pub extra: ExtraFields,
215}
216
217/// Public block-trade channel row (`public-block-trades`).
218///
219/// Each push represents a single filled instrument trade.
220///
221/// OKX docs: <https://www.okx.com/docs-v5/en/#block-trading-websocket-public-block-trades-channel>
222#[derive(Debug, Clone, Default, Deserialize)]
223#[serde(rename_all = "camelCase")]
224#[non_exhaustive]
225pub struct PublicBlockTradeUpdate {
226    /// Instrument ID, e.g., `BTC-USD-231020-5000-P`.
227    #[serde(default)]
228    pub inst_id: String,
229    /// Trade ID.
230    #[serde(default)]
231    pub trade_id: String,
232    /// Fill price.
233    #[serde(default)]
234    pub px: NumberString,
235    /// Fill size.
236    #[serde(default)]
237    pub sz: NumberString,
238    /// Fill side: `buy` or `sell` (taker perspective).
239    #[serde(default)]
240    pub side: String,
241    /// Implied volatility (options only).
242    #[serde(default)]
243    pub fill_vol: NumberString,
244    /// Forward price (options only).
245    #[serde(default)]
246    pub fwd_px: NumberString,
247    /// Index price (futures / swap / option).
248    #[serde(default)]
249    pub idx_px: NumberString,
250    /// Mark price (futures / swap / option).
251    #[serde(default)]
252    pub mark_px: NumberString,
253    /// Group RFQ ID; empty for normal trades.
254    #[serde(default)]
255    pub group_id: String,
256    /// Push time (Unix milliseconds).
257    #[serde(default)]
258    pub ts: NumberString,
259    /// Unrecognized fields retained for forward compatibility.
260    #[serde(flatten, default)]
261    pub extra: ExtraFields,
262}
263
264/// Public structure-block-trade channel row (`public-struc-block-trades`).
265///
266/// OKX docs: <https://www.okx.com/docs-v5/en/#block-trading-websocket-public-structure-block-trades-channel>
267#[derive(Debug, Clone, Default, Deserialize)]
268#[serde(rename_all = "camelCase")]
269#[non_exhaustive]
270pub struct PublicStructureBlockTradeUpdate {
271    /// Block trade ID.
272    #[serde(default)]
273    pub block_td_id: String,
274    /// Group RFQ ID; empty for normal trades.
275    #[serde(default)]
276    pub group_id: String,
277    /// Legs of the structure block trade.
278    ///
279    /// Each leg carries `instId`, `px`, `sz`, `side`, and `tradeId`.
280    #[serde(default)]
281    pub legs: Vec<BlockLeg>,
282    /// Trade creation time (Unix milliseconds).
283    #[serde(default)]
284    pub c_time: NumberString,
285    /// Unrecognized fields retained for forward compatibility.
286    #[serde(flatten, default)]
287    pub extra: ExtraFields,
288}
289
290/// `block-tickers` channel row.
291///
292/// OKX docs: <https://www.okx.com/docs-v5/en/#block-trading-websocket-block-tickers-channel>
293#[derive(Debug, Clone, Default, Deserialize)]
294#[serde(rename_all = "camelCase")]
295#[non_exhaustive]
296pub struct BlockTickerUpdate {
297    /// Instrument type, e.g., `SWAP`, `FUTURES`, `OPTION`.
298    #[serde(default)]
299    pub inst_type: String,
300    /// Instrument ID, e.g., `LTC-USD-SWAP`.
301    #[serde(default)]
302    pub inst_id: String,
303    /// 24h block-trading volume in currency units.
304    #[serde(default)]
305    pub vol_ccy24h: NumberString,
306    /// 24h block-trading volume in contracts.
307    #[serde(default)]
308    pub vol24h: NumberString,
309    /// Ticker data generation time (Unix milliseconds).
310    #[serde(default)]
311    pub ts: NumberString,
312    /// Unrecognized fields retained for forward compatibility.
313    #[serde(flatten, default)]
314    pub extra: ExtraFields,
315}