外汇EA编写教程:为EA事务优化创建自定义标准

简介

MetaTrader 5客户提供各种机会来优化EA交易的参数。除了包含在策略测试程序中的优化标准之外,开发人员还有机会创建自己的标准。这样,测试和优化EA事务的可能性是无限的。本文介绍了一种既适用于复杂标准又适用于简单标准的实用标准生成方法。

1。政策测试计划
的功能审查

由于这个话题已经讨论了很多次,我只想列出相关的文章,并对它们作一个简要的介绍。建议您在阅读本文之前熟悉以下信息。

  • “MetaTrader 5中的测试原则”。本部分详细阐述了EA交易测试的所有技术细节,包括数据生成模式、开盘价和M1栏的处理。它还描述了测试期间指标的使用、环境变量的模拟和标准事件的处理。此外,本部分还介绍了多货币测试的基本知识。
  • “使用MQL5测试和优化EA交易指南”。本部分包括EA事务输入参数的测试和优化。介绍了参数拟合的过程、试验结果的解释和最佳参数的选择。
  • “使用testerretraction()函数模拟利润提取”。本节介绍了如何使用测试人员提取函数从政策测试程序中的账户中建立提取模型,以及该函数如何影响政策测试程序中净资产损失的算法。

当然,首先,您需要熟悉客户提供的说明。

2。策略测试程序中的嵌入式优化标准

如果您查看文档,您会发现以下说明:优化标准是一个系数,其值决定测试参数集的质量。优化准则的值越高,对给定参数集的测试结果就越好。

这里需要注意的一点是,优化标准只能用于优化的遗传算法模式。显然,当您仔细检查所有可能的参数值组合时,您会发现不可能通过任何因素来选择EA事务的最佳参数。另一方面,我们可以保存测试结果并对其进行处理,以确定最佳参数组合。

如说明所述,政策测试程序包含以下遗传算法使用的优化标准:

  • 天平最大值(最大天平)——最大天平;
  • 余额+最大利润系数(余额+最大利润系数)-余额与利润系数乘积的最大值;
  • 余额+最大预期收益(余额+最大预期收益)-余额与预期收益的乘积;
  • 余额+最小支取(余额+最小损失)-在这种情况下,考虑余额值和损失水平:(100%损失水平)x余额;
  • 平衡+最大回收系数(平衡+最大回收系数)-平衡和回收系数的乘积;
  • 平衡+最大夏普比率(平衡+最大夏普比率)-平衡与夏普比率的乘积;
  • 自定义最大值-自定义优化条件。这里的优化标准是EA事务中ontester()函数的值。此参数允许使用任何自定义值来优化EA事务。

如图1所示,您可以从策略测试仪的设置(设置)选项卡中选择优化条件:

选择 EA 交易的优化标准

图1。优化选择EA事务的标准

定制Max,列表中的最后一个标准,是我们最感兴趣的。本标准适用于本文的主题。

三。创建自定义优化标准

首先要做的是向用户展示是否可以实现参数的自由组合(不限于图1所示的组合,而是自定义组合);这些参数在每个EA事务完成后由策略测试程序计算。

例如,以下组合很有趣:余额最大值+最小提取值+交易数(最大余额+最小损失+交易数)-交易越多,结果越可靠。或以下一个-余额最大值+最小提取值+最大利润系数(最大余额+最小损失+最大利润系数)。当然,还有许多其他有趣的组合没有包含在策略测试程序设置中。

让我们把这种标准组合称为简单的优化标准。

但单凭这些标准无法对交易系统做出可靠的估计。从“风险最低的利润”的角度出发,我们可以假设以下条件:我们可以优化参数,得到最平滑的均衡曲线,其个别交易结果偏离直线最小。

我们把这个标准称为根据平衡曲线进行优化的标准。

我们需要使用的下一个优化标准是交易系统的安全系数。这一系数在“和谐一致”一文中作了介绍。它描述了交易系统与市场的对应关系,在参数优化时需要确定。让我们称之为优化交易系统(CST)安全系数的标准。

此外,我们可以自由组合所描述的标准。

4。ontester()函数

在编写代码部分之前,让我们先看看如何在策略测试程序中组织自定义EA优化标准。

预定义的函数ontester()用于创建自定义优化条件。在每个EA事务测试结束时,在指定的时间段内自动调用此函数。OnDeInit()函数在调用之前被调用。

同样,要使用ontester()函数,应该启用快速遗传基算法(fast genetic algorithms)的优化模式,如图1所示。

函数有一个双精度返回值,用于在策略测试程序中进行优化。

请重新阅读说明:

在遗传优化中,用降序表示一代内的结果,即从优化准则的角度看,最优结果是最大值的结果。在这种情况下,最坏的值是在最后被丢弃的,并且不参与下一代的生成过程。

因此,在创建自定义优化标准时,我们需要获得一个完整的值,该值将用于估计EA事务。价值越大,EA事务就越好。

5。编写测试EA事务

现在,是时候编写一个将在策略测试程序中优化的EA事务了。在这种情况下,对事务的主要要求是简单和快速,并且不需要太多时间来处理优化的例程过程。当然,也希望EA交易不会完全无利可图。

让我们使用以“几种查找MQL5趋势的方法”介绍的EA事务作为试点交易过程,并对其进行改进。显然,EA交易基于三个移动平均值的“部门”。改进包括消除使用度量来加速操作,以及在EA事务中删除代码的计算部分。这使得测试速度显著增加(在两年的时间间隔内几乎增加了三倍)。

设置输入参数的部分相对简单:

input double Lots = 0.1; 
input int  MA1Period = 200; // period of the greatest moving average
input int  MA2Period = 50;  // period of the medium moving average
input int  MA3Period = 21;  // period of the smallest moving average

移动平均周期是我们想要优化的周期。

上面的文章详细介绍了EA事务的结构和操作,因此我们在这里不提它。主要的创新是ontester()函数,这是测试完成时的另一个事件处理程序。目前,函数为空,返回控制。

//---------------------------------------------------------------------
//  The handler of the event of completion of another test pass:
//---------------------------------------------------------------------
double OnTester()
{
  return(0.0);
}

本文附带了EA事务文件fanexpert。MQ5。从交易执行的角度,我们可以确认它与Fantrend专家的一致性。MQ5 EA事务。在图表上创建新列时,检查信号是否存在以及信号的方向。

为了获得每次运行时计算的测试结果,使用testerstatistics()函数;它返回作为测试结果计算的请求统计信息。只能从ontester()和ondinit()函数调用它,否则结果将未定义。

现在,让我们添加一个自定义优化标准。假设我们需要根据最大回收系数来确定最佳结果。为此,我们需要知道余额的最大损失和测试结束时的毛利。恢复系数是通过利润除以最大亏损额来计算的。

这只是作为一个例子,因为恢复系数包含在计算的测试统计信息列表中。

为此,请将以下简单代码添加到ontester()函数中:

//---------------------------------------------------------------------
//  The handler of the event of completion of another test pass:
//---------------------------------------------------------------------
double OnTester()
{
  double  profit = TesterStatistics(STAT_PROFIT);
  double  max_dd = TesterStatistics(STAT_BALANCE_DD);
  double  rec_factor = profit/max_dd;

  return(rec_factor);
}

为了简单起见,代码中没有除数零检查。由于最大损失可能等于零,因此必须在实际的EA事务中进行检查。

现在让我们创建上面的条件:最大余额+最小损失+交易数量-余额+最小损失+交易数量。

要执行此操作,请按如下方式更改ontester()函数:

double OnTester()
{
  double  param = 0.0;

//  Balance max + min Drawdown + Trades Number:
  double  balance = TesterStatistics(STAT_PROFIT);
  double  min_dd = TesterStatistics(STAT_BALANCE_DD);
  if(min_dd > 0.0)
  {
    min_dd = 1.0 / min_dd;
  }
  double  trades_number = TesterStatistics(STAT_TRADES);
  param = balance * min_dd * trades_number;

  return(param);
}

这里你可以用一个与损失相反的值,因为假设在相同的其他条件下,损失越小,情况越好。FanExpert EA事务根据创建的优化标准进行优化。MA1Period参数使用2009.06.01到2011.06.03的时间范围和1个计划。将移动平均值的范围设置为100-2000。

在优化结束时,您将获得以下按最佳参数排序的值列表:

按最大余额 + 最小亏损 + 交易次数标准进行优化的最佳结果

图2。基于最大余额+最小损失+交易数量标准的最佳结果

它列出了最佳参数(按结果列排序)。

现在让我们看看最坏的参数:

图3。根据最大余额+最小损失+交易次数准则优化的最差参数

通过比较这两个表,我们可以看到既考虑了亏损,也考虑了利润,以及交易数量。也就是说,我们的优化标准正在发挥作用。此外,我们还可以看到优化图(线性):

优化图

图4。基于最大余额+最小损失+交易数量的优化图表

横轴显示优化参数,纵轴显示优化标准。我们可以清楚地看到最大设定标准,它在980到1200的时间范围内。

你应该明白这是一个参数的遗传优化,而不是一个完整的搜索。这就是为什么图2和图3中的表格包含了经过几代自然选择的最“可行”参数。也许有些成功的设想已经被放弃了。

1106个周期的余额/净资产曲线如下:

针对 MA1Period = 1106 个周期的余额/资产净值曲线

图5。MA1周期=1106周期的平衡/导航曲线

6。使用自定义优化条件创建

通过这种方式,我们学习了如何创建和使用简单的优化标准。现在让我们创建一个类来简化它在EA事务中的使用。除了使用方便之外,这种类型的主要要求之一是速度。优化准则的计算必须快速进行,否则要花很长时间才能得到结果。

MetaTrader 5允许使用云计算进行优化。这是一个重大突破,因为处理大量参数需要强大的计算能力。因此,为了开发类,我们打算使用最简单和最快的解决方案,即使从编程的角度来看它还不够好。

出于开发目的,我们打算使用客户机提供的标准数据组织类。

首先,让我们对计算出的测试统计数据进行分类:

  • 测试结果与浮点型和整数型的优化准则成正比。

换句话说,测试结果的值越大,优化标准的值越好,同时,值越大。测试结束时的毛利人统计利润就是此类测试结果的典型例子。它的值是一个浮点类型,范围从负无穷大(实际上仅限于预付款的值)到正无穷大。

交易数量统计交易是此类测试结果的另一个例子。一般来说,事务越多,优化结果越可靠。它的值是一个整数类型,范围从零到无穷大。

  • 测试结果的值与优化标准的浮点和整数类型成反比。

换句话说,测试结果的值越小,优化标准的值越好,同时,值越大。平衡状态的最大损失和任何其他损失都是此类测试结果的例子。

为了得到这样的测试结果,我们打算使用反向值来计算优化准则的值。当然,为了避免相应的错误,我们需要将零分开。

为自定义优化标准tcustomriterion创建基类非常简单。其目的是确定基本功能。其外观如下:

class TCustomCriterion : public CObject
{
protected:
  int     criterion_level;        // type of criterion

public:
  int   GetCriterionLevel();
  virtual double  GetCriterion();  // get value of the result of optimization
};

应在继承的类中重写虚拟方法tcustomriterion::getcriterion。这是在每个测试EA事务结束时返回完整测试结果值的主要方法。

tcustomriterion::criterian_级别的类成员用于存储此类实例中固有的自定义条件类型。它将进一步用于根据对象的类型来区分对象。

现在,我们可以从这个类的成员继承优化所需的所有类。

tsimpleCriterian类用于创建与指定的测试统计信息对应的“简单”自定义标准。其定义如下:

class TSimpleCriterion : public TCustomCriterion
{
protected:
  ENUM_STATISTICS  stat_param_type;

public:
  ENUM_STATISTICS  GetCriterionType();     // get type of optimized stat. parameter

public:
  virtual double   GetCriterion();           // receive optimization result value
  TSimpleCriterion(ENUM_STATISTICS _stat); // constructor
};

这里我们使用带参数的构造函数,其实现如下:

//---------------------------------------------------------------------
//  Constructor:
//---------------------------------------------------------------------
TSimpleCriterion::TSimpleCriterion(ENUM_STATISTICS _stat)
:
stat_param_type( _stat )
{
  criterion_level = 0;
}

在MQL5中,这个新函数在创建类实例时很容易使用。我们还将重写虚拟方法tsimpleCriterian::getCriterian,它用于在每次测试通过时获得优化结果。它的实现非常简单:

//---------------------------------------------------------------------
//  Get the result of optimization:
//---------------------------------------------------------------------
double  TSimpleCriterion::GetCriterion()
{
  return(TesterStatistics(stat_param_type));
}

如您所见,此方法只返回相应的测试统计信息。

使用tsimpleDivCriteria类创建另一个“简单”自定义优化标准。用于测试与优化准则成反比的结果值。

tsimpleDivCriteria::getCriterian方法如下:

//---------------------------------------------------------------------
//  Get value of the optimization result:
//---------------------------------------------------------------------
double  TSimpleDivCriterion::GetCriterion()
{
  double  temp = TesterStatistics(stat_param_type);
  if(temp>0.0)
  {
    return(1.0/temp);
  }
  return(0.0);
}

此代码不需要任何其他解释。

使用tsimpleMinCriteria和tsimpleMaxCriteria类创建其他两种类型的“简单”自定义优化标准。它们分别用于创建具有测试统计的上限和下限的标准。

如果您在优化过程中故意放弃错误的参数值,它们可能会很有用。例如,您可以限制最小事务数、最大损失等。

tsimpleMinCriteria类描述如下:

class TSimpleMinCriterion : public TSimpleCriterion
{
  double  min_stat_param;

public:
  virtual double  GetCriterion();    // receive optimization result value
  TSimpleMinCriterion(ENUM_STATISTICS _stat, double _min);
};

这里我们使用一个带有两个参数的构造函数。参数_min用于设置测试统计的最小值。如果另一个测试的结果值小于指定值,则放弃该结果。

方法tsimpleMinCriterian::getCriterian的实现如下:

//---------------------------------------------------------------------
//  Get value of the optimization result:
//---------------------------------------------------------------------
double  TSimpleMinCriterion::GetCriterion()
{
  double  temp = TesterStatistics(stat_param_type);
  if(temp<this.min_stat_param)
  {
    return(-1.0);
  }
  return(temp);
}

tsimpleMaxCriteria类的创建类似,无需进一步解释。简单自定义标准的其他类的创建与上述类类似,这些类位于自定义优化中。本文附带的MQH文件。同样的原理也可以用于开发优化中使用的任何其他类。

在使用上述类之前,我们先创建一个容器类,以便更轻松地处理标准设置。为此,我们还使用标准的数据组织类。因为我们需要一个简单的标准跟进,最适合的课程是carrayobj。此类允许组织从cobject类继承的动态对象数组。

容器类tcustomriterion数组的描述非常简单:

class TCustomCriterionArray : public CArrayObj
{
public:
  virtual double  GetCriterion( );  // get value of the optimization result
};

此类中只有一个方法—tcustomriterion array::getcriterion,它在每个测试结束时返回优化条件的值。具体实施如下:

double  TCustomCriterionArray::GetCriterion()
{
  double  temp = 1.0;
  int     count = this.Total();
  if(count == 0)
  {
    return(0.0);
  }
  for(int i=0; i<count; i++)
  {
    temp *= ((TCustomCriterion*)(this.At(i))).GetCriterion();
    if(temp <= 0.0)
    {
      return(temp);
    }
  }

  return(temp);
}

您应该注意以下几点:如果在标准处理过程中遇到负值,则进一步运行该循环毫无意义。此外,它排除了两个负值相乘以获得正值的情况。

7。使用自定义优化条件的类

这样,我们就拥有了在EA事务优化期间使用“简单”自定义标准所需的一切。让我们分析一下改进“实验性”EA FanExpert:
的步骤顺序。

  • 添加包含自定义标准类说明的包含文件:
#include <CustomOptimisation.mqh>
  • 向使用自定义标准的容器类对象添加指针:
TCustomCriterionArray*  criterion_Ptr;
  • 使用自定义标准初始化指向容器类对象的指针:
  criterion_array = new TCustomCriterionArray();
  if(CheckPointer(criterion_array) == POINTER_INVALID)
  {
    return(-1);
  }

此过程在OnInit函数中完成。如果未成功创建对象,则返回负值。在这种情况下,EA事务将停止运行。

  • 向EA事务添加所需的优化标准:
  criterion_Ptr.Add(new TSimpleCriterion(STAT_PROFIT));
  criterion_Ptr.Add(new TSimpleDivCriterion(STAT_BALANCE_DD));
  criterion_Ptr.Add(new TSimpleMinCriterion(STAT_TRADES, 20.0));

在这个例子中,我们决定通过最大化利润、最小化损失和最大化交易数量来优化EA交易。此外,我们放弃了导致少于20个事务的EA事务的外部参数集。

  • 向ontester函数添加相应的调用:
  return(criterion_Ptr.GetCriterion());
  • 在ondeinit函数中,添加代码以删除容器对象:
  if(CheckPointer(criterion_Ptr) == POINTER_DYNAMIC)
  {
    delete(criterion_Ptr);
  }

这都是为了优化。操作优化,确保一切按预期进行。为此,在策略测试程序的设置选项卡中设置参数,如下图所示:

策略测试程序的设置

图6。策略测试程序设置

图7显示了策略测试程序的输入参数(输入参数)选项卡中输入参数优化范围的设置:

优化后的输入参数

图7。优化输入参数

使用“云”代理进行优化。为此,请在“代理”选项卡上设置以下参数:

测试代理的参数

图8。测试代理的参数

现在单击Start按钮(参见图6)并等待优化完成。当使用云计算技术时,优化将很快完成。最后,我们根据指定的标准得到优化结果:

优化结果

图9。优化结果

我们的“试点”EA交易已成功优化。使用“云”代理进行优化需要13分钟。粉丝体验样品。本文附带的MQ5文件包含用于检查标准的EA事务。

8。根据平衡曲线的分析结果,建立一个自定义的优化标准

此类是在“控制EA事务操作期间的平衡曲线斜率”一文的基础上创建的。该优化准则的目的是最大限度地将平衡曲线近似为直线。根据交易结果和直线的标准方差估计直线的接近程度。计算回归线的线性方程,根据策略测试程序中的交易结果绘制回归线。

为了放弃负余额曲线,还设置了其他限制,即利润必须大于规定值,交易次数必须小于规定值。

因此,考虑到利润限额和交易数量,优化标准将与交易结果与直线之间的标准方差成反比。

为了根据平衡曲线来实现优化准则,我们需要使用上面提到的TbalanceSlope类。我们将把它改为使用带参数的构造函数(为了方便起见),并添加标准方差的计算来计算线性回归。平衡斜坡。本文附带的MQH文件包含此代码。

向EA事务添加优化标准的步骤与上述步骤相同。现在,优化标准如下:

criterion_Ptr.Add(new TBalanceSlopeCriterion(Symbol( ), 10000.0));

除了平衡曲线标准外,我们还可以添加其他标准。对于读者来说,我留下了用不同的统计参数集进行测试的可能性。

让我们根据设定的标准进行优化。为了获得更多的交易时间,请使用h4时间表、2010.01.01-2011.01.01区间和欧元兑美元交易品种进行优化。我们将得到一组结果:

选择 EA 交易的优化标准0

图10。根据平衡曲线优化结果

现在,我们需要估计优化的质量。我认为主要的标准是EA事务在最佳范围之外的性能。为了检查这类操作,在2010.01.01至2011.06.14期间进行了一次测试。

通过比较两个最优参数集(其收益几乎相同)的结果,我们发现最佳结果是中间部分的结果。在优化间隔之外,结果用红线区分:

选择 EA 交易的优化标准1

图11。最佳结果

总的来说,曲线的性能没有恶化。盈利能力略有下降,从1.60降至1.56。

选择 EA 交易的优化标准2

图12。中间优化结果

在最佳范围之外,EA交易没有盈利。盈利能力从2.17大幅下降至1.75。

因此,我们可以得出以下结论:假设平衡曲线与优化参数持续时间之间存在相关性是合理的。当然,我们不能排除以下特殊情况,即使使用本标准的可接受结果对于EA事务是不可能实现的。在这种情况下,我们需要做更多的分析和实验。

也许,对于这个标准,我们需要使用最大可能(但合理)的范围。连接的风扇平衡。MQ5文件包含用于检查标准的EA事务。

9。根据交易系统安全系数(CSTS)创建定制优化标准

如“一致性”一文所述,使用以下公式计算交易系统的安全系数(CST):

CSTS = Avg.Win / Avg.Loss ((110% – %Win) / (%Win-10%) + 1)

其中:

  • 平均赢-平均赢-平均赢-平均赢-平均赢-平均赢-平均赢-平均赢-平均赢-平均赢-平均赢-平均赢-A
  • 平均损失-损失交易的平均值;
  • %win——盈利交易的百分比;

如果CSTS值小于1,则交易系统位于高风险交易区;即使较小的值也表明其位于非盈利交易区。CST的价值越大,交易系统就越适合市场,利润也就越高。

在策略测试程序中,计算CST所需的所有统计数据都是在每次测试通过后计算出来的。现在,我们需要创建一个从tcustomriterion继承的ttssfcriterion类,并在其中实现getcriterion()方法。该方法的实现代码如下:

double  TTSSFCriterion::GetCriterion()
{
  double  avg_win = TesterStatistics(STAT_GROSS_PROFIT) / TesterStatistics(STAT_PROFIT_TRADES);
  double  avg_loss = -TesterStatistics(STAT_GROSS_LOSS) / TesterStatistics(STAT_LOSS_TRADES);
  double  win_perc = 100.0 * TesterStatistics(STAT_PROFIT_TRADES) / TesterStatistics(STAT_TRADES);

//  Calculated safe ratio for this percentage of profitable deals:
  double  teor = (110.0 - win_perc) / (win_perc - 10.0) + 1.0;

//  Calculate real ratio:
  double  real = avg_win / avg_loss;

//  CSTS:
  double  tssf = real / teor;

  return(tssf);
}

假设较短的区间适用于优化准则。然而,为了避免拟合,最好在优化结果中间使用结果。

让我们为读者提供自我优化的可能性。所附的fanexperttssf.mq5文件包含用于检查标准的EA事务。

总结

无论如何,您必须承认,与其他方案相比,这种简单的解决方案(使用单个积分率)几乎是完美的,通过它可以创建自定义优化标准。该方案使可靠交易系统的发展门槛得以提高。云技术的采用大大减少了优化的限制。

其他的进化方法可能涉及由不同的信息来源描述的标准,这些标准已经在数学和统计学上得到了确认。我们有合适的工具。

本文由MetaQuotes Software Corp.翻译自俄语原文
,网址为https://www.mql5.com/ru/articles/286。

附加文件下载zip balanceslope.mqh(14.56 kb)customoptimization.mqh(20 kb)fanexpert.mq5(8.82 kb)fanexpertbalance.mq5(8.99 kb)、fanexpertimple.mq5(9.17 kb)、fanexperttssf.mq5(8.86 kb)

 

 


MyFxtop迈投(www.myfxtop.com)-靠谱的外汇跟单社区,免费跟随高手做交易!

 

免责声明:本文系转载自网络,如有侵犯,请联系我们立即删除,另:本文仅代表作者个人观点,与迈投财经(www.myfxtop.cn)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。

風險提示

MyFxtops邁投所列信息僅供參考,不構成投資建議,也不代表任何形式的推薦或者誘導行為。MyFxtops邁投非外匯經紀商,不接觸妳的任何資金。 MYFXTOPS不保證客戶盈利,不承擔任何責任。從事外彙和差價合約等金融產品的槓桿交易具有高風險,損失有可能超過本金,請量力而行,入市前需充分了解潛在的風險。過去的交易成績並不代表以後的交易成績。依據各地區法律法規,MyFxtops邁投不向中國大陸、美國、加拿大、朝鮮居民提供服務。

邁投公眾號

聯繫我們

客服QQ:981617007
Email: service@myfxtop.com

MyFxtops 邁投