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, ObDeltaPoint, ObSnapshotPoint, OpenInterestPoint, OptionGreeksPoint,
9 OrderbookL3Point, PredictedFundingPoint, PremiumIndexKlinePoint, RiskLimitPoint,
10 SettlementEventPoint, 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 OrderbookDelta,
24 Kline(KlineInterval),
25 MarkPrice,
26 FundingRate,
27 OpenInterest,
28 Liquidation,
29 AggTrade,
30 BlockTrade,
32 IndexPrice,
33 CompositeIndex,
34 OptionGreeks,
35 VolatilityIndex,
36 HistoricalVolatility,
37 Basis,
38 InsuranceFund,
39 OrderbookL3,
40 SettlementEvent,
41 AuctionEvent,
42 MarketWarning,
43 RiskLimit,
44 PredictedFunding,
45 FundingSettlement,
46 MarkPriceKline(KlineInterval),
47 IndexPriceKline(KlineInterval),
48 PremiumIndexKline(KlineInterval),
49}
50
51impl Stream {
52 pub(crate) fn to_kind(&self) -> Kind {
53 match self {
54 Stream::Trade => Kind::Trade,
55 Stream::AggTrade => Kind::AggTrade,
56 Stream::Kline(iv) => Kind::Kline(iv.clone()),
57 Stream::Ticker => Kind::Ticker,
58 Stream::Orderbook => Kind::Orderbook,
59 Stream::OrderbookDelta => Kind::OrderbookDelta,
60 Stream::MarkPrice => Kind::MarkPrice,
61 Stream::FundingRate => Kind::FundingRate,
62 Stream::OpenInterest => Kind::OpenInterest,
63 Stream::Liquidation => Kind::Liquidation,
64 Stream::BlockTrade => Kind::BlockTrade,
65 Stream::IndexPrice => Kind::IndexPrice,
66 Stream::CompositeIndex => Kind::CompositeIndex,
67 Stream::OptionGreeks => Kind::OptionGreeks,
68 Stream::VolatilityIndex => Kind::VolatilityIndex,
69 Stream::HistoricalVolatility => Kind::HistoricalVolatility,
70 Stream::Basis => Kind::Basis,
71 Stream::InsuranceFund => Kind::InsuranceFund,
72 Stream::OrderbookL3 => Kind::OrderbookL3,
73 Stream::SettlementEvent => Kind::SettlementEvent,
74 Stream::AuctionEvent => Kind::AuctionEvent,
75 Stream::MarketWarning => Kind::MarketWarning,
76 Stream::RiskLimit => Kind::RiskLimit,
77 Stream::PredictedFunding => Kind::PredictedFunding,
78 Stream::FundingSettlement => Kind::FundingSettlement,
79 Stream::MarkPriceKline(iv) => Kind::MarkPriceKline(iv.clone()),
80 Stream::IndexPriceKline(iv) => Kind::IndexPriceKline(iv.clone()),
81 Stream::PremiumIndexKline(iv) => Kind::PremiumIndexKline(iv.clone()),
82 }
83 }
84}
85
86#[derive(Debug, Clone)]
87pub(crate) struct Entry {
88 pub(crate) exchange: ExchangeId,
89 pub(crate) symbol: String,
90 pub(crate) account_type: AccountType,
91 pub(crate) streams: Vec<Stream>,
92 pub(crate) is_raw: bool,
99}
100
101#[derive(Debug, Default, Clone)]
104pub struct SubscriptionSet {
105 pub(crate) entries: Vec<Entry>,
106}
107
108impl SubscriptionSet {
109 pub fn new() -> Self { Self::default() }
110
111 pub fn add(
118 mut self,
119 exchange: ExchangeId,
120 symbol: impl Into<String>,
121 account_type: AccountType,
122 streams: impl IntoIterator<Item = Stream>,
123 ) -> Self {
124 self.entries.push(Entry {
125 exchange,
126 symbol: symbol.into(),
127 account_type,
128 streams: streams.into_iter().collect(),
129 is_raw: false,
130 });
131 self
132 }
133
134 pub fn add_raw(
146 mut self,
147 exchange: ExchangeId,
148 symbol: impl Into<String>,
149 account_type: AccountType,
150 streams: impl IntoIterator<Item = Stream>,
151 ) -> Self {
152 self.entries.push(Entry {
153 exchange,
154 symbol: symbol.into(),
155 account_type,
156 streams: streams.into_iter().collect(),
157 is_raw: true,
158 });
159 self
160 }
161
162 pub fn len(&self) -> usize { self.entries.len() }
163 pub fn is_empty(&self) -> bool { self.entries.is_empty() }
164}
165
166#[derive(Debug, Clone)]
168pub enum Event {
169 Trade {
170 exchange: ExchangeId,
171 symbol: String,
172 point: TradePoint,
173 },
174 AggTrade {
175 exchange: ExchangeId,
176 symbol: String,
177 point: AggTradePoint,
178 },
179 Bar {
180 exchange: ExchangeId,
181 symbol: String,
182 timeframe: KlineInterval,
183 point: BarPoint,
184 },
185 Ticker {
186 exchange: ExchangeId,
187 symbol: String,
188 point: TickerPoint,
189 },
190 OrderbookSnapshot {
191 exchange: ExchangeId,
192 symbol: String,
193 point: ObSnapshotPoint,
194 },
195 OrderbookDelta {
196 exchange: ExchangeId,
197 symbol: String,
198 point: ObDeltaPoint,
199 },
200 MarkPrice {
201 exchange: ExchangeId,
202 symbol: String,
203 point: MarkPricePoint,
204 },
205 FundingRate {
206 exchange: ExchangeId,
207 symbol: String,
208 point: FundingRatePoint,
209 },
210 OpenInterest {
211 exchange: ExchangeId,
212 symbol: String,
213 point: OpenInterestPoint,
214 },
215 Liquidation {
216 exchange: ExchangeId,
217 symbol: String,
218 point: LiquidationPoint,
219 },
220 BlockTrade {
222 exchange: ExchangeId,
223 symbol: String,
224 point: BlockTradePoint,
225 },
226 IndexPrice {
227 exchange: ExchangeId,
228 symbol: String,
229 point: IndexPricePoint,
230 },
231 CompositeIndex {
232 exchange: ExchangeId,
233 symbol: String,
234 point: CompositeIndexPoint,
235 },
236 OptionGreeks {
237 exchange: ExchangeId,
238 symbol: String,
239 point: OptionGreeksPoint,
240 },
241 VolatilityIndex {
242 exchange: ExchangeId,
243 symbol: String,
244 point: VolatilityIndexPoint,
245 },
246 HistoricalVolatility {
247 exchange: ExchangeId,
248 symbol: String,
249 point: HistoricalVolatilityPoint,
250 },
251 Basis {
252 exchange: ExchangeId,
253 symbol: String,
254 point: BasisPoint,
255 },
256 InsuranceFund {
257 exchange: ExchangeId,
258 symbol: String,
259 point: InsuranceFundPoint,
260 },
261 OrderbookL3 {
262 exchange: ExchangeId,
263 symbol: String,
264 point: OrderbookL3Point,
265 },
266 SettlementEvent {
267 exchange: ExchangeId,
268 symbol: String,
269 point: SettlementEventPoint,
270 },
271 AuctionEvent {
272 exchange: ExchangeId,
273 symbol: String,
274 point: AuctionEventPoint,
275 },
276 MarketWarning {
277 exchange: ExchangeId,
278 symbol: String,
279 point: MarketWarningPoint,
280 },
281 RiskLimit {
282 exchange: ExchangeId,
283 symbol: String,
284 point: RiskLimitPoint,
285 },
286 PredictedFunding {
287 exchange: ExchangeId,
288 symbol: String,
289 point: PredictedFundingPoint,
290 },
291 FundingSettlement {
292 exchange: ExchangeId,
293 symbol: String,
294 point: FundingSettlementPoint,
295 },
296 MarkPriceKline {
297 exchange: ExchangeId,
298 symbol: String,
299 timeframe: KlineInterval,
300 point: MarkPriceKlinePoint,
301 },
302 IndexPriceKline {
303 exchange: ExchangeId,
304 symbol: String,
305 timeframe: KlineInterval,
306 point: IndexPriceKlinePoint,
307 },
308 PremiumIndexKline {
309 exchange: ExchangeId,
310 symbol: String,
311 timeframe: KlineInterval,
312 point: PremiumIndexKlinePoint,
313 },
314}
315
316impl Event {
317 pub fn exchange(&self) -> ExchangeId {
318 match self {
319 Event::Trade { exchange, .. } | Event::AggTrade { exchange, .. } |
320 Event::Bar { exchange, .. } | Event::Ticker { exchange, .. } |
321 Event::OrderbookSnapshot { exchange, .. } | Event::OrderbookDelta { exchange, .. } |
322 Event::MarkPrice { exchange, .. } |
323 Event::FundingRate { exchange, .. } | Event::OpenInterest { exchange, .. } |
324 Event::Liquidation { exchange, .. } |
325 Event::BlockTrade { exchange, .. } | Event::IndexPrice { exchange, .. } |
326 Event::CompositeIndex { exchange, .. } | Event::OptionGreeks { exchange, .. } |
327 Event::VolatilityIndex { exchange, .. } | Event::HistoricalVolatility { exchange, .. } |
328 Event::Basis { exchange, .. } | Event::InsuranceFund { exchange, .. } |
329 Event::OrderbookL3 { exchange, .. } | Event::SettlementEvent { exchange, .. } |
330 Event::AuctionEvent { exchange, .. } | Event::MarketWarning { exchange, .. } |
331 Event::RiskLimit { exchange, .. } | Event::PredictedFunding { exchange, .. } |
332 Event::FundingSettlement { exchange, .. } |
333 Event::MarkPriceKline { exchange, .. } | Event::IndexPriceKline { exchange, .. } |
334 Event::PremiumIndexKline { exchange, .. } => *exchange,
335 }
336 }
337 pub fn symbol(&self) -> &str {
338 match self {
339 Event::Trade { symbol, .. } | Event::AggTrade { symbol, .. } |
340 Event::Bar { symbol, .. } | Event::Ticker { symbol, .. } |
341 Event::OrderbookSnapshot { symbol, .. } | Event::OrderbookDelta { symbol, .. } |
342 Event::MarkPrice { symbol, .. } |
343 Event::FundingRate { symbol, .. } | Event::OpenInterest { symbol, .. } |
344 Event::Liquidation { symbol, .. } |
345 Event::BlockTrade { symbol, .. } | Event::IndexPrice { symbol, .. } |
346 Event::CompositeIndex { symbol, .. } | Event::OptionGreeks { symbol, .. } |
347 Event::VolatilityIndex { symbol, .. } | Event::HistoricalVolatility { symbol, .. } |
348 Event::Basis { symbol, .. } | Event::InsuranceFund { symbol, .. } |
349 Event::OrderbookL3 { symbol, .. } | Event::SettlementEvent { symbol, .. } |
350 Event::AuctionEvent { symbol, .. } | Event::MarketWarning { symbol, .. } |
351 Event::RiskLimit { symbol, .. } | Event::PredictedFunding { symbol, .. } |
352 Event::FundingSettlement { symbol, .. } |
353 Event::MarkPriceKline { symbol, .. } | Event::IndexPriceKline { symbol, .. } |
354 Event::PremiumIndexKline { symbol, .. } => symbol,
355 }
356 }
357
358 pub(crate) fn set_symbol(&mut self, new_symbol: String) {
366 match self {
367 Event::Trade { symbol, .. }
368 | Event::AggTrade { symbol, .. }
369 | Event::Bar { symbol, .. }
370 | Event::Ticker { symbol, .. }
371 | Event::OrderbookSnapshot { symbol, .. }
372 | Event::OrderbookDelta { symbol, .. }
373 | Event::MarkPrice { symbol, .. }
374 | Event::FundingRate { symbol, .. }
375 | Event::OpenInterest { symbol, .. }
376 | Event::Liquidation { symbol, .. }
377 | Event::BlockTrade { symbol, .. }
378 | Event::IndexPrice { symbol, .. }
379 | Event::CompositeIndex { symbol, .. }
380 | Event::OptionGreeks { symbol, .. }
381 | Event::VolatilityIndex { symbol, .. }
382 | Event::HistoricalVolatility { symbol, .. }
383 | Event::Basis { symbol, .. }
384 | Event::InsuranceFund { symbol, .. }
385 | Event::OrderbookL3 { symbol, .. }
386 | Event::SettlementEvent { symbol, .. }
387 | Event::AuctionEvent { symbol, .. }
388 | Event::MarketWarning { symbol, .. }
389 | Event::RiskLimit { symbol, .. }
390 | Event::PredictedFunding { symbol, .. }
391 | Event::FundingSettlement { symbol, .. }
392 | Event::MarkPriceKline { symbol, .. }
393 | Event::IndexPriceKline { symbol, .. }
394 | Event::PremiumIndexKline { symbol, .. } => *symbol = new_symbol,
395 }
396 }
397 pub fn timestamp_ms(&self) -> i64 {
398 use crate::series::DataPoint;
399 match self {
400 Event::Trade { point, .. } => point.timestamp_ms(),
401 Event::AggTrade { point, .. } => point.timestamp_ms(),
402 Event::Bar { point, .. } => point.timestamp_ms(),
403 Event::Ticker { point, .. } => point.timestamp_ms(),
404 Event::OrderbookSnapshot { point, .. } => point.timestamp_ms(),
405 Event::OrderbookDelta { point, .. } => point.timestamp_ms(),
406 Event::MarkPrice { point, .. } => point.timestamp_ms(),
407 Event::FundingRate { point, .. } => point.timestamp_ms(),
408 Event::OpenInterest { point, .. } => point.timestamp_ms(),
409 Event::Liquidation { point, .. } => point.timestamp_ms(),
410 Event::BlockTrade { point, .. } => point.timestamp_ms(),
411 Event::IndexPrice { point, .. } => point.timestamp_ms(),
412 Event::CompositeIndex { point, .. } => point.timestamp_ms(),
413 Event::OptionGreeks { point, .. } => point.timestamp_ms(),
414 Event::VolatilityIndex { point, .. } => point.timestamp_ms(),
415 Event::HistoricalVolatility { point, .. } => point.timestamp_ms(),
416 Event::Basis { point, .. } => point.timestamp_ms(),
417 Event::InsuranceFund { point, .. } => point.timestamp_ms(),
418 Event::OrderbookL3 { point, .. } => point.timestamp_ms(),
419 Event::SettlementEvent { point, .. } => point.timestamp_ms(),
420 Event::AuctionEvent { point, .. } => point.timestamp_ms(),
421 Event::MarketWarning { point, .. } => point.timestamp_ms(),
422 Event::RiskLimit { point, .. } => point.timestamp_ms(),
423 Event::PredictedFunding { point, .. } => point.timestamp_ms(),
424 Event::FundingSettlement { point, .. } => point.timestamp_ms(),
425 Event::MarkPriceKline { point, .. } => point.timestamp_ms(),
426 Event::IndexPriceKline { point, .. } => point.timestamp_ms(),
427 Event::PremiumIndexKline { point, .. } => point.timestamp_ms(),
428 }
429 }
430}
431
432pub struct SubscriptionHandle {
436 pub(crate) rx: tokio::sync::mpsc::UnboundedReceiver<Event>,
437 pub(crate) _refs: Vec<MultiplexRef>,
438}
439
440impl std::fmt::Debug for SubscriptionHandle {
441 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
442 f.debug_struct("SubscriptionHandle").finish()
443 }
444}
445
446impl SubscriptionHandle {
447 pub async fn recv(&mut self) -> Option<Event> {
448 self.rx.recv().await
449 }
450}
451
452#[derive(Debug)]
459pub struct FailedStream {
460 pub exchange: ExchangeId,
461 pub account_type: AccountType,
462 pub symbol: String,
464 pub stream: Stream,
465 pub error: crate::StationError,
466}
467
468pub struct SubscribeReport {
481 pub handle: SubscriptionHandle,
482 pub ok: Vec<SeriesKey>,
483 pub failed: Vec<FailedStream>,
484}
485
486impl SubscribeReport {
487 pub fn is_fully_ok(&self) -> bool { self.failed.is_empty() }
489 pub fn total(&self) -> usize { self.ok.len() + self.failed.len() }
491}
492
493impl std::fmt::Debug for SubscribeReport {
494 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
495 f.debug_struct("SubscribeReport")
496 .field("ok", &self.ok.len())
497 .field("failed", &self.failed.len())
498 .finish()
499 }
500}
501
502pub(crate) struct MultiplexRef {
503 pub(crate) station: std::sync::Weak<crate::station::StationInner>,
504 pub(crate) key: SeriesKey,
505}
506
507impl Drop for MultiplexRef {
508 fn drop(&mut self) {
509 if let Some(inner) = self.station.upgrade() {
510 inner.release_consumer(&self.key);
511 }
512 }
513}