📅 财经日历 📊 实时波动 📈 大盘云图 📶 行情走势 🆚 投机情绪 🚀 今日热点

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

    2013-09-02 · 8416 阅读
    去年年底结束的国际大赛的第一名为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!
    来源:必胜外汇
    ""
    还没有人打赏,支持一下
    回复

    举报

     

    回答|共 11 个

    latitude43 LV1

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

    看过了,还是支持一下

    大侠是我 LV3

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

    看过了,还是支持一}

    竹乐居士 LV4

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

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

    andy LV3

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

    EA真的能赚钱么?

    微不足道 LV3

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

    感谢分享

    我的家 LV7

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

    看看怎么样

    有点傻 LV3

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

    看看是什么东西啊

    hnc69pag LV3

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

    谢谢分享!!!!!

    shzq LV4

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

    谢谢楼主的分享
    12下一页
    您需要登录后才可以回帖 登录 | 注册

    提醒: 禁止引战、谩骂、灌水内容

    微信二维码

    有问题联系客服