"""
Message formatters for Telegram alerts.
"""
def format_balance(available: float, equity: float) -> str:
"""Format wallet balance message."""
return (
f"💰 Bybit Balance\n"
f"━━━━━━━━━━━━━━━━━━━━\n"
f"Available: ${available:.2f}\n"
f"Equity: ${equity:.2f}\n"
f"━━━━━━━━━━━━━━━━━━━━"
)
def format_entry(symbol: str, side: str, entry: float, qty: float,
leverage: int, tp_prices: list[float], sl_price: float,
strategy: str, extra: str = "") -> str:
"""Format trade entry notification."""
direction = "LONG" if side == "BUY" else "SHORT"
notional = qty * entry
lines = [
f"{'🟢' if side == 'BUY' else '🔴'} {strategy} {direction} {symbol}",
f"━━━━━━━━━━━━━━━━━━━━",
f"💰 Entry: ${entry:.6f}",
f"📊 Size: {qty} ({leverage}x, ${notional:.2f})",
]
for i, tp in enumerate(tp_prices, 1):
tp_pct = abs(tp - entry) / entry * 100
lines.append(f"🎯 TP{i}: ${tp:.6f} (+{tp_pct:.1f}%)")
sl_pct = abs(sl_price - entry) / entry * 100
lines.append(f"🛑 SL: ${sl_price:.6f} (-{sl_pct:.1f}%)")
if extra:
lines.append(extra)
lines.append("━━━━━━━━━━━━━━━━━━━━")
return "\n".join(lines)
def format_close(symbol: str, reason: str, entry_price: float,
exit_price: float, pnl_pct: float, pnl_usdt: float,
age_min: float, strategy: str, wins: int = 0,
losses: int = 0, total_pnl: float = 0) -> str:
"""Format trade close notification."""
emoji_map = {"TP": "🎯", "SL": "🛑", "TIME_STOP": "⏱", "MANUAL": "👋", "BE": "🔒"}
emoji = emoji_map.get(reason, "📌")
total = wins + losses
wr = (wins / total * 100) if total > 0 else 0
lines = [
f"{emoji} {strategy} {reason}: {symbol}",
f"━━━━━━━━━━━━━━━━━━━━",
f"Entry: ${entry_price:.6f}",
f"Exit: ${exit_price:.6f} ({pnl_pct:+.2f}%)",
f"💵 PnL: ${pnl_usdt:+.4f}",
f"⏱ {age_min:.0f}min",
f"📊 WR: {wr:.0f}% ({wins}W/{losses}L)",
f"💰 Total: ${total_pnl:+.2f}",
f"━━━━━━━━━━━━━━━━━━━━",
]
return "\n".join(lines)