Skip to main content

brokapi_bcs/
subs.rs

1//! The subscription records a connector keeps, and the generator of subscription ids.
2//!
3//! These types are the bookkeeping of the connectors. A bot does not build them: it gets a
4//! [`SubscriptionId`] from a `subscribe_*` call and passes it back to `unsubscribe`.
5
6use std::sync::atomic::{AtomicU64, Ordering};
7
8use brokapi_bcs_protocol::ws::models::MarketDataSubscribe;
9use brokapi_core::{InstrumentId, SubscribeOpts, SubscriptionId};
10
11/// What a market data subscription delivers.
12#[derive(Debug, Clone)]
13pub enum MdSubKind {
14    /// Order book snapshots of one instrument.
15    OrderBook,
16    /// Trades of the market (the tape) of one instrument.
17    MarketTrades,
18    /// Best bid and ask of one instrument.
19    Quotes,
20    /// The latest candle of one instrument and timeframe.
21    Candles,
22}
23
24/// One live market data subscription, as the connector remembers it.
25#[derive(Debug, Clone)]
26pub struct MdSubscription {
27    /// The id the bot got from `subscribe_*`.
28    pub id: SubscriptionId,
29    /// The instrument the data is about.
30    pub instrument: InstrumentId,
31    /// What the subscription delivers.
32    pub kind: MdSubKind,
33    /// The options given at subscribe time (backpressure policy, depth).
34    pub opts: SubscribeOpts,
35    /// The WebSocket message that created it. It is replayed after a reconnect, and its mirror
36    /// image is sent to unsubscribe.
37    pub ws: MarketDataSubscribe,
38}
39
40/// What a user data subscription delivers.
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum UdSubKind {
43    /// Status changes of orders.
44    OrderState,
45    /// Portfolio updates.
46    Portfolio,
47    /// Fills of orders.
48    Executions,
49}
50
51/// One live user data subscription, as the connector remembers it.
52#[derive(Debug, Clone)]
53pub struct UdSubscription {
54    /// The id the bot got from `subscribe_*`.
55    pub id: SubscriptionId,
56    /// What the subscription delivers.
57    pub kind: UdSubKind,
58    /// The options given at subscribe time. Order state and executions use a lossless buffer.
59    pub opts: SubscribeOpts,
60}
61
62/// Hands out subscription ids of one connector, in increasing order, from a thread-safe counter.
63///
64/// The market data connector counts from 1, the user data connector from 1001, so the ids of the
65/// two connectors of one bot do not collide.
66pub struct SubIdGen(AtomicU64);
67
68impl SubIdGen {
69    /// Creates a generator whose first id is `start + 1`.
70    pub fn new(start: u64) -> Self {
71        Self(AtomicU64::new(start))
72    }
73
74    /// Returns the next id. Safe to call from several tasks.
75    pub fn next(&self) -> SubscriptionId {
76        SubscriptionId::new(self.0.fetch_add(1, Ordering::Relaxed) + 1)
77    }
78}