1#![allow(non_camel_case_types)]
9
10use std::fmt;
11use std::str::FromStr;
12
13macro_rules! wire_enum {
14 (
15 $(#[$meta:meta])*
16 $name:ident,
17 display_name = $display:expr,
18 { $( $variant:ident = $wire:literal [ $( $alias:literal ),* ] ),* $(,)? }
19 ) => {
20 $(#[$meta])*
21 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23 pub enum $name {
24 $( #[cfg_attr(feature = "serde", serde(rename = $wire))] $variant ),*
25 }
26
27 impl $name {
28 pub const ALL: &'static [Self] = &[ $( Self::$variant ),* ];
30
31 pub fn as_str(&self) -> &'static str {
33 match self { $( Self::$variant => $wire ),* }
34 }
35
36 pub fn chinese_alias(&self) -> &'static [&'static str] {
38 match self { $( Self::$variant => &[ $( $alias ),* ] ),* }
39 }
40
41 pub const DISPLAY: &'static str = $display;
43 }
44
45 impl fmt::Display for $name {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 f.write_str(self.as_str())
48 }
49 }
50
51 impl FromStr for $name {
52 type Err = EnumParseError;
53 fn from_str(s: &str) -> Result<Self, Self::Err> {
56 $( if s == $wire { return Ok(Self::$variant); } )*
57 $(
58 $( if s == $alias { return Ok(Self::$variant); } )*
59 )*
60 Err(EnumParseError { input: s.to_string(), type_name: $display })
61 }
62 }
63 };
64}
65
66#[derive(Debug, Clone, PartialEq, Eq)]
68pub struct EnumParseError {
69 pub input: String,
71 pub type_name: &'static str,
73}
74
75impl fmt::Display for EnumParseError {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 write!(f, "unknown {} value: {:?}", self.type_name, self.input)
78 }
79}
80
81impl std::error::Error for EnumParseError {}
82
83wire_enum!(
84 Direction, display_name = "Direction",
86 {
87 LONG = "LONG" ["多"],
88 SHORT = "SHORT" ["空"],
89 NET = "NET" ["净"]
90 }
91);
92
93wire_enum!(
94 Offset, display_name = "Offset",
96 {
97 NONE = "NONE" [""],
98 OPEN = "OPEN" ["开"],
99 CLOSE = "CLOSE" ["平"],
100 CLOSETODAY = "CLOSETODAY" ["平今"],
101 CLOSEYESTERDAY = "CLOSEYESTERDAY" ["平昨"]
102 }
103);
104
105wire_enum!(
106 Status, display_name = "Status",
108 {
109 SUBMITTING = "SUBMITTING" ["提交中"],
110 NOTTRADED = "NOTTRADED" ["未成交"],
111 PARTTRADED = "PARTTRADED" ["部分成交"],
112 ALLTRADED = "ALLTRADED" ["全部成交"],
113 CANCELLED = "CANCELLED" ["已撤销"],
114 REJECTED = "REJECTED" ["拒单"]
115 }
116);
117
118wire_enum!(
119 Asset, display_name = "Asset",
121 {
122 EQUITY = "EQUITY" ["股票"],
123 BOND = "BOND" ["债券"],
124 FUTURES = "FUTURES" ["期货"],
125 OPTION = "OPTION" ["期权"],
126 FOREX = "FOREX" ["外汇"]
127 }
128);
129
130wire_enum!(
131 InstrumentType, display_name = "InstrumentType",
133 {
134 STOCK = "STOCK" ["股票"],
135 ETF = "ETF" [],
136 INDEX = "INDEX" ["指数"],
137 FUTURES_CONTRACT = "FUTURES_CONTRACT" ["期货合约"],
138 MAIN_CONTRACT = "MAIN_CONTRACT" ["主力合约"],
139 CONTINUOUS_CONTRACT = "CONTINUOUS_CONTRACT" ["连续合约"],
140 OPTION_CONTRACT = "OPTION_CONTRACT" ["期权合约"],
141 BOND = "BOND" ["债券"],
142 CONVERTIBLE_BOND = "CONVERTIBLE_BOND" ["可转债"],
143 SPREAD = "SPREAD" ["价差组合"],
144 HEDGE = "HEDGE" ["对冲组合"]
145 }
146);
147
148wire_enum!(
149 OrderType, display_name = "OrderType",
151 {
152 LIMIT = "LIMIT" ["限价"],
153 MARKET = "MARKET" ["市价"],
154 STOP = "STOP" [],
155 FAK = "FAK" [],
156 FOK = "FOK" [],
157 RFQ = "RFQ" ["询价"]
158 }
159);
160
161wire_enum!(
162 OptionType, display_name = "OptionType",
164 {
165 CALL = "CALL" ["看涨期权"],
166 PUT = "PUT" ["看跌期权"]
167 }
168);
169
170wire_enum!(
171 Currency, display_name = "Currency",
173 {
174 USD = "USD" [],
175 HKD = "HKD" [],
176 CNY = "CNY" [],
177 CAD = "CAD" []
178 }
179);
180
181wire_enum!(
182 Exchange, display_name = "Exchange",
187 {
188 CFFEX = "CFFEX" [],
189 SHFE = "SHFE" [],
190 CZCE = "CZCE" [],
191 DCE = "DCE" [],
192 INE = "INE" [],
193 GFEX = "GFEX" [],
194 SSE = "SSE" [],
195 SZSE = "SZSE" [],
196 BSE = "BSE" [],
197 SHHK = "SHHK" [],
198 SZHK = "SZHK" [],
199 SGE = "SGE" [],
200 WXE = "WXE" [],
201 CFETS = "CFETS" [],
202 XBOND = "XBOND" [],
203 SMART = "SMART" [],
204 NYSE = "NYSE" [],
205 NASDAQ = "NASDAQ" [],
206 ARCA = "ARCA" [],
207 EDGEA = "EDGEA" [],
208 ISLAND = "ISLAND" [],
209 BATS = "BATS" [],
210 IEX = "IEX" [],
211 AMEX = "AMEX" [],
212 TSE = "TSE" [],
213 NYMEX = "NYMEX" [],
214 COMEX = "COMEX" [],
215 GLOBEX = "GLOBEX" [],
216 IDEALPRO = "IDEALPRO" [],
217 CME = "CME" [],
218 ICE = "ICE" [],
219 SEHK = "SEHK" [],
220 HKFE = "HKFE" [],
221 SGX = "SGX" [],
222 CBOT = "CBT" [],
223 CBOE = "CBOE" [],
224 CFE = "CFE" [],
225 DME = "DME" [],
226 EUREX = "EUX" [],
227 APEX = "APEX" [],
228 LME = "LME" [],
229 BMD = "BMD" [],
230 TOCOM = "TOCOM" [],
231 EUNX = "EUNX" [],
232 KRX = "KRX" [],
233 OTC = "OTC" [],
234 IBKRATS = "IBKRATS" [],
235 LOCAL = "LOCAL" [],
236 ETF_INDEX = "ETF_index" [],
237 SW = "SW" []
238 }
239);
240
241wire_enum!(
242 Interval, display_name = "Interval",
244 {
245 TICK = "TICK" [],
246 MINUTE = "MINUTE" [],
247 MINUTE_5 = "MINUTE_5" [],
248 MINUTE_15 = "MINUTE_15" [],
249 MINUTE_30 = "MINUTE_30" [],
250 HOUR = "HOUR" [],
251 DAILY = "DAILY" [],
252 WEEKLY = "WEEKLY" []
253 }
254);
255
256impl Interval {
257 pub fn seconds(&self) -> i64 {
260 match self {
261 Self::TICK => 0,
262 Self::MINUTE => 60,
263 Self::MINUTE_5 => 300,
264 Self::MINUTE_15 => 900,
265 Self::MINUTE_30 => 1800,
266 Self::HOUR => 3600,
267 Self::DAILY => 86400,
268 Self::WEEKLY => 604800,
269 }
270 }
271}
272
273pub const ACTIVE_STATUSES: [Status; 3] =
275 [Status::SUBMITTING, Status::NOTTRADED, Status::PARTTRADED];
276
277impl Status {
278 pub fn is_active(&self) -> bool {
280 ACTIVE_STATUSES.contains(self)
281 }
282}
283
284impl Default for Exchange {
288 fn default() -> Self {
289 Self::LOCAL
290 }
291}
292
293impl Default for OrderType {
295 fn default() -> Self {
296 Self::LIMIT
297 }
298}
299
300impl Default for Offset {
302 fn default() -> Self {
303 Self::NONE
304 }
305}
306
307impl Default for Status {
309 fn default() -> Self {
310 Self::SUBMITTING
311 }
312}
313
314impl Default for Direction {
316 fn default() -> Self {
317 Self::NET
318 }
319}
320
321impl Default for Asset {
323 fn default() -> Self {
324 Self::EQUITY
325 }
326}