# System Architecture ## Overview The Ouroboros V2는 `Proactive` 구조를 중심으로 동작합니다. - 장전: Gemini 1회 호출로 시장별 `DayPlaybook` 생성 - 장중: `ScenarioEngine`이 로컬 조건 매칭으로 의사결정 - 장후: `ContextAggregator` + `DailyReviewer`로 성과 집계/교훈 생성 `main.py`가 아래 컴포넌트를 오케스트레이션합니다. - `KISBroker` / `OverseasBroker` - `PreMarketPlanner` / `ScenarioEngine` / `PlaybookStore` - `ContextStore` / `ContextAggregator` / `ContextScheduler` - `DailyReviewer` / `EvolutionOptimizer` - `TelegramClient` / `TelegramCommandHandler` 안전/운영 컴포넌트도 핵심입니다. - `RiskManager`: circuit breaker, fat-finger 검증 - `PriorityTaskQueue` + `CriticalityAssessor`: 우선순위/지연 제어 ## Market Scope V2 기본 설정은 `ENABLED_MARKETS="KR,US"` 입니다. 현재 코드 기준 주의점(런타임 영향): - 설정은 `KR,US`를 기본값으로 사용 - 스케줄 레이어(`src/markets/schedule.py`)는 `US_NASDAQ`, `US_NYSE` 구조를 아직 유지 - `US` 코드가 스케줄에 직접 정의되지 않아 US 시장 누락 가능성이 있음 ## Decision Flow ### 1) Pre-market 1. `SmartVolatilityScanner.scan()`으로 후보 종목 수집 2. `PreMarketPlanner.generate_playbook(market, candidates)` 호출 3. 결과를 `PlaybookStore.save()`로 DB 저장 4. 실패 시 empty/defensive playbook 사용 ### 2) In-market 1. 시장 데이터 + 스캐너 메트릭(`rsi`, `volume_ratio`) 구성 2. `ScenarioEngine.evaluate(playbook, stock_code, market_data, portfolio_data)` 3. `TradeDecision` 변환 후 주문/로그/알림 처리 4. `decision_logs`와 `trades`를 `decision_id`로 연결 ### 3) End-of-day 1. `ContextAggregator.aggregate_daily_from_trades(date, market)` 2. `DailyReviewer.generate_scorecard(date, market)` 3. `store_scorecard_in_context()`로 `scorecard_{market}` 저장 4. `generate_lessons()`로 장후 교훈 생성 5. (US 종료 시) `EvolutionOptimizer.evolve()` 실행 ## Risk Policy - `RiskManager`는 주문 전 검증을 강제합니다. - circuit breaker: 손실 임계치 하회 시 거래 중단 - fat-finger: 주문 금액 과대 시 주문 차단 - 실패 시 알림은 보내되, 예외 처리로 루프 안정성 유지 ## Error Handling Strategy - API 호출 실패: 재시도(지수 백오프) 후 종목/사이클 스킵 - 시나리오/플래너 실패: empty 또는 defensive playbook으로 안전 폴백 - Telegram 실패: warning 로깅 후 거래 루프 지속 - 대시보드 스레드 실패: warning 로깅 후 메인 트레이딩 루프와 분리 유지 ## Configuration Reference 상세 설정은 `src/config.py`를 기준으로 합니다. - 거래 모드: `TRADE_MODE`, `DAILY_SESSIONS`, `SESSION_INTERVAL_HOURS` - 전략: `PRE_MARKET_MINUTES`, `MAX_SCENARIOS_PER_STOCK`, `RESCAN_INTERVAL_SECONDS` - 시장: `ENABLED_MARKETS` - 대시보드: `DASHBOARD_ENABLED`, `DASHBOARD_HOST`, `DASHBOARD_PORT` - 알림: `TELEGRAM_*` ## Context Tree 레이어 전략: - `L7~L5`: 시장별 키 - `L4~L1`: 글로벌 통합 롤업 구현 포인트: - `L7` 쓰기: `volatility_{market}_{stock}` 등 - `L6` 집계: `total_pnl_KR`, `trade_count_US` 등 - `ContextScheduler.run_if_due()`: - 주간/월간/분기/연간/legacy 집계 - 일 1회 `cleanup_expired_contexts()` 호출 ## Data Model (핵심) ### `trades` - `market`, `exchange_code`, `selection_context`, `decision_id` 포함 - SELL 시 `get_latest_buy_trade()`를 통해 원본 BUY `decision_id`를 찾아 결과 업데이트 ### `decision_logs` - 의사결정 입력/컨텍스트 스냅샷 저장 - `outcome_pnl`, `outcome_accuracy` 업데이트 가능 ### `playbooks` - `UNIQUE(date, market)` - `status`, `token_count`, `scenario_count`, `match_count` 관리 ## Dashboard `src/dashboard/app.py`의 FastAPI 앱이 SQLite를 직접 조회합니다. 엔드포인트: - `GET /api/status` - `GET /api/playbook/{date}?market=KR` - `GET /api/scorecard/{date}?market=KR` - `GET /api/performance?market=all` - `GET /api/context/{layer}` - `GET /api/decisions?market=KR` - `GET /api/scenarios/active?market=US` 실행 통합: - CLI `--dashboard` - 또는 `DASHBOARD_ENABLED=true` - `main.py`에서 daemon thread로 uvicorn 실행 ## Known Gaps (2026-02-16) - `Issue 4-1` Telegram 확장 명령 미구현 (`/report`, `/scenarios`, `/review`, `/dashboard`) - `Issue 1-7` 일부 미완: - `price_change_pct` 정규화 계층 명시 미흡 - 영향: `price_change_pct` 기반 조건은 현재 사실상 매칭되지 않음 - HOLD 시 별도 손절 모니터링 플래그 처리 미완 - US 스캐닝 확장(`fetch_overseas_rankings`) 미구현