feat: 새로운 안전 규칙 및 최적화 적용을 통한 트레이딩 시스템 개선
변경 사항 (Changes): 구문 오류(Syntax error) 및 토큰 낭비를 방지하기 위해 에이전트 쉘(Agent shell)과 파이썬 코드 스니펫에 다수의 신규 안전 규칙(Safety rules)을 추가함. 스키마 검증 및 적절한 SQL 포맷팅을 보장하기 위해 임시(Ad-hoc) 데이터베이스 쿼리 작성 가이드라인을 도입함. 코드 수정 후 UI 기능이 정상 작동하는지 확인하기 위해, 백테스트 웹 서비스 재시작 및 브라우저 검증에 대한 새로운 규칙을 구현함. 시스템 전반의 무결성(Integrity)을 유지하기 위해 실전 매매(Live trading), 웹 백테스팅, 파라미터 탐색(Parameter searches) 간의 일관성 검사(Consistency checks) 체계를 확립함. 기대 효과 (Impact): 이러한 개선 사항들은 트레이딩 시스템의 견고성(Robustness)과 신뢰성을 향상시키며, 에러 발생을 최소화하고 다양한 시스템 컴포넌트 간의 원활한 상호작용을 보장함.
This commit is contained in:
124
scripts/_diag_mom_2min_gap.py
Normal file
124
scripts/_diag_mom_2min_gap.py
Normal file
@@ -0,0 +1,124 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user