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))]
16#[non_exhaustive]
17pub enum OrderSide {
18 #[default]
20 Buy,
21 Sell,
23}
24
25impl fmt::Display for OrderSide {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 match self {
28 Self::Buy => write!(f, "BUY"),
29 Self::Sell => write!(f, "SELL"),
30 }
31 }
32}
33
34#[derive(Debug, Clone, PartialEq, Eq)]
36pub struct ParseOrderSideError(String);
37
38impl fmt::Display for ParseOrderSideError {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 write!(f, "invalid order side: '{}'", self.0)
41 }
42}
43
44impl std::error::Error for ParseOrderSideError {}
45
46impl FromStr for OrderSide {
47 type Err = ParseOrderSideError;
48
49 fn from_str(s: &str) -> Result<Self, Self::Err> {
50 match s.to_uppercase().as_str() {
51 "BUY" | "B" => Ok(Self::Buy),
52 "SELL" | "S" => Ok(Self::Sell),
53 _ => Err(ParseOrderSideError(s.to_string())),
54 }
55 }
56}
57
58impl From<OrderSide> for request_new_order::TransactionType {
59 fn from(side: OrderSide) -> Self {
60 match side {
61 OrderSide::Buy => Self::Buy,
62 OrderSide::Sell => Self::Sell,
63 }
64 }
65}
66
67impl From<OrderSide> for request_bracket_order::TransactionType {
68 fn from(side: OrderSide) -> Self {
69 match side {
70 OrderSide::Buy => Self::Buy,
71 OrderSide::Sell => Self::Sell,
72 }
73 }
74}
75
76impl From<OrderSide> for request_oco_order::TransactionType {
77 fn from(side: OrderSide) -> Self {
78 match side {
79 OrderSide::Buy => Self::Buy,
80 OrderSide::Sell => Self::Sell,
81 }
82 }
83}
84
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
87#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
88#[non_exhaustive]
89pub enum OrderType {
90 Market,
92 #[default]
94 Limit,
95 StopMarket,
97 StopLimit,
99}
100
101impl fmt::Display for OrderType {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 match self {
104 Self::Market => write!(f, "MARKET"),
105 Self::Limit => write!(f, "LIMIT"),
106 Self::StopMarket => write!(f, "STOP_MARKET"),
107 Self::StopLimit => write!(f, "STOP_LIMIT"),
108 }
109 }
110}
111
112#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct ParseOrderTypeError(String);
115
116impl fmt::Display for ParseOrderTypeError {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 write!(f, "invalid order type: '{}'", self.0)
119 }
120}
121
122impl std::error::Error for ParseOrderTypeError {}
123
124impl FromStr for OrderType {
125 type Err = ParseOrderTypeError;
126
127 fn from_str(s: &str) -> Result<Self, Self::Err> {
128 match s.to_uppercase().as_str() {
129 "MARKET" | "MKT" => Ok(Self::Market),
130 "LIMIT" | "LMT" => Ok(Self::Limit),
131 "STOPMARKET" | "STPMKT" | "STOP_MARKET" | "STOP-MARKET" => Ok(Self::StopMarket),
132 "STOPLIMIT" | "STPLMT" | "STOP_LIMIT" | "STOP-LIMIT" => Ok(Self::StopLimit),
133 _ => Err(ParseOrderTypeError(s.to_string())),
134 }
135 }
136}
137
138impl From<OrderType> for request_new_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_modify_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_bracket_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
171impl From<OrderType> for request_oco_order::PriceType {
172 fn from(order_type: OrderType) -> Self {
173 match order_type {
174 OrderType::Market => Self::Market,
175 OrderType::Limit => Self::Limit,
176 OrderType::StopMarket => Self::StopMarket,
177 OrderType::StopLimit => Self::StopLimit,
178 }
179 }
180}
181
182#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
184#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
185#[non_exhaustive]
186pub enum TimeInForce {
187 #[default]
189 Day,
190 Gtc,
192 Ioc,
194 Fok,
196}
197
198impl fmt::Display for TimeInForce {
199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200 match self {
201 Self::Day => write!(f, "DAY"),
202 Self::Gtc => write!(f, "GTC"),
203 Self::Ioc => write!(f, "IOC"),
204 Self::Fok => write!(f, "FOK"),
205 }
206 }
207}
208
209#[derive(Debug, Clone, PartialEq, Eq)]
211pub struct ParseTimeInForceError(String);
212
213impl fmt::Display for ParseTimeInForceError {
214 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
215 write!(f, "invalid time-in-force: '{}'", self.0)
216 }
217}
218
219impl std::error::Error for ParseTimeInForceError {}
220
221impl FromStr for TimeInForce {
222 type Err = ParseTimeInForceError;
223
224 fn from_str(s: &str) -> Result<Self, Self::Err> {
225 match s.to_uppercase().as_str() {
226 "DAY" => Ok(Self::Day),
227 "GTC" | "GOODTILLCANCELLED" | "GOOD_TILL_CANCELLED" | "GOOD-TILL-CANCELLED" => {
228 Ok(Self::Gtc)
229 }
230 "IOC" | "IMMEDIATEORCANCEL" | "IMMEDIATE_OR_CANCEL" | "IMMEDIATE-OR-CANCEL" => {
231 Ok(Self::Ioc)
232 }
233 "FOK" | "FILLORKILL" | "FILL_OR_KILL" | "FILL-OR-KILL" => Ok(Self::Fok),
234 _ => Err(ParseTimeInForceError(s.to_string())),
235 }
236 }
237}
238
239impl From<TimeInForce> for request_new_order::Duration {
240 fn from(tif: TimeInForce) -> Self {
241 match tif {
242 TimeInForce::Day => Self::Day,
243 TimeInForce::Gtc => Self::Gtc,
244 TimeInForce::Ioc => Self::Ioc,
245 TimeInForce::Fok => Self::Fok,
246 }
247 }
248}
249
250impl From<TimeInForce> for request_bracket_order::Duration {
251 fn from(tif: TimeInForce) -> Self {
252 match tif {
253 TimeInForce::Day => Self::Day,
254 TimeInForce::Gtc => Self::Gtc,
255 TimeInForce::Ioc => Self::Ioc,
256 TimeInForce::Fok => Self::Fok,
257 }
258 }
259}
260
261impl From<TimeInForce> for request_oco_order::Duration {
262 fn from(tif: TimeInForce) -> Self {
263 match tif {
264 TimeInForce::Day => Self::Day,
265 TimeInForce::Gtc => Self::Gtc,
266 TimeInForce::Ioc => Self::Ioc,
267 TimeInForce::Fok => Self::Fok,
268 }
269 }
270}