"""ai_news Top 5/5 텔레그램 메시지 빌더 (MarkdownV2).""" from __future__ import annotations from typing import Any, Dict, List _MD_SPECIAL = r"_*[]()~`>#+-=|{}.!\\" def _escape(text: str) -> str: return "".join("\\" + c if c in _MD_SPECIAL else c for c in str(text)) def _cost_won(tokens_input: int, tokens_output: int) -> int: """Claude Haiku 가격 환산 (대략): in $1/M × ₩1300, out $5/M × ₩1300.""" return int(tokens_input * 0.0013 + tokens_output * 0.0065) def _row_line(idx: int, r: Dict[str, Any]) -> str: score = r["score_raw"] sign = "+" if score >= 0 else "" return ( f"{idx}\\. {_escape(r['ticker'])} \\({sign}{score:.1f}\\) — " f"{_escape(r['reason'])}" ) def build_message( *, asof: str, top_pos: List[Dict[str, Any]], top_neg: List[Dict[str, Any]], tokens_input: int, tokens_output: int, ) -> str: lines: List[str] = [ f"🌅 *AI 뉴스 분석* \\({_escape(asof)} 08:00\\)", "", "📈 *호재 Top 5*", ] if top_pos: for i, r in enumerate(top_pos, 1): lines.append(_row_line(i, r)) else: lines.append(_escape("- (없음)")) lines += ["", "📉 *악재 Top 5*"] if top_neg: for i, r in enumerate(top_neg, 1): lines.append(_row_line(i, r)) else: lines.append(_escape("- (없음)")) cost = _cost_won(tokens_input, tokens_output) lines += [ "", f"_분석: 시총 상위 100종목 · 토큰 {tokens_input:,} in / {tokens_output:,} out · " f"약 ₩{cost:,}_", ] return "\n".join(lines)