利用余额图进行策略优化并将结果与 "余额 + 最大锋锐比率" 标准进行比较

Vladimir Karputov | 13 十一月, 2017

内容


1. 概述

在工作当中, 令我恍然大悟的是基于历史数据的余额图其增长已经不足了。另外, 我们需要它足够平滑。换言之, 距趋势线的均方差应尽可能地缩短。这意味着除了盈利, 我们也希望稳定。为了达到这个目的, 我们再来检查一下另一个优化参数: 余额图曲线及其距回归线偏差的方差。

我们将会利用 ALGLIB 数值分析函数库来获得线性回归方程比率和其它一些统计特征。


2. 如何计算余额图的趋势线?

我们需要为余额图建立一条趋势线, 距此线偏差的平方和最小。

通过标准最小二乘 (LS) 法找出用于计算趋势线方程式 y=ax+b 的比率。我不打算提供所有必要的数学方程式。代之, 我将在 ALGLIB 函数库中使用一个现成的函数, 令其适合我们的需求。

2.1. 计算优化准则的算法

我们来看看五笔交易的例子:

插图1. Balance and Linear regression.png

插图1. 余额图和线性回归

这五笔交易形成 "余额" 1-2-3-4-5 余额线。使用最小二乘法计算并绘制线性回归线 (使用 ALGLIB 数值分析函数库进行计算)。

2.2. 引入第一个 TrendProfit 变量。

它代表用来绘制回归线的每笔交易的利润:

插图2. 参数 TrendProfit

插图2. TrendProfit 参数

计算此变量作为回归线高度与交易数量的比率。反过来, 计算的高度作为回归线在 B 点和 A 点的差值。

现在我们需要得到回归线构建误差 — 回归线距余额线的平均偏差。我们称其为 距线性回归的标准余额偏差, 并标记为 LR 标准误差:

插图3. LR 标准误差

插图3. LR 标准误差

在此方程中, 计算的 误差 作为余额和线性回归之间的差值。您可在 此处 找到有关方程的详细信息 (俄语)。 

考虑插图上的情况。1, 错误如下:

误差 #1 误差 #2 误差 #3 误差 #4 误差 #5
10 000 - 10 600 = - 600 12 000 - 11 200 = 800 11 000 - 11 800 = - 800 14 000 - 12 400 = 1600 12 000 - 13 000 = - 1000

所以, LR 标准误差 等于:

插图4. 计算 LR 标准误差

插图4. 计算 LR 标准误差

2.3. ProfitStability 变量。

此参数负责余额图的平滑度。我们的目标:

计算的 ProfitStability 作为 TrendProfit 与 LR 标准误差 的比率:

插图5. 变量 ProfitStability

插图5. ProfitStability 变量 

为降低交易量差异对交易的影响, 我们可以将 ProfitStability 变量除以所有交易的总量。


3. 协同 ALGLIB 函数库操作

到目前为止 (统合构建 1645), ALGLIB 函数库已集成到标准库很久了: [数据文件夹]\MQL5\Include\Math\Alglib\alglib.mqh

插图6. alglib

插图6. 标准库中 ALGLIB 函数库的路径

ALGLIB 函数库类 

我们将需要以下类来处理线性回归:

BalanceRegression.mqh 类

所有与线性回归和参数计算相关的工作均在 Balance regression.mqh 类中执行。

类方法

 设置参数
 SetStartBalance   设置初始余额
 SetFromDate  设置请求交易历史的初始日期
 SetVolumeNormalization  设置交易量常规化模式
 访问计算结果
 GetProfitStability  访问计算结果 


协同 CBalanceRegression 操作包括以下步骤。

  1. 设置初始余额 — 调用 SetStartBalance 方法。
  2. 设置请求交易历史的初始日期 — 调用 SetFromDate 方法。
  3. 设置交易量常规化模式 — 调用 SetVolumeNormalization 方法。如果我们想使用交易量常规化, 传递 'true', 否则 — 'false'。 
  4. 获取计算结果 — 调用 GetProfitStability 方法, 将所获结果返回给 OnTester 过程。

3.1. 计算步骤 (GetProfitStability 方法)

(佣金 + 掉期 + 利润) > 0.0 的交易结果保存至 arr_profits 数组。所有交易的交易量汇总到 total_volume 变量。

//---
   double   arr_profits[];                            // 成交结果数组 
   double   total_volume=0;                           // 总交易量

接下来, 遍历所有交易 — 填入 arr_profits 数组并累计交易量至 total_volume 变量:

//--- 请求交易历史 
   HistorySelect(m_from_date,to_date);
   uint total_deals=HistoryDealsTotal();
   ulong ticket_history_deal=0;
//--- 对于所有交易 
   for(uint i=0;i<total_deals;i++)
     {
      //--- 尝试得到成交 ticket_history_deal 
      if((ticket_history_deal=HistoryDealGetTicket(i))>0)
        {
         long     deal_type         =HistoryDealGetInteger(ticket_history_deal,DEAL_TYPE);
         double   deal_volume       =HistoryDealGetDouble(ticket_history_deal,DEAL_VOLUME);
         double   deal_commission   =HistoryDealGetDouble(ticket_history_deal,DEAL_COMMISSION);
         double   deal_swap         =HistoryDealGetDouble(ticket_history_deal,DEAL_SWAP);
         double   deal_profit       =HistoryDealGetDouble(ticket_history_deal,DEAL_PROFIT);

         if(deal_type!=DEAL_TYPE_BUY && deal_type!=DEAL_TYPE_SELL)
            continue;

         if(deal_commission==0.0 && deal_swap==0.0 && deal_profit==0.0)
            continue;

         total_volume+=deal_volume;

         int arr_size=ArraySize(arr_profits);
         ArrayResize(arr_profits,arr_size+1,50);   // 调整数组

         if(arr_size==0)
            arr_profits[arr_size]=GetSetStartBalance()+deal_commission+deal_swap+deal_profit;
         else
            arr_profits[arr_size]=arr_profits[arr_size-1]+deal_commission+deal_swap+deal_profit;

         int d=0;
        }
     }

注意: 当我们在 arr_profits 数组里首次加入记录时, 我们 累加初始余额 和交易的清算结果。对于随后的所有记录, 累加前一条记录 和交易的清算结果。

声明 CMatrixDouble 类对象。事实上, 这是一个矩阵。我们来填充: 交易索引 (从 "1" 开始) 的清算结果。

//--- CMatrixDouble 对象
   CMatrixDouble xy(arr_size,2);
   for(int i=0;i<arr_size;i++)
     {
      xy[i].Set(0,i+1);
      xy[i].Set(1,arr_profits[i]);
      //Print(arr_profits[i]); // 用于调试
     }

声明必要的类对象 (CLinReg, CLinearModel, CLRReport) 并计算 线性回归:

//--- 线性回归构造
   CLinReg        linear_regression;
   CLinearModel   linear_model;
   CLRReport      linear_report;
   int retcode;
   linear_regression.LRBuild(xy,arr_size,1,retcode,linear_model,linear_report);
   if(retcode!=1)
     {
      Print("线性回归失败, 错误代码=",retcode);
      return(0.0);
     }
   int nvars;
   double coefficients[];
   linear_regression.LRUnpack(linear_model,coefficients,nvars);
   double coeff_a=coefficients[0];
   double coeff_b=coefficients[1];
   PrintFormat("y = %.1f x + %.1f",coeff_a,coeff_b);

最后, 调用 LRUnpack 方法获取 y = a*x + b 方程的比率。比率位于 coefficients 数组。

现在我们已使用 ALGLIB 函数库计算了线性回归, 我们可以直接计算参数, 这是整篇文章的焦点。

//--- 参数计算
   double TrendProfit=((double)arr_size*coeff_a+coeff_b)-(1.0*coeff_a+coeff_b);  // 回归线在 "Y" 轴上的投影 
   TrendProfit/=(double)arr_size;                                                // 除以交易数量
   double TrendMSE=linear_report.m_rmserror;                                     // 训练集合上的均方根误差
   double ProfitStability=TrendProfit/TrendMSE;
//--- 常规化交易量
   if(GetVolumeNormalization())
      ProfitStability/=total_volume;
//--- 我们乘以交易数量 - 我们对传递少量成交不感兴趣
   ProfitStability*=arr_size;
//---
   return(ProfitStability*10000.0);

根据利用 SetVolumeNormalization 方法设置的初始参数, 我们即可将 ProfitStability 参数除以总的交易量, 也可不除。结果乘以 10000 以便更好地表示结果。


4. 包含 CBalanceRegression 类

我们来研究包含在 CBalanceRegression 类中可用于各种 EA 的算法。 

4.1. 利用 MQL5 向导生成智能交易系统

我们想检查交易量常规化对结果的影响。这意味着, 我们需要一个能够动态计算已开仓成交量的 EA。这可以在 MQL5 向导 中完成: 选择 智能交易系统 (生成), 并在 "资金管理" 页面中包含一个资金管理模块:

  • "固定保证金交易" — 按照可用保证金的 % 计算手数
  • "固定风险交易" — 按照余额 % 计算手数
  • "优化的成交量交易" — 依照交易历史计算手数

对于本文, 我选择了 "固定风险交易" 的资金管理模块, 而 EA 本身则被命名为 "EA test balance regression.mq5"。以它为例, 我将展示如何包含 CBalanceRegression 类的文件。

步骤 1. 包含 CBalanceRegression 文件并声明类对象 (m_balance_regression)。

注意: CBalanceRegression 类文件应该位于 [数据文件夹]\MQL5\Include\Balance regression 文件夹中。

//--- 可用的资金管理
#include <Expert\Money\MoneyFixedRisk.mqh>
//--- 可用的余额回归模块
#include <Balance regression\BalanceRegression.mqh>
//+------------------------------------------------------------------+
//| 输入                                                              |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| 智能系统的全局对象                                                  |
//+------------------------------------------------------------------+
CExpert ExtExpert;
CBalanceRegression m_balance_regression;
//+------------------------------------------------------------------+
//| 智能系统的初始化函数                                                 |
//+------------------------------------------------------------------+

步骤 2. 将启用/禁用交易量常规化的参数添加到输入参数:

input double             Money_FixRisk_Percent=10.0;                            // 风险百分比
//--- 余额常规化的输入
input bool               InpVolumeNormalization=true;                           // 交易量常规化
//+------------------------------------------------------------------+
//| 智能系统的全局对象                                                  |
//+------------------------------------------------------------------+

步骤 3. 为 CBalanceRegression 类的 m_balance_regression 对象设置参数: 用于请求交易历史和交易量常规化模式的初始数据:

//+------------------------------------------------------------------+
//| 智能系统的初始化函数                                                 |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 设置 CBalanceRegression 的参数
   m_balance_regression.SetStartBalance(AccountInfoDouble(ACCOUNT_BALANCE));
   m_balance_regression.SetFromDate(TimeCurrent());
   m_balance_regression.SetVolumeNormalization(InpVolumeNormalization);
//--- 智能系统初始化

步骤 4. 在文件的末尾添加 OnTester 过程。在此, 我们接收自定义优化标准 (通过调用 GetProfitStability) 并将参数传递给测试器:

//+------------------------------------------------------------------+
//| 测试器函数                                                         |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
   double ret=m_balance_regression.GetProfitStability(TimeCurrent());
//---
   return(ret);
  }

4.2. 智能交易系统基于标准 MACD 采样和 移动平均线

EA 原文件分别位于 [数据文件夹]\MQL5\Experts\Examples\MACD\MACD Sample.mq5 和 [数据文件夹]MQL5\Experts\Examples\Moving Average\Moving Average.mq5 中。

取出原始的 EA, 并以不同的名字保存它们的副本。我已选择好名称 "MACD Sample balance regression.mq5" 和 "Moving Average balance regression.mq5"。

步骤 1. 包含 CBalanceRegression 类的文件并声明这个类的对象 (m_balance_regression)。

注意: CBalanceRegression 类文件应该位于 [数据文件夹]\MQL5\Include\Balance regression 文件夹中。

MACD Sample balance regression.mq5 Moving Average balance regression.mq5
#include <Trade\AccountInfo.mqh>
//--- 可用的余额回归模块
#include <Balance regression\BalanceRegression.mqh>
CBalanceRegression m_balance_regression;
//---
input double InpLots          =0.1; // Lots
#include <Trade\Trade.mqh>
//--- 可用的余额回归模块
#include <Balance regression\BalanceRegression.mqh>
CBalanceRegression m_balance_regression;

input double MaximumRisk        = 0.02;    // 最大风险百分比

步骤 2. 将启用/禁用交易量常规化的参数添加到输入参数:

MACD Sample balance regression.mq5 Moving Average balance regression.mq5
input int    InpMATrendPeriod =26;  // MA 趋势周期
//--- 余额常规化的输入
input bool   InpVolumeNormalization=true; // 成交量常规化
//---
int ExtTimeOut=10; // 交易操作之间的超时秒数
input int    MovingShift        = 6;       // 移动均线偏移
//--- 余额常规化的输入
input bool   InpVolumeNormalization=true;  // 成交量常规化
//---
int    ExtHandle=0;

步骤 3. 为 CBalanceRegression 类的 m_balance_regression 对象设置参数: 用于请求交易历史和交易量常规化模式的初始数据:

MACD Sample balance regression.mq5  Moving Average balance regression.mq5
//+------------------------------------------------------------------+
//| 初始化并检查输入参数                                                 |
//+------------------------------------------------------------------+
bool CSampleExpert::Init(void)
  {
//--- 设置 CBalanceRegression 的参数
   m_balance_regression.SetStartBalance(AccountInfoDouble(ACCOUNT_BALANCE));
   m_balance_regression.SetFromDate(TimeCurrent());
   m_balance_regression.SetVolumeNormalization(InpVolumeNormalization);
//--- 初始化公用信息
  
//+------------------------------------------------------------------+
//| 智能系统初始化函数                                                  |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- 设置 CBalanceRegression 的参数
   m_balance_regression.SetStartBalance(AccountInfoDouble(ACCOUNT_BALANCE));
   m_balance_regression.SetFromDate(TimeCurrent());
   m_balance_regression.SetVolumeNormalization(InpVolumeNormalization);
//--- 如果对冲模式激活, 则准备用于控制仓位的交易类

步骤 4. 在两个 EA 文件的末尾添加 OnTester 过程。在此, 我们接收自定义优化标准 (通过调用 GetProfitStability) 并将参数传递给测试器:

//+------------------------------------------------------------------+
//| 测试器函数                                                         |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
   double ret=m_balance_regression.GetProfitStability(TimeCurrent());
//---
   return(ret);
  }

5. 在 EURUSD H4 上的优化, 未启用前瞻测试

我们有三个 EA, 在其上我们可以检查使用回归方法优化余额图的思路。两个 EA (EA test balance regression.mq5Moving Average balance regression.mq5) 在交易期间动态计算持仓量, 而 MACD Sample balance regression.mq5 使用固定手数。

5.1. EA test balance regression.mq5, EURUSD H4, 未启用前瞻测试

为了不错过任何选项并加速测试, 我选择了两个参数进行优化 - 开仓/平仓信号的边界参数:

插图7 上显示的参数相同。测试器, 输入选卡

插图7 上显示的参数相同。测试器, 输入选卡

  • 测试 1: 优化标准 "余额 + 最大锋锐比率" 参数, 
  • 测试 2: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'false', 
  • 测试 3: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'true'。

5.1.1 测试 1: 优化标准 "余额 + 最大锋锐比率" 参数。

针对测试 1 (注: "优化" 等于 "余额 + 最大锋锐比率") 的测试器设置:

插图8. 测试器, 设置选卡

插图8. 测试器, 设置选卡

5.1.2. 本地家庭网络中的两台 PC 与云端测试的速度比较

家庭网络内拥有两台电脑:

  1. 一台笔记本配置为四核 Intel Core i3-3120M @2.50GHz, 8077 MB。由于终端还需要与第二台计算机上的代理进行通信, 因此测试中只使用了四个代理中的三个。
  2. 一台桌面机配置为六核 AMD Phenom II X6 1075T 处理器, 4058 MB。测试中只使用六个代理中的四个代理, 以免 CPU 过热。

插图9. 家庭网络中的优化

插图9. 家庭网络中的优化

测试 1 家庭网络中 21 分 43 秒内通关

现在, 我删除缓存内的测试结果, 并在 MQL5 Cloud Europe 1 上启动测试 1。在 云端, 测试花费了 1 分 9 秒。测试成本为 $0.06

测试 1 结果, 结果列按降序排列, 五个最佳结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 开仓信号阀值 平仓信号阀值
346 4349.76 17818.98 181.83 1.28 1.45 0.16 27989.31 60.48 98 30 100
345 4349.76 17818.98 181.83 1.28 1.45 0.16 27989.31 60.48 98 25 100
344 4349.76 17818.98 181.83 1.28 1.45 0.16 27989.31 60.48 98 20 100
343 4349.76 17818.98 181.83 1.28 1.45 0.16 27989.31 60.48 98 15 100
327 4349.76 17818.98 181.83 1.28 1.45 0.16 27989.31 60.48 98 30 95

插图10. 测试 1, 优化通关 346

插图10. 测试 1, 优化通关 346

5.1.3. 测试 2: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'false'。

针对测试 2 (注: "优化" 等于 "自定义最大") 的测试器设置:

插图11. 测试器, 设置选卡

插图11. 测试器, 设置选卡

 针对测试 2 (注: "交易量常规化" 在 Value 栏为 'false') 的测试器设置:

插图12. 测试器, 输入选卡

插图12. 测试器, 输入选卡

测试 2 结果, 结果列按降序排列, 五个最佳结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 开仓信号阀值 平仓信号阀值
270 40085.45 11072.30 93.04 1.12 0.90 0.11 40085.45 41.18 119 30 80
269 40085.45 11072.30 93.04 1.12 0.90 0.11 40085.45 41.18 119 25 80
268 40085.45 11072.30 93.04 1.12 0.90 0.11 40085.45 41.18 119 20 80
267 40085.45 11072.30 93.04 1.12 0.90 0.11 40085.45 41.18 119 15 80
251 40085.45 11072.30 93.04 1.12 0.90 0.11 40085.45 41.18 119 30 75


插图13. EURUSDH4, 测试 2 优化通关 270

插图13. EURUSDH4, 测试 2, 优化通关 270

依照 "自定义最大" 自定义参数优化可令我们选择较小盈利的结果, 但净值回撤 (Equity DD % 栏) 较小。此外, 测试 2 有一个较小的余额回撤。如果我们比较插图, 这可以被直观地看到。12 和 13。

5.1.4. 测试 3: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'true':

针对测试 3 (设置与测试 2 类似) 的测试器设置:

插图14. 测试器, 设置选卡

插图14. 测试器, 设置选卡

针对测试 3 (注: "交易量常规化" 在 Value 栏为 'true') 的测试器设置:

插图15. 测试器, 输入选卡

插图15. 测试器, 输入选卡

在云端, 测试花费 2 分 27 秒。整个测试在 MQL5 Cloud Europe 1 上进行。测试成本是 $0.08。

测试 3 结果, 结果列按降序排列, 五个最佳结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 开仓信号阀值 平仓信号阀值
346 92.11 17818.98 181.83 1.28 1.45 0.16 92.11253 60.48 98 30 100
345 92.11 17818.98 181.83 1.28 1.45 0.16 92.11253 60.48 98 25 100
344 92.11 17818.98 181.83 1.28 1.45 0.16 92.11253 60.48 98 20 100
343 92.11 17818.98 181.83 1.28 1.45 0.16 92.11253 60.48 98 15 100
327 92.11 17818.98 181.83 1.28 1.45 0.16 92.11253 60.48 98 30 95

在测试 3 中交易量参数等于 'true', 与测试 1 中定义相同的最佳选项。这是运用线性回归方法优化余额图的一个很好的迹象。

结论: 运用线性回归方法 优化 余额图的结果与"余额 + 最大锋锐比率" 优化方法相比不差甚至相当。

5.2. Moving Average balance regression.mq5, EURUSD, H4, 未启用前瞻测试

选择以下参数用于优化:

插图16. 测试器, 输入选卡

插图16. 测试器, 输入选卡

我将针对 Moving Average balance regression EA 进行三次测试:

  • 测试 1: 优化标准 "余额 + 最大锋锐比率" 参数, 
  • 测试 2: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'false', 
  • 测试 3: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'true'。

测试器设置 (货币, 逐笔报价的生成方法和时间间隔与插图 5 相同)。

5.2.1. 测试 1 (优化标准 "余额 + 最大锋锐比率" 参数) 在云端执行。在云端, 测试花费 1 分 22 秒。整个测试在 MQL5 Cloud Europe 1 上进行。测试成本为 $0.03。

测试 1 结果, 结果列按降序排列, 五个最佳结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 递减因子 移动均线周期
19 3500.83 1209.31 28.79 2.89 2.74 0.31 280.3791 4.29 42 9 13
18 3500.83 1209.31 28.79 2.89 2.74 0.31 280.3791 4.29 42 8 13
17 3500.83 1209.31 28.79 2.89 2.74 0.31 280.3791 4.29 42 7 13
21 3438.91 1202.00 28.62 2.76 2.52 0.31 287.1098 4.59 42 11 13
20 3438.91 1202.00 28.62 2.76 2.52 0.31 287.1098 4.59 42 10 13

我们来看看最佳通关 #19:

插图17. EURUSDH4, 测试 1 优化通关 19

插图17. EURUSDH4, 测试 1, 优化通关 19

5.2.2. 测试 2 (优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'false') 在云端执行。在云端, 测试花费 0 分 00 秒, 因为结果已经从缓存中获取, 尽管它们是逆反的。整个测试在 MQL5 Cloud Europe 2 上进行。测试成本为 $0.00。

测试 2 结果, 结果列按降序排列, 五个最佳结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 递减因子 移动均线周期
141 102076.24 1029.99 25.75 2.16 2.29 0.22 102076.2 3.93 40 14 22
140 102076.24 1029.99 25.75 2.16 2.29 0.22 102076.2 3.93 40 13 22
139 102076.24 1029.99 25.75 2.16 2.29 0.22 102076.2 3.93 40 12 22
142 101254.84 1037.87 25.95 2.15 2.31 0.22 101254.8 3.93 40 15 22
138 90936.41 960.67 24.02 2.09 2.08 0.21 90936.41 4.31 40 11 22

通关 141 位于表格的最顶端 (它在结果列中具有最大值):

插图18. EURUSDH4, 测试 2 优化通关 141

插图18. EURUSDH4, 测试 2, 优化通关 141

在测试 2 中, 比之 "余额 + 最大锋锐比率" 参数, 优化余额图展示更佳结果。

5.2.3. 测试 3 (优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'true') 在云端执行。在云端, 测试花费 1 分 13 秒。整个测试在 MQL5 Cloud Europe 2 上进行。测试成本为 $0.05。

测试 3 结果, 结果列按降序排列, 五个最佳结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 递减因子 移动均线周期
141 13869.05 1029.99 25.75 2.16 2.29 0.22 13869.05 3.93 40 14 22
140 13869.05 1029.99 25.75 2.16 2.29 0.22 13869.05 3.93 40 13 22
139 13869.05 1029.99 25.75 2.16 2.29 0.22 13869.05 3.93 40 12 22
142 13235.93 1037.87 25.95 2.15 2.31 0.22 13235.93 3.93 40 15 22
138 12542.95 960.67 24.02 2.09 2.08 0.21 12542.95 4.31 40 11 22

测试 3 选取了与测试 2 中相同的最佳选项。交易量优化参数等于 "true" 没有做任何调整。

结论: 在两次测试 (Test 2 和 3) 中, 依照 "自定义最大" 参数取得了比测试 1 更好的结果。交易量优化参数等于 'true' 在测试 3 中没有做任何调整

5.3. MACD Sample balance regression.mq5, EURUSD, H4, 未启用前瞻测试

选择以下参数用于优化:

插图19. 测试器, 输入选卡

插图19. 测试器, 输入选卡

我将针对 MACD Sample balance regression EA 进行同样的三次测试:

测试器设置 (货币, 逐笔报价的生成方法和时间间隔与插图5 相同)。

5.3.1. 测试 1 (优化标准 "余额 + 最大锋锐比率" 参数) 在云端执行。在云端, 测试花费 3 分 55 秒 (时间相比较大, 由于任务没有在一些慢速代理上执行, 所以, 10 个任务分布在其它代理上)。整个测试在 MQL5 Cloud Europe 1 上进行。测试成本为 $0.04。

测试 1 结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 止盈 尾随停止
163 767049.82 363.32 24.22
3.87 74.02 24573559 0.91 15 25 50
136 767049.82 363.32 24.22
3.87 74.02 24573559 0.91 15 25 45
109 767049.82 363.32 24.22
3.87 74.02 24573559 0.91 15 25 40
82 767049.82 363.32 24.22
3.87 74.02 24573559 0.91 15 25 35
55 767049.82 363.32 24.22
3.87 74.02 24573559 0.91 15 25 30

在这个时间帧内, 很少有交易 (从 13 日到 16 日)。我希望在较低的时间帧内会有更多的交易 (M15)。这些测试在下面的另一章节中显示。而现在, 最佳结果是 #163:

插图20. EURUSDH4, 测试 1 优化通关 163

插图20. EURUSDH4, 测试 1, 优化通关 163

5.3.2. 测试 2 (优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'false') 在云端执行。在云端, 测试花费 0 分 00 秒, 因为结果已经从缓存中获取, 尽管它们是逆反的。整个测试在 MQL5 Cloud Europe 2 上进行。测试成本为 $0.00。

测试 2 结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 止盈 尾随停止
163 24573558.59 363.32 24.22
3.87 74.02 24573559 0.91 15 25 50
136 24573558.59 363.32 24.22
3.87 74.02 24573559 0.91 15 25 45
109 24573558.59 363.32 24.22
3.87 74.02 24573559 0.91 15 25 40
82 24573558.59 363.32 24.22
3.87 74.02 24573559 0.91 15 25 35
55 24573558.59 363.32 24.22
3.87 74.02 24573559 0.91 15 25 30

测试 2 选取了与测试 1 中相同的最佳结果 (除结果栏之外, 比较所有列)。 

5.3.3. 测试 3 (优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'true') 在云端执行。在云端, 测试花费 1 分 5 秒。整个测试在 MQL5 Cloud Europe 2 上进行。测试成本为 $0.05。

测试 3 结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 止盈 尾随停止
163 16382372.39 363.32 24.22
3.87 74.02 16382372 0.91 15 25 50
136 16382372.39 363.32 24.22
3.87 74.02 16382372 0.91 15 25 45
109 16382372.39 363.32 24.22
3.87 74.02 16382372 0.91 15 25 40
82 16382372.39 363.32 24.22
3.87 74.02 16382372 0.91 15 25 35
55 16382372.39 363.32 24.22
3.87 74.02 16382372 0.91 15 25 30
测试 3 选取了与测试 1 和测试 2 相同的最佳结果 (除结果栏之外, 比较所有列)。

运用线性回归方法对余额图进行优化时, 与使用 "余额 + 最大锋锐比率" 方法相同。


6. EURUSD M15 的优化, 启用前瞻测试

我们有相同的三个 EA: EA test balance regression.mq5, Moving Average balance regression.mq5 和 MACD Sample balance regression.mq5。与以前的测试不同, 我们现在启用 前瞻测试, 并在 M15 上测试。

6.1. EA test balance regression.mq5, 前瞻测试。我将进行 三次测试:

  • 测试 1: 优化标准 "余额 + 最大锋锐比率" 参数
  • 测试 2: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'false'
  • 测试 3: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'true'。

6.1.1. 测试 1: 优化标准 "余额 + 最大锋锐比率" 参数。测试器设置:

插图21. 测试器, 设置选卡

插图21. 测试器, 设置选卡

测试器参数与插图 7 上显示的参数相同。

在云端, 测试花费 2 分 14 秒。整个测试在 MQL5 Cloud Europe 2 上进行。测试成本是 $0.08。

优化结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 开仓信号阀值 平仓信号阀值
352 23196.38 85836.92 721.32 1.47 2.03 0.24 2722.602 48.82 119 60 100
351 23196.38 85836.92 721.32 1.47 2.03 0.24 2722.602 48.82 119 55 100
333 23196.38 85836.92 721.32 1.47 2.03 0.24 2722.602 48.82 119 60 95
332 23196.38 85836.92 721.32 1.47 2.03 0.24 2722.602 48.82 119 55 95
314 23196.38 85836.92 721.32 1.47 2.03 0.24 2722.602 48.82 119 60 90

插图22. EURUSDM15, 测试 1 优化通关 352

插图22. EURUSDM15, 测试 1, 优化通关 352

前瞻结果:

通关 前瞻结果 回测结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 开仓信号阀值 平仓信号阀值
284 216.48 11708.46 18.91 1.89 1.02 0.02 0.02 7172.395 9.33 10 100 80
283 216.48 11708.46 18.91 1.89 1.02 0.02 0.02 7172.395 9.33 10 95 80
282 216.48 11708.46 18.91 1.89 1.02 0.02 0.02 7172.395 9.33 10 90 80
281 216.48 11708.46 18.91 1.89 1.02 0.02 0.02 7172.395 9.33 10 85 80
265 216.48 11708.46 18.91 1.89 1.02 0.02 0.02 7172.395 9.33 10 100 75

在此, 最好的选项是在前瞻区域只有 10 笔交易的那个。当然, 这还不够, 但我们仍然需要进行测试:

插图23。EURUSDM15, 测试 1 前瞻通关 284

插图23。EURUSDM15, 测试 1, 前瞻通关 284

6.1.2. 测试 2: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'false'。

最佳优化结果 (非前瞻):

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 开仓信号阀值 平仓信号阀值
284 180332.68 10820.37 309.15 4.67 6.80 0.56 180332.7 7.98 35 100 80
283 180332.68 10820.37 309.15 4.67 6.80 0.56 180332.7 7.98 35 95 80
282 180332.68 10820.37 309.15 4.67 6.80 0.56 180332.7 7.98 35 90 80
281 180332.68 10820.37 309.15 4.67 6.80 0.56 180332.7 7.98 35 85 80
265 180332.68 10820.37 309.15 4.67 6.80 0.56 180332.7 7.98 35 100 75

插图24. EURUSDM15, 测试 2 优化通关 284

插图24. EURUSDM15, 测试 2, 优化通关 284

前瞻结果:

通关 前瞻结果 回测结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 开仓信号阀值 平仓信号阀值
284 -14294.76 180332.68 18.91 1.89 1.02 0.02 0.02 -14294.8 9.33 10 100 80
283 -14294.76 180332.68 18.91 1.89 1.02 0.02 0.02 -14294.8 9.33 10 95 80
282 -14294.76 180332.68 18.91 1.89 1.02 0.02 0.02 -14294.8 9.33 10 90 80
281 -14294.76 180332.68 18.91 1.89 1.02 0.02 0.02 -14294.8 9.33 10 85 80
265 -14294.76 180332.68 18.91 1.89 1.02 0.02 0.02 -14294.8 9.33 10 100 75

在测试 2 中, 前瞻测试展示与测试 1 中相同的结果。

在测试 2 中运用线性回归方法优化余额图令我们能够检测到不比测试 1 ("余额 + 最大锋锐比率" 方法) 差的结果。

6.1.3. 测试 3: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'true'。在云端, 测试花费 3 分 29 秒。整个测试在 MQL5 Cloud Europe 1 上进行。测试成本为 $0.07。

最佳优化结果 (非前瞻):

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 开仓信号阀值 平仓信号阀值
208 1660.90 10008.05 285.94 4.50 6.55 0.56 1660.901 7.98 35 100 60
207 1660.90 10008.05 285.94 4.50 6.55 0.56 1660.901 7.98 35 95 60
206 1660.90 10008.05 285.94 4.50 6.55 0.56 1660.901 7.98 35 90 60
205 1660.90 10008.05 285.94 4.50 6.55 0.56 1660.901 7.98 35 85 60
189 1660.90 10008.05 285.94 4.50 6.55 0.56 1660.901 7.98 35 100 55


插图25. EURUSDM15, 测试 3 优化通关 208

插图25. EURUSDM15, 测试 3, 优化通关 208

启用 "交易量常规化" 对结果没有显著影响。而且, 在优化间隔内发现了最佳结果之一。

最好的前瞻结果:

通关 前瞻结果 回测结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 开仓信号阀值 平仓信号阀值
266 -103.43 -25.56 -7464.56 -24.64 0.66 -0.99 -0.11 -103.428 75.43 303 10 80
247 -103.43 -25.56 -7464.56 -24.64 0.66 -0.99 -0.11 -103.428 75.43 303 10 75
228 -103.43 -25.56 -7464.56 -24.64 0.66 -0.99 -0.11 -103.428 75.43 303 10 70
209 -103.43 -25.56 -7464.56 -24.64 0.66 -0.99 -0.11 -103.428 75.43 303 10 65
156 -120.35 -29.28 -8013.01 -22.76 0.63 -1.00 -0.13 -120.35 80.44 352 30 50

测试 3 中的前瞻测试 (已交易量优化参数为 "true") 仅显示负值结果 (参见 "Forward Result" 列)。这是运用线性回归方法来优化余额图的优良结果, 因为已经为前瞻测试选择了最准确和最真实的结果。

运用线性回归方法优化余额图 (已交易量优化参数是 'false') 可令您获得与 "余额最大 + 锋锐比率" 方法相当的结果)。当 已交易量优化参数为 'true' 时, 前瞻测试显示在此时间帧上的真实测试图像。

6.2. MACD Sample balance regression.mq5, 前瞻测试

6.2.1. 测试 1: 优化标准 "余额 + 最大锋锐比率" 参数, 在云端执行。在云端, 测试花费 1 分 3 秒。整个测试在 MQL5 Cloud Europe 1 上进行。测试成本为 $0.06。

优化结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 止盈 尾随停止
171 2094.29 479.93 8.57 1.81 2.03 0.20 -1.69249 2.30 56 65 50
144 2094.29 479.93 8.57 1.81 2.03 0.20 -1.69249 2.30 56 65 45
182 2078.33 489.23 8.74 1.82 2.07 0.20 -9.9625 2.29 56 120 50
155 2077.49 489.03 8.73 1.82 2.07 0.20 -9.90369 2.29 56 120 45
181 2066.17 484.13 8.65 1.81 2.05 0.20 -8.1109 2.29 56 115 50


插图26. EURUSDM15, 测试 1 优化通关 171

插图26. EURUSDM15, 测试 1, 优化通关 171

前瞻结果:

通关 前瞻结果 回测结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 止盈 尾随停止
78 1182.13 1659.86 83.87 5.24 1.43 0.42 0.12 -44.8452 1.95 16 140 30
77 1134.97 1659.86 78.87 4.93 1.41 0.40 0.11 -53.5369 1.95 16 135 30
105 1107.99 1639.60 78.17 4.89 1.40 0.39 0.11 -26.6428 1.96 16 140 35
76 1085.51 1659.86 73.87 4.62 1.38 0.37 0.11 -62.5775 1.95 16 130 30
171 1060.24 2094.29 62.97 3.94 1.32 0.36 0.11 -347.982 1.70 16 65 50


插图27. EURUSDM15, 测试 1 前瞻通关 78

插图27. EURUSDM15, 测试 1, 前瞻通关 78

6.2.2. 测试 2: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'false'。

优化结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 止盈 尾随停止
168 84498.76 442.03 7.89 1.74 2.08 0.19 84498.76 2.07 56 50 50
141 84498.76 442.03 7.89 1.74 2.08 0.19 84498.76 2.07 56 50 45
114 84498.76 442.03 7.89 1.74 2.08 0.19 84498.76 2.07 56 50 40
167 83473.95 442.03 7.89 1.74 2.08 0.19 83473.95 2.06 56 45 50
140 83473.95 442.03 7.89 1.74 2.08 0.19 83473.95 2.06 56 45 45


插图28. EURUSDM15, 测试 2 优化通关 168

插图28. EURUSDM15, 测试 2, 优化通关 168

前瞻结果:

通关 前瞻结果 回测结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 止盈 尾随停止
78 1182.13 1659.86 83.87 5.24 1.43 0.42 0.12 6462.158 1.95 16 140 30
77 1134.97 1659.86 78.87 4.93 1.41 0.40 0.11 5018.77 1.95 16 135 30
105 1107.99 1639.60 78.17 4.89 1.40 0.39 0.11 5617.275 1.96 16 140 35
76 1085.51 1659.86 73.87 4.62 1.38 0.37 0.11 3525.665 1.95 16 130 30
171 1060.24 2094.29 62.97 3.94 1.32 0.36 0.11 -5131.93 1.70 16 65 50

插图29. EURUSDM15, 测试 2 前瞻通关 78

插图29. EURUSDM15, 测试 2, 前瞻通关 78

在测试 2 中运用回归方法优化余额图显示与 "余额 + 最大锋锐比率" 方法相当的结果。

6.2.3. 测试 3: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'true', 在云端执行。在云端, 测试花费 1 分 44 秒。整个测试在 MQL5 Cloud Europe 1 上进行。测试成本是 $0.08。

优化结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 止盈 尾随停止
168 15089.06 442.03 7.89 1.74 2.08 0.19 15089.06 2.07 56 50 50
141 15089.06 442.03 7.89 1.74 2.08 0.19 15089.06 2.07 56 50 45
114 15089.06 442.03 7.89 1.74 2.08 0.19 15089.06 2.07 56 50 40
167 14906.06 442.03 7.89 1.74 2.08 0.19 14906.06 2.06 56 45 50
140 14906.06 442.03 7.89 1.74 2.08 0.19 14906.06 2.06 56 45 45

前瞻结果:

通关 前瞻结果 回测结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 止盈 尾随停止
78 4038.85 13138.16 83.87 5.24 1.43 0.42 0.12 4038.849 1.95 16 140 30
105 3510.80 13026.26 78.17 4.89 1.40 0.39 0.11 3510,797 1.96 16 140 35
77 3136.73 13138.16 78.87 4.93 1.41 0.40 0.11 3136.731 1.95 16 135 30
132 3074.09 13598.05 73.17 4.57 1.38 0.37 0.10 3074.089 1.96 16 140 40
159 2658.84 13777.31 68.47 4.28 1.35 0.35 0.10 2658.844 1.96 16 140 45
在测试 3 中, 优化和前瞻结果与测试 2 完全匹配 — 已交易量优化参数等于 "true", 且在测试 3 中没有显著影响。这是因为 MACD Sample balance regression.mq5 EA 以固定手数交易。

运用线性回归方法优化余额图已经证明与标准的 "余额最大 + 锋锐比率" 方法相当。

6.3. Moving Average balance regression.mq5 EA, 前瞻 测试

6.3.1. 测试 1: 优化标准 "余额 + 最大锋锐比率" 参数。测试器和参数选项卡类似于插图15。测试器和参数选项卡类似于插图23。

在云端, 测试花费 1 分 28 秒。整个测试在 MQL5 Cloud Europe 1 上进行。测试成本为 $0.05。

优化结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 递减因子 移动均线周期
53 -1.29 -16.76 -0.03 0.99 -0.03 0.00 11966.34 5.92 525 4 16
52 -1.29 -16.76 -0.03 0.99 -0.03 0.00 11966.34 5.92 525 3 16
165 -6.17 -24.02 -0.05 0.99 -0.03 0.00 -37045.4 6.66 465 12 24
166 -26.36 -49.14 -0.11 0.99 -0.07 0.00 -38052.8 6.86 465 13 24
163 -39.47 -61.88 -0.13 0.98 -0.09 0.00 -39156.1 6.62 465 10 24


插图30. EURUSDM15, 测试 1 优化通关 53

插图30. EURUSDM15, 测试 1, 优化通关 53

前瞻结果:

通关 前瞻结果 回测结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 递减因子 移动均线周期
48 409.74 -460.18 185.78 1.06 1.16 0.80 0.04 42602.76 2.26 175 12 15
49 364.79 -461.14 165.23 0.94 1.14 0.67 0.04 38508.36 2.41 175 13 15
50 362.45 -460.40 164.15 0.94 1.14 0.66 0.04 38292.53 2.42 175 14 15
51 353.14 -467.05 159.83 0.91 1.13 0.65 0.03 37460.15 2.42 175 15 15
47 350.60 -629.53 144.32 0.82 1.13 0.65 0.03 32767.39 2.17 175 11 15


插图31. EURUSDM15, 测试 1 前瞻通关 48

插图31. EURUSDM15, 测试 1, 前瞻通关 48

6.3.2. 测试 2优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'false''。 

优化结果: 

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 递减因子 移动均线周期
53 11966.34 -16.76 -0.03 0.99 -0.03 0.00 11966.34 5.92 525 4 16
52 11966.34 -16.76 -0.03 0.99 -0.03 0.00 11966.34 5.92 525 3 16
54 2465.75 -103.27 -0.20 0.96 -0.14 -0.01 2465.748 7.19 525 5 16
57 813.83 -91.78 -0.17 0.97 -0.13 -0.01 813.831 6.75 525 8 16
56 813.83 -91.78 -0.17 0.97 -0.13 -0.01 813.831 6.75 525 7 16

前瞻结果:

通关 前瞻结果 回测结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 递减因子 移动均线周期
48 42602.76 -73708.28 185.78 1.06 1.16 0.80 0.04 42602.76 2.26 175 12 15
49 38508.36 -74600.92 165.23 0.94 1.14 0.67 0.04 38508.36 2.41 175 13 15
50 38292.53 -74386.41 164.15 0.94 1.14 0.66 0.04 38292.53 2.42 175 14 15
51 37460.15 -75315.40 159.83 0.91 1.13 0.65 0.03 37460.15 2.42 175 15 15
47 32767.39 -107616.36 144.32 0.82 1.13 0.65 0.03 32767.39 2.17 175 11 15
在测试 2 中运用线性回归方法优化余额图检测到与测试 1 中相同的结果。

6.3.3. 测试 3: 优化 "自定义最大" 自定义参数, 而已交易量优化参数是 'true', 在云端执行。在云端, 测试花费 0 分 42 秒。整个测试在 MQL5 Cloud Europe 1 上进行。测试成本为 $0.04。 

优化结果:

通关 结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 递减因子 移动均线周期
53 243.32 -16.76 -0.03 0.99 -0.03 0.00 243.3172 5.92 525 4 16
52 243.32 -16.76 -0.03 0.99 -0.03 0.00 243.3172 5.92 525 3 16
54 45.69 -103.27 -0.20 0.96 -0.14 -0.01 45.68738 7.19 525 5 16
57 13.40 -91.78 -0.17 0.97 -0.13 -0.01 13.40301 6.75 525 8 16
56 13.40 -91.78 -0.17 0.97 -0.13 -0.01 13.40301 6.75 525 7 16

前瞻结果: 

通关 前瞻结果 回测结果 盈利 预期回报 盈利因子 恢复因子 锋锐比率 自定义 净值回撤 % 交易 递减因子 移动均线周期
48 1772.90 -997.81 185.78 1.06 1.16 0.80 0.04 1772.899 2.26 175 12 15
49 1591.91 -994.94 165.23 0.94 1.14 0.67 0.04 1591.912 2.41 175 13 15
50 1577.12 -987.34 164.15 0.94 1.14 0.66 0.04 1577.123 2.42 175 14 15
51 1537.14 -972.44 159.83 0.91 1.13 0.65 0.03 1537.142 2.42 175 15 15
47 1473.35 -1540.90 144.32 0.82 1.13 0.65 0.03 1473.354 2.17 175 11 15

测试 3 中运用线性回归方法优化余额图完全重现了测试 1 的结果。换言之, 启用交易量优化对结果没有影响, 尽管 Moving Average balance regression.mq5 EA 在交易中应用了动态手数计算。

运用线性回归方法优化余额图已经证明与标准的 "余额最大 + 锋锐比率" 方法相当。


7 上显示的参数相同。结束语

运用线性回归方法优化余额图的结果已经证明达至 "余额 + 最大锋锐比率" 优化方法的水平。使用动态手数的 EA 显示出有趣的结果: 在某些情况下, "交易量常规化" 设置与前瞻测试相结合产生更可靠的画面。

我相信, 所描述的方法有权存在, 且可进一步改进, 例如考虑盈利和亏损交易的持续时间, 并对所得到的数值进行实验。