use std::time::Duration;
use digdigdig3::core::types::{AccountType, ExchangeId};
use digdigdig3::core::websocket::KlineInterval;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Kind {
Trade,
AggTrade,
Kline(KlineInterval),
Ticker,
Orderbook,
OrderbookDelta,
MarkPrice,
FundingRate,
OpenInterest,
Liquidation,
BlockTrade,
AuctionEvent,
IndexPrice,
CompositeIndex,
OptionGreeks,
VolatilityIndex,
HistoricalVolatility,
LongShortRatio,
TakerVolume,
LiquidationBucket,
Basis,
InsuranceFund,
OrderbookL3,
SettlementEvent,
MarketWarning,
RiskLimit,
PredictedFunding,
FundingSettlement,
MarkPriceKline(KlineInterval),
IndexPriceKline(KlineInterval),
PremiumIndexKline(KlineInterval),
RangeBar(u64),
TickBar(u32),
VolumeBar(u64),
Footprint(KlineInterval),
OrderUpdate,
BalanceUpdate,
PositionUpdate,
}
#[derive(Debug, Clone, Copy)]
pub struct PollSpec {
pub cadence: Duration,
pub jitter_pct: u8,
}
impl Kind {
pub(crate) fn is_derived(&self) -> bool {
matches!(
self,
Kind::Basis
| Kind::FundingSettlement
| Kind::RangeBar(_)
| Kind::TickBar(_)
| Kind::VolumeBar(_)
| Kind::Footprint(_)
)
}
pub fn is_poll_only(&self) -> Option<PollSpec> {
match self {
Kind::LongShortRatio => Some(PollSpec {
cadence: Duration::from_secs(5 * 60), jitter_pct: 10,
}),
Kind::TakerVolume => Some(PollSpec {
cadence: Duration::from_secs(5 * 60),
jitter_pct: 10,
}),
Kind::LiquidationBucket => Some(PollSpec {
cadence: Duration::from_secs(5 * 60),
jitter_pct: 10,
}),
Kind::HistoricalVolatility => Some(PollSpec {
cadence: Duration::from_secs(60 * 60), jitter_pct: 5,
}),
_ => None,
}
}
pub fn slug(&self) -> String {
match self {
Kind::Trade => "trades".to_string(),
Kind::AggTrade => "agg_trades".to_string(),
Kind::Kline(iv) => format!("klines_{}", iv.as_str()),
Kind::Ticker => "tickers".to_string(),
Kind::Orderbook => "orderbook_snapshots".to_string(),
Kind::OrderbookDelta => "orderbook_deltas".to_string(),
Kind::MarkPrice => "mark_price".to_string(),
Kind::FundingRate => "funding_rate".to_string(),
Kind::OpenInterest => "open_interest".to_string(),
Kind::Liquidation => "liquidations".to_string(),
Kind::BlockTrade => "block_trades".to_string(),
Kind::AuctionEvent => "auction_events".to_string(),
Kind::IndexPrice => "index_price".to_string(),
Kind::CompositeIndex => "composite_index".to_string(),
Kind::OptionGreeks => "option_greeks".to_string(),
Kind::VolatilityIndex => "volatility_index".to_string(),
Kind::HistoricalVolatility => "historical_volatility".to_string(),
Kind::LongShortRatio => "long_short_ratio".to_string(),
Kind::TakerVolume => "taker_volume".to_string(),
Kind::LiquidationBucket => "liquidation_bucket".to_string(),
Kind::Basis => "basis".to_string(),
Kind::InsuranceFund => "insurance_fund".to_string(),
Kind::OrderbookL3 => "orderbook_l3".to_string(),
Kind::SettlementEvent => "settlement_events".to_string(),
Kind::MarketWarning => "market_warnings".to_string(),
Kind::RiskLimit => "risk_limit".to_string(),
Kind::PredictedFunding => "predicted_funding".to_string(),
Kind::FundingSettlement => "funding_settlement".to_string(),
Kind::MarkPriceKline(iv) => format!("mark_price_klines_{}", iv.as_str()),
Kind::IndexPriceKline(iv) => format!("index_price_klines_{}", iv.as_str()),
Kind::PremiumIndexKline(iv) => format!("premium_index_klines_{}", iv.as_str()),
Kind::RangeBar(r) => format!("range_bars_{r}"),
Kind::TickBar(n) => format!("tick_bars_{n}"),
Kind::VolumeBar(v) => format!("volume_bars_{v}"),
Kind::Footprint(iv) => format!("footprint_{}", iv.as_str()),
Kind::OrderUpdate => "order_updates".to_string(),
Kind::BalanceUpdate => "balance_updates".to_string(),
Kind::PositionUpdate => "position_updates".to_string(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SeriesKey {
pub exchange: ExchangeId,
pub account_type: AccountType,
pub symbol: String,
pub kind: Kind,
}
impl SeriesKey {
pub fn new(
exchange: ExchangeId,
account_type: AccountType,
symbol: impl Into<String>,
kind: Kind,
) -> Self {
Self {
exchange,
account_type,
symbol: symbol.into(),
kind,
}
}
pub fn account_label(&self) -> &'static str {
match self.account_type {
AccountType::Spot => "spot",
AccountType::Margin => "margin",
AccountType::FuturesCross => "futures_cross",
AccountType::FuturesIsolated => "futures_isolated",
AccountType::Earn => "earn",
AccountType::Lending => "lending",
AccountType::Options => "options",
AccountType::Convert => "convert",
}
}
pub fn exchange_label(&self) -> String {
format!("{:?}", self.exchange).to_lowercase()
}
}