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