2026/2/19 12:32:04
网站建设
项目流程
网站制作及实现,什么是网站风格策划的重点,wordpress 登入插件,乡镇门户网站建设免责声明#xff1a;本文基于个人学习经验整理#xff0c;仅供技术交流参考#xff0c;不构成投资建议。 一、前言
在期货量化这条路上#xff0c;我已经走了整整二十年。这些年踩过最多的坑#xff0c;就是参数优化。
很多人把回测曲线调得漂亮无比#xff0c;一到实盘…免责声明本文基于个人学习经验整理仅供技术交流参考不构成投资建议。一、前言在期货量化这条路上我已经走了整整二十年。这些年踩过最多的坑就是参数优化。很多人把回测曲线调得漂亮无比一到实盘就不行了。问题出在哪大多是过拟合——策略只是记住了历史数据而不是学会了市场规律。2026年了参数优化的方法论已经很成熟。今天这篇文章我来系统讲讲科学的参数优化方法。二、参数优化的常见误区误区1追求完美回测曲线年化100%、最大回撤3%、胜率90%——这种曲线99%是过拟合的结果。误区2参数越多越好参数越多过拟合风险越大。简单的策略往往更稳健。误区3只看最优参数只关注收益最高的参数组合忽视参数稳定性。误区4用全部数据优化没有留出样本外数据验证导致看着答案做题。三、科学的参数优化流程1. 数据分割 → 2. 参数搜索 → 3. 稳定性验证 → 4. 样本外测试 → 5. 滚动验证四、Step 1数据分割将数据分为三部分数据集占比用途训练集60%参数优化验证集20%参数筛选测试集20%最终验证代码示例fromtqsdkimportTqApi,TqAuth,TqBacktest,TqSimfromdatetimeimportdate# 数据分割# 训练集2023-01 到 2024-06 (18个月)# 验证集2024-07 到 2024-12 (6个月)# 测试集2025-01 到 2025-06 (6个月)TRAIN_STARTdate(2023,1,1)TRAIN_ENDdate(2024,6,30)VALID_STARTdate(2024,7,1)VALID_ENDdate(2024,12,31)TEST_STARTdate(2025,1,1)TEST_ENDdate(2025,6,30)五、Step 2参数搜索方法1网格搜索遍历所有参数组合importitertoolsfromtqsdkimportTqApi,TqAuth,TqBacktest,TqSimfromdatetimeimportdate# 参数网格param_grid{ma_fast:[5,10,15,20],ma_slow:[20,30,40,50,60],stop_loss:[0.01,0.02,0.03]}results[]# 网格搜索forma_fast,ma_slow,stop_lossinitertools.product(param_grid[ma_fast],param_grid[ma_slow],param_grid[stop_loss]):# 跳过无效组合ifma_fastma_slow:continue# 运行回测profitrun_backtest(ma_fast,ma_slow,stop_loss,TRAIN_START,TRAIN_END)results.append({ma_fast:ma_fast,ma_slow:ma_slow,stop_loss:stop_loss,profit:profit})# 按收益排序importpandasaspd df_resultspd.DataFrame(results)df_resultsdf_results.sort_values(profit,ascendingFalse)print(df_results.head(10))方法2随机搜索当参数空间很大时随机搜索效率更高importrandomdefrandom_search(n_iter100):results[]foriinrange(n_iter):# 随机采样参数params{ma_fast:random.randint(5,30),ma_slow:random.randint(20,100),stop_loss:random.uniform(0.01,0.05)}ifparams[ma_fast]params[ma_slow]:continueprofitrun_backtest(**params,start_dtTRAIN_START,end_dtTRAIN_END)results.append({**params,profit:profit})returnpd.DataFrame(results)六、Step 3参数稳定性验证好的参数应该是稳健的——参数小幅变化时策略表现不会剧烈波动。defcheck_param_stability(best_params,df_results):检查参数稳定性# 找到最优参数附近的参数组合nearbydf_results[(abs(df_results[ma_fast]-best_params[ma_fast])5)(abs(df_results[ma_slow]-best_params[ma_slow])10)]iflen(nearby)5:print(附近参数组合太少无法评估稳定性)returnFalse# 计算收益的标准差profit_stdnearby[profit].std()profit_meannearby[profit].mean()# 变异系数 0.5 认为稳定cvprofit_std/abs(profit_mean)ifprofit_mean!0elsefloat(inf)print(f参数稳定性评估:)print(f 附近参数组合数:{len(nearby)})print(f 收益均值:{profit_mean:.2%})print(f 收益标准差:{profit_std:.2%})print(f 变异系数:{cv:.2f})ifcv0.5:print( ✅ 参数稳定性良好)returnTrueelse:print( ❌ 参数稳定性较差可能存在过拟合风险)returnFalse七、Step 4样本外测试用验证集数据测试参数defvalidate_params(params,valid_start,valid_end):在验证集上测试参数# 在验证集上运行回测profitrun_backtest(**params,start_dtvalid_start,end_dtvalid_end)returnprofit# 测试Top 5参数组合top_paramsdf_results.head(5).to_dict(records)print(验证集测试结果:)fori,paramsinenumerate(top_params):train_profitparams[profit]valid_profitvalidate_params(params,VALID_START,VALID_END)# 计算衰减率decay(train_profit-valid_profit)/train_profitiftrain_profit0elsefloat(inf)print(f参数组合{i1}:)print(f 训练集收益:{train_profit:.2%})print(f 验证集收益:{valid_profit:.2%})print(f 衰减率:{decay:.2%})print()衰减率解读 30%参数泛化能力较好30%-50%可接受50%可能存在过拟合八、Step 5滚动验证更严格的验证方法——滚动窗口测试fromdatetimeimportdate,timedeltafromdateutil.relativedeltaimportrelativedeltadefrolling_validation(params,windows):滚动窗口验证results[]fortrain_start,train_end,test_start,test_endinwindows:# 训练这里只是验证不重新优化参数train_profitrun_backtest(**params,start_dttrain_start,end_dttrain_end)# 测试test_profitrun_backtest(**params,start_dttest_start,end_dttest_end)results.append({train_start:train_start,train_end:train_end,test_start:test_start,test_end:test_end,train_profit:train_profit,test_profit:test_profit})returnpd.DataFrame(results)# 定义滚动窗口windows[(date(2023,1,1),date(2023,12,31),date(2024,1,1),date(2024,6,30)),(date(2023,7,1),date(2024,6,30),date(2024,7,1),date(2024,12,31)),(date(2024,1,1),date(2024,12,31),date(2025,1,1),date(2025,6,30)),]# 运行滚动验证rolling_resultsrolling_validation(best_params,windows)print(rolling_results)# 计算测试集收益的稳定性test_profitsrolling_results[test_profit]print(f\n滚动验证汇总:)print(f 测试集收益均值:{test_profits.mean():.2%})print(f 测试集收益标准差:{test_profits.std():.2%})print(f 正收益比例:{(test_profits0).mean():.2%})九、完整优化流程代码fromtqsdkimportTqApi,TqAuth,TqBacktest,TqSimfromdatetimeimportdateimportpandasaspdimportnumpyasnpimportitertools# 配置 SYMBOLSHFE.rb2505TRAIN_STARTdate(2023,1,1)TRAIN_ENDdate(2024,6,30)VALID_STARTdate(2024,7,1)VALID_ENDdate(2024,12,31)TEST_STARTdate(2025,1,1)TEST_ENDdate(2025,6,30)# 回测函数 defrun_backtest(ma_fast,ma_slow,stop_loss,start_dt,end_dt):运行回测返回收益率apiTqApi(TqSim(init_balance100000),backtestTqBacktest(start_dtstart_dt,end_dtend_dt),authTqAuth(账户,密码))# ... 策略代码 ...final_balanceapi.get_account().balance api.close()return(final_balance-100000)/100000# 主流程 print(*50)print(Step 1: 参数网格搜索训练集)print(*50)param_grid{ma_fast:[5,10,15,20],ma_slow:[30,40,50,60],stop_loss:[0.02,0.03]}results[]forma_fast,ma_slow,stop_lossinitertools.product(*param_grid.values()):ifma_fastma_slow:continueprofitrun_backtest(ma_fast,ma_slow,stop_loss,TRAIN_START,TRAIN_END)results.append({ma_fast:ma_fast,ma_slow:ma_slow,stop_loss:stop_loss,profit:profit})df_resultspd.DataFrame(results).sort_values(profit,ascendingFalse)print(df_results.head(10))print(\n*50)print(Step 2: 参数稳定性验证)print(*50)best_paramsdf_results.iloc[0].to_dict()check_param_stability(best_params,df_results)print(\n*50)print(Step 3: 验证集测试)print(*50)valid_profitrun_backtest(best_params[ma_fast],best_params[ma_slow],best_params[stop_loss],VALID_START,VALID_END)print(f验证集收益:{valid_profit:.2%})print(\n*50)print(Step 4: 最终测试集验证)print(*50)test_profitrun_backtest(best_params[ma_fast],best_params[ma_slow],best_params[stop_loss],TEST_START,TEST_END)print(f测试集收益:{test_profit:.2%})print(\n*50)print(最终结果)print(*50)print(f最优参数:{best_params})print(f训练集收益:{best_params[profit]:.2%})print(f验证集收益:{valid_profit:.2%})print(f测试集收益:{test_profit:.2%})十、总结2026年期货策略参数优化的核心原则数据分割训练集、验证集、测试集分开参数稳定性选择稳健的参数而非最优的参数样本外验证必须在未见过的数据上测试滚动验证多时间段验证增加可信度保持简单参数越少越好希望这篇文章能帮助你科学地进行参数优化避免过拟合的陷阱声明本文基于个人学习经验整理仅供技术交流参考不构成任何投资建议。