"""시장 이벤트 플레이북 API 읽기 전용 엔드포인트: GET /api/playbook/today — 오늘 적용 중인 플레이북 GET /api/playbook/upcoming — 향후 N일 이벤트 목록 GET /api/playbook/realtime — 실시간 이벤트 상태 (서킷브레이커, VI) 쓰기 엔드포인트 (require_api_key): POST /api/playbook/circuit-breaker — 서킷브레이커 수동 발동 DELETE /api/playbook/circuit-breaker — 서킷브레이커 수동 해제 POST /api/playbook/vi/{stock_code} — VI 수동 발동 """ import logging from fastapi import APIRouter, Query from app.services.market_playbook import ( get_today_playbook, get_upcoming_events, check_realtime_events, trigger_circuit_breaker, clear_circuit_breaker, trigger_vi, get_realtime_state_summary, ) logger = logging.getLogger(__name__) router = APIRouter() @router.get("/today") async def get_today_playbook_endpoint(): """오늘 적용 중인 플레이북 행동 지침.""" playbook = get_today_playbook() return playbook.to_dict() @router.get("/upcoming") async def get_upcoming_events_endpoint(days: int = Query(default=7, ge=1, le=30)): """향후 N일 이내 예정된 시장 이벤트 목록.""" events = get_upcoming_events(days=days) return { "days": days, "count": len(events), "events": [ { "type": e.event_type.value, "date": e.event_date.isoformat(), "description": e.description, "phase": e.phase.value, "days_until": e.days_until, } for e in events ], } @router.get("/realtime") async def get_realtime_events_endpoint(): """실시간 이벤트 상태 (서킷브레이커, VI).""" alerts = check_realtime_events() state = get_realtime_state_summary() return { "alerts": [ { "type": a.event_type.value, "description": a.description, "severity": a.severity, } for a in alerts ], "state": state, } @router.post("/circuit-breaker") async def trigger_circuit_breaker_endpoint(description: str = "수동 서킷브레이커 발동"): """서킷브레이커 수동 발동 (긴급 매매 중단).""" trigger_circuit_breaker(description) logger.warning(f"[PlaybookAPI] 서킷브레이커 수동 발동: {description}") return {"status": "activated", "description": description} @router.delete("/circuit-breaker") async def clear_circuit_breaker_endpoint(): """서킷브레이커 수동 해제.""" clear_circuit_breaker() logger.info("[PlaybookAPI] 서킷브레이커 수동 해제") return {"status": "cleared"} @router.post("/vi/{stock_code}") async def trigger_vi_endpoint(stock_code: str, description: str = ""): """특정 종목 VI 수동 발동.""" trigger_vi(stock_code, description or f"수동 VI 발동: {stock_code}") return {"status": "triggered", "stock_code": stock_code}