下载MetaTrader 5

如何快速创建一个"2010 年自动交易锦标赛"专用"EA 交易"

8 十一月 2013, 07:31
Andrew Kornishkin
0
1 034

简介

为了开发出一种参与“2010 自动交易锦标赛”的“EA 交易”,我们使用一个即用的、来自《交易机器人的原型》一文的“EA 交易”模板。 即便是 MQL5 程序员初哥也能胜任此任务,因为您策略的基类、函数和模板都已经开发完毕。 编写少量的代码来实现您的交易理念就足够了。  

我们需要准备的内容:
  • 策略选择
  • 编写“EA 交易”
  • 测试
  • 策略测试程序中的优化
  • 策略优化
  • 以不同时间间隔测试

1. 策略选择

人们相信随势交易比区间交易更有利可图,而且盘中量发生的反弹,要比通道边界的崩溃更加频繁。

基于上述假设,我们会向着通道边界(轨道线)反弹的当前趋势建仓。 我们会根据平仓信号或在达到 Stop Loss(止损)或 Take Profit(获利)水平时平仓。

  与趋势信号一样,我们会利用 MACD 增长或在日线图上的减少,还会根据小时时间表上的通道边界反弹进行交易。  

图 1. EURUSD 日线图上的 MACD 指标

图 1. EURUSD 日线图上的 MACD 指标

如果 MACD 指标连续于两个柱上增长 - 此为买入信号。 如连续在两个柱上减少 - 则为卖出信号。

图 2. 轨道线边界价格反弹

图 2. 轨道线边界价格反弹


2. 编写“EA 交易”

2.1. 包含的模块

专家会采用来自 ExpertAdvisor.mqh 模块的“EA 交易”类。

#include <ExpertAdvisor.mqh>

2.2. 输入变量

input int    SL        =  50; // 止损距离
input int    TP        = 100; // 获利距离
input int    TS        =  50; // 追踪止损距离
input int    FastEMA   =  15; // 快速 EMA
input int    SlowEMA   =  26; // 慢速 EMA
input int    MACD_SMA  =   1; // MACD 信号线
input int    EnvelPer  =  20; // 轨道线周期
input double EnvelDev  = 0.4; // 轨道线方差
input double Risk      = 0.1; // 风险

2.3. 创建一个继承自 CExpertAdvisor 的类

class CMyEA : public CExpertAdvisor
  {
protected:
   double            m_risk;          // 风险大小
   int               m_sl;            // 止损
   int               m_tp;            // 获利
   int               m_ts;            // 追踪止损
   int               m_pFastEMA;      // 快速 EMA
   int               m_pSlowEMA;      // 慢速 EMA
   int               m_pMACD_SMA;     /// MACD 信号线
   int               m_EnvelPer;      // 轨道线周期
   double            m_EnvelDev;      // 轨道线方差
   int               m_hmacd;         // MACD指标句柄
   int               m_henvel;        // 轨道线指标句柄
public:
   void              CMyEA();
   void             ~CMyEA();
   virtual bool      Init(string smb,ENUM_TIMEFRAMES tf); // 初始化
   virtual bool      Main();                              // 主函数
   virtual void      OpenPosition(long dir);              // 根据信号开仓
   virtual void      ClosePosition(long dir);             // 根据信号平仓
   virtual long      CheckSignal(bool bEntry);            // 检查信号
  };
//------------------------------------------------------------------

2.4. 删除指标
//------------------------------------------------------------------    
void CMyEA::~CMyEA()
  {
   IndicatorRelease(m_hmacd);  // 删除MACD指标
   IndicatorRelease(m_henvel); // 删除轨道线指标
  
}
//------------------------------------------------------------------    

2.5. 初始化变量
//------------------------------------------------------------------    Init
bool CMyEA::Init(string smb,ENUM_TIMEFRAMES tf)
  {
   if(!CExpertAdvisor::Init(0,smb,tf)) return(false);    // initialize parent class
   // 复制参数
    m_risk=Risk; 
   m_tp=TP; 
   m_sl=SL; 
   m_ts=TS;
   m_pFastEMA=FastEMA; 
   m_pSlowEMA=SlowEMA; 
   m_pMACD_SMA=MACD_SMA;
   m_EnvelPer = EnvelPer;
   m_EnvelDev = EnvelDev;
   m_hmacd=iMACD(m_smb,PERIOD_D1,m_pFastEMA,m_pSlowEMA,m_pMACD_SMA,PRICE_CLOSE);      // 创建MACD指标
   m_henvel=iEnvelopes(m_smb,PERIOD_H1,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev); // 创建轨道线指标
   if(m_hmacd==INVALID_HANDLE ||m_henvel==INVALID_HANDLE ) return(false);             //如果报错,则退出
   m_bInit=true; 
   return(true);                                                                      // 允许交易
  
} 


2.6. 交易函数

//------------------------------------------------------------------    CheckSignal
long CMyEA::CheckSignal(bool bEntry)
  {
   double macd[4],   // MACD 指标值数组
         env1[3],    // 轨道线上轨值数组
         env2[3];    // 轨道线下轨值数组
   MqlRates rt[3];   // 最近3个柱形的价格数组
   
   if(CopyRates(m_smb,m_tf,0,3,rt)!=3) // 将最近3个柱形的价格值复制到数组中
     {
       Print("CopyRates ",m_smb," history is not loaded"); 
        return(WRONG_VALUE);
     
}
   // 将指标值复制到数组
   if(CopyBuffer(m_hmacd,0,0,4,macd)<4 || CopyBuffer(m_henvel,0,0,2,env1)<2 ||CopyBuffer(m_henvel,1,0,2,env2)<2)
     { 
        Print("CopyBuffer - no data"); 
       return(WRONG_VALUE);
     
}
   // 如果MACD在增长并且价格从轨道线下轨反弹,买入
   if(rt[1].open<env2[1] && rt[1].close>env2[1] && macd[1]<macd[2] &&  macd[2]<macd[3])
      return(bEntry ?ORDER_TYPE_BUY:ORDER_TYPE_SELL); // 买入的条件
   // 如果MACD在下降并且价格从轨道线上轨向下反弹,卖出
   if(rt[1].open>env1[1] && rt[2].close<env1[1]&& macd[1]>macd[2] &&  macd[2]>macd[3])
      return(bEntry ?ORDER_TYPE_SELL:ORDER_TYPE_BUY); // 卖出条件

   return(WRONG_VALUE); // 如果没有信号
  
}

CMyEA ea; // 类的实例

所以,编写代码后,将作为结果的“EA 交易”发送至策略测试程序。


3. 测试

在策略测试程序中,周期为 "去年" ,货币对为 EURUSD 时 ,我们得到下述图表:

图 3. 带初始化参数的交易系统的测试结果

图 3. 带初始化参数的交易系统的测试结果

结果不是那么令人满意,所以我们开始优化 Stop Loss 和 Take Profit 的水平。


4. 策略测试程序中的优化

我们会以 10-500 的间隔、50 的步幅,优化 Stop Loss 和 Take Profit 参数。

最佳结果: Stop Loss = 160,Take Profit = 310。优化 Stop Loss 与 Take Profit 之后,我们收到 67% 的可盈利交易(之前是 36%)和 $1522.97 的净利润。 由此,通过简单的处理,我们升级好的系统已经实现了收支平衡,甚至还有一些盈利。

图 4. 带有优化 Stop Loss 与 Take Profit 的交易系统的测试结果

图 4. 带有优化 Stop Loss 与 Take Profit 的交易系统的测试结果

接下来,我们来优化轨道线周期与方差。

轨道线周期会以 4 为步幅,从 10 变到 40,而方差则从 0.1 变到 1,步幅为 0.1。

最佳优化结果为: 轨道线周期 = 22,轨道线方差 = 0.3。 即使现在,我们已经获得了 $14418.92 的净利润和 79% 的可盈利交易。

图 5. 带有优化轨道线周期与方差的交易系统的测试结果

图 5. 带有优化轨道线周期与方差的交易系统的测试结果

如果我们将风险加到 0.8,我们就会获得 $77330.95 的净利润。

图 6. 带有优化风险的交易系统的测试结果

图 6. 带有优化风险的交易系统的测试结果

 

5. 策略优化

策略优化可能包含下述步骤:

  • 更改趋势指标
  • 选择另一条轨道线
  • 选择另一个时间表
  • 更改交易条件

5.1. 更改趋势指标

通过《在 MQL5 中寻找趋势的几种方法》一文我们可以看出,最佳的趋势指标是移动平均线和移动平均“扇形图”。

我们用简单的移动平均线来替代 MACD 指标。 EA 代码请见随附的 Macena.mq5 文件。

5.2. 选择另一条轨道线

Envelopes (轨道线)旁边,您也可以自行选择另一条轨道线。 例如:Price Channel(价格通道)、Bollinger Bands (布林带)或是某条基于移动平均线的轨道线。

随附的 Maboll.mq5 文件中,有一份使用 MA 与布林带的 EA 示例。

5.3. 选择另一个时间表

我们将时间表改大或改小。 大时间表用 H4,小时间表则用 M15,然后测试并优化您的系统。

为达此目的,只需替换代码中的一行:

m_henvel=iEnvelopes(m_smb,PERIOD_H1,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev);  // 创建轨道线指标

如是 H4 时间表:

m_henvel=iEnvelopes(m_smb,PERIOD_H4,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev);  // 创建轨道线指标 

如是 M15 时间表:

m_henvel=iEnvelopes(m_smb,PERIOD_M15,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev);  // 创建轨道线指标

5.4. 更改交易条件

作为一次试验,我们还要更改交易条件。  

  1. 让系统具备反向的能力。 我们会在从轨道线下边界反弹时买入,并在从轨道线上边界反弹时卖出。
  2. 不按日趋势检查系统。 也很简单,只需将下述代码插入交易块即可:
    //------------------------------------------------------------------ 检查信号
    long CMyEA::CheckSignal(bool bEntry)
      {
       double env1[3],   // 轨道线上轨值数组
             env2[3];    // 轨道线下轨值数组
       MqlRates rt[3];   // 最近3个柱形的价格数组
    
       if(CopyRates(m_smb,m_tf,0,3,rt)!=3) // 将最近3个柱形的价格值复制到数组中
         {
          Print("CopyRates ",m_smb," history is not loaded");
          return(WRONG_VALUE);
         
    }
    // 将指标值复制到数组
       if(CopyBuffer(m_henvel,0,0,2,env1)<2 || CopyBuffer(m_henvel,1,0,2,env2)<2)
         {
          Print("CopyBuffer - no data");
          return(WRONG_VALUE);
         
    }
    // 如果MACD在增长并且价格从轨道线下轨反弹,买入
       if(rt[1].open<env2[1] && rt[1].close>env2[1])
          return(bEntry ?ORDER_TYPE_BUY:ORDER_TYPE_SELL); // 买入的条件
    // 如果MACD在下降并且价格从轨道线上轨向下反弹,卖出
       if(rt[1].open>env1[1] && rt[2].close<env1[1])
          return(bEntry ?ORDER_TYPE_SELL:ORDER_TYPE_BUY); // 卖出条件
    
       return(WRONG_VALUE); // 如果没有信号
      
    }
    
    CMyEA ea; // 类的实例
    //------------------------------------------------------------------    OnInit
    
    

     3. 如果价格未大幅下滑、而是转而向上,我们就会平卖出持仓。

     4. 如果价格未大幅上扬、而是转而向下,我们就会平买入持仓。

您可以自创方法来优化交易策略,相关文献中也有一些介绍。

更深入的研究,就靠您自己了。


6. 以不同时间间隔测试

按相同的时间间隔测试我们的“EA 交易”,每次 1 个月。 我们将 "去年" 作为一个测试周期。 时间周期 - 3 个月。

测试间隔
利润,以美元计
可盈利交易
 1.01.2010 - 30.03.2010
7239.50 76.92%
 1.02.2010 - 30.04.2010 -6577.50 0%
 1.03.2010 - 30.05.2010 -8378.50 50%
 1.04.2010 - 30.06.2010 -6608.00 0%
 1.05.2010 - 30.07.2010  41599.50 80%
  1.06.2010 - 30.08.2010  69835.50  85%
总结: 将“EA 交易”搭配如此一种进取性资金管理使用,并不可取。 降低风险。


总结

简要总结: 以此模板为基础,您可以用最少的时间和精力,快速实现您的交易理念。

对于系统参数和交易标准的优化也没有任何问题。

要创建一套稳定性更高的交易系统,有必要在更长的时间间隔内对所有参数进行优化。

参考资源列表:
  1. 《用 MQL5 语言编写的 20 种交易信号》
  2. 《交易机器人的原型》
  3. 《在 MQL5 中寻找趋势的几种方法》
  4. 《基于流行交易系统的“EA 交易”以及交易机器人优化点石成金》
  5. 《“EA 交易”中的限制和验证》
  6. 《利用 MQL5 面向对象编程法编写“EA 交易”》
  7. 《“EA 交易”中的资金管理函数》。  

本文译自 MetaQuotes Software Corp. 撰写的俄文原文
原文地址: https://www.mql5.com/ru/articles/148

附加的文件 |
mabol.mq5 (11.2 KB)
macena.mq5 (11.86 KB)
maena.mq5 (11.16 KB)
使用TesterWithdrawal() 函数模拟利润提取 使用TesterWithdrawal() 函数模拟利润提取

本文讲述的是用于交易系统风险评估的TesterWithDrawal()函数的用法,即运行期间提取一部分资产。此外,还会讲到此函数对于策略测试程序中资产净值减少的计算算法的作用。在优化您的EA交易的时候,就会用到此函数。

利用 MQL5 面向对象编程法编写"EA 交易" 利用 MQL5 面向对象编程法编写"EA 交易"

本文将着重讲述的是面向对象法,将我们曾在"针对初学者以 MQL5 编写"EA 交易"的分步指南"文中谈到的内容落到实处-创建简单的"EA 交易"。 很多人都觉得难,但是,我向您保证,看完本文之后,您就能够编写自己的面向对象 "EA 交易"了。

Simulink: EA 交易开发人员指南 Simulink: EA 交易开发人员指南

我不是专业的程序员。 正因如此,对于我来说,要进行交易系统开发,“由简入繁”是最最重要的原则。 那么,对我来说,怎样才算是简单呢? 首先,是创建系统过程的可视化,及其工作的逻辑。 还有,手写代码要尽可能地少。 在本文中,我将尝试根据 Matlab 软件包完成交易系统的创建和测试,然后再编写一个 MetaTrader 5 “EA 交易”。而测试过程会采用 MetaTrader 5 的历史数据。

利用模糊逻辑创建指标的简单示例 利用模糊逻辑创建指标的简单示例

本文专门讲解金融市场分析模糊逻辑理念的实际应用。 我们会根据两条模糊规则和轨道线指标,提供生成信号的指标示例。 开发出的指标会采用多个指标缓冲区:7 个计算用缓冲区,5 个图表显示用缓冲区和 2 个颜色缓冲区。