옵투나 오류수정정
This commit is contained in:
125
kis_trader/backtest/bt_rest_warmup_cache.py
Normal file
125
kis_trader/backtest/bt_rest_warmup_cache.py
Normal file
@@ -0,0 +1,125 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""백테 REST 전일봉 웜업 DB 캐시 — 다른 PC/동일 study 재사용.
|
||||
|
||||
성공분만 저장. 실패는 저장하지 않아 다른 머신·코드 개선 후 재시도 가능.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
logger = logging.getLogger("kis_trader.bt_rest_warmup_cache")
|
||||
|
||||
_TABLE = "bt_rest_warmup_cache"
|
||||
_ENSURED = False
|
||||
|
||||
_DDL = """
|
||||
CREATE TABLE IF NOT EXISTS bt_rest_warmup_cache (
|
||||
code VARCHAR(16) NOT NULL,
|
||||
period_day CHAR(8) NOT NULL COMMENT '백테 구간 시작일 YYYYMMDD',
|
||||
market VARCHAR(8) NOT NULL DEFAULT 'KR',
|
||||
n_bars INT NOT NULL DEFAULT 0 COMMENT '확보에 쓴 REST 봉수',
|
||||
ok TINYINT NOT NULL DEFAULT 0,
|
||||
prefix_json LONGTEXT NULL COMMENT '[{datetime,open,high,low,close,volume},...]',
|
||||
updated_at DATETIME NOT NULL,
|
||||
PRIMARY KEY (code, period_day, market),
|
||||
KEY idx_bt_rest_warm_day (period_day, market)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||
COMMENT='모멘텀 백테 REST 전일봉 웜업 공유 캐시(성공만)'
|
||||
"""
|
||||
|
||||
|
||||
def ensure_bt_rest_warmup_cache_table() -> None:
|
||||
global _ENSURED
|
||||
if _ENSURED:
|
||||
return
|
||||
try:
|
||||
from database import TradeDB
|
||||
|
||||
db = TradeDB()
|
||||
db.conn.execute(_DDL)
|
||||
_ENSURED = True
|
||||
except Exception as exc:
|
||||
logger.warning("⚠️ bt_rest_warmup_cache 테이블 생성 실패: %s", exc)
|
||||
|
||||
|
||||
def _day_key(start_key: str) -> str:
|
||||
s = str(start_key or "").strip().replace("-", "")[:8]
|
||||
return s if len(s) == 8 and s.isdigit() else ""
|
||||
|
||||
|
||||
def load_rest_warmup_prefix(
|
||||
code: str,
|
||||
*,
|
||||
period_day: str,
|
||||
market: str = "KR",
|
||||
) -> Optional[Tuple[List[Dict[str, Any]], int]]:
|
||||
"""성공 캐시면 (prefix_rows, n_bars), 없으면 None."""
|
||||
c = str(code or "").strip()
|
||||
day = _day_key(period_day)
|
||||
mkt = str(market or "KR").strip().upper() or "KR"
|
||||
if not c or not day:
|
||||
return None
|
||||
try:
|
||||
ensure_bt_rest_warmup_cache_table()
|
||||
from database import TradeDB
|
||||
|
||||
cur = TradeDB().conn.execute(
|
||||
"SELECT ok, n_bars, prefix_json FROM bt_rest_warmup_cache "
|
||||
"WHERE code=%s AND period_day=%s AND market=%s LIMIT 1",
|
||||
(c, day, mkt),
|
||||
)
|
||||
row = cur.fetchone()
|
||||
if not row:
|
||||
return None
|
||||
if int(row.get("ok") or 0) != 1:
|
||||
return None
|
||||
raw = row.get("prefix_json") or "[]"
|
||||
rows = json.loads(raw) if isinstance(raw, str) else (raw or [])
|
||||
if not isinstance(rows, list) or not rows:
|
||||
return None
|
||||
return rows, int(row.get("n_bars") or 0)
|
||||
except Exception as exc:
|
||||
logger.debug("bt_rest_warmup load miss %s: %s", c, exc)
|
||||
return None
|
||||
|
||||
|
||||
def save_rest_warmup_prefix(
|
||||
code: str,
|
||||
*,
|
||||
period_day: str,
|
||||
market: str,
|
||||
n_bars: int,
|
||||
prefix_rows: List[Dict[str, Any]],
|
||||
) -> bool:
|
||||
"""성공 접두만 upsert. 실패는 저장하지 않음."""
|
||||
c = str(code or "").strip()
|
||||
day = _day_key(period_day)
|
||||
mkt = str(market or "KR").strip().upper() or "KR"
|
||||
if not c or not day or not prefix_rows:
|
||||
return False
|
||||
try:
|
||||
ensure_bt_rest_warmup_cache_table()
|
||||
from database import TradeDB
|
||||
|
||||
payload = json.dumps(prefix_rows, ensure_ascii=False, separators=(",", ":"))
|
||||
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
TradeDB().conn.execute(
|
||||
"""
|
||||
INSERT INTO bt_rest_warmup_cache
|
||||
(code, period_day, market, n_bars, ok, prefix_json, updated_at)
|
||||
VALUES (%s, %s, %s, %s, 1, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
n_bars=VALUES(n_bars),
|
||||
ok=1,
|
||||
prefix_json=VALUES(prefix_json),
|
||||
updated_at=VALUES(updated_at)
|
||||
""",
|
||||
(c, day, mkt, int(n_bars or 0), payload, now),
|
||||
)
|
||||
return True
|
||||
except Exception as exc:
|
||||
logger.warning("⚠️ bt_rest_warmup 저장 실패 %s: %s", c, exc)
|
||||
return False
|
||||
Reference in New Issue
Block a user