deribit_http/model/
instrument.rs

1/******************************************************************************
2   Author: Joaquín Béjar García
3   Email: jb@taunais.com
4   Date: 15/9/25
5******************************************************************************/
6use pretty_simple_display::{DebugPretty, DisplaySimple};
7use serde::{Deserialize, Serialize};
8use serde_with::skip_serializing_none;
9use std::fmt::Display;
10
11/// Instrument kind enumeration
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
13#[serde(rename_all = "lowercase")]
14pub enum InstrumentKind {
15    /// Future contract
16    Future,
17    /// Option contract
18    Option,
19    /// Spot trading
20    Spot,
21    /// Future combo
22    #[serde(rename = "future_combo")]
23    FutureCombo,
24    /// Option combo
25    #[serde(rename = "option_combo")]
26    OptionCombo,
27}
28
29impl Display for InstrumentKind {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        match self {
32            InstrumentKind::Future => write!(f, "future"),
33            InstrumentKind::Option => write!(f, "option"),
34            InstrumentKind::Spot => write!(f, "spot"),
35            InstrumentKind::FutureCombo => write!(f, "future_combo"),
36            InstrumentKind::OptionCombo => write!(f, "option_combo"),
37        }
38    }
39}
40
41/// Instrument type enumeration
42#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
43#[serde(rename_all = "lowercase")]
44pub enum InstrumentType {
45    /// Linear instrument
46    Linear,
47    /// Reversed instrument
48    Reversed,
49}
50
51/// Instrument information
52#[skip_serializing_none]
53#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize, Default)]
54pub struct Instrument {
55    /// Instrument name (e.g., "BTC-PERPETUAL", "ETH-25JUL25-3000-C")
56    pub instrument_name: String,
57    /// Price index used for mark price calculation
58    pub price_index: Option<String>,
59    /// Instrument kind
60    pub kind: Option<InstrumentKind>,
61    /// Base currency
62    pub currency: Option<String>,
63    /// Whether the instrument is active for trading
64    pub is_active: Option<bool>,
65    /// Expiration timestamp (None for perpetuals)
66    pub expiration_timestamp: Option<i64>,
67    /// Strike price (for options)
68    pub strike: Option<f64>,
69    /// Option type (call/put, for options only)
70    pub option_type: Option<OptionType>,
71    /// Minimum price movement
72    pub tick_size: Option<f64>,
73    /// Minimum trade amount
74    pub min_trade_amount: Option<f64>,
75    /// Contract size
76    pub contract_size: Option<f64>,
77    /// Settlement period
78    pub settlement_period: Option<String>,
79    /// Instrument type (linear/reversed)
80    pub instrument_type: Option<InstrumentType>,
81    /// Quote currency
82    pub quote_currency: Option<String>,
83    /// Settlement currency
84    pub settlement_currency: Option<String>,
85    /// Creation timestamp
86    pub creation_timestamp: Option<i64>,
87    /// Maximum leverage
88    pub max_leverage: Option<f64>,
89    /// Maker commission rate
90    pub maker_commission: Option<f64>,
91    /// Taker commission rate
92    pub taker_commission: Option<f64>,
93    /// Unique instrument identifier
94    pub instrument_id: Option<u32>,
95    /// Base currency for the instrument
96    pub base_currency: Option<String>,
97    /// Counter currency for the instrument
98    pub counter_currency: Option<String>,
99}
100
101impl Instrument {
102    /// Check if the instrument is a perpetual contract
103    pub fn is_perpetual(&self) -> bool {
104        self.expiration_timestamp.is_none()
105            && self
106                .kind
107                .as_ref()
108                .is_some_and(|k| matches!(k, InstrumentKind::Future))
109    }
110
111    /// Check if the instrument is an option
112    pub fn is_option(&self) -> bool {
113        self.kind
114            .as_ref()
115            .is_some_and(|k| matches!(k, InstrumentKind::Option | InstrumentKind::OptionCombo))
116    }
117
118    /// Check if the instrument is a future
119    pub fn is_future(&self) -> bool {
120        self.kind
121            .as_ref()
122            .is_some_and(|k| matches!(k, InstrumentKind::Future | InstrumentKind::FutureCombo))
123    }
124
125    /// Check if the instrument is a spot
126    pub fn is_spot(&self) -> bool {
127        self.kind
128            .as_ref()
129            .is_some_and(|k| matches!(k, InstrumentKind::Spot))
130    }
131}
132
133/// Option type enumeration
134#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
135#[serde(rename_all = "lowercase")]
136pub enum OptionType {
137    /// Call option
138    Call,
139    /// Put option
140    Put,
141}