feat(agent-office): stock screener 평일 16:30 KST 자동 잡 + 텔레그램 전송

- StockAgent.on_screener_schedule: snapshot/refresh → screener/run(mode=auto)
  → telegram_payload(MarkdownV2) 발송. skipped_holiday는 무발신,
  실패 시 운영자 HTML 알림.
- service_proxy: refresh_screener_snapshot, run_stock_screener 추가
  (각각 180s timeout, STOCK_LAB_URL 기존 env 재사용).
- telegram.messaging.send_raw: parse_mode 파라미터 추가
  (기본 HTML 유지, MarkdownV2 페이로드 직접 전달용).
- scheduler: cron day_of_week=mon-fri hour=16 minute=30 id=stock_screener
  (Asia/Seoul TZ).
- on_command 'run_screener' 수동 트리거 추가.
- tests: 성공/휴일/스냅샷실패/run실패/이상status 5케이스.
This commit is contained in:
2026-05-12 14:54:24 +09:00
parent c4cb18a25c
commit 119ac88e1e
5 changed files with 347 additions and 3 deletions

View File

@@ -32,6 +32,34 @@ async def summarize_stock_news(limit: int = 15) -> Dict[str, Any]:
return resp.json()
async def refresh_screener_snapshot() -> Dict[str, Any]:
"""stock-lab의 KRX 일봉 스냅샷 갱신 (스크리너 실행 전 호출).
네이버 금융 일괄 다운로드라 보통 30~120s, 여유있게 180s.
"""
async with httpx.AsyncClient(timeout=180.0) as client:
resp = await client.post(f"{STOCK_LAB_URL}/api/stock/screener/snapshot/refresh")
resp.raise_for_status()
return resp.json()
async def run_stock_screener(mode: str = "auto") -> Dict[str, Any]:
"""stock-lab의 스크리너 실행.
반환 status:
- 'skipped_holiday': 공휴일/주말 — telegram_payload 없음
- 'success': telegram_payload 동봉
엔진 자체는 수 초 내 끝나지만, 컨텍스트 로드+200종목 처리 여유 180s.
"""
async with httpx.AsyncClient(timeout=180.0) as client:
resp = await client.post(
f"{STOCK_LAB_URL}/api/stock/screener/run",
json={"mode": mode},
)
resp.raise_for_status()
return resp.json()
async def scrape_stock_news() -> Dict[str, Any]:
"""stock-lab의 수동 뉴스 스크랩 트리거 — DB에 최신 뉴스 저장.