deribit_fix/model/
types.rs

1/******************************************************************************
2   Author: Joaquín Béjar García
3   Email: jb@taunais.com
4   Date: 21/7/25
5******************************************************************************/
6use deribit_base::{impl_json_debug_pretty, impl_json_display};
7use serde::{Deserialize, Serialize};
8use std::str::FromStr;
9
10/// FIX message type identifiers
11#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12pub enum MsgType {
13    /// Heartbeat (0)
14    Heartbeat,
15    /// Test Request (1)
16    TestRequest,
17    /// Resend Request (2)
18    ResendRequest,
19    /// Reject (3)
20    Reject,
21    /// Business Message Reject (j)
22    BusinessMessageReject,
23    /// Sequence Reset (4)
24    SequenceReset,
25    /// Logout (5)
26    Logout,
27    /// Execution Report (8)
28    ExecutionReport,
29    /// Order Cancel Reject (9)
30    OrderCancelReject,
31    /// Logon (A)
32    Logon,
33    /// New Order Single (D)
34    NewOrderSingle,
35    /// Order Cancel Request (F)
36    OrderCancelRequest,
37    /// Order Cancel/Replace Request (G)
38    OrderCancelReplaceRequest,
39    /// Quote Request (R)
40    QuoteRequest,
41    /// Market Data Request (V)
42    MarketDataRequest,
43    /// Market Data Snapshot/Full Refresh (W)
44    MarketDataSnapshotFullRefresh,
45    /// Market Data Incremental Refresh (X)
46    MarketDataIncrementalRefresh,
47    /// Market Data Request Reject (Y)
48    MarketDataRequestReject,
49    /// Quote Cancel (Z)
50    QuoteCancel,
51    /// Mass Quote Acknowledgement (b)
52    MassQuoteAcknowledgement,
53    /// Security Definition Request (c)
54    SecurityDefinitionRequest,
55    /// Security Definition (d)
56    SecurityDefinition,
57    /// Security Status Request (e)
58    SecurityStatusRequest,
59    /// Security Status (f)
60    SecurityStatus,
61    /// Mass Quote (i)
62    MassQuote,
63    /// Order Mass Cancel Request (q)
64    OrderMassCancelRequest,
65    /// Order Mass Cancel Report (r)
66    OrderMassCancelReport,
67    /// Security List Request (x)
68    SecurityListRequest,
69    /// Security List (y)
70    SecurityList,
71    /// Quote Status Report (AI)
72    QuoteStatusReport,
73    /// RFQ Request (AH)
74    RfqRequest,
75    /// Quote Request Reject (AG)
76    QuoteRequestReject,
77    /// Trade Capture Report Request (AD)
78    TradeCaptureReportRequest,
79    /// Trade Capture Report (AE)
80    TradeCaptureReport,
81    /// Trade Capture Report Request Ack (AQ)
82    TradeCaptureReportRequestAck,
83    /// Order Mass Status Request (AF)
84    OrderMassStatusRequest,
85    /// Request For Positions (AN)
86    RequestForPositions,
87    /// Position Report (AP)
88    PositionReport,
89    /// User Request (BE)
90    UserRequest,
91    /// User Response (BF)
92    UserResponse,
93    /// MM Protection Limits (MM)
94    MmProtectionLimits,
95    /// MM Protection Limits Result/Reject (MR)
96    MmProtectionLimitsResult,
97    /// MM Protection Reset (MZ)
98    MmProtectionReset,
99}
100
101impl MsgType {
102    /// Convert to FIX message type string
103    pub fn as_str(&self) -> &'static str {
104        match self {
105            MsgType::Heartbeat => "0",
106            MsgType::TestRequest => "1",
107            MsgType::ResendRequest => "2",
108            MsgType::Reject => "3",
109            MsgType::BusinessMessageReject => "j",
110            MsgType::SequenceReset => "4",
111            MsgType::Logout => "5",
112            MsgType::ExecutionReport => "8",
113            MsgType::OrderCancelReject => "9",
114            MsgType::Logon => "A",
115            MsgType::NewOrderSingle => "D",
116            MsgType::OrderCancelRequest => "F",
117            MsgType::OrderCancelReplaceRequest => "G",
118            MsgType::QuoteRequest => "R",
119            MsgType::MarketDataRequest => "V",
120            MsgType::MarketDataSnapshotFullRefresh => "W",
121            MsgType::MarketDataIncrementalRefresh => "X",
122            MsgType::MarketDataRequestReject => "Y",
123            MsgType::QuoteCancel => "Z",
124            MsgType::MassQuoteAcknowledgement => "b",
125            MsgType::SecurityDefinitionRequest => "c",
126            MsgType::SecurityDefinition => "d",
127            MsgType::SecurityStatusRequest => "e",
128            MsgType::SecurityStatus => "f",
129            MsgType::MassQuote => "i",
130            MsgType::OrderMassCancelRequest => "q",
131            MsgType::OrderMassCancelReport => "r",
132            MsgType::SecurityListRequest => "x",
133            MsgType::SecurityList => "y",
134            MsgType::QuoteStatusReport => "AI",
135            MsgType::RfqRequest => "AH",
136            MsgType::QuoteRequestReject => "AG",
137            MsgType::TradeCaptureReportRequest => "AD",
138            MsgType::TradeCaptureReport => "AE",
139            MsgType::TradeCaptureReportRequestAck => "AQ",
140            MsgType::OrderMassStatusRequest => "AF",
141            MsgType::RequestForPositions => "AN",
142            MsgType::PositionReport => "AP",
143            MsgType::UserRequest => "BE",
144            MsgType::UserResponse => "BF",
145            MsgType::MmProtectionLimits => "MM",
146            MsgType::MmProtectionLimitsResult => "MR",
147            MsgType::MmProtectionReset => "MZ",
148        }
149    }
150}
151
152/// Error type for parsing MsgType from string
153#[derive(Debug, Clone, PartialEq, Eq)]
154pub struct ParseMsgTypeError(pub String);
155
156impl std::fmt::Display for ParseMsgTypeError {
157    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
158        write!(f, "Unknown message type: {}", self.0)
159    }
160}
161
162impl std::error::Error for ParseMsgTypeError {}
163
164impl FromStr for MsgType {
165    type Err = ParseMsgTypeError;
166
167    fn from_str(s: &str) -> Result<Self, Self::Err> {
168        match s {
169            "0" => Ok(MsgType::Heartbeat),
170            "1" => Ok(MsgType::TestRequest),
171            "2" => Ok(MsgType::ResendRequest),
172            "3" => Ok(MsgType::Reject),
173            "j" => Ok(MsgType::BusinessMessageReject),
174            "4" => Ok(MsgType::SequenceReset),
175            "5" => Ok(MsgType::Logout),
176            "8" => Ok(MsgType::ExecutionReport),
177            "9" => Ok(MsgType::OrderCancelReject),
178            "A" => Ok(MsgType::Logon),
179            "D" => Ok(MsgType::NewOrderSingle),
180            "F" => Ok(MsgType::OrderCancelRequest),
181            "G" => Ok(MsgType::OrderCancelReplaceRequest),
182            "R" => Ok(MsgType::QuoteRequest),
183            "V" => Ok(MsgType::MarketDataRequest),
184            "W" => Ok(MsgType::MarketDataSnapshotFullRefresh),
185            "X" => Ok(MsgType::MarketDataIncrementalRefresh),
186            "Y" => Ok(MsgType::MarketDataRequestReject),
187            "Z" => Ok(MsgType::QuoteCancel),
188            "b" => Ok(MsgType::MassQuoteAcknowledgement),
189            "c" => Ok(MsgType::SecurityDefinitionRequest),
190            "d" => Ok(MsgType::SecurityDefinition),
191            "e" => Ok(MsgType::SecurityStatusRequest),
192            "f" => Ok(MsgType::SecurityStatus),
193            "i" => Ok(MsgType::MassQuote),
194            "q" => Ok(MsgType::OrderMassCancelRequest),
195            "r" => Ok(MsgType::OrderMassCancelReport),
196            "x" => Ok(MsgType::SecurityListRequest),
197            "y" => Ok(MsgType::SecurityList),
198            "AI" => Ok(MsgType::QuoteStatusReport),
199            "AH" => Ok(MsgType::RfqRequest),
200            "AG" => Ok(MsgType::QuoteRequestReject),
201            "AD" => Ok(MsgType::TradeCaptureReportRequest),
202            "AE" => Ok(MsgType::TradeCaptureReport),
203            "AQ" => Ok(MsgType::TradeCaptureReportRequestAck),
204            "AF" => Ok(MsgType::OrderMassStatusRequest),
205            "AN" => Ok(MsgType::RequestForPositions),
206            "AP" => Ok(MsgType::PositionReport),
207            "BE" => Ok(MsgType::UserRequest),
208            "BF" => Ok(MsgType::UserResponse),
209            "MM" => Ok(MsgType::MmProtectionLimits),
210            "MR" => Ok(MsgType::MmProtectionLimitsResult),
211            "MZ" => Ok(MsgType::MmProtectionReset),
212            _ => Err(ParseMsgTypeError(s.to_string())),
213        }
214    }
215}
216
217/// Execution type enumeration
218#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
219pub enum ExecType {
220    /// New order
221    New,
222    /// Order done for day
223    DoneForDay,
224    /// Order canceled
225    Canceled,
226    /// Order replaced
227    Replaced,
228    /// Pending cancel
229    PendingCancel,
230    /// Order stopped
231    Stopped,
232    /// Order rejected
233    Rejected,
234    /// Order suspended
235    Suspended,
236    /// Pending new order
237    PendingNew,
238    /// Calculated
239    Calculated,
240    /// Order expired
241    Expired,
242    /// Order restated
243    Restated,
244    /// Pending replace
245    PendingReplace,
246    /// Trade execution
247    Trade,
248    /// Trade correction
249    TradeCorrect,
250    /// Trade cancellation
251    TradeCancel,
252    /// Order status update
253    OrderStatus,
254}
255
256impl From<ExecType> for char {
257    fn from(exec_type: ExecType) -> Self {
258        match exec_type {
259            ExecType::New => '0',
260            ExecType::DoneForDay => '3',
261            ExecType::Canceled => '4',
262            ExecType::Replaced => '5',
263            ExecType::PendingCancel => '6',
264            ExecType::Stopped => '7',
265            ExecType::Rejected => '8',
266            ExecType::Suspended => '9',
267            ExecType::PendingNew => 'A',
268            ExecType::Calculated => 'B',
269            ExecType::Expired => 'C',
270            ExecType::Restated => 'D',
271            ExecType::PendingReplace => 'E',
272            ExecType::Trade => 'F',
273            ExecType::TradeCorrect => 'G',
274            ExecType::TradeCancel => 'H',
275            ExecType::OrderStatus => 'I',
276        }
277    }
278}
279
280impl TryFrom<char> for ExecType {
281    type Error = String;
282
283    fn try_from(value: char) -> Result<Self, Self::Error> {
284        match value {
285            '0' => Ok(ExecType::New),
286            '3' => Ok(ExecType::DoneForDay),
287            '4' => Ok(ExecType::Canceled),
288            '5' => Ok(ExecType::Replaced),
289            '6' => Ok(ExecType::PendingCancel),
290            '7' => Ok(ExecType::Stopped),
291            '8' => Ok(ExecType::Rejected),
292            '9' => Ok(ExecType::Suspended),
293            'A' => Ok(ExecType::PendingNew),
294            'B' => Ok(ExecType::Calculated),
295            'C' => Ok(ExecType::Expired),
296            'D' => Ok(ExecType::Restated),
297            'E' => Ok(ExecType::PendingReplace),
298            'F' => Ok(ExecType::Trade),
299            'G' => Ok(ExecType::TradeCorrect),
300            'H' => Ok(ExecType::TradeCancel),
301            'I' => Ok(ExecType::OrderStatus),
302            _ => Err(format!("Invalid ExecType: {}", value)),
303        }
304    }
305}
306
307/// Market data entry type
308#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
309pub enum MDEntryType {
310    /// Bid price
311    Bid,
312    /// Offer/ask price
313    Offer,
314    /// Trade price
315    Trade,
316    /// Index value
317    IndexValue,
318    /// Opening price
319    OpeningPrice,
320    /// Closing price
321    ClosingPrice,
322    /// Settlement price
323    SettlementPrice,
324    /// Trading session high price
325    TradingSessionHighPrice,
326    /// Trading session low price
327    TradingSessionLowPrice,
328    /// Trading session VWAP price
329    TradingSessionVWAPPrice,
330    /// Order imbalance
331    Imbalance,
332    /// Trade volume
333    TradeVolume,
334    /// Open interest
335    OpenInterest,
336}
337
338/// Security type enumeration
339#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
340pub enum SecurityType {
341    /// Future contract
342    Future,
343    /// Option contract
344    Option,
345    /// Spot trading
346    Spot,
347    /// Index instrument
348    Index,
349}
350
351impl_json_debug_pretty!(MsgType, ExecType, MDEntryType, SecurityType);
352impl_json_display!(MsgType, ExecType, MDEntryType, SecurityType);