use pretty_simple_display::{DebugPretty, DisplaySimple};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use std::fmt::Display;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum InstrumentKind {
Future,
Option,
Spot,
#[serde(rename = "future_combo")]
FutureCombo,
#[serde(rename = "option_combo")]
OptionCombo,
}
impl Display for InstrumentKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
InstrumentKind::Future => write!(f, "future"),
InstrumentKind::Option => write!(f, "option"),
InstrumentKind::Spot => write!(f, "spot"),
InstrumentKind::FutureCombo => write!(f, "future_combo"),
InstrumentKind::OptionCombo => write!(f, "option_combo"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum InstrumentType {
Linear,
Reversed,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize, Default)]
pub struct Instrument {
pub instrument_name: String,
pub price_index: Option<String>,
pub kind: Option<InstrumentKind>,
pub currency: Option<String>,
pub is_active: Option<bool>,
pub expiration_timestamp: Option<i64>,
pub strike: Option<f64>,
pub option_type: Option<OptionType>,
pub tick_size: Option<f64>,
pub min_trade_amount: Option<f64>,
pub contract_size: Option<f64>,
pub settlement_period: Option<String>,
pub instrument_type: Option<InstrumentType>,
pub quote_currency: Option<String>,
pub settlement_currency: Option<String>,
pub creation_timestamp: Option<i64>,
pub max_leverage: Option<f64>,
pub maker_commission: Option<f64>,
pub taker_commission: Option<f64>,
pub instrument_id: Option<u32>,
pub base_currency: Option<String>,
pub counter_currency: Option<String>,
}
impl Instrument {
pub fn is_perpetual(&self) -> bool {
self.expiration_timestamp.is_none()
&& self
.kind
.as_ref()
.is_some_and(|k| matches!(k, InstrumentKind::Future))
}
pub fn is_option(&self) -> bool {
self.kind
.as_ref()
.is_some_and(|k| matches!(k, InstrumentKind::Option | InstrumentKind::OptionCombo))
}
pub fn is_future(&self) -> bool {
self.kind
.as_ref()
.is_some_and(|k| matches!(k, InstrumentKind::Future | InstrumentKind::FutureCombo))
}
pub fn is_spot(&self) -> bool {
self.kind
.as_ref()
.is_some_and(|k| matches!(k, InstrumentKind::Spot))
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum OptionType {
Call,
Put,
}