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    CloseAllRequested {
68        job_id: u64,
69        total: usize,
70        symbols: Vec<String>,
71    },
72    CloseAllProgress {
73        job_id: u64,
74        symbol: String,
75        completed: usize,
76        total: usize,
77        failed: usize,
78        reason: Option<String>,
79    },
80    CloseAllFinished {
81        job_id: u64,
82        completed: usize,
83        total: usize,
84        failed: usize,
85    },
86    TickDropped,
87    LogRecord(LogRecord),
88    LogMessage(String),
89    Error(String),
90}
91
92#[derive(Debug, Clone, Default)]
93pub struct EvSnapshotEntry {
94    pub ev: f64,
95    pub p_win: f64,
96    pub gate_mode: String,
97    pub gate_blocked: bool,
98    pub updated_at_ms: u64,
99}
100
101#[derive(Debug, Clone, Default)]
102pub struct ExitPolicyEntry {
103    pub stop_price: Option<f64>,
104    pub expected_holding_ms: Option<u64>,
105    pub protective_stop_ok: Option<bool>,
106    pub updated_at_ms: u64,
107}
108
109#[derive(Debug, Clone, Default)]
110pub struct AssetPnlEntry {
111    pub is_futures: bool,
112    pub side: Option<OrderSide>,
113    pub position_qty: f64,
114    pub entry_price: f64,
115    pub realized_pnl_usdt: f64,
116    pub unrealized_pnl_usdt: f64,
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq)]
120pub enum LogLevel {
121    Debug,
122    Info,
123    Warn,
124    Error,
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq)]
128pub enum LogDomain {
129    Ws,
130    Strategy,
131    Risk,
132    Order,
133    Portfolio,
134    Ui,
135    System,
136}
137
138#[derive(Debug, Clone)]
139pub struct LogRecord {
140    pub ts_ms: u64,
141    pub level: LogLevel,
142    pub domain: LogDomain,
143    pub event: &'static str,
144    pub symbol: Option<String>,
145    pub strategy_tag: Option<String>,
146    pub trace_id: Option<String>,
147    pub msg: String,
148}
149
150impl LogRecord {
151    pub fn new(level: LogLevel, domain: LogDomain, event: &'static str, msg: impl Into<String>) -> Self {
152        Self {
153            ts_ms: chrono::Utc::now().timestamp_millis() as u64,
154            level,
155            domain,
156            event,
157            symbol: None,
158            strategy_tag: None,
159            trace_id: None,
160            msg: msg.into(),
161        }
162    }
163}