1use serde::{Deserialize, Serialize};
7use std::str::FromStr;
8
9#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
11pub enum MsgType {
12 Heartbeat,
14 TestRequest,
16 ResendRequest,
18 Reject,
20 BusinessMessageReject,
22 SequenceReset,
24 Logout,
26 ExecutionReport,
28 OrderCancelReject,
30 Logon,
32 NewOrderSingle,
34 OrderCancelRequest,
36 OrderCancelReplaceRequest,
38 QuoteRequest,
40 MarketDataRequest,
42 MarketDataSnapshotFullRefresh,
44 MarketDataIncrementalRefresh,
46 MarketDataRequestReject,
48 QuoteCancel,
50 MassQuoteAcknowledgement,
52 SecurityDefinitionRequest,
54 SecurityDefinition,
56 SecurityStatusRequest,
58 SecurityStatus,
60 MassQuote,
62 OrderMassCancelRequest,
64 OrderMassCancelReport,
66 SecurityListRequest,
68 SecurityList,
70 QuoteStatusReport,
72 RfqRequest,
74 QuoteRequestReject,
76 TradeCaptureReportRequest,
78 TradeCaptureReport,
80 TradeCaptureReportRequestAck,
82 OrderMassStatusRequest,
84 RequestForPositions,
86 PositionReport,
88 UserRequest,
90 UserResponse,
92 MmProtectionLimits,
94 MmProtectionLimitsResult,
96 MmProtectionReset,
98}
99
100impl MsgType {
101 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#[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#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
218pub enum ExecType {
219 New,
221 DoneForDay,
223 Canceled,
225 Replaced,
227 PendingCancel,
229 Stopped,
231 Rejected,
233 Suspended,
235 PendingNew,
237 Calculated,
239 Expired,
241 Restated,
243 PendingReplace,
245 Trade,
247 TradeCorrect,
249 TradeCancel,
251 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#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
308pub enum MDEntryType {
309 Bid,
311 Offer,
313 Trade,
315 IndexValue,
317 OpeningPrice,
319 ClosingPrice,
321 SettlementPrice,
323 TradingSessionHighPrice,
325 TradingSessionLowPrice,
327 TradingSessionVWAPPrice,
329 Imbalance,
331 TradeVolume,
333 OpenInterest,
335}
336
337#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
339pub enum SecurityType {
340 Future,
342 Option,
344 Spot,
346 Index,
348}
349
350impl_json_debug_pretty!(MsgType, ExecType, MDEntryType, SecurityType);
351impl_json_display!(MsgType, ExecType, MDEntryType, SecurityType);