一般的トレーディングシステムを基にした Expert Advisors と売買ロボット最適化の錬金術(パート5)
はじめに
このサイクルの先行記事(1、2、3、4)では、もっともシンプルなトレーディングシステム、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
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索