一般的トレーディングシステムを基にした Expert Advisors と売買ロボット最適化の錬金術(パート6)
はじめに
先行記事で、2つの異なるタイムフレームからもたらされる情報を処理する Expert Advisor の書き方について詳しく説明しました。ただ、問題はこの上方が正確に市場参入するには不十分であることが多いのです。たとえば、小さなタイムフレームが H1 で、1時間足のバーが変化するとすぐに市場エンターするのは、ベストなソリューションではないことが多いものです。というのも、H1より小さいタイムフレームのトレンドと、通常価格にノイズが存在することはポジションのオープンに反して作用するためです。多くの場合、この短期トレンドはかなり簡単に検出されます。そのような場合、ポジションオープンに反して移動する場合、小さいタイムフレームにおけるこのトレンドが逆方向に変わるまで市場エンターを延期します。または、最悪の場合、次の1時間足バーが変化する前に市場にエンターします。本稿で行おうとしていりのはこのタスクです。
エルダーのトリプル・スクリーン システム
アレクサンダー・エルダーはトレーディングや群衆行動の心理に関する人気のある本の著者として知られています。金融市場を分析するのに3つのタイムフレームのチャートを使用する考えを思いついたのはこの人です。この3つのチャートは「エルダーのトリプル・スクリーン」と呼ばれます。先行記事 でダブル・スクリーンの構築方法はすでに学習しました。ここでは、それに3番目のスクリーンを追加します。さらにコードを複雑にする例として、私の先行記事から出来上がった EA の一部を使用します。ただし、本稿では、変更のためだけに、同様の手順で別の EA(Exp_14.mq4)を構築することにしました。
コードを書く最初の基本として、アラートを出す移動平均 JFatl.nq4 をオシレータJCCIX.mq4 および、数個のストキャスティック オシレータで構成されるインディケータ StepMA_Stoch_NK.mq4 を持つ2つの MA で構成されるトレンドフォローインディケータ MAMA_NK.mq4 と置き換えた Exp_12.mq4 を取ります。最終的に、初期アルゴリズムは同じままで、カスタムインディケータに対する呼び出し、EA の外部変数、init() 関数のブロック内定数の初期を変えただけで、また、市場エンターのシグナルを検出するブロックのコードを複雑にしました。前稿でおこなったと同様に、ひじょうに一般的な形式でふたたび2つのタイムフレームを使用してこの EA のワーキングアルゴリズムを提供します。ただし、今回はもっと詳細まで行います。
ロングポジションに対したは以下を取得します。
ショートポジションに対しては以下です。
可能な限り合理的に3つの異なるタイムフレームのチャートを使用するために、プログラムコードの中に実装するべき結果的なアルゴリズムは以下のようなものです。
ロングポジション向け:
ショートポジション向け:
Exp_15.mq4 を基にしてこのアルゴリズムをプログラムコードに実装すると、以下のように表記できます。
//+==================================================================+ //| Exp_15.mq4 | //| Copyright © 2008, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+==================================================================+ #property copyright "Copyright © 2008, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //----+ +---------------------------------------------------------------------------+ //---- EXPERT ADVISORS INPUTS FOR BUY TRADES extern bool Test_Up = true;//filter of trade calculations direction extern double Money_Management_Up = 0.1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeX_Up = 1440; extern int PeriodWATR_Up = 10; extern double Kwatr_Up = 1.0000; extern int HighLow_Up = 0; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int Timeframe_Up = 240; extern int JJLength_Up = 8; // depth of JJMA smoothing for the entry price extern int JXLength_Up = 8; // depth of JurX smoothing for the obtained indicator extern int Phase_Up = 100;// the parameter ranging // from -100 to +100 influences the process quality; extern int IPC_Up = 0; /* Selecting price to calculate the indicator on (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 TimeframeN_Up = 15; extern int Noise_period_Up = 8; //extern int SmoothN_Up = 7; //extern int MaMethodN_Up = 1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int STOPLOSS_Up = 50; // StopLoss extern int TAKEPROFIT_Up = 100; // TakeProfit extern bool ClosePos_Up = true; // enable forcible closing the position //----+ +---------------------------------------------------------------------------+ //---- EXPERT ADVISORS INPUTS FOR SELL TRADES extern bool Test_Dn = true;//filter of trade calculations direction extern double Money_Management_Dn = 0.1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeX_Dn = 1440; extern int PeriodWATR_Dn = 10; extern double Kwatr_Dn = 1.0000; extern int HighLow_Dn = 0; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int Timeframe_Dn = 240; extern int JJLength_Dn = 8; // depth of JJMA smoothing for the entry price extern int JXLength_Dn = 8; // depth of JurX smoothing for the obtained indicator extern int Phase_Dn = 100;// the parameter ranging // from -100 to +100 influences the process quality; extern int IPC_Dn = 0; /* Selecting price to calculate the indicator on (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 TimeframeN_Dn = 15; extern int Noise_period_Dn = 8; //extern int SmoothN_Dn = 7; //extern int MaMethodN_Dn = 1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int STOPLOSS_Dn = 50; // StopLoss extern int TAKEPROFIT_Dn = 100; // TakeProfit extern bool ClosePos_Dn = true; // enable forcible closing the position //----+ +---------------------------------------------------------------------------+ //---- Integer variables for calling to custom indicators int SmoothN_Up = 7, SmoothN_Dn = 7, MaMethodN_Up = 1, MaMethodN_Dn = 1; //---- Integer variables for the minimum of reference bars int MinBar_Up, MinBar_Dn, MinBarX_Up, MinBarX_Dn, MinBarN_Up, MinBarN_Dn; //+==================================================================+ //| Custom Expert functions | //+==================================================================+ #include <Lite_EXPERT1.mqh> //+==================================================================+ //| TimeframeCheck() functions | //+==================================================================+ void TimeframeCheck(string Name, int Timeframe) { //----+ //---- Checking the value of variable Timeframe for correctness 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 values of timeframe variables for correctness TimeframeCheck("TimeframeX_Up", TimeframeX_Up); TimeframeCheck("Timeframe_Up", Timeframe_Up); TimeframeCheck("TimeframeN_Up", TimeframeN_Up); //---- Checking the values of timeframe variables for correctness TimeframeCheck("TimeframeX_Dn", TimeframeX_Dn); TimeframeCheck("Timeframe_Dn", Timeframe_Dn); TimeframeCheck("TimeframeN_Dn", TimeframeN_Dn); //---- Initialization of variables MinBarX_Up = 2 + PeriodWATR_Up; MinBar_Up = 4 + 3 * JXLength_Up + 30; MinBarN_Up = 4 + Noise_period_Up + SmoothN_Up; //---- Initialization of variables MinBarX_Dn = 2 + PeriodWATR_Dn; MinBar_Dn = 4 + 3 * JXLength_Dn + 30; MinBarN_Dn = 4 + Noise_period_Dn + SmoothN_Dn; //---- initialization complete return(0); } //+==================================================================+ //| expert deinitialization function | //+==================================================================+ int deinit() { //----+ //---- EA deinitialization complete return(0); //----+ } //+==================================================================+ //| Custom Expert iteration function | //+==================================================================+ int start() { //----+ Declaration of local variables int bar; double JCCIX[2], Trend, Fast_StepMA, Slow_StepMA, MA1, MA2; //----+ Declaration of static variables static datetime StopTime_Up, StopTime_Dn; static double TrendX_Up, TrendX_Dn, OldTrend_Up, OldTrend_Dn; //--- static int LastBars_Up, LastBars_Dn; static int LastBarsX_Up, LastBarsX_Dn, LastBarsN_Up, LastBarsN_Dn; //--- static bool BUY_Sign, BUY_Stop, SELL_Sign, SELL_Stop; static bool SecondStart_Up, SecondStart_Dn, NoiseBUY_Sign, NoiseSELL_Sign; //----+ +---------------------------------------------------------------+ //----++ CODE FOR LONG POSITIONS | //----+ +---------------------------------------------------------------+ if (Test_Up) { int IBARS_Up = iBars(NULL, Timeframe_Up); int IBARSX_Up = iBars(NULL, TimeframeX_Up); int IBARSN_Up = iBars(NULL, TimeframeN_Up); //--- if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up && IBARSN_Up >= MinBarN_Up) { //----+ +----------------------+ //----+ DETECTING A TREND | //----+ +----------------------+ if (LastBarsX_Up != IBARSX_Up) { //----+ Initialization of variables LastBarsX_Up = IBARSX_Up; BUY_Sign = false; BUY_Stop = false; //----+ calculating the values of indicators Fast_StepMA = iCustom(NULL, TimeframeX_Up, "StepMA_Stoch_NK", PeriodWATR_Up, Kwatr_Up, HighLow_Up, 0, 1); //--- Slow_StepMA = iCustom(NULL, TimeframeX_Up, "StepMA_Stoch_NK", PeriodWATR_Up, Kwatr_Up, HighLow_Up, 1, 1); //----+ detecting a trend TrendX_Up = Fast_StepMA - Slow_StepMA; //----+ defining a signal to close trades if (TrendX_Up < 0) BUY_Stop = true; } //----+ +----------------------------------------+ //----+ DETECTING SIGNALS TO ENTER THE MARKET | //----+ +----------------------------------------+ if (LastBars_Up != IBARS_Up && TrendX_Up > 0) { //----+ Initialization of variables BUY_Sign = false; LastBars_Up = IBARS_Up; //----+ Initialization of noise variables NoiseBUY_Sign = false; StopTime_Up = iTime(NULL, Timeframe_Up, 0) + 50 * Timeframe_Up; //----+ Initialization of zero if (!SecondStart_Up) { //--- Search for trend direction at the first start for(bar = 2; bar < IBARS_Up - 1; bar++) { JCCIX[0] = iCustom(NULL, Timeframe_Up, "JCCIX", JJLength_Up, JXLength_Up, Phase_Up, IPC_Up, 0, bar); //--- JCCIX[1] = iCustom(NULL, Timeframe_Up, "JCCIX", JJLength_Up, JXLength_Up, Phase_Up, IPC_Up, 0, bar + 1); //--- OldTrend_Up = JCCIX[0] - JCCIX[1]; //--- if (OldTrend_Up != 0) { SecondStart_Up = true; break; } } } //----+ calculating the values of indicators and loading them to a buffer for(bar = 1; bar < 3; bar++) JCCIX[bar - 1] = iCustom(NULL, Timeframe_Up, "JCCIX", JJLength_Up, JXLength_Up, Phase_Up, IPC_Up, 0, bar); //----+ detecting signals for trades Trend = JCCIX[0] - JCCIX[1]; if (TrendX_Up > 0) if (OldTrend_Up < 0) if (Trend > 0) BUY_Sign = true; if (Trend != 0) OldTrend_Up = Trend; } //----+ +------------------------------------------------+ //----+ DETECTING NOISE SIGNALS TO ENTER THE MARKET | //----+ +------------------------------------------------+ if (BUY_Sign) if (LastBarsN_Up != IBARSN_Up) { NoiseBUY_Sign = false; LastBarsN_Up = IBARSN_Up; //--- MA1 = iCustom(NULL, TimeframeN_Up, "2Moving Avereges", Noise_period_Up, SmoothN_Up, MaMethodN_Up, MaMethodN_Up, PRICE_LOW, 0, 0, 1); //--- MA2 = iCustom(NULL, TimeframeN_Up, "2Moving Avereges", Noise_period_Up, SmoothN_Up, MaMethodN_Up, MaMethodN_Up, PRICE_LOW, 0, 0, 2); //--- if (MA1 > MA2 || TimeCurrent() > StopTime_Up) NoiseBUY_Sign = true; } //----+ +-------------------+ //----+ MAKING TRADES | //----+ +-------------------+ if (NoiseBUY_Sign) 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); int IBARSN_Dn = iBars(NULL, TimeframeN_Dn); //--- if (IBARS_Dn >= MinBar_Dn && IBARSX_Dn >= MinBarX_Dn && IBARSN_Dn >= MinBarN_Dn) { //----+ +----------------------+ //----+ DETECTING A TREND | //----+ +----------------------+ if (LastBarsX_Dn != IBARSX_Dn) { //----+ Initialization of variables LastBarsX_Dn = IBARSX_Dn; SELL_Sign = false; SELL_Stop = false; //----+ calculating the values of indicators Fast_StepMA = iCustom(NULL, TimeframeX_Dn, "StepMA_Stoch_NK", PeriodWATR_Dn, Kwatr_Dn, HighLow_Dn, 0, 1); //--- Slow_StepMA = iCustom(NULL, TimeframeX_Dn, "StepMA_Stoch_NK", PeriodWATR_Dn, Kwatr_Dn, HighLow_Dn, 1, 1); //----+ detecting a trend TrendX_Dn = Fast_StepMA - Slow_StepMA; //----+ defining a signal to close trades if (TrendX_Dn > 0) SELL_Stop = true; } //----+ +----------------------------------------+ //----+ DETECTING SIGNALS TO ENTER THE MARKET | //----+ +----------------------------------------+ if (LastBars_Dn != IBARS_Dn && TrendX_Dn < 0) { //----+ Initialization of variables SELL_Sign = false; LastBars_Dn = IBARS_Dn; //----+ Initialization of noise variables NoiseSELL_Sign = false; StopTime_Dn = iTime(NULL, Timeframe_Dn, 0) + 50 * Timeframe_Dn; //----+ Initialization of zero if (!SecondStart_Dn) { //--- Search for trend direction at the first start for(bar = 2; bar < IBARS_Dn - 1; bar++) { JCCIX[0] = iCustom(NULL, Timeframe_Dn, "JCCIX", JJLength_Dn, JXLength_Dn, Phase_Dn, IPC_Dn, 0, bar); //--- JCCIX[1] = iCustom(NULL, Timeframe_Dn, "JCCIX", JJLength_Dn, JXLength_Dn, Phase_Dn, IPC_Dn, 0, bar + 1); //--- OldTrend_Dn = JCCIX[0] - JCCIX[1]; //--- if (OldTrend_Dn != 0) { SecondStart_Dn = true; break; } } } //----+ calculating the values of indicators and loading them to a buffer for(bar = 1; bar < 3; bar++) JCCIX[bar - 1]= iCustom(NULL, Timeframe_Dn, "JCCIX", JJLength_Dn, JXLength_Dn, Phase_Dn, IPC_Dn, 0, bar); //----+ detecting signals for trades Trend = JCCIX[0] - JCCIX[1]; //--- if (TrendX_Dn < 0) if (OldTrend_Dn > 0) if (Trend < 0) SELL_Sign = true; if (Trend != 0) OldTrend_Dn = Trend; } //----+ +------------------------------------------------+ //----+ DETECTING NOISE SIGNALS TO ENTER THE MARKET | //----+ +------------------------------------------------+ if (SELL_Sign) if (LastBarsN_Dn != IBARSN_Dn) { NoiseSELL_Sign = false; LastBarsN_Dn = IBARSN_Dn; //--- MA1 = iCustom(NULL, TimeframeN_Dn, "2Moving Avereges", Noise_period_Dn, SmoothN_Dn, MaMethodN_Dn, MaMethodN_Dn, PRICE_HIGH, 0, 0, 1); //--- MA2 = iCustom(NULL, TimeframeN_Dn, "2Moving Avereges", Noise_period_Dn, SmoothN_Dn, MaMethodN_Dn, MaMethodN_Dn, PRICE_HIGH, 0, 0, 2); //--- if (MA1 < MA2 || TimeCurrent() > StopTime_Dn) NoiseSELL_Sign = true; } //----+ +-------------------+ //----+ MAKING TRADES | //----+ +-------------------+ if (NoiseSELL_Sign) 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); } //+------------------------------------------------------------------+
次に、 Exp_14.mq4 を Exp_15.mq4に変えることについて細かいところに入っていきます。プログラムコードには新規のモジュール"DETECTING NOISE SIGNALS TO ENTER THE MARKET" があります。このモジュール処理のポイントは、以下のように表すことができます(ロングポジションについてのアルゴリズムのみ考察しています)。
小さいタイムフレームのトレンド方向が市場エンターシグナル BUY_Sig と一致するとき、シグナル NoiseBUY_Sign が発生します。または、このトレンドが一致しなければ、バーの定期的変化前にシグナル NoiseBUY_Sign が発生します。
トレンドフォロー MA として、標準的平均化アルゴリズムによって価格シーケンスのダブル平滑化で取得されるインディケータを使用しました。このモジュールからの EA に対する外部パラメータとして、変数を2つだけ使用しました。
extern int TimeframeN_Up = 15; extern int Noise_period_Up = 8;
固定されたカスタムインディケータ 2Moving Avereges.mq4 の外部変数はほとんど作成しました(グローバル変数の初期化)
int SmoothN_Up = 7, SmoothN_Dn = 7, MaMethodN_Up = 1, MaMethodN_Dn = 1;
コード追加の残りのロジックは完全に前稿で行ったのと同一です。
3つのタイムフレームを使用して Expert Advisor を構築する概念
ひととおり、EA のコードはできており、私はこの段階でやめにすることができるでしょう。ですが、私は作業の一番小さな部分が行われたと思います。この考えに基づき書かれた最初のトレーディングシステムは実取引ではほとんど良い結果を出さないでしょう。より適したバージョンを選ぶために1つか2つ以上似た EA のコードを書く必要があります。よって、アルゴリズムを計算して特定のトレードシグナルから抽出し、トリプル・スクリーン アルゴリズムだけを使用します。それは一般に問題ではありません。アルゴリズムを持たない結果のコードは以下のように表記されます。
//+==================================================================+ //| ThreeScreens.mqh | //| Copyright © 2008, Nikolay Kositsin | //| Khabarovsk, farria@mail.redcom.ru | //+==================================================================+ #property copyright "Copyright © 2008, Nikolay Kositsin" #property link "farria@mail.redcom.ru" //----+ +---------------------------------------------------------------------------+ //---- EXPERT ADVISORS INPUTS FOR BUY TRADES extern bool Test_Up = true;//filter of trade calculations direction extern double Money_Management_Up = 0.1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeX_Up = 1440; // Declarations and initializations of the EA external parameters for long positions for the largest timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int Timeframe_Up = 240; // Declarations and initializations of the EA external parameters for long positions for the middle timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeN_Up = 15; // Declarations and initializations of the EA external parameters for long positions for the smallest timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int STOPLOSS_Up = 50; // StopLoss extern int TAKEPROFIT_Up = 100; // TakeProfit extern bool ClosePos_Up = true; // enable forcible closing the position //----+ +---------------------------------------------------------------------------+ //---- EXPERT ADVISORS INPUTS FOR SELL TRADES extern bool Test_Dn = true;//filter of trade calculations direction extern double Money_Management_Dn = 0.1; //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeX_Dn = 1440; // Declarations and initializations of the EA external parameters for short positions forlargest timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int Timeframe_Dn = 240; // Declarations and initializations of the EA external parameters for short positions formiddle timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int TimeframeN_Dn = 15; // Declarations and initializations of the EA external parameters for short positions forthe smallest timeframe //---- + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + extern int STOPLOSS_Dn = 50; // StopLoss extern int TAKEPROFIT_Dn = 100; // TakeProfit extern bool ClosePos_Dn = true; // enable forcible closing the position //----+ +---------------------------------------------------------------------------+ //---- Integer variables for the minimum of reference bars int MinBar_Up, MinBar_Dn, MinBarX_Up, MinBarX_Dn, MinBarN_Up, MinBarN_Dn; //+==================================================================+ //| Custom Expert functions | //+==================================================================+ #include <Lite_EXPERT1.mqh> //+==================================================================+ //| TimeframeCheck() functions | //+==================================================================+ void TimeframeCheck(string Name, int Timeframe) { //----+ //---- Checking the value of variable Timeframe for correctness 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 values of timeframe variables for correctness TimeframeCheck("TimeframeX_Up", TimeframeX_Up); TimeframeCheck("Timeframe_Up", Timeframe_Up); TimeframeCheck("TimeframeN_Up", TimeframeN_Up); //---- Checking the values of timeframe variables for correctness TimeframeCheck("TimeframeX_Dn", TimeframeX_Dn); TimeframeCheck("Timeframe_Dn", Timeframe_Dn); TimeframeCheck("TimeframeN_Dn", TimeframeN_Dn); //---- Initialization of variables for long positions MinBarX_Up = // initialization of the variable for the minimum reference bars for largest timeframe MinBar_Up = // initialization of the variable for the minimum reference bars for middle timeframe MinBarN_Up = // initialization of the variable for the minimum reference bars for the smallest timeframe //---- Initialization of variables for short positions MinBarX_Dn = // initialization of the variable for the minimum reference bars for largest timeframe MinBar_Dn = // initialization of the variable for the minimum reference bars for middle timeframe MinBarN_Dn = // initialization of the variable for the minimum reference bars for the smallest timeframe //---- initialization complete return(0); } //+==================================================================+ //| expert deinitialization function | //+==================================================================+ int deinit() { //----+ //---- EA deinitialization complete return(0); //----+ } //+==================================================================+ //| Custom Expert iteration function | //+==================================================================+ int start() { //----+ Declaration of local variables of trading algorithms //----+ Declaration of static variables of trading algortihms //----+ Declaration of static variables static datetime StopTime_Up, StopTime_Dn; //--- static int LastBars_Up, LastBars_Dn; static int LastBarsX_Up, LastBarsX_Dn; static int LastBarsN_Up, LastBarsN_Dn; //--- static bool BUY_Sign, BUY_Stop; static bool SELL_Sign, SELL_Stop; static bool NoiseBUY_Sign, NoiseSELL_Sign; static double TrendX_Up, TrendX_Dn; //----+ +---------------------------------------------------------------+ //----++ CODE FOR LONG POSITIONS | //----+ +---------------------------------------------------------------+ if (Test_Up) { int IBARS_Up = iBars(NULL, Timeframe_Up); int IBARSX_Up = iBars(NULL, TimeframeX_Up); int IBARSN_Up = iBars(NULL, TimeframeN_Up); //--- if (IBARS_Up >= MinBar_Up && IBARSX_Up >= MinBarX_Up && IBARSN_Up >= MinBarN_Up) { //----+ +----------------------+ //----+ DETECTING A TREND | //----+ +----------------------+ if (LastBarsX_Up != IBARSX_Up) { //----+ Initialization of variables LastBarsX_Up = IBARSX_Up; BUY_Sign = false; BUY_Stop = false; // Trend direction detecting algorithm on the largest timeframe //(initializing variable TrendX_Up) //----+ defining a signal to close trades if (TrendX_Up < 0) BUY_Stop = true; } //----+ +----------------------------------------+ //----+ DETECTING SIGNALS TO ENTER THE MARKET | //----+ +----------------------------------------+ if (LastBars_Up != IBARS_Up && TrendX_Up > 0) { //----+ Initialization of variables BUY_Sign = false; LastBars_Up = IBARS_Up; //----+ Initialization of noise variables NoiseBUY_Sign = false; StopTime_Up = iTime(NULL, Timeframe_Up, 0) + 50 * Timeframe_Up; // Entering point determining algorithm on the middle timeframe //(Initializing variable BUY_Sign) } //----+ +------------------------------------------------+ //----+ DETECTING NOISE SIGNALS TO ENTER THE MARKET | //----+ +------------------------------------------------+ if (BUY_Sign) if (LastBarsN_Up != IBARSN_Up) { NoiseBUY_Sign = false; LastBarsN_Up = IBARSN_Up; //--- // Entering point precising algorithm on the smallest timeframe //(Initializing variable NoiseBUY_Sign) } //----+ +-------------------+ //----+ MAKING TRADES | //----+ +-------------------+ if (NoiseBUY_Sign) 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); int IBARSN_Dn = iBars(NULL, TimeframeN_Dn); //--- if (IBARS_Dn >= MinBar_Dn && IBARSX_Dn >= MinBarX_Dn && IBARSN_Dn >= MinBarN_Dn) { //----+ +----------------------+ //----+ DETECTING A TREND | //----+ +----------------------+ if (LastBarsX_Dn != IBARSX_Dn) { //----+ Initialization of variables LastBarsX_Dn = IBARSX_Dn; SELL_Sign = false; SELL_Stop = false; // Trend direction detecting algorithm on the largest timeframe //(initializing variable TrendX_Dn) //----+ defining a signal to close trades if (TrendX_Dn > 0) SELL_Stop = true; } //----+ +----------------------------------------+ //----+ DETECTING SIGNALS TO ENTER THE MARKET | //----+ +----------------------------------------+ if (LastBars_Dn != IBARS_Dn && TrendX_Dn < 0) { //----+ Initialization of variables SELL_Sign = false; LastBars_Dn = IBARS_Dn; //----+ Initialization of noise variables NoiseSELL_Sign = false; StopTime_Dn = iTime(NULL, Timeframe_Dn, 0) + 50 * Timeframe_Dn; // Entering point determining algorithm on the middle timeframe //(Initializing variable SELL_Sign) } //----+ +------------------------------------------------+ //----+ DETECTING NOISE SIGNALS TO ENTER THE MARKET | //----+ +------------------------------------------------+ if (SELL_Sign) if (LastBarsN_Dn != IBARSN_Dn) { NoiseSELL_Sign = false; LastBarsN_Dn = IBARSN_Dn; //--- // Entering point precising algorithm on the smallest timeframe //(Initializing variable NoiseSELL_Sign) } //----+ +-------------------+ //----+ MAKING TRADES | //----+ +-------------------+ if (NoiseSELL_Sign) 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); } //+------------------------------------------------------------------+
このコードをを書くためのテンプレートとして使用するなら、まず対応するブロック: "DETECTING A TREND" おおび "DETECTING NOISE SIGNAL TO ENTER THE MARKET"、の変数を初期化します。
TrendX_Up = 1; TrendX_Dn =-1; Noise8uy_Sign = true; NoiseSELL_Sign = true;
その後、ブロック "DETECTING SIGNALS TO ENTER THE MARKET" にご自分のコードを追加し、このコードで動作するようEA を調整します。のコードでこれを行う方法を学習することができます。そこには、中間のタイムフレームについて市場にエンターするシグナルを検出するアルゴリズムのみが存在します。同時に、もっとも大きなタイムフレームでトレンドを検出したり、もっとも小さいタイムフレームでノイズのトレンドを検出するアルゴリズムはありません。この場合、ブロック int init() 内のバーの最小本数に対する変数の初期化には注意を払う必要があります。
//---- Initialization of variables MinBarX_Up = 0; MinBar_Up = 4 + 3 * JXLength_Up + 30; MinBarN_Up = 0; //---- Initialization of variables MinBarX_Dn = 0; MinBar_Dn = 4 + 3 * JXLength_Dn + 30; MinBarN_Dn = 0;
第2ステップでは、ブロック "DETECTING A TREND" から初期化を削除します。
TrendX_Up = 1; TrendX_Dn =-1;
こういうブロックでトレンド方向を検出するためにコードを追加し、再度 EA を調整します。コードを書く上でこの段階は Exp_15_B.mq4 に表示されます。ブロック init() の変数 MinBarX_Up および MinBarX_Dn を初期化することを忘れないでください。
//---- Initialization of variables MinBarX_Up = 2 + PeriodWATR_Up; MinBar_Up = 4 + 3 * JXLength_Up + 30; MinBarN_Up = 0; //---- Initialization of variables MinBarX_Dn = 2 + PeriodWATR_Dn; MinBar_Dn = 4 + 3 * JXLength_Dn + 30; MinBarN_Dn = 0;
結果、2つのタイムフレームで動作する EA を取得します。第3ステップでは、ブロック "DETECTING NOISE SIGNALS TO ENTER THE MARKET" の EA コードとまったく同じように、
Noise8uy_Sign = true; NoiseSELL_Sign = true;
それらブロックから初期化が事前に削除され、この場合、ブロック int init() 内のバーの最小本数に対する変数を初期化するため、算術演算が追加されます。
//---- Initialization of variables MinBarX_Up = 2 + PeriodWATR_Up; MinBar_Up = 4 + 3 * JXLength_Up + 30; MinBarN_Up = 4 + Noise_period_Up + SmoothN_Up; //---- Initialization of variables MinBarX_Dn = 2 + PeriodWATR_Dn; MinBar_Dn = 4 + 3 * JXLength_Dn + 30; MinBarN_Dn = 4 + Noise_period_Dn + SmoothN_Dn;
これで、EA のコードは3段階で作成されることが判りました。ただし、このコードを1段階だけで構築する場合、将来簡単には検出できないエラーが起こる可能性があります。
おわりに
本稿では、3つのタイムフレームを使う Expert Advisorを書く一般的な方法の私バージョンを提供しました。技術的には、この考えはかなり簡単に MQL4 に実装できるものです。ですが、もう一つ別の疑問があります。「その考え方の特定の実用的意味を明確にするにはどのようなソリューションが役立つのでしょうか?」
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1535
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索