digdigdig3_station/series/
key.rs1use std::time::Duration;
2
3use digdigdig3::core::types::{AccountType, ExchangeId};
4use digdigdig3::core::websocket::KlineInterval;
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
11pub enum Kind {
12 Trade,
13 AggTrade,
14 Kline(KlineInterval),
15 Ticker,
16 Orderbook,
17 OrderbookDelta,
18 MarkPrice,
19 FundingRate,
20 OpenInterest,
21 Liquidation,
22 BlockTrade,
24 IndexPrice,
25 CompositeIndex,
26 OptionGreeks,
27 VolatilityIndex,
28 HistoricalVolatility,
29 LongShortRatio,
30 Basis,
31 InsuranceFund,
32 OrderbookL3,
33 SettlementEvent,
34 MarketWarning,
35 RiskLimit,
36 PredictedFunding,
37 FundingSettlement,
38 MarkPriceKline(KlineInterval),
39 IndexPriceKline(KlineInterval),
40 PremiumIndexKline(KlineInterval),
41 OrderUpdate,
44 BalanceUpdate,
46 PositionUpdate,
48}
49
50#[derive(Debug, Clone, Copy)]
55pub struct PollSpec {
56 pub cadence: Duration,
58 pub jitter_pct: u8,
62}
63
64impl Kind {
65 pub(crate) fn is_derived(&self) -> bool {
71 matches!(self, Kind::Basis | Kind::FundingSettlement)
72 }
73
74 pub fn is_poll_only(&self) -> Option<PollSpec> {
80 match self {
81 Kind::LongShortRatio => Some(PollSpec {
82 cadence: Duration::from_secs(5 * 60), jitter_pct: 10,
84 }),
85 Kind::HistoricalVolatility => Some(PollSpec {
86 cadence: Duration::from_secs(60 * 60), jitter_pct: 5,
88 }),
89 _ => None,
90 }
91 }
92
93 pub fn slug(&self) -> String {
95 match self {
96 Kind::Trade => "trades".to_string(),
97 Kind::AggTrade => "agg_trades".to_string(),
98 Kind::Kline(iv) => format!("klines_{}", iv.as_str()),
99 Kind::Ticker => "tickers".to_string(),
100 Kind::Orderbook => "orderbook_snapshots".to_string(),
101 Kind::OrderbookDelta => "orderbook_deltas".to_string(),
102 Kind::MarkPrice => "mark_price".to_string(),
103 Kind::FundingRate => "funding_rate".to_string(),
104 Kind::OpenInterest => "open_interest".to_string(),
105 Kind::Liquidation => "liquidations".to_string(),
106 Kind::BlockTrade => "block_trades".to_string(),
107 Kind::IndexPrice => "index_price".to_string(),
108 Kind::CompositeIndex => "composite_index".to_string(),
109 Kind::OptionGreeks => "option_greeks".to_string(),
110 Kind::VolatilityIndex => "volatility_index".to_string(),
111 Kind::HistoricalVolatility => "historical_volatility".to_string(),
112 Kind::LongShortRatio => "long_short_ratio".to_string(),
113 Kind::Basis => "basis".to_string(),
114 Kind::InsuranceFund => "insurance_fund".to_string(),
115 Kind::OrderbookL3 => "orderbook_l3".to_string(),
116 Kind::SettlementEvent => "settlement_events".to_string(),
117 Kind::MarketWarning => "market_warnings".to_string(),
118 Kind::RiskLimit => "risk_limit".to_string(),
119 Kind::PredictedFunding => "predicted_funding".to_string(),
120 Kind::FundingSettlement => "funding_settlement".to_string(),
121 Kind::MarkPriceKline(iv) => format!("mark_price_klines_{}", iv.as_str()),
122 Kind::IndexPriceKline(iv) => format!("index_price_klines_{}", iv.as_str()),
123 Kind::PremiumIndexKline(iv) => format!("premium_index_klines_{}", iv.as_str()),
124 Kind::OrderUpdate => "order_updates".to_string(),
125 Kind::BalanceUpdate => "balance_updates".to_string(),
126 Kind::PositionUpdate => "position_updates".to_string(),
127 }
128 }
129}
130
131#[derive(Debug, Clone, PartialEq, Eq, Hash)]
134pub struct SeriesKey {
135 pub exchange: ExchangeId,
136 pub account_type: AccountType,
137 pub symbol: String,
139 pub kind: Kind,
140}
141
142impl SeriesKey {
143 pub fn new(
144 exchange: ExchangeId,
145 account_type: AccountType,
146 symbol: impl Into<String>,
147 kind: Kind,
148 ) -> Self {
149 Self {
150 exchange,
151 account_type,
152 symbol: symbol.into(),
153 kind,
154 }
155 }
156
157 pub fn account_label(&self) -> &'static str {
159 match self.account_type {
160 AccountType::Spot => "spot",
161 AccountType::Margin => "margin",
162 AccountType::FuturesCross => "futures_cross",
163 AccountType::FuturesIsolated => "futures_isolated",
164 AccountType::Earn => "earn",
165 AccountType::Lending => "lending",
166 AccountType::Options => "options",
167 AccountType::Convert => "convert",
168 }
169 }
170
171 pub fn exchange_label(&self) -> String {
173 format!("{:?}", self.exchange).to_lowercase()
174 }
175}