如何不陷入优化陷阱?
开发交易系统时一点不考虑优化那就好了.
然而在现实中, 开发一个可以获利的交易策略
是一个尝试并改错的过程, 其中一定形式的优化总是需要的.
某些地方总是有优化, 如果桌面上看不到, 那它就埋藏在阴影中.
J. Katz, D. Mccormick. 交易策略百科全书.
什么是交易系统的优化?
创建一个交易系统, 首先包含了整理如何建立关闭买入卖出仓位的规则. 这些规则通常包含一些指标和参数. 如果它们改变了, 交易系统的盈利能力也会改变. 这个问题是经常遇到的: 是否有必要优化交易系统或者它只是使系统和历史数据更符合吗?
这也许主要因为人们对"交易系统的优化"过程有不同的看法. 所以让我们首先定义什么是优化.首先, 我们应该明白, 通过"优化"交易系统的选择和创建将能使它与其它系统相比更好解决我们的问题. 例如, 我们正在寻找这样一个系统, 它可以在目前的日元/美元货币对上获得最大的利润. 为此, 我们会选择从一些不同系统中固定参数得到一个系统. 这可能是根据系统使用的不同指标来选择的. 让我们称此为"第一类优化".
第二, 我们应该明白, 通过"优化"所选交易系统的这些参数将可以使我们得到最好的结果. 这可能是通过选择计算平均的周期数或者计算随机振荡结构的周期数. 让我们称之为"第二类优化".
我想没有人会怀疑, 交易者创建交易策略时会明确地或者隐含地使用这两种优化. 确实, 一旦我们选择运行了一个交易系统, 我们就会假定我们在使用所拥有的最好的交易系统. 也就是说, 我们使用了第一类优化. 然而, 因为任何系统都有一些参数, 我们会尝试寻找这些参数的数值以得到最好的结果. 这明显是第二类优化. 另外, 当创建一个交易系统时是不可能把这两类优化分开的. 这就是为什么对于在创建交易系统时是否使用优化这个问题的答案非常清楚: 必须使用优化. 另外一件事就是怎样做. 在创建一个交易系统时有几个步骤:- 产生构成交易系统的想法;
- 选择标准或者决定规则;
- 定义系统的参数;
- 测试系统; 以及
- 如果需要做系统修改就回到前面的部分.
第二类优化的问题
当创建一个自动交易系统时, 所有的开发者都会同时使用第一类和第二类优化. 搜索标准与决定规则是启发式系统的任务, 例如神经网络, 遗传算法, 当然还有人的大脑 - 当今功能最强大的系统. 这是第一类优化, 所以是由交易者全部负责此类优化的.第二类优化是搜索最佳参数. 就是在这里会发生问题, 因为很容易使数据与历史相符并获取了"巨量利润". 不幸的是, 这只在历史上有效. 此类"过度优化" 可能难以避免, 所以一些交易者开始感到消极的态度了. 为什么呢?
怎样才能解决过度优化问题?
我们应该怎么做呢?我们不能忽略优化, 因为那样我们可能会找到错误参数而失去会失去最好的方案或者一个潜在的获利策略. 然而, 过度优化也会产生严重的问题. 我们必须找到最佳方案.让我们使用数学进行优化. 一般情况下, 当有较多参数需要优化时, 我们要找到一个超平面, 其中利润相对稳定, 在参数有稍许改动时利润多少改变接近. 在优化中, 我们要尝试找到这样的方案: 利润是最高的, 而且离最佳方案的参数有小的偏移时不会引起利润的大幅波动.
不幸的是, MetaTrader 里面还没有内建的算法用于自己搜索最优方案. KRAB 是解决此类问题的最强大的算法之一. 它在N.Zagoruko的书籍中有描述: 数据与知识分析的应用方法(Applied Methods of Data and Knowledge Anaysis). 新西伯利亚:数学学院出版社,1999 (俄文版). 如果下面的版本能够实现就太好了 - 但是现在也不错!
MetaTrader 可以为一个或者两个将要优化的参数创建优化图. 这意思是把优化结果投射到一个平面上, 我们就可以找到最优方案. 换句话说, 两个两个地优化参数我们就能够得到最佳的方案范围.对于三个参数, 我们必须重复此过程
然而, 对于5个参数, 这将是
当优化两个参数时, 我们获得了如下的优化图:
下面的图就不是那么清楚了: 我们可以看到在这张图上有两个区域有极值点. 我们应该选择哪一个呢?
有经验的眼睛将会注意到右下角的方案区域, 因为此区域周围利润的减少比图上开始阶段的要少. 所以我建议您仔细分析优化图以节约保护您的存款.
让我们开始学习一个简单的EA交易 - 分析三个参数并找到最优方案范围. EA 交易的名称是 SP. 它运行于市场分析到超买/超卖的时刻.
//+------------------------------------------------------------------+ //| SP.mq4 | //| Copyright © 2006, MetaQuotes Software Corp. | //| https://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "Copyright © 2006, MetaQuotes Software Corp." #property link "https://www.metaquotes.net" //---- 输入参数 extern int TakeProfit=50; extern int StopLoss=30; extern int RsiLen=4; extern int KLen=8; extern int Momlength=10; extern int Lots=1; extern int rsi_oversold=39; extern int stoc_oversold=29; extern int rsi_overbought=60; extern int stoc_overbought=70; extern int Mom_Sell=-2; extern int Mom_Buy=2; int expertBars; double RSIlevel; double Stoclevel; double MomLevel; double DLen=3; //+------------------------------------------------------------------+ //| 如果是到来的新柱返回true, 否则返回false | //+------------------------------------------------------------------+ bool isNewBar() { //---- bool res=false; if (expertBars!=Bars) { expertBars=Bars; res=true; } //---- return(res); } //+------------------------------------------------------------------+ //| EA 初始化函数 | //+------------------------------------------------------------------+ int init() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| EA 终止化函数 | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| EA 起始处理函数 | //+------------------------------------------------------------------+ int start() { double price; double stop; double profit; //---- if ((isNewBar())&& (OrdersTotal()==0)&& (AccountBalance()>5000)) { RSIlevel=iRSI(NULL,0,RsiLen,PRICE_CLOSE,0); Stoclevel=iStochastic(NULL,0,KLen,DLen,3,MODE_SMA,0,MODE_MAIN,0); MomLevel=100 - iMomentum(NULL,0,Momlength,PRICE_CLOSE,0); /*if (AccountBalance()>50000) {Lots=NormalizeDouble( AccountBalance()/10000,0)-4;} else Lots=1;*/ if ((RSIlevelrsi_oversold)&&(Stoclevelstoc_oversold)&&(MomLevel>Mom_Sell)) { price=Ask; stop=NormalizeDouble(price-StopLoss*Point,Digits); profit=NormalizeDouble(price+TakeProfit*Point,Digits); OrderSend(Symbol(),OP_BUY,Lots,price,3,stop,profit,NULL,0,0,Green); //Print(AccountBalance()); } if ((RSIlevel>rsi_overbought)&&(Stoclevel>stoc_overbought)&&(MomLevelMom_Buy)) { price=Bid; stop=NormalizeDouble(price+StopLoss*Point,Digits); profit=NormalizeDouble(price-TakeProfit*Point,Digits); OrderSend(Symbol(),OP_SELL,Lots,price,3,stop,profit,NULL,0,0,Green); //Print(AccountBalance()); } } //---- return(0); } //+------------------------------------------------------------------+
我们优化三个参数 – Stochastic 和 RSI 的周期数以及止损水平.
RSI和止损水平的依赖.
最佳区域为:
- 图 1 – (4;5)&(3;6);
- 图 2 – (80;90)&(3;6);
- 图 3 – (80;90)&(4;5).
把它们结合, 就得到最佳方案 – (5,4,80).
应该注意到, 止损在优化时的步长大一些, 是10. 如果有必要, 也可以使用更小的步长来获得方案.结论
这当然很好, 单元绿色饱和的程度使我们能够评估区域获利的能力. 但是, 如果亏损部分可以用红色表示就更好了. 这将使我们在绝对另外一个层次来评估策略. 实际上, 我们取得了优化的全三维图!最后, 一些针对优化的建议:
- 用于优化的数据样本必须有代表性. 对于日图时间框架, 必须超过3年.
- 在优化样本之外测试您的策略 - 这将允许您评估选择的参数.
- 不要同时优化过多参数 - 也许这样它们符合历史的程度太高了.
- 增加步长以减少优化时间. 最佳区域不会被忽略. 得到的区域簇可以晚些时候更加详细地分析(筛选技术).
- 不要花太多时间在优化上 - 您最好使EA交易的算法现代化.
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/1434