use crate::core::types::AccountType;
#[derive(Debug, Clone)]
pub struct DeribitUrls {
pub rest: &'static str,
pub ws: &'static str,
}
impl DeribitUrls {
pub const MAINNET: Self = Self {
rest: "https://www.deribit.com/api/v2",
ws: "wss://www.deribit.com/ws/api/v2",
};
pub const TESTNET: Self = Self {
rest: "https://test.deribit.com/api/v2",
ws: "wss://test.deribit.com/ws/api/v2",
};
pub fn rest_url(&self) -> &str {
self.rest
}
pub fn ws_url(&self) -> &str {
self.ws
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DeribitMethod {
Auth,
GetInstruments,
GetOrderBook,
Ticker,
GetBookSummaryByCurrency,
GetLastTradesByInstrument,
GetLastTradesByInstrumentAndTime,
GetTradingviewChartData,
Buy,
Sell,
Edit,
Cancel,
CancelByLabel,
CancelAll,
CancelAllByCurrency,
CancelAllByInstrument,
GetOpenOrders,
GetOpenOrdersByCurrency,
GetOpenOrdersByInstrument,
GetOrderState,
ClosePosition,
GetAccountSummary,
GetUserTradesByInstrument,
GetUserTradesByCurrency,
GetSettlementHistoryByInstrument,
GetCurrentDepositAddress,
Withdraw,
GetDeposits,
GetWithdrawals,
GetPosition,
GetPositions,
Subscribe,
Unsubscribe,
SubscribePrivate,
UnsubscribePrivate,
Test,
GetFundingRateHistory,
GetFundingRateValue,
GetIndexPrice,
GetHistoricalVolatility,
GetMarkPriceHistory,
GetOrderHistoryByCurrency,
GetOrderHistoryByInstrument,
GetUserTradesByCurrencyTime,
GetTriggerOrderHistory,
GetTransactionLog,
}
impl DeribitMethod {
pub fn method(&self) -> &'static str {
match self {
Self::Auth => "public/auth",
Self::GetInstruments => "public/get_instruments",
Self::GetOrderBook => "public/get_order_book",
Self::Ticker => "public/ticker",
Self::GetBookSummaryByCurrency => "public/get_book_summary_by_currency",
Self::GetLastTradesByInstrument => "public/get_last_trades_by_instrument",
Self::GetLastTradesByInstrumentAndTime => "public/get_last_trades_by_instrument_and_time",
Self::GetTradingviewChartData => "public/get_tradingview_chart_data",
Self::Buy => "private/buy",
Self::Sell => "private/sell",
Self::Edit => "private/edit",
Self::Cancel => "private/cancel",
Self::CancelByLabel => "private/cancel_by_label",
Self::CancelAll => "private/cancel_all",
Self::CancelAllByCurrency => "private/cancel_all_by_currency",
Self::CancelAllByInstrument => "private/cancel_all_by_instrument",
Self::GetOpenOrders => "private/get_open_orders",
Self::GetOpenOrdersByCurrency => "private/get_open_orders_by_currency",
Self::GetOpenOrdersByInstrument => "private/get_open_orders_by_instrument",
Self::GetOrderState => "private/get_order_state",
Self::ClosePosition => "private/close_position",
Self::GetAccountSummary => "private/get_account_summary",
Self::GetUserTradesByInstrument => "private/get_user_trades_by_instrument",
Self::GetUserTradesByCurrency => "private/get_user_trades_by_currency",
Self::GetSettlementHistoryByInstrument => "private/get_settlement_history_by_instrument",
Self::GetCurrentDepositAddress => "private/get_current_deposit_address",
Self::Withdraw => "private/withdraw",
Self::GetDeposits => "private/get_deposits",
Self::GetWithdrawals => "private/get_withdrawals",
Self::GetPosition => "private/get_position",
Self::GetPositions => "private/get_positions",
Self::Subscribe => "public/subscribe",
Self::Unsubscribe => "public/unsubscribe",
Self::SubscribePrivate => "private/subscribe",
Self::UnsubscribePrivate => "private/unsubscribe",
Self::Test => "public/test",
Self::GetFundingRateHistory => "public/get_funding_rate_history",
Self::GetFundingRateValue => "public/get_funding_rate_value",
Self::GetIndexPrice => "public/get_index_price",
Self::GetHistoricalVolatility => "public/get_historical_volatility",
Self::GetMarkPriceHistory => "public/get_mark_price_history",
Self::GetOrderHistoryByCurrency => "private/get_order_history_by_currency",
Self::GetOrderHistoryByInstrument => "private/get_order_history_by_instrument",
Self::GetUserTradesByCurrencyTime => "private/get_user_trades_by_currency_and_time",
Self::GetTriggerOrderHistory => "private/get_trigger_order_history",
Self::GetTransactionLog => "private/get_transaction_log",
}
}
pub fn requires_auth(&self) -> bool {
self.method().starts_with("private/")
}
pub fn http_method(&self) -> &'static str {
"POST"
}
}
pub fn format_symbol(base: &str, quote: &str, account_type: AccountType) -> String {
match account_type {
AccountType::Spot => {
format!("{}-{}", base.to_uppercase(), quote.to_uppercase())
}
AccountType::FuturesCross | AccountType::FuturesIsolated => {
let base = base.to_uppercase();
let quote = quote.to_uppercase();
if quote == "USDC" {
format!("{}_USDC-PERPETUAL", base)
}
else {
format!("{}-PERPETUAL", base)
}
}
AccountType::Margin => {
format!("{}-PERPETUAL", base.to_uppercase())
}
_ => {
format!("{}-{}", base.to_uppercase(), quote.to_uppercase())
}
}
}
pub fn parse_currency(instrument_name: &str) -> Option<&str> {
let first_part = instrument_name.split(&['-', '_'][..]).next()?;
Some(first_part)
}
pub fn parse_instrument_kind(instrument_name: &str) -> &'static str {
if instrument_name.ends_with("-PERPETUAL") {
if instrument_name.contains("_USDC") {
"linear_perpetual"
} else {
"perpetual"
}
} else if instrument_name.matches('-').count() == 3 {
"option"
} else if instrument_name.matches('-').count() == 1 {
"future"
} else {
"unknown"
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_format_symbol() {
assert_eq!(
format_symbol("BTC", "USD", AccountType::FuturesCross),
"BTC-PERPETUAL"
);
assert_eq!(
format_symbol("ETH", "USD", AccountType::FuturesCross),
"ETH-PERPETUAL"
);
assert_eq!(
format_symbol("SOL", "USDC", AccountType::FuturesCross),
"SOL_USDC-PERPETUAL"
);
assert_eq!(
format_symbol("XRP", "USDC", AccountType::FuturesCross),
"XRP_USDC-PERPETUAL"
);
assert_eq!(
format_symbol("BTC", "USDC", AccountType::Spot),
"BTC-USDC"
);
}
#[test]
fn test_parse_currency() {
assert_eq!(parse_currency("BTC-PERPETUAL"), Some("BTC"));
assert_eq!(parse_currency("ETH-29MAR24"), Some("ETH"));
assert_eq!(parse_currency("SOL_USDC-PERPETUAL"), Some("SOL"));
assert_eq!(parse_currency("BTC-27DEC24-50000-C"), Some("BTC"));
}
#[test]
fn test_parse_instrument_kind() {
assert_eq!(parse_instrument_kind("BTC-PERPETUAL"), "perpetual");
assert_eq!(parse_instrument_kind("ETH-PERPETUAL"), "perpetual");
assert_eq!(parse_instrument_kind("SOL_USDC-PERPETUAL"), "linear_perpetual");
assert_eq!(parse_instrument_kind("BTC-29MAR24"), "future");
assert_eq!(parse_instrument_kind("ETH-27DEC24"), "future");
assert_eq!(parse_instrument_kind("BTC-27DEC24-50000-C"), "option");
assert_eq!(parse_instrument_kind("ETH-29MAR24-3000-P"), "option");
}
#[test]
fn test_method_names() {
assert_eq!(DeribitMethod::Auth.method(), "public/auth");
assert_eq!(DeribitMethod::Buy.method(), "private/buy");
assert_eq!(DeribitMethod::GetOrderBook.method(), "public/get_order_book");
assert_eq!(DeribitMethod::GetPositions.method(), "private/get_positions");
}
#[test]
fn test_requires_auth() {
assert!(!DeribitMethod::Auth.requires_auth());
assert!(!DeribitMethod::GetOrderBook.requires_auth());
assert!(DeribitMethod::Buy.requires_auth());
assert!(DeribitMethod::GetPositions.requires_auth());
}
}