English Русский 中文 Español Deutsch Português
一般的トレーディングシステムを基にした Expert Advisors と売買ロボット最適化の錬金術(パート5)

一般的トレーディングシステムを基にした Expert Advisors と売買ロボット最適化の錬金術(パート5)

MetaTrader 4トレーディングシステム | 21 4月 2016, 12:35
550 0
Nikolay Kositsin
Nikolay Kositsin

はじめに

このサイクルの先行記事(1234)では、もっともシンプルなトレーディングシステム、1フレームでのみ動作する特徴のもの、について説明しました。結果、そのようなトレーディングシステムは、よりグローバルなタイムスケールでは市場トレンドの変化にまったく反応がないのです。これは変化する市場状況での損失につながります。その種類のシステムではそのような変化は検出されないのです。実際、1つのタイムフレームだけのチャートから取得されるデータにもとづく本番のトレーディングシステムはほとんど使用に耐えません。通常、一般の処理に対しては最低2つのタイムフレームが使用されるものです。現行トレンドは通常高いタイムフレームのチャートで特定され、同時にこのトレンド方向での市場参入ポイントは小さいタイムフレームのチャートで計算されます。私見ですが、そのようなシステムの設計を学びたい読者の方にとっては、先行記事で述べている一番シンプルなトレーディング戦略で十分です。ここでは、上記理由により、そのようなトレーディングシステムを完了する方法をお話します。



タイムフレームを2つ採用したトレーディングシステム

理論の観点では、相違はありません。先行記事で説明されているトレーディングシステムを基に、より複雑なシステムを構築していきます。始めのエッセンスとしては、一番シンプルなトレーディングシステムはどれも以下の形式で提供されます。

ロングポジション向け:

ショートポジション向け:

タイムフレームを2つ使うわれわれのシステムでは、市場参入の条件は小さいタイムフレームで計算されるインディケータを基に定義されます。トレンド方向は高いタイムフレームで特定されます。よって、その条件を持つアルゴリズムは以下のようなものとなります。

ロングポジション向け:

ショートポジション向け:

この場合、Trend 変数は高いタイムフレームでの現トレンドの方向のみ定義し、市場参入の他の条件はこのグローバルトレンドの方向についてのみExpert Advisor のトレードアクションを制限します。プログラムコードの観点では、高いタイムフレームで現行トレンドが検出されるどのようなアルゴリズムを使用しても相違はまったくありません。ちいさいタイムフレームで市場参入ポイントを計算するのと、高いタイムフレームで現行トレンドを検出するのにどのアルゴリズムを使用するかは EA プログラマー次第です。以前に説明されている、A Exp_5.mq4 によって紹介された OsMA オシレータを持つアルゴリズムを分析します。現行トレンドを決めるには移動 J2JMA.mq4 を使用します。その場合、トレード定義条件はひじょうにシンプルです。

次に既存の Exp_5.mq4 にコードをいくつか追加し、上記ロジックにそれをインクルードします。以下ができたコードです。

//For the EA operation Metatrader\EXPERTS\indicators folder must
//contain indicators 5c_OsMA.mq4 and J2JMA.mq4
//+==================================================================+
//|                                                       Exp_11.mq4 |
//|                             Copyright © 2008,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2008, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +--------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR BUY TRADES 
extern bool   Test_Up = true;//filter of trade calculations direction
extern double Money_Management_Up = 0.1;
//---- input parameters of the custom indicator J2JMA.mq4
extern int    TimeframeX_Up = 240;
extern int    Length1X_Up = 4;  // depth of the first smoothing
extern int    Phase1X_Up = 100; // parameter of the first smoothing
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    Length2X_Up = 4;  // depth of the second smoothing 
extern int    Phase2X_Up = 100; // parameter of the second smoothing, 
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    IPCX_Up = 0;/* Selecting prices on which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
//---- input parameters of the custom indicator 5c_OsMA.mq4
extern int    Timeframe_Up = 60;
extern double IndLevel_Up = 0; // breakout level of the indicator
extern int    FastEMA_Up = 12;  // quick EMA period
extern int    SlowEMA_Up = 26;  // slow EMA period
extern int    SignalSMA_Up = 9;  // signal SMA period
extern int    STOPLOSS_Up = 50;  // stop loss
extern int    TAKEPROFIT_Up = 100; // take profit
extern int    TRAILINGSTOP_Up = 0; // trailing stop
extern int    PriceLevel_Up =40; // difference between the current price and
                                         // the price of a pending order triggering
extern bool   ClosePos_Up = true; // forced position closing allowed
//----+ +--------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR SELL TRADES
extern bool   Test_Dn = true;//filter of trade calculations direction
extern double Money_Management_Dn = 0.1;
//---- input parameters of the custom indicator J2JMA.mq4
extern int    TimeframeX_Dn = 240;
extern int    Length1X_Dn = 4;  // smoothing depth 
extern int    Phase1X_Dn = 100;  // parameter of the first smoothing 
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    Length2X_Dn = 4;  // smoothing depth 
extern int    Phase2X_Dn = 100; // parameter of the second smoothing 
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    IPCX_Dn = 0;/* Selecting prices on which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
//---- input parameters of the custom indicator 5c_OsMA.mq4
extern int    Timeframe_Dn = 60;
extern double IndLevel_Dn = 0; // breakout level of the indicator
extern int    FastEMA_Dn = 12;  // quick EMA period
extern int    SlowEMA_Dn = 26;  // slow EMA period
extern int    SignalSMA_Dn = 9;  // signal SMA period
extern int    STOPLOSS_Dn = 50;  // stop loss
extern int    TAKEPROFIT_Dn = 100; // take profit
extern int    TRAILINGSTOP_Dn = 0; // trailing stop
extern int    PriceLevel_Dn = 40; // difference between the current price and 
                                         // the price of a pending order triggering
extern bool   ClosePos_Dn = true; // forced position closing allowed
//----+ +--------------------------------------------------------------------------+
//---- Integer variables for the minimum of calculation bars
int MinBarX_Up, MinBar_Up, MinBarX_Dn, MinBar_Dn;
//+==================================================================+
//| TimeframeCheck() functions                                       |
//+==================================================================+
void TimeframeCheck(string Name, int Timeframe)
  {
//----+
   //---- Checking the correctness of Timeframe variable value
   if (Timeframe != 1)
    if (Timeframe != 5)
     if (Timeframe != 15)
      if (Timeframe != 30)
       if (Timeframe != 60)
        if (Timeframe != 240)
         if (Timeframe != 1440)
           Print(StringConcatenate("TimeframeCheck: Parameter ",Name,
                     " cannot ", "be equal to ", Timeframe, "!!!"));    
//----+ 
  }
//+==================================================================+
//| Custom Expert functions                                          |
//+==================================================================+
#include <Lite_EXPERT1.mqh>
//+==================================================================+
//| Custom Expert initialization function                            |
//+==================================================================+
int init()
  {
//---- Checking the correctness of Timeframe_Up variable value
   TimeframeCheck("Timeframe_Up", Timeframe_Up); 
   //---- Checking the correctness of TimeframeX_Up variable value
   TimeframeCheck("TimeframeX_Up", TimeframeX_Up);                                                                        
//---- Checking the correctness of Timeframe_Dn variable value 
   TimeframeCheck("Timeframe_Dn", Timeframe_Dn);
   //---- Checking the correctness of Timeframe_Dn variable value 
   TimeframeCheck("TimeframeX_Dn", TimeframeX_Dn);    
//---- Initialization of variables
   MinBar_Up  = 3 + MathMax(FastEMA_Up, SlowEMA_Up) + SignalSMA_Up;
   MinBarX_Up  = 3 + 30 + 30;
   MinBar_Dn  = 3 + MathMax(FastEMA_Dn, SlowEMA_Dn) + SignalSMA_Dn;
   MinBarX_Dn  = 3 + 30 + 30;                              
//---- end of initialization
   return(0);
  }
//+==================================================================+
//| expert deinitialization function                                 |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- End of the EA deinitialization
    return(0);
//----+ 
  }
//+==================================================================+
//| Custom Expert iteration function                                 |
//+==================================================================+
int start()
  {
   //----+ Declaring local variables
   double J2JMA1, J2JMA2, Osc1, Osc2;
   //----+ Declaring static variables
   //----+ +---------------------------------------------------------------+
   static double TrendX_Up, TrendX_Dn;
   static datetime StopTime_Up, StopTime_Dn; 
   static int LastBars_Up, LastBarsX_Up, LastBarsX_Dn, LastBars_Dn;
   static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop;
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR LONG POSITIONS                                        |
   //----+ +---------------------------------------------------------------+
   if (Test_Up) 
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      int IBARSX_Up = iBars(NULL, TimeframeX_Up);
      
      if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up)
       {
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Up != IBARSX_Up)
          {
           //----+ Initialization of variables 
           LastBarsX_Up = IBARSX_Up;
           BUY_Stop = false;
           
           //----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Length2X_Up,
                                             Phase1X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Length2X_Up,
                                             Phase1X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 2);
           
           //----+ defining trend
           TrendX_Up = J2JMA1 - J2JMA2;
           //----+ defining a signal for closing trades
           if (TrendX_Up < 0)
                      BUY_Stop = true;                                      
          }
          
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Up != IBARS_Up)
          {
           //----+ Initialization of variables 
           BUY_Sign = false;
           LastBars_Up = IBARS_Up;
           StopTime_Up = iTime(NULL, Timeframe_Up, 0)
                                          + 60 * Timeframe_Up;
           //----+ calculating indicator values
           Osc1 = iCustom(NULL, Timeframe_Up, 
                         "5c_OsMA", FastEMA_Up, SlowEMA_Up,
                                               SignalSMA_Up, 5, 1);
           //---                   
           Osc2 = iCustom(NULL, Timeframe_Up, 
                         "5c_OsMA", FastEMA_Up, SlowEMA_Up,
                                               SignalSMA_Up, 5, 2);
           
           //----+ defining signals for trades
           if (TrendX_Up > 0)                                           
            if (Osc2 < IndLevel_Up)
             if (Osc1 > IndLevel_Up)
                        BUY_Sign = true;                               
          }
          
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
         if (!OpenBuyLimitOrder1(BUY_Sign, 1, 
              Money_Management_Up, STOPLOSS_Up, TAKEPROFIT_Up,
                                            PriceLevel_Up, StopTime_Up))
                                                                 return(-1);
         if (ClosePos_Up)
                if (!CloseOrder1(BUY_Stop, 1))
                                        return(-1);
                                        
         if (!Make_TreilingStop(1, TRAILINGSTOP_Up))
                                              return(-1);
        }
     }
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR SHORT POSITIONS                                       |
   //----+ +---------------------------------------------------------------+
   if (Test_Dn) 
    {
      int IBARS_Dn = iBars(NULL, Timeframe_Dn);
      int IBARSX_Dn = iBars(NULL, TimeframeX_Dn);
      
      if (IBARS_Dn >= MinBar_Dn && IBARSX_Dn >= MinBarX_Dn)
       {
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Dn != IBARSX_Dn)
          {
           //--- Initialization of variables 
           LastBarsX_Dn = IBARSX_Dn;
           SELL_Stop = false;
           
           //----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Dn, 
                                "J2JMA", Length1X_Dn, Length2X_Dn,
                                             Phase1X_Dn, Phase2X_Dn,  
                                                     0, IPCX_Dn, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Dn, 
                                "J2JMA", Length1X_Dn, Length2X_Dn,
                                             Phase1X_Dn, Phase2X_Dn,  
                                                     0, IPCX_Dn, 0, 2);
           
           //----+ defining trend                                 
           TrendX_Dn = J2JMA1 - J2JMA2;
           //----+ defining a signal for closing trades
           if (TrendX_Dn > 0)
                      SELL_Stop = true;                                      
          }
         
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Dn != IBARS_Dn)
          {
           //----+ Initialization of variables 
           SELL_Sign = false;
           LastBars_Dn = IBARS_Dn;
           StopTime_Dn = iTime(NULL, Timeframe_Dn, 0)
                                          + 60 * Timeframe_Dn;
           //----+ calculating indicator values    
           Osc1 = iCustom(NULL, Timeframe_Dn, 
                         "5c_OsMA", FastEMA_Dn, SlowEMA_Dn,
                                               SignalSMA_Dn, 5, 1);
           //---                   
           Osc2 = iCustom(NULL, Timeframe_Dn, 
                         "5c_OsMA", FastEMA_Dn, SlowEMA_Dn,
                                               SignalSMA_Dn, 5, 2);
           
           //----+ defining signals for trades
           if (TrendX_Dn < 0)                                           
            if (Osc2 > IndLevel_Dn)
             if (Osc1 < IndLevel_Dn)
                        SELL_Sign = true;                               
          }
          
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
          if (!OpenSellLimitOrder1(SELL_Sign, 2, 
              Money_Management_Dn, STOPLOSS_Dn, TAKEPROFIT_Dn,
                                            PriceLevel_Dn, StopTime_Dn))
                                                                 return(-1);
          if (ClosePos_Dn)
                if (!CloseOrder1(SELL_Stop, 2))
                                        return(-1);
                                        
          if (!Make_TreilingStop(2, TRAILINGSTOP_Dn))
                                                  return(-1);
        }
     }
   //----+ +---------------------------------------------------------------+
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+

考えはそれほどボリュームのあるものではありませんが、視覚的にこのコードは最初の Exp_5mq4 の2倍になっています。結果についてお話します。再びロングポジションに対する EA 部分のみ分析します。ショートポジションに対する部分はその類似です。J2JMA インディケータの必要な値を取得するための追加のソースコードは以下のようになります。

//----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Up, "J2JMA", Length1X_Up, Phase1X_Up, Length2X_Up, Phase2X_Up, 0, IPCX_Up, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Up, "J2JMA", Length1X_Up, Phase1X_Up, Length2X_Up, Phase2X_Up, 0, IPCX_Up, 0, 2);
//----+ defining trend
           Trend_Up = J2JMA1 - J2JMA2;

ここで、EA の冒頭部分には、J2JMA インディケータ呼び出しに対応する新しい6個の外部変数の宣言が入っています。


extern int    TimeframeX_Up = 240;
extern int    Length1X_Up = 4;  // depth of the first smoothing
extern int    Phase1X_Up = 100; // parameter of the first smoothing
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    Length2X_Up = 4;  // depth of the second smoothing 
extern int    Phase2X_Up = 100; // parameter of the second smoothing, 
       //changing in the range -100 ... +100, influences the quality 
       //of the transient process of averaging;  
extern int    IPCX_Up = 0;/* Selecting prices on which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */

類似の変数 MinBarX_Up が計算バーの最小値に対するグローバル変数の宣言表に追加されています。それは EA の外部変数に続きます。

//---- Integer variables for the minimum of calculation bars
int MinBarX_Up, MinBar_Up, MinBarX_Dn, MinBar_Dn;

EA の初期化ブロックでは、新規の外部変数 TimeframeХ_Up の正確性を追加確認が行われます。

//---- Checking the correctness of TimeframeX_Up variable value
   TimeframeCheck("TimeframeХ_Up", TimeframeX_Up);

同じブロックで、変数 MinBarX_Up の初期化を行います。

MinBarX_Up  = 3 + 30 + 30;

それ以上の変更は EA の start() 関数ブロックで行われます。ローカル変数宣言行では新しい変数:J2JMA1 および J2JMA2、が2つ追加されます。

//----+ Declaring local variables
   double J2JMA1, J2JMA2, Osc1, Osc2;

Trend_Up 変数は静的変数として宣言されます。それはバー変更のとき一度初期化されるだけだからです。その値は start() 関数ののちのティックで使用されます。

static double TrendX_Up, TrendX_Dn;

同様に、変数 LastBarsX_Up は静的変数として宣言されます。

static int LastBars_Up, LastBarsX_Up, LastBarsX_Dn, LastBars_Dn;

ロングポジションについてのコードでは、計算の充足確認がより複雑になります。

if (Test_Up) 
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      int IBARSX_Up = iBars(NULL, TimeframeX_Up);
      
      if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up)
       {
         // CODE FOR LONG POSITIONS
       }
     }

そして、新しいブロックが追加されます。

         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Up != IBARSX_Up)
          {
           //----+ Initialization of variables 
           LastBarsX_Up = IBARSX_Up;
           BUY_Stop = false;
           
           //----+ calculating indicator values for J2JMA   
           J2JMA1 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Phase1X_Up,
                                            Length2X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 1);
           //---                     
           J2JMA2 = iCustom(NULL, TimeframeX_Up, 
                                "J2JMA", Length1X_Up, Phase1X_Up,
                                            Length2X_Up, Phase2X_Up,  
                                                     0, IPCX_Up, 0, 2);
           
           //----+ defining trend                                 
           TrendX_Up = J2JMA1 - J2JMA2;
           //----+ defining a signal for closing trades
           if (Trend_Up < 0)
                      BUY_Stop = true;                                      
          }

このブロックでは、変数Trend_Up の初期化が必要で、またここでは、オープンしているポジションを強制的にクローズするシグナルが定義されます( BUY_Stop 変数の初期化)。一般的に、はじめの Exp_5.mq4 では、最終変数はブロック『DEFINING SIGNALS FOR MARKET ENTERING』で初期化されますが、新規の EA では、この初期化をブロック『DEFINING TREND』に入れ、それの初期化アルゴリズムを変更する方が合理的です。

そしてもっとも重要なことは、ブロック『DEFINING SIGNALS FOR MARKET ENTERING』でアルゴリズムを定義してシグナルに小さな変更を加えることです。

           //----+ defining signals for trades
           if (TrendX_Up > 0)                                           
            if (Osc2 < IndLevel_Up)
             if (Osc1 > IndLevel_Up)
                        BUY_Sign = true;

変更がすべて終わったら、このアルゴリズムは変数 Trend_Up の助けを借りて現稿トレンドの方向を考慮します。

次に EA 最適化の詳細についていくらかお話します。当然、EA はロングポジションかショートポジションのどちらか向けに個別うに最適化され、この場合にも最適化用の外部変数がひじょうに多数存在します。おそらく、こういった変数をすべて同時に最適化することは妥当ではないでしょう。そのため、最適化の遺伝的アルゴリズムはは8個以上の変数を最適化しません。これに対するもっとも適切なソリューションは変数の一部の値を固定し、固定されていないのこりの部分-もっとも緊急性の高い変数、のみ最適化することです。そして最適化後、最適のバリアントを選び、残りのパラメータ最適化を試みるのです。

たとえば、ロングポジションに対してはこれは以下のようになります。

テスター Exp_11.ini に対する設定を持つファイルは TESTER.zip アーカイブ内にあります。ここで、TimeframeX_Up 同様、 Money_Management_Upも最適化する必要はありません。TimeframeX_Up 変数については、最初その値は変数 Timeframe_Up の値よりも大きいことに注意が必要です。Length1X_Up の値はひじょうに広い範囲で変化し、Phase1X_Up の値は -100~100 の範囲で変化します。パラメータ Length2X_Up、Phase2X_Up、IPCX_Up は最初の最適化で固定する方がよいです。Exp_5.mq4 について説明している先行記事にある IndLevel_Up パラメータについても同様です。パラメータ FastEMA_Up および SlowEMA_Up については、パラメータ変化の低い値が小さくなりすぎないようにします。もちろん、それらはすばらしい結果を示しますが、そのような結果に意味があるのでしょうか?トレーリングストップを使用する妥当性も最適化後確認します。論理変数ClosePos_Up による強制的なポジションのクローズは、常にトレンド変化後に定期用します。その値は「真」に固定するのが得策です。

最適化中、ストラテジーテスタのチャート期間は変数 Timeframe_Up または Timeframe_Dn(最適化中のトレンド方向によります) の値に等しくし、最終テストまたはアカウント処理で、チャート期間はそれら変数の最長値に設定します。もう一つ重要な点があります。この Expert Advisor は最低2つのタイムフレームを使用しているため、最適化、検証、アカウント処理のために履歴データをダウンロードするには配慮が必要です。異なるディーラーで複数のアカウントを開いている際には特に注意が必要です。

4番目の記事で、さらに統計分析をするために Microsoft Excel で最適化結果をエクスポートすることについて述べました。私は、本稿で提供している EA はその手続きに最適であると思います。これを試したい方のために、私は本稿推奨のとおりにアカウントを持つ EA コードを変更しました(Exp_11_2.mq4)。そのコードは本稿に添付しています。

異なるタイムフレームの2つのチャートデータを計算する EA のもう一つの例

この考えに基づくEA の例が一つだけでは本稿にとって十分ではないと思い、この原理に従って構築される Expert Advisor をもう一つ入れておきます。基本的に、私は初稿から最初の EA Exp_1.mq4 を使用します。市場参入条件を定義し、ポジションを管理するコード部分はできています。ここでは、大きいタイムフレームに対するアクティブな市場トレンドを定義する必要があります。この Expert Advisor では、インディケータ MAMA_NK.mq4 を使用します。

この場合、トレンド方向を決める条件は最初のバーの2つの移動値とは異なります。


類似のコードを書きます。Exp_11.mq4 のコードがテンプレートとして使用されています。

//+==================================================================+
//|                                                       Exp_12.mq4 |
//|                             Copyright © 2008,   Nikolay Kositsin | 
//|                              Khabarovsk,   farria@mail.redcom.ru | 
//+==================================================================+
#property copyright "Copyright © 2008, Nikolay Kositsin"
#property link "farria@mail.redcom.ru"
//----+ +---------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR BUY TRADES 
extern bool   Test_Up = true;//filter of trade calculations direction
extern double Money_Management_Up = 0.1;
//----
extern int    TimeframeX_Up = 240;
extern double FastLimitX_Up = 0.5;
extern double SlowLimitX_Up = 0.05;
extern int    IPCX_Up = 9;/* Selecting prices, upon which the indicator will be calculated
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close, 15-Heiken Ashi Open0.) */
//---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
extern int    Timeframe_Up = 60;
extern int    Length_Up = 4;  // smoothing depth
extern int    Phase_Up = 100; // parameter changing in the range
          //-100 ... +100, influences the quality of a transient process;
extern int    IPC_Up = 0;/* Selecting prices, upon which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int    STOPLOSS_Up = 50;  // stop loss
extern int    TAKEPROFIT_Up = 100; // take profit
extern bool   ClosePos_Up = true; // forced position closing is allowed
//----+ +---------------------------------------------------------------------------+
//---- EA INPUT PARAMETERS FOR SELL TRADES 
extern bool   Test_Dn = true;//filter of trade calculations direction
extern double Money_Management_Dn = 0.1;
//----
extern int    TimeframeX_Dn = 60;
extern double FastLimitX_Dn = 0.5;
extern double SlowLimitX_Dn = 0.05;
extern int    IPCX_Dn = 9;/* Selecting prices, upon which the indicator will be calculated 
(0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 6-WEIGHTED, 
7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close, 15-Heiken Ashi Open0.) */
//---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
extern int    Timeframe_Dn = 60;
extern int    Length_Dn = 4;  // smoothing depth 
extern int    Phase_Dn = 100; // parameter changing in the range
         // -100 ... +100, influences the quality of a transient process; 
extern int    IPC_Dn = 0;/* Selecting prices, upon which the indicator will 
be calculated (0-CLOSE, 1-OPEN, 2-HIGH, 3-LOW, 4-MEDIAN, 5-TYPICAL, 
6-WEIGHTED, 7-Heiken Ashi Close, 8-SIMPL, 9-TRENDFOLLOW, 10-0.5*TRENDFOLLOW, 
11-Heiken Ashi Low, 12-Heiken Ashi High, 13-Heiken Ashi Open, 
14-Heiken Ashi Close.) */
extern int   STOPLOSS_Dn = 50;  // stop loss
extern int   TAKEPROFIT_Dn = 100; // take profit
extern bool   ClosePos_Dn = true; // forced position closing is allowed
//----+ +---------------------------------------------------------------------------+
//---- Integer variables for the minimum of counted bars
int MinBar_Up, MinBar_Dn, MinBarX_Up, MinBarX_Dn;
//+==================================================================+
//| Custom Expert functions                                          |
//+==================================================================+
#include <Lite_EXPERT1.mqh>
//+==================================================================+
//| TimeframeCheck() functions                                       |
//+==================================================================+
void TimeframeCheck(string Name, int Timeframe)
  {
//----+
   //---- Checking the correctness of Timeframe variable value
   if (Timeframe != 1)
    if (Timeframe != 5)
     if (Timeframe != 15)
      if (Timeframe != 30)
       if (Timeframe != 60)
        if (Timeframe != 240)
         if (Timeframe != 1440)
           Print(StringConcatenate("Parameter ",Name,
                     " cannot ", "be equal to ", Timeframe, "!!!"));    
//----+ 
  }
//+==================================================================+
//| Custom Expert initialization function                            |
//+==================================================================+
int init()
  {
//---- Checking the correctness of Timeframe_Up variable value
   TimeframeCheck("TimeframeX_Up", TimeframeX_Up);
//---- Checking the correctness of Timeframe_Up variable value
   TimeframeCheck("Timeframe_Up", Timeframe_Up);
//---- Checking the correctness of Timeframe_Dn variable value 
   TimeframeCheck("TimeframeX_Dn", TimeframeX_Dn);
//---- Checking the correctness of Timeframe_Dn variable value 
   TimeframeCheck("Timeframe_Dn", Timeframe_Dn);
//---- Initialization of variables
   MinBarX_Up = 1 + 7;
   MinBar_Up = 4 + 39 + 30;
   MinBarX_Dn = 1 + 7;
   MinBar_Dn = 4 + 39 + 30;                                       
//---- end of initialization
   return(0);
  }
//+==================================================================+
//| expert deinitialization function                                 |
//+==================================================================+  
int deinit()
  {
//----+
   
    //---- End of the EA deinitialization
    return(0);
//----+ 
  }
//+==================================================================+
//| Custom Expert iteration function                                 |
//+==================================================================+
int start()
  {
   //----+ Declaration of local variables
   int    bar;
   double Mov[3], dMov12, dMov23, Mama1, Fama1;
   //----+ declaration of static variables
   static double TrendX_Up, TrendX_Dn;
   static int LastBars_Up, LastBars_Dn, LastBarsX_Up, LastBarsX_Dn;
   static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop;
   
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR LONG POSITIONS                                        |
   //----+ +---------------------------------------------------------------+
   if (Test_Up) 
    {
      int IBARS_Up = iBars(NULL, Timeframe_Up);
      int IBARSX_Up = iBars(NULL, TimeframeX_Up);
      
      if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up)
       {       
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Up != IBARSX_Up)
          {
           //----+ Initialization of variables 
           LastBarsX_Up = IBARSX_Up;
           BUY_Stop = false;
           
           //----+ calculating indicator values
           Fama1 = iCustom(NULL, TimeframeX_Up, 
                    "MAMA_NK", FastLimitX_Up, SlowLimitX_Up, IPCX_Up, 0, 1);
           //---         
           Mama1 = iCustom(NULL, TimeframeX_Up, 
                    "MAMA_NK", FastLimitX_Up, SlowLimitX_Up, IPCX_Up, 1, 1);
           //----+ defining trend
           TrendX_Up = Mama1 - Fama1;
           //----+ defining signals for trade closing
           if (TrendX_Up < 0)
                      BUY_Stop = true;                                      
          }
         
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Up != IBARS_Up)
          {
           //----+ Initialization of variables 
           BUY_Sign = false;
           LastBars_Up = IBARS_Up; 
           
           //----+ calculating indicator values and uploading them into buffer      
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Up, 
                                "JFatl", Length_Up, Phase_Up, 
                                                   0, IPC_Up, 0, bar);
           
           //----+ defining signals for trades
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
            
           if (TrendX_Up > 0)                     
              if (dMov23 < 0)
                if (dMov12 > 0)
                        BUY_Sign = true;                                    
          }
         
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
          if (!OpenBuyOrder1(BUY_Sign, 1, Money_Management_Up, 
                                          STOPLOSS_Up, TAKEPROFIT_Up))
                                                                 return(-1);
          if (ClosePos_Up)
                if (!CloseOrder1(BUY_Stop, 1))
                                        return(-1);
        }
     }
     
   //----+ +---------------------------------------------------------------+
   //----++ CODE FOR SHORT POSITIONS                                       |
   //----+ +---------------------------------------------------------------+
   if (Test_Dn) 
    {
      int IBARS_Dn = iBars(NULL, Timeframe_Dn);
      int IBARSX_Dn = iBars(NULL, TimeframeX_Dn);
      
      if (IBARS_Dn >= MinBar_Dn && IBARSX_Dn >= MinBarX_Dn)
       {
         //----+ +----------------------+
         //----+ DEFINING TREND         |
         //----+ +----------------------+
         if (LastBarsX_Dn != IBARSX_Dn)
          {
           //----+ Initialization of variables
           LastBarsX_Dn = IBARSX_Dn;
           SELL_Stop = false;
           
           //----+ calculating indicator values
           Fama1 = iCustom(NULL, TimeframeX_Dn, 
                    "MAMA_NK", FastLimitX_Dn, SlowLimitX_Dn, IPCX_Dn, 0, 1);
           //---         
           Mama1 = iCustom(NULL, TimeframeX_Dn, 
                    "MAMA_NK", FastLimitX_Dn, SlowLimitX_Dn, IPCX_Dn, 1, 1);
           //----+ defining trend
           TrendX_Dn = Mama1 - Fama1;
           //----+ defining signals for trade closing
           if (TrendX_Dn > 0)
                      SELL_Stop = true;                                      
          }
         
         //----+ +----------------------------------------+
         //----+ DEFINING SIGNAL FOR MARKET ENTERING      |
         //----+ +----------------------------------------+
         if (LastBars_Dn != IBARS_Dn)
          {
           //----+ Initialization of variables 
           SELL_Sign = false;
                      LastBars_Dn = IBARS_Dn; 
           
           //----+ calculating indicator values and uploading them into buffer     
           for(bar = 1; bar <= 3; bar++)
                     Mov[bar - 1]=                  
                         iCustom(NULL, Timeframe_Dn, 
                                "JFatl", Length_Dn, Phase_Dn, 
                                                   0, IPC_Dn, 0, bar);
           
           //----+ defining signals for trades   
           dMov12 = Mov[0] - Mov[1];
           dMov23 = Mov[1] - Mov[2]; 
            
           if (TrendX_Dn < 0)                                 
              if (dMov23 > 0)
                if (dMov12 < 0)
                       SELL_Sign = true;                                         
          }
          
         //----+ +-------------------+
         //----+ EXECUTION OF TRADES |
         //----+ +-------------------+
          if (!OpenSellOrder1(SELL_Sign, 2, Money_Management_Dn, 
                                            STOPLOSS_Dn, TAKEPROFIT_Dn))
                                                                   return(-1);
          if (ClosePos_Dn)
                if (!CloseOrder1(SELL_Stop, 2))
                                        return(-1);
        }
     }
//----+ 
    
    return(0);
  }
//+------------------------------------------------------------------+

この EA の基本的なアルゴリズムは前の EA のものとは異なりますが、グラフを2つ使用する概念はこの場合にも完璧に動作するようです。



おわりに


本稿で述べられている自動売買システムを構築する方法は、すでにいくらか EA のプログラミング経験のある読者が最小の労力で類似のExpert Advisorを作成するのに役立つと思います。またここで、そのような Expert Advisorの実用性は、適切な最適化に大きく左右されることを付け加えておきます。


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

添付されたファイル |
EXPERTS.zip (19.56 KB)
INCLUDE.zip (25.55 KB)
indicators.zip (14.02 KB)
TESTER.zip (6.72 KB)
誤信、パート1:資産管理は一番ではなく、あまり重要ではない 誤信、パート1:資産管理は一番ではなく、あまり重要ではない
0.1ロットに基づく戦略の結果のテストの最初のデモは、フォーラムでは事実上標準になっています。プロからは「そこまで悪くない」というコメントを得て、初心者は「0.1」のテストが堅実な結果をもたらすと考え、肯定的な数学的予想が自動的にポジティブな結果を提供すると考え、攻撃的な資産管理を導入しようとしますl。どのような結果が得られるのか見てみましょう。それとともに、とてもためになるいくつかの人工的なバランスグラフを実行してみます。
グラフィカル ライン リクエストのメタ言語トレーディングと適しているトレーディング学習 グラフィカル ライン リクエストのメタ言語トレーディングと適しているトレーディング学習
本稿では、従来のテクニカル分析と互換性のある簡単で解りやすいグラフィカル トレーディングリクエスト言語について説明します。添付の G ターミナルは取引結果のグラフィカル分析に使用される半自動 Expert Advisor です。初心者トレーダーの独学と訓練に適しています。
トレーリングストップのパターンとマーケットの退出 トレーリングストップのパターンとマーケットの退出
注文修正やクローッジングのアルゴリズムの開発者は、異なるメソッドから取得された結果をどのように比較するかという不滅の悩みに苦しみます。チェックのメカニズムは、よく知られています - それは、ストラテジーテスターです。しかし、注文のオープン/クローズにおいて等しくEAを動作させるにはどうすれば良いでしょうか?この記事は、トレーリングストップやマーケットの退出のための異なるアルゴリズムの結果を比較するためのプラットフォームを数学的に維持できる注文のオープンの繰り返しを提供するツールを紹介します。
一般的トレーディングシステムを基にした Expert Advisors と売買ロボット最適化の錬金術(パート4) 一般的トレーディングシステムを基にした Expert Advisors と売買ロボット最適化の錬金術(パート4)
本稿では、もっともシンプルなトレーディングシステムのアルゴリズム実装を分析し、バックテストの最適化結果を表形式で html ファイルに記録する方法を紹介します。本稿はトレーダーおよび EA プログラマ―の初心者に有用なものです。