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