Skip to main content

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