ls증권 히스토리 구독 넣음

This commit is contained in:
Your Name
2026-07-30 18:05:07 +09:00
parent 61bec4bd1d
commit 67eab24603
1593 changed files with 135733 additions and 1232 deletions

View File

@@ -310,19 +310,26 @@ def resolve_breakout_universe(
*,
use_saved_history: bool,
strategy_id: str = BREAKOUT_STRATEGY_ID,
history_source: str = "kiwoom",
) -> Tuple[Optional[Dict[str, List[str]]], str, int, int]:
if use_saved_history and strategy_id:
try:
from kis_trader.database.db_manager import get_db as _get_ext_db
from kis_trader.backtest.universe_history_source import (
history_source_label,
resolve_backtest_universe_history_source,
)
hs = resolve_backtest_universe_history_source(history_source)
history = _get_ext_db().get_universe_by_candle_time(
strategy_id=strategy_id,
start_ymd=start_ymd,
end_ymd=end_ymd,
exit_debounce_sec=breakout_universe_exit_debounce_sec(),
history_source=hs,
)
if history:
return history, "history", len(history), 1
return history, history_source_label(hs), len(history), 1
except Exception:
pass
return None, "all", 0, 1
@@ -334,12 +341,21 @@ def load_breakout_candles_by_code(
end_key: str,
lookback_min: int = 1,
vol_window: int = 7,
*,
history_source: str = "kiwoom",
) -> Tuple[Dict[str, List[Dict]], int]:
"""ws_candles 1분봉 전 종목 로드."""
"""1분봉 전 종목 로드. history_source=ls → ls_ws_candles."""
min_bars = breakout_min_bars_required({
"lookback_min": lookback_min,
"vol_window": int(vol_window),
})
hs = str(history_source or "kiwoom").strip().lower()
if hs in ("ls", "ls_condition", "ls_ws"):
from kis_trader.backtest.ls_history_loaders import load_ls_candles_by_code
return load_ls_candles_by_code(
db, start_key, end_key, min_bars=min_bars,
)
ind_cols = ws_candles_select_indicator_cols(db)
codes_raw = db.conn.execute(
@@ -427,11 +443,22 @@ def run_breakout_backtest_web_aligned(
_sk, _ek = min(_days), max(_days)
if len(_sk) >= 8 and len(_ek) >= 8:
from kis_trader.backtest.universe_timeline import build_universe_timeline
from kis_trader.backtest.universe_history_source import (
resolve_backtest_universe_history_source,
)
_deb = breakout_universe_exit_debounce_sec()
# 슬롯 dict(resolve_breakout_universe)와 동일 소스 — LS 라벨인데 키움 타임라인 쓰는 사고 방지
_hs = resolve_backtest_universe_history_source(
engine_params.get("_universe_history_source")
or engine_params.get("universe_history_source")
)
engine_params["_universe_history_source"] = _hs
_tl = build_universe_timeline(
strategy_id=BREAKOUT_STRATEGY_ID,
start_ymd=_sk[:8], end_ymd=_ek[:8],
debounce_sec=_deb, strict=False, strict_lag_minutes=0,
history_source=_hs,
)
if _tl is not None:
engine_params["_universe_timeline"] = _tl
@@ -439,6 +466,7 @@ def run_breakout_backtest_web_aligned(
meta_out["universe_timing"] = "scan_at"
meta_out["universe_timeline_snapshots"] = _tl.snapshot_count
meta_out["universe_exit_debounce_sec"] = _deb
meta_out["universe_history_source"] = _hs
db_for_share = (meta_out or {}).get("db")
if db_for_share and "share_denom_by_code" not in engine_params:
@@ -453,17 +481,38 @@ def run_breakout_backtest_web_aligned(
start_key = str(meta_out.get("start_key") or "")
end_key = str(meta_out.get("end_key") or "")
db = meta_out.get("db")
if db is None and start_key and end_key:
from kis_trader.backtest.backtest_portfolio_common import ensure_meta_db
db = ensure_meta_db(meta_out)
if db and start_key and end_key:
loaded_ticks, tick_rows = load_breakout_ticks_by_code(
db, start_key, end_key, set(candles_by_code.keys()),
)
_hs_tick = str(
engine_params.get("_universe_history_source")
or engine_params.get("universe_history_source")
or (meta_out or {}).get("universe_history_source")
or "kiwoom"
).strip().lower()
if _hs_tick in ("ls", "ls_condition", "ls_ws"):
from kis_trader.backtest.ls_history_loaders import load_ls_ticks_by_code
loaded_ticks, tick_rows = load_ls_ticks_by_code(
db, start_key, end_key, set(candles_by_code.keys()),
)
_tick_tbl = "ls_ws_ticks"
else:
loaded_ticks, tick_rows = load_breakout_ticks_by_code(
db, start_key, end_key, set(candles_by_code.keys()),
)
_tick_tbl = "ws_ticks"
tick_meta = tick_coverage_stats(candles_by_code, loaded_ticks)
tick_meta["ws_tick_rows_loaded"] = tick_rows
tick_meta["tick_table"] = _tick_tbl
if tick_rows <= 0:
from kis_trader.utils.logger import get_logger as _get_logger
_get_logger("kis_trader.breakout_backtest").warning(
"⚠️ ws_ticks 데이터 없음 — B안 OHLC high 폴백 (틱 수집 후 재백테 권장)",
"⚠️ %s 데이터 없음 — B안 OHLC high 폴백 (틱 수집 후 재백테 권장)",
_tick_tbl,
)
elif loaded_ticks:
tick_meta = tick_coverage_stats(candles_by_code, loaded_ticks)