kubera 0.0.2

Trade-Exchange Engine Library for Cryptocurrencies market written in Rust.
Documentation
use std::sync::Arc;
use std::time::SystemTime;
use bincode::{Decode, Encode};
use crate::accounts::AccountSystem;
use crate::assets::AssetSystem;
use crate::matcher::OrderMatch;
use crate::storage::StorageSystem;

#[derive(Debug, Clone, Copy, Encode, Decode)]
pub struct Order {
    pub id: u64,
    pub account_id: u64,
    pub trade_type: TradeType,
    pub price_type: PriceType,
    pub execution_type: ExecutionType,
    pub crypto_currency_id: u64,
    pub currency_id: u64,
    pub quantity: f64,
    pub timestamp: SystemTime,
    pub status: OrderStatus,
}

#[derive(Debug, Clone, Copy, Encode, Decode)]
pub struct OrderHistory {
    pub id: u64,
    pub order_id: u64,
    pub quantity: f64,
    pub timestamp: SystemTime,
    pub status: OrderStatus,
}

#[derive(Debug, Clone, Copy, Encode, Decode)]
pub enum OrderStatus {
    Open,
    Closed,
    PartiallyFilled,
    Cancelled,
}

#[derive(Debug, PartialEq, Clone, Copy, Encode, Decode)]
pub enum TradeType {
    Buy,
    Sell,
}

#[derive(Debug, PartialEq,Clone, Copy, Encode, Decode)]
pub enum PriceType {
    Market,
    Limit(f64),
}

#[derive(Debug, Clone, Copy, Encode, Decode)]
pub enum ExecutionType {
    Full,
    Partial,
}

pub struct OrderSystem {
    pub order_last_id: u64,
    pub order_history_id: u64,
    pub storage_system: Arc<StorageSystem>,
    pub assets_system: Arc<AssetSystem>,
}

impl OrderSystem {
    pub fn new(storage_system: Arc<StorageSystem>, assets_system: Arc<AssetSystem>) -> OrderSystem {
        let mut order_last_id = 0;
        match storage_system.get_last_order() {
            None => {}
            Some(order) => {
                order_last_id = order.id;
            }
        }
        let mut order_history_id = 0;
        match storage_system.get_last_order_history() {
            None => {}
            Some(order_history) => {
                order_history_id = order_history.id;
            }
        }


        OrderSystem {
            order_last_id,
            order_history_id,
            storage_system,
            assets_system,
        }
    }

    pub fn create_order(&mut self, mut order: Order) -> Order {
        self.order_last_id += 1;
        order.id = self.order_last_id;
        self.storage_system.add_order(&order);
        order
    }

    pub fn create_order_history(&mut self, order_match: &OrderMatch,  accounts_system: &mut AccountSystem) {
        {

            let mut buy_order: Order = self.storage_system.get_order(order_match.buy_order_id).unwrap();
            let quantity = self.storage_system.get_order_histories_by_order_id(order_match.buy_order_id).iter().fold(0.0, |acc, x| acc + x.quantity);
            let status = if (quantity + order_match.quantity) == buy_order.quantity {
                OrderStatus::Closed
            } else {
                OrderStatus::PartiallyFilled
            };
            buy_order.status = status;

            self.order_history_id += 1;
            let order_history = OrderHistory {
                id: self.order_history_id,
                order_id: order_match.buy_order_id,
                quantity: order_match.quantity,
                timestamp: order_match.timestamp,
                status: status,
            };
            self.storage_system.add_order_history(&order_history);
            accounts_system.add_currency_to_account(buy_order.account_id, buy_order.currency_id, -(order_match.quantity as f64 * order_match.price));
            accounts_system.add_crypto_currency_to_account(buy_order.account_id, buy_order.crypto_currency_id, order_match.quantity as f64);
        }

        let mut sell_order: Order = self.storage_system.get_order(order_match.sell_order_id).unwrap();
        let quantity = self.storage_system.get_order_histories_by_order_id(order_match.sell_order_id).iter().fold(0.0, |acc, x| acc + x.quantity);
        let status = if (quantity + order_match.quantity) == sell_order.quantity {
            OrderStatus::Closed
        } else {
            OrderStatus::PartiallyFilled
        };
        sell_order.status = status;

        self.order_history_id += 1;
        let order_history = OrderHistory {
            id: self.order_history_id,
            order_id: order_match.sell_order_id,
            quantity: order_match.quantity,
            timestamp: order_match.timestamp,
            status: status,
        };
        self.storage_system.add_order_history(&order_history);
        accounts_system.add_currency_to_account(sell_order.account_id, sell_order.currency_id, order_match.quantity * order_match.price);
        accounts_system.add_crypto_currency_to_account(sell_order.account_id, sell_order.crypto_currency_id, -(order_match.quantity));

    }

}