私たちのファンページに参加してください
MACD Sample - MetaTrader 5のためのエキスパート
- 発行者:
- MetaQuotes
- ビュー:
- 7886
- 評価:
- パブリッシュ済み:
- 2015.11.26 13:37
- アップデート済み:
- 2016.11.22 07:34
- このコードに基づいたロボットまたはインジケーターが必要なら、フリーランスでご注文ください フリーランスに移動
MACDのサンプルEAは MetaTrader 5 に標準装備されています。また、MACDを使ったEAのサンプルでもあります。
MACDのファイル Sample.mq5 は terminal_data_folder\MQL5\Experts\Examples\MACD\"にあります。このEAは、EA開発におけるオブジェクト指向の一例です。
EAの構造とどのように機能するかを見てみましょう。
1 EA プロパティ
1.1. EA プロパティ
//+------------------------------------------------------------------+ //| MACD Sample.mq5 | //| Copyright 2009-2013, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2009-2013, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "5.20" #property description "It is important to make sure that the expert works with a normal" #property description "chart and the user did not make any mistakes setting input" #property description "variables (Lots, TakeProfit, TrailingStop) in our case," #property description "we check TakeProfit on a chart of more than 2*trend_period bars"
初めの5行はコメントです。後ろの7行が MQL5 のプロパティで(copyright, link, version)、プリプロセッサー指示文#propertyを使います。
EAをはしらせるとき、これらは"Common" タブに表示されます:
図1 MACDのEAの一般パラメータ
1.2. インクルードファイル
次に、#includeでコンパイラーに標準ライブラリのtrade classesを含ませることを指示します。
- Trade.mqh (CTrade - トレードのクラス);
- SymbolInfo.mqh (CSymbolInfo - トレードのプロパティで稼働するクラス);
- PositionInfo.mqh (CPositionInfo - 約定したポジションプロパティで稼働するクラス);
- AccountInfo.mqh (CAccountInfo - トレードアカウントで稼働するクラス)。
//--- include files #include <Trade\Trade.mqh> #include <Trade\SymbolInfo.mqh> #include <Trade\PositionInfo.mqh> #include <Trade\AccountInfo.mqh>
適切なクラスのインスタンスが、 CExpert class (セクション 3)のメンバとして使われます。
1.3. インプット
続いて、タイプ、名前、デフォルト値、コメントです。ルールは図2の通りです。
//--- Expert Advisor input parameters input double InpLots =0.1; // Lots input int InpTakeProfit =50; // Take Profit (in pips) input int InpTrailingStop =30; // Trailing Stop Level (in pips) input int InpMACDOpenLevel =3; // MACD open level (in pips) input int InpMACDCloseLevel=2; // MACD close level (in pips) input int InpMATrendPeriod =26; // MA trend period
パラメータの名前の前には"Inp"がついています。また、グローバル変数の前には"Ext"をつけます。大量の異なる変数を扱う際に、わかりやすくするためのものです。
InpLots - トレードロット、InpTakeProfit と InpTrailingStop は利確とトレーリングレベルを決めます。
パラメータラインに書かれたコメントのテキストは(デフォルト値を含む)、パラメータの名前の代わりとして"Options"タブに表示されます:
図2. MACDのEAのパラメータ
1.4. グローバル変数
グローバル変数 ExtTimeOut を宣言します。これは、トレード実行の有効期限の制御に使われます。
int ExtTimeOut=10; // 時間 (秒) トレード実行
CSampleExpert の宣言の後、76行目で別のグローバル変数を宣言します。 ExtExpert - CSampleExpert クラスインスタンス:
//--- ExtExpert グローバル変数
CSampleExpert ExtExpert;
ExtExpert オブジェクト (CSampleExpert サンプルクラス) は、トレード手法の基本ロジックを含みます。(セクション 3)
2. イベントハンドラ関数
イベントハンドラ関数
2.1. OnInit() 初期関数
OnInit() 関数は、EAを稼働させたときの最初に一回だけ起動します。一般的に、OnInit()ではEA実行の準備処理を行います: パラメータをチェックしやインジケーターやパラメータを初期化などクリティカルエラーが発生した場合には、その後の処理は無意味になり、関数は INIT_FAILED を返します。
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(void) { //--- initialization and creation of all the required objects if(!ExtExpert.Init()) return(INIT_FAILED); //--- successful initialization return(INIT_SUCCEEDED); }
今回の場合、ExtExpert の Init()メソッドが呼び出されます。これはすべてのオブジェクトの状態に応じてtrueかfalseを返します。(セクション 3.4 参照)。 エラーが発生した場合、 OnInit() は INIT_FAILED を返します。- これは、初期化に失敗した場合の、EA/インジケーターの挙動として正常です。
2.2. OnTick() 関数
OnTick() 関数は、EAを稼働させているチャートのシンボルに新しいクオートが来た場合に呼び出されます。
//+------------------------------------------------------------------+ //| Expert new tick handling function | //+------------------------------------------------------------------+ void OnTick(void) { static datetime limit_time=0; // stores the last call time + timeout //--- do not operate if the required time has not elapsed if(TimeCurrent()>=limit_time) { //--- checking data if(Bars(Symbol(),Period())>2*InpMATrendPeriod) { //--- after the call of the Processing() method increase the value of limit_time by ExtTimeOut if(ExtExpert.Processing()) limit_time=TimeCurrent()+ExtTimeOut; } } }
OnTick()では、イベントハンドラが定期的にExtExpert.Processing()を呼び出します。これは相場分析やトレード条件が整った際のトレードの実行に使われます。
呼び出される時間の間隔は、ExtTimeOut パラメータの値によって設定されます。
2.3. OnDeInit() 関数
OnDeInit()は、EAがチャートから外された際に呼ばれます。グラフィックオブジェクトを稼働中に描写していた場合、それらもチャートから取り外されます。
今回の場合、終了時に呼び出す関数を使われず、何も実行されません。
3. CSampleExpert クラス
3.1. CSampleExpert クラス
//+------------------------------------------------------------------+ //| The MACD Sample EA class sample | //+------------------------------------------------------------------+ class CSampleExpert { protected: //--- protected variables - class members are available only inside the class methods double m_adjusted_point; // a multiplier for 3/5-digit quotes CTrade m_trade; // CTrade class sample CSymbolInfo m_symbol; // CSymbolInfo class sample CPositionInfo m_position; // CPositionInfo class sample CAccountInfo m_account; // CAccountInfo class sample //--- indicator handles int m_handle_macd; // the MACD indicator handle int m_handle_ema; // the Moving Average indicator handle //--- indicator buffers double m_buff_MACD_main[]; // the buffer of the main line of the MACD indicator double m_buff_MACD_signal[]; // the buffer of the signal line of the MACD indicator double m_buff_EMA[]; // EMA indicator buffers //--- current indicator values double m_macd_current; double m_macd_previous; double m_signal_current; double m_signal_previous; double m_ema_current; double m_ema_previous; //--- levels (in standard points) double m_macd_open_level; double m_macd_close_level; double m_traling_stop; double m_take_profit; public: //--- constructor CSampleExpert(void); //--- destructor ~CSampleExpert(void); //--- public-methods can be called from outside the class //--- initialization method bool Init(void); //--- deinitialization method void Deinit(void); //--- method of processing bool Processing(void); protected: //--- protected-methods can be accessed only inside the class methods bool InitCheckParameters(const int digits_adjust); bool InitIndicators(void); bool LongClosed(void); bool ShortClosed(void); bool LongModified(void); bool ShortModified(void); bool LongOpened(void); bool ShortOpened(void); };
このEA のクラスには、変数(クラス メンバ)と関数(クラス メソッド)の宣言が含まれています。
変数処理をより便利にするため、すべてのメンバ変数は頭に"m_" (メンバ)がついています。これはその変数がクラスメンバであることを表します。変数やメソッドの宣言の前に、その型を指定します。(あるいは関数の返り値の型)
クラスメンバの変数やメソッドを見るには access modifiersを使います。クラス中では、CSampleExpert は保護されていて、publicを使います。publicで宣言されたすべての変数とメソッドは、外側からアクセスすることが可能です。CSampleExpert クラスには5つのメソッドがあります:
- CSampleExpert(void) - コンストラクタ (インスタンスを生成した際に自動的にコールされます);
- ~CSampleExpert(void) - ディストラクタ (インスタンスを削除したさいに自動的にコールされます);
- bool Init(void) - 全データを準備するための初期メソッド;
- void Deinit(void) - 終了時のメソッド;
- bool Processing(void) - プロセス時のメソッド
保護されたアクセス修飾子で宣言されたCSampleExpert 変数は、 CSampleExpertメソッド(とその子クラス)の中でのみ利用可能です。
- double m_adjusted_point - 少数桁数3/5に修正する変数;
- CTrade m_trade - СTrade クラスサンプル;
- CSymbolInfo m_symbol - CSymbolInfo クラスサンプル;
- CPositionInfo m_position - СPositionInfo クラスサンプル;
- CAccountInfo m_account - CAccountInfo クラスサンプル;
- int m_handle_macd - MACDハンドルの値を保存する変数
- int m_handle_ema - EMAの値を保存する変数;
- double m_buff_MACD_main[] - MACDのメインラインを呼び出すdouble 型の動的配列;
- double m_buff_MACD_signal[] - MACDのシグナルラインを呼び出すdouble 型の動的配列;
- double m_buff_EMA[] - EMAの値を呼び出すdouble 型の動的配列;
- double m_macd_current - 現在のMACDのメインラインを保存;
- double m_macd_previous - ひとつ前のMACDのメインラインの値を保存;
- double m_signal_current - 現在のMACDのシグナルラインの値を保存;
- double m_signal_previous - ひとつ前の MACDのシグナルラインを保存;
- double m_ema_current - 現在のEMAの値を保存;
- double m_ema_previous - ひとつ前のEMAの値を保存
- double m_macd_open_level,
- double m_macd_close_level,
- double m_traling_stop,
- double m_take_profit - m_adjusted_point を考慮にいれた価格の値(パラメータで設定)を保存するのに使います。
CSampleExpert は、保護されたアクセス修飾子で宣言します:
- bool InitCheckParameters(const int digits_adjust) - パラメータとEAの初期設定の整合性を確認します。
- bool InitIndicators(void) - MACD と Moving Averageの初期設定;
- bool LongClosed(void) - 買いポジションの決済条件になればtrueを返し、決済します。
- bool ShortClosed(void) - 売りポジションの決済条件になればtrueを返し、決済します。
- bool LongModified(void) - 買いポジションのストップロスを変更する条件が整った場合trueを返し、ストップロスを修正します。
- bool ShortModified(void) - 売りポジションのストップロスを変更する条件が整った場合trueを返し、ストップロスを修正します。
- bool LongOpened(void) - 買いポジションをとる条件がそろえばtrueを返し、新規ポジションを建てます。
- bool ShortOpened(void) - 売りポジションをとる条件がそろえばtrueを可視、新規ポジションを建てます。
3.2. CSampleExpert Class Constructor
//+------------------------------------------------------------------+ //| CSampleExpert Class Constructor | //+------------------------------------------------------------------+ CSampleExpert::CSampleExpert(void) : m_adjusted_point(0), m_handle_macd(INVALID_HANDLE), m_handle_ema(INVALID_HANDLE), m_macd_current(0), m_macd_previous(0), m_signal_current(0), m_signal_previous(0), m_ema_current(0), m_ema_previous(0), m_macd_open_level(0), m_macd_close_level(0), m_traling_stop(0), m_take_profit(0) { ArraySetAsSeries(m_buff_MACD_main,true); ArraySetAsSeries(m_buff_MACD_signal,true); ArraySetAsSeries(m_buff_EMA,true); }
Class constructorが、 サンプルオブジェクトが生成された際に自動的に呼び出されます。呼び出された際、変数のデフォルトの値がセットされ、indexing direction が m_buff_MACD_main[], m_buff_MACD_signal[], m_buff_EMA[]にセットされます。
3.3. CSampleExpert Class destructor
//+------------------------------------------------------------------+ //| CSampleExpert class destructor | //+------------------------------------------------------------------+ CSampleExpert::~CSampleExpert(void) { }
CSampleExpert デストラクタには何も記述されていません。
3.4. CSampleExpert の初期メソッド
//+------------------------------------------------------------------+ //| Initialization and verification of input parameters | //+------------------------------------------------------------------+ bool CSampleExpert::Init(void) { //--- setting common properties m_symbol.Name(Symbol()); // symbol m_trade.SetExpertMagicNumber(12345); // magic //--- taking into account 3/5-digit quotes int digits_adjust=1; if(m_symbol.Digits()==3 || m_symbol.Digits()==5) digits_adjust=10; m_adjusted_point=m_symbol.Point()*digits_adjust; //--- setting the values of the levels taking into account the m_adjusted_point modifier m_macd_open_level =InpMACDOpenLevel*m_adjusted_point; m_macd_close_level=InpMACDCloseLevel*m_adjusted_point; m_traling_stop =InpTrailingStop*m_adjusted_point; m_take_profit =InpTakeProfit*m_adjusted_point; //--- setting the slippage of 3 points m_trade.SetDeviationInPoints(3*digits_adjust); //--- if(!InitCheckParameters(digits_adjust)) return(false); if(!InitIndicators()) return(false); //--- successful completion return(true); }
Init()では、変数は初期化され、パラメータは変更されます。
m_symbol (CSymbolInfo )のためのName()の呼び出しでは、EAを稼働させているシンボルの名前をセットします。次にSetExpertMagicNumber() が呼び出され、m_tradeのためのEAのマジックナンバーを設定します。後に、シンボルの桁数を取得するためDigits()が使われます。 もし修正が必要な場合には適切な値に補正されます。
次に、m_trade のSetDeviationInPoints()が呼び出されます。これは許容スリッページを設定します。
3.5. CSampleExpert の InitCheckParameters
//+------------------------------------------------------------------+ //| Checking for input parameters | //+------------------------------------------------------------------+ bool CSampleExpert::InitCheckParameters(const int digits_adjust) { //--- checking correctness of the Take Profit level if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel()) { printf("Take Profit must be greater than %d",m_symbol.StopsLevel()); return(false); } //--- checking correctness of the Trailing Stop level if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel()) { printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel()); return(false); } //--- checking correctness of the trade volume if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax()) { printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax()); return(false); } if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0E-10) { printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep()); return(false); } //--- show warning if Take Profit<=Trailing Stop if(InpTakeProfit<=InpTrailingStop) printf("Warning: Trailing Stop must be less than Take Profit"); //--- successful completion return(true); }
EAのパラメータが正しいかどうかInitCheckParameters()で確認します。もし無効なパラメータがあった場合、適切なメッセージが表示されます。そして、関数はfalseを返します。
3.6. CSampleExpert の InitIndicators()
//+------------------------------------------------------------------+ //| Indicators initialization method | //+------------------------------------------------------------------+ bool CSampleExpert::InitIndicators(void) { //--- creating the MACD indicator if(m_handle_macd==INVALID_HANDLE) if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE) { printf("Error creating MACD indicator"); return(false); } //--- creating the EMA indicator if(m_handle_ema==INVALID_HANDLE) if((m_handle_ema=iMA(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))==INVALID_HANDLE) { printf("Error creating EMA indicator"); return(false); } //--- successful completion return(true); }
InitIndicators()では、m_handle_macd と m_handle_ema 変数の整合性を確認します。(コンストラクタで初期化されたので、INVALID_HANDLEと一致する必要があります。) テクニカルインジケーターMACD、Moving Averageが生成されます。(iMACD と iMA 関数を使用します。) 成功した場合、関数はtrueを返し、インジケーターのハンドルがm_handle_macd と m_handle_emaに保存されます。
生成されたインジケーターのハンドルは次に計算されたデータ(BarsCalculated)の確認とProcessing() のインジケーターの値(CopyBuffer)の取得に使われます。
3.7. CSampleExpert の LongClosed()
//+------------------------------------------------------------------+ //| Checking conditions for closing a long position | //+------------------------------------------------------------------+ bool CSampleExpert::LongClosed(void) { bool res=false; //--- Should the position be closed? if(m_macd_current>0) if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous) if(m_macd_current>m_macd_close_level) { //--- closing the position if(m_trade.PositionClose(Symbol())) printf("Long position by %s to be closed",Symbol()); else printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment()); res=true; } //--- returning the result return(res); }
決済条件が整った場合、LongClosed() はtrueを返し、買いポジションを決済します:
- m_macd_current>0 - 現在のMACDのメインラインの値が正(MACD ヒストグラムが0ラインよりも上);
- m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - MACDのメインラインがシグナルを下向きにクロス
- m_macd_current>m_macd_close_level - 現在のMACDのメインラインの値が m_macd_close_levelよりも高い
3.8. CSampleExpert の ShortClosed()
//+------------------------------------------------------------------+ //| Checking conditions for closing a short position | //+------------------------------------------------------------------+ bool CSampleExpert::ShortClosed(void) { bool res=false; //--- Should the position be closed? if(m_macd_current<0) if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous) if(MathAbs(m_macd_current)>m_macd_close_level) { //--- closing the position if(m_trade.PositionClose(Symbol())) printf("Short position by %s to be closed",Symbol()); else printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment()); res=true; } //--- returning the result return(res); }
売りポジションの決済条件が整った場合、ShortClosed() はtrueを返し、決済します:
- m_macd_current<0 - 現在のMACDのメインラインの値が負 (MACD ヒストグラムが0ラインよりも下)。
- m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - MACDのメインラインがシグナルを上向きにクラス
- MathAbs(m_macd_current)>m_macd_close_level - 現在のMACDのメインラインが m_macd_close_levelよりも高い
3.9. CSampleExpert の LongModified()
//+------------------------------------------------------------------+ //| Checking conditions for long position modification | //+------------------------------------------------------------------+ bool CSampleExpert::LongModified(void) { bool res=false; //--- checking if Trailing Stop is required if(InpTrailingStop>0) { if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop) { double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits()); double tp=m_position.TakeProfit(); if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0) { //--- modifying Stop Loss and Take Profit of the position if(m_trade.PositionModify(Symbol(),sl,tp)) printf("Long position by %s to be modified",Symbol()); else { printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Modify parameters : SL=%f,TP=%f",sl,tp); } res=true; } } } //--- returning the result return(res); }
買いポジションの修正条件が整った場合、LongModified() はtrueを返し、ストップロスを修正します: InpTrailingStop>0 の場合、価格がトレーリングストップのポイントを通過するかどうかを確認します。そして、新しいストップロスの値が計算され、ストップロスが修正されます。
3.10. CSampleExpert の ShortModified
//+------------------------------------------------------------------+ //| Checking conditions for long position modification | //+------------------------------------------------------------------+ bool CSampleExpert::ShortModified(void) { bool res=false; //--- checking if Trailing Stop is required if(InpTrailingStop>0) { if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop)) { double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits()); double tp=m_position.TakeProfit(); if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0) { //--- modifying Stop Loss and Take Profit of the position if(m_trade.PositionModify(Symbol(),sl,tp)) printf("Short position by %s to be modified",Symbol()); else { printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Modify parameters : SL=%f,TP=%f",sl,tp); } res=true; } } } //--- returning the result return(res); }
売りポジションの修正条件が整った場合、ShortModified() はtrueを返し、ストップロスを修正します: InpTrailingStop>0 の場合、価格がトレーリングストップのポイントを通過するかどうかを確認します。そして、新しいストップロスの値が計算され、ストップロスが修正されます。
3.11. CSampleExpert の LongOpened()
//+------------------------------------------------------------------+ //| Check for long position opening | //+------------------------------------------------------------------+ bool CSampleExpert::LongOpened(void) { bool res=false; //--- checking conditions for opening a long position if(m_macd_current<0) if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous) if(MathAbs(m_macd_current)>(m_macd_open_level) && m_ema_current>m_ema_previous) { double price=m_symbol.Ask(); double tp =m_symbol.Bid()+m_take_profit; //--- checking free margin if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0) printf("We have no money. Free Margin = %f",m_account.FreeMargin()); else { //--- opening a long position if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp)) printf("Position by %s to be opened",Symbol()); else { printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Open parameters : price=%f,TP=%f",price,tp); } } res=true; } //--- returning the result return(res); }
LongOpened() 買いポジションをとる条件がそろえばtrueを返し、新規ポジションを建てます:
- m_macd_current<0 - 現在のMACDのメインラインの値が負 (MACD ヒストグラムが0ラインよりも下);
- m_macd_current>m_signal_current && m_macd_previous<m_signal_previous - MACDのメインラインがシグナルを上向きにクラス;
- MathAbs(m_macd_current)>m_macd_open_level - 現在のMACDのメインラインが m_macd_open_levelよりも高い;
- m_ema_current>m_ema_previous - EMAが上昇
すべての条件がそろったとき、余剰証拠金を確認します。(標準ライブラリCAccountInfo の FreeMarginCheck() ) 買いポジションが CTrade のPositionOpen()によって建てられます。
3.12. CSampleExpert の ShortOpened
//+------------------------------------------------------------------+ //| Check for short position opening | //+------------------------------------------------------------------+ bool CSampleExpert::ShortOpened(void) { bool res=false; //--- checking conditions for opening a short position if(m_macd_current>0) if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous) if(m_macd_current>(m_macd_open_level) && m_ema_current<m_ema_previous) { double price=m_symbol.Bid(); double tp =m_symbol.Ask()-m_take_profit; //--- checking free margin if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0) printf("We have no money. Free Margin = %f",m_account.FreeMargin()); else { //--- opening a short position if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp)) printf("Position by %s to be opened",Symbol()); else { printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment()); printf("Open parameters : price=%f,TP=%f",price,tp); } } res=true; } //--- returning the result return(res); }
ShortOpened() 売りポジションをとる条件がそろえばtrueを可視、新規ポジションを建てます:
- m_macd_current>0 - 現在のMACDのメインラインの値が正(MACD ヒストグラムが0ラインよりも上);
- m_macd_current<m_signal_current && m_macd_previous>m_signal_previous - MACDのメインラインがシグナルを下向きにクロス;
- m_macd_current>m_macd_open_level - 現在のMACDのメインラインが m_macd_open_levelよりも高い;
- m_ema_current<m_ema_previous - EMAが減少。
すべての条件がそろったとき、余剰証拠金を確認します。(標準ライブラリCAccountInfo の FreeMarginCheck() ) 売りポジションが CTrade のPositionOpen()によって建てられます。
3.13CSampleExpert の Processing()
//+------------------------------------------------------------------+ //| main function returns true if any position processed | //+------------------------------------------------------------------+ bool CSampleExpert::Processing(void) { //--- updating quotes if(!m_symbol.RefreshRates()) return(false); //--- updating indicator values if(BarsCalculated(m_handle_macd)<2 || BarsCalculated(m_handle_ema)<2) return(false); if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main) !=2 || CopyBuffer(m_handle_macd,1,0,2,m_buff_MACD_signal)!=2 || CopyBuffer(m_handle_ema,0,0,2,m_buff_EMA) !=2) return(false); //--- to simplify work with indicators and for faster access //--- the current values of the indicators are saved in internal variables (class members) m_macd_current =m_buff_MACD_main[0]; m_macd_previous =m_buff_MACD_main[1]; m_signal_current =m_buff_MACD_signal[0]; m_signal_previous=m_buff_MACD_signal[1]; m_ema_current =m_buff_EMA[0]; m_ema_previous =m_buff_EMA[1]; //--- correct market entry is important, but a correct exit is even more important //--- first check if there is an open position if(m_position.Select(Symbol())) { if(m_position.PositionType()==POSITION_TYPE_BUY) { //--- if necessary, we try to close or modify a long position if(LongClosed()) return(true); if(LongModified()) return(true); } else { //--- if necessary, we try to close or modify a short position if(ShortClosed()) return(true); if(ShortModified()) return(true); } } //--- no open positions else { //--- check conditions and open a long position if necessary if(LongOpened()) return(true); //--- check conditions and open a short position if necessary if(ShortOpened()) return(true); } //--- exit without position processing return(false); }
CSampleExpert の Processing() はEAのメソッドです。Processing() が OnTick() で呼び出され、このメソッドの連続して呼び出す時間間隔を管理します。( ExtTimeOut 秒と同等) (セクション 2.2)。
CSymbolInfoのRefreshRates()を呼び出すことによって、クオートが更新されます。 BarsCalculated()関数は、 MACD と Moving Averageの計算に使うバーの数のリクエストに使います。 (セクション 3.6)バーの数が2本以下の場合、関数から抜けfalseを返します。
次に、CopyBuffer関数が、最新の2つのテクニカルインジケーターの値をリクエストします。(MACDのメインとシグナルラインと移動平均の値); データ量が2つ以下の場合、関数から抜けます。その後、配列m_buff_MACD_main[]、 m_buff_MACD_signal[]、 m_buff_EMA[] のインジケーターの値が変数m_macd_previous、m_signal_current、m_signal_previous、 m_ema_current、 m_ema_previousにコピーされます。
次のステップは、標準ライブラリのCPositionInfo で取得したポジションを処理することです。Select()の呼び出しがtrueの場合、現在約定しているポジションがあることを意味します。ポジション種別はPositionType() で取得可能です。約定したポジションの種別に応じて、さらなる処理が実行されます。
4. バックテスト
パラメータの最適な値は MetaTrader 5 terminal の Strategy Testerを使うことで探索可能です。
図3 は、EAの2013年のデフォルトの結果を表します。
図3. MACDのEAのバックテスト結果
結果
MetaTrader 5 の標準パックにあるサンプルのMACD のEAは、EAのオブジェクト指向の一例です。
MetaQuotes Ltdによってロシア語から翻訳されました。
元のコード: https://www.mql5.com/ru/code/2154
リアルタイムでの最適化結果の可視化の実例の紹介(資産曲線とEAの統計的パラメータ)。
ColorSchaffJJRSXTrendCycle_HTFインディケータ ColorSchaffJJRSXTrendCycleは、入力パラメータのインディケータの時間軸を変更することができます。