feat(agent-office): 보유종목 브리핑 텔레그램 포매터
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
82
agent-office/tests/test_holdings_brief_format.py
Normal file
82
agent-office/tests/test_holdings_brief_format.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import sys, os
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
|
||||
|
||||
from app.notifiers import telegram_stock as ts
|
||||
|
||||
|
||||
def test_format_holdings_brief():
|
||||
payload = {
|
||||
"date": "2026-05-29",
|
||||
"holdings": [
|
||||
{"ticker": "005930", "name": "삼성전자", "action": "trim", "tech_score": 60.0,
|
||||
"exit_flags": {"ma50_break": True}, "issues": [{"type":"news","severity":"high","summary":"악재"}],
|
||||
"pnl_rate": 5.2, "reasons": "MA50 이탈"},
|
||||
{"ticker": "000660", "name": "SK하이닉스", "action": "hold", "tech_score": 75.0,
|
||||
"exit_flags": {}, "issues": [], "pnl_rate": -2.0, "reasons": "특이 신호 없음"},
|
||||
],
|
||||
"portfolio_health": {"positions": 2, "total_pnl_rate": 3.1, "max_weight": 0.6, "cash_ratio": 0.2},
|
||||
}
|
||||
txt = ts.format_holdings_brief(payload)
|
||||
assert "삼성전자" in txt
|
||||
assert "축소" in txt or "trim" in txt
|
||||
assert "%" in txt
|
||||
|
||||
|
||||
def test_format_holdings_brief_empty_holdings():
|
||||
"""빈 holdings + None portfolio_health에도 크래시 없음."""
|
||||
payload = {"date": "2026-05-29", "holdings": [], "portfolio_health": None}
|
||||
txt = ts.format_holdings_brief(payload)
|
||||
assert "보유종목 인텔리전스" in txt
|
||||
assert "자동매매" in txt
|
||||
|
||||
|
||||
def test_format_holdings_brief_missing_fields():
|
||||
"""pnl_rate None·name None·issues None 방어적 처리."""
|
||||
payload = {
|
||||
"date": None,
|
||||
"holdings": [
|
||||
{"ticker": "005930", "name": None, "action": "sell",
|
||||
"pnl_rate": None, "reasons": None, "issues": None},
|
||||
],
|
||||
"portfolio_health": {},
|
||||
}
|
||||
txt = ts.format_holdings_brief(payload)
|
||||
assert "005930" in txt # ticker fallback
|
||||
assert "🔴 매도" in txt
|
||||
|
||||
|
||||
def test_format_holdings_brief_sell_action():
|
||||
"""sell 액션은 🔴 매도로 표시."""
|
||||
payload = {
|
||||
"date": "2026-05-29",
|
||||
"holdings": [
|
||||
{"ticker": "000660", "name": "SK하이닉스", "action": "sell",
|
||||
"pnl_rate": -12.5, "reasons": "손절선 이탈", "issues": []},
|
||||
],
|
||||
"portfolio_health": {"positions": 1, "total_pnl_rate": -12.5,
|
||||
"max_weight": 1.0, "cash_ratio": 0.0},
|
||||
}
|
||||
txt = ts.format_holdings_brief(payload)
|
||||
assert "🔴 매도" in txt
|
||||
assert "-12.5%" in txt
|
||||
|
||||
|
||||
def test_format_holdings_brief_issue_severity_icons():
|
||||
"""이슈 심각도별 이모지 매핑 확인."""
|
||||
payload = {
|
||||
"date": "2026-05-29",
|
||||
"holdings": [
|
||||
{"ticker": "005930", "name": "삼성전자", "action": "hold", "pnl_rate": 2.0,
|
||||
"reasons": "특이 신호 없음",
|
||||
"issues": [
|
||||
{"type": "news", "severity": "high", "summary": "심각 악재"},
|
||||
{"type": "volume_surge", "severity": "med", "summary": "거래량 급증"},
|
||||
{"type": "price_move", "severity": "low", "summary": "소폭 변동"},
|
||||
]},
|
||||
],
|
||||
"portfolio_health": {},
|
||||
}
|
||||
txt = ts.format_holdings_brief(payload)
|
||||
assert "🔴" in txt # high severity
|
||||
assert "🟠" in txt # med severity
|
||||
assert "🟡" in txt # low severity
|
||||
Reference in New Issue
Block a user