변경 사항 (Changes): 구문 오류(Syntax error) 및 토큰 낭비를 방지하기 위해 에이전트 쉘(Agent shell)과 파이썬 코드 스니펫에 다수의 신규 안전 규칙(Safety rules)을 추가함. 스키마 검증 및 적절한 SQL 포맷팅을 보장하기 위해 임시(Ad-hoc) 데이터베이스 쿼리 작성 가이드라인을 도입함. 코드 수정 후 UI 기능이 정상 작동하는지 확인하기 위해, 백테스트 웹 서비스 재시작 및 브라우저 검증에 대한 새로운 규칙을 구현함. 시스템 전반의 무결성(Integrity)을 유지하기 위해 실전 매매(Live trading), 웹 백테스팅, 파라미터 탐색(Parameter searches) 간의 일관성 검사(Consistency checks) 체계를 확립함. 기대 효과 (Impact): 이러한 개선 사항들은 트레이딩 시스템의 견고성(Robustness)과 신뢰성을 향상시키며, 에러 발생을 최소화하고 다양한 시스템 컴포넌트 간의 원활한 상호작용을 보장함.
125 lines
4.6 KiB
Python
125 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
|
"""SK 10:36 BT vs 10:38 live — DB 타임라인 + 틱/봉 진단."""
|
|
from __future__ import annotations
|
|
|
|
import subprocess
|
|
from database import TradeDB
|
|
|
|
CODE = "475150"
|
|
DAY = "20260713"
|
|
DAY_DASH = "2026-07-13"
|
|
|
|
|
|
def main() -> None:
|
|
db = TradeDB()
|
|
try:
|
|
cols = [r["Field"] for r in db.conn.execute("SHOW COLUMNS FROM trade_history").fetchall()]
|
|
print("trade_history cols:", cols)
|
|
|
|
rows = db.conn.execute(
|
|
"SELECT code, name, strategy, buy_price, sell_price, qty, realized_pnl, "
|
|
"buy_date, sell_date, sell_reason, hold_minutes "
|
|
"FROM trade_history WHERE code=%s AND buy_date LIKE %s ORDER BY buy_date",
|
|
(CODE, DAY_DASH + "%"),
|
|
).fetchall()
|
|
print(f"\ntrade_history SK today n={len(rows)}")
|
|
for r in rows:
|
|
d = dict(r)
|
|
print(
|
|
f" buy={d.get('buy_date')} sell={d.get('sell_date')} "
|
|
f"bp={d.get('buy_price')} sp={d.get('sell_price')} qty={d.get('qty')} "
|
|
f"pnl={d.get('realized_pnl')} reason={d.get('sell_reason')} "
|
|
f"strat={d.get('strategy')}"
|
|
)
|
|
|
|
print("\n1m candles 10:34-10:40:")
|
|
cans = db.conn.execute(
|
|
"SELECT candle_time, open, high, low, close, volume FROM ws_candles "
|
|
"WHERE code=%s AND timeframe=%s AND candle_time BETWEEN %s AND %s "
|
|
"ORDER BY candle_time",
|
|
(CODE, 1, DAY + "1034", DAY + "1040"),
|
|
).fetchall()
|
|
for c in cans:
|
|
print(
|
|
f" {c['candle_time']} O={c['open']} H={c['high']} "
|
|
f"L={c['low']} C={c['close']} V={c['volume']}"
|
|
)
|
|
|
|
print("\nfirst/last tick per minute 10:35-10:39:")
|
|
for m in ("1035", "1036", "1037", "1038", "1039"):
|
|
tt0, tt1 = DAY + m + "00", DAY + m + "59"
|
|
r = db.conn.execute(
|
|
"SELECT COUNT(*) n, MIN(tick_time) mn, MAX(tick_time) mx, "
|
|
"MIN(price) lo, MAX(price) hi FROM ws_ticks "
|
|
"WHERE code=%s AND tick_time BETWEEN %s AND %s",
|
|
(CODE, tt0, tt1),
|
|
).fetchone()
|
|
first = db.conn.execute(
|
|
"SELECT tick_time, price FROM ws_ticks "
|
|
"WHERE code=%s AND tick_time BETWEEN %s AND %s "
|
|
"ORDER BY tick_time ASC LIMIT 1",
|
|
(CODE, tt0, tt1),
|
|
).fetchone()
|
|
print(
|
|
f" {m}: n={r['n']} {r['mn']}~{r['mx']} "
|
|
f"first={dict(first) if first else None} range={r['lo']}~{r['hi']}"
|
|
)
|
|
|
|
# nearest tick to live buy 10:38:06 at 51600
|
|
print("\nticks near live buy 51600 @10:38:")
|
|
near = db.conn.execute(
|
|
"SELECT tick_time, price, volume FROM ws_ticks "
|
|
"WHERE code=%s AND tick_time BETWEEN %s AND %s AND price BETWEEN %s AND %s "
|
|
"ORDER BY tick_time LIMIT 20",
|
|
(CODE, DAY + "103700", DAY + "103900", 51500, 51700),
|
|
).fetchall()
|
|
for t in near:
|
|
print(f" {dict(t)}")
|
|
|
|
# ticks near BT buy 50800 @10:36
|
|
print("\nticks near BT buy 50800 @10:36:")
|
|
near2 = db.conn.execute(
|
|
"SELECT tick_time, price, volume FROM ws_ticks "
|
|
"WHERE code=%s AND tick_time BETWEEN %s AND %s AND price BETWEEN %s AND %s "
|
|
"ORDER BY tick_time LIMIT 20",
|
|
(CODE, DAY + "103600", DAY + "103700", 50700, 50900),
|
|
).fetchall()
|
|
for t in near2:
|
|
print(f" {dict(t)}")
|
|
|
|
hcols = [r["Field"] for r in db.conn.execute(
|
|
"SHOW COLUMNS FROM target_candidates_history"
|
|
).fetchall()]
|
|
print("\nhistory cols:", hcols)
|
|
if "slot_key" in hcols:
|
|
hs2 = db.conn.execute(
|
|
"SELECT slot_key, COUNT(*) n FROM target_candidates_history "
|
|
"WHERE code=%s AND slot_key LIKE %s GROUP BY slot_key ORDER BY slot_key",
|
|
(CODE, DAY + "103%"),
|
|
).fetchall()
|
|
print("SK slots 103x:")
|
|
for h in hs2:
|
|
print(f" {h['slot_key']} n={h['n']}")
|
|
|
|
finally:
|
|
db.close()
|
|
|
|
print("\n=== journal 10:34-10:41 ===")
|
|
p = subprocess.run(
|
|
[
|
|
"journalctl", "-u", "kis_trader_main.service",
|
|
"--since", "2026-07-13 10:34:00",
|
|
"--until", "2026-07-13 10:41:00",
|
|
"--no-pager",
|
|
],
|
|
capture_output=True, text=True,
|
|
)
|
|
keys = ("475150", "이터닉스", "MOMENTUM")
|
|
for line in p.stdout.splitlines():
|
|
if any(k in line for k in keys):
|
|
print(line[:240])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|