English Русский Español Deutsch 日本語 Português
preview
神经网络实验(第 1 部分):重温几何学

神经网络实验(第 1 部分):重温几何学

MetaTrader 5测试者 | 6 九月 2022, 12:36
1 822 0
Roman Poshtar
Roman Poshtar

概述

在本文中,我想与大家分享我的神经网络实验。在阅读了 MQL5 上提供的大量信息后,我得出结论,就是理论知识足够了。 那里有许多好文章、函数库和源代码。 不幸的是,所有这些数据并不能得出一个合乎逻辑的结论 — 可盈利的一款交易系统。 我们试着解决这个问题。

我并非这个领域的专家,更不是作家或记者,但我会尝试以一种易于理解的方式表达我的思路,分享我的经验。

这些素材主要是为初学者设计的,比如我自己。


我的理解。 基础

一般来说,神经网络善于识别形态,而传递给神经网络进行训练的数据至关重要。 我将从这个假设开始。 我们要用到几何学。 我将把几何形状转换成神经网络。 首先,我们用一个常规的感知器,我在这里找到了它的样本(МTC Сombo - MetaTrader 4 的智能系统)。 在执行测试时,我决定放弃振荡器,转而采用均线。 测试若是涉及振荡器,则不会产生好结果。 我相信,当价格上升,振荡器下降时,每个人都知道所谓的背离。 均线参数更接近价格本身。


形状和线条

基准将由参数为 1 和 24、应用简单方法、收盘价的两条移动平均值指标组成。 换言之,其思路是不仅要传递当前指标位置,还要传递当前指标之前的状态。 在我看到的许多例子中,价格直接传递给神经网络,我认为这是根本错误的。 

我以价值点的形式传递所有数值,这非常重要,因为这些数值有一个特定的范围,它们不能超出该范围。 将价格传递给神经网络是没有意义的,因为它可能在不同的范围内振荡,例如 10 年。 另外,请记住,在构建形状时,我们可用到不同数量的指标参数。 形状即可以很复杂,也可以很简单。 下面提供了一些可能的选项。 当然,您可以提出自己的方法。

     形状 1:简单线条

       已收盘蜡烛 1、4、7 和 10 距 MA 1 和 MA 24 之间的点数距离。

      感知器 1

      double perceptron1() 
        {
         double w1 = x1 - 100.0;
         double w2 = x2 - 100.0;
         double w3 = x3 - 100.0;
         double w4 = x4 - 100.0;
         
         double a1 = (ind_In1[1]-ind_In2[1])/Point();
         double a2 = (ind_In1[4]-ind_In2[4])/Point();
         double a3 = (ind_In1[7]-ind_In2[7])/Point();
         double a4 = (ind_In1[10]-ind_In2[10])/Point();
         
         return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
        }


        形状 2:简单线条

          已收盘蜡烛 1-4、4-7 和 7-10 距 MA1 之间的点数距离。

          感知器 2

          double perceptron2() 
            {
             double w1 = y1 - 100.0;
             double w2 = y2 - 100.0;
             double w3 = y3 - 100.0;
             
             double a1 = (ind_In1[1]-ind_In1[4])/Point();
             double a2 = (ind_In1[4]-ind_In1[7])/Point();
             double a3 = (ind_In1[7]-ind_In1[10])/Point();
             
             return (w1 * a1 + w2 * a2 + w3 * a3);
            }


            形状 3:简单线条

              已收盘蜡烛 1-4、4-7 和 7-10 距 MA 24 之间的点数距离。

              感知器 3

              double perceptron3() 
                {
                 double w1 = z1 - 100.0;
                 double w2 = z2 - 100.0;
                 double w3 = z3 - 100.0;
                 
                 double a1 = (ind_In2[1]-ind_In2[4])/Point();
                 double a2 = (ind_In2[4]-ind_In2[7])/Point();
                 double a3 = (ind_In2[7]-ind_In2[10])/Point();
                 
                 return (w1 * a1 + w2 * a2 + w3 * a3);
                }


                形状 4:蝴蝶(轨迹线)

                  已收盘蜡烛 1--10 距 MA 1 之间的点数距离。 以及已收盘蜡烛 1-10 距 MA 24 点数距离。蜡烛 1 的 MA 1 和 蜡烛 10 的 MA 24 之间的点数距离。 蜡烛1 的 MA 24 和蜡烛10 的 MA 1 之间的点数距离。 结果是一只蝴蝶。

                  感知器 4

                  double perceptron4() 
                    {
                     double w1 = f1 - 100.0;
                     double w2 = f2 - 100.0;
                     double w3 = f3 - 100.0;
                     double w4 = f4 - 100.0;
                     
                     double a1 = (ind_In1[1]-ind_In1[10])/Point();
                     double a2 = (ind_In2[1]-ind_In2[10])/Point();
                     double a3 = (ind_In1[1]-ind_In2[10])/Point();
                     double a4 = (ind_In2[1]-ind_In1[10])/Point();
                     
                     return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
                    }


                    形状 5:四边形

                      已收盘蜡烛 1-1,10-10 距指标之间的点数距离。 以及 MA1 的 1-10 之间的点数距离,和指标 MA 24 的 1-10 之间的点数距离。 结果是一个四边形。

                      感知器 5

                      double perceptron5() 
                        {
                         double w1 = c1 - 100.0;
                         double w2 = c2 - 100.0;
                         double w3 = c3 - 100.0;
                         double w4 = c4 - 100.0;
                         
                         double a1 = (ind_In1[1]-ind_In1[10])/Point();
                         double a2 = (ind_In2[1]-ind_In2[10])/Point();
                         double a3 = (ind_In1[1]-ind_In2[1])/Point();
                         double a4 = (ind_In1[10]-ind_In2[10])/Point();
                         
                         return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
                        }


                        形状 6:复杂

                          在此,我将把上述所有形状组合成一个复杂的形状。

                          感知器 6

                          double perceptron6() 
                            {
                             double w1 = x1 - 100.0;
                             double w2 = x2 - 100.0;
                             double w3 = x3 - 100.0;
                             double w4 = x4 - 100.0;  
                             
                             double w5 = y1 - 100.0;
                             double w6 = y2 - 100.0;
                             double w7 = y3 - 100.0;
                             
                             double w8 = z1 - 100.0;
                             double w9 = z2 - 100.0;
                             double w10 = z3 - 100.0;
                            
                             double w11 = f1 - 100.0;
                             double w12 = f2 - 100.0;
                             double w13 = f3 - 100.0;
                             double w14 = f4 - 100.0;
                             
                             double a1 = (ind_In1[1]-ind_In2[1])/Point();
                             double a2 = (ind_In1[4]-ind_In2[4])/Point();
                             double a3 = (ind_In1[7]-ind_In2[7])/Point();
                             double a4 = (ind_In1[10]-ind_In2[10])/Point();  
                             
                             double a5 = (ind_In1[1]-ind_In1[4])/Point();
                             double a6 = (ind_In1[4]-ind_In1[7])/Point();
                             double a7 = (ind_In1[7]-ind_In1[10])/Point();
                             
                             double a8 = (ind_In2[1]-ind_In2[4])/Point();
                             double a9 = (ind_In2[4]-ind_In2[7])/Point();
                             double a10 = (ind_In2[7]-ind_In2[10])/Point();
                             
                             double a11 = (ind_In1[1]-ind_In1[10])/Point();
                             double a12 = (ind_In2[1]-ind_In2[10])/Point();
                             double a13 = (ind_In1[1]-ind_In2[10])/Point();
                             double a14 = (ind_In2[1]-ind_In1[10])/Point(); 
                             
                             return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4   +   w5 * a5 + w6 * a6 + w7 * a7   +   w8 * a8 + w9 * a9 + w10 * a10   +   w11 * a11 + w12 * a12 + w13 * a13 + w14 * a14);
                            }


                          角度

                          我们来研究另一种将价格数据传递给感知器的有趣方法 — 指标倾角。 这些数据也不能超出某个范围,而这非常适合我们,因为我们希望传递某个模板,就像前面所用的形状和线条的情况一样。 

                          我遇到了很多定义角度的方法,但其中很多都取决于价格图标的比例,这并不适合我。 所以我宁愿用点数与柱线的数量之比来计算切线角度,而非计算图表角度。 tg(α) 正切角度是相对支撑腿 a 与相邻支撑腿 b 的比率。

                          ta

                          也可以使用不同指标数字,处理复杂结构,并用不同数量蜡烛进行分析。 坡度在屏幕截图上显示为非固定线。 我们来研究几个例子。


                          感知器 1。 MA 1 位置 3 坡度

                          蜡烛 1-4、1-7 和 1-10 与 MA 1 之间的倾角。 

                          感知器 t1

                          double perceptront1() 
                            {
                             double w1 = x1 - 100.0;
                             double w2 = x2 - 100.0;
                             double w3 = x3 - 100.0;
                             
                             double a1 = (ind_In1[1]-ind_In1[4])/4;
                             double a2 = (ind_In1[1]-ind_In1[7])/7;
                             double a3 = (ind_In1[1]-ind_In1[10])/10;
                          
                             return (w1 * a1 + w2 * a2 + w3 * a3);
                            }
                            感知器 2。 MA 1 和 MA 24 位置 4 坡度

                              蜡烛 1-4、和 1-10 与 MA 1 之间的倾角,蜡烛 1-5、和 1-10 与 MA 24 之间的倾角。

                              感知器 t2

                              double perceptront2() 
                                {
                                 double w1 = x1 - 100.0;
                                 double w2 = x2 - 100.0;
                                 double w3 = x3 - 100.0;
                                 double w4 = x4 - 100.0;
                                 
                                 double a1 = (ind_In1[1]-ind_In1[5])/5;
                                 double a2 = (ind_In1[1]-ind_In1[10])/10;
                                 double a3 = (ind_In2[1]-ind_In2[5])/5;
                                 double a4 = (ind_In2[1]-ind_In2[10])/10;
                                 
                                 return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
                                }


                                感知器 3。 MA 1 和 MA 24 位置 4 坡度(以或多或少复杂的设计为例)

                                  角度与 MA 1 和 MA 24 之间的斜率相关。

                                  感知器 t3

                                  double perceptront3() 
                                    {
                                     double w1 = x1 - 100.0;
                                     double w2 = x2 - 100.0;
                                     double w3 = x3 - 100.0;
                                     double w4 = x4 - 100.0;
                                     
                                     double a1 = (ind_In1[1]-ind_In1[10])/10;
                                     double a2 = (ind_In2[1]-ind_In1[4])/4;
                                     double a3 = (ind_In2[1]-ind_In1[7])/7;
                                     double a4 = (ind_In2[1]-ind_In1[10])/10;
                                     
                                     return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
                                    }


                                    感知器 4。 MA 1 和 MA 24 位置 4 坡度(以或多或少复杂的设计为例)

                                      角度与 MA 1 和 MA 24 之间的斜率相关。

                                      感知器 t4

                                      double perceptront4() 
                                        {
                                         double w1 = x1 - 100.0;
                                         double w2 = x2 - 100.0;
                                         double w3 = x3 - 100.0;
                                         double w4 = x4 - 100.0;
                                         
                                         double a1 = (ind_In1[1]-ind_In1[10])/10;
                                         double a2 = (ind_In2[1]-ind_In1[10])/10;
                                         double a3 = (ind_In1[1]-ind_In1[10])/10;
                                         double a4 = (ind_In2[1]-ind_In2[10])/10;
                                         
                                         return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4);
                                        }

                                      策略

                                      我决定在下面的代码中明确指定,采用逆势趋势策略进行训练。 对于卖出,第一根蜡烛上的 MA 1 高于 MA 24。 买入的情况则相反。 这对于明确区分买卖是必要的。 另一方面,您可以做相反的事情 — 顺势而为。

                                      您还可以用其她指标或其数值,例如 TEMA 指标。 在五位小数的品种上预测 400 点的价格走势是不可能的。 没有人知道行情将走向何方。 因此,为了进行测试,我为五位小数品种设置了 600 点的固定止损和 60 点的止盈。 您可以从下面下载现成的 EA。 我们看看结果。

                                      //SELL++++++++++++++++++++++++++++++++++++++++++++++++
                                      
                                      if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (ind_In1[1]>ind_In2[1]) && (perceptron1()<0) &&(SpreadS1<=MaxSpread)){//v1
                                        OpenSell(symbolS1.Name(), LotsXSell, TakeProfit, StopLoss, EAComment);
                                      }
                                      
                                      //BUY++++++++++++++++++++++++++++++++++++++++++++++++
                                      
                                      if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (ind_In1[1]<ind_In2[1]) && (perceptron1()>0) && (SpreadS1<=MaxSpread)){//v1
                                        OpenBuy(symbolS1.Name(), LotsXBuy, TakeProfit, StopLoss, EAComment);
                                      }

                                      优化、测试和资源

                                      正如我们所知,神经网络的优化需要大量的计算资源。 因此,在利用策略测试器进行优化时,我建议采用“仅开盘价”模式,在代码中明确显示收盘价。 否则,即便以我相当有限的能力,也觉得这不是一项可行的任务。 但是,即使采用了这种优化模式,我也建议使用云网络服务。 优化的目标是找到某些可盈利的形态。 这种形态的发生率(可盈利的交易数量)应该远远高于无利可图形态。 这一切都取决于止损/获利比率。

                                      往前看,我应该说我针对每个 EA 已经连续进行了 10 次优化。 会有很多优化值,这导致在遗传算法模式下每次通过的结果约为 10000-15000。 相应地,通过次数越多,找到所需权重比值的机会就越高。 该问题应通过 MQL5 手段解决。 我真的不想放弃策略测试。

                                      与上面引用的文章(其中步骤等于 1)相比,5 步优化值不是偶然选择的。 在实验期间,我注意到这导致感知器权重比的结果更加分散,而这对结果有更佳的影响。


                                      优化 EA 1 感知器 1 图例。 简单线条。 (一个感知器一个形状)。

                                        • 优化日期从 2010 年 5 月 31 日至 2021 年 5 月 30 日。
                                        • 模式 (仅开盘价), (遗传算法), (最大盈利)。
                                        • 初始资金 10,000。
                                        • 止盈 = 60,止损 = 600。
                                        • 周期 H1.
                                        • 固定手数 0.01。
                                        • 优化参数 x1, x2, x3, x4  - 感知器权重比。从 0 到 200,以 5 为增量进行优化。

                                         

                                        优化和前向验证测试结果。

                                        1 感知器 1 图例。

                                        如您所见,结果距有希望甚远。 最佳结果为 0.87。 运行正向验证测试没有任何意义。


                                        优化 EA 1 感知器 1 图例。 (一个感知器一个形状)。
                                        • 优化日期从 2010 年 5 月 31 日至 2021 年 5 月 30 日。
                                        • 模式 (仅开盘价), (遗传算法), (最大盈利)。
                                        • 初始资金 10,000。
                                        • 止盈 = 60,止损 = 600。
                                        • 周期 H1.
                                        • 固定手数 0.01。
                                        • 优化参数 x1, x2, x3, x4, y1, y2, y3, z1, z2, z3, f1, f2, f3, f4  - 感知器权重比。从 0 到 200,以 5 为增量进行优化。

                                         

                                        优化和前向验证测试结果。

                                        1 感知器 4 图例。

                                        结果与之前的结果非常相似。最佳结果为 0.94。


                                        优化 EA 4 感知器 4 图例。 (四个感知器四个不同形状)。

                                         主要代码如下所示:

                                        //SELL++++++++++++++++++++++++++++++++++++++++++++++++
                                        
                                        if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (ind_In1[1]>ind_In2[1]) && (perceptron1()<0) && (perceptron2()<0) && (perceptron3()<0) && (perceptron4()<0) && (SpreadS1<=MaxSpread)){//v1
                                          OpenSell(symbolS1.Name(), LotsXSell, TakeProfit, StopLoss, EAComment);
                                        }
                                        
                                        //BUY++++++++++++++++++++++++++++++++++++++++++++++++
                                        
                                        if ((CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (ind_In1[1]<ind_In2[1]) && (perceptron1()>0) && (perceptron2()>0) && (perceptron3()>0) && (perceptron4()>0) && (SpreadS1<=MaxSpread)){//v1
                                          OpenBuy(symbolS1.Name(), LotsXBuy, TakeProfit, StopLoss, EAComment);
                                        }
                                        • 优化日期从 2010 年 5 月 31 日至 2021 年 5 月 30 日。
                                        • 模式 (仅开盘价), (遗传算法), (复杂准则最大化)。
                                        • 初始资金 10,000。
                                        • 止盈 = 200,止损 = 200。
                                        • 周期 H1.
                                        • 固定手数 0.01。
                                        • 优化参数 x1, x2, x3, x4, y1, y2, y3, z1, z2, z3, f1, f2, f3, f4  - 感知器权重比。从 0 到 200,以 5 为增量进行优化。

                                        优化和前向验证测试结果。

                                        4 感知器 4 图例。

                                        前向验证测试日期从 2021 年 5 月 31 日至 2022 年 5 月 30 日。在所有结果中,我们应选择具有最大利润因子的结果,其中复杂标准的最大化值超过 40-50。

                                        测试 1

                                        测试 2

                                        • 优化日期从 2010 年 5 月 31 日至 2021 年 5 月 30 日。
                                        • 模式 (仅开盘价), (遗传算法), (最大盈利)。
                                        • 初始资金 10,000。
                                        • 止盈 = 60,止损 = 600
                                        • 周期 H1.
                                        • 固定手数 0.01。
                                        • 优化参数 x1, x2, x3, x4, y1, y2, y3, z1, z2, z3, f1, f2, f3, f4  - 感知器权重比。从 0 到 200,以 5 为增量进行优化。

                                         

                                        优化和前向验证测试结果。

                                        4 感知器 4 图例。

                                        得到了结果。最佳结果为 32。 把日期从 2021 年 5 月 31 日更改为 2022 年 5 月 30 日,并运行正向验证测试。 在所有结果中,我们应该选择利润因子最大、交易数量最小值不少于 10-20 的结果。

                                        测试 1

                                        测试 2


                                        优化 EA 4 感知器 4 正切。 (四个感知器 四个不同的角度)。

                                        • 优化日期从 2010 年 5 月 31 日至 2021 年 5 月 30 日。
                                        • 模式 (仅开盘价), (遗传算法), (复杂准则最大化)。
                                        • 初始资金 10,000。
                                        • 止盈 = 200,止损 = 200。
                                        • 周期 H1.
                                        • 固定手数 0.01。
                                        • 优化参数 x1, x2, x3, x4, y1, y2, y3, z1, z2, z3, f1, f2, f3, f4  - 感知器权重比。从 0 到 200,以 5 为增量进行优化。

                                        优化和前向验证测试结果。

                                        4 感知器 4 正切。

                                        前向验证测试日期从 2021 年 5 月 31 日提前至 2022 年 5 月 30 日。 在所有结果当中,我们应该选择具有最大利润因子的一个,复杂准则的最大化值超过 20-40。

                                        测试 1

                                        测试 2

                                        • 优化日期从 2010 年 5 月 31 日至 2021 年 5 月 30 日。
                                        • 模式 (仅开盘价), (遗传算法), (最大盈利)。
                                        • 初始资金 10,000。
                                        • 止盈 = 60,止损 = 600。
                                        • 周期 H1.
                                        • 固定手数 0.01。
                                        • 优化参数 x1, x2, x3, x4, y1, y2, y3, z1, z2, z3, f1, f2, f3, f4  - 感知器权重比。从 0 到 200,以 5 为增量进行优化。

                                         

                                        优化和前向验证测试结果。

                                        4 感知器 4 正切。

                                        得到了结果。最佳结果为 32。 我会留下一个前向验证测试作为家庭作业。 我认为,这样会更有趣味。 此外,应当注意的是,与利润因子相关的交易数量有所增加。


                                         在我的实验过程中,我遇到了几个需要解决的问题。

                                        • 首先。 由于优化多个权重比参数的复杂性,有必要在 EA 代码中移动它们。
                                        • 其二。 我们应该有一个包含所有优化参数的数据库,然后在 EA 中同时采用它们进行交易。 我认为,这可以用 .CSV 类型的文件。

                                        结束语

                                        我真的希望我的实验能给您带来新的发现,并最终取得成功。 我的目标是获得一个现成的盈利策略。 通过优良的前向验证测试结果,我已经部分达成了这一目标。 然而,还有许多工作要做。 现在是时候转向更复杂的系统,同时从掌握的经验中获益。 此外,我们应该更多地利用我们所拥有的。 我们会在实验的第二部分来讨论这个问题。 不要错过! 事情变得越发令人兴奋。

                                         

                                        本文由MetaQuotes Ltd译自俄文
                                        原文地址: https://www.mql5.com/ru/articles/11077

                                        附加的文件 |
                                        EA.zip (181.54 KB)
                                        学习如何基于交易量设计交易系统 学习如何基于交易量设计交易系统
                                        这是我们系列文集中的新篇章,介绍如何基于最流行的技术指标设计交易系统。 本文将专门讨论交易量指标。 作为一个概念,交易量是金融市场交易中非常重要的因素之一,我们必须予以关注。 贯穿本文,我们将学习如何基于交易量指标设计一款简单的系统。
                                        DoEasy. 控件 (第 8 部分): 基准 WinForms 对象类别,GroupBox 和 CheckBox 控件 DoEasy. 控件 (第 8 部分): 基准 WinForms 对象类别,GroupBox 和 CheckBox 控件
                                        本文研究创建 “GroupBox” 和 “CheckBox” WinForms 对象,以及开发 WinForms 对象类别的基准对象。 所有已创建对象仍然是静态的,即,它们无法与鼠标交互。
                                        从头开始开发智能交易系统(第 19 部分):新订单系统 (II) 从头开始开发智能交易系统(第 19 部分):新订单系统 (II)
                                        在本文中,我们将开发一个“看看发生了什么”类型的图形订单系统。 请注意,我们这次不是从头开始,只不过我们将修改现有系统,在我们交易的资产图表上添加更多对象和事件。
                                        在莫斯科交易所(MOEX)里使用限价订单进行自动网格交易 在莫斯科交易所(MOEX)里使用限价订单进行自动网格交易
                                        本文研究针对 MetaTrader 5 平台开发 MQL5 智能交易系统(EA),旨在能在 MOEX 上操作。 该 EA 采用网格策略,面向 MetaTrader 5 终端,并在 MOEX 上进行交易。 EA 包括了依据止损和止盈平仓,以及在某些市场条件下取消挂单。