Files
kis_trader/tmp_mom_smoke_web.py
Hwang 61c72a8a4c feat(tests): 신규 키움 웹소켓 조건검색 및 실시간 조건검색 테스트 추가
변경 사항
----
- _test_kiwoom_condition_list.py: 키움 웹소켓 조건검색 '목록조회' 기능을 단독으로 테스트하는 스크립트 추가
- _test_kiwoom_condition_realtime.py: 'momentum' 조건식을 실시간으로 등록하고 초기 매칭 종목 리스트 및 실시간 편입/이탈을 수신하는 테스트 스크립트 추가
- _verify_columnar_bitid.py, _verify_shared_e2e_breakout.py, _verify_shared_e2e.py: 공유 메모리 및 dict 간의 데이터 일관성을 검증하는 테스트 추가

영향
----
- 신규 테스트 스크립트 추가로 키움 웹소켓 API의 기능 검증 및 안정성을 높임
- 기존 기능에 대한 영향 없음

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 01:27:00 +09:00

47 lines
1.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""웹 /api/backtest/momentum 스모크 — Flask test_client (서버 불필요)."""
import json
import sys
sys.path.insert(0, "/home/hoon/kis_bot")
from backtest_web import app # noqa: E402
QS = {
"start": "2026-06-01",
"end": "2026-06-14",
"universe": "sim",
"pattern_breakout": "1",
"pattern_pullback": "1",
"chase_lookback_min": "10",
"pullback_lookback_min": "15",
"pullback_min_pct": "0.3",
"pullback_max_pct": "3.0",
"use_ema_filter": "1",
"use_rsi_max_filter": "0",
"use_high_chase_filter": "0",
"use_daily_range_filter": "0",
"mom_max_from_open_pct": "999",
"mom_min_from_open_pct": "-999",
}
with app.test_client() as c:
r = c.get("/api/backtest/momentum", query_string=QS)
print("HTTP", r.status_code)
d = r.get_json(silent=True) or {}
if d.get("error"):
print("ERROR:", d["error"])
sys.exit(1)
s = d.get("summary") or {}
p = d.get("params") or {}
print("--- V2 스모크 (6/1~14, universe=sim) ---")
print(f"패턴: 돌파={p.get('pattern_breakout')} 눌림={p.get('pattern_pullback')} chase={p.get('chase_lookback_min')}")
print(f"RSI≥{p.get('mom_rsi_min')} vol×{p.get('mom_vol_mult')} EMA={p.get('use_ema_filter')} ({p.get('ema_fast_period')}/{p.get('ema_slow_period')})")
print(f"거래: {s.get('total_trades')}건 | 승률 {s.get('win_rate')}% | PF {s.get('profit_factor')}")
print(f"총손익: {s.get('total_pnl'):+,}원 | MDD {s.get('max_drawdown'):,}원 | 평균보유 {s.get('avg_hold_min')}")
print(f"종목수: {p.get('codes_analyzed')} | 슬롯 {p.get('max_stocks')} × {p.get('slot_money'):,.0f}")
reasons = d.get("reasons") or {}
if reasons:
top = sorted(reasons.items(), key=lambda x: -x[1])[:8]
print("청산사유:", ", ".join(f"{k}={v}" for k, v in top))