feat(옵투나·웹): 후처리 재탐색·ob_modes·적용감사·수집통계
- Optuna web jobs/TPE/apply snapshot·틱로더 정합, jobs limit·감사로그 - 백테 UI 호가모드·후보 적용 흐름, feed_collect_stats API/탭 - 가설검증·교차검증 룰, 4전략 스모크·OB slot41 진단 스크립트 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -174,8 +174,10 @@ def load_ls_ticks_by_code(
|
||||
) -> Tuple[Dict[str, Dict[str, List[Dict[str, Any]]]], int]:
|
||||
"""
|
||||
ls_ws_ticks → {code: {minute_key: [tick...]}}.
|
||||
tick 스키마: tick_time/price/volume/source(=ls)
|
||||
tick 스키마: tick_time/price/volume/source(=ls)/_lag_sec(가능 시)
|
||||
"""
|
||||
from kis_trader.engine.feed_fallback import packet_lag_seconds
|
||||
|
||||
s12 = (start_key or "")[:12]
|
||||
e12 = (end_key or "")[:12]
|
||||
s_dt = _ct_to_ls_dt(s12)
|
||||
@@ -193,13 +195,13 @@ def load_ls_ticks_by_code(
|
||||
# 종목 수가 많으면 IN 절 — 청크당 한 번
|
||||
ph = ",".join(["%s"] * len(code_list))
|
||||
rows = db.conn.execute(
|
||||
f"SELECT code, ts, price, volume FROM ls_ws_ticks "
|
||||
f"SELECT code, ts, price, volume, chetime FROM ls_ws_ticks "
|
||||
f"WHERE ts >= %s AND ts <= %s AND code IN ({ph})",
|
||||
[chunk_s, chunk_e, *code_list],
|
||||
).fetchall()
|
||||
else:
|
||||
rows = db.conn.execute(
|
||||
"SELECT code, ts, price, volume FROM ls_ws_ticks "
|
||||
"SELECT code, ts, price, volume, chetime FROM ls_ws_ticks "
|
||||
"WHERE ts >= %s AND ts <= %s",
|
||||
[chunk_s, chunk_e],
|
||||
).fetchall()
|
||||
@@ -209,15 +211,36 @@ def load_ls_ticks_by_code(
|
||||
for r in rows or []:
|
||||
code = str(r["code"]).strip()
|
||||
tt = _ts_to_tick_time(r.get("ts"))
|
||||
che = str(r.get("chetime") or "").strip()
|
||||
che_d = "".join(ch for ch in che if ch.isdigit())
|
||||
# chetime 이 HHMMSS 이면 수신 ts 날짜와 합쳐 14자리
|
||||
if len(che_d) >= 14:
|
||||
tt = che_d[:14]
|
||||
elif len(che_d) >= 6 and len(tt) >= 8:
|
||||
tt = (tt[:8] + che_d[-6:]).ljust(14, "0")[:14]
|
||||
if len(tt) < 12:
|
||||
continue
|
||||
minute_key = tt[:12]
|
||||
lag = None
|
||||
try:
|
||||
recv_raw = r.get("ts")
|
||||
if isinstance(recv_raw, datetime):
|
||||
recv_dt = recv_raw
|
||||
else:
|
||||
recv_s = str(recv_raw or "")[:19]
|
||||
recv_dt = datetime.strptime(recv_s, "%Y-%m-%d %H:%M:%S")
|
||||
lag_f = packet_lag_seconds(tt, now_dt=recv_dt)
|
||||
if lag_f is not None:
|
||||
lag = int(lag_f)
|
||||
except Exception:
|
||||
lag = None
|
||||
tick = {
|
||||
"code": code,
|
||||
"tick_time": tt.ljust(14, "0")[:14],
|
||||
"price": float(r.get("price") or 0),
|
||||
"volume": int(float(r.get("volume") or 0)),
|
||||
"source": "ls",
|
||||
"_lag_sec": lag,
|
||||
}
|
||||
bucket = out[code].setdefault(minute_key, [])
|
||||
bucket.append(tick)
|
||||
|
||||
Reference in New Issue
Block a user