Skip to main content

sandbox_quant/
event.rs

1use std::collections::HashMap;
2
3use crate::model::candle::Candle;
4use crate::model::order::OrderSide;
5use crate::model::signal::Signal;
6use crate::model::tick::Tick;
7use crate::order_manager::{OrderHistorySnapshot, OrderHistoryStats, OrderUpdate};
8use crate::risk_module::RateBudgetSnapshot;
9
10#[derive(Debug, Clone)]
11pub enum WsConnectionStatus {
12    Connected,
13    Disconnected,
14    Reconnecting { attempt: u32, delay_ms: u64 },
15}
16
17#[derive(Debug, Clone)]
18pub enum AppEvent {
19    MarketTick(Tick),
20    StrategySignal {
21        signal: Signal,
22        symbol: String,
23        source_tag: String,
24        price: Option<f64>,
25        timestamp_ms: u64,
26    },
27    StrategyState {
28        fast_sma: Option<f64>,
29        slow_sma: Option<f64>,
30    },
31    OrderUpdate(OrderUpdate),
32    WsStatus(WsConnectionStatus),
33    HistoricalCandles {
34        candles: Vec<Candle>,
35        interval_ms: u64,
36        interval: String,
37    },
38    BalanceUpdate(HashMap<String, f64>),
39    OrderHistoryUpdate(OrderHistorySnapshot),
40    StrategyStatsUpdate {
41        strategy_stats: HashMap<String, OrderHistoryStats>,
42    },
43    EvSnapshotUpdate {
44        symbol: String,
45        source_tag: String,
46        ev: f64,
47        p_win: f64,
48        gate_mode: String,
49        gate_blocked: bool,
50    },
51    ExitPolicyUpdate {
52        symbol: String,
53        source_tag: String,
54        stop_price: Option<f64>,
55        expected_holding_ms: Option<u64>,
56        protective_stop_ok: Option<bool>,
57    },
58    AssetPnlUpdate {
59        by_symbol: HashMap<String, AssetPnlEntry>,
60    },
61    RiskRateSnapshot {
62        global: RateBudgetSnapshot,
63        orders: RateBudgetSnapshot,
64        account: RateBudgetSnapshot,
65        market_data: RateBudgetSnapshot,
66    },
67    TickDropped,
68    LogRecord(LogRecord),
69    LogMessage(String),
70    Error(String),
71}
72
73#[derive(Debug, Clone, Default)]
74pub struct EvSnapshotEntry {
75    pub ev: f64,
76    pub p_win: f64,
77    pub gate_mode: String,
78    pub gate_blocked: bool,
79    pub updated_at_ms: u64,
80}
81
82#[derive(Debug, Clone, Default)]
83pub struct ExitPolicyEntry {
84    pub stop_price: Option<f64>,
85    pub expected_holding_ms: Option<u64>,
86    pub protective_stop_ok: Option<bool>,
87    pub updated_at_ms: u64,
88}
89
90#[derive(Debug, Clone, Default)]
91pub struct AssetPnlEntry {
92    pub is_futures: bool,
93    pub side: Option<OrderSide>,
94    pub position_qty: f64,
95    pub entry_price: f64,
96    pub realized_pnl_usdt: f64,
97    pub unrealized_pnl_usdt: f64,
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Eq)]
101pub enum LogLevel {
102    Debug,
103    Info,
104    Warn,
105    Error,
106}
107
108#[derive(Debug, Clone, Copy, PartialEq, Eq)]
109pub enum LogDomain {
110    Ws,
111    Strategy,
112    Risk,
113    Order,
114    Portfolio,
115    Ui,
116    System,
117}
118
119#[derive(Debug, Clone)]
120pub struct LogRecord {
121    pub ts_ms: u64,
122    pub level: LogLevel,
123    pub domain: LogDomain,
124    pub event: &'static str,
125    pub symbol: Option<String>,
126    pub strategy_tag: Option<String>,
127    pub trace_id: Option<String>,
128    pub msg: String,
129}
130
131impl LogRecord {
132    pub fn new(level: LogLevel, domain: LogDomain, event: &'static str, msg: impl Into<String>) -> Self {
133        Self {
134            ts_ms: chrono::Utc::now().timestamp_millis() as u64,
135            level,
136            domain,
137            event,
138            symbol: None,
139            strategy_tag: None,
140            trace_id: None,
141            msg: msg.into(),
142        }
143    }
144}