10评论

4收藏

2009年mt4编程--神经网络的EA的示例(含源码)

avatar 金市有约 | 6658 人阅读 | 10 人评论 | 2013-09-02

去年年底结束的国际大赛的第一名为Better所夺得,他采用的就是神经网络原理的EA,这使得用神经网络方法做EA成为不少人关注的焦点。这里翻译一篇采用神经网络做EA的不错的示例文章,当然附有源码是吸引人的地方,不过也许作者提出了研究神经网络EA的一些思考更为值得注意。

作者提出了∶
1。“如果有飞机,为什么还要教人类去飞?”
意思是研究是经网络不必从零起步。MT4里已有了不错的“遗传算法”
文中介绍了如何利用MT4已有的“遗传算法”

2。大家都说做单子最重要的是“顺势而为”,但更需要解决的是∶
“一个基于趋势的交易系统是不能成功交易在盘整(sideways trends),
也不能识别市场的回调(setbacks)和逆转(reversals.,反向走势)!”
这可是抓到不少人心中的“痒处”,有多少人不是到了该逆势时没转向而产生亏损呢?

3。训练神经网络需要用多长的历史数据,提出了并不是用的历史数据越长越好,另外也不是训练的间隔越短越好,文中提出了什么情况下有需再训练它。

等等。。
(ATS)自动的(智能的,采用神经网络的)交易系统的问题表述如下
如果我们有一个(BTS, basic trading system),同时需要用创建一个神经网络系统并教会它做BTS所不能做的事,按这个思路就是要创建这样一个交易系统∶它由互相补充(配合)的两部分组成,BTS和NN(神经网络)。
呃,英语说,我们不需要再去发现“新大陆”,它们是已经存在的东西!进一步说,如果我们已经有了汽车,那为什么还要教人如何跑得快?如果有飞机,为什么还要教人类去飞?
一旦有一个趋势交易系统的ATS,我们仅需要教会这个神经网络如何逆势(反趋势)交易的策略。这一点是非常必要的,因为一个基于趋势的交易系统是不能成功交易在盘整(sideways trends),也不能识别市场的回调(setbacks)和逆转(reversals.,反向走势)!当然,你可以采用两个ATS,一个基于“趋势”,一个基于“反趋势”(逆向),然后把它们挂到同一图表上。另一个办法是,你能教会神经网络如何与你现有的系统“互补地”协调工作!
为实现这个目标,我们设计了一个两层的神经网络,下层有两个感知机(perceptrons)上层有一个感知机。
这个神经网络的能输出下列三种状态之一
进场做多
进场做空
不确定状态
实际上,第三种状态是就把控制权交给BTS,反之前两种状态是交易信号由神经网络给出。
神经网络的“教育”分成三步骤,每一步骤“教育”一个感知机,在任何一步骤,这个优化了的BTS必须存在为的是“感知机们”知道它自己能做什么。
感知机们分别的“教育”由遗传算法来承担,由于这样的算法的缺乏,换句话说,搜索到的这样的算法有限,限制了“输入”(参数变量)的数量(借助这样算法得到的参数变量的值),然而,每一步骤的“教育”是密切配合补充的。(因此效果还是不错),这样这个神经网络不会太大,整个的优化也不会耗费太多的时间。
在“教育”NN之前的一步是对BTS进行优化。

为了不使我们自己也被搞糊涂了,我们将已经测试通过的ATS的输入(参数变量)记录上(”通过”("pass")的步骤号(stage number).,输入s(参数变量)的标识符将和stage number(步骤号)一致(等同)。
这样,我们开始对这个NN进行优化和“教育”的准备。设置初始保证金为$100万(以便于在优化期间不产生人为的补充保证金的通知)。Input(参数变量)是按“余额”进行优化,设置EA的Strategy Tester的测试的属性tab为"Testing" 。开始运行遗传算法。
在这个EA的开仓量 "lots".的值设为0.1 lot。

从这个ATS算法明确地有效开始,实施优化,所采用复盘模型是∶“仅用开盘价(以最快速的方法分析刚形成的柱线)”。

优化步骤1,BTS的优化
设置为 1 为这input(参数变量)“为通过”(the input "pass")。我们仅仅优化步骤1相关的那些inputs(参数变量),即,尾标为 1 的参数变量,于是,我们仅仅测试优化有关的inputs而不测试其他的变量参数

tp1,BTS的所取的止盈值(TakeProfit)。在step 1,优化的值的范围在10到100,

sl1,BTS的所取的止损值(StopLoss)。在step 1,优化的值的范围在10到100 。
p1,用于BTS的CCI的周期值。在step 1 ,优化的值的范围在 3到100
下面是BTS优化的结果

                               
登录/注册后可看大图



步骤 2 ,“教育负责“开空仓”(short positions)的感知机

根据步骤的步骤号,设置(input,参数变量) 的"pass"的值为 2。

不测试那些已经测试过的优化了的以前步骤的inputs.(变量参数)。以防万一,保存以前步骤获得的inputs(变量参数值)到一个文件中去
根据我们的规则,必须是测试那些是在尾标为 2的inputs(变量参数)。
x12, x22, x32, x42 是识别并开空仓的感知机的权重,它们的值在step 1时被优化在范围0 to 200
tp2  (TakeProfit) 是感知机所开的仓的止盈值,它们的值在step 1时被优化在范围10 to 100。
sl2 (StopLos) 在 step 1它是感知机所开的仓的止损值,被优化值的范围在 10 to 100
p2 感知机所分析的价格差的周期值 (iiCCI()函数的一个参数∶period - Averaging period for calculation),在step 1 它的值所优化的范围在3 to 100
现在,开始用遗传算法来优化“教育”NN(让它“学习”市场),获得的结果如下∶


                               
登录/注册后可看大图


                               
登录/注册后可看大图
步骤 3 “教育”负责开多仓的感知机(“学习”市场)。
设置值 3 (根据步骤的步骤号)说明这些input(变量参数)已经“通过”(the input "pass")
同样,不测试,那些已经测试过的优化了的,以前步骤的inputs.(变量参数值),以防万一,保存以前步骤获得的inputs.(变量参数值) 到一个文件中去
根据我们的规则,优化测试的inputs(变量参数值)必须是尾标为3的那些变量参数。
x13, x23, x33, x43是识别多仓的感知机的权重,它们的值在step 1时被优化时得到的范围在0 to 200
tp 3  (TakeProfit) 是感知机所开的仓的“止盈值”,它的值在step 1时被优化时的范围是在10 to 100。
sl3 (StopLoss) 是感知机所开的仓的“止盈值”,它们的值在step 1时被优化为范围是10 to 100。
p3 --感知机所分析的价差的周期值。它在步骤 1 优化时得到的值的范围是 3 to 100 。
启动采用遗传算法的优化来“教育”NN,所获得的结果如下∶

                               
登录/注册后可看大图

                               
登录/注册后可看大图

步骤 4 (最终步骤) “教育”第一层,即“教育”在上层的感知机。
Set the value 4 (according to the stage number) for the input "pass".
根据步骤的步骤号,设置值4 为输入通过(for the input "pass")

不测试那些在之前步骤已经测试过的优化了的“输入” (inputs) (意思是∶已经在之前步骤优化过的变量的参数值就不再优化它们了)。以防万一,将之前步骤获得的这些变量的参数值存到一个文件中去。

根据我们的规则,只测试优化标识符最后位是4的那些inputs(变量的参数值)

x14, x24, x34, x44 是第一层感知机参数的权重值。在步骤 1 时它们被优化的值的范围在0 to 200 。
p4 被感知机分析的价差的值的周期。在步骤 1 它的值的范围被优化在 3 to 100 。
采用遗传算法来优化,启动“教育”来教它“学习”。所获得结果如下∶

                               
登录/注册后可看大图

                               
登录/注册后可看大图


这就是全部,神经网络已经被“教育”了。

这个ATS有一个不能被优化的input(参数) mn-- Magic Number.(魔法号)它是一个交易系统它所开的仓位的识别符,为的是不和手动开仓或其他ATSes开的仓位混淆。这个Magic Number的值必须是唯一的并且和这个特别的EA尚未开仓的magic numbers不一致。
P.S.


出于保证有一些安全保险的考虑,初始保证金的金额设置是考虑为绝对最大回落的两倍

这个EA的源代码没有优化。
如果你需要置换嵌入另一个交易系统算法的BTS,你必须修改BTS功能的内部。
以便于不输入优化时的初值,终值和步长,你可采用已备好的combo.set文件,把它放置到MT4的 \tester 目录并加载这个EA的属性(properties)到Strategy Tester。
这个EA的再优化可在周末进行,即周六和周日,但仅在前面一周的结果是不盈利的。亏损的出现意味着市场已经改变,于是需要重新优化,若是仍然获利意味着这个ATS不需要重新优化,它对市场目前的模型的识别继续有效!
源码:
//+------------------------------------------------------------------+
//|                                                  Combo_Right.mq4 |
//||                              Copyright 2010,fx68com@gmail.com||
//||                                              http://www.fx68.com ||
//+------------------------------------------------------------------+
#property copyright "Copyright 2010,fx68com@gmail.com"
#property link      "http://www.fx68.com"
//---- 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.1;
extern int          mn = 888;
static int          prevtime = 0;
static double       sl = 10;
static double       tp = 10;
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
   if (Time[0] == prevtime) return(0);
   prevtime = Time[0];
   
   if (! IsTradEAllowed()) {
      again();
      return(0);
   }
//----
   int total = OrdersTotal();
   for (int i = 0; i < total; i++) {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == mn) {
         return(0);
      }
   }
   
   sl = sl1;
   tp = tp1;
   
   int ticket = -1;
   
   RefreshRates();
   
   if (Supervisor() > 0) {
      ticket = OrderSend(Symbol(), OP_BUY, lots, NormalizeDouble(Ask,Digits), 1, NormalizeDouble(Bid - sl * Point,Digits), NormalizeDouble(Bid + tp * Point,Digits), WindowExpertName(), mn, 0, Blue);
      if (ticket < 0) {
         again();      
      }
   } else {
      ticket = OrderSend(Symbol(), OP_SELL, lots, NormalizeDouble(Bid,Digits), 1, NormalizeDouble(Ask + sl * Point,Digits),NormalizeDouble(Ask - tp * Point,Digits), WindowExpertName(), mn, 0, Red);
      if (ticket < 0) {
         again();
      }
   }
//-- Exit --
   return(0);
}
//+--------------------------- getLots ----------------------------------+

double Supervisor() {
   if (pass == 4) {
      if (perceptron3() > 0) {
         if (perceptron2() > 0) {
            sl = sl3;
            tp = tp3;
            return(1);
         }
       } else {
         if (perceptron1() < 0) {
            sl = sl2;
            tp = tp2;
            return(-1);
         }
      }
      return(basicTradingSystem());
   }
   if (pass == 3) {
      if (perceptron2() > 0) {
         sl = sl3;
         tp = tp3;
         return(1);
       } else {
         return(basicTradingSystem());
       }
   }
   if (pass == 2) {
      if (perceptron1() < 0) {
         sl = sl2;
         tp = tp2;
         return(-1);
       } else {
         return(basicTradingSystem());
       }
   }
   return(basicTradingSystem());
}
double perceptron1()   {
   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()   {
   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()   {
   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 = Time[1];
   Sleep(30000);
}
必胜注:关注神经网络应用的朋友越来越多,我们收集了这篇文章供大家参考。但是这篇文章的做法似乎只是系统测试优化的简化版,分步测试,减少了组合的次数,但几步最优的组合在一起未必结果最优。当然他这个EA是把信号分别发出,1-4的部分之间相对独立,这样测试也是可以的,也就基本等同于全部一次性测试。如果不是这种结构的话,就会失去很多有利的参数组合。真正的神经网络应该是交互式的自动获取有利参数。另外,设置步骤写的不够清楚,似乎这样更明确:
训练方法:  
1 打开智能交易测试界面,选择Combo_Right,单击“智能交易属性”按钮,将起始资金设置为1000000(为了避免中途没钱,所以资金设置大一点)。  
2 切换到“输入参数”选项卡,单击“加载”按钮,将combo.set里的参数加载到EA中。
3 在参数“tp1”、“sl1”和“p1”前打上勾,
将“pass”参数设置为1,单击“确定”按钮退出。
4 在智能交易测试界面,选择“优化”复选项,然后选择一个商品,复盘模型设置为“仅用开盘价”(这个EA只对每根K线的收盘价进行分析,因此选用“每个即时价位”结果是一样的,而花的时间要多得多,所以没有必要),选择起始日期(俺推荐先试试2个月的长度),时间周期任意吧,作者给的图是一小时,因此我测试的时候也是用的一小时。选择好以后,单击“开始”按钮。
5 优化完毕,将最优结果备份,然后单击“智能交易属性”按钮,切换到“输入参数”选项卡,将“tp1”、“sl1”和“p1”前面的勾去掉,并将刚才的最优结果输入到“赋值”一栏。  
6 在所有尾号为“2”的参数前打上勾,
将“pass”参数设置为2,单击“确定”按钮退出,单击“开始”按钮。  
7 优化完毕,将最优结果备份,然后单击“智能交易属性”按钮,切换到“输入参数”选项卡,将所有尾号为“2”的参数前面的勾去掉,并将刚才的最优结果输入到“赋值”一栏。
8 在所有尾号为“3”的参数前打上勾,
将“pass”参数设置为3,单击“确定”按钮退出,单击“开始”按钮。
9 优化完毕,将最优结果备份,然后单击“智能交易属性”按钮,切换到“输入参数”选项卡,将所有尾号为“3”的参数前面的勾去掉,并将刚才的最优结果输入到“赋值”一栏。  
10 在所有尾号为“4”的参数前打上勾,
将“pass”参数设置为4,单击“确定”按钮退出,单击“开始”按钮。
11 优化完毕,将最优结果备份,然后单击“智能交易属性”按钮,切换到“输入参数”选项卡,将所有尾号为“4”的参数前面的勾去掉,并将刚才的最优结果输入到“赋值”一栏。  
12 单击“保存”按钮,将最优参数保存为一个文件。  
训练完毕,现在你手里有了针对某个特定货币、某个特定时间周期在某个时间段的最优参数,然而,这只是根据历史数据进行的最优化,至于实测的效果,则要挂着观察了。实测时,“pass”参数一定要设置为4!
来源:必胜外汇
""
还没有人打赏,支持一下

评论|共 10 个

latitude43

发表于 2013-9-11 06:16:24 | 显示全部楼层

看过了,还是支持一下

大侠是我

发表于 2013-9-15 21:07:55 | 显示全部楼层

看过了,还是支持一}

竹乐居士

发表于 2013-9-25 13:00:16 | 显示全部楼层

好好好红红火火红红火火好

andy

发表于 2014-11-2 08:52:25 | 显示全部楼层

EA真的能赚钱么?

微不足道

发表于 2014-11-2 23:43:54 | 显示全部楼层

感谢分享

我的家

发表于 2014-11-3 03:33:30 | 显示全部楼层

看看怎么样

有点傻

发表于 2014-11-5 01:35:20 | 显示全部楼层

看看是什么东西啊

hnc69pag

发表于 2014-11-26 00:17:23 | 显示全部楼层

谢谢分享!!!!!

shzq

发表于 2019-3-13 16:32:07 来自手机 | 显示全部楼层

谢谢楼主的分享

12下一页
您需要登录后才可以回帖 登录 | 注册 微信登录

EA之家评论守则