English Русский 中文 Español Deutsch Português
preview
トレーディングにおけるニューラルネットワークの実用化。 Python (パートI)

トレーディングにおけるニューラルネットワークの実用化。 Python (パートI)

MetaTrader 5 | 5 2月 2021, 09:37
1 507 0
Andrey Dibrov
Andrey Dibrov

イントロダクション

前の記事では、「トレードにおけるニューラルネットワークの実用化 と実践」と題して、Matlabのニューラルネットワークを用いて実装したニューラルネットワークモジュールの実用化について考えてみました。 しかし、その記事では、インプットデータの作成やネットワークトレーニング関連の操作に関する質問は取り上げられていませんでした。 この記事では、それらの疑問を例を用いて検討し、Pythonで動作するライブラリのニューラルネットワークを使用して、さらなるコードを実装していきます。 今回は、トレードシステムの実装原理が異なります。 この変形は、基本記事「トレードにおけるニューラルネットワークの実用化」の第5段落で説明しました。 今回の実装では、Google社が開発した機械学習ライブラリTensorFlowを使用します。 また、ニューラル ネットワークを記述するために Keras ライブラリを使用します。


1. データ作成

ニューラルネットワーク学習のデータ準備に関するポイントを考えてみましょう。

  • 意思決定のために、2つのニューラルネットワークを用いて、一方向にポジションを開くために使用します。
  • 前述のポイントによれば、トレーニングデータは、各方向ごとに2つのグループに分割する必要があります。
  • 前のシステムと同様に、最初のニューラルネットワークをトレーニングして、標準的なテクニカルインジケータと同様のインジケータを構築します。 以前のシステムでは、自分で書いたインジケータを使用していたので、タスク中のExpert Advisorに負荷をかけたくなかったので、このソリューションを使用しました。 ターミナルからはクオートしか受け取れないので、Pythonを使用します。 ニューラルネットワークのデータを用意するには、インジケータをPythonスクリプトで構築する必要があります。 このようなインジケータを構築するためのニューラルネットワークを教えることで、スクリプト内で重複する必要がなくなります。 
  • 2番目のニューラルネットワークは、トレード戦略を作成することに基づいて、シグナルインジケータを構築します。
  • ニューラルネットワークは、EURUSDのH1チャートでトレーニングされます。
  • その結果、システムを構築するためには、買いのためのニューラルネットワークを2つ、売りのためのネットワークを2つ用意する必要があります。 このように、4つのニューラルネットワークがシステムの中で機能することになります。

ネットワークを学習するためのデータを準備するために、2つのスクリプトを使用します。PythonPrices.mq5とPythonIndicators.mq5です。

//+------------------------------------------------------------------+
//|                                                 PythonPrices.mq5 |
//|                                   Copyright 2020, Andrey Dibrov. |
//|                           https://www.mql5.com/ru/users/tomcat66 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, Andrey Dibrov."
#property link      "https://www.mql5.com/ru/users/tomcat66"
#property version   "1.00"
#property strict
#property script_show_inputs

input string Date="2004.07.01 00:00";
input string DateOut="2010.12.31 23:00";
input int History=0;

double inB[22];
string Date1;

int HandleInpuNet1Min;
int HandleInpuNet1Max;

double DibMin1_1[];
double DibMax1_1 [];
int DibMin1_1Handle;
int DibMax1_1Handle;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int k=iBars(NULL,PERIOD_H1)-1;

   DibMin1_1Handle=iCustom(NULL,PERIOD_H1,"DibMin1-1",History);
   CopyBuffer(DibMin1_1Handle,0,0,k,DibMin1_1);
   ArraySetAsSeries(DibMin1_1,true);

   DibMax1_1Handle=iCustom(NULL,PERIOD_H1,"DibMax1-1",History);
   CopyBuffer(DibMax1_1Handle,0,0,k,DibMax1_1);
   ArraySetAsSeries(DibMax1_1,true);

   HandleInpuNet1Min=FileOpen(Symbol()+"InputNet1Min.csv",FILE_CSV|FILE_WRITE|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";");
   HandleInpuNet1Max=FileOpen(Symbol()+"InputNet1Max.csv",FILE_CSV|FILE_WRITE|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";");
   FileSeek(HandleInpuNet1Min,0,SEEK_END);
   FileSeek(HandleInpuNet1Max,0,SEEK_END);

   if(HandleInpuNet1Min>0)
     {
      Alert("Writing to the file InputNet1Min");

      for(int i=iBars(NULL,PERIOD_H1)-1; i>=0; i--)
        {

         Date1=TimeToString(iTime(NULL,PERIOD_H1,i));

         if(DateOut>=Date1 && Date<=Date1)
           {
            if((DibMin1_1[i]==-1 && DibMin1_1[i+1]==1 && DibMax1_1[i]==1) || (DibMin1_1[i]==1 && DibMax1_1[i]==1))
              {
               for(int m=0; m<=14; m++)
                 {
                  inB[m]=inB[m+5];
                 }

               inB[15]=(iOpen(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)))-iLow(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i))))*100000;
               inB[16]=(iHigh(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)))-iOpen(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i))))*100000;
               inB[17]=(iHigh(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)))-iLow(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i))))*10000;
               inB[18]=(iHigh(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)))-iOpen(NULL,PERIOD_H1,i+1))*10000;
               inB[19]=(iOpen(NULL,PERIOD_H1,i+1)-iLow(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i))))*10000;

               inB[20]=(iHigh(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)))-iOpen(NULL,PERIOD_H1,i))*10000;
               inB[21]=(iOpen(NULL,PERIOD_H1,i)-iLow(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i))))*10000;

               FileWrite(HandleInpuNet1Min,

                         inB[0],inB[1],inB[2],inB[3],inB[4],inB[5],inB[6],inB[7],inB[8],inB[9],inB[10],inB[11],inB[12],inB[13],inB[14],inB[15],
                         inB[16],inB[17],inB[18],inB[19],inB[20],inB[21]);
              }
           }
        }

      FileClose(HandleInpuNet1Min);
     }
//------------------------------------------------------------------------------------------------------------------------------------------------

   if(HandleInpuNet1Max>0)
     {
      Alert("Writing the file InputNet1Max");

      for(int i=iBars(NULL,PERIOD_H1)-1; i>=0; i--)
        {

         Date1=TimeToString(iTime(NULL,PERIOD_H1,i));

         if(DateOut>=Date1 && Date<=Date1)
           {
            if((DibMax1_1[i]==-1 && DibMax1_1[i+1]==1 && DibMin1_1[i]==1)|| (DibMin1_1[i]==1 && DibMax1_1[i]==1))
              {
               for(int m=0; m<=14; m++)
                 {
                  inB[m]=inB[m+5];
                 }

               inB[15]=(iOpen(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)))-iLow(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i))))*100000;
               inB[16]=(iHigh(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)))-iOpen(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i))))*100000;
               inB[17]=(iHigh(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)))-iLow(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i))))*10000;
               inB[18]=(iHigh(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)))-iOpen(NULL,PERIOD_H1,i+1))*10000;
               inB[19]=(iOpen(NULL,PERIOD_H1,i+1)-iLow(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i))))*10000;

               inB[20]=(iHigh(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)))-iOpen(NULL,PERIOD_H1,i))*10000;
               inB[21]=(iOpen(NULL,PERIOD_H1,i)-iLow(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i))))*10000;

               FileWrite(HandleInpuNet1Max,

                         inB[0],inB[1],inB[2],inB[3],inB[4],inB[5],inB[6],inB[7],inB[8],inB[9],inB[10],inB[11],inB[12],inB[13],inB[14],inB[15],
                         inB[16],inB[17],inB[18],inB[19],inB[20],inB[21]);
              }
           }
        }

      FileClose(HandleInpuNet1Max);
     }
   Alert("Files written");

  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                             PythonIndicators.mq5 |
//|                                   Copyright 2020, Andrey Dibrov. |
//|                           https://www.mql5.com/ru/users/tomcat66 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, Andrey Dibrov."
#property link      "https://www.mql5.com/ru/users/tomcat66"
#property version   "1.00"
#property strict
#property script_show_inputs

input string Date="2004.07.01 00:00";
input string DateOut="2010.12.31 23:00";
input int History=0;

double Stochastic0[];
double Stochastic1[];
double CCI_Open[];
double CCI_Low[];
double CCI_High[];
double Momentum_Open[];
double Momentum_Low[];
double Momentum_High[];
double RSI_Open[];
double RSI_Low[];
double RSI_High[];
double WPR[];
double MACD_Open[];
double MACD_Low[];
double MACD_High[];
double OsMA_Open[];
double OsMA_Low[];
double OsMA_High[];
double TriX_Open[];
double TriX_Low[];
double TriX_High[];
double BearsPower[];
double BullsPower[];
double ADX_MINUSDI[];
double ADX_PLUSDI[];
double StdDev_Open[];
double StdDev_Low[];
double StdDev_High[];

//--------------------------
double DibMin1_1[];
double DibMax1_1 [];

int DibMin1_1Handle;
int DibMax1_1Handle;
//--------------------------
double inB[60];
double inS[60];

string Date1;

int HandleInputNet2OutNet1Min;
int HandleOutNet2Min;
int HandleInputNet2OutNet1Max;
int HandleOutNet2Max;

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int k=iBars(NULL,PERIOD_H1)-1;

//------ Daily Low

   DibMin1_1Handle=iCustom(NULL,PERIOD_H1,"DibMin1-1",History);
   CopyBuffer(DibMin1_1Handle,0,0,k,DibMin1_1);
   ArraySetAsSeries(DibMin1_1,true);

   DibMax1_1Handle=iCustom(NULL,PERIOD_H1,"DibMax1-1",History);
   CopyBuffer(DibMax1_1Handle,0,0,k,DibMax1_1);
   ArraySetAsSeries(DibMax1_1,true);

   int Stochastic_handle=iStochastic(NULL,PERIOD_H1,5,3,3,MODE_SMA,STO_LOWHIGH);
   CopyBuffer(Stochastic_handle,0,0,k,Stochastic0);
   CopyBuffer(Stochastic_handle,1,0,k,Stochastic1);
   ArraySetAsSeries(Stochastic0,true);
   ArraySetAsSeries(Stochastic1,true);

   int CCI_Open_handle=iCCI(NULL,PERIOD_H1,14,PRICE_OPEN);
   CopyBuffer(CCI_Open_handle,0,0,k,CCI_Open);
   ArraySetAsSeries(CCI_Open,true);

   int CCI_Low_handle=iCCI(NULL,PERIOD_H1,14,PRICE_LOW);
   CopyBuffer(CCI_Low_handle,0,0,k,CCI_Low);
   ArraySetAsSeries(CCI_Low,true);

   int Momentum_Open_handle=iMomentum(NULL,PERIOD_H1,14,PRICE_OPEN);
   CopyBuffer(Momentum_Open_handle,0,0,k,Momentum_Open);
   ArraySetAsSeries(Momentum_Open,true);

   int Momentum_Low_handle=iMomentum(NULL,PERIOD_H1,14,PRICE_LOW);
   CopyBuffer(Momentum_Low_handle,0,0,k,Momentum_Low);
   ArraySetAsSeries(Momentum_Low,true);

   int RSI_Open_handle=iRSI(NULL,PERIOD_H1,14,PRICE_OPEN);
   CopyBuffer(RSI_Open_handle,0,0,k,RSI_Open);
   ArraySetAsSeries(RSI_Open,true);

   int RSI_Low_handle=iRSI(NULL,PERIOD_H1,14,PRICE_LOW);
   CopyBuffer(RSI_Low_handle,0,0,k,RSI_Low);
   ArraySetAsSeries(RSI_Low,true);

   int WPR_handle=iWPR(NULL,PERIOD_H1,14);
   CopyBuffer(WPR_handle,0,0,k,WPR);
   ArraySetAsSeries(WPR,true);

   int MACD_Open_handle=iMACD(NULL,PERIOD_H1,12,26,9,PRICE_OPEN);
   CopyBuffer(MACD_Open_handle,0,0,k,MACD_Open);
   ArraySetAsSeries(MACD_Open,true);

   int MACD_Low_handle=iMACD(NULL,PERIOD_H1,12,26,9,PRICE_LOW);
   CopyBuffer(MACD_Low_handle,0,0,k,MACD_Low);
   ArraySetAsSeries(MACD_Low,true);

   int OsMA_Open_handle=iOsMA(NULL,PERIOD_H1,12,26,9,PRICE_OPEN);
   CopyBuffer(OsMA_Open_handle,0,0,k,OsMA_Open);
   ArraySetAsSeries(OsMA_Open,true);

   int OsMA_Low_handle=iOsMA(NULL,PERIOD_H1,12,26,9,PRICE_LOW);
   CopyBuffer(OsMA_Low_handle,0,0,k,OsMA_Low);
   ArraySetAsSeries(OsMA_Low,true);

   int TriX_Open_handle=iTriX(NULL,PERIOD_H1,14,PRICE_OPEN);
   CopyBuffer(TriX_Open_handle,0,0,k,TriX_Open);
   ArraySetAsSeries(TriX_Open,true);

   int TriX_Low_handle=iTriX(NULL,PERIOD_H1,14,PRICE_LOW);
   CopyBuffer(TriX_Low_handle,0,0,k,TriX_Low);
   ArraySetAsSeries(TriX_Low,true);

   int BearsPower_handle=iBearsPower(NULL,PERIOD_H1,13);
   CopyBuffer(BearsPower_handle,0,0,k,BearsPower);
   ArraySetAsSeries(BearsPower,true);

   int ADX_MINUSDI_handle=iADX(NULL,PERIOD_H1,14);
   CopyBuffer(ADX_MINUSDI_handle,2,0,k,ADX_MINUSDI);
   ArraySetAsSeries(ADX_MINUSDI,true);

   int StdDev_Open_handle=iStdDev(NULL,PERIOD_H1,20,0,MODE_SMA,PRICE_OPEN);
   CopyBuffer(StdDev_Open_handle,0,0,k,StdDev_Open);
   ArraySetAsSeries(StdDev_Open,true);

   int StdDev_Low_handle=iStdDev(NULL,PERIOD_H1,20,0,MODE_SMA,PRICE_LOW);
   CopyBuffer(StdDev_Low_handle,0,0,k,StdDev_Low);
   ArraySetAsSeries(StdDev_Low,true);
//---------------------------------------------------------------------------------------------------------------------------

   HandleInputNet2OutNet1Min=FileOpen(Symbol()+"InputNet2OutNet1Min.csv",FILE_CSV|FILE_WRITE|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";");
   HandleOutNet2Min=FileOpen(Symbol()+"OutNet2Min.csv",FILE_CSV|FILE_WRITE|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";");
   FileSeek(HandleInputNet2OutNet1Min,0,SEEK_END);
   FileSeek(HandleOutNet2Min,0,SEEK_END);

   if(HandleInputNet2OutNet1Min>0)
     {
      Alert("Writing the files InputNet2OutNet1Min and OutNet2Min");

      for(int i=iBars(NULL,PERIOD_H1)-1; i>=0; i--)
        {
         Date1=TimeToString(iTime(NULL,PERIOD_H1,i));

         if(DateOut>=Date1 && Date<=Date1)
           {
            if(((DibMin1_1[i]==-1 && DibMin1_1[i+1]==1 && DibMax1_1[i]==1)) || (DibMin1_1[i]==1 && DibMax1_1[i]==1))

              {
               for(int m=0; m<=35; m++)
                 {
                  inB[m]=inB[m+12];
                 }

               inB[36]=Stochastic0[i];
               inB[37]=Stochastic1[i];
               inB[38]=CCI_Low[i];
               inB[39]=Momentum_Low[i];
               inB[40]=RSI_Low[i];;
               inB[41]=WPR[i+1];
               inB[42]=MACD_Low[i]*10000;
               inB[43]=OsMA_Low[i]*100000;
               inB[44]=TriX_Low[i]*100000;;
               inB[45]=BearsPower[i+1]*1000;
               inB[46]=ADX_MINUSDI[i+1];
               inB[47]=StdDev_Low[i]*10000;

               inB[48]=Stochastic0[i];
               inB[49]=Stochastic1[i];
               inB[50]=CCI_Open[i];
               inB[51]=Momentum_Open[i];
               inB[52]=RSI_Open[i];;
               inB[53]=WPR[i];
               inB[54]=MACD_Open[i]*10000;
               inB[55]=OsMA_Open[i]*100000;
               inB[56]=TriX_Open[i]*100000;;
               inB[57]=BearsPower[i]*1000;
               inB[58]=ADX_MINUSDI[i];
               inB[59]=StdDev_Open[i]*10000;

               FileWrite(HandleInputNet2OutNet1Min,
                         inB[0],inB[1],inB[2],inB[3],inB[4],inB[5],inB[6],inB[7],inB[8],inB[9],inB[10],inB[11],inB[12],inB[13],
                         inB[14],inB[15],inB[16],inB[17],inB[18],inB[19],inB[20],inB[21],inB[22],inB[23],inB[24],inB[25],inB[26],
                         inB[27],inB[28],inB[29],inB[30],inB[31],inB[32],inB[33],inB[34],inB[35],inB[36],inB[37],inB[38],inB[39],
                         inB[40],inB[41],inB[42],inB[43],inB[44],inB[45],inB[46],inB[47],inB[48],inB[49],inB[50],inB[51],inB[52],
                         inB[53],inB[54],inB[55],inB[56],inB[57],inB[58],inB[59]);

               FileWrite(HandleOutNet2Min,
                         (iOpen(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)))-iOpen(NULL,PERIOD_H1,i))*10000);
              }
           }
        }
     }

   //------ Daily High

   int CCI_High_handle=iCCI(NULL,PERIOD_H1,14,PRICE_HIGH);
   CopyBuffer(CCI_High_handle,0,0,k,CCI_High);
   ArraySetAsSeries(CCI_High,true);

   int Momentum_High_handle=iMomentum(NULL,PERIOD_H1,14,PRICE_HIGH);
   CopyBuffer(Momentum_High_handle,0,0,k,Momentum_High);
   ArraySetAsSeries(Momentum_High,true);

   int RSI_High_handle=iRSI(NULL,PERIOD_H1,14,PRICE_HIGH);
   CopyBuffer(RSI_High_handle,0,0,k,RSI_High);
   ArraySetAsSeries(RSI_High,true);

   int MACD_High_handle=iMACD(NULL,PERIOD_H1,12,26,9,PRICE_HIGH);
   CopyBuffer(MACD_High_handle,0,0,k,MACD_High);
   ArraySetAsSeries(MACD_High,true);

   int OsMA_High_handle=iOsMA(NULL,PERIOD_H1,12,26,9,PRICE_HIGH);
   CopyBuffer(OsMA_High_handle,0,0,k,OsMA_High);
   ArraySetAsSeries(OsMA_High,true);

   int TriX_High_handle=iTriX(NULL,PERIOD_H1,14,PRICE_HIGH);
   CopyBuffer(TriX_High_handle,0,0,k,TriX_High);
   ArraySetAsSeries(TriX_High,true);

   int BullsPower_handle=iBullsPower(NULL,PERIOD_H1,13);
   CopyBuffer(BullsPower_handle,0,0,k,BullsPower);
   ArraySetAsSeries(BullsPower,true);

   int ADX_PLUSDI_handle=iADX(NULL,PERIOD_H1,14);
   CopyBuffer(ADX_PLUSDI_handle,1,0,k,ADX_PLUSDI);
   ArraySetAsSeries(ADX_PLUSDI,true);

   int StdDev_High_handle=iStdDev(NULL,PERIOD_H1,20,0,MODE_SMA,PRICE_HIGH);
   CopyBuffer(StdDev_High_handle,0,0,k,StdDev_High);
   ArraySetAsSeries(StdDev_High,true);
//---------------------------------------------------------------------------------------------------------------------------

   HandleInputNet2OutNet1Max=FileOpen(Symbol()+"InputNet2OutNet1Max.csv",FILE_CSV|FILE_WRITE|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";");
   HandleOutNet2Max=FileOpen(Symbol()+"OutNet2Max.csv",FILE_CSV|FILE_WRITE|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";");
   FileSeek(HandleInputNet2OutNet1Max,0,SEEK_END);
   FileSeek(HandleOutNet2Max,0,SEEK_END);

   if(HandleInputNet2OutNet1Max>0)
     {
      Alert("Writing the files InputNet2OutNet1Max and OutNet2Max");

      for(int i=iBars(NULL,PERIOD_H1)-1; i>=0; i--)
        {
         Date1=TimeToString(iTime(NULL,PERIOD_H1,i));

         if(DateOut>=Date1 && Date<=Date1)
           {
            if(((DibMax1_1[i]==-1 && DibMax1_1[i+1]==1 && DibMin1_1[i]==1)) || (DibMin1_1[i]==1 && DibMax1_1[i]==1))

              {
               for(int m=0; m<=35; m++)
                 {
                  inS[m]=inS[m+12];
                 }

               inS[36]=Stochastic0[i];
               inS[37]=Stochastic1[i];
               inS[38]=CCI_High[i];
               inS[39]=Momentum_High[i];
               inS[40]=RSI_High[i];;
               inS[41]=WPR[i+1];
               inS[42]=MACD_High[i]*10000;
               inS[43]=OsMA_High[i]*100000;
               inS[44]=TriX_High[i]*100000;;
               inS[45]=BullsPower[i+1]*1000;
               inS[46]=ADX_PLUSDI[i+1];
               inS[47]=StdDev_High[i]*10000;

               inS[48]=Stochastic0[i];
               inS[49]=Stochastic1[i];
               inS[50]=CCI_Open[i];
               inS[51]=Momentum_Open[i];
               inS[52]=RSI_Open[i];;
               inS[53]=WPR[i];
               inS[54]=MACD_Open[i]*10000;
               inS[55]=OsMA_Open[i]*100000;
               inS[56]=TriX_Open[i]*100000;;
               inS[57]=BullsPower[i]*1000;
               inS[58]=ADX_PLUSDI[i];
               inS[59]=StdDev_Open[i]*10000;

               FileWrite(HandleInputNet2OutNet1Max,
                         inS[0],inS[1],inS[2],inS[3],inS[4],inS[5],inS[6],inS[7],inS[8],inS[9],inS[10],inS[11],inS[12],inS[13],
                         inS[14],inS[15],inS[16],inS[17],inS[18],inS[19],inS[20],inS[21],inS[22],inS[23],inS[24],inS[25],inS[26],
                         inS[27],inS[28],inS[29],inS[30],inS[31],inS[32],inS[33],inS[34],inS[35],inS[36],inS[37],inS[38],inS[39],
                         inS[40],inS[41],inS[42],inS[43],inS[44],inS[45],inS[46],inS[47],inS[48],inS[49],inS[50],inS[51],inS[52],
                         inS[53],inS[54],inS[55],inS[56],inS[57],inS[58],inS[59]);

               FileWrite(HandleOutNet2Max,
                         (iOpen(NULL,PERIOD_H1,i)-iOpen(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i))))*10000);
              }
           }
        }
     }

   Alert("Files written");
  }
//+------------------------------------------------------------------+

1サンプルは、営業日の開始からその日の安値の最初のリーチまでとなります。 2回目のサンプルは、その日の高値の最初のリーチまでとなります。 このため、スクリプトでは2つのインジケータを使用します。DibMin1-1.mq5 と DibMax1-1.mq5 です。

//+------------------------------------------------------------------+
//|                                                    DibMin1-1.mq5 |
//|                                   Copyright 2020, Andrey Dibrov. |
//|                           https://www.mql5.com/ru/users/tomcat66 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, Andrey Dibrov."
#property link      "https://www.mql5.com/ru/users/tomcat66"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_minimum -2
#property indicator_maximum 2
#property indicator_color1 Red
#property indicator_label1  "DibMin1-1"
//---- input parameters
input int History=500;
double Buf[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Buf,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int    i,z,Calc;
   double price;

   i=iBars(NULL,PERIOD_H1)-1;
   if(i>History-1)
      i=History-1;
   if(History==0)
      i=iBars(NULL,PERIOD_H1)-1;
   ArraySetAsSeries(Buf,true);
   ArraySetAsSeries(time,true);

   while(i>=0)
     {
      int min=0;
      Calc=(int)time[i]%86400/3600;
      double min1=iLow(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)));
      for(z=0;z<=Calc;z++)
        {
          price=iLow(NULL,PERIOD_H1,i+z);
          if(min1<price)
          {
           min=1;
          }else
          {
           min=-1;
          break;
          }
         }
      Buf[i]=min;
      i--;
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|                                                    DibMax1-1.mq5 |
//|                                   Copyright 2020, Andrey Dibrov. |
//|                           https://www.mql5.com/ru/users/tomcat66 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, Andrey Dibrov."
#property link      "https://www.mql5.com/ru/users/tomcat66"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE 
#property indicator_minimum -2
#property indicator_maximum 2
#property indicator_color1 LightSeaGreen
#property indicator_label1  "DibMax1-1"
//---- input parameters
input int History=500;
double Buf[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,Buf,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int    i,z,Calc;
   double price;
   
   i=iBars(NULL,PERIOD_H1)-1;
   if (i>History-1)i=History-1;
   if (History==0) i=iBars(NULL,PERIOD_H1)-1;
   ArraySetAsSeries(Buf,true);
   ArraySetAsSeries(time,true);
   
   while(i>=0)
     {
      int max=0;
      Calc=(int)time[i]%86400/3600;
      double max1=iHigh(NULL,PERIOD_D1,iBarShift(NULL,PERIOD_D1,iTime(NULL,PERIOD_H1,i)));
      for(z=0;z<=Calc;z++)
        {
          price=iHigh(NULL,PERIOD_H1,i+z);//+1-1
          if(max1>price)
          {
           max=1;
          }else
          {
           max=-1;
           break;
          }
         }   
      Buf[i]=max;
      i--;
      } 
   return(rates_total);
  }
//+------------------------------------------------------------------+

サンプルインジケータ

価格が日足の極値に達すると、インジケータ値は-1に設定されます。

EURUSD H1チャート上でスクリプトを実行すると、\Common\Filesフォルダ内に6つのCSVファイルが作成されます。

  • EURUSDInputNet1MaxとEURUSDInputNet1Minは価格データ付きのファイルです。 このファイル名から、例えば EURUSDInputNet1Max には Net1Max ニューラル ネットワークのインプットデータが含まれていることがわかります。
  • EURUSDInputNet2OutNet1MaxとEURUSDInputNet2OutNet1Minはインジケータ値のファイルです。 これらの値が Net2 のインプットとなり、Net1 の出力となります。 この部分は多少の実験が必要なことに注意してください。Net2 は、標準的なテクニカルインジケータを使用して、または Net1 の応答を使用して学習させることができます。
  • EURUSDOutNet2MaxとEURUSDOutNet2Minは、Net2の出力:時間足の始まりと日足の始まり(または日足の終わりと時間足の始まり)の価格差です。

  1. ニューラルネットワークは、価格が極端な値に近づくことでトレーニングされますが、価格そのものではなく、インジケータ値を解釈します。
  2. ニューラルネットワークのターゲットは、時間足の始まりと日足の始まり (日足の終わりと時間足の始まり)の価格の差です。 また、ここで他のターゲットを試してみることができます、例えば、他の価格.の間の差のようなものです。
  3. このアプローチでは、ニューラルネットワークは日の特定の高値と安値を見つけるためにトレーニングされているのではなく、日の極値までの価格振幅を考慮して、高値/安値が近づく確率で動作するので、ニューラルネットワークモジュールのエラー応答の確率を平滑化します。 その後、価格振幅を利用することにした場合、日足終値と時間足始値の差を利用することができます。 この場合、起こるべきイベントではなく、達成されたターゲットを使用してニューラルネットワークをトレーニングするので、最初のオプションが好ましいようです。 このオプションは、過去のイベントを評価する方が予測を立てるよりも簡単なので、より論理的です。

2. パイソンニューラルネットワーク学習

まずは、MQL5のドキュメントのインテグレーションのセクションを確認します。 Python 3.8をインストールしてMetaTrader5の統合モジュールを接続したら、同じようにTensorFlow、Keras、Numpy、Pandasのライブラリを接続します。

TensorFlowのインストール


TensorFlowセットアップウィンドウ


ニューラルネットワークはPythonスクリプトEURUSDPyTren.pyを使って学習します。

import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import load_model

InputNet1=pd.read_csv('EURUSDInputNet1Min.csv', delimiter=';',header=None)
InputNet2OutNet1=pd.read_csv('EURUSDInputNet2OutNet1Min.csv', delimiter=';',header=None)
OutNet2=pd.read_csv('EURUSDOutNet2Min.csv', delimiter=';',header=None)

mean = InputNet1.mean(axis=0)
std = InputNet1.std(axis=0)
InputNet1 -= mean
InputNet1 /= std

mean = InputNet2OutNet1.mean(axis=0)
std = InputNet2OutNet1.std(axis=0)
InputNet2OutNet1 -= mean
InputNet2OutNet1 /= std

Net1Min = Sequential()
Net1Min.add(Dense(22, activation='relu', input_shape=(InputNet1.shape[1],)))
Net1Min.add(Dense(60))

Net1Min.compile(optimizer='adam', loss='mse', metrics=['mse'])
print(Net1Min.summary())

Net1Min.fit(InputNet1, InputNet2OutNet1, epochs=10, batch_size=10,verbose=2,validation_split=0.3)
Net1Min.save('net1Min.h5')

mean = OutNet2.mean(axis=0)
std = OutNet2.std(axis=0)
OutNet2 -= mean
OutNet2 /= std

Net2Min = Sequential()
Net2Min.add(Dense(60, activation='relu', input_shape=(InputNet2OutNet1.shape[1],)))
Net2Min.add(Dense(1))

Net2Min.compile(optimizer='adam', loss='mse', metrics=['mae'])
print(Net2Min.summary())

Net2Min.fit(InputNet2OutNet1, OutNet2, epochs=100, batch_size=10,verbose=2,validation_split=0.3)
Net2Min.save('net2Min.h5')

InputNet1=pd.read_csv('EURUSDInputNet1Max.csv', delimiter=';',header=None)
InputNet2OutNet1=pd.read_csv('EURUSDInputNet2OutNet1Max.csv', delimiter=';',header=None)
OutNet2=pd.read_csv('EURUSDOutNet2Max.csv', delimiter=';',header=None)

mean = InputNet1.mean(axis=0)
std = InputNet1.std(axis=0)
InputNet1 -= mean
InputNet1 /= std

mean = InputNet2OutNet1.mean(axis=0)
std = InputNet2OutNet1.std(axis=0)
InputNet2OutNet1 -= mean
InputNet2OutNet1 /= std

Net1Max = Sequential()
Net1Max.add(Dense(22, activation='relu', input_shape=(InputNet1.shape[1],)))
Net1Max.add(Dense(60))

Net1Max.compile(optimizer='adam', loss='mse', metrics=['mse'])
print(Net1Max.summary())

Net1Max.fit(InputNet1, InputNet2OutNet1, epochs=10, batch_size=10,verbose=2,validation_split=0.3)
Net1Max.save('net1Max.h5')

mean = OutNet2.mean(axis=0)
std = OutNet2.std(axis=0)
OutNet2 -= mean
OutNet2 /= std

Net2Max = Sequential()
Net2Max.add(Dense(60, activation='relu', input_shape=(InputNet2OutNet1.shape[1],)))
Net2Max.add(Dense(1))

Net2Max.compile(optimizer='adam', loss='mse', metrics=['mae'])
print(Net2Max.summary())

Net2Max.fit(InputNet2OutNet1, OutNet2, epochs=100, batch_size=10,verbose=2,validation_split=0.3)
Net2Max.save('net2Max.h5')

NetTest=pd.read_csv('EURUSDTest.csv', delimiter=';',header=None)
Date=pd.read_csv('EURUSDDate.csv', delimiter=';',header=None)

Net1Min = load_model('net1Min.h5')
Net2Min=  load_model('net2Min.h5')
Net1Max = load_model('net1Max.h5')
Net2Max=  load_model('net2Max.h5')
Net1Min = Net1Min.predict(NetTest)
Net2Min = Net2Min.predict(Net1Min)
Net1Max = Net1Max.predict(NetTest)
Net2Max = Net2Max.predict(Net1Max)

Date=pd.DataFrame(Date)
Date['0'] = Net2Min
Date.to_csv('IndicatorMin.csv',index=False, header=False,sep=';')
Date['0'] = Net2Max
Date.to_csv('IndicatorMax.csv',index=False, header=False,sep=';')

Date['0'] = Net2Min
Date['1'] = Net2Max
Date.to_csv('Indicator.csv',index=False, header=False,sep=';')

input('Press ENTER to exit') 

このスクリプトを\Common\Filesに保存します。

スクリプトを詳しく見ていきましょう。
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import load_model

Kerasからライブラリ、パッケージ、モジュールを接続するためのブロックです。

InputNet1=pd.read_csv('EURUSDInputNet1Min.csv', delimiter=';',header=None)
InputNet2OutNet1=pd.read_csv('EURUSDInputNet2OutNet1Min.csv', delimiter=';',header=None)
OutNet2=pd.read_csv('EURUSDOutNet2Min.csv', delimiter=';',header=None)

データファイルからデータフレームを作成します。

mean = InputNet1.mean(axis=0)
std = InputNet1.std(axis=0)
InputNet1 -= mean
InputNet1 /= std
データを標準化します。
Net1Min = Sequential()
Net1Min.add(Dense(22, activation='relu', input_shape=(InputNet1.shape[1],)))
Net1Min.add(Dense(60))

シークエンシャルネットワークモデルは、インプット層に22個のニューロンがあり、出力層には60個のニューロンがあります。

Net1Min = Sequential()
Net1Min.add(Dense(22, activation='relu', input_shape=(InputNet1.shape[1],)))
Net1Min.add(Dense(11))
Net1Min.add(Dense(60))
さらに、隠しレイヤーを追加してみるのもいいでしょう。
Net1Max.compile(optimizer='adam', loss='mse', metrics=['mse'])
print(Net1Max.summary())

ネットワークをコンパイルし、そのパラメータをPrintします。

Net1Min.fit(InputNet1, InputNet2OutNet1, epochs=10, batch_size=10,verbose=2,validation_split=0.3)
Net1Min.save('net1Min.h5')

ニューラル ネットワークのトレーニング: 10 エポック; ミニサンプル サイズは 10; トレーニング データの 30% は検証に割り当てられます。 ハイパー パラメータは、さらなる調整が必要な場合もあります。 トレーニングされたニューラルネットワークを保存します。

NetTest=pd.read_csv('EURUSDTest.csv', delimiter=';',header=None)
Date=pd.read_csv('EURUSDDate.csv', delimiter=';',header=None)

テスト用のデータフレームを作成します。

Net1Min = load_model('net1Min.h5')
Net2Min=  load_model('net2Min.h5')
Net1Max = load_model('net1Max.h5')
Net2Max=  load_model('net2Max.h5')
Net1Min = Net1Min.predict(NetTest)
Net2Min = Net2Min.predict(Net1Min)
Net1Max = Net1Max.predict(NetTest)
Net2Max = Net2Max.predict(Net1Max)

保存したニューラルネットワークを読み込み、その結果を取得します。

Date=pd.DataFrame(Date)
Date['0'] = Net2Min
Date.to_csv('IndicatorMin.csv',index=False, header=False,sep=';')
Date['0'] = Net2Max
Date.to_csv('IndicatorMax.csv',index=False, header=False,sep=';')

Date['0'] = Net2Min
Date['1'] = Net2Max
Date.to_csv('Indicator.csv',index=False, header=False,sep=';')

取得したデータをファイルに保存します。

input('Press ENTER to exit') 
待つか、ウィンドウを閉じるか。

また、スクリプトの正常な動作を確保するためには、ニューラルネットワークの応答を受信するためのデータを準備しておく必要がありますが、インジケータを形成するために使用され、このインジケータのトレード戦略の効率を分析するために使用します。

PythonTestExpert Expert Advisorsを使って行います。

//+------------------------------------------------------------------+
//|                                             PythonTestExpert.mq5 |
//|                                   Copyright 2020, Andrey Dibrov. |
//|                           https://www.mql5.com/ru/users/tomcat66 |
//+------------------------------------------------------------------+
#property copyright " Copyright © 2019, Andrey Dibrov."
#property link      "https://www.mql5.com/ru/users/tomcat66"
#property version   "1.00"
#property strict

int handleInput;
int HandleDate;

double in[22];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   handleInput=FileOpen(Symbol()+"Test.csv",FILE_CSV|FILE_WRITE|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";");
   HandleDate=FileOpen(Symbol()+"Date.csv",FILE_CSV|FILE_READ|FILE_WRITE|FILE_ANSI|FILE_COMMON,";");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   FileClose(handleInput);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   for(int i=0; i<=14; i++)
     {
      in[i]=in[i+5];
     }

   in[15]=((iOpen(NULL,PERIOD_D1,0)-iLow(NULL,PERIOD_D1,0))*100000);
   in[16]=((iHigh(NULL,PERIOD_D1,0)-iOpen(NULL,PERIOD_D1,0))*100000);
   in[17]=((iHigh(NULL,PERIOD_D1,0)-iLow(NULL,PERIOD_D1,0))*100000);
   in[18]=((iHigh(NULL,PERIOD_D1,0)-iOpen(NULL,PERIOD_H1,1))*10000);
   in[19]=((iOpen(NULL,PERIOD_H1,1)-iLow(NULL,PERIOD_D1,0))*10000);


   in[20]=((iHigh(NULL,PERIOD_D1,0)-iOpen(NULL,PERIOD_H1,0))*10000);
   in[21]=((iOpen(NULL,PERIOD_H1,0)-iLow(NULL,PERIOD_D1,0))*10000);


   FileWrite(handleInput,

             in[0],in[1],in[2],in[3],in[4],in[5],in[6],in[7],in[8],in[9],in[10],in[11],in[12],in[13],in[14],in[15],
             in[16],in[17],in[18],in[19],in[20],in[21]);

   FileWrite(HandleDate,TimeCurrent());

  }
//+------------------------------------------------------------------+

オープンプライスモードを使用して、H1チャート上のストラテジーテスターでエキスパートアドバイザを実行します。 テストのデータ期間:2011年初頭から現在までです。 このエキスパートアドバイザは、MetaTrader5から受け取った価格を元にPythonスクリプトが形成するデータを実際の運用でシミュレーションします。 


このEAは、EURUSDTestとEURUSDDateの2つのファイルを\Commonフォルダに作成します。

PythonスクリプトEURUSDPyTren.pyを実行します。 (うまくいかない場合は、先に説明した追加パッケージを再インストールし、コンピュータを再起動する必要があるかもしれません)。 すべてが正しい場合、スクリプトはダブルクリックで実行されます。

スクリプト操作

その結果、「\Common\Files」フォルダ内に以下のファイルが作成されます。 

  • net1Max.h5, net1Min.h5, net2Max.h5, net2Min.h5 - リアルタイムでトレードする際に基本スクリプトで使用するトレーニングされたネットワークです。
  • IndicatorMaxとIndicatorMinは、別々のテストの2つのネットワーク応答です。
  • インジケータは複合的な対応です。

Folder \Common\Files


ターミナルの1_MetaTrader5インジケータを起動します。

//+------------------------------------------------------------------+
//|                                                        1_MetaTrader5.mq5 |
//|                                 Copyright © 2019, Andrey Dibrov. |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2019, Andrey Dibrov."
//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
#property indicator_type1   DRAW_LINE
#property indicator_type2   DRAW_LINE
#property indicator_color1  Red
#property indicator_color2  DodgerBlue

int Handle;
int i;

double    ExtBuffer[];
double    SignBuffer[];

datetime Date1;
datetime Date0;

string File_Name="Indicator.csv";

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
   SetIndexBuffer(0,ExtBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignBuffer,INDICATOR_DATA);

   IndicatorSetInteger(INDICATOR_DIGITS,5);

  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {

   Handle=FileOpen(File_Name,FILE_CSV|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";");

   Date0=StringToTime(FileReadString(Handle));

   FileClose(Handle);

   i=iBarShift(NULL,PERIOD_H1,Date0,false);
   
   Handle=FileOpen(File_Name,FILE_CSV|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";");
  
   ArraySetAsSeries(ExtBuffer,true);
   ArraySetAsSeries(SignBuffer,true);

   while(!FileIsEnding(Handle) && !IsStopped())
     {
      Date1=StringToTime(FileReadString(Handle));
      ExtBuffer[i]=StringToDouble(FileReadString(Handle));
      SignBuffer[i]=StringToDouble(FileReadString(Handle));
      i--;
     }
  
   FileClose(Handle);

   return(rates_total);
  }
//+------------------------------------------------------------------+

インジケータ

ニューラルネットワークのトレーニングにはあまり力を入れていませんが、依存関係が見えています。

3. 得られた結果の最適化。

PythonOptimizExpertEAを使って、出来上がったインジケータを最適化してみましょう。 

//+------------------------------------------------------------------+
//|                                          PythonOptimizExpert.mq5 |
//|                                   Copyright 2020, Andrey Dibrov. |
//|                           https://www.mql5.com/ru/users/tomcat66 |
//+------------------------------------------------------------------+
#property copyright " Copyright © 2019, Andrey Dibrov."
#property link      "https://www.mql5.com/ru/users/tomcat66"
#property version   "1.00"
#property strict

#include<Trade\Trade.mqh>

CTrade  trade;

input int H1;
input int H2;
input int H3;
input int H4;

input double Buy;
input double Buy1;
input double Sell;
input double Sell1;

input int LossBuy;
input int ProfitBuy;
input int LossSell;
input int ProfitSell;

ulong TicketBuy1;
ulong TicketSell0;

datetime Count;

double Buf_0[];
double Buf_1[];

bool send1;
bool send0;

int k;
int K;
int bars;
int Handle;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

   Handle=FileOpen("Indicator.csv",FILE_CSV|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";");

   while(!FileIsEnding(Handle)&& !IsStopped())
     {
      StringToTime(FileReadString(Handle));
      bars++;
     }
   FileClose(Handle);

   ArrayResize(Buf_0,bars);
   ArrayResize(Buf_1,bars);

   Handle=FileOpen("Indicator.csv",FILE_CSV|FILE_SHARE_READ|FILE_ANSI|FILE_COMMON,";");

   while(!FileIsEnding(Handle)&& !IsStopped())
     {
      Count=StringToTime(FileReadString(Handle));
      Buf_0[k]=StringToDouble(FileReadString(Handle));
      Buf_1[k]=StringToDouble(FileReadString(Handle));
      k++;
     }
   FileClose(Handle);

   int deviation=10;
   trade.SetDeviationInPoints(deviation);
   trade.SetTypeFilling(ORDER_FILLING_RETURN);
   trade.SetAsyncMode(true);
//---
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   MqlDateTime stm;
   TimeToStruct(TimeCurrent(),stm);

   int    digits=(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);
   double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT);
   double PriceAsk=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
   double PriceBid=SymbolInfoDouble(_Symbol,SYMBOL_BID);

   doubleSL1=NormalizeDouble(PriceBid-LossBuy*point,digits);
   doubleTP1=NormalizeDouble(PriceAsk+ProfitBuy*point,digits);
   doubleSL0=NormalizeDouble(PriceAsk+LossSell*point,digits);
   doubleTP0=NormalizeDouble(PriceBid-ProfitSell*point,digits);

   if(LossBuy==0)
      SL1=0;

   if(ProfitBuy==0)
      TP1=0;

   if(LossSell==0)
      SL0=0;

   if(ProfitSell==0)
      TP0=0;

//---------Buy1
   if(send1==false && K>0 &&  Buf_0[K]<Buy && Buy<Buy1 && iLow(NULL,PERIOD_H1,1)<iLow(NULL,PERIOD_H1,2) && stm.hour>H1 && stm.hour<H2 && H1<H2)
     {
      send1=trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,1,PriceAsk,SL1,TP1);//SL1,TP1
      TicketBuy1 = trade.ResultDeal();
     }

   if(send1==true && K>0 &&  Buf_0[K]>Buy1 &&  Buy<Buy1 && iHigh(NULL,PERIOD_H1,1)>iHigh(NULL,PERIOD_H1,2) )
     {
      trade.PositionClose(TicketBuy1);
      send1=false;
     }

//---------Sell0

   if(send0==false && K>0 &&  Buf_1[K]<Sell && Sell<Sell1 && iHigh(NULL,PERIOD_H1,1)>iHigh(NULL,PERIOD_H1,2) && stm.hour>H3 && stm.hour<H4 && H3<H4)
     {
      send0=trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,1,PriceBid,SL0,TP0);//SL0,TP0
      TicketSell0 = trade.ResultDeal();
     }

   if(send0==true && K>0 &&  Buf_1[K]>Sell1 && Sell<Sell1 && iLow(NULL,PERIOD_H1,1)<iLow(NULL,PERIOD_H1,2) )
     {
      trade.PositionClose(TicketSell0);
      send0=false;
     }
   K++;
  }

//+------------------------------------------------------------------+
//| Tester function                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
   double ret=0.0;
//---

//---
   return(ret);
  }
//+------------------------------------------------------------------+

以下の変数を最適化することができます。

  • Н1, Н2 - 買いが実行される時間帯。
  • Н3 ,H4 - 売りが行われる時間帯。
  • Buy, Buy1 —Buf_0[]インジケータの赤線レベルを示します。
  • Sell, Sell1 - は、Buf_1[] インジケータの青い線のレベルを示します。
  • LossBuy、ProfitBuy、LossSell、ProfitSell - リミットレベル。

図のように最適化パラメータを設定してみましょう。 インジケータレベルの最適化のみを行うということです。

最適化されたインジケータレベル

最適化パラメータ

最適化の結果



テスト結果。 最適化期間はテストチャートの赤線までです。 続いて、最適化されたパラメータを使用してテストを行います。


得られたパラメータを使って、さらにタイムオーダーとストップオーダーで最適化してみましょう。

では、得られたパラメータをすべてテストしてみましょう。


オプションで、それぞれのトレード方向を個別に最適化してみることもできます。

結論

以下の動画は、Pythonスクリプトの準備を理解するのに役立つでしょう。



MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/8502

添付されたファイル |
EURUSDPyTren.py (3.47 KB)
DibMax1-1.mq5 (5.11 KB)
DibMin1-1.mq5 (5.08 KB)
PythonPrices.mq5 (11.46 KB)
パターン検索への総当たり攻撃アプローチ(第II部): イマージョン パターン検索への総当たり攻撃アプローチ(第II部): イマージョン
本稿では、引き続き総当たり攻撃アプローチについて説明します。改良されたアプリケーションの新バージョンを使用して、パターンをより良く説明を試みます。また、さまざまな時間間隔と時間枠を使用して、安定性の違いの特定も試みます。
スプレッドシートを使ってトレード戦略を構築する スプレッドシートを使ってトレード戦略を構築する
この記事では、スプレッドシート(Excel、Calc、Google)を使ってあらゆる戦略を分析できるようにするための基本的な考え方や方法を解説します。 得られた結果をMetaTrader5のテスターと比較します。
DoEasyライブラリの時系列(第58部): 指標バッファデータの時系列 DoEasyライブラリの時系列(第58部): 指標バッファデータの時系列
時系列の操作に関するトピックのしめくくりとして、指標バッファに格納されているストレージ、検索、およびデータの並べ替えを整理します。これにより、プログラムでライブラリベースで作成される指標の値に基づいて分析をさらに実行できます。ライブラリのすべてのコレクションクラスの一般的な概念により、対応するコレクションで必要なデータを簡単に見つけることができます。それぞれ、今日作成されたクラスでも同じことが可能です。
手動チャートおよび取引ツールキット(第II部)チャートグラフィック描画ツール 手動チャートおよび取引ツールキット(第II部)チャートグラフィック描画ツール
これは連載の次の記事で、キーボードショートカットを使用してチャートグラフィックを手動で適用するための便利なライブラリを作成した方法を示します。使用されるツールには、直線とその組み合わせが含まれます。第2部では、第1部で説明した関数を使用して、描画ツールがどのように適用されるかを確認します。ライブラリは、チャート作成タスクを大幅に簡素化する任意のエキスパートアドバイザーまたはインディケーターに接続できます。このソリューションは外部DLLを使用せず、すべてのコマンドは組み込みのMQLツールを使用して実装されます。