1macro_rules! int_enum {
4 ($(#[$meta:meta])* $name:ident { $($variant:ident = $value:expr => $label:literal),+ $(,)? }) => {
5 $(#[$meta])*
6 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7 pub enum $name {
8 $($variant),+,
9 Unknown(i32),
10 }
11
12 impl $name {
13 pub const fn from_i32(value: i32) -> Self {
15 match value {
16 $($value => Self::$variant,)+
17 other => Self::Unknown(other),
18 }
19 }
20
21 pub const fn as_i32(self) -> i32 {
23 match self {
24 $(Self::$variant => $value,)+
25 Self::Unknown(value) => value,
26 }
27 }
28
29 pub const fn name(self) -> &'static str {
31 match self {
32 $(Self::$variant => $label,)+
33 Self::Unknown(_) => "UNKNOWN",
34 }
35 }
36 }
37 };
38}
39
40int_enum! {
41 TickType {
43 BidSize = 0 => "BID_SIZE",
44 Bid = 1 => "BID",
45 Ask = 2 => "ASK",
46 AskSize = 3 => "ASK_SIZE",
47 Last = 4 => "LAST",
48 LastSize = 5 => "LAST_SIZE",
49 High = 6 => "HIGH",
50 Low = 7 => "LOW",
51 Volume = 8 => "VOLUME",
52 Close = 9 => "CLOSE",
53 BidOptionComputation = 10 => "BID_OPTION_COMPUTATION",
54 AskOptionComputation = 11 => "ASK_OPTION_COMPUTATION",
55 LastOptionComputation = 12 => "LAST_OPTION_COMPUTATION",
56 ModelOption = 13 => "MODEL_OPTION",
57 Open = 14 => "OPEN",
58 Low13Week = 15 => "LOW_13_WEEK",
59 High13Week = 16 => "HIGH_13_WEEK",
60 Low26Week = 17 => "LOW_26_WEEK",
61 High26Week = 18 => "HIGH_26_WEEK",
62 Low52Week = 19 => "LOW_52_WEEK",
63 High52Week = 20 => "HIGH_52_WEEK",
64 AverageVolume = 21 => "AVG_VOLUME",
65 OpenInterest = 22 => "OPEN_INTEREST",
66 OptionHistoricalVolatility = 23 => "OPTION_HISTORICAL_VOL",
67 OptionImpliedVolatility = 24 => "OPTION_IMPLIED_VOL",
68 OptionBidExchange = 25 => "OPTION_BID_EXCH",
69 OptionAskExchange = 26 => "OPTION_ASK_EXCH",
70 OptionCallOpenInterest = 27 => "OPTION_CALL_OPEN_INTEREST",
71 OptionPutOpenInterest = 28 => "OPTION_PUT_OPEN_INTEREST",
72 OptionCallVolume = 29 => "OPTION_CALL_VOLUME",
73 OptionPutVolume = 30 => "OPTION_PUT_VOLUME",
74 IndexFuturePremium = 31 => "INDEX_FUTURE_PREMIUM",
75 BidExchange = 32 => "BID_EXCH",
76 AskExchange = 33 => "ASK_EXCH",
77 AuctionVolume = 34 => "AUCTION_VOLUME",
78 AuctionPrice = 35 => "AUCTION_PRICE",
79 AuctionImbalance = 36 => "AUCTION_IMBALANCE",
80 MarkPrice = 37 => "MARK_PRICE",
81 BidEfpComputation = 38 => "BID_EFP_COMPUTATION",
82 AskEfpComputation = 39 => "ASK_EFP_COMPUTATION",
83 LastEfpComputation = 40 => "LAST_EFP_COMPUTATION",
84 OpenEfpComputation = 41 => "OPEN_EFP_COMPUTATION",
85 HighEfpComputation = 42 => "HIGH_EFP_COMPUTATION",
86 LowEfpComputation = 43 => "LOW_EFP_COMPUTATION",
87 CloseEfpComputation = 44 => "CLOSE_EFP_COMPUTATION",
88 LastTimestamp = 45 => "LAST_TIMESTAMP",
89 Shortable = 46 => "SHORTABLE",
90 NotUsed = 47 => "NOT_USED",
91 RealTimeVolume = 48 => "RT_VOLUME",
92 Halted = 49 => "HALTED",
93 BidYield = 50 => "BID_YIELD",
94 AskYield = 51 => "ASK_YIELD",
95 LastYield = 52 => "LAST_YIELD",
96 CustomerOptionComputation = 53 => "CUST_OPTION_COMPUTATION",
97 TradeCount = 54 => "TRADE_COUNT",
98 TradeRate = 55 => "TRADE_RATE",
99 VolumeRate = 56 => "VOLUME_RATE",
100 LastRthTrade = 57 => "LAST_RTH_TRADE",
101 RealTimeHistoricalVolatility = 58 => "RT_HISTORICAL_VOL",
102 IbDividends = 59 => "IB_DIVIDENDS",
103 BondFactorMultiplier = 60 => "BOND_FACTOR_MULTIPLIER",
104 RegulatoryImbalance = 61 => "REGULATORY_IMBALANCE",
105 NewsTick = 62 => "NEWS_TICK",
106 ShortTermVolume3Min = 63 => "SHORT_TERM_VOLUME_3_MIN",
107 ShortTermVolume5Min = 64 => "SHORT_TERM_VOLUME_5_MIN",
108 ShortTermVolume10Min = 65 => "SHORT_TERM_VOLUME_10_MIN",
109 DelayedBid = 66 => "DELAYED_BID",
110 DelayedAsk = 67 => "DELAYED_ASK",
111 DelayedLast = 68 => "DELAYED_LAST",
112 DelayedBidSize = 69 => "DELAYED_BID_SIZE",
113 DelayedAskSize = 70 => "DELAYED_ASK_SIZE",
114 DelayedLastSize = 71 => "DELAYED_LAST_SIZE",
115 DelayedHigh = 72 => "DELAYED_HIGH",
116 DelayedLow = 73 => "DELAYED_LOW",
117 DelayedVolume = 74 => "DELAYED_VOLUME",
118 DelayedClose = 75 => "DELAYED_CLOSE",
119 DelayedOpen = 76 => "DELAYED_OPEN",
120 RealTimeTradeVolume = 77 => "RT_TRD_VOLUME",
121 CreditmanMarkPrice = 78 => "CREDITMAN_MARK_PRICE",
122 CreditmanSlowMarkPrice = 79 => "CREDITMAN_SLOW_MARK_PRICE",
123 DelayedBidOption = 80 => "DELAYED_BID_OPTION",
124 DelayedAskOption = 81 => "DELAYED_ASK_OPTION",
125 DelayedLastOption = 82 => "DELAYED_LAST_OPTION",
126 DelayedModelOption = 83 => "DELAYED_MODEL_OPTION",
127 LastExchange = 84 => "LAST_EXCH",
128 LastRegulatoryTime = 85 => "LAST_REG_TIME",
129 FuturesOpenInterest = 86 => "FUTURES_OPEN_INTEREST",
130 AverageOptionVolume = 87 => "AVG_OPT_VOLUME",
131 DelayedLastTimestamp = 88 => "DELAYED_LAST_TIMESTAMP",
132 ShortableShares = 89 => "SHORTABLE_SHARES",
133 DelayedHalted = 90 => "DELAYED_HALTED",
134 Reuters2MutualFunds = 91 => "REUTERS_2_MUTUAL_FUNDS",
135 EtfNavClose = 92 => "ETF_NAV_CLOSE",
136 EtfNavPriorClose = 93 => "ETF_NAV_PRIOR_CLOSE",
137 EtfNavBid = 94 => "ETF_NAV_BID",
138 EtfNavAsk = 95 => "ETF_NAV_ASK",
139 EtfNavLast = 96 => "ETF_NAV_LAST",
140 EtfFrozenNavLast = 97 => "ETF_FROZEN_NAV_LAST",
141 EtfNavHigh = 98 => "ETF_NAV_HIGH",
142 EtfNavLow = 99 => "ETF_NAV_LOW",
143 SocialMarketAnalytics = 100 => "SOCIAL_MARKET_ANALYTICS",
144 EstimatedIpoMidpoint = 101 => "ESTIMATED_IPO_MIDPOINT",
145 FinalIpoLast = 102 => "FINAL_IPO_LAST",
146 DelayedYieldBid = 103 => "DELAYED_YIELD_BID",
147 DelayedYieldAsk = 104 => "DELAYED_YIELD_ASK",
148 OddLotBid = 105 => "ODD_LOT_BID",
149 OddLotAsk = 106 => "ODD_LOT_ASK",
150 OddLotBidSize = 107 => "ODD_LOT_BID_SIZE",
151 OddLotAskSize = 108 => "ODD_LOT_ASK_SIZE",
152 OddLotBidExchange = 109 => "ODD_LOT_BID_EXCH",
153 OddLotAskExchange = 110 => "ODD_LOT_ASK_EXCH",
154 NotSet = 111 => "NOT_SET"
155 }
156}
157
158int_enum! {
159 MarketDataType {
161 RealTime = 1 => "REALTIME",
162 Frozen = 2 => "FROZEN",
163 Delayed = 3 => "DELAYED",
164 DelayedFrozen = 4 => "DELAYED_FROZEN"
165 }
166}
167
168int_enum! {
169 FaDataType {
171 Groups = 1 => "GROUPS",
172 Aliases = 3 => "ALIASES"
173 }
174}
175
176int_enum! {
177 Liquidities {
179 None = 0 => "None",
180 Added = 1 => "Added",
181 Remove = 2 => "Remove",
182 RoundedOut = 3 => "RoundedOut"
183 }
184}
185
186int_enum! {
187 OptionExerciseType {
189 None = -1 => "None",
190 Exercise = 1 => "Exercise",
191 Lapse = 2 => "Lapse",
192 DoNothing = 3 => "DoNothing",
193 Assigned = 100 => "Assigned",
194 AutoexerciseClearing = 101 => "AutoexerciseClearing",
195 Expired = 102 => "Expired",
196 Netting = 103 => "Netting",
197 AutoexerciseTrading = 200 => "AutoexerciseTrading"
198 }
199}
200
201int_enum! {
202 TriggerMethod {
204 Default = 0 => "Default",
205 DoubleBidAsk = 1 => "DoubleBidAsk",
206 Last = 2 => "Last",
207 DoubleLast = 3 => "DoubleLast",
208 BidAsk = 4 => "BidAsk",
209 LastBidAsk = 7 => "LastBidAsk",
210 MidPoint = 8 => "MidPoint"
211 }
212}
213
214#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
216pub enum FundAssetType {
217 None,
218 Others,
219 MoneyMarket,
220 FixedIncome,
221 MultiAsset,
222 Equity,
223 Sector,
224 Guaranteed,
225 Alternative,
226 Unknown,
227}
228
229impl FundAssetType {
230 pub const fn code(self) -> &'static str {
231 match self {
232 Self::None => "None",
233 Self::Others => "000",
234 Self::MoneyMarket => "001",
235 Self::FixedIncome => "002",
236 Self::MultiAsset => "003",
237 Self::Equity => "004",
238 Self::Sector => "005",
239 Self::Guaranteed => "006",
240 Self::Alternative => "007",
241 Self::Unknown => "",
242 }
243 }
244
245 pub fn from_code(code: &str) -> Self {
246 match code {
247 "None" => Self::None,
248 "000" => Self::Others,
249 "001" => Self::MoneyMarket,
250 "002" => Self::FixedIncome,
251 "003" => Self::MultiAsset,
252 "004" => Self::Equity,
253 "005" => Self::Sector,
254 "006" => Self::Guaranteed,
255 "007" => Self::Alternative,
256 _ => Self::Unknown,
257 }
258 }
259}
260
261#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
263pub enum FundDistributionPolicyIndicator {
264 None,
265 AccumulationFund,
266 IncomeFund,
267 Unknown,
268}
269
270impl FundDistributionPolicyIndicator {
271 pub const fn code(self) -> &'static str {
272 match self {
273 Self::None => "None",
274 Self::AccumulationFund => "N",
275 Self::IncomeFund => "Y",
276 Self::Unknown => "",
277 }
278 }
279
280 pub fn from_code(code: &str) -> Self {
281 match code {
282 "None" => Self::None,
283 "N" => Self::AccumulationFund,
284 "Y" => Self::IncomeFund,
285 _ => Self::Unknown,
286 }
287 }
288}
289
290#[cfg(test)]
291mod tests {
292 use super::*;
293
294 #[test]
295 fn unknown_wire_values_are_preserved() {
296 assert_eq!(TickType::from_i32(999).as_i32(), 999);
297 assert_eq!(MarketDataType::from_i32(3), MarketDataType::Delayed);
298 }
299
300 #[test]
301 fn string_enum_codes_round_trip() {
302 assert_eq!(FundAssetType::from_code("004"), FundAssetType::Equity);
303 assert_eq!(FundDistributionPolicyIndicator::IncomeFund.code(), "Y");
304 }
305}