- Optuna web jobs/TPE/apply snapshot·틱로더 정합, jobs limit·감사로그 - 백테 UI 호가모드·후보 적용 흐름, feed_collect_stats API/탭 - 가설검증·교차검증 룰, 4전략 스모크·OB slot41 진단 스크립트 Co-authored-by: Cursor <cursoragent@cursor.com>
147 lines
4.5 KiB
Python
147 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Apply trial#120 params → 1일 모멘텀 백테 (호가 ON). DB 미변경."""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
|
|
_ROOT = Path(__file__).resolve().parents[1]
|
|
if str(_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(_ROOT))
|
|
|
|
|
|
def main() -> int:
|
|
t0 = time.time()
|
|
start = end = "2026-08-25"
|
|
out_json = _ROOT / "logs" / "mom_bt_20260825_trial120_ob_on.json"
|
|
print(f"start prepare {start} OB=on", flush=True)
|
|
|
|
from database import TradeDB
|
|
from kis_trader.backtest.optuna_momentum import prepare_momentum_search_context
|
|
from kis_trader.backtest.param_search_momentum import evaluate_momentum_param_combo
|
|
|
|
db = TradeDB()
|
|
row = db.conn.execute(
|
|
"SELECT payload_json FROM optuna_study_result WHERE study_name=%s",
|
|
("momentum_tpe_20260818_20260821_20260823_192516",),
|
|
).fetchone()
|
|
payload = json.loads(row["payload_json"])
|
|
t120 = next(x for x in payload["results_gated"] if x.get("optuna_trial_number") == 120)
|
|
combo = dict(t120["params"])
|
|
print(
|
|
"trial120 ob=%s whip=%s sl=%s tp=%s" % (
|
|
combo.get("_orderbook_filter_enabled"),
|
|
combo.get("whipsaw_enabled"),
|
|
combo.get("sl_pct"),
|
|
combo.get("tp_pct"),
|
|
),
|
|
flush=True,
|
|
)
|
|
|
|
ctx = prepare_momentum_search_context(
|
|
start,
|
|
end,
|
|
"tpe",
|
|
orderbook_filter="on",
|
|
market="KR",
|
|
)
|
|
if ctx is None:
|
|
print("PREPARE FAILED", flush=True)
|
|
return 1
|
|
|
|
print(
|
|
"ctx ready codes=%d ticks=%s ob_codes=%d fee=%s slot=%s max=%s budget=%s"
|
|
% (
|
|
len(ctx.codes_candles),
|
|
bool(ctx.ticks_by_code),
|
|
len(ctx.orderbook_by_code or {}),
|
|
ctx.fee_rate,
|
|
ctx.slot_money,
|
|
ctx.max_stocks,
|
|
ctx.total_budget_krw,
|
|
),
|
|
flush=True,
|
|
)
|
|
|
|
base = dict(ctx.base_fixed)
|
|
base["_orderbook_filter_enabled"] = True
|
|
base["ob_filter_enabled"] = True
|
|
|
|
grid_keys = list(payload.get("grid_keys") or [])
|
|
if not grid_keys:
|
|
grid_keys = [k for k in combo.keys() if not str(k).startswith("_")]
|
|
|
|
result = evaluate_momentum_param_combo(
|
|
combo,
|
|
base_fixed=base,
|
|
grid_keys=grid_keys,
|
|
codes_candles=ctx.codes_candles,
|
|
min_trades=0,
|
|
min_win_rate=0.0,
|
|
min_pf=0.0,
|
|
universe_by_slot=ctx.universe_by_slot,
|
|
slot_money=ctx.slot_money,
|
|
max_stocks=ctx.max_stocks,
|
|
total_budget_krw=ctx.total_budget_krw,
|
|
fee_rate=ctx.fee_rate,
|
|
sell_tax=ctx.sell_tax,
|
|
period_days=1,
|
|
cache_holder=ctx.cache_holder,
|
|
ticks_by_code=ctx.ticks_by_code,
|
|
orderbook_by_code=ctx.orderbook_by_code,
|
|
program_by_code=getattr(ctx, "program_by_code", None),
|
|
start_key="20260825",
|
|
end_key="20260825",
|
|
include_trades=True,
|
|
)
|
|
print("elapsed_sec", round(time.time() - t0, 1), flush=True)
|
|
if not result:
|
|
print("NO RESULT", flush=True)
|
|
return 2
|
|
|
|
trades = result.get("_trades") or result.get("trades") or []
|
|
out = {
|
|
"ok": True,
|
|
"date": start,
|
|
"source": "optuna trial#120 + prepare orderbook_filter=on",
|
|
"study": "momentum_tpe_20260818_20260821_20260823_192516",
|
|
"total_trades": result.get("total_trades"),
|
|
"win_rate": result.get("win_rate"),
|
|
"total_pnl": result.get("total_pnl"),
|
|
"pf": result.get("pf"),
|
|
"trades": trades,
|
|
}
|
|
print(
|
|
"RESULT trades=%s WR=%s PnL=%s PF=%s"
|
|
% (out["total_trades"], out["win_rate"], out["total_pnl"], out["pf"]),
|
|
flush=True,
|
|
)
|
|
for tr in trades:
|
|
code = str(tr.get("code") or "")
|
|
line = (
|
|
" %s->%s %s %s pnl=%s entry=%s exit=%s"
|
|
% (
|
|
tr.get("buy_time") or tr.get("entry_time"),
|
|
tr.get("sell_time") or tr.get("exit_time"),
|
|
code,
|
|
tr.get("sell_reason"),
|
|
tr.get("pnl"),
|
|
tr.get("entry_price") or tr.get("buy_price"),
|
|
tr.get("exit_price") or tr.get("sell_price"),
|
|
)
|
|
)
|
|
print(line, flush=True)
|
|
if code == "417010":
|
|
print(" *** NANOTEAM IN BACKTEST ***", flush=True)
|
|
|
|
out_json.write_text(json.dumps(out, ensure_ascii=False, indent=2, default=str))
|
|
print("JSON", out_json, flush=True)
|
|
print("DONE", flush=True)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|