feat(Core/UI): 백테스트 전역 엔진 선택 버튼 추가 및 스캘핑 Rust 방어로직 포팅 1차 완료

This commit is contained in:
Your Name
2026-09-03 02:49:14 +09:00
parent ac1190f1fc
commit 3b7c21cde4
316 changed files with 56952 additions and 1 deletions

123
scratch/check_stale_data.py Normal file
View File

@@ -0,0 +1,123 @@
"""
DB 실태 조사:
1. 현재 KEEP_DAYS 관련 env 값
2. ws_ticks / ws_orderbook / ws_candles 의 오래된 데이터 존재 여부
3. 인덱스를 못 타는 "어긋난 데이터" 확인 (recv_ts 포맷, candle_time 포맷)
"""
import sys, os
sys.path.insert(0, '/home/hoon/kis_bot')
os.chdir('/home/hoon/kis_bot')
from database import TradeDB
db = TradeDB()
try:
# 1. 현재 DB env 값 확인
print("=== [1] DB ENV 값 확인 ===")
env_keys = [
'WS_TICK_KEEP_DAYS', 'WS_ORDERBOOK_KEEP_DAYS', 'WS_PROGRAM_KEEP_DAYS',
'SCALP_CANDLE_KEEP_DAYS', 'LS_WS_ORDERBOOK_KEEP_DAYS'
]
for k in env_keys:
# env_config 메인 테이블에서 최신 행 가져오기
row = db.conn.execute(
"SELECT * FROM env_config ORDER BY id DESC LIMIT 1"
).fetchone()
row_dict = dict(row) if row else {}
# env_config_ext 확인
ext_row = db.conn.execute(
"SELECT env_value FROM env_config_ext WHERE env_key = %s", (k,)
).fetchone()
val = dict(ext_row)['env_value'] if ext_row else row_dict.get(k, 'NULL(코드기본값)')
print(f" {k} = {val}")
# 2. ws_ticks 현황 (min/max recv_ts, 총 행 수)
print("\n=== [2] ws_ticks 현황 ===")
cols = [dict(r)['Field'] for r in db.conn.execute("SHOW COLUMNS FROM ws_ticks").fetchall()]
print(f" 컬럼: {cols}")
row = db.conn.execute(
"SELECT COUNT(*) AS cnt, MIN(recv_ts) AS min_ts, MAX(recv_ts) AS max_ts FROM ws_ticks"
).fetchone()
print(f" 총 행 수: {dict(row)}")
# recv_ts 형식 샘플
rows = db.conn.execute("SELECT recv_ts FROM ws_ticks LIMIT 5").fetchall()
print(f" recv_ts 샘플: {[dict(r)['recv_ts'] for r in rows]}")
# recv_ts 포맷 이상 데이터 수 (YYYY-MM-DD HH:MM:SS 가 아닌 것)
row = db.conn.execute(
"SELECT COUNT(*) AS cnt FROM ws_ticks WHERE recv_ts NOT REGEXP '^[0-9]{4}-[0-9]{2}-[0-9]{2} '"
).fetchone()
print(f" recv_ts 포맷 이상 행 수: {dict(row)['cnt']}")
# 3. ws_orderbook 현황
print("\n=== [3] ws_orderbook 현황 ===")
row = db.conn.execute(
"SELECT COUNT(*) AS cnt, MIN(recv_ts) AS min_ts, MAX(recv_ts) AS max_ts FROM ws_orderbook"
).fetchone()
print(f" 총 행 수: {dict(row)}")
rows = db.conn.execute("SELECT recv_ts FROM ws_orderbook LIMIT 3").fetchall()
print(f" recv_ts 샘플: {[dict(r)['recv_ts'] for r in rows]}")
# 4. ws_candles 현황
print("\n=== [4] ws_candles 현황 ===")
cols_c = [dict(r)['Field'] for r in db.conn.execute("SHOW COLUMNS FROM ws_candles").fetchall()]
print(f" 컬럼: {cols_c}")
row = db.conn.execute(
"SELECT COUNT(*) AS cnt, MIN(candle_time) AS min_ct, MAX(candle_time) AS max_ct FROM ws_candles"
).fetchone()
print(f" 총 행 수: {dict(row)}")
rows = db.conn.execute("SELECT candle_time FROM ws_candles LIMIT 5").fetchall()
print(f" candle_time 샘플: {[dict(r)['candle_time'] for r in rows]}")
# candle_time 포맷: 새 코드는 YYYYMMDDHHMM (12자리)
# 혹시 다른 포맷이 있는지
row = db.conn.execute(
"SELECT COUNT(*) AS cnt FROM ws_candles WHERE LENGTH(candle_time) != 12 OR candle_time NOT REGEXP '^[0-9]+$'"
).fetchone()
print(f" candle_time 포맷 이상 행 수: {dict(row)['cnt']}")
# 5. ls_ws_ticks 현황
print("\n=== [5] ls_ws_ticks 현황 ===")
row = db.conn.execute(
"SELECT COUNT(*) AS cnt, MIN(ts) AS min_ts, MAX(ts) AS max_ts FROM ls_ws_ticks"
).fetchone()
print(f" 총 행 수: {dict(row)}")
# 6. ls_ws_orderbook 현황
print("\n=== [6] ls_ws_orderbook 현황 ===")
row = db.conn.execute(
"SELECT COUNT(*) AS cnt, MIN(recv_ts) AS min_ts, MAX(recv_ts) AS max_ts FROM ls_ws_orderbook"
).fetchone()
print(f" 총 행 수: {dict(row)}")
# 7. 7일 이전 오래된 데이터 수
print("\n=== [7] 7일 기준 오래된 데이터 ===")
import datetime
cutoff7 = (datetime.datetime.now() - datetime.timedelta(days=7)).strftime("%Y-%m-%d %H:%M:%S")
print(f" cutoff 기준: {cutoff7}")
for table, col in [('ws_ticks', 'recv_ts'), ('ws_orderbook', 'recv_ts'), ('ls_ws_orderbook', 'recv_ts')]:
row = db.conn.execute(
f"SELECT COUNT(*) AS cnt FROM {table} WHERE {col} < %s", (cutoff7,)
).fetchone()
print(f" {table}: {dict(row)['cnt']}행 (7일 초과 오래된 것)")
# ws_candles: candle_time < 3일 전 vs 7일 전
cutoff3 = (datetime.datetime.now() - datetime.timedelta(days=3)).strftime("%Y%m%d%H%M")
cutoff7c = (datetime.datetime.now() - datetime.timedelta(days=7)).strftime("%Y%m%d%H%M")
row3 = db.conn.execute(
"SELECT COUNT(*) AS cnt FROM ws_candles WHERE candle_time < %s", (cutoff3,)
).fetchone()
row7 = db.conn.execute(
"SELECT COUNT(*) AS cnt FROM ws_candles WHERE candle_time < %s", (cutoff7c,)
).fetchone()
print(f" ws_candles: 3일 초과={dict(row3)['cnt']}행, 7일 초과={dict(row7)['cnt']}")
# ls_ws_ticks: ts 기준
row = db.conn.execute(
"SELECT COUNT(*) AS cnt FROM ls_ws_ticks WHERE ts < %s", (cutoff7,)
).fetchone()
print(f" ls_ws_ticks: {dict(row)['cnt']}행 (7일 초과 오래된 것)")
finally:
db.close()