Skip to main content

bat_markets_core/
execution.rs

1use serde::{Deserialize, Serialize};
2
3use crate::account::Balance;
4use crate::command::{CommandLifecycleEvent, CommandReceipt};
5use crate::market::{FastBookTop, FastKline, FastTicker, FastTrade, FundingRate, OpenInterest};
6use crate::market::{FastLiquidation, FastMarkPrice, FastOrderBookDelta};
7use crate::position::Position;
8use crate::primitives::SequenceNumber;
9use crate::trade::{Execution, Order};
10
11/// Coarse behavior for a single execution lane.
12#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
13pub struct LanePolicy {
14    pub lossless: bool,
15    pub coalescing_allowed: bool,
16    pub buffer_capacity: usize,
17    pub reconnect_required: bool,
18    pub idempotent: bool,
19}
20
21/// Stable lane policies exposed by the adapter.
22#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
23pub struct LaneSet {
24    pub public: LanePolicy,
25    pub private: LanePolicy,
26    pub command: LanePolicy,
27}
28
29impl LaneSet {
30    /// Standard lane policies shared by current linear futures adapters.
31    #[must_use]
32    pub const fn linear_futures_defaults() -> Self {
33        Self {
34            public: LanePolicy {
35                lossless: false,
36                coalescing_allowed: true,
37                buffer_capacity: 4_096,
38                reconnect_required: true,
39                idempotent: false,
40            },
41            private: LanePolicy {
42                lossless: true,
43                coalescing_allowed: false,
44                buffer_capacity: 8_192,
45                reconnect_required: true,
46                idempotent: true,
47            },
48            command: LanePolicy {
49                lossless: true,
50                coalescing_allowed: false,
51                buffer_capacity: 1_024,
52                reconnect_required: true,
53                idempotent: true,
54            },
55        }
56    }
57}
58
59/// Public market-data lane output.
60#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
61pub enum PublicLaneEvent {
62    Ticker(FastTicker),
63    Trade(FastTrade),
64    BookTop(FastBookTop),
65    OrderBookDelta(FastOrderBookDelta),
66    Kline(FastKline),
67    MarkPrice(FastMarkPrice),
68    FundingRate(FundingRate),
69    OpenInterest(OpenInterest),
70    Liquidation(FastLiquidation),
71    Divergence(DivergenceEvent),
72}
73
74/// Divergence marker surfaced by live transport or reconciliation paths.
75#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
76pub enum DivergenceEvent {
77    ReconcileRequired,
78    StateDivergence,
79    SequenceGap { at: Option<SequenceNumber> },
80}
81
82/// Private state-lane output.
83#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
84pub enum PrivateLaneEvent {
85    Balance(Balance),
86    Position(Position),
87    Order(Order),
88    Execution(Execution),
89    Divergence(DivergenceEvent),
90}
91
92/// Command-lane output.
93#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
94pub enum CommandLaneEvent {
95    Receipt(CommandReceipt),
96    Lifecycle(CommandLifecycleEvent),
97}
98
99#[cfg(test)]
100mod tests {
101    use super::*;
102
103    #[test]
104    fn linear_futures_lane_defaults_keep_public_lossy_and_commands_lossless() {
105        let lanes = LaneSet::linear_futures_defaults();
106
107        assert!(!lanes.public.lossless);
108        assert!(lanes.public.coalescing_allowed);
109        assert_eq!(lanes.public.buffer_capacity, 4_096);
110        assert!(lanes.private.lossless);
111        assert!(!lanes.private.coalescing_allowed);
112        assert_eq!(lanes.private.buffer_capacity, 8_192);
113        assert!(lanes.command.lossless);
114        assert!(lanes.command.idempotent);
115        assert_eq!(lanes.command.buffer_capacity, 1_024);
116    }
117}