Commit Graph

15 Commits

Author SHA1 Message Date
28f9c8c3a6 feat(signal_v2-phase3b): chronos_predictor + 4 mock tests
ChronosPredictor wraps HuggingFace ChronosPipeline. Batch predict
returns ChronosPrediction(median, q10, q90, conf, as_of) per ticker.
Confidence = 1 - clamp(spread/2, 0, 1) where spread = (q90-q10) / |median|.
Lazy import of chronos lib (heavy). GPU auto-detect with FP16.

44 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 18:00:46 +09:00
c5a88fab66 feat(signal_v2-phase3b): momentum_classifier + 6 unit tests
aggregate_1min_to_5min: 1분봉 5개 → 5분봉 1개 (open=첫, close=마지막,
high=max, low=min, volume=sum). classify_minute_momentum: 직전 5개
5분봉 양봉 개수 + 거래량 60분 multiplier → 5-level
(strong_up/weak_up/neutral/weak_down/strong_down).

40 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 17:55:34 +09:00
7056cf2fa6 feat(signal_v2-phase3b): kis_client.get_daily_ohlcv (60 daily bars)
TR_ID FHKST03010100 (수정주가 일봉). KIS returns descending; client
reverses to ascending and trims to last N days.

1 new test, 34 total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 17:49:06 +09:00
b690900cfc fix(signal_v2-phase3a): V1 KIS env pattern + test isolation fix
config.py: kis_env_type (virtual/real) + KIS_REAL_*/KIS_VIRTUAL_* env
variables (V1 호환). kis_app_key/kis_app_secret/kis_account properties
auto-select based on env type.

main.py: KIS not-configured warning uses descriptive message including
env type + expected var name.

test_main.py: monkeypatch load_dotenv to no-op + setenv empty string
(instead of delenv) — defeats .env re-read on importlib.reload.
Pre-existing test_startup_warns_if_webai_api_key_missing also fixed.

33/33 tests pass (was 31/33).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 10:25:58 +09:00
d85512d036 feat(signal_v2-phase3a): main.py lifespan integrates KIS client + WS
AppContext extended with kis_client + kis_ws. lifespan:
- If KIS_APP_KEY set: create KISClient + KISWebSocket, fetch portfolio,
  subscribe WebSocket H0STASP0 for holdings.
- If unset: WARNING log, signal_v2 still serves /health (no KIS data).
- Shutdown closes kis_ws → kis_client → stock client in order.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 05:21:55 +09:00
3ebe95ba29 feat(signal_v2-phase3a): pull_worker KIS minute cycle + WS callback
_run_kis_minute_cycle: portfolio + screener union 종목 분봉 fetch +
screener-only 종목 호가 REST fetch. WebSocket callback factory
(make_asking_price_callback).

poll_loop / _run_polling_cycle 에 kis_client optional param 추가
(Phase 5 까지 None 일 때도 정상 동작).

2 new tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 05:19:24 +09:00
163c9fb690 feat(signal_v2-phase3a): kis_websocket + 4 integration tests
KISWebSocket: approval_key (POST /oauth2/Approval) + H0STASP0 호가
실시간 subscribe + receive loop + exponential reconnect (1s → 2s → 4s
→ max 30s). _parse_asking_price 필드 인덱스 운영 검증 필요
(현재 가정: 마지막 2 필드가 ask_total/bid_total).

4 tests pass, 29 total.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 05:16:20 +09:00
27bf360b01 feat(signal_v2-phase3a): kis_client REST + 4 integration tests
KISClient: 분봉 (FHKST03010200) + 호가 (FHKST01010200) async REST.
V1 토큰 파일 (signal_v1/data/kis_token.json) read-only 공유, mtime
캐시. 초당 2회 throttle. exponential retry (max 3, 1s/2s/4s).

4 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 05:12:45 +09:00
eafa73edb1 feat(signal_v2-phase3a): scheduler NXT windows (20:00-23:30 / 04:30-07:00)
NXT 시간외 거래 시간대도 5분 cron 폴링 활성화. 23:30-04:30 dead zone
(KIS 점검) → 04:30 까지 skip. 기존 _seconds_until_next_market_open
(휴장일/주말용) 와 별개로 _seconds_until_nxt_or_market_open 신설.

3 new tests, scheduler suite 11 passed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 05:09:27 +09:00
94c684bab8 feat(signal_v2): pull_worker + FastAPI app + 2 integration tests
poll_loop: asyncio.gather parallel fetch of 3 endpoints (portfolio,
news_sentiment, screener_preview) + state update. main.py: FastAPI
lifespan creates StockClient/SignalDedup/shutdown.Event then spawns
poll_loop as background task. GET /health reports status, last poll
times, cache size.

Signal V2 test suite: 19/19 PASS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 03:49:50 +09:00
1a6d9fcb39 feat(signal_v2): rate_limit + 3 unit tests
SignalDedup: 24h-rolling duplicate signal blocker. SQLite WAL +
busy_timeout=120000 standard fix (reference_sqlite_concurrency.md
pattern). PK (ticker, action) with UPSERT. Phase 4 (signal generator)
will call is_recent() before sending + record() after sending.

3 unit tests pass, total 17 signal_v2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 03:46:59 +09:00
6cb5085118 test(signal_v2): add scheduler boundary tests at exact transitions
Code review noted missing boundary tests at:
- 09:00:00 (pre-market → market) → 60
- 15:30:00 (market → post-market) → 300
- 20:00:00 (post-market → overnight skip)

3 new tests, total 8 scheduler / 14 signal_v2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 03:45:55 +09:00
fdabc69004 feat(signal_v2): scheduler + 5 unit tests
Time-window dispatcher: pre-market (07:00-09:00, 5min), market
(09:00-15:30, 1min), post-market (15:30-20:00, 5min), overnight skip
to next market day 07:00. Weekend + holiday detection via holidays.json.

Stub holidays.json with 13 dates. Task 6 will sync from
web-backend/stock/app/holidays.json.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 03:44:24 +09:00
8469bf7ffa feat(signal_v2): stock_client + 6 integration tests
httpx async client with custom retry loop (max 3, exponential 1s/2s/4s),
memory dict cache (portfolio 60s / news-sentiment 300s / screener 60s),
X-WebAI-Key auth header injection. Stale fallback returns last
successful response with logger.warning on persistent failures.

6 integration tests pass with respx httpx mock.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 03:40:12 +09:00
8a2fac03a6 feat(signal_v2): foundation — config + state + requirements
- signal_v2/config.py: Settings dataclass loading web-ai/.env explicitly
- signal_v2/state.py: PollState dataclass + module-level singleton
- requirements.txt: httpx / fastapi / uvicorn / pytest-asyncio / respx
- .gitignore: signal_v2/data/*.db (WAL/SHM)
- empty tests/ marker

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 03:35:36 +09:00