ニューラルネットワークの実験(第7回):指標の受け渡し
はじめに
今回の記事では、意味のあるデータ、いわゆる時系列をニューラルネットワークに渡すことの重要性について詳しく説明します。特に、私たちのお気に入りの指標を渡します。これを達成するために、私がニューラルネットワークを扱う際に使用する新しい概念をいくつか紹介します。ただし、これが限界ではないと思います。時間が経てば、正確に何をどのように渡す必要があるのかを理解する上で、新しいビジョンが得られるでしょう。
背景と考察
このトピックに関する多数の記事を読んでいると、ニューラルネットワークに基づく取引システムの直接的な結果に関する悲しい状況が常に観察されます。多くの優れたアイデアやアルゴリズムは、望ましい結果をもたらしません。
入力パラメータを渡す間、常に同じ状況が観察されます。例えば、私の意見では、オシレーター値の直接受け渡しは資産の価格と何の共通点もありません。オシレーターには、いわゆる発散というよく知られた問題があります。これらは、始値、終値、高値、安値であり、直接渡されると何の意味も持たず、システムに理解できない雑音をもたらします。これらの値は何にも関連付けられておらず、時間の経過とともに大きく広がります。例として、任意の通貨ペアの日次チャートを開いて、終値の変動範囲を確認します。
理論と概念
このセクションでは、私が自分で分類し、実験で使用している概念のいくつかについて説明します。
- 距離:任意の指標から別の指標またはそのゼロ値までの距離。私の意見では、大原則は現在の状況を歴史上の安定した価値に結び付けることです。MA1指標の直接値を渡すと、価格値が特定の範囲なしで時間の経過とともに変化するため、理解できない標本スプレッドが得られます。これは、分類または統計的動作のわずかなヒントを意味します。2つの指標の違い(例えば、ポイント単位のMA1とMA100、または4ローソク足前の値を持つMACD指標のゼロローソク足上の現在の距離)を伝える場合は別の問題になります。したがって、距離を使用することで、市場が平均から大きく離れているかどうか、現時点での履歴標本と比較してかなり買われすぎているのか売られすぎているのかを判断できます。また、距離を使用して、市場がどこで上昇または下降しているかを判断します。値は正または負のいずれかになります。
- 累積:相互に相対的な1つまたは複数の指標の合計値、またはゼロ以外の一部の指標のゼロ点またはゼロ値点の計算。したがって、累積により、特定の方向への特定の動きがどれくらいの時間おこなわれるかを判断することができます。累積が小さい場合は、現在統合が進行中である可能性があります。逆に、累積が大きい場合は、長期化する傾向があります。方向は符号(-または+)によって異なります。言い換えれば、累積値は統合の「乱気流」中には大きな値を持ちませんが、代わりにトレンド中には大きな値を持ちます。
- 傾斜角:指標の現在の傾斜角は、現在のインパルスの動きまたはその不在、および商品の活動の減衰についてニューラルネットワークに通知する非常に優れた方法です。特定の履歴(例えば、10ローソク足)の指標の傾斜角を決定できる機能は、履歴の標本化結果と比較して現在の状況を分析する際に十分に証明されています。傾斜角度をラジアンで測定します。これが私個人に合った唯一の方法であり、チャートのスケールに依存しません。
例
距離の使用例
- 現在のゼロローソク足の距離の受け渡し:MA100に対するMA1指標。現在の値とゼロ値を基準としたMACD指標。現在の値とゼロ値を基準としたCCI指標。
#property copyright "2023, Roman Poshtar" #property link "https://www.mql5.com/ru/users/romanuch" #property strict #property version "1.0" input int x1 = 1; input int x2 = 1; input int x3 = 1; int handle_In1S1; int handle_In2S1; int handle_In3S1; int handle_In4S1; double ind_In1S1[]; double ind_In2S1[]; double ind_In3S1[]; double ind_In4S1[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In1S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In2S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE); //--- if the handle is not created if(handle_In3S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE); //--- if the handle is not created if(handle_In4S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In1S1,true); if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In2S1,true); if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In3S1,true); if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In4S1,true); if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1)) { return; } //--- perceptron1(); } //+------------------------------------------------------------------+ //| The PERCEPRRON - a perceiving and recognizing function | //+------------------------------------------------------------------+ double perceptron1() { double w1 = x1 - 10.0; double w2 = x2 - 10.0; double w3 = x3 - 10.0; double a1 = ((ind_In1S1[0]-ind_In2S1[0])/Point()); double a2 = ind_In3S1[0]; double a3 = ind_In4S1[0]; Print("a1 = ", a1); Print("a2 = ", a2); Print("a3 = ", a3); Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3)); Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); return (w1 * a1 + w2 * a2 + w3 * a3); }
ログデータ
a1:MA1指標とMA100指標間の通貨ペアポイントの差。正負の両方の値を取ることができます。
a2:MACD指標の現在値。正負の両方の値を取ることができます。
a3:CCI指標の現在値。正負の両方の値を取ることができます。
- Nローソク足後方の距離の受け渡し:MA1指標。MA100指標。MACD指標。CCI指標。
#property copyright "2023, Roman Poshtar" #property link "https://www.mql5.com/ru/users/romanuch" #property strict #property version "1.0" input int Candles= 10; input int x1 = 1; input int x2 = 1; input int x3 = 1; input int x4 = 1; int handle_In1S1; int handle_In2S1; int handle_In3S1; int handle_In4S1; double ind_In1S1[]; double ind_In2S1[]; double ind_In3S1[]; double ind_In4S1[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In1S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In2S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE); //--- if the handle is not created if(handle_In3S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE); //--- if the handle is not created if(handle_In4S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In1S1,true); if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In2S1,true); if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In3S1,true); if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In4S1,true); if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1)) { return; } //--- perceptron1(); } //+------------------------------------------------------------------+ //| The PERCEPRRON - a perceiving and recognizing function | //+------------------------------------------------------------------+ double perceptron1() { double w1 = x1 - 10.0; double w2 = x2 - 10.0; double w3 = x3 - 10.0; double w4 = x4 - 10.0; double a1 = ((ind_In1S1[0]-ind_In1S1[Candles])/Point()); double a2 = ((ind_In2S1[0]-ind_In2S1[Candles])/Point()); double a3 = ind_In3S1[0]-ind_In3S1[Candles]; double a4 = ind_In4S1[0]-ind_In4S1[Candles]; Print("a1 = ", a1); Print("a2 = ", a2); Print("a3 = ", a3); Print("a3 = ", a4); Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4)); Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); }
ログデータ
a1:MA1指標のローソク足0とローソク足10間の通貨ペアポイントの差。正負の両方の値を取ることができます。
a2:MA100指標のローソク足0とローソク足10間の通貨ペアポイントの差。正負の両方の値を取ることができます。
a3:ローソク足0とローソク足10のMACD指標値の差。正負の両方の値を取ることができます。
a4:ローソク足0とローソク足10のCCI指標値の差。正負の両方の値を取ることができます。
- 過去のゼロ値を基準とした、MA1指標とMA100指標の交点からの距離の受け渡し:過去のゼロ値を基準としたMACD指標。過去のゼロ値を基準としたCCI指標。
#property copyright "2023, Roman Poshtar" #property link "https://www.mql5.com/ru/users/romanuch" #property strict #property version "1.0" input int Candles= 10; input int x1 = 1; input int x2 = 1; input int x3 = 1; input int x4 = 1; int handle_In1S1; int handle_In2S1; int handle_In3S1; int handle_In4S1; double ind_In1S1[]; double ind_In2S1[]; double ind_In3S1[]; double ind_In4S1[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In1S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In2S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE); //--- if the handle is not created if(handle_In3S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE); //--- if the handle is not created if(handle_In4S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In1S1,true); if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In2S1,true); if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In3S1,true); if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In4S1,true); if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1)) { return; } //--- perceptron1(); } //+------------------------------------------------------------------+ //| The PERCEPRRON - a perceiving and recognizing function | //+------------------------------------------------------------------+ double perceptron1() { int c1=0; int c2=0; int c3=0; double w1 = x1 - 10.0; double w2 = x2 - 10.0; double w3 = x3 - 10.0; double w4 = x4 - 10.0; for(int i=0; i<=1000; i++){ if(ind_In1S1[0]>ind_In2S1[0]){if (ind_In1S1[i]<ind_In2S1[i]){c1=i; break;}} if(ind_In1S1[0]<ind_In2S1[0]){if (ind_In1S1[i]>ind_In2S1[i]){c1=i; break;}} } double a1 = ((ind_In1S1[0]-ind_In1S1[c1])/Point()); double a2 = ((ind_In2S1[0]-ind_In2S1[c1])/Point()); for(int i=0; i<=1000; i++){ if(ind_In3S1[0]>0){if (ind_In3S1[i]<0){c2=i; break;}} if(ind_In3S1[0]<0){if (ind_In3S1[i]>0){c2=i; break;}} } double a3 = ind_In3S1[0]-ind_In3S1[c2]; for(int i=0; i<=1000; i++){ if(ind_In4S1[0]>0){if (ind_In4S1[i]<0){c3=i; break;}} if(ind_In4S1[0]<0){if (ind_In4S1[i]>0){c3=i; break;}} } double a4 = ind_In4S1[0]-ind_In4S1[c3]; Print("a1 = ", a1); Print("a2 = ", a2); Print("a3 = ", a3); Print("a4 = ", a4); Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4)); Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); }
ログデータ
a1:ローソク足0のMA1指標と、MA1指標とMA100指標の最後の交差点を特徴とするローソク足の通貨ペアポイントの差。正負の両方の値を取ることができます。
a2:ローソク足0のMA100指標と、MA1とMA100指標の最後の交差点を特徴とするローソク足の通貨ペアポイントの差。正負の両方の値を取ることができます。
a3:ローソク足0と値0の最後の交差点を特徴とするローソク足のMACD指標値の差。正負の両方の値を取ることができます。
a4:ローソク足0と値0の最後の交差を特徴とするローソク足のCCI指標値の差。正負の両方の値を取ることができます。
交差値の検索は、最初にループ内で実行されます。
パーセプトロンに渡すために累積を使用する例
- N指標ローソク足の累積の受け渡し:
#property copyright "2023, Roman Poshtar" #property link "https://www.mql5.com/ru/users/romanuch" #property strict #property version "1.0" input int Candles= 10; input int x1 = 1; input int x2 = 1; input int x3 = 1; int handle_In1S1; int handle_In2S1; int handle_In3S1; int handle_In4S1; double ind_In1S1[]; double ind_In2S1[]; double ind_In3S1[]; double ind_In4S1[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In1S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In2S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE); //--- if the handle is not created if(handle_In3S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE); //--- if the handle is not created if(handle_In4S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In1S1,true); if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In2S1,true); if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In3S1,true); if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In4S1,true); if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1)) { return; } //--- perceptron1(); } //+------------------------------------------------------------------+ //| The PERCEPRRON - a perceiving and recognizing function | //+------------------------------------------------------------------+ double perceptron1() { double sum1 = 0; double sum2 = 0; double sum3 = 0; double w1 = x1 - 10.0; double w2 = x2 - 10.0; double w3 = x3 - 10.0; for(int i=0; i<=Candles; i++) { sum1+=ind_In1S1[i]-ind_In2S1[i]; } double a1 = sum1; for(int i=0; i<=Candles; i++) { sum2+=ind_In3S1[i]; } double a2 = sum2; for(int i=0; i<=Candles; i++) { sum3+=ind_In4S1[i]; } double a3 = sum3; Print("a1 = ", a1); Print("a2 = ", a2); Print("a3 = ", a3); Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3)); Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); return (w1 * a1 + w2 * a2 + w3 * a3); }
ログデータ
a1:Candlesパラメータのローソク足数に対するMA1指標とMA100指標の差の累積。正負の両方の値を取ることができます。
a2:Candlesパラメータのローソク足の数に対するMACD指標の累積。正負の両方の値を取ることができます。
a3:Candlesパラメータのローソク足の数に対するCCI指標の累積。正負の両方の値を取ることができます。
- 過去の指標のゼロ点または過去の指標の最後の交点からの累積の受け渡し
#property copyright "2023, Roman Poshtar" #property link "https://www.mql5.com/ru/users/romanuch" #property strict #property version "1.0" input int Candles= 10; input int x1 = 1; input int x2 = 1; input int x3 = 1; int handle_In1S1; int handle_In2S1; int handle_In3S1; int handle_In4S1; double ind_In1S1[]; double ind_In2S1[]; double ind_In3S1[]; double ind_In4S1[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In1S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In2S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE); //--- if the handle is not created if(handle_In3S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE); //--- if the handle is not created if(handle_In4S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In1S1,true); if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In2S1,true); if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In3S1,true); if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In4S1,true); if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1)) { return; } //--- perceptron1(); } //+------------------------------------------------------------------+ //| The PERCEPRRON - a perceiving and recognizing function | //+------------------------------------------------------------------+ double perceptron1() { double sum1 = 0; double sum2 = 0; double sum3 = 0; double w1 = x1 - 10.0; double w2 = x2 - 10.0; double w3 = x3 - 10.0; for(int i=0; i<=1000; i++) { if(ind_In1S1[0]>ind_In2S1[0]) { if(ind_In1S1[i]<ind_In2S1[i]) { break; }; sum1+=(ind_In1S1[i]-ind_In2S1[i]); } if(ind_In1S1[0]<ind_In2S1[0]) { if(ind_In1S1[i]>ind_In2S1[i]) { break; }; sum1+=(ind_In1S1[i]-ind_In2S1[i]); } } double a1 = sum1; for(int i=0; i<=1000; i++) { if(ind_In3S1[0]>0) { if(ind_In3S1[i]<0) { break; }; sum2+=ind_In3S1[i]; } if(ind_In3S1[0]<0) { if(ind_In3S1[i]>0) { break; }; sum2+=ind_In3S1[i]; } } double a2 = sum2; for(int i=0; i<=1000; i++) { if(ind_In4S1[0]>0) { if(ind_In4S1[i]<0) { break; }; sum3+=ind_In4S1[i]; } if(ind_In4S1[0]<0) { if(ind_In4S1[i]>0) { break; }; sum3+=ind_In4S1[i]; } } double a3 = sum3; Print("a1 = ", a1); Print("a2 = ", a2); Print("a3 = ", a3); Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3)); Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); return (w1 * a1 + w2 * a2 + w3 * a3); }
ログデータ
a1:最後の交点からのMA1指標とMA100指標の差の累積。正負の両方の値を取ることができます。
a2:値0の最後の交点からのMACD指標の累積。正負の両方の値を取ることができます。
a3:値0の最後の交点からのCCI指標の累積。正負の両方の値を取ることができます。
指標の傾斜角度の使用例
- N指標ローソク足の勾配角度の受け渡し
#property copyright "2023, Roman Poshtar" #property link "https://www.mql5.com/ru/users/romanuch" #property strict #property version "1.0" input int Candles= 10; input int x1 = 1; input int x2 = 1; input int x3 = 1; input int x4 = 1; int handle_In1S1; int handle_In2S1; int handle_In3S1; int handle_In4S1; double ind_In1S1[]; double ind_In2S1[]; double ind_In3S1[]; double ind_In4S1[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In1S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In2S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE); //--- if the handle is not created if(handle_In3S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE); //--- if the handle is not created if(handle_In4S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In1S1,true); if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In2S1,true); if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In3S1,true); if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In4S1,true); if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1)) { return; } //--- perceptron1(); } //+------------------------------------------------------------------+ //| The PERCEPRRON - a perceiving and recognizing function | //+------------------------------------------------------------------+ double perceptron1() { double w1 = x1 - 10.0; double w2 = x2 - 10.0; double w3 = x3 - 10.0; double w4 = x4 - 10.0; double a1 = (((ind_In1S1[0]-ind_In1S1[Candles])/Point())/Candles); double a2 = (((ind_In2S1[0]-ind_In2S1[Candles])/Point())/Candles); double a3 = ((ind_In3S1[0]-ind_In3S1[Candles])/Candles); double a4 = ((ind_In4S1[0]-ind_In4S1[Candles])/Candles); Print("a1 = ", a1); Print("a2 = ", a2); Print("a3 = ", a3); Print("a4 = ", a4); Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4)); Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); }
ログデータ
a1:Candlesパラメータのローソク足の数に対するMA1指標の傾斜角。正負の両方の値を取ることができます。
a2:Candlesパラメータのローソク足の数に対するMA100指標の傾斜角度。正負の両方の値を取ることができます。
a3:Candlesパラメータのローソク足の数に対するMACD指標の傾斜角。正負の両方の値を取ることができます。
a4:Candlesパラメータのローソク足の数に対するCCI指標の傾斜角。正負の両方の値を取ることができます。
- 過去の指標のゼロ点、または過去の指標の最後の交差点からの勾配角度の受け渡し
#property copyright "2023, Roman Poshtar" #property link "https://www.mql5.com/ru/users/romanuch" #property strict #property version "1.0" input int x1 = 1; input int x2 = 1; input int x3 = 1; input int x4 = 1; int handle_In1S1; int handle_In2S1; int handle_In3S1; int handle_In4S1; double ind_In1S1[]; double ind_In2S1[]; double ind_In3S1[]; double ind_In4S1[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In1S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In2S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In3S1=iMACD(Symbol(),PERIOD_CURRENT,12,26,9,PRICE_CLOSE); //--- if the handle is not created if(handle_In3S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In4S1=iCCI(Symbol(),PERIOD_CURRENT,14,PRICE_CLOSE); //--- if the handle is not created if(handle_In4S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In1S1,true); if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In2S1,true); if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In3S1,true); if(!iGetArray(handle_In3S1,0,0,1010,ind_In3S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In4S1,true); if(!iGetArray(handle_In4S1,0,0,1010,ind_In4S1)) { return; } //--- perceptron1(); } //+------------------------------------------------------------------+ //| The PERCEPRRON - a perceiving and recognizing function | //+------------------------------------------------------------------+ double perceptron1() { int c1=0; int c2=0; int c3=0; double w1 = x1 - 10.0; double w2 = x2 - 10.0; double w3 = x3 - 10.0; double w4 = x4 - 10.0; for(int i=0; i<=1000; i++) { if(ind_In1S1[0]>ind_In2S1[0]) { if(ind_In1S1[i]<ind_In2S1[i]) { c1=i; break; } } if(ind_In1S1[0]<ind_In2S1[0]) { if(ind_In1S1[i]>ind_In2S1[i]) { c1=i; break; } } } double a1 = (((ind_In1S1[0]-ind_In1S1[c1])/Point())/c1); double a2 = (((ind_In2S1[0]-ind_In2S1[c1])/Point())/c1); for(int i=0; i<=1000; i++) { if(ind_In3S1[0]>0) { if(ind_In3S1[i]<0) { c2=i; break; } } if(ind_In3S1[0]<0) { if(ind_In3S1[i]>0) { c2=i; break; } } } double a3 = ((ind_In3S1[0]-ind_In3S1[c2])/c2); for(int i=0; i<=1000; i++) { if(ind_In4S1[0]>0) { if(ind_In4S1[i]<0) { c3=i; break; } } if(ind_In4S1[0]<0) { if(ind_In4S1[i]>0) { c3=i; break; } } } double a4 = ((ind_In4S1[0]-ind_In4S1[c3])/c3); Print("a1 = ", a1); Print("a2 = ", a2); Print("a3 = ", a3); Print("a4 = ", a4); Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4)); Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); }
ログデータ
a1:MA1指標とMA100指標の最後の交点からのMA1指標の傾斜角。正負の両方の値を取ることができます。
a2:MA1指標とMA100指標の最後の交点からのMA100指標の傾斜角。正負の両方の値を取ることができます。
a3:指標による0の値の最後の交点からのMACD指標の傾斜角。正負の両方の値を取ることができます。
a4:CCI指標の値0と指標の最後の交点からの傾斜角。正負の両方の値を取ることができます。
パーセプトロンに渡すために結合された値を使用する例
- MA1指標とMA100指標の値を組み合わせて渡します。
#property copyright "2023, Roman Poshtar" #property link "https://www.mql5.com/ru/users/romanuch" #property strict #property version "1.0" input int Candles= 10; input int x1 = 1; input int x2 = 1; input int x3 = 1; input int x4 = 1; input int x5 = 1; input int x6 = 1; input int x7 = 1; int handle_In1S1; int handle_In2S1; double ind_In1S1[]; double ind_In2S1[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { handle_In1S1=iMA(Symbol(),PERIOD_CURRENT,1,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In1S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- handle_In2S1=iMA(Symbol(),PERIOD_CURRENT,100,0,MODE_SMA,PRICE_CLOSE); //--- if the handle is not created if(handle_In2S1==INVALID_HANDLE) { return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In1S1,true); if(!iGetArray(handle_In1S1,0,0,1010,ind_In1S1)) { return; } //--- //--- get data from the three buffers of the i-Regr indicator ArraySetAsSeries(ind_In2S1,true); if(!iGetArray(handle_In2S1,0,0,1010,ind_In2S1)) { return; } //--- perceptron1(); } //+------------------------------------------------------------------+ //| The PERCEPRRON - a perceiving and recognizing function | //+------------------------------------------------------------------+ double perceptron1() { int c1=0; double sum1 = 0; double sum2 = 0; double w1 = x1 - 10.0; double w2 = x2 - 10.0; double w3 = x3 - 10.0; double w4 = x4 - 10.0; double w5 = x5 - 10.0; double w6 = x6 - 10.0; double w7 = x7 - 10.0; double a1 = ((ind_In1S1[0]-ind_In2S1[0])/Point()); for(int i=0; i<=Candles; i++) { sum1+=ind_In1S1[i]-ind_In2S1[i]; } double a2 = sum1; for(int i=0; i<=1000; i++) { if(ind_In1S1[0]>ind_In2S1[0]) { if(ind_In1S1[i]<ind_In2S1[i]) { break; }; sum2+=(ind_In1S1[i]-ind_In2S1[i]); } if(ind_In1S1[0]<ind_In2S1[0]) { if(ind_In1S1[i]>ind_In2S1[i]) { break; }; sum2+=(ind_In1S1[i]-ind_In2S1[i]); } } double a3 = sum2; double a4 = (((ind_In1S1[0]-ind_In1S1[Candles])/Point())/Candles); double a5 = (((ind_In2S1[0]-ind_In2S1[Candles])/Point())/Candles); for(int i=0; i<=1000; i++) { if(ind_In1S1[0]>ind_In2S1[0]) { if(ind_In1S1[i]<ind_In2S1[i]) { c1=i; break; } } if(ind_In1S1[0]<ind_In2S1[0]) { if(ind_In1S1[i]>ind_In2S1[i]) { c1=i; break; } } } double a6 = (((ind_In1S1[0]-ind_In1S1[c1])/Point())/c1); double a7 = (((ind_In2S1[0]-ind_In2S1[c1])/Point())/c1); Print("a1 = ", a1); Print("a2 = ", a2); Print("a3 = ", a3); Print("a4 = ", a4); Print("a5 = ", a5); Print("a6 = ", a6); Print("a7 = ", a7); Print("Perceptron = ", (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4 + w5 * a5 + w6 * a6 + w7 * a7)); Print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4 + w5 * a5 + w6 * a6 + w7 * a7); }
ログデータ
a1:現在のローソク足のMA1とMA100の間の距離。正負の両方の値を取ることができます。
a2:Candlesパラメータのローソク足数の指標MA1とMA100の間の累積。正負の両方の値を取ることができます。
a3:指標の最後の交点からの指標MA1とMA100の間の累積。正負の両方の値を取ることができます。
a4:Candlesパラメータのローソク足の数に対するMA1指標の傾斜角。正負の両方の値を取ることができます。
a5:Candlesパラメータのローソク足の数に対するMA100指標の傾斜角。 正負の両方の値を取ることができます。
a6:MA1指標の最後の交点からの指標の傾斜角。正負の両方の値を取ることができます。
a7-MA100指標の最後の交点からの指標の傾斜角度。正負の両方の値を取ることができます。
エキスパートアドバイザー(EA)
ここでは2つのEAを開発します。例として、指標間の距離の値を使用します。最初のものは、パラメータの最適化と選択のために実装されます。2つ目は、最初の結果から得られた結果を使用して取引することを目的としています。このアプローチについては、以前の記事ですでに検討しました。この方法は、取引で利用可能なすべての最適化結果を分類して使用するのに役立ちます。例えば、最適化中に50件の良好な結果が得られました。ご想像のとおり、50のチャートにEAをインストールするのはあまり便利ではありません。したがって、2つ目のEAを利用してすべての結果を同時に使用します。
この方法の詳細については「ニューラルネットワークの実験(第3回):実用化」稿をご覧ください。
以下に最適化のための最初のEAのメインコードを提供し、パーセプトロンに渡したものについて説明します。
ポジションを建てるためのメインコード
//SELL++++++++++++++++++++++++++++++++++++++++++++++++ if((perceptron1()<-Param) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment)==0) && (SpreadS1<=MaxSpread)) { OpenSell(symbolS1.Name(), LotsXSell, TP, SL, EAComment); } //BUY++++++++++++++++++++++++++++++++++++++++++++++++ if((perceptron1()>Param) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment)==0) && (SpreadS1<=MaxSpread)) { OpenBuy(symbolS1.Name(), LotsXBuy, TP, SL, EAComment); }
パーセプトロンコード
- a1は、現在のローソク足のMA1指標とCandlesパラメータのローソク足の間の距離です。
- a2は、現在のローソク足のMA100指標とCandlesパラメータのローソク足の間の距離です。
- a3は、現在のローソク足のCCI指標とCandlesパラメータのローソク足の間の距離です。
- a4は、現在のローソク足のStdDev指標とCandlesパラメータのローソク足の間の距離です。
この場合のCandlesパラメータは最適化されておらず、値は8でした。
//+------------------------------------------------------------------+ //| The PERCEPRRON - a perceiving and recognizing function | //+------------------------------------------------------------------+ double perceptron1() { double w1 = x1 - 10.0; double w2 = x2 - 10.0; double w3 = x3 - 10.0; double w4 = x4 - 10.0; double a1 = ((ind_In1S1[0]-ind_In1S1[Candles])/PointS1); double a2 = ((ind_In2S1[0]-ind_In2S1[Candles])/PointS1); double a3 = (ind_In3S1[0]-ind_In3S1[Candles]); double a4 = (ind_In4S1[0]-ind_In4S1[Candles]); return (w1 * a1 + w2 * a2 + w3 * a3 + w4 * a4); }
ここでは、最適化とテストのためのすべてのパラメータを提供します。本文中ではこれ以上繰り返さないようにします。
- 外国為替市場
- EURUSD
- 時間枠:H1
- 指標:MA 1 SMA CLOSE, MA 200 SMA CLOSE, CCI 42, StdDev 60
- ストップロスとテイクプロフィット:400と830
- 最適化およびテストモード「1 Minute OHLC」および「Maximum Profit」。私たちのEAは最初はM1始値で動作します。ここでは、実験として「Maximum Profit」モードを使用します。
- 最適化範囲は1年で、2021.10.10から2022.10.10までです。1年というのは何かの基準ではありません。ご自分で増減してください。
- フォワードテストの範囲は1年で、2022.10.10から2023.10.10まで。
- フォワードテストでは、最初の50件の最良の最適化結果が同時に使用されました。
- 初回入金:10000
- レバレッジ:1:500
最適化設定は以下のスクリーンショットに示されています
最適化の結果を以下のスクリーンショットに示します。
最適化が完了したら、Excelを使用してCSV形式のファイルを生成します。最初の50件の最良の結果を採用していることを思い出してください。結果のファイルをテストのために2つ目のEAのコードに貼り付けます。コードにすると以下のようになります。
string EURUSD[][8]= { {"Profit","Trades","x1","x2","x3","x4","Param"}, {"266.45","239","2","1","9","8","5000"}, {"266.45","239","2","1","9","13","5000"}, {"266.45","239","2","1","9","11","5000"}, {"266.45","239","2","1","9","10","5000"}, {"266.45","239","2","1","9","8","5000"}, {"266.45","239","2","1","9","12","5000"}, {"266.45","239","2","1","9","20","5000"}, {"266.45","239","2","1","9","14","5000"}, {"266.45","239","2","1","9","2","5000"}, {"266.45","239","2","1","9","3","5000"}, {"259.69","239","0","0","12","17","5500"}, {"259.69","239","0","0","12","8","5500"}, {"259.69","239","0","0","12","1","5500"}, {"259.69","239","0","0","12","9","5500"}, {"259.69","239","0","0","12","16","5500"}, {"259.69","239","0","0","12","18","5500"}, {"259.69","239","0","0","12","11","5500"}, {"259.69","239","0","0","12","7","5500"}, {"259.69","239","0","0","12","15","5500"}, {"259.69","239","0","0","12","8","5500"}, {"259.69","239","0","0","12","9","5500"}, {"259.69","239","0","0","12","17","5500"}, {"259.69","239","0","0","12","6","5500"}, {"259.69","239","0","0","12","15","5500"}, {"259.69","239","0","0","12","4","5500"}, {"259.69","239","0","0","12","7","5500"}, {"259.69","239","0","0","12","11","5500"}, {"259.69","239","0","0","12","14","5500"}, {"259.69","239","0","0","12","1","5500"}, {"259.69","239","0","0","12","5","5500"}, {"259.69","239","0","0","12","3","5500"}, {"259.69","239","0","0","12","0","5500"}, {"259.69","239","0","0","12","12","5500"}, {"259.69","239","0","0","12","16","5500"}, {"259.69","239","0","0","12","8","5500"}, {"259.69","239","0","0","12","10","5500"}, {"259.69","239","0","0","12","16","5500"}, {"259.69","239","0","0","12","18","5500"}, {"259.69","239","0","0","12","13","5500"}, {"259.69","239","0","0","12","9","5500"}, {"259.69","239","0","0","12","12","5500"}, {"259.69","239","0","0","12","11","5500"}, {"259.69","239","0","0","12","7","5500"}, {"259.69","239","0","0","12","15","5500"}, {"259.69","239","0","0","12","14","5500"}, {"259.69","239","0","0","12","3","5500"}, {"259.69","239","0","0","12","19","5500"}, {"259.69","239","0","0","12","0","5500"}, {"259.69","239","0","0","12","17","5500"}, {"259.69","239","0","0","12","2","5500"} };
2つ目の取引EAのコードも提供します。ご覧のとおり、ループ内の最適化中に取得されたすべての値を調べて、それらをパーセプトロンの現在の実行結果と比較します。値が一致すると、対応する買いまたは売りのポジションが建てられます。同時に建てるポジションの数の制限は、MaxSeriesパラメータと、コメントによってポジションを計算するCalculateSeries関数によって制御されます。
for(int i=1; i<=(ArraySize(EURUSD)/8)-1; i++) { comm=(EURUSD[i][0]+EURUSD[i][1]); x1=(int)StringToInteger(EURUSD[i][2]); x2=(int)StringToInteger(EURUSD[i][3]); x3=(int)StringToInteger(EURUSD[i][4]); x4=(int)StringToInteger(EURUSD[i][5]); Param=(int)StringToInteger(EURUSD[i][6]); //SELL++++++++++++++++++++++++++++++++++++++++++++++++ if((NewOpen==true) && (CalculateSeries(Magic)<MaxSeries) && (perceptron1()<-Param) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_SELL, EAComment+" En_"+comm)==0) && (SpreadS1<=MaxSpread)) { OpenSell(symbolS1.Name(), LotsXSell, TP, SL, EAComment+" En_"+comm); } //BUY++++++++++++++++++++++++++++++++++++++++++++++++ if((NewOpen==true) && (CalculateSeries(Magic)<MaxSeries) && (perceptron1()>Param) && (CalculatePositions(symbolS1.Name(), Magic, POSITION_TYPE_BUY, EAComment+" En_"+comm)==0) && (SpreadS1<=MaxSpread)) { OpenBuy(symbolS1.Name(), LotsXBuy, TP, SL, EAComment+" En_"+comm); } }
//+------------------------------------------------------------------+ //| Calculate Positions | //+------------------------------------------------------------------+ int CalculateSeries(ulong mag) { int total=0; string com=""; for(int i=PositionsTotal()-1; i>=0; i--) { if(position.SelectByIndex(i)) { if(position.Magic()==mag) { if(com!=position.Comment()) { com=position.Comment(); total++; } } } } //--- return(total); }
バックワードテストの結果
次は、フォワードテスト結果です。
結論
添付ファイル内のファイルのリスト
- Distance1、Distance2、Distance3:距離をパーセプトロンに渡す例を特徴とするEA
- Accumulation1、Accumulation2:累積をパーセプトロンに渡す例を特徴とするEA
- Angle1、Angle2:指標の傾斜角をパーセプトロンに渡す例を特徴とするEA
- Combo 1:組み合わされた指標データをパーセプトロンに渡す例を含むEA
- Perceptron – opt:最適化EA
- Perceptron–trade:最適化されたパラメータを取引するためのEA
フォワードテストの結果からわかるように、指標を渡すためのアプローチはうまく機能しています。最初の6か月間、EAはかなり自信を持って残高を押し上げます。上記では、指標受け渡しのあらゆる種類の例を示しました。それらをテストしてみることに興味があるかもしれません。今回は多くの作業がおこなわれましたが、常に努力すべきことがあります。
質問があったら、フォーラムまたはプライベートメッセージでお気軽にご連絡ください。いつでも喜んでお手伝いします。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/13598
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索