Struct rust_ob::OrderBook

source ·
pub struct OrderBook<OrderID>where
    OrderID: Copy + PartialEq + Eq + Hash,{ /* private fields */ }

Implementations§

source§

impl<OrderID> OrderBook<OrderID>where OrderID: Copy + PartialEq + Eq + Hash,

source

pub fn new() -> Self

Create new initialized OrderBook

source

pub fn process_limit_order( &mut self, id: OrderID, side: Side, price: Decimal, quantity: Decimal ) -> Result<Vec<OrderMatch<OrderID>>, ProcessLimitOrder>

Process new limit order

use rust_ob::{
    OrderBook,
    Side,
    OrderMatch,
    errors,
};
use rust_decimal::Decimal;

let mut ob = OrderBook::new();

let res1 = ob.process_limit_order(1, Side::Sell, Decimal::from(4), Decimal::from(4)).unwrap();
assert_eq!(res1.len(), 0);

let res2 = ob.process_limit_order(2, Side::Sell, Decimal::from(3), Decimal::from(2)).unwrap();
assert_eq!(res2.len(), 0);

let res3 = ob.process_limit_order(3, Side::Buy, Decimal::from(8), Decimal::from(3)).unwrap();
assert_eq!(
    res3,
    vec![
        OrderMatch {
            order: 2,
            quantity: Decimal::from(2),
            cost: Decimal::from(-6)
        },
        OrderMatch {
            order: 1,
            quantity: Decimal::from(1),
            cost: Decimal::from(-4)
        },
        OrderMatch {
            order: 3,
            quantity: Decimal::from(3),
            cost: Decimal::from(10)
        }
    ]
);


// all costs sum to zero
assert_eq!(res3.iter().map(|val| val.cost).sum::<Decimal>(), Decimal::ZERO);

// quantity on sell orders == quantity on buy orders
// last OrderMatch of Vec (if not empty) is always the order just placed
assert_eq!(res3.iter().take(res3.len()-1).map(|val| val.quantity).sum::<Decimal>(), res3.last().unwrap().quantity);

// possible errors
assert_eq!(ob.process_limit_order(4, Side::Buy, Decimal::from(10), Decimal::from(0)).unwrap_err(), errors::ProcessLimitOrder::NonPositiveQuantity);
assert_eq!(ob.process_limit_order(1, Side::Buy, Decimal::from(10), Decimal::from(25)).unwrap_err(), errors::ProcessLimitOrder::OrderAlreadyExists);
source

pub fn cancel_order(&mut self, id: OrderID) -> Result<(), CancelOrder>

Cancels order with id

use rust_ob::{
    OrderBook,
    Side,
    errors,
};
use rust_decimal::Decimal;

let mut ob = OrderBook::new();
let _ = ob.process_limit_order(884213, Side::Sell, Decimal::from(5), Decimal::from(5));

assert_eq!(ob.cancel_order(884213), Ok(()));

// possible errors
assert_eq!(ob.cancel_order(884213), Err(errors::CancelOrder::OrderNotFound));
source

pub fn calculate_market_cost( &self, side: Side, quantity: Decimal ) -> Result<(Decimal, Decimal), CalculateMarketCost>

Calculates cost to buy/sell up to quantity. This function does not mutate anything in OrderBook. The return tuple is in format (quantity_fulfilled, cost).

use rust_ob::{
    OrderBook,
    Side,
    errors,
};
use rust_decimal::Decimal;

let mut ob = OrderBook::new();
let _ = ob.process_limit_order(1, Side::Buy, Decimal::from(5), Decimal::from(5));
let _ = ob.process_limit_order(2, Side::Buy, Decimal::from(3), Decimal::from(3));

assert_eq!(ob.calculate_market_cost(Side::Sell, Decimal::from(6)).unwrap(), (Decimal::from(6), Decimal::from(-28)));
assert_eq!(ob.calculate_market_cost(Side::Sell, Decimal::from(12)).unwrap(), (Decimal::from(8), Decimal::from(-34)));

// possible errors
assert_eq!(ob.calculate_market_cost(Side::Sell, Decimal::from(0)), Err(errors::CalculateMarketCost::NonPositiveQuantity));
source

pub fn process_market_order( &mut self, id: OrderID, side: Side, quantity: Decimal ) -> Result<Vec<OrderMatch<OrderID>>, ProcessMarketOrder>

Process new market order

use rust_ob::{
    OrderBook,
    Side,
    OrderMatch,
    errors,
};
use rust_decimal::Decimal;

let mut ob = OrderBook::new();
let _ = ob.process_limit_order(1, Side::Sell, Decimal::from(5), Decimal::from(5));
let _ = ob.process_limit_order(2, Side::Sell, Decimal::from(3), Decimal::from(3));

assert_eq!(
    ob.process_market_order(3, Side::Buy, Decimal::from(6)).unwrap(),
    vec![
        OrderMatch {
            order: 2,
            quantity: Decimal::from(3),
            cost: Decimal::from(-9)
        },
        OrderMatch {
            order: 1,
            quantity: Decimal::from(3),
            cost: Decimal::from(-15)
        },
        OrderMatch {
            order: 3,
            quantity: Decimal::from(6),
            cost: Decimal::from(24)
        }
    ]
);

// possible errors
assert_eq!(ob.process_market_order(4, Side::Buy, Decimal::from(0)), Err(errors::ProcessMarketOrder::NonPositiveQuantity));
assert_eq!(ob.process_market_order(1, Side::Buy, Decimal::from(3)), Err(errors::ProcessMarketOrder::OrderAlreadyExists));
source

pub fn get_highest_priority_order(&self, side: Side) -> Option<OrderID>

Returns the OrderID of the next to be fulfilled order by side if any order exists on side

source

pub fn get_highest_priority_price(&self, side: Side) -> Option<Decimal>

Returns the price of the next to be fulfilled order by side if any order exists on side

source

pub fn get_highest_priority_price_quantity( &self, side: Side ) -> Option<(Decimal, Decimal)>

Returns (price, quantity_at_price) of the highest priority price by side if any order exists on side

Trait Implementations§

source§

impl<OrderID> Debug for OrderBook<OrderID>where OrderID: Copy + PartialEq + Eq + Hash + Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<OrderID> Display for OrderBook<OrderID>where OrderID: Copy + PartialEq + Eq + Hash + Display,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<OrderID: Copy + PartialEq + Eq + Hash + Send> Send for OrderBook<OrderID>

Auto Trait Implementations§

§

impl<OrderID> !RefUnwindSafe for OrderBook<OrderID>

§

impl<OrderID> !Sync for OrderBook<OrderID>

§

impl<OrderID> Unpin for OrderBook<OrderID>where OrderID: Unpin,

§

impl<OrderID> !UnwindSafe for OrderBook<OrderID>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToString for Twhere T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.