use std::fmt;
use serde::{Deserialize, Serialize};
use super::{
error::{MarginValidationError, QuantityValidationError},
leverage::Leverage,
margin::Margin,
price::Price,
quantity::Quantity,
};
pub mod util;
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[serde(rename_all = "lowercase")]
pub enum TradeSide {
Buy,
Sell,
}
impl fmt::Display for TradeSide {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TradeSide::Buy => "Buy".fmt(f),
TradeSide::Sell => "Sell".fmt(f),
}
}
}
#[derive(Serialize, Debug, Clone, PartialEq, Eq, Copy)]
pub enum TradeSize {
#[serde(rename = "quantity")]
Quantity(Quantity),
#[serde(rename = "margin")]
Margin(Margin),
}
impl TradeSize {
pub fn quantity<Q>(value: Q) -> std::result::Result<Self, QuantityValidationError>
where
Q: TryInto<Quantity, Error = QuantityValidationError>,
{
Ok(Self::Quantity(value.try_into()?))
}
pub fn margin<M>(value: M) -> std::result::Result<Self, MarginValidationError>
where
M: TryInto<Margin, Error = MarginValidationError>,
{
Ok(Self::Margin(value.try_into()?))
}
pub fn to_quantity_and_margin(
&self,
price: Price,
leverage: Leverage,
) -> Result<(Quantity, Margin), QuantityValidationError> {
match self {
TradeSize::Margin(margin) => {
let quantity = Quantity::try_calculate(*margin, price, leverage)?;
Ok((quantity, *margin))
}
TradeSize::Quantity(quantity) => {
let margin = Margin::calculate(*quantity, price, leverage);
Ok((*quantity, margin))
}
}
}
}
impl From<Quantity> for TradeSize {
fn from(quantity: Quantity) -> Self {
TradeSize::Quantity(quantity)
}
}
impl From<Margin> for TradeSize {
fn from(margin: Margin) -> Self {
TradeSize::Margin(margin)
}
}
impl fmt::Display for TradeSize {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TradeSize::Quantity(quantity) => write!(f, "Quantity({})", quantity),
TradeSize::Margin(margin) => write!(f, "Margin({})", margin),
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[serde(rename_all = "lowercase")]
pub enum TradeExecutionType {
Market,
Limit,
}
impl fmt::Display for TradeExecutionType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let type_str = match self {
TradeExecutionType::Market => "Market",
TradeExecutionType::Limit => "Limit",
};
write!(f, "{}", type_str)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub enum TradeExecution {
Market,
Limit(Price),
}
impl TradeExecution {
pub fn to_type(&self) -> TradeExecutionType {
match self {
TradeExecution::Market => TradeExecutionType::Market,
TradeExecution::Limit(_) => TradeExecutionType::Limit,
}
}
}
impl From<Price> for TradeExecution {
fn from(price: Price) -> Self {
Self::Limit(price)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TradeStatus {
Open,
Running,
Closed,
}
impl TradeStatus {
pub fn as_str(&self) -> &'static str {
match self {
TradeStatus::Open => "open",
TradeStatus::Running => "running",
TradeStatus::Closed => "closed",
}
}
}
impl fmt::Display for TradeStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}