Skip to main content

mkt_types/
trading.rs

1use derive_builder::Builder;
2use rust_decimal::Decimal;
3use strum_macros::{Display, EnumString};
4use time::OffsetDateTime;
5
6use crate::{Extensions, MarketKind, Symbol};
7
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[non_exhaustive]
10#[derive(Debug, Clone, PartialEq, Eq, Hash)]
11pub struct OrderId(pub String);
12
13impl OrderId {
14    pub fn new(value: impl Into<String>) -> Self {
15        Self(value.into())
16    }
17}
18
19#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20#[non_exhaustive]
21#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22pub struct ClientOrderId(pub String);
23
24impl ClientOrderId {
25    pub fn new(value: impl Into<String>) -> Self {
26        Self(value.into())
27    }
28}
29
30#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31#[non_exhaustive]
32#[derive(Debug, Clone, PartialEq, Eq, Hash)]
33pub enum OrderKey {
34    Exchange(OrderId),
35    Client(ClientOrderId),
36}
37
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39#[non_exhaustive]
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, EnumString)]
41#[strum(serialize_all = "snake_case", ascii_case_insensitive)]
42pub enum OrderSide {
43    Buy,
44    Sell,
45}
46
47#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
48#[non_exhaustive]
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, EnumString)]
50#[strum(serialize_all = "snake_case", ascii_case_insensitive)]
51pub enum OrderType {
52    Market,
53    Limit,
54    StopMarket,
55    StopLimit,
56    PostOnly,
57}
58
59#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
60#[non_exhaustive]
61#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, EnumString)]
62#[strum(serialize_all = "SCREAMING_SNAKE_CASE", ascii_case_insensitive)]
63pub enum TimeInForce {
64    Gtc,
65    Ioc,
66    Fok,
67    Gtx,
68}
69
70#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
71#[non_exhaustive]
72#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, EnumString)]
73#[strum(serialize_all = "snake_case", ascii_case_insensitive)]
74pub enum OrderStatus {
75    New,
76    PartiallyFilled,
77    Filled,
78    Canceled,
79    Rejected,
80    Expired,
81}
82
83#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
84#[non_exhaustive]
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, EnumString)]
86#[strum(serialize_all = "snake_case", ascii_case_insensitive)]
87pub enum PositionSide {
88    Long,
89    Short,
90    Both,
91}
92
93#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
94#[non_exhaustive]
95#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, EnumString)]
96#[strum(serialize_all = "snake_case", ascii_case_insensitive)]
97pub enum MarginMode {
98    Cross,
99    Isolated,
100}
101
102#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
103#[non_exhaustive]
104#[derive(Debug, Clone, PartialEq, Builder)]
105#[builder(pattern = "owned", setter(into))]
106pub struct SpotOrderRequest {
107    pub symbol: Symbol,
108    pub side: OrderSide,
109    pub order_type: OrderType,
110    pub quantity: Decimal,
111    #[builder(default)]
112    pub price: Option<Decimal>,
113    #[builder(default)]
114    pub time_in_force: Option<TimeInForce>,
115    #[builder(default)]
116    pub client_order_id: Option<ClientOrderId>,
117    #[builder(default)]
118    pub extensions: Extensions,
119}
120
121impl SpotOrderRequest {
122    pub fn builder() -> SpotOrderRequestBuilder {
123        SpotOrderRequestBuilder::default()
124    }
125}
126
127#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
128#[non_exhaustive]
129#[derive(Debug, Clone, PartialEq, Builder)]
130#[builder(pattern = "owned", setter(into))]
131pub struct FuturesOrderRequest {
132    pub symbol: Symbol,
133    pub side: OrderSide,
134    pub order_type: OrderType,
135    pub quantity: Decimal,
136    #[builder(default)]
137    pub price: Option<Decimal>,
138    #[builder(default)]
139    pub time_in_force: Option<TimeInForce>,
140    #[builder(default)]
141    pub position_side: Option<PositionSide>,
142    #[builder(default)]
143    pub reduce_only: bool,
144    #[builder(default)]
145    pub client_order_id: Option<ClientOrderId>,
146    #[builder(default)]
147    pub extensions: Extensions,
148}
149
150impl FuturesOrderRequest {
151    pub fn builder() -> FuturesOrderRequestBuilder {
152        FuturesOrderRequestBuilder::default()
153    }
154}
155
156#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
157#[non_exhaustive]
158#[derive(Debug, Clone, PartialEq, Eq)]
159pub struct SpotCancelOrderRequest {
160    pub symbol: Symbol,
161    pub key: OrderKey,
162}
163
164impl SpotCancelOrderRequest {
165    pub fn new(symbol: Symbol, key: OrderKey) -> Self {
166        Self { symbol, key }
167    }
168}
169
170#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
171#[non_exhaustive]
172#[derive(Debug, Clone, PartialEq, Eq)]
173pub struct FuturesCancelOrderRequest {
174    pub symbol: Symbol,
175    pub key: OrderKey,
176}
177
178impl FuturesCancelOrderRequest {
179    pub fn new(symbol: Symbol, key: OrderKey) -> Self {
180        Self { symbol, key }
181    }
182}
183
184#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
185#[non_exhaustive]
186#[derive(Debug, Clone, PartialEq, Eq)]
187pub struct SpotOrderQuery {
188    pub symbol: Symbol,
189    pub key: OrderKey,
190}
191
192impl SpotOrderQuery {
193    pub fn new(symbol: Symbol, key: OrderKey) -> Self {
194        Self { symbol, key }
195    }
196}
197
198#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
199#[non_exhaustive]
200#[derive(Debug, Clone, PartialEq, Eq)]
201pub struct FuturesOrderQuery {
202    pub symbol: Symbol,
203    pub key: OrderKey,
204}
205
206impl FuturesOrderQuery {
207    pub fn new(symbol: Symbol, key: OrderKey) -> Self {
208        Self { symbol, key }
209    }
210}
211
212#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
213#[non_exhaustive]
214#[derive(Debug, Clone, PartialEq, Builder)]
215#[builder(pattern = "owned", setter(into))]
216pub struct Order {
217    pub id: OrderId,
218    #[builder(default)]
219    pub client_order_id: Option<ClientOrderId>,
220    pub symbol: Symbol,
221    pub market_kind: MarketKind,
222    pub side: OrderSide,
223    pub order_type: OrderType,
224    pub status: OrderStatus,
225    #[builder(default)]
226    pub time_in_force: Option<TimeInForce>,
227    #[builder(default)]
228    pub price: Option<Decimal>,
229    #[builder(default)]
230    pub average_price: Option<Decimal>,
231    pub quantity: Decimal,
232    pub filled_quantity: Decimal,
233    #[builder(default)]
234    pub original_quote_quantity: Option<Decimal>,
235    #[builder(default)]
236    pub cumulative_quote_quantity: Option<Decimal>,
237    #[cfg_attr(
238        feature = "serde",
239        serde(with = "time::serde::timestamp::milliseconds")
240    )]
241    pub created_at: OffsetDateTime,
242    #[cfg_attr(
243        feature = "serde",
244        serde(with = "time::serde::timestamp::milliseconds::option")
245    )]
246    #[builder(default)]
247    pub updated_at: Option<OffsetDateTime>,
248    #[builder(default)]
249    pub extensions: Extensions,
250}
251
252impl Order {
253    pub fn builder() -> OrderBuilder {
254        OrderBuilder::default()
255    }
256}
257
258#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
259#[non_exhaustive]
260#[derive(Debug, Clone, PartialEq, Builder)]
261#[builder(pattern = "owned", setter(into))]
262pub struct Fill {
263    #[builder(default)]
264    pub id: Option<String>,
265    pub order_id: OrderId,
266    pub symbol: Symbol,
267    pub side: OrderSide,
268    pub price: Decimal,
269    pub quantity: Decimal,
270    #[builder(default)]
271    pub fee: Option<Decimal>,
272    #[builder(default)]
273    pub fee_asset: Option<String>,
274    #[cfg_attr(
275        feature = "serde",
276        serde(with = "time::serde::timestamp::milliseconds")
277    )]
278    pub timestamp: OffsetDateTime,
279    #[builder(default)]
280    pub extensions: Extensions,
281}
282
283impl Fill {
284    pub fn builder() -> FillBuilder {
285        FillBuilder::default()
286    }
287}
288
289#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
290#[non_exhaustive]
291#[derive(Debug, Clone, PartialEq, Builder)]
292#[builder(pattern = "owned", setter(into))]
293pub struct SetLeverageRequest {
294    pub symbol: Symbol,
295    pub leverage: Decimal,
296    #[builder(default)]
297    pub margin_mode: Option<MarginMode>,
298    #[builder(default)]
299    pub position_side: Option<PositionSide>,
300}
301
302impl SetLeverageRequest {
303    pub fn builder() -> SetLeverageRequestBuilder {
304        SetLeverageRequestBuilder::default()
305    }
306}