""" Sprint 3 验证脚本 — Optuna 参数优化。 用法: python cli/demo_optimizer.py python cli/demo_optimizer.py --ts_code 600519.SH --trials 100 """ import sys, os, argparse sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from data.data_manager import DataManager from factors.engine import FactorEngine from factors.registry import get_factor from backtest.vectorbt.engine import VectorBTEngine from backtest.strategies.rsi_mean_revert import RSIMeanRevertStrategy from optimizer.engine import OptunaEngine from optimizer.space import rsi_revert_space def main(): p = argparse.ArgumentParser(description="Sprint 3 — Optuna 参数优化验证") p.add_argument("--ts_code", default="000001.SZ", help="测试股票代码") p.add_argument("--trials", type=int, default=200, help="试验次数(默认: 200)") args = p.parse_args() print("=" * 60) print("Sprint 3 — Optuna 参数优化验证") print("=" * 60) print("\n[1/4] 初始化...") dm = DataManager(); dm.init_db() engine_fe = FactorEngine(dm) bt_engine = VectorBTEngine() opt_engine = OptunaEngine(bt_engine) price_df = dm.get_daily(args.ts_code).set_index("trade_date").sort_index() factor_df = engine_fe.compute(args.ts_code, [get_factor("rsi_14")]) print(" 数据: {} 条日线, {} 个因子".format(len(price_df), factor_df.shape[1])) print("[OK]") print("\n[2/4] RSI 反转策略参数寻优 (sharpe, {} trials)...".format(args.trials)) result = opt_engine.optimize( strategy_class=RSIMeanRevertStrategy, search_space=rsi_revert_space, price_df=price_df, factor_df=factor_df, metric="sharpe", n_trials=args.trials, ) print(result.summary()) if result.param_importance: print(" 参数重要性:") for k, v in sorted(result.param_importance.items(), key=lambda x: -x[1]): print(" {}: {:.4f}".format(k, v)) print("\n[3/4] 默认参数 vs 最优参数 对比...") strategies_compare = [ ("默认(30/70)", RSIMeanRevertStrategy(oversold=30, overbought=70)), ("最优", RSIMeanRevertStrategy(**result.best_params)), ] reports = {} for name, s in strategies_compare: reports[name] = bt_engine.run(s, price_df, factor_df) metrics = [("总收益(%)", "total_return"), ("年化CAGR(%)", "cagr"), ("最大回撤(%)", "max_drawdown"), ("夏普比率", "sharpe_ratio"), ("卡玛比率", "calmar_ratio"), ("胜率(%)", "win_rate"), ("盈利因子", "profit_factor"), ("交易笔数", "total_trades")] print(" {:<18s} {:>12s} {:>12s}".format("指标", "默认(30/70)", "最优")) print(" " + "-" * 42) for label, attr in metrics: vals = [] for r in reports.values(): v = getattr(r, attr) vals.append("{:.2f}".format(v) if isinstance(v, float) else str(v)) print(" {:<18s} {:>12s} {:>12s}".format(label, vals[0], vals[1])) print("\n[4/4] Walk-Forward 滚动窗口验证...") try: wf = opt_engine.optimize_walk_forward( RSIMeanRevertStrategy, rsi_revert_space, price_df, factor_df, metric="sharpe", n_trials=min(80, args.trials), train_window=252 * 3, test_window=252, ) print(wf.summary()) except Exception as e: print(" [SKIP] Walk-Forward 异常: {}".format(e)) # 存入 DB try: from reports.storage import save_report from datetime import datetime lines = ["## 参数优化 — {}".format(args.ts_code), result.summary(), "", "### 默认 vs 最优对比"] save_report("\n".join(lines), "参数优化", subject_type="stock", subject_code=args.ts_code) print("\n 报告已存入 DB") except Exception as e: print("\n [WARN] 报告入库失败: {}".format(e)) print("\n" + "=" * 60) print("Sprint 3 验证完成") print("=" * 60) if __name__ == "__main__": main()