"""Telegram notifications — fire-and-forget, never blocks trade execution.""" import logging import os import httpx log = logging.getLogger(__name__) _TOKEN = os.getenv("TELEGRAM_BOT_TOKEN", "") _CHAT_ID = os.getenv("TELEGRAM_CHAT_ID", "") async def _send(text: str) -> None: """POST a message to Telegram. Swallows all errors silently.""" if not _TOKEN or not _CHAT_ID: return try: async with httpx.AsyncClient(timeout=10) as client: resp = await client.post( f"https://api.telegram.org/bot{_TOKEN}/sendMessage", json={"chat_id": _CHAT_ID, "text": text}, ) if resp.status_code != 200: log.warning("Telegram %d: %s", resp.status_code, resp.text[:200]) except Exception as exc: log.warning("Telegram notification failed: %s", exc) async def trade_opened(question: str, direction: str, size_usdc: float, edge_net: float) -> None: emoji = "📈" if direction == "BUY_YES" else "📉" await _send( f"{emoji} TRADE ABIERTO\n" f"{question[:80]}\n" f"Dir: {direction} Size: ${size_usdc:.2f} Edge: {edge_net:+.3f}" ) async def trade_closed(question: str, pnl: float) -> None: emoji = "✅" if pnl > 0 else "❌" result = "GANADO" if pnl > 0 else "PERDIDO" await _send( f"{emoji} {result}\n" f"{question[:80]}\n" f"PnL: {pnl:+.2f} USDC" ) async def trade_legacy_closed(question: str, recovered: float, reason: str) -> None: await _send( f"🔒 LEGACY CLOSE\n" f"{question[:80]}\n" f"Recuperado: ${recovered:.2f} | {reason[:60]}" )