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 RangeBar(u64),
49 TickBar(u32),
51 VolumeBar(u64),
56 Footprint(KlineInterval),
60 OrderUpdate,
63 BalanceUpdate,
65 PositionUpdate,
67}
68
69#[derive(Debug, Clone, Copy)]
74pub struct PollSpec {
75 pub cadence: Duration,
77 pub jitter_pct: u8,
81}
82
83impl Kind {
84 pub(crate) fn is_derived(&self) -> bool {
90 matches!(
91 self,
92 Kind::Basis
93 | Kind::FundingSettlement
94 | Kind::RangeBar(_)
95 | Kind::TickBar(_)
96 | Kind::VolumeBar(_)
97 | Kind::Footprint(_)
98 )
99 }
100
101 pub fn is_poll_only(&self) -> Option<PollSpec> {
107 match self {
108 Kind::LongShortRatio => Some(PollSpec {
109 cadence: Duration::from_secs(5 * 60), jitter_pct: 10,
111 }),
112 Kind::HistoricalVolatility => Some(PollSpec {
113 cadence: Duration::from_secs(60 * 60), jitter_pct: 5,
115 }),
116 _ => None,
117 }
118 }
119
120 pub fn slug(&self) -> String {
122 match self {
123 Kind::Trade => "trades".to_string(),
124 Kind::AggTrade => "agg_trades".to_string(),
125 Kind::Kline(iv) => format!("klines_{}", iv.as_str()),
126 Kind::Ticker => "tickers".to_string(),
127 Kind::Orderbook => "orderbook_snapshots".to_string(),
128 Kind::OrderbookDelta => "orderbook_deltas".to_string(),
129 Kind::MarkPrice => "mark_price".to_string(),
130 Kind::FundingRate => "funding_rate".to_string(),
131 Kind::OpenInterest => "open_interest".to_string(),
132 Kind::Liquidation => "liquidations".to_string(),
133 Kind::BlockTrade => "block_trades".to_string(),
134 Kind::IndexPrice => "index_price".to_string(),
135 Kind::CompositeIndex => "composite_index".to_string(),
136 Kind::OptionGreeks => "option_greeks".to_string(),
137 Kind::VolatilityIndex => "volatility_index".to_string(),
138 Kind::HistoricalVolatility => "historical_volatility".to_string(),
139 Kind::LongShortRatio => "long_short_ratio".to_string(),
140 Kind::Basis => "basis".to_string(),
141 Kind::InsuranceFund => "insurance_fund".to_string(),
142 Kind::OrderbookL3 => "orderbook_l3".to_string(),
143 Kind::SettlementEvent => "settlement_events".to_string(),
144 Kind::MarketWarning => "market_warnings".to_string(),
145 Kind::RiskLimit => "risk_limit".to_string(),
146 Kind::PredictedFunding => "predicted_funding".to_string(),
147 Kind::FundingSettlement => "funding_settlement".to_string(),
148 Kind::MarkPriceKline(iv) => format!("mark_price_klines_{}", iv.as_str()),
149 Kind::IndexPriceKline(iv) => format!("index_price_klines_{}", iv.as_str()),
150 Kind::PremiumIndexKline(iv) => format!("premium_index_klines_{}", iv.as_str()),
151 Kind::RangeBar(r) => format!("range_bars_{r}"),
152 Kind::TickBar(n) => format!("tick_bars_{n}"),
153 Kind::VolumeBar(v) => format!("volume_bars_{v}"),
154 Kind::Footprint(iv) => format!("footprint_{}", iv.as_str()),
155 Kind::OrderUpdate => "order_updates".to_string(),
156 Kind::BalanceUpdate => "balance_updates".to_string(),
157 Kind::PositionUpdate => "position_updates".to_string(),
158 }
159 }
160}
161
162#[derive(Debug, Clone, PartialEq, Eq, Hash)]
165pub struct SeriesKey {
166 pub exchange: ExchangeId,
167 pub account_type: AccountType,
168 pub symbol: String,
170 pub kind: Kind,
171}
172
173impl SeriesKey {
174 pub fn new(
175 exchange: ExchangeId,
176 account_type: AccountType,
177 symbol: impl Into<String>,
178 kind: Kind,
179 ) -> Self {
180 Self {
181 exchange,
182 account_type,
183 symbol: symbol.into(),
184 kind,
185 }
186 }
187
188 pub fn account_label(&self) -> &'static str {
190 match self.account_type {
191 AccountType::Spot => "spot",
192 AccountType::Margin => "margin",
193 AccountType::FuturesCross => "futures_cross",
194 AccountType::FuturesIsolated => "futures_isolated",
195 AccountType::Earn => "earn",
196 AccountType::Lending => "lending",
197 AccountType::Options => "options",
198 AccountType::Convert => "convert",
199 }
200 }
201
202 pub fn exchange_label(&self) -> String {
204 format!("{:?}", self.exchange).to_lowercase()
205 }
206}