- trades 테이블에 mode TEXT DEFAULT 'paper' 컬럼 추가
- 기존 DB 마이그레이션: ALTER TABLE으로 mode 컬럼 자동 추가
- log_trade() 함수에 mode 파라미터 추가 (기본값 'paper')
- trading_cycle(), run_daily_session()에서 settings.MODE 전달
- 테스트 5개 추가 (mode 저장, 기본값, 스키마 검증, 마이그레이션)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- #210: init_db()에 WAL 저널 모드 적용 (파일 DB에만, :memory: 제외)
- 대시보드(READ)와 거래루프(WRITE) 동시 접근 시 SQLite 락 오류 방지
- busy_timeout=5000ms 설정
- #213: RATE_LIMIT_RPS 기본값 2.0으로 통일 (.env.example이 5.0으로 잘못 표기됨)
- #216: .env.example 중요 변수 추가 및 정리
- KIS_BASE_URL 모의/실전 URL 주석 명시 (포트 29443 수정 포함)
- MODE, TRADE_MODE, ENABLED_MARKETS, PAPER_OVERSEAS_CASH 추가
- GEMINI_MODEL 업데이트 (gemini-pro → gemini-2.0-flash-exp)
- DASHBOARD 설정 섹션 추가
테스트 2개 추가 (WAL 파일 DB 적용, 메모리 DB 미적용 검증)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
대시보드 표시 전용 데이터를 AI 의사결정용 context tree에 저장하는 것은
관심사 분리 위반. system_metrics 경량 테이블을 신설하여 완전히 분리. (PR #197 코드리뷰 반영)
- db.py: system_metrics 테이블 추가 (key/value/updated_at)
- main.py: context_store.set_context(L6_DAILY) → db_conn.execute(system_metrics)
- app.py: contexts 쿼리 → system_metrics 쿼리
- tests: _seed_cb_context를 system_metrics 삽입으로 변경
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- /api/positions 엔드포인트 신설: 마지막 거래가 BUY인 종목을 오픈 포지션으로 반환
- _connect()에 WAL 모드 + busy_timeout=8000 추가 (트레이딩 루프와 동시 읽기 안전)
- init_db()에 idx_trades_stock_market_ts 인덱스 추가 (포지션 쿼리 최적화)
- index.html: 카드와 P&L 차트 사이에 포지션 패널 삽입 (종목/시장/수량/진입가/보유시간)
- 포지션 패널 테스트 3개 추가 (open BUY 반환, SELL 제외, 빈 DB 처리)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MARKET_SHORTHAND + expand_market_codes()로 config "US" → schedule "US_NASDAQ/NYSE/AMEX" 자동 확장
- /report, /scenarios, /review, /dashboard 텔레그램 명령 추가
- price_change_pct를 trading_cycle과 run_daily_session에 주입
- HOLD시 get_open_position 기반 손절 모니터링 및 자동 SELL 오버라이드
- 대시보드 /api/status 동적 market 조회로 변경
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add decision_id column to trades table, capture log_decision() return
value, and update original BUY decision outcome on SELL execution.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add playbooks table to src/db.py with UNIQUE(date, market) constraint
- PlaybookStore: save/load/delete, status management, match_count tracking,
list_recent with market filter, stats without full deserialization
- DayPlaybook JSON serialization via Pydantic model_dump_json/model_validate_json
- 23 tests, 100% coverage on playbook_store.py
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implement comprehensive multi-market trading system with automatic
market selection based on timezone and trading hours.
## New Features
- Market schedule module with 10 global markets (KR, US, JP, HK, CN, VN)
- Overseas broker for KIS API international stock trading
- Automatic market detection based on current time and timezone
- Next market open waiting logic when all markets closed
- ConnectionError retry with exponential backoff (max 3 attempts)
## Architecture Changes
- Market-aware trading cycle with domestic/overseas broker routing
- Market context in AI prompts for better decision making
- Database schema extended with market and exchange_code columns
- Config setting ENABLED_MARKETS for market selection
## Testing
- 19 new tests for market schedule (timezone, DST, lunch breaks)
- All 54 tests passing
- Lint fixes with ruff
## Files Added
- src/markets/schedule.py - Market schedule and timezone logic
- src/broker/overseas.py - KIS overseas stock API client
- tests/test_market_schedule.py - Market schedule test suite
## Files Modified
- src/main.py - Multi-market main loop with retry logic
- src/config.py - ENABLED_MARKETS setting
- src/db.py - market/exchange_code columns with migration
- src/brain/gemini_client.py - Dynamic market context in prompts
Resolves#5
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Migrate from deprecated google-generativeai to google-genai (>=1.0) using the
new Client-based API, and fix SQLite "unable to open database file" in Docker
by chowning the data directory to appuser before switching users.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>