1use crate::types::{ModifyOrderOp, OrderType, TrdEnv, TrdSide};
7
8pub const TRD_ENV_PARSE_CHOICES: &str = "real|simulate|sim";
9pub const TRD_SIDE_PARSE_CHOICES: &str = "BUY|SELL|SELL_SHORT|SHORT|BUY_BACK|COVER";
10pub const ORDER_TYPE_PARSE_CHOICES: &str = "NORMAL|LIMIT|MARKET|ABSOLUTE_LIMIT|AUCTION|\
11AUCTION_LIMIT|SPECIAL_LIMIT|SPECIAL_LIMIT_ALL|STOP|STOP_LIMIT|MIT|LIT|\
12TRAILING_STOP|TRAILING_STOP_LIMIT|TWAP_MARKET|TWAP_LIMIT|VWAP_MARKET|VWAP_LIMIT \
13or compact aliases / official OrderType int";
14pub const MODIFY_OP_PARSE_CHOICES: &str = "NORMAL|MODIFY|CANCEL|DISABLE|ENABLE|DELETE";
15
16pub const ORDER_TYPE_INT_VALUES: &[i32] =
18 &[1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];
19
20#[must_use]
21pub fn parse_trd_env(raw: &str) -> Option<TrdEnv> {
22 match raw.trim().to_ascii_lowercase().as_str() {
23 "simulate" | "sim" => Some(TrdEnv::Simulate),
24 "real" => Some(TrdEnv::Real),
25 _ => None,
26 }
27}
28
29#[must_use]
30pub fn parse_trd_side(raw: &str) -> Option<TrdSide> {
31 match raw.trim().to_ascii_uppercase().as_str() {
32 "BUY" => Some(TrdSide::Buy),
33 "SELL" => Some(TrdSide::Sell),
34 "SELL_SHORT" | "SHORT" => Some(TrdSide::SellShort),
35 "BUY_BACK" | "COVER" => Some(TrdSide::BuyBack),
36 _ => None,
37 }
38}
39
40#[must_use]
41pub fn parse_order_type(raw: &str) -> Option<OrderType> {
42 let upper = raw.trim().to_ascii_uppercase();
43 let compact = upper.replace(['_', '-'], "");
44 match upper.as_str() {
45 "NORMAL" | "LIMIT" => Some(OrderType::Normal),
46 "MARKET" => Some(OrderType::Market),
47 "ABSOLUTE_LIMIT" => Some(OrderType::AbsoluteLimit),
48 "AUCTION" => Some(OrderType::Auction),
49 "AUCTION_LIMIT" => Some(OrderType::AuctionLimit),
50 "SPECIAL_LIMIT" => Some(OrderType::SpecialLimit),
51 "SPECIAL_LIMIT_ALL" => Some(OrderType::SpecialLimitAll),
52 "STOP" => Some(OrderType::Stop),
53 "STOP_LIMIT" | "STOP-LIMIT" => Some(OrderType::StopLimit),
54 "MIT" | "MARKET_IF_TOUCHED" => Some(OrderType::MarketifTouched),
55 "LIT" | "LIMIT_IF_TOUCHED" => Some(OrderType::LimitifTouched),
56 "TRAIL" | "TRAILING_STOP" | "TRAILING-STOP" => Some(OrderType::TrailingStop),
57 "TRAIL_LIMIT" | "TRAILING_STOP_LIMIT" => Some(OrderType::TrailingStopLimit),
58 "TWAP_MARKET" => Some(OrderType::TwapMarket),
59 "TWAP_LIMIT" => Some(OrderType::TwapLimit),
60 "VWAP_MARKET" => Some(OrderType::VwapMarket),
61 "VWAP_LIMIT" => Some(OrderType::VwapLimit),
62 _ => match compact.as_str() {
63 "ABSOLUTELIMIT" => Some(OrderType::AbsoluteLimit),
64 "AUCTIONLIMIT" => Some(OrderType::AuctionLimit),
65 "SPECIALLIMIT" => Some(OrderType::SpecialLimit),
66 "SPECIALLIMITALL" => Some(OrderType::SpecialLimitAll),
67 "STOPLIMIT" => Some(OrderType::StopLimit),
68 "MARKETIFTOUCHED" => Some(OrderType::MarketifTouched),
69 "LIMITIFTOUCHED" => Some(OrderType::LimitifTouched),
70 "TRAILINGSTOP" => Some(OrderType::TrailingStop),
71 "TRAILLIMIT" | "TRAILINGSTOPLIMIT" => Some(OrderType::TrailingStopLimit),
72 "TWAPMARKET" => Some(OrderType::TwapMarket),
73 "TWAPLIMIT" => Some(OrderType::TwapLimit),
74 "VWAPMARKET" => Some(OrderType::VwapMarket),
75 "VWAPLIMIT" => Some(OrderType::VwapLimit),
76 _ => upper.parse::<i32>().ok().and_then(order_type_from_i32),
77 },
78 }
79}
80
81#[must_use]
82pub fn order_type_from_i32(value: i32) -> Option<OrderType> {
83 match value {
84 1 => Some(OrderType::Normal),
85 2 => Some(OrderType::Market),
86 5 => Some(OrderType::AbsoluteLimit),
87 6 => Some(OrderType::Auction),
88 7 => Some(OrderType::AuctionLimit),
89 8 => Some(OrderType::SpecialLimit),
90 9 => Some(OrderType::SpecialLimitAll),
91 10 => Some(OrderType::Stop),
92 11 => Some(OrderType::StopLimit),
93 12 => Some(OrderType::MarketifTouched),
94 13 => Some(OrderType::LimitifTouched),
95 14 => Some(OrderType::TrailingStop),
96 15 => Some(OrderType::TrailingStopLimit),
97 16 => Some(OrderType::TwapMarket),
98 17 => Some(OrderType::TwapLimit),
99 18 => Some(OrderType::VwapMarket),
100 19 => Some(OrderType::VwapLimit),
101 _ => None,
102 }
103}
104
105#[must_use]
106pub fn parse_modify_op(raw: &str) -> Option<ModifyOrderOp> {
107 match raw.trim().to_ascii_uppercase().as_str() {
108 "NORMAL" | "MODIFY" => Some(ModifyOrderOp::Normal),
109 "CANCEL" => Some(ModifyOrderOp::Cancel),
110 "DISABLE" => Some(ModifyOrderOp::Disable),
111 "ENABLE" => Some(ModifyOrderOp::Enable),
112 "DELETE" => Some(ModifyOrderOp::Delete),
113 _ => None,
114 }
115}
116
117#[cfg(test)]
118mod tests;