
ニューラルネットワークの実験(第1回):幾何学の再検討
はじめに
この記事では、ニューラルネットワークに関する私の実験を共有したいと思います。 MQL5で入手できる大量の情報を読んだ後、理論は十分であるという結論に達しました。優れた記事、ライブラリ、ソースコードがたくさんあります。残念ながら、これらすべてのデータから、収益性の高い取引システムという論理的な結論が得られるわけではありません。これを直してみましょう。
私はこの分野の専門家ではなく、ライターやジャーナリストでもありませんが、自分の経験を共有するために、アクセスしやすい方法で自分の考えを表現しようとします。
この記事は、主に私のような初心者向けに設計されています。
私の理解:基礎
一般に、ニューラルネットワークはパターンの認識に優れていると考えられていますが、訓練のためにニューラルネットワークに渡されるデータは最も重要です。この仮定から始めます。幾何学を使用しましょう。幾何学的形状をニューラルネットワークに転送します。まず、こちら(МTCСombo-MetaTrader4のエキスパート)に見本がある、通常のパーセプトロンを見てみましょう。テストの実行中に、オシレータを見切ってMAを使用することにしました。オシレータを含むテストでは、良い結果が得られませんでした。価格が上昇してオシレータが下降する、いわゆるダイバージェンスについては誰もが知っていると思います。MAパラメータは価格そのものに近いです。
形と線
基本は、パラメータ1と24を持つ2つの移動平均指標で構成され、SimpleメソッドがCloseに適用されます。つまり、現在の指標の場所だけでなく、現在の指標の前の状態も渡すという考え方です。私が見た多くの例では、価格はニューラルネットワークに直接渡されますが、これは根本的に間違っていると思います。
すべての値をポイント単位で渡します。これらの値には特定の範囲を超えることができないため、これは非常に重要です。ニューラルネットワークに価格を渡すことは、たとえば10年間、さまざまな範囲で変動する可能性があるため、意味がありません。また、形状を構築する際に、さまざまな数の指標パラメータを使用できます。形状は複雑でも単純でもかまいません。可能なオプションを2、3以下に示します。もちろん、読者は自分自身のものを思いつくことができます。
MA1とMA24の間の閉じたローソク足1、4、7、10上のポイントでの距離。
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:シンプルな線
MA1の閉じたローソク足1~4、4~7、7~10間のポイント単位の距離。
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:シンプルな線
MA24の閉じたローソク足1~4、4~7、7~10間のポイント単位の距離。
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:バタフライ(エンベロープ)
MA1の閉じたローソク足1~10の間のポイント単位の距離。MA24の閉じたローソク足1~10間のポイント単位の距離。 MA1のローソク足1とMA24のローソク足10の間のポイント単位の距離。MA24のローソク足1とMA1のローソク足10の間のポイント単位の距離。結果はバタフライです。
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間のポイント単位の距離と指標MA24の1~10間のポイント単位の距離。結果は四角形です。
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:複雑
ここでは、上記のすべての形状を組み合わせて複雑なものにします。
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の比率です。
異なる数の指標を使用したり、複雑な構造を処理したり、分析に異なる数のローソク足を使用したりすることも可能です。傾斜角度は、スクリーンショットでは固定されていない線として表示されます。いくつかの例を考えてみましょう。
MA1ローソク1~4間、ローソク1~7間、ローソク1~10間の傾斜角。
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); }
ローソク足1~5、ローソク足1~10の間のMA1の傾き。 MA24は、ローソク足1~5の間、ローソク足1~10の間の勾配です。
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:MA1およびMA24の4つの傾斜角度(多かれ少なかれ複雑な設計を例として使用)
角度は、MA1とMA24の間の勾配で結ばれています。
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:MA1およびMA24の4つの傾斜角度(多かれ少なかれ複雑な設計を例として使用)
角度は、MA1とMA24の間の勾配で結ばれています。
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); }
戦略
以下のコードで明示的に指定することにより、訓練にカウンタートレンド戦略を使用することにしました。売りの場合、最初のローソク足のMA1はMA24を上回ります。買いの場合は反対です。これは、売買を明確に区別するために必要です。一方、反対のことをすることができます。トレンドの使用です。
TEMA指標など、他の指標またはその値を使用することもできます。5桁の銘柄で400ポイントの値動きを予測することは不可能です。市場がどこに向かうかは誰にもわかりません。したがって、テストを実行するために、5桁の銘柄に対して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); }
最適化、テスト、リソース
ご存知のように、ニューラルネットワークの最適化にはかなりの計算リソースが必要です。したがって、最適化のためにストラテジーテスターを使用する場合は、コード自体に終値を明示的に示す「始値のみ」モードをお勧めします。そうでなければ、これは私のかなり控えめな能力では実行可能なタスクではありません.しかし、この最適化モードでも、クラウドネットワークサービスを使用することをお勧めします。最適化の目標は、特定の収益性の高いパターンを見つけることです。このようなパターンの発生(収益性の高い取引の数)は、収益性のないものよりもはるかに高くなるはずです。すべてはStopLoss/TakeProfitの比率に依存します。
先を見据えると、各EAの最適化を10回連続して実行したと言わざるを得ません。多くの最適化値があり、遺伝的アルゴリズムモードでは、パスごとに約10,000~15,000の結果が得られます。したがって、パスが多ければ多いほど、重量比の所望の値を見つける確率が高くなります。この問題はMQL5によって解決されるはずです。私は本当にストラテジーテスターをあきらめたくありません。
上記の記事(ステップは1に等しい)とは対照的に、5つの最適化値のステップは偶然に選択されたわけではありません。実験中に、これによりパーセプトロンの重み比の結果がより散らばり、結果により良い影響を与えることに気付きました。
- 2010.05.31から2021.05.31までの最適化日
- モード:始値のみ、遺伝的アルゴリズム、最大利益
- 初期資本:10,000
- テイクプロフィット=60、ストップロス=600
- 期間H1
- 固定ロット0.01
- 最適化されたパラメータx1、x2、x3、x4 - パーセプトロンの重量比。 5刻みで0から200までの値で最適化
次は、最適化とフォワードテストの結果です。
ご覧のとおり、結果は有望とはほど遠いものです。最良の結果は0.87です。フォワードテストを実行しても意味がありません。
- 2010.05.31から2021.05.31までの最適化日
- モード:始値のみ、遺伝的アルゴリズム、最大利益
- 初期資本:10,000
- テイクプロフィット=60、ストップロス=600
- 期間H1
- 固定ロット0.01
- 最適化されたパラメータx1、x2、x3、x4、y1、y2、y3、z1、z2、z3、f1、f2、f3、f4 - パーセプトロンの重み比。 5刻みで0から200までの値で最適化
次は、最適化とフォワードテストの結果です。
これは前のものと非常によく似ています。 最良の結果は0.94です。
EA4パーセプトロン4の図の最適化。(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.05.31から2021.05.31までの最適化日
- モード:始値のみ、遺伝的アルゴリズム、複雑な基準の最大値
- 初期資本:10,000
- テイクプロフィット=200、ストップロス=200
- 期間H1
- 固定ロット0.01
- 最適化されたパラメータx1、x2、x3、x4、y1、y2、y3、z1、z2、z3、f1、f2、f3、f4 - パーセプトロンの重み比。 5刻みで0から200までの値で最適化
次は、最適化とフォワードテストの結果です。
2021.05.31から2022.05.31までのフォワードテスト日。すべての結果の中から、複雑な基準の最大値が40~50を超える最大の利益率を特徴とするものを選択する必要があります。
- 2010.05.31から2021.05.31までの最適化日
- モード:始値のみ、遺伝的アルゴリズム、最大利益
- 初期資本:10,000
- テイクプロフィット=60、ストップロス=600
- 期間H1
- 固定ロット0.01
- 最適化されたパラメータx1、x2、x3、x4、y1、y2、y3、z1、z2、z3、f1、f2、f3、f4 - パーセプトロンの重み比。 5刻みで0から200までの値で最適化
次は、最適化とフォワードテストの結果です。
結果が得られました。 最高の結果は32です。日付を2021.05.31から2022.05.31に変更し、フォワードテストを実行します。すべての結果の中から、10~20以上の最小取引数で最大の利益率を特徴とするものを選択する必要があります。
EA4パーセプトロン4タンジェントの最適化。(4つの異なる角度を持つ4つのパーセプトロン)。
- 2010.05.31から2021.05.31までの最適化日
- モード:始値のみ、遺伝的アルゴリズム、複雑な基準の最大値
- 初期資本:10,000
- テイクプロフィット=200、ストップロス=200
- 期間H1
- 固定ロット0.01
- 最適化されたパラメータx1、x2、x3、x4、y1、y2、y3、z1、z2、z3、f1、f2、f3、f4 - パーセプトロンの重み比。 5刻みで0から200までの値で最適化
最適化と転送テストの結果。
テスト日を2021.05.31から2022.05.31にフォワードします。すべての結果の中から、複雑な基準の最大値が20~40を超える最大の利益率を特徴とするものを選択する必要があります。
- 2010.05.31から2021.05.31までの最適化日
- モード:始値のみ、遺伝的アルゴリズム、最大利益
- 初期資本:10,000
- テイクプロフィット=60、ストップロス=600
- 期間H1
- 固定ロット0.01
- 最適化されたパラメータx1、x2、x3、x4、y1、y2、y3、z1、z2、z3、f1、f2、f3、f4 - パーセプトロンの重み比。 5刻みで0から200までの値で最適化
次は、最適化とフォワードテストの結果です。
結果が得られました。 最高の結果は32です。フォワードテストは宿題として残します。こうすればもっと面白くなると思います。さらに、利益率に関連する取引数が増加していることに注意する必要があります。
実験の過程で、解決すべきいくつかの問題に遭遇しました。
- 1:複数の重量比パラメータの最適化は複雑であるため、それらをEAコード内に移動する必要があります。
- 2:最適化されたすべてのパラメータのデータベースを用意し、それらをEAで同時に取引するために使用する必要があります。.CSV形式のファイルを使用できるようになると思います。
結論
私の実験が読者に新しい発見をもたらし、最終的には成功に導くことを心から願っています。私の目的は、すぐ使える、収益性の高い戦略を取得することでした。良好なフォワードテスト結果を得ることで、部分的にそれを達成しましたが、まだ多くの作業が必要です。得られた経験から恩恵を受けながら、より複雑なシステムに移行するべきです。それに、今持っているものをもっと活用すべきです。これについては、実験の第2部で説明します。お見逃しなく。もっと面白くなるところです。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/11077





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索