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>
This commit is contained in:
105
kis_trader/scripts/migrate_split_env_config.py
Normal file
105
kis_trader/scripts/migrate_split_env_config.py
Normal file
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
env_config → env_config(공통) + config_{전략} 분리 마이그레이션.
|
||||
|
||||
1) config_scalp / config_short / config_momentum / config_breakout / config_updow 테이블 생성·컬럼 보강
|
||||
2) 기존 env_config 최신 행 + env_config_ext 값을 테이블별로 INSERT
|
||||
3) 공통 키만 env_config 에 새 스냅샷 INSERT
|
||||
|
||||
실행:
|
||||
cd ~/kis_bot && python3 -m kis_trader.scripts.migrate_split_env_config
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
_ROOT = Path(__file__).resolve().parents[2]
|
||||
if str(_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(_ROOT))
|
||||
|
||||
from config_schema import CONFIG_TABLE_NAMES, classify_config_key # noqa: E402
|
||||
from database import ( # noqa: E402
|
||||
CONFIG_TABLE_KEYS,
|
||||
ENV_CONFIG_KEYS,
|
||||
TradeDB,
|
||||
)
|
||||
|
||||
|
||||
def _load_legacy_flat(db: TradeDB) -> dict:
|
||||
"""기존 fat env_config 1행 + env_config_ext."""
|
||||
flat = {}
|
||||
try:
|
||||
row = db.conn.execute(
|
||||
"SELECT * FROM env_config ORDER BY id DESC LIMIT 1"
|
||||
).fetchone()
|
||||
if row:
|
||||
rk = row.keys() if hasattr(row, "keys") else []
|
||||
for k in ENV_CONFIG_KEYS:
|
||||
if k in rk and row[k] is not None and str(row[k]).strip() != "":
|
||||
flat[k] = str(row[k])
|
||||
except Exception as e:
|
||||
print(f"legacy env_config 읽기 실패: {e}")
|
||||
try:
|
||||
ext = db.conn.execute(
|
||||
"SELECT env_key, env_value FROM env_config_ext"
|
||||
).fetchall()
|
||||
for er in ext or []:
|
||||
ek = er["env_key"] if isinstance(er, dict) else er[0]
|
||||
ev = er["env_value"] if isinstance(er, dict) else er[1]
|
||||
if ek:
|
||||
flat[str(ek)] = "" if ev is None else str(ev)
|
||||
except Exception:
|
||||
pass
|
||||
return flat
|
||||
|
||||
|
||||
def main() -> int:
|
||||
db = TradeDB()
|
||||
db._migrate_config_table_columns()
|
||||
|
||||
flat = _load_legacy_flat(db)
|
||||
if not flat:
|
||||
merged = db.get_merged_env_snapshot()
|
||||
if merged:
|
||||
flat = dict(merged)
|
||||
if not flat:
|
||||
print("❌ 마이그레이션할 env 데이터 없음")
|
||||
db.close()
|
||||
return 1
|
||||
|
||||
print(f"소스 키 {len(flat)}개 → 테이블별 INSERT")
|
||||
eid = db.insert_env_snapshot(flat)
|
||||
if not eid:
|
||||
print("❌ insert_env_snapshot 실패")
|
||||
db.close()
|
||||
return 1
|
||||
|
||||
snap = db.get_merged_env_snapshot()
|
||||
print(f"\n✅ 완료 env_config id={eid}")
|
||||
print(f"병합 snapshot 키 수: {len(snap)}")
|
||||
for tbl in CONFIG_TABLE_NAMES:
|
||||
n = len(CONFIG_TABLE_KEYS.get(tbl, ()))
|
||||
filled = sum(1 for k in CONFIG_TABLE_KEYS.get(tbl, ()) if snap.get(k))
|
||||
print(f" {tbl}: 컬럼 {n} / 값 있음 {filled}")
|
||||
|
||||
checks = [
|
||||
"KIS_APP_KEY_REAL",
|
||||
"SCALP_STOP_LOSS_PCT",
|
||||
"TAIL_ATR_TP_MAX_PCT",
|
||||
"SHOULDER_MIN_HIGH_PCT",
|
||||
"MOMENTUM_SLOT_MONEY",
|
||||
"UPDOW_MAX_BUY_AMOUNT",
|
||||
"SELL_USE_ORDERBOOK_ON_PROFIT",
|
||||
]
|
||||
print("\n검증:")
|
||||
for k in checks:
|
||||
tbl = classify_config_key(k)
|
||||
print(f" {k} [{tbl}] = {snap.get(k, '(없음)')}")
|
||||
|
||||
db.close()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user