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 AssetPnlUpdate {
44 by_symbol: HashMap<String, AssetPnlEntry>,
45 },
46 RiskRateSnapshot {
47 global: RateBudgetSnapshot,
48 orders: RateBudgetSnapshot,
49 account: RateBudgetSnapshot,
50 market_data: RateBudgetSnapshot,
51 },
52 TickDropped,
53 LogRecord(LogRecord),
54 LogMessage(String),
55 Error(String),
56}
57
58#[derive(Debug, Clone, Default)]
59pub struct AssetPnlEntry {
60 pub is_futures: bool,
61 pub side: Option<OrderSide>,
62 pub position_qty: f64,
63 pub entry_price: f64,
64 pub realized_pnl_usdt: f64,
65 pub unrealized_pnl_usdt: f64,
66}
67
68#[derive(Debug, Clone, Copy, PartialEq, Eq)]
69pub enum LogLevel {
70 Debug,
71 Info,
72 Warn,
73 Error,
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
77pub enum LogDomain {
78 Ws,
79 Strategy,
80 Risk,
81 Order,
82 Portfolio,
83 Ui,
84 System,
85}
86
87#[derive(Debug, Clone)]
88pub struct LogRecord {
89 pub ts_ms: u64,
90 pub level: LogLevel,
91 pub domain: LogDomain,
92 pub event: &'static str,
93 pub symbol: Option<String>,
94 pub strategy_tag: Option<String>,
95 pub trace_id: Option<String>,
96 pub msg: String,
97}
98
99impl LogRecord {
100 pub fn new(level: LogLevel, domain: LogDomain, event: &'static str, msg: impl Into<String>) -> Self {
101 Self {
102 ts_ms: chrono::Utc::now().timestamp_millis() as u64,
103 level,
104 domain,
105 event,
106 symbol: None,
107 strategy_tag: None,
108 trace_id: None,
109 msg: msg.into(),
110 }
111 }
112}