feat: Telegram notifications + SSE position stream + PnL summary

- Add telegram.rs: send/edit messages via Bot API
- Add SSE position listener: position_opened → edit "Filled",
  position_closed → edit TP/SL result + send daily+alltime PnL summary
- Extend State with tg_message_id and trade details for notifications
- Add PosState to persist position info across SSE events
- Add Deal domain type and history_deals() client method
- New env: TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID, TELEGRAM_THREAD_ID

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
romysaputrasihananda
2026-06-11 01:28:45 +07:00
co-authored by Claude Sonnet 4.6
parent 0583b6d0fb
commit a49aee6ae0
10 changed files with 575 additions and 110 deletions
+17
View File
@@ -122,6 +122,23 @@ impl Mt5Client {
Ok(w.data)
}
pub async fn history_deals(
&self,
date_from: &str,
date_to: &str,
symbol: Option<&str>,
) -> Result<Vec<domain::Deal>, Mt5Error> {
let url = format!("{}/history/deals", self.base_url);
let mut req = self.http.get(&url)
.query(&[("date_from", date_from), ("date_to", date_to)]);
if let Some(sym) = symbol {
req = req.query(&[("symbol", sym)]);
}
let text = self.fetch_text(req).await?;
let w: DataVec<domain::Deal> = serde_json::from_str(&text)?;
Ok(w.data)
}
pub async fn place_order(
&self,
request: &TradeRequest,
+1
View File
@@ -4,4 +4,5 @@ mod types;
pub use client::Mt5Client;
pub use error::Mt5Error;
pub use domain::Deal;
pub use types::{HealthStatus, OrderCheckResult, PendingOrder, TradeRequest, TradeResult};