ls증권 히스토리 구독 넣음
This commit is contained in:
@@ -43,6 +43,7 @@ def resolve_scalp_universe(
|
||||
*,
|
||||
use_saved_history: bool,
|
||||
strategy_id: str = SCALP_STRATEGY_ID,
|
||||
history_source: str = "kiwoom",
|
||||
) -> Tuple[Optional[Dict[str, List[str]]], str, int, int]:
|
||||
"""
|
||||
backtest_web 유니버스 해석과 동일.
|
||||
@@ -53,16 +54,22 @@ def resolve_scalp_universe(
|
||||
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,
|
||||
)
|
||||
|
||||
debounce_sec = scalp_universe_exit_debounce_sec()
|
||||
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=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
|
||||
@@ -88,6 +95,7 @@ def prepend_scalp_candle_warmup(
|
||||
period_start_key: str,
|
||||
*,
|
||||
warmup_bars: Optional[int] = None,
|
||||
history_source: str = "kiwoom",
|
||||
) -> int:
|
||||
"""
|
||||
``period_start_key``(YYYYMMDDHHMM) 이전 N봉을 종목별로 prepend.
|
||||
@@ -100,6 +108,13 @@ def prepend_scalp_candle_warmup(
|
||||
)
|
||||
if wb <= 0 or db is None or not period_start_key:
|
||||
return 0
|
||||
hs = str(history_source or "kiwoom").strip().lower()
|
||||
if hs in ("ls", "ls_condition", "ls_ws"):
|
||||
from kis_trader.backtest.ls_history_loaders import prepend_ls_candle_warmup
|
||||
|
||||
return prepend_ls_candle_warmup(
|
||||
db, candles_by_code, str(period_start_key)[:12], wb,
|
||||
)
|
||||
ps = str(period_start_key)[:12]
|
||||
total_prepended = 0
|
||||
for code, rows in list(candles_by_code.items()):
|
||||
@@ -139,8 +154,23 @@ def load_scalp_candles_by_code(
|
||||
start_key: str,
|
||||
end_key: str,
|
||||
rsi_period: int = 3,
|
||||
*,
|
||||
history_source: str = "kiwoom",
|
||||
) -> Tuple[Dict[str, List[Dict]], int]:
|
||||
"""ws_candles 1분봉 전 종목 로드 (+ 기간 전 웜업 prepend)."""
|
||||
"""1분봉 전 종목 로드 (+ 웜업). history_source=ls → ls_ws_candles."""
|
||||
min_bars = int(rsi_period) + 5
|
||||
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
|
||||
|
||||
candles_by_code, total_candles = load_ls_candles_by_code(
|
||||
db, start_key, end_key, min_bars=min_bars,
|
||||
)
|
||||
prepend_scalp_candle_warmup(
|
||||
db, candles_by_code, str(start_key)[:12], history_source="ls",
|
||||
)
|
||||
return candles_by_code, total_candles
|
||||
|
||||
codes_raw = db.conn.execute(
|
||||
"SELECT DISTINCT code FROM ws_candles WHERE timeframe=1 "
|
||||
"AND candle_time >= %s AND candle_time <= %s ORDER BY code",
|
||||
@@ -150,7 +180,6 @@ def load_scalp_candles_by_code(
|
||||
|
||||
candles_by_code: Dict[str, List[Dict]] = {}
|
||||
total_candles = 0
|
||||
min_bars = int(rsi_period) + 5
|
||||
|
||||
for code in codes:
|
||||
rows = db.conn.execute(
|
||||
@@ -212,7 +241,15 @@ def run_scalping_backtest_web_aligned(
|
||||
engine_params["_backtest_period_start_key"] = _sk_w
|
||||
_db_w = (meta_out or {}).get("db")
|
||||
if _db_w is not None and str(mode).strip().lower() != "momentum":
|
||||
prepend_scalp_candle_warmup(_db_w, candles_by_code, _sk_w)
|
||||
_hs_w = 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()
|
||||
prepend_scalp_candle_warmup(
|
||||
_db_w, candles_by_code, _sk_w, history_source=_hs_w,
|
||||
)
|
||||
|
||||
from kis_trader.backtest.backtest_env_timeline import attach_backtest_env_timeline_to_params
|
||||
attach_backtest_env_timeline_to_params(engine_params, meta_out, "SCALP")
|
||||
@@ -236,18 +273,41 @@ def run_scalping_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.scalping_backtest").warning(
|
||||
"⚠️ ws_ticks 데이터 없음 — SCALP 틱 청산/진입 스킵 "
|
||||
"⚠️ %s 데이터 없음 — SCALP 틱 청산/진입 스킵 "
|
||||
"(틱 수집 후 재백테 권장, FALLBACK_OHLC=1 시 OHLC)",
|
||||
_tick_tbl,
|
||||
)
|
||||
elif loaded_ticks:
|
||||
tick_meta = tick_coverage_stats(candles_by_code, loaded_ticks)
|
||||
|
||||
Reference in New Issue
Block a user