ls증권 히스토리 구독 넣음
This commit is contained in:
@@ -581,19 +581,27 @@ class TradeDBExt:
|
||||
# ------------------------------------------------------------------
|
||||
# 백테스트 헬퍼: 특정 시점의 유니버스 복원
|
||||
# ------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def _universe_history_table(history_source: str = "kiwoom") -> str:
|
||||
from kis_trader.backtest.universe_history_source import history_table_for_source
|
||||
return history_table_for_source(history_source)
|
||||
|
||||
def get_universe_at(
|
||||
self, *, strategy_id: str, at_time: str
|
||||
self, *, strategy_id: str, at_time: str, history_source: str = "kiwoom",
|
||||
) -> List[Dict]:
|
||||
"""
|
||||
``at_time`` ('YYYY-MM-DD HH:MM:SS') 시점에 봇이 보던 유니버스를 복원.
|
||||
= 그 시각 이전의 가장 최근 event_time 스냅샷.
|
||||
|
||||
``history_source``: ``kiwoom``(target_candidates_history) | ``ls``(ls_candidates_history)
|
||||
"""
|
||||
self._ensure_history_columns()
|
||||
table = self._universe_history_table(history_source)
|
||||
try:
|
||||
row = self.conn.execute(
|
||||
"""
|
||||
f"""
|
||||
SELECT MAX(event_time) AS et
|
||||
FROM target_candidates_history
|
||||
FROM {table}
|
||||
WHERE strategy_id=%s AND event_time <= %s
|
||||
""",
|
||||
(strategy_id, at_time),
|
||||
@@ -602,8 +610,8 @@ class TradeDBExt:
|
||||
if not et:
|
||||
return []
|
||||
rows = self.conn.execute(
|
||||
"""
|
||||
SELECT code, name FROM target_candidates_history
|
||||
f"""
|
||||
SELECT code, name FROM {table}
|
||||
WHERE strategy_id=%s AND event_time=%s
|
||||
ORDER BY code
|
||||
""",
|
||||
@@ -611,7 +619,7 @@ class TradeDBExt:
|
||||
).fetchall()
|
||||
return [{"code": r["code"], "name": r["name"]} for r in rows]
|
||||
except Exception as e:
|
||||
logger.error("get_universe_at 실패: %s", e)
|
||||
logger.error("get_universe_at 실패(src=%s): %s", history_source, e)
|
||||
return []
|
||||
|
||||
def iter_universe_events(
|
||||
@@ -621,6 +629,7 @@ class TradeDBExt:
|
||||
start_time: str,
|
||||
end_time: str,
|
||||
preserve_insert_order: bool = False,
|
||||
history_source: str = "kiwoom",
|
||||
) -> List[Dict]:
|
||||
"""
|
||||
``[start_time, end_time]`` 구간의 모든 스냅샷 이벤트를 시간순 반환.
|
||||
@@ -629,14 +638,16 @@ class TradeDBExt:
|
||||
|
||||
``preserve_insert_order=True``: 스냅샷 내 종목 순서를 DB insert(id) 순으로
|
||||
유지 (백테 매수 우선순위 정합). 기본 False 는 code 가나다순.
|
||||
``history_source``: ``kiwoom`` | ``ls``
|
||||
"""
|
||||
self._ensure_history_columns()
|
||||
table = self._universe_history_table(history_source)
|
||||
order_clause = "event_time, id" if preserve_insert_order else "event_time, code"
|
||||
try:
|
||||
rows = self.conn.execute(
|
||||
f"""
|
||||
SELECT event_time, code, name
|
||||
FROM target_candidates_history
|
||||
FROM {table}
|
||||
WHERE strategy_id=%s
|
||||
AND event_time BETWEEN %s AND %s
|
||||
ORDER BY {order_clause}
|
||||
@@ -654,7 +665,7 @@ class TradeDBExt:
|
||||
for et, items in sorted(grouped.items())
|
||||
]
|
||||
except Exception as e:
|
||||
logger.error("iter_universe_events 실패: %s", e)
|
||||
logger.error("iter_universe_events 실패(src=%s): %s", history_source, e)
|
||||
return []
|
||||
|
||||
@staticmethod
|
||||
@@ -673,6 +684,7 @@ class TradeDBExt:
|
||||
strict: bool = False,
|
||||
strict_lag_minutes: int = 1,
|
||||
exit_debounce_sec: int = 0,
|
||||
history_source: str = "kiwoom",
|
||||
) -> Dict[str, List[str]]:
|
||||
"""
|
||||
백테스트 편의용 — 1분봉 캔들 시각(YYYYMMDDHHMM)을 키로 하는 유니버스 dict.
|
||||
@@ -695,6 +707,7 @@ class TradeDBExt:
|
||||
strict: 종목별 첫 event_time 기준 편입 지연 적용
|
||||
strict_lag_minutes: 첫 편입 분 이후 추가 대기 분 (기본 1)
|
||||
exit_debounce_sec: 짧은 EXIT→재편입 무시(초). 0=OFF.
|
||||
history_source: ``kiwoom`` | ``ls``
|
||||
|
||||
Returns:
|
||||
``{candle_time(YYYYMMDDHHMM): [code, ...]}`` —
|
||||
@@ -703,12 +716,23 @@ class TradeDBExt:
|
||||
"""
|
||||
self._ensure_history_columns()
|
||||
|
||||
from kis_trader.backtest.universe_history_source import (
|
||||
apply_ls_session_filter_to_start,
|
||||
normalize_universe_history_source,
|
||||
)
|
||||
|
||||
history_source = normalize_universe_history_source(history_source)
|
||||
|
||||
# 조회 범위: 전일 마지막 스냅샷도 포함하기 위해 시작일 00:00:00 이전 1건은
|
||||
# 엔진 쪽에서 "이전에 유효했던 유니버스" 로 물려받는 게 자연스럽다.
|
||||
# 단순화를 위해 start_ymd 00:00:00 ~ end_ymd 23:59:59 범위로 쿼리.
|
||||
# LS + SESSION_ONLY: 장전 sticky 스냅 제외 → 당일 09:00 부터.
|
||||
start_time = (
|
||||
f"{start_ymd[:4]}-{start_ymd[4:6]}-{start_ymd[6:8]} 00:00:00"
|
||||
)
|
||||
start_time = apply_ls_session_filter_to_start(
|
||||
start_time, source=history_source,
|
||||
)
|
||||
end_time = (
|
||||
f"{end_ymd[:4]}-{end_ymd[4:6]}-{end_ymd[6:8]} 23:59:59"
|
||||
)
|
||||
@@ -718,6 +742,7 @@ class TradeDBExt:
|
||||
start_time=start_time,
|
||||
end_time=end_time,
|
||||
preserve_insert_order=True,
|
||||
history_source=history_source,
|
||||
)
|
||||
if not events:
|
||||
return {}
|
||||
@@ -768,6 +793,7 @@ class TradeDBExt:
|
||||
try:
|
||||
prev_items = self.get_universe_at(
|
||||
strategy_id=strategy_id, at_time=start_time,
|
||||
history_source=history_source,
|
||||
)
|
||||
prev_codes_set = {
|
||||
str(it["code"]) for it in prev_items if it.get("code")
|
||||
|
||||
Reference in New Issue
Block a user