EA: 自动交易系统 "合集"

 

自动交易系统 "合集":

ATS 基于经典的趋势跟随策略, 并经双层神经网络训练, 逆势入场。

自动交易系统 (ATS) 的问题陈述如下:

试想我们已有一个基本交易系统 - BTS。有必要创建并训练一个神级网络来做事情, 但 BTS 不能胜任这个任务。必然结果是创建一个交易系统, 由两种组合构成, 且系统互补: BTS 和 NN (神经网络)。

或是, 像英文谚语所说: 没必要再去发现大陆, 它们都已经被发现。为什么要教导一些人跑得快些, 如果我们有一辆车, 或者飞翔, 如果我们有一架飞机?

一旦我们拥有一款趋势跟随 ATS, 我们仅需教导神经网络逆势策略。这是必然的, 因为一个目的在趋势基础上进行交易的系统, 不能在盘整, 或者识别出行情回撤或翻转时交易。您可以, 当然, 利用两个 ATS - 一个跟随趋势, 另一个逆势 - 并挂载到同一图表上。另一面, 您可以训练一个神经网络来补充您已存在的交易系统。

作者: Yury Reshetov

 

关于神经网络入门级别的EA。

另外MACD版本: https://www.mql5.com/zh/code/17137

MTC 神经网络, 加上 MACD
MTC 神经网络, 加上 MACD
  • 投票: 18
  • 2017.02.09
  • Vladimir Karputov
  • www.mql5.com
MTC 神经网络, 加上 MACD - 用于 MetaTrader 5 的智能交易系统。
 
1.因为是2007年的EA,原来是4位小数(pips),现在都是5位了,我稍微修改,在sl,tp参数中加入调整
 使得sl,tp表示的意义依然是pips
 
2. EA的训练规则是:
第一次优化时 设置pass = 1, 要优化参数组合是OP1(tp1,sl1,p1)
第二次优化时 设置pass = 2, 这时EA参数中的tp1,sl1,p1,Xmn,则用第一次优化的结果OP1,Xmn.
                       本次优化的参数组合是OP2(tp2,sl2,p2)以及Xmn(x12, x22, x32, x42)
第三次优化时 设置pass = 3, 把第一次,第二优化的参数输入对应位置,然后本次要优化的参数OP3(tp3,sl3,p3),以及Xmn(x13, x23, x33, x43)
第四次优化时 设置pass = 4, 用前面三次优化后的结果输入对应位置。  本次优化参数Xmn(x14, x24, x34, x44), p4

优化完成后,那么以后实际使用时参数pass=4即可,等于是用前面四阶段的优化参数交易。

优化时的设置规则是
tp1,sl1 优化范围是10到100,按照1递增
p1: 优化范围是3到100,按照1递增
Xmn 参数按照0到200,按照1递增

其他OP2,OP3组合亦是如此设置
 

修改后EA源代码:

//+------------------------------------------------------------------+
//|                                                  Combo_Right.mq4 |
//|                               Copyright ?2008, Yury V. Reshetov |
//|                               http://bigforex.biz/load/2-1-0-171 |
//+------------------------------------------------------------------+
//2017-05-17 13:12:40 Combo_Right_2017.mq4
//https://www.mql5.com/zh/code/7917
/*
1.因为是2007年的EA,原来是4位小数(pips),现在都是5位了,我稍微修改,在sl,tp参数中加入调整
 使得sl,tp表示的意义依然是pips
 
2. EA的训练规则是:
第一次优化时 设置pass = 1, 要优化参数组合是OP1(tp1,sl1,p1)
第二次优化时 设置pass = 2, 这时EA参数中的tp1,sl1,p1,Xmn,则用第一次优化的结果OP1,Xmn.
             本次优化的参数组合是OP2(tp2,sl2,p2)以及Xmn(x12, x22, x32, x42)
第三次优化时 设置pass = 3, 把第一次,第二优化的参数输入对应位置,然后本次要优化的参数OP3(tp3,sl3,p3),以及Xmn(x13, x23, x33, x43)
第四次优化时 设置pass = 4, 用前面三次优化后的结果输入对应位置。  本次优化参数Xmn(x14, x24, x34, x44), p4

优化完成后,那么以后实际使用时参数pass=4即可,等于是用前面四阶段的优化参数交易。

优化时的设置规则是
tp1,sl1 优化范围是10到100,按照1递增
p1: 优化范围是3到100,按照1递增
Xmn 参数按照0到200,按照1递增

其他OP2,OP3组合亦是如此设置

*/
#property copyright "Copyright ?2008, Yury V. Reshetov"
#property link      "http://bigforex.biz/load/2-1-0-171"

#property strict

//---- input parameters
extern double       tp1 = 50;
extern double       sl1 = 50;
extern int          p1=10;

extern int          x12 = 100;
extern int          x22 = 100;
extern int          x32 = 100;
extern int          x42 = 100;


extern double       tp2 = 50;
extern double       sl2 = 50;
extern int          p2=20;

extern int          x13 = 100;
extern int          x23 = 100;
extern int          x33 = 100;
extern int          x43 = 100;


extern double       tp3 = 50;
extern double       sl3 = 50;
extern int          p3=20;

extern int          x14 = 100;
extern int          x24 = 100;
extern int          x34 = 100;
extern int          x44 = 100;

extern int          p4=20;
extern int          pass = 1;
extern double       lots = 0.01;
extern int          mn=888;

//---
static int          prevtime=0;
static double       sl = 10;
static double       tp = 10;


int pt=1;// 判断 pips 时用 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(Digits()==5 || Digits()==3)pt=10;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
void OnTick()
  {

   if(Time[0] == prevtime) return;
   prevtime=(int)Time[0];

   if(!IsTradeAllowed())
     {
      again();
      return;
     }

//----  如果有持仓则返回,即不开新单
   int total=OrdersTotal();
   for(int i=0; i<total; i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==mn)
           {
            return;
           }
        }
     }

//---  如果没有持仓,下面则进入开仓环节

   sl = sl1;
   tp = tp1;

   int ticket=-1;

   RefreshRates();

   if(Supervisor()>0) // 大于0则开多单
     {
      ticket=OrderSend(Symbol(),OP_BUY,lots,Ask,1,Bid-sl*Point *pt,Bid+tp*Point *pt,WindowExpertName(),mn,0,clrBlue);
      if(ticket<0)
        {
         //again(); //毫无必要。
         return;
        }
     }
   else  //否则就开空单
     {
      ticket=OrderSend(Symbol(),OP_SELL,lots,Bid,1,Ask+sl*Point *pt,Ask-tp*Point *pt,WindowExpertName(),mn,0,clrRed);
      if(ticket<0)
        {
         //again();
         return;
        }
     }
//-- Exit --
   return;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Supervisor()
  {
   if(pass==4) //第四阶段,
     {
      if(perceptron3()>0) //如果第三层是 多
        {
         if(perceptron2()>0) //如果第二层也是 多
           {
            sl = sl3;
            tp = tp3;
            return(1); //第三,二层都是多,则开多,且止盈止损按时sl3,tp3来
           }
        }
      else //否则第三层是空,则下降到第一层
        {
         if(perceptron1()<0)// 如果第一层也是空
           {
            sl = sl2;
            tp = tp2;
            return(-1);//三,一,都是空,且止盈止损按时sl2,tp2来
           }
        }

      //上面神经网络没有结果,则采用基本系统,sl,tp没有更新。
      return(basicTradingSystem());
     }

   if(pass==3)//训练的第三阶段:优化出做多的参数
     {
      if(perceptron2()>0)//第二层是>0 返回1,做多
        {
         sl = sl3;
         tp = tp3;
         return(1);
        }
      else //否则 用基本系统
        {
         return(basicTradingSystem());
        }
     }

   if(pass==2)//训练的第二阶段:优化出做空的参数
     {
      if(perceptron1()<0) //第一层<0 返回-1,则做空
        {
         sl = sl2;
         tp = tp2;
         return(-1);
        }
      else
        {
         return(basicTradingSystem());
        }
     }

//--- pass = 1,即设置的初始值 第一阶段 ,用 基本系统训练,优化出参数tp1,sl1,p1

   return(basicTradingSystem());
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double perceptron1()
  {
  if(p2*4>Bars-1)return(0);
  
   double       w1 = x12 - 100;
   double       w2 = x22 - 100;
   double       w3 = x32 - 100;
   double       w4 = x42 - 100;
   double a1 = Close[0] - Open[p2];
   double a2 = Open[p2] - Open[p2 * 2];
   double a3 = Open[p2 * 2] - Open[p2 * 3];
   double a4 = Open[p2 * 3] - Open[p2 * 4];
   return(w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double perceptron2()
  {
  if(p3*4>Bars-1)return(0);
   double       w1 = x13 - 100;
   double       w2 = x23 - 100;
   double       w3 = x33 - 100;
   double       w4 = x43 - 100;
   double a1 = Close[0] - Open[p3];
   double a2 = Open[p3] - Open[p3 * 2];
   double a3 = Open[p3 * 2] - Open[p3 * 3];
   double a4 = Open[p3 * 3] - Open[p3 * 4];
   return(w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double perceptron3()
  {
  if(p4*4>Bars-1)return(0);
   double       w1 = x14 - 100;
   double       w2 = x24 - 100;
   double       w3 = x34 - 100;
   double       w4 = x44 - 100;
   double a1 = Close[0] - Open[p4];
   double a2 = Open[p4] - Open[p4 * 2];
   double a3 = Open[p4 * 2] - Open[p4 * 3];
   double a4 = Open[p4 * 3] - Open[p4 * 4];
   return(w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double basicTradingSystem()
  {
   return(iCCI(Symbol(), 0, p1, PRICE_OPEN, 0));
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void again()
  {
   prevtime=(int)Time[1];
   Sleep(300);
  }
//+------------------------------------------------------------------+
 

贴个附件,方便下载。

附加的文件:
 

我在EURUSD,M30图表,经过一个多小时训练,把PASS1,PASS2,PASS3,PASS4都依次训练一遍,最后得到PASS4的全部参数就是最优的。

完了测试下,60%收益,回撤2.63%,但这只代表我训练的时段经过优化后的效果,不代表为来实战。

贴上最后拟合好后的参数,见附件,实际使用时要注意,交易的品种一定要与你训练时的品种和周期一样。



附加的文件:
原因: