1#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6use std::fmt;
7use std::str::FromStr;
8
9use crate::rti::{
10 request_bracket_order, request_modify_order, request_new_order, request_oco_order,
11};
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16pub enum OrderSide {
17 #[default]
18 Buy,
19 Sell,
20}
21
22impl fmt::Display for OrderSide {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 match self {
25 Self::Buy => write!(f, "BUY"),
26 Self::Sell => write!(f, "SELL"),
27 }
28 }
29}
30
31#[derive(Debug, Clone, PartialEq, Eq)]
32pub struct ParseOrderSideError(String);
33
34impl fmt::Display for ParseOrderSideError {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 write!(f, "invalid order side: '{}'", self.0)
37 }
38}
39
40impl std::error::Error for ParseOrderSideError {}
41
42impl FromStr for OrderSide {
43 type Err = ParseOrderSideError;
44
45 fn from_str(s: &str) -> Result<Self, Self::Err> {
46 match s.to_uppercase().as_str() {
47 "BUY" | "B" => Ok(Self::Buy),
48 "SELL" | "S" => Ok(Self::Sell),
49 _ => Err(ParseOrderSideError(s.to_string())),
50 }
51 }
52}
53
54impl From<OrderSide> for request_new_order::TransactionType {
55 fn from(side: OrderSide) -> Self {
56 match side {
57 OrderSide::Buy => Self::Buy,
58 OrderSide::Sell => Self::Sell,
59 }
60 }
61}
62
63impl From<OrderSide> for request_bracket_order::TransactionType {
64 fn from(side: OrderSide) -> Self {
65 match side {
66 OrderSide::Buy => Self::Buy,
67 OrderSide::Sell => Self::Sell,
68 }
69 }
70}
71
72impl From<OrderSide> for request_oco_order::TransactionType {
73 fn from(side: OrderSide) -> Self {
74 match side {
75 OrderSide::Buy => Self::Buy,
76 OrderSide::Sell => Self::Sell,
77 }
78 }
79}
80
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
82#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
83pub enum OrderType {
84 Market,
85 #[default]
86 Limit,
87 StopMarket,
88 StopLimit,
89}
90
91impl fmt::Display for OrderType {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 match self {
94 Self::Market => write!(f, "MARKET"),
95 Self::Limit => write!(f, "LIMIT"),
96 Self::StopMarket => write!(f, "STOP_MARKET"),
97 Self::StopLimit => write!(f, "STOP_LIMIT"),
98 }
99 }
100}
101
102#[derive(Debug, Clone, PartialEq, Eq)]
103pub struct ParseOrderTypeError(String);
104
105impl fmt::Display for ParseOrderTypeError {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 write!(f, "invalid order type: '{}'", self.0)
108 }
109}
110
111impl std::error::Error for ParseOrderTypeError {}
112
113impl FromStr for OrderType {
114 type Err = ParseOrderTypeError;
115
116 fn from_str(s: &str) -> Result<Self, Self::Err> {
117 match s.to_uppercase().as_str() {
118 "MARKET" | "MKT" => Ok(Self::Market),
119 "LIMIT" | "LMT" => Ok(Self::Limit),
120 "STOPMARKET" | "STPMKT" | "STOP_MARKET" | "STOP-MARKET" => Ok(Self::StopMarket),
121 "STOPLIMIT" | "STPLMT" | "STOP_LIMIT" | "STOP-LIMIT" => Ok(Self::StopLimit),
122 _ => Err(ParseOrderTypeError(s.to_string())),
123 }
124 }
125}
126
127impl From<OrderType> for request_new_order::PriceType {
128 fn from(order_type: OrderType) -> Self {
129 match order_type {
130 OrderType::Market => Self::Market,
131 OrderType::Limit => Self::Limit,
132 OrderType::StopMarket => Self::StopMarket,
133 OrderType::StopLimit => Self::StopLimit,
134 }
135 }
136}
137
138impl From<OrderType> for request_modify_order::PriceType {
139 fn from(order_type: OrderType) -> Self {
140 match order_type {
141 OrderType::Market => Self::Market,
142 OrderType::Limit => Self::Limit,
143 OrderType::StopMarket => Self::StopMarket,
144 OrderType::StopLimit => Self::StopLimit,
145 }
146 }
147}
148
149impl From<OrderType> for request_bracket_order::PriceType {
150 fn from(order_type: OrderType) -> Self {
151 match order_type {
152 OrderType::Market => Self::Market,
153 OrderType::Limit => Self::Limit,
154 OrderType::StopMarket => Self::StopMarket,
155 OrderType::StopLimit => Self::StopLimit,
156 }
157 }
158}
159
160impl From<OrderType> for request_oco_order::PriceType {
161 fn from(order_type: OrderType) -> Self {
162 match order_type {
163 OrderType::Market => Self::Market,
164 OrderType::Limit => Self::Limit,
165 OrderType::StopMarket => Self::StopMarket,
166 OrderType::StopLimit => Self::StopLimit,
167 }
168 }
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
172#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
173pub enum TimeInForce {
174 #[default]
175 Day,
176 Gtc,
177 Ioc,
178 Fok,
179}
180
181impl fmt::Display for TimeInForce {
182 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183 match self {
184 Self::Day => write!(f, "DAY"),
185 Self::Gtc => write!(f, "GTC"),
186 Self::Ioc => write!(f, "IOC"),
187 Self::Fok => write!(f, "FOK"),
188 }
189 }
190}
191
192#[derive(Debug, Clone, PartialEq, Eq)]
193pub struct ParseTimeInForceError(String);
194
195impl fmt::Display for ParseTimeInForceError {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 write!(f, "invalid time-in-force: '{}'", self.0)
198 }
199}
200
201impl std::error::Error for ParseTimeInForceError {}
202
203impl FromStr for TimeInForce {
204 type Err = ParseTimeInForceError;
205
206 fn from_str(s: &str) -> Result<Self, Self::Err> {
207 match s.to_uppercase().as_str() {
208 "DAY" => Ok(Self::Day),
209 "GTC" | "GOODTILLCANCELLED" | "GOOD_TILL_CANCELLED" | "GOOD-TILL-CANCELLED" => {
210 Ok(Self::Gtc)
211 }
212 "IOC" | "IMMEDIATEORCANCEL" | "IMMEDIATE_OR_CANCEL" | "IMMEDIATE-OR-CANCEL" => {
213 Ok(Self::Ioc)
214 }
215 "FOK" | "FILLORKILL" | "FILL_OR_KILL" | "FILL-OR-KILL" => Ok(Self::Fok),
216 _ => Err(ParseTimeInForceError(s.to_string())),
217 }
218 }
219}
220
221impl From<TimeInForce> for request_new_order::Duration {
222 fn from(tif: TimeInForce) -> Self {
223 match tif {
224 TimeInForce::Day => Self::Day,
225 TimeInForce::Gtc => Self::Gtc,
226 TimeInForce::Ioc => Self::Ioc,
227 TimeInForce::Fok => Self::Fok,
228 }
229 }
230}
231
232impl From<TimeInForce> for request_bracket_order::Duration {
233 fn from(tif: TimeInForce) -> Self {
234 match tif {
235 TimeInForce::Day => Self::Day,
236 TimeInForce::Gtc => Self::Gtc,
237 TimeInForce::Ioc => Self::Ioc,
238 TimeInForce::Fok => Self::Fok,
239 }
240 }
241}
242
243impl From<TimeInForce> for request_oco_order::Duration {
244 fn from(tif: TimeInForce) -> Self {
245 match tif {
246 TimeInForce::Day => Self::Day,
247 TimeInForce::Gtc => Self::Gtc,
248 TimeInForce::Ioc => Self::Ioc,
249 TimeInForce::Fok => Self::Fok,
250 }
251 }
252}