cxmr-exchanges 0.0.1

Exchanges identifiers.
Documentation
//! Crypto-bank exchange orders primitives.

use cxmr_currency::{Currency, CurrencyPair};

use super::Error;

/// Currency order details.
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
pub struct Order {
    /// Order side, which is an `Ask` or a `Bid`.
    pub side: OrderSide,
    /// Price rate is a price of a unit.
    pub rate: f64,
    /// Order amount.
    pub amount: f64,
}

impl Order {
    /// Returns true if order side is Bid.
    pub fn is_bid(&self) -> bool {
        match self.side {
            OrderSide::Ask => false,
            OrderSide::Bid => true,
        }
    }

    /// Gets total order value from struct.
    /// It is calculated if `total` contains `None` value.
    pub fn total(&self) -> f64 {
        self.rate * self.amount
    }
}

/// Order status.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum OrderStatus {
    New,
    PartiallyFilled,
    Filled,
    Canceled,
    PendingCancel,
    Rejected,
    Expired,
}

impl Default for OrderStatus {
    fn default() -> Self {
        OrderStatus::New
    }
}

/// Order type.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum OrderType {
    Limit,
    Market,
    StopLoss,
    StopLossLimit,
    TakeProfit,
    TakeProfitLimit,
    LimitMaker,
}

/// Order filling time.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum OrderTime {
    GoodTilCancel,
    ImmediateOrCancel,
    FillOrKill,
}

/// Order side can be either `Ask` when we are selling
/// or a `Bid` when we are trying to buy something.
#[derive(Serialize, Deserialize, PartialEq, Clone)]
pub enum OrderSide {
    /// Ask or a sell.
    Ask,
    /// Bid or a buy.
    Bid,
}

/// Tries to convert from integer to `OrderSide`.
/// Ask is `0` and Bid is `1.
impl std::convert::TryFrom<i64> for OrderSide {
    type Error = Error;

    fn try_from(k: i64) -> Result<Self, Self::Error> {
        match k {
            0 => Ok(OrderSide::Ask),
            1 => Ok(OrderSide::Bid),
            _ => Err(Error::InvalidOrderSideId(k)),
        }
    }
}

impl std::fmt::Debug for OrderSide {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        // TODOL colored
        // use colored::*;
        // match self {
        //     OrderSide::Ask => write!(f, "{}", "ASK".red()),
        //     OrderSide::Bid => write!(f, "{}", "BID".green()),
        // }
        match self {
            OrderSide::Ask => write!(f, "{}", "ASK"),
            OrderSide::Bid => write!(f, "{}", "BID"),
        }
    }
}

/// Market exchange order.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct ExchangeOrder {
    pub id: Option<String>,
    pub pair: CurrencyPair,
    pub side: OrderSide,
    pub kind: OrderType,
    pub amount: u64,
    pub rate: Option<u64>,
    pub stop: Option<u64>,
    pub time: OrderTime,
}

/// Market order execution report.
///
/// Response of order creation.
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct OrderExecution {
    /// Order status.
    pub status: OrderStatus,
    /// Order rate.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub rate: Option<u64>,
    /// Order stop rate.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub stop: Option<u64>,
    /// Cumulative order quantity.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub amount: Option<u64>,
    /// Cumulative executed quantity.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub executed: Option<u64>,
    /// Order fills.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub fills: Option<Vec<OrderFill>>,
    // pub iceberg: Option<u64>,
}

/// Market order fill data.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct OrderFill {
    /// Order rate.
    pub rate: u64,
    /// Order amount.
    pub amount: u64,
    /// Order fee.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub fee: Option<OrderFee>,
}

/// Order fee structure.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct OrderFee {
    pub amount: u64,
    pub currency: Currency,
}

impl OrderFee {
    pub fn new(amount: u64, currency: Currency) -> Self {
        OrderFee {
            amount: amount,
            currency: currency,
        }
    }
}

/// Market order.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct MarketOrder {
    pub id: String,
    pub pair: CurrencyPair,
    pub side: OrderSide,
    pub kind: OrderType,
    pub rate: u64,
    pub stop: Option<u64>,
    pub amount: u64,
    pub time: OrderTime,
    pub status: OrderStatus,
    pub executed: Option<u64>,
    pub created_at: u64,
    pub updated_at: u64,
    // pub iceberg: Option<u64>,
}