한투 호가 = 2번째 앱키 전용 키 없거나 start 실패 시 메인에 H0STASP0 안 붙임. 운영설정 WS_ORDERBOOK_SAVE_KIS 빨간 danger. LS RAM 합집합 후보∪보유∪영구∪grace. sync_targets와 split reconcile 둘 다. 틱 DB 영구 게이트는 그대로. 분봉 쓰레기 → 다음 소스 봉 통째 그 분 틱 0건이거나 전부 봉끝 대비 LIVE_FEED_FALLBACK_MAX_AGE_SEC 초과면 구멍. 메인 WS → 2차 → LS → REST → rollup. CANDLE_GARBAGE_FALLBACK 기본 true. 파일: feed_fallback.py(신규), ws_manager.py, kis_ws.py, candle_series.py, bt_candle_source.py, live_config_schema.py, database.py, 스모크, MD 2개. 같은 ws_manager/database/kis_ws/live_config에는 직전 커밋 이후 쌓여 있던 시세 폴백·ENV 키 정리도 같이 들어갔습니다. 파일 단위로 나눌 수 없어서입니다.
116 lines
3.5 KiB
Python
116 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""025980 lag~28s vs 어제 아침 max~5s — 스키마 확인 후 1회 조회."""
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
from database import TradeDB
|
|
from kis_trader.utils.env import get_env_from_db
|
|
|
|
LAG = """
|
|
TIMESTAMPDIFF(
|
|
SECOND,
|
|
STR_TO_DATE(
|
|
CASE
|
|
WHEN CHAR_LENGTH(tick_time) >= 14 THEN LEFT(tick_time, 14)
|
|
WHEN CHAR_LENGTH(tick_time) = 6 THEN CONCAT(DATE_FORMAT(recv_ts, '%%Y%%m%%d'), tick_time)
|
|
ELSE NULL
|
|
END,
|
|
'%%Y%%m%%d%%H%%i%%s'
|
|
),
|
|
recv_ts
|
|
)
|
|
"""
|
|
|
|
db = TradeDB()
|
|
cols = [r["Field"] for r in db.conn.execute("SHOW COLUMNS FROM ws_ticks").fetchall()]
|
|
print("ws_ticks cols:", cols)
|
|
|
|
print("LIVE_MAX", get_env_from_db("KIWOOM_TICK_LIVE_MAX_LAG_SEC"))
|
|
print("TIME_MAX", get_env_from_db("KIWOOM_TICK_TIME_MAX_LAG_SEC"))
|
|
print("FLUSH", get_env_from_db("WS_TICK_DB_FLUSH_SEC"))
|
|
print("BATCH", get_env_from_db("WS_TICK_DB_BATCH_SIZE"))
|
|
|
|
sel = [
|
|
c
|
|
for c in (
|
|
"id",
|
|
"code",
|
|
"tick_time",
|
|
"tick_time_raw",
|
|
"recv_ts",
|
|
"price",
|
|
"volume",
|
|
"source",
|
|
)
|
|
if c in cols
|
|
]
|
|
sel_sql = ", ".join(sel)
|
|
|
|
print("\n== 오늘 kiwoom lag>5 ==")
|
|
rows = db.conn.execute(
|
|
f"SELECT {sel_sql}, {LAG} AS lag_sec FROM ws_ticks "
|
|
"WHERE source=%s AND recv_ts >= %s AND recv_ts < %s AND "
|
|
f"{LAG} > 5 ORDER BY lag_sec DESC LIMIT 20",
|
|
("kiwoom", "2026-08-19 09:00:00", "2026-08-19 09:15:00"),
|
|
).fetchall()
|
|
for r in rows:
|
|
print(dict(r))
|
|
|
|
print("\n== 025980 09:04:50~09:06:00 (id순) ==")
|
|
rows = db.conn.execute(
|
|
f"SELECT {sel_sql}, {LAG} AS lag_sec FROM ws_ticks "
|
|
"WHERE source=%s AND code=%s AND recv_ts >= %s AND recv_ts <= %s "
|
|
"ORDER BY id",
|
|
("kiwoom", "025980", "2026-08-19 09:04:50", "2026-08-19 09:06:00"),
|
|
).fetchall()
|
|
print("n", len(rows))
|
|
for r in rows:
|
|
print(dict(r))
|
|
|
|
# 같은 recv 초에 몰린 종목 수 (WS 스레드 스톨 흔적)
|
|
print("\n== 오늘 09:05:30~09:05:40 recv 초별 건수/종목 ==")
|
|
rows = db.conn.execute(
|
|
"SELECT recv_ts, COUNT(*) n, COUNT(DISTINCT code) codes "
|
|
"FROM ws_ticks WHERE source=%s AND recv_ts >= %s AND recv_ts <= %s "
|
|
"GROUP BY recv_ts ORDER BY recv_ts",
|
|
("kiwoom", "2026-08-19 09:05:30", "2026-08-19 09:05:40"),
|
|
).fetchall()
|
|
for r in rows:
|
|
print(dict(r))
|
|
|
|
print("\n== 오늘 09:00~09:10 lag 분포 ==")
|
|
rows = db.conn.execute(
|
|
f"SELECT {LAG} AS lag_sec, COUNT(*) n FROM ws_ticks "
|
|
"WHERE source=%s AND recv_ts >= %s AND recv_ts < %s "
|
|
f"GROUP BY {LAG} ORDER BY lag_sec DESC LIMIT 15",
|
|
("kiwoom", "2026-08-19 09:00:00", "2026-08-19 09:10:00"),
|
|
).fetchall()
|
|
for r in rows:
|
|
print(dict(r))
|
|
|
|
print("\n== 어제 09:00~09:15 lag 분포 top ==")
|
|
rows = db.conn.execute(
|
|
f"SELECT {LAG} AS lag_sec, COUNT(*) n FROM ws_ticks "
|
|
"WHERE source=%s AND recv_ts >= %s AND recv_ts < %s "
|
|
f"GROUP BY {LAG} ORDER BY lag_sec DESC LIMIT 15",
|
|
("kiwoom", "2026-08-18 09:00:00", "2026-08-18 09:15:00"),
|
|
).fetchall()
|
|
for r in rows:
|
|
print(dict(r))
|
|
|
|
print("\n== 어제 10:51~12:00 (잔존) lag 분포 top ==")
|
|
rows = db.conn.execute(
|
|
f"SELECT {LAG} AS lag_sec, COUNT(*) n FROM ws_ticks "
|
|
"WHERE source=%s AND recv_ts >= %s AND recv_ts < %s "
|
|
f"GROUP BY {LAG} ORDER BY lag_sec DESC LIMIT 10",
|
|
("kiwoom", "2026-08-18 10:51:00", "2026-08-18 12:00:00"),
|
|
).fetchall()
|
|
for r in rows:
|
|
print(dict(r))
|