1use std::collections::HashMap;
19
20use chrono::{DateTime, Utc};
21use nautilus_model::enums::{OrderSide, PositionSide};
22use serde::{Deserialize, Serialize};
23use serde_json::Value;
24use strum::{AsRefStr, Display, EnumString, FromRepr};
25use ustr::Ustr;
26
27use crate::{
28 common::enums::{
29 DydxFillType, DydxLiquidity, DydxOrderStatus, DydxOrderType, DydxPositionStatus,
30 DydxTickerType, DydxTimeInForce,
31 },
32 websocket::enums::DydxWsChannel,
33};
34
35#[derive(
37 Clone,
38 Copy,
39 Debug,
40 PartialEq,
41 Eq,
42 Hash,
43 Display,
44 AsRefStr,
45 EnumString,
46 FromRepr,
47 Serialize,
48 Deserialize,
49)]
50#[serde(rename_all = "snake_case")]
51#[strum(serialize_all = "snake_case")]
52pub enum DydxWsMessageType {
53 Connected,
55 Subscribed,
57 Unsubscribed,
59 ChannelData,
61 ChannelBatchData,
63 Error,
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct DydxWsMessageGeneral {
70 #[serde(rename = "type")]
71 pub msg_type: Option<DydxWsMessageType>,
72 pub connection_id: Option<String>,
73 pub message_id: Option<u64>,
74 pub channel: Option<DydxWsChannel>,
75 pub id: Option<String>,
76 pub message: Option<String>,
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize)]
81pub struct DydxBlockHeightSubscribedContents {
82 pub height: String,
83 pub time: DateTime<Utc>,
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct DydxWsBlockHeightSubscribedData {
89 #[serde(rename = "type")]
90 pub msg_type: DydxWsMessageType,
91 pub connection_id: String,
92 pub message_id: u64,
93 pub channel: DydxWsChannel,
94 pub id: String,
95 pub contents: DydxBlockHeightSubscribedContents,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize)]
100pub struct DydxBlockHeightChannelContents {
101 #[serde(rename = "blockHeight")]
102 pub block_height: String,
103 pub time: DateTime<Utc>,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct DydxWsBlockHeightChannelData {
109 #[serde(rename = "type")]
110 pub msg_type: DydxWsMessageType,
111 pub connection_id: String,
112 pub message_id: u64,
113 pub id: String,
114 pub channel: DydxWsChannel,
115 pub version: String,
116 pub contents: DydxBlockHeightChannelContents,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct DydxOraclePriceMarket {
122 #[serde(rename = "oraclePrice")]
123 pub oracle_price: String,
124 #[serde(rename = "effectiveAt")]
125 pub effective_at: String,
126 #[serde(rename = "effectiveAtHeight")]
127 pub effective_at_height: String,
128 #[serde(rename = "marketId")]
129 pub market_id: u32,
130}
131
132#[derive(Debug, Clone, Serialize, Deserialize)]
134pub struct DydxMarketMessageContents {
135 #[serde(rename = "oraclePrices")]
136 pub oracle_prices: Option<HashMap<String, DydxOraclePriceMarket>>,
137 pub trading: Option<Value>,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct DydxWsMarketChannelData {
143 #[serde(rename = "type")]
144 pub msg_type: DydxWsMessageType,
145 pub channel: DydxWsChannel,
146 pub contents: DydxMarketMessageContents,
147 pub version: String,
148 pub message_id: u64,
149 pub connection_id: Option<String>,
150 pub id: Option<String>,
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize)]
155pub struct DydxWsMarketSubscribedData {
156 #[serde(rename = "type")]
157 pub msg_type: DydxWsMessageType,
158 pub connection_id: String,
159 pub message_id: u64,
160 pub channel: DydxWsChannel,
161 pub contents: Value, }
163
164#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct DydxAssetBalance {
167 pub symbol: Ustr,
168 pub side: OrderSide,
169 pub size: String,
170 #[serde(rename = "assetId")]
171 pub asset_id: String,
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
176pub struct DydxPerpetualPosition {
177 pub market: Ustr,
178 pub status: DydxPositionStatus,
179 pub side: PositionSide,
180 pub size: String,
181 #[serde(rename = "maxSize")]
182 pub max_size: String,
183 #[serde(rename = "entryPrice")]
184 pub entry_price: String,
185 #[serde(rename = "exitPrice")]
186 pub exit_price: Option<String>,
187 #[serde(rename = "realizedPnl")]
188 pub realized_pnl: String,
189 #[serde(rename = "unrealizedPnl")]
190 pub unrealized_pnl: String,
191 #[serde(rename = "createdAt")]
192 pub created_at: String,
193 #[serde(rename = "closedAt")]
194 pub closed_at: Option<String>,
195 #[serde(rename = "sumOpen")]
196 pub sum_open: String,
197 #[serde(rename = "sumClose")]
198 pub sum_close: String,
199 #[serde(rename = "netFunding")]
200 pub net_funding: String,
201}
202
203#[derive(Debug, Clone, Serialize, Deserialize)]
205pub struct DydxWsOrderSubaccountMessageContents {
206 pub id: String,
207 #[serde(rename = "subaccountId")]
208 pub subaccount_id: String,
209 #[serde(rename = "clientId")]
210 pub client_id: String,
211 #[serde(rename = "clobPairId")]
212 pub clob_pair_id: String,
213 pub side: OrderSide,
214 pub size: String,
215 pub price: String,
216 pub status: DydxOrderStatus,
217 #[serde(rename = "type")]
218 pub order_type: DydxOrderType,
219 #[serde(rename = "timeInForce")]
220 pub time_in_force: DydxTimeInForce,
221 #[serde(rename = "postOnly")]
222 pub post_only: bool,
223 #[serde(rename = "reduceOnly")]
224 pub reduce_only: bool,
225 #[serde(rename = "orderFlags")]
226 pub order_flags: String,
227 #[serde(rename = "goodTilBlock")]
228 pub good_til_block: Option<String>,
229 #[serde(rename = "goodTilBlockTime")]
230 pub good_til_block_time: Option<String>,
231 #[serde(rename = "createdAtHeight")]
232 pub created_at_height: String,
233 #[serde(rename = "clientMetadata")]
234 pub client_metadata: String,
235 #[serde(rename = "triggerPrice")]
236 pub trigger_price: Option<String>,
237 #[serde(rename = "totalFilled")]
238 pub total_filled: String,
239 #[serde(rename = "updatedAt")]
240 pub updated_at: Option<String>,
241 #[serde(rename = "updatedAtHeight")]
242 pub updated_at_height: Option<String>,
243}
244
245#[derive(Debug, Clone, Serialize, Deserialize)]
247pub struct DydxWsFillSubaccountMessageContents {
248 pub id: String,
249 #[serde(rename = "subaccountId")]
250 pub subaccount_id: String,
251 pub side: OrderSide,
252 pub liquidity: DydxLiquidity,
253 #[serde(rename = "type")]
254 pub fill_type: DydxFillType,
255 pub market: Ustr,
256 #[serde(rename = "marketType")]
257 pub market_type: DydxTickerType,
258 pub price: String,
259 pub size: String,
260 pub fee: String,
261 #[serde(rename = "createdAt")]
262 pub created_at: String,
263 #[serde(rename = "createdAtHeight")]
264 pub created_at_height: String,
265 #[serde(rename = "orderId")]
266 pub order_id: String,
267 #[serde(rename = "clientMetadata")]
268 pub client_metadata: String,
269}
270
271#[derive(Debug, Clone, Serialize, Deserialize)]
273pub struct DydxWsSubaccountsSubscribedContents {
274 pub subaccount: DydxSubaccountInfo,
275}
276
277#[derive(Debug, Clone, Serialize, Deserialize)]
279pub struct DydxSubaccountInfo {
280 pub address: String,
281 #[serde(rename = "subaccountNumber")]
282 pub subaccount_number: u32,
283 pub equity: String,
284 #[serde(rename = "freeCollateral")]
285 pub free_collateral: String,
286 #[serde(rename = "openPerpetualPositions")]
287 pub open_perpetual_positions: Option<HashMap<String, DydxPerpetualPosition>>,
288 #[serde(rename = "assetPositions")]
289 pub asset_positions: Option<HashMap<String, DydxAssetBalance>>,
290 #[serde(rename = "marginEnabled")]
291 pub margin_enabled: bool,
292 #[serde(rename = "updatedAtHeight")]
293 pub updated_at_height: String,
294 #[serde(rename = "latestProcessedBlockHeight")]
295 pub latest_processed_block_height: String,
296}
297
298#[derive(Debug, Clone, Serialize, Deserialize)]
300pub struct DydxWsSubaccountsSubscribed {
301 #[serde(rename = "type")]
302 pub msg_type: DydxWsMessageType,
303 pub connection_id: String,
304 pub message_id: u64,
305 pub channel: DydxWsChannel,
306 pub id: String,
307 pub contents: DydxWsSubaccountsSubscribedContents,
308}
309
310#[derive(Debug, Clone, Serialize, Deserialize)]
312pub struct DydxWsSubaccountsChannelContents {
313 pub orders: Option<Vec<DydxWsOrderSubaccountMessageContents>>,
314 pub fills: Option<Vec<DydxWsFillSubaccountMessageContents>>,
315}
316
317#[derive(Debug, Clone, Serialize, Deserialize)]
319pub struct DydxWsSubaccountsChannelData {
320 #[serde(rename = "type")]
321 pub msg_type: DydxWsMessageType,
322 pub connection_id: String,
323 pub message_id: u64,
324 pub id: String,
325 pub channel: DydxWsChannel,
326 pub version: String,
327 pub contents: DydxWsSubaccountsChannelContents,
328}