1use digdigdig3::core::types::{AccountType, ExchangeId};
2use digdigdig3::core::websocket::KlineInterval;
3
4use crate::data::{
5 AggTradePoint, AuctionEventPoint, BarPoint, BasisPoint, BlockTradePoint, CompositeIndexPoint,
6 FundingRatePoint, FundingSettlementPoint, HistoricalVolatilityPoint, IndexPriceKlinePoint,
7 IndexPricePoint, InsuranceFundPoint, LiquidationPoint, MarkPriceKlinePoint, MarkPricePoint,
8 MarketWarningPoint, ObSnapshotPoint, OpenInterestPoint, OptionGreeksPoint, OrderbookL3Point,
9 PredictedFundingPoint, PremiumIndexKlinePoint, RiskLimitPoint, SettlementEventPoint,
10 TickerPoint, TradePoint, VolatilityIndexPoint,
11};
12use crate::series::{Kind, SeriesKey};
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash)]
19pub enum Stream {
20 Ticker,
21 Trade,
22 Orderbook,
23 Kline(KlineInterval),
24 MarkPrice,
25 FundingRate,
26 OpenInterest,
27 Liquidation,
28 AggTrade,
29 BlockTrade,
31 IndexPrice,
32 CompositeIndex,
33 OptionGreeks,
34 VolatilityIndex,
35 HistoricalVolatility,
36 Basis,
37 InsuranceFund,
38 OrderbookL3,
39 SettlementEvent,
40 AuctionEvent,
41 MarketWarning,
42 RiskLimit,
43 PredictedFunding,
44 FundingSettlement,
45 MarkPriceKline(KlineInterval),
46 IndexPriceKline(KlineInterval),
47 PremiumIndexKline(KlineInterval),
48}
49
50impl Stream {
51 pub(crate) fn to_kind(&self) -> Kind {
52 match self {
53 Stream::Trade => Kind::Trade,
54 Stream::AggTrade => Kind::AggTrade,
55 Stream::Kline(iv) => Kind::Kline(iv.clone()),
56 Stream::Ticker => Kind::Ticker,
57 Stream::Orderbook => Kind::Orderbook,
58 Stream::MarkPrice => Kind::MarkPrice,
59 Stream::FundingRate => Kind::FundingRate,
60 Stream::OpenInterest => Kind::OpenInterest,
61 Stream::Liquidation => Kind::Liquidation,
62 Stream::BlockTrade => Kind::BlockTrade,
63 Stream::IndexPrice => Kind::IndexPrice,
64 Stream::CompositeIndex => Kind::CompositeIndex,
65 Stream::OptionGreeks => Kind::OptionGreeks,
66 Stream::VolatilityIndex => Kind::VolatilityIndex,
67 Stream::HistoricalVolatility => Kind::HistoricalVolatility,
68 Stream::Basis => Kind::Basis,
69 Stream::InsuranceFund => Kind::InsuranceFund,
70 Stream::OrderbookL3 => Kind::OrderbookL3,
71 Stream::SettlementEvent => Kind::SettlementEvent,
72 Stream::AuctionEvent => Kind::AuctionEvent,
73 Stream::MarketWarning => Kind::MarketWarning,
74 Stream::RiskLimit => Kind::RiskLimit,
75 Stream::PredictedFunding => Kind::PredictedFunding,
76 Stream::FundingSettlement => Kind::FundingSettlement,
77 Stream::MarkPriceKline(iv) => Kind::MarkPriceKline(iv.clone()),
78 Stream::IndexPriceKline(iv) => Kind::IndexPriceKline(iv.clone()),
79 Stream::PremiumIndexKline(iv) => Kind::PremiumIndexKline(iv.clone()),
80 }
81 }
82}
83
84#[derive(Debug, Clone)]
85pub(crate) struct Entry {
86 pub(crate) exchange: ExchangeId,
87 pub(crate) symbol: String,
88 pub(crate) account_type: AccountType,
89 pub(crate) streams: Vec<Stream>,
90}
91
92#[derive(Debug, Default, Clone)]
95pub struct SubscriptionSet {
96 pub(crate) entries: Vec<Entry>,
97}
98
99impl SubscriptionSet {
100 pub fn new() -> Self { Self::default() }
101
102 pub fn add(
103 mut self,
104 exchange: ExchangeId,
105 symbol: impl Into<String>,
106 account_type: AccountType,
107 streams: impl IntoIterator<Item = Stream>,
108 ) -> Self {
109 self.entries.push(Entry {
110 exchange,
111 symbol: symbol.into(),
112 account_type,
113 streams: streams.into_iter().collect(),
114 });
115 self
116 }
117
118 pub fn len(&self) -> usize { self.entries.len() }
119 pub fn is_empty(&self) -> bool { self.entries.is_empty() }
120}
121
122#[derive(Debug, Clone)]
124pub enum Event {
125 Trade {
126 exchange: ExchangeId,
127 symbol: String,
128 point: TradePoint,
129 },
130 AggTrade {
131 exchange: ExchangeId,
132 symbol: String,
133 point: AggTradePoint,
134 },
135 Bar {
136 exchange: ExchangeId,
137 symbol: String,
138 timeframe: KlineInterval,
139 point: BarPoint,
140 },
141 Ticker {
142 exchange: ExchangeId,
143 symbol: String,
144 point: TickerPoint,
145 },
146 OrderbookSnapshot {
147 exchange: ExchangeId,
148 symbol: String,
149 point: ObSnapshotPoint,
150 },
151 MarkPrice {
152 exchange: ExchangeId,
153 symbol: String,
154 point: MarkPricePoint,
155 },
156 FundingRate {
157 exchange: ExchangeId,
158 symbol: String,
159 point: FundingRatePoint,
160 },
161 OpenInterest {
162 exchange: ExchangeId,
163 symbol: String,
164 point: OpenInterestPoint,
165 },
166 Liquidation {
167 exchange: ExchangeId,
168 symbol: String,
169 point: LiquidationPoint,
170 },
171 BlockTrade {
173 exchange: ExchangeId,
174 symbol: String,
175 point: BlockTradePoint,
176 },
177 IndexPrice {
178 exchange: ExchangeId,
179 symbol: String,
180 point: IndexPricePoint,
181 },
182 CompositeIndex {
183 exchange: ExchangeId,
184 symbol: String,
185 point: CompositeIndexPoint,
186 },
187 OptionGreeks {
188 exchange: ExchangeId,
189 symbol: String,
190 point: OptionGreeksPoint,
191 },
192 VolatilityIndex {
193 exchange: ExchangeId,
194 symbol: String,
195 point: VolatilityIndexPoint,
196 },
197 HistoricalVolatility {
198 exchange: ExchangeId,
199 symbol: String,
200 point: HistoricalVolatilityPoint,
201 },
202 Basis {
203 exchange: ExchangeId,
204 symbol: String,
205 point: BasisPoint,
206 },
207 InsuranceFund {
208 exchange: ExchangeId,
209 symbol: String,
210 point: InsuranceFundPoint,
211 },
212 OrderbookL3 {
213 exchange: ExchangeId,
214 symbol: String,
215 point: OrderbookL3Point,
216 },
217 SettlementEvent {
218 exchange: ExchangeId,
219 symbol: String,
220 point: SettlementEventPoint,
221 },
222 AuctionEvent {
223 exchange: ExchangeId,
224 symbol: String,
225 point: AuctionEventPoint,
226 },
227 MarketWarning {
228 exchange: ExchangeId,
229 symbol: String,
230 point: MarketWarningPoint,
231 },
232 RiskLimit {
233 exchange: ExchangeId,
234 symbol: String,
235 point: RiskLimitPoint,
236 },
237 PredictedFunding {
238 exchange: ExchangeId,
239 symbol: String,
240 point: PredictedFundingPoint,
241 },
242 FundingSettlement {
243 exchange: ExchangeId,
244 symbol: String,
245 point: FundingSettlementPoint,
246 },
247 MarkPriceKline {
248 exchange: ExchangeId,
249 symbol: String,
250 timeframe: KlineInterval,
251 point: MarkPriceKlinePoint,
252 },
253 IndexPriceKline {
254 exchange: ExchangeId,
255 symbol: String,
256 timeframe: KlineInterval,
257 point: IndexPriceKlinePoint,
258 },
259 PremiumIndexKline {
260 exchange: ExchangeId,
261 symbol: String,
262 timeframe: KlineInterval,
263 point: PremiumIndexKlinePoint,
264 },
265}
266
267impl Event {
268 pub fn exchange(&self) -> ExchangeId {
269 match self {
270 Event::Trade { exchange, .. } | Event::AggTrade { exchange, .. } |
271 Event::Bar { exchange, .. } | Event::Ticker { exchange, .. } |
272 Event::OrderbookSnapshot { exchange, .. } | Event::MarkPrice { exchange, .. } |
273 Event::FundingRate { exchange, .. } | Event::OpenInterest { exchange, .. } |
274 Event::Liquidation { exchange, .. } |
275 Event::BlockTrade { exchange, .. } | Event::IndexPrice { exchange, .. } |
276 Event::CompositeIndex { exchange, .. } | Event::OptionGreeks { exchange, .. } |
277 Event::VolatilityIndex { exchange, .. } | Event::HistoricalVolatility { exchange, .. } |
278 Event::Basis { exchange, .. } | Event::InsuranceFund { exchange, .. } |
279 Event::OrderbookL3 { exchange, .. } | Event::SettlementEvent { exchange, .. } |
280 Event::AuctionEvent { exchange, .. } | Event::MarketWarning { exchange, .. } |
281 Event::RiskLimit { exchange, .. } | Event::PredictedFunding { exchange, .. } |
282 Event::FundingSettlement { exchange, .. } |
283 Event::MarkPriceKline { exchange, .. } | Event::IndexPriceKline { exchange, .. } |
284 Event::PremiumIndexKline { exchange, .. } => *exchange,
285 }
286 }
287 pub fn symbol(&self) -> &str {
288 match self {
289 Event::Trade { symbol, .. } | Event::AggTrade { symbol, .. } |
290 Event::Bar { symbol, .. } | Event::Ticker { symbol, .. } |
291 Event::OrderbookSnapshot { symbol, .. } | Event::MarkPrice { symbol, .. } |
292 Event::FundingRate { symbol, .. } | Event::OpenInterest { symbol, .. } |
293 Event::Liquidation { symbol, .. } |
294 Event::BlockTrade { symbol, .. } | Event::IndexPrice { symbol, .. } |
295 Event::CompositeIndex { symbol, .. } | Event::OptionGreeks { symbol, .. } |
296 Event::VolatilityIndex { symbol, .. } | Event::HistoricalVolatility { symbol, .. } |
297 Event::Basis { symbol, .. } | Event::InsuranceFund { symbol, .. } |
298 Event::OrderbookL3 { symbol, .. } | Event::SettlementEvent { symbol, .. } |
299 Event::AuctionEvent { symbol, .. } | Event::MarketWarning { symbol, .. } |
300 Event::RiskLimit { symbol, .. } | Event::PredictedFunding { symbol, .. } |
301 Event::FundingSettlement { symbol, .. } |
302 Event::MarkPriceKline { symbol, .. } | Event::IndexPriceKline { symbol, .. } |
303 Event::PremiumIndexKline { symbol, .. } => symbol,
304 }
305 }
306
307 pub(crate) fn set_symbol(&mut self, new_symbol: String) {
315 match self {
316 Event::Trade { symbol, .. }
317 | Event::AggTrade { symbol, .. }
318 | Event::Bar { symbol, .. }
319 | Event::Ticker { symbol, .. }
320 | Event::OrderbookSnapshot { symbol, .. }
321 | Event::MarkPrice { symbol, .. }
322 | Event::FundingRate { symbol, .. }
323 | Event::OpenInterest { symbol, .. }
324 | Event::Liquidation { symbol, .. }
325 | Event::BlockTrade { symbol, .. }
326 | Event::IndexPrice { symbol, .. }
327 | Event::CompositeIndex { symbol, .. }
328 | Event::OptionGreeks { symbol, .. }
329 | Event::VolatilityIndex { symbol, .. }
330 | Event::HistoricalVolatility { symbol, .. }
331 | Event::Basis { symbol, .. }
332 | Event::InsuranceFund { symbol, .. }
333 | Event::OrderbookL3 { symbol, .. }
334 | Event::SettlementEvent { symbol, .. }
335 | Event::AuctionEvent { symbol, .. }
336 | Event::MarketWarning { symbol, .. }
337 | Event::RiskLimit { symbol, .. }
338 | Event::PredictedFunding { symbol, .. }
339 | Event::FundingSettlement { symbol, .. }
340 | Event::MarkPriceKline { symbol, .. }
341 | Event::IndexPriceKline { symbol, .. }
342 | Event::PremiumIndexKline { symbol, .. } => *symbol = new_symbol,
343 }
344 }
345 pub fn timestamp_ms(&self) -> i64 {
346 use crate::series::DataPoint;
347 match self {
348 Event::Trade { point, .. } => point.timestamp_ms(),
349 Event::AggTrade { point, .. } => point.timestamp_ms(),
350 Event::Bar { point, .. } => point.timestamp_ms(),
351 Event::Ticker { point, .. } => point.timestamp_ms(),
352 Event::OrderbookSnapshot { point, .. } => point.timestamp_ms(),
353 Event::MarkPrice { point, .. } => point.timestamp_ms(),
354 Event::FundingRate { point, .. } => point.timestamp_ms(),
355 Event::OpenInterest { point, .. } => point.timestamp_ms(),
356 Event::Liquidation { point, .. } => point.timestamp_ms(),
357 Event::BlockTrade { point, .. } => point.timestamp_ms(),
358 Event::IndexPrice { point, .. } => point.timestamp_ms(),
359 Event::CompositeIndex { point, .. } => point.timestamp_ms(),
360 Event::OptionGreeks { point, .. } => point.timestamp_ms(),
361 Event::VolatilityIndex { point, .. } => point.timestamp_ms(),
362 Event::HistoricalVolatility { point, .. } => point.timestamp_ms(),
363 Event::Basis { point, .. } => point.timestamp_ms(),
364 Event::InsuranceFund { point, .. } => point.timestamp_ms(),
365 Event::OrderbookL3 { point, .. } => point.timestamp_ms(),
366 Event::SettlementEvent { point, .. } => point.timestamp_ms(),
367 Event::AuctionEvent { point, .. } => point.timestamp_ms(),
368 Event::MarketWarning { point, .. } => point.timestamp_ms(),
369 Event::RiskLimit { point, .. } => point.timestamp_ms(),
370 Event::PredictedFunding { point, .. } => point.timestamp_ms(),
371 Event::FundingSettlement { point, .. } => point.timestamp_ms(),
372 Event::MarkPriceKline { point, .. } => point.timestamp_ms(),
373 Event::IndexPriceKline { point, .. } => point.timestamp_ms(),
374 Event::PremiumIndexKline { point, .. } => point.timestamp_ms(),
375 }
376 }
377}
378
379pub struct SubscriptionHandle {
383 pub(crate) rx: tokio::sync::mpsc::UnboundedReceiver<Event>,
384 pub(crate) _refs: Vec<MultiplexRef>,
385}
386
387impl std::fmt::Debug for SubscriptionHandle {
388 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
389 f.debug_struct("SubscriptionHandle").finish()
390 }
391}
392
393impl SubscriptionHandle {
394 pub async fn recv(&mut self) -> Option<Event> {
395 self.rx.recv().await
396 }
397}
398
399pub(crate) struct MultiplexRef {
400 pub(crate) station: std::sync::Weak<crate::station::StationInner>,
401 pub(crate) key: SeriesKey,
402}
403
404impl Drop for MultiplexRef {
405 fn drop(&mut self) {
406 if let Some(inner) = self.station.upgrade() {
407 inner.release_consumer(&self.key);
408 }
409 }
410}