rust_order_book/
order.rs

1//! This module defines the public API for submitting market and limit orders
2//! via [`MarketOrderOptions`] and [`LimitOrderOptions`].
3//!
4//! Users will not need to interact with internal structs like [`MarketOrder`]
5//! or [`LimitOrder`] directly.
6
7pub type OrderId = u64;
8pub type Price = u64;
9pub type Quantity = u64;
10
11use crate::{utils::current_timestamp_millis, OrderStatus, OrderType, Side, TimeInForce};
12use serde::{Deserialize, Serialize};
13
14/// Options for submitting a market order to the order book.
15///
16/// Market orders are matched immediately against the best available prices,
17/// consuming liquidity.
18///
19/// # Fields
20/// - `side`: Buy or Sell
21/// - `quantity`: The total amount to trade
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub struct MarketOrderOptions {
24    pub side: Side,
25    pub quantity: u64,
26}
27
28#[derive(Debug)]
29pub(crate) struct MarketOrder {
30    pub id: OrderId,
31    pub side: Side,
32    pub orig_qty: u64,
33    pub executed_qty: u64,
34    pub remaining_qty: u64,
35    pub status: OrderStatus,
36}
37
38impl MarketOrder {
39    pub fn new(id: OrderId, options: MarketOrderOptions) -> MarketOrder {
40        MarketOrder {
41            id,
42            side: options.side,
43            orig_qty: options.quantity,
44            executed_qty: 0,
45            remaining_qty: options.quantity,
46            status: OrderStatus::New,
47        }
48    }
49}
50
51/// Options for submitting a limit order to the order book.
52///
53/// Limit orders rest at a specific price level unless matched immediately.
54/// Time-in-force and post-only logic can be configured.
55///
56/// # Fields
57/// - `side`: Buy or Sell
58/// - `quantity`: Order size
59/// - `price`: Limit price
60/// - `time_in_force`: Optional TIF setting (default: GTC)
61/// - `post_only`: Optional post-only flag (default: false)
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub struct LimitOrderOptions {
64    pub side: Side,
65    pub quantity: u64,
66    pub price: u64,
67    pub time_in_force: Option<TimeInForce>,
68    pub post_only: Option<bool>,
69}
70
71#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
72pub struct LimitOrder {
73    pub id: OrderId,
74    pub side: Side,
75    pub executed_qty: u64,
76    pub remaining_qty: u64,
77    pub orig_qty: u64,
78    pub price: u64,
79    pub order_type: OrderType,
80    pub time: i64,
81    pub time_in_force: TimeInForce,
82    pub post_only: bool,
83    pub taker_qty: u64,
84    pub maker_qty: u64,
85    pub status: OrderStatus,
86}
87
88impl LimitOrder {
89    pub fn new(id: OrderId, options: LimitOrderOptions) -> LimitOrder {
90        LimitOrder {
91            id,
92            side: options.side,
93            orig_qty: options.quantity,
94            executed_qty: 0,
95            remaining_qty: options.quantity,
96            price: options.price,
97            order_type: OrderType::Limit,
98            time: current_timestamp_millis(),
99            time_in_force: get_order_time_in_force(options.time_in_force),
100            post_only: options.post_only.unwrap_or(false),
101            taker_qty: 0,
102            maker_qty: 0,
103            status: OrderStatus::New,
104        }
105    }
106}
107
108pub(crate) fn get_order_time_in_force(time_in_force: Option<TimeInForce>) -> TimeInForce {
109    time_in_force.unwrap_or(TimeInForce::GTC)
110}