""" 05 규칙 알림 텔레그램 메시지 포맷. """ from __future__ import annotations from typing import Any from config import COIN_NAME, MONITOR_ALERT_KRW_AMOUNT, SYMBOL def _fmt_krw(value: float) -> str: """원화 금액 표시.""" if value >= 100: return f"₩{value:,.0f}" if value >= 1: return f"₩{value:,.2f}" return f"₩{value:,.4f}" def _fmt_price(value: float) -> str: """코인 단가 표시.""" if value >= 100: return f"₩{value:,.0f}" if value >= 10: return f"₩{value:,.2f}" if value >= 1: return f"₩{value:,.3f}" return f"₩{value:,.4f}" def _holding_qty(balances: dict[str, dict[str, float]], symbol: str) -> float: """ 잔고 dict에서 코인 보유 수량을 반환합니다. Args: balances: load_balances_dict() 결과. symbol: 통화 코드 (예: WLD). Returns: 보유 수량 (없으면 0). """ info = balances.get(symbol) or {} return float(info.get("balance") or 0.0) def build_rule_alert_message( hit: dict[str, Any], balances: dict[str, dict[str, float]] | None = None, *, trade_krw: float | None = None, trade_qty: float | None = None, ) -> str: """ 규칙 발화 알림 본문을 만듭니다. trade_krw·trade_qty가 있으면 실제(모의) 체결 규모를 표시합니다. 없으면 매수는 MONITOR_ALERT_KRW_AMOUNT, 매도는 보유×가격(또는 참고 금액). Args: hit: evaluate_live_rules 항목 (side, rule_id, dt, close). balances: 잔고 dict (모의·실거래). trade_krw: 체결 원화(모의·실거래 planned/executed). trade_qty: 체결 수량(매도 시). Returns: 텔레그램 메시지 문자열. """ side = str(hit.get("side", "")).upper() close = float(hit["close"]) rule_id = hit.get("rule_id", "") dt = hit.get("dt", "") qty_basis = "" if trade_krw is not None and trade_krw > 0: amount = float(trade_krw) if trade_qty is not None and trade_qty > 0: qty = float(trade_qty) qty_basis = "체결 기준" elif close > 0: qty = amount / close qty_basis = "체결 기준(원화→수량)" else: qty = 0.0 qty_basis = "체결 기준" elif side == "SELL" and balances is not None: qty = _holding_qty(balances, SYMBOL) amount = qty * close qty_basis = "보유 기준(체결 전)" elif side == "BUY": amount = float(MONITOR_ALERT_KRW_AMOUNT) qty = amount / close if close > 0 else 0.0 qty_basis = "참고 매수 규모(알림용)" else: amount = float(MONITOR_ALERT_KRW_AMOUNT) qty = amount / close if close > 0 else 0.0 qty_basis = "참고 규모(잔고 미조회)" lines = [ f"[DeepCoin {side}] {COIN_NAME}", f"규칙: {rule_id}", f"시각: {dt}", f"가격: {_fmt_price(close)}", f"수량: {qty:,.4f} {SYMBOL} ({qty_basis})", f"금액: {_fmt_krw(amount)}", "※ 알림만 전송, 자동 주문 없음", ] return "\n".join(lines)