Files
kis_bot/kis_trader/backtest/universe_history_source.py
2026-07-30 18:05:07 +09:00

82 lines
2.6 KiB
Python

"""
백테/Optuna 유니버스 이력 테이블 소스 해석
========================================
- ``kiwoom`` / ``target`` → ``target_candidates_history`` (실매 키움·KIS 조건식)
- ``ls`` → ``ls_candidates_history`` (LS AFR 수집)
기본값 ``kiwoom``. CLI / 웹 body / env ``BACKTEST_UNIVERSE_HISTORY_SOURCE`` 우선순위.
"""
from __future__ import annotations
from typing import Any, Optional
from kis_trader.utils.env import get_env_bool, get_env_from_db
VALID_HISTORY_SOURCES = frozenset({"kiwoom", "target", "ls"})
def normalize_universe_history_source(raw: Any) -> str:
s = str(raw or "").strip().lower()
if s in ("", "kiwoom", "target", "kis", "condition"):
return "kiwoom"
if s in ("ls", "ls_condition", "ls_afr"):
return "ls"
return "kiwoom"
def resolve_backtest_universe_history_source(
override: Any = None,
*,
default: str = "kiwoom",
) -> str:
"""override(CLI/웹) > env BACKTEST_UNIVERSE_HISTORY_SOURCE > default."""
if override is not None and str(override).strip() != "":
return normalize_universe_history_source(override)
env_v = get_env_from_db("BACKTEST_UNIVERSE_HISTORY_SOURCE", default)
return normalize_universe_history_source(env_v or default)
def history_table_for_source(source: str) -> str:
src = normalize_universe_history_source(source)
if src == "ls":
return "ls_candidates_history"
return "target_candidates_history"
def history_source_label(source: str, *, strict: bool = False) -> str:
src = normalize_universe_history_source(source)
if src == "ls":
return "history_ls_strict" if strict else "history_ls"
return "history_strict" if strict else "history"
def ls_universe_session_only_enabled() -> bool:
"""LS sticky(장전 00시 스냅) 제외 — 기본 ON."""
return bool(get_env_bool("BACKTEST_LS_UNIVERSE_SESSION_ONLY", True))
def apply_ls_session_filter_to_start(
start_time: str,
*,
source: str,
session_only: Optional[bool] = None,
) -> str:
"""
LS + session_only 이면 당일 09:00:00 이전 스냅을 조회 시작에서 잘라낸다.
start_time 형식: 'YYYY-MM-DD HH:MM:SS'
"""
src = normalize_universe_history_source(source)
if src != "ls":
return start_time
if session_only is None:
session_only = ls_universe_session_only_enabled()
if not session_only:
return start_time
# start_time 날짜의 09:00:00 과 max
try:
day = str(start_time)[:10]
floor = f"{day} 09:00:00"
return floor if floor > str(start_time) else str(start_time)
except Exception:
return start_time