Files
kis_bot/kis_trader/backtest/optuna_dart.py
Your Name 61bec4bd1d feat: Add DART strategy and related configurations
ㅇ
Changes:
- Introduced the DART strategy to the trading system, including its configuration and integration into the existing framework.
- Updated the database schema to include DART-specific tables for disclosures and watchlists.
- Enhanced the backtesting and parameter search functionalities to support the DART strategy.
- Implemented new rules for browser verification and API interactions to ensure compliance with the updated DART strategy.

Impact:
- These additions expand the trading capabilities of the system, allowing for more comprehensive analysis and execution of DART-related strategies, while maintaining system integrity and performance.
2026-07-21 07:50:24 +09:00

105 lines
3.0 KiB
Python

#!/usr/bin/env python3
"""kis_trader/backtest/optuna_dart.py — DART Optuna TPE."""
from __future__ import annotations
import logging
from datetime import datetime
from typing import Any, Dict, Optional
import optuna
from optuna.samplers import TPESampler
from database import TradeDB
from kis_trader.backtest.optuna_common import (
announce_optuna_json_path,
resolve_optuna_storage_url,
)
from kis_trader.backtest.param_search_dart import (
_dart_grids,
apply_params_to_db,
evaluate_dart_param_combo,
)
from kis_trader.engine import dart_engine as de
logger = logging.getLogger("param_search_optuna")
_FAIL = -1e18
def prepare_dart_search_context(start: str, end: str, mode: str) -> Optional[Dict[str, Any]]:
grids = _dart_grids()
if mode not in grids:
logger.error("DART mode: %s (fast/coarse/fine)", mode)
return None
db = TradeDB()
try:
env_row = db.get_merged_env_snapshot() or {}
finally:
db.close()
return {
"start": start,
"end": end,
"mode": mode,
"grid": grids[mode],
"env_row": env_row,
"base": de.get_dart_defaults_from_db(env_row=env_row),
}
def run_dart_optuna(
ctx: Dict[str, Any],
*,
n_trials: int,
storage_url: Optional[str] = None,
study_name: Optional[str] = None,
min_trades: int = 1,
sampler_name: str = "tpe",
seed: int = 42,
show_progress: bool = False,
**_kwargs: Any,
) -> optuna.Study:
grid: Dict[str, Any] = ctx["grid"]
storage = storage_url or resolve_optuna_storage_url()
name = study_name or "dart_%s_%s" % (
ctx["mode"], datetime.now().strftime("%Y%m%d_%H%M%S"),
)
sampler = TPESampler(seed=seed) if sampler_name != "random" else optuna.samplers.RandomSampler(seed=seed)
study = optuna.create_study(
study_name=name,
storage=storage,
direction="maximize",
sampler=sampler,
load_if_exists=True,
)
def objective(trial: optuna.Trial) -> float:
params = dict(ctx["base"])
for axis, values in grid.items():
params[axis] = trial.suggest_categorical(axis, list(values))
res = evaluate_dart_param_combo(
params, start=ctx["start"], end=ctx["end"], env_row=ctx["env_row"],
)
n = int(res.get("trade_count") or 0)
pnl = float(res.get("total_pnl") or 0)
trial.set_user_attr("trade_count", n)
trial.set_user_attr("total_pnl", pnl)
trial.set_user_attr("win_rate", float(res.get("win_rate") or 0))
if n < min_trades:
return _FAIL
return pnl
study.optimize(objective, n_trials=n_trials, show_progress_bar=show_progress)
announce_optuna_json_path("dart", study)
return study
def apply_best_dart_trial(study: optuna.Study) -> bool:
try:
best = study.best_trial
except Exception:
return False
if float(best.value or _FAIL) <= 0:
logger.warning("DART best PnL<=0 — DB 미적용")
return False
apply_params_to_db(dict(best.params))
return True