112 lines
3.3 KiB
Markdown
112 lines
3.3 KiB
Markdown
# 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`
|
|
|
|
## Market Scope
|
|
|
|
V2 기본 설정은 `ENABLED_MARKETS="KR,US"` 입니다.
|
|
|
|
현재 코드 기준 주의점:
|
|
|
|
- 설정은 `KR,US`를 기본값으로 사용
|
|
- 스케줄 레이어(`src/markets/schedule.py`)는 `US_NASDAQ`, `US_NYSE` 구조를 아직 유지
|
|
- 완전한 `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()` 실행
|
|
|
|
## 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` 정규화 계층 명시 미흡
|
|
- HOLD 시 별도 손절 모니터링 플래그 처리 미완
|
|
- US 스캐닝 확장(`fetch_overseas_rankings`) 미구현
|