Skip to main content

nautilus_deribit/common/
enums.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Common enumerations for the Deribit adapter.
17
18use std::fmt::Display;
19
20use nautilus_model::enums::{MarketStatusAction, TimeInForce, TriggerType};
21use serde::{Deserialize, Serialize};
22use strum::{AsRefStr, Display as StrumDisplay, EnumIter, EnumString};
23
24/// Deribit product type.
25#[derive(
26    Clone,
27    Copy,
28    Debug,
29    PartialEq,
30    Eq,
31    Hash,
32    AsRefStr,
33    StrumDisplay,
34    EnumIter,
35    EnumString,
36    Serialize,
37    Deserialize,
38)]
39#[serde(rename_all = "snake_case")]
40#[strum(serialize_all = "snake_case")]
41#[cfg_attr(
42    feature = "python",
43    pyo3::pyclass(
44        eq,
45        eq_int,
46        module = "nautilus_trader.core.nautilus_pyo3.deribit",
47        from_py_object,
48        rename_all = "SCREAMING_SNAKE_CASE",
49    )
50)]
51#[cfg_attr(
52    feature = "python",
53    pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.deribit")
54)]
55pub enum DeribitProductType {
56    /// Future contract
57    Future,
58    /// Option contract
59    Option,
60    /// Spot market
61    Spot,
62    /// Future combo
63    #[serde(rename = "future_combo")]
64    FutureCombo,
65    /// Option combo
66    #[serde(rename = "option_combo")]
67    OptionCombo,
68}
69
70/// Deribit currency.
71#[derive(
72    Clone, Copy, Debug, PartialEq, Eq, Hash, AsRefStr, EnumIter, EnumString, Serialize, Deserialize,
73)]
74#[serde(rename_all = "UPPERCASE")]
75#[strum(serialize_all = "UPPERCASE")]
76#[cfg_attr(
77    feature = "python",
78    pyo3::pyclass(
79        eq,
80        eq_int,
81        module = "nautilus_trader.core.nautilus_pyo3.deribit",
82        from_py_object,
83        rename_all = "SCREAMING_SNAKE_CASE",
84    )
85)]
86#[cfg_attr(
87    feature = "python",
88    pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.deribit")
89)]
90pub enum DeribitCurrency {
91    /// Bitcoin
92    BTC,
93    /// Ethereum
94    ETH,
95    /// USD Coin
96    USDC,
97    /// Tether
98    USDT,
99    /// Euro stablecoin
100    EURR,
101    /// All currencies
102    #[serde(rename = "any")]
103    ANY,
104}
105
106impl DeribitCurrency {
107    /// Returns the currency as a string.
108    #[must_use]
109    pub fn as_str(&self) -> &'static str {
110        match self {
111            Self::BTC => "BTC",
112            Self::ETH => "ETH",
113            Self::USDC => "USDC",
114            Self::USDT => "USDT",
115            Self::EURR => "EURR",
116            Self::ANY => "any",
117        }
118    }
119}
120
121impl Display for DeribitCurrency {
122    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123        write!(f, "{}", self.as_str())
124    }
125}
126
127/// Deribit option type.
128#[derive(
129    Clone,
130    Copy,
131    Debug,
132    PartialEq,
133    Eq,
134    Hash,
135    AsRefStr,
136    StrumDisplay,
137    EnumIter,
138    EnumString,
139    Serialize,
140    Deserialize,
141)]
142#[serde(rename_all = "lowercase")]
143#[strum(serialize_all = "lowercase")]
144pub enum DeribitOptionType {
145    /// Call option
146    Call,
147    /// Put option
148    Put,
149}
150
151/// Deribit instrument lifecycle state.
152#[derive(
153    Clone, Copy, Debug, PartialEq, Eq, Hash, AsRefStr, EnumIter, EnumString, Serialize, Deserialize,
154)]
155#[serde(rename_all = "snake_case")]
156#[strum(serialize_all = "snake_case")]
157pub enum DeribitInstrumentState {
158    /// Instrument has been created but not yet active.
159    Created,
160    /// Instrument is active and trading.
161    Started,
162    /// Instrument has been settled (options/futures at expiry).
163    Settled,
164    /// Instrument is closed for trading.
165    Closed,
166    /// Instrument has been terminated.
167    Terminated,
168}
169
170impl Display for DeribitInstrumentState {
171    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
172        match self {
173            Self::Created => write!(f, "created"),
174            Self::Started => write!(f, "started"),
175            Self::Settled => write!(f, "settled"),
176            Self::Closed => write!(f, "closed"),
177            Self::Terminated => write!(f, "terminated"),
178        }
179    }
180}
181
182impl From<DeribitInstrumentState> for MarketStatusAction {
183    fn from(state: DeribitInstrumentState) -> Self {
184        match state {
185            DeribitInstrumentState::Created => Self::PreOpen,
186            DeribitInstrumentState::Started => Self::Trading,
187            DeribitInstrumentState::Settled => Self::Close,
188            DeribitInstrumentState::Closed => Self::Close,
189            DeribitInstrumentState::Terminated => Self::NotAvailableForTrading,
190        }
191    }
192}
193
194/// Deribit time in force values for order execution.
195#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
196#[serde(rename_all = "snake_case")]
197pub enum DeribitTimeInForce {
198    /// Good till cancelled.
199    #[serde(rename = "good_til_cancelled")]
200    GoodTilCancelled,
201    /// Good till day (expires at end of trading day).
202    #[serde(rename = "good_til_day")]
203    GoodTilDay,
204    /// Immediate or cancel.
205    #[serde(rename = "immediate_or_cancel")]
206    ImmediateOrCancel,
207    /// Fill or kill.
208    #[serde(rename = "fill_or_kill")]
209    FillOrKill,
210}
211
212impl DeribitTimeInForce {
213    /// Returns the time in force as a Deribit API string.
214    #[must_use]
215    pub fn as_str(&self) -> &'static str {
216        match self {
217            Self::GoodTilCancelled => "good_til_cancelled",
218            Self::GoodTilDay => "good_til_day",
219            Self::ImmediateOrCancel => "immediate_or_cancel",
220            Self::FillOrKill => "fill_or_kill",
221        }
222    }
223}
224
225impl TryFrom<TimeInForce> for DeribitTimeInForce {
226    type Error = String;
227
228    fn try_from(tif: TimeInForce) -> Result<Self, Self::Error> {
229        match tif {
230            TimeInForce::Gtc => Ok(Self::GoodTilCancelled),
231            TimeInForce::Ioc => Ok(Self::ImmediateOrCancel),
232            TimeInForce::Fok => Ok(Self::FillOrKill),
233            TimeInForce::Gtd => Ok(Self::GoodTilDay),
234            _ => Err(format!(
235                "TimeInForce::{tif} is not supported on Deribit (valid: GTC, IOC, FOK, GTD)"
236            )),
237        }
238    }
239}
240
241/// Deribit API environment.
242#[derive(
243    Copy,
244    Clone,
245    Debug,
246    Default,
247    StrumDisplay,
248    PartialEq,
249    Eq,
250    Hash,
251    AsRefStr,
252    EnumIter,
253    EnumString,
254    Serialize,
255    Deserialize,
256)]
257#[serde(rename_all = "lowercase")]
258#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
259#[cfg_attr(
260    feature = "python",
261    pyo3::pyclass(
262        eq,
263        eq_int,
264        module = "nautilus_trader.core.nautilus_pyo3.deribit",
265        from_py_object,
266        rename_all = "SCREAMING_SNAKE_CASE",
267    )
268)]
269#[cfg_attr(
270    feature = "python",
271    pyo3_stub_gen::derive::gen_stub_pyclass_enum(module = "nautilus_trader.deribit")
272)]
273pub enum DeribitEnvironment {
274    /// Live trading environment.
275    #[default]
276    Mainnet,
277    /// Testnet environment.
278    Testnet,
279}
280
281/// Resolves an optional Nautilus trigger type to a Deribit trigger string.
282pub fn resolve_trigger_type(trigger_type: Option<TriggerType>) -> Option<String> {
283    trigger_type.and_then(|tt| match tt {
284        TriggerType::LastPrice | TriggerType::Default => Some("last_price".to_string()),
285        TriggerType::MarkPrice => Some("mark_price".to_string()),
286        TriggerType::IndexPrice => Some("index_price".to_string()),
287        _ => None,
288    })
289}
290
291#[cfg(test)]
292mod tests {
293    use rstest::rstest;
294
295    use super::*;
296
297    #[rstest]
298    #[case(DeribitInstrumentState::Created, MarketStatusAction::PreOpen)]
299    #[case(DeribitInstrumentState::Started, MarketStatusAction::Trading)]
300    #[case(DeribitInstrumentState::Settled, MarketStatusAction::Close)]
301    #[case(DeribitInstrumentState::Closed, MarketStatusAction::Close)]
302    #[case(
303        DeribitInstrumentState::Terminated,
304        MarketStatusAction::NotAvailableForTrading
305    )]
306    fn test_deribit_instrument_state_to_market_status_action(
307        #[case] state: DeribitInstrumentState,
308        #[case] expected: MarketStatusAction,
309    ) {
310        assert_eq!(MarketStatusAction::from(state), expected);
311    }
312}