MQL5ウィザード:トレーディングシグナル用モジュール作成方法
はじめに
MetaTrader 5は、トレーディングにおけるアイディアを素早くチェックするための協力なツールを提供します。これはMQL5ウィザード.のトレーディング戦略のジェネレーターです。エキスパートアドバイザーの自動生成のためのMQL5ウィザードの使用は、「MQL5 Wizard: Creating Expert Advisors without Programming(MQL5ウィザード:プログラミングなしでエキスパートアドバイザーを作成する)」という記事にて紹介されています。コード生成システムのオープン性は、 標準 版に独自のトレーディングシグナル、資金管理システムの追加を可能にします。
この記事では、エキスパートアドバイザーをMQL5ウィザードで作成する際に使用するためのトレーディングシグナルのモジュールの規則を紹介します。
MQL5ウィザードにて作成されたエキスパートアドバイザーは4つの支柱 ベースクラスを土台としています:
図1. CExpertベースクラスのストラクチャー
CExpertクラス(もしくはサブクラス)はトレーディングロボットのメイン「エンジン」にあたります。CExpertのインスタンスは、それぞれのクラスのコピーを含んでいます:CExpertSignal、CExpertMoneyやCExpertTrailing (もしくは、それらのサブクラス)です。
- CExpertSignalは、トレーディングシグナルジェネレーターの基礎です。 CExpertに含まれるCEpertSignalから派生したクラスのインスタンスは、市場への参入や参入レベル、内臓のアルゴリズムに基づく注文の発行などについての情報をエキスパートアドバイザーに提供します。トレーディング処理の実行についての最終的な意思決定は、EAによってなされます。
- CExpertMoneyは、資産・リスク管理システムの土台です。CEpertMoneyの派生クラスのインスタンスは、ポジションのオープン、未決注文設定量を計算します。その量についての最終的な判断はEAによって行われます。
- CExpertTrailingは、オープンポジションのサポートモジュールの基礎です。CEpertTraillingクラスのインスタンスはEAに注文hの修正の必要性を知らせます。注文の修正の最終判断はEAによってなされます。
さらに、CExpert クラスのメンバーは以下のクラスのインスタンスです:
- CExpertTrade (トレーディング用)
- CIndicators (EAの動作に関連するタイムシリーズやインジケーターの管理用)
- CSymbolInfo (証券についてん情報の取得用)
- CAccountInfo (トレーディング用口座の状態についての情報取得用)
- CPositionInfo (fポジションについての情報取得用)
- COrderInfo (未決注文についての情報取得用)
「エキスパート」の下はCExpertかそのサブクラスのインスタンスを意味します。
CEpertや、使用方法についての詳細は、個別の記事にて紹介されます。
1. CExpertSignalベースクラス
CExpertSignalは、トレーディングシグナルジェネレーターの基礎です。「外部世界」とのコミュニケーションのためにCEpertSignalは、パブリックの仮想メソッドを持ちます。
初期化 | 詳細 |
仮想Init | クラスインスタンスの初期化は、モジュールデータの同期化にEAのデータを提供します。 |
仮想ValidationSettings | 設定パラメーターの確認 |
仮想InitIndicators | トレーディングシグナルのジェネレーターの実行のために必要なタイムシリーズやインジケーターの作成と初期化 |
ポジションのオープン・リバース・クローズのシグナル | |
仮想CheckOpenLong | ロングポジションのオープンシグナルの生成とエントリーレベルの定義、保護的注文の発行 |
仮想CheckOpenShort | ショートポジションのオープンの生成、エントリーレベルの定義と保護的注文の発行 |
仮想CheckCloseLong | ロングポジションのシグナル生成とエグジットレベルの定義 |
仮想CheckCloseShort | ショートポジションのクローズシグナル生成とエグジットレベルの定義 |
仮想CheckReverseLong | ロングポジションのリバース用シグナル生成と、リバースレベルの定義と保護的注文の発行 |
仮想CheckReverseShort | ショートポジションのシグナル用生成とリバースレベルの定義と保護的注文の発行 |
未決注文管理 | |
仮想CheckTrailingOrderLong | 買い未決注文の修正シグナル生成と新規注文価格の定義 |
仮想CheckTrailingOrderShort | 売りの未決注文修正シグナルの生成と、新規注文価格の定義 |
メソッドの詳細
1.1. 初期化メソッド:
Init() メソッドは自動的にクラスインスタンスがエキスパートに追加されてすぐに呼ばれます。再定義は必要ありません。
virtual bool Init(CSymbolInfo* symbol, ENUM_TIMEFRAMES period, double adjusted_point);
ValidationSettings()メソッドは、すべてのパラメーターが設定されたのちエキスパートから直接呼ばれます。セットアップパラメーターがあれば、メソッドをオーバーライドしなければなりません。
virtual bool ValidationSettings();
オーバーライドメソッドは、すべてのオプションが有効であればtrueを返す必要があります。もしパラメーターの一つが正しくなければ、falseを返します。(それ以降の作業は不可能です)
ベースクラスCExpertSignalは、調整可能なパラメーターを持たないため、ベースクラスのメソッドは、チェックを実行せずtrueを返します。
InitIndicators ()メソッドは、すべての必要なインジケーターとタイムシリーズの初期化と生成を実行します。すべてのパラメーターが設定され、確認されたのちにエキスパートから呼ばれます。もしトレーディングシグナルジェネレーターがすくなくとも一つインジケーターやタイムシリーズを使用するなら、そのメソッドは再定義されなければなりません。
virtual bool InitIndicators(CIndicators* indicators);
インジケーターやタイムシリーズは、適切な標準ライブラリクラスを通して使用されなければなりません。すべてのインジケーターやタイムシリーズのポインターは、エキスパートのインジケーターのコレクションに追加されます。
再定義されたメソッドはすべてのインジケーターやタイムシリーズの操作が成功すれば、trueを返します。もし少なくとも一つのインジケーターやタイムシリーズの処理が失敗に終われば、そのメソッドはfalseを返します。
ベースクラスCExpertSignalインジケーターやタイムシリーズを使用しないため、ベースクラスのメソッドは、常にtrueを返します。
1.2. ポジションのオープンのシグナルチェック用メソッド:
CheckOpenLong()メソッドは、ロングポジションのオープンのシグナルを生成し、エントリーレベルや保護的注文のレベルの定義を行います。ロングオープンポジションをオープンする必要があるかを決定するためにエキスパートにより呼ばれます。もし、ロングポジションのオープン用シグナルが生成されれば、そのメソッドは再定義されます。
virtual bool CheckOpenLong(double& price, double& sl, double& tp, datetime& expiration);
そのメソッドは、ロングポジションのオープンにおける状況のチェックを行うアルゴリズムを実行します。もし条件が満たされれば、価格変数や期限、si、tpが(パラメーターに渡されるリファレンス)適切な値をわりあてられ、メソッドはtrueを返します。もし条件が満たされなければ、そのメソッドはfalseを返します。
ベースクラスCExpertSignalは、ロングポジションのオープンに関するシグナルの生成のための内蔵アルゴリズムを持ち、ベースクラスのメソッドは常にfalseを返します。
CheckOpenShort()メソッドは、ショートポジションのオープン用シグナルを生成し、エントリーや保護的注文のレベルを設定します。ショートポジションをオープンにする必要があるか決定するためにエキスパートにより決定されます。そのメソッドはもしショートポジションのオープンに関するシグナルが生成sあれれば、再定義される必要があります。
virtual bool CheckOpenShort(double& price, double& sl, double& tp, datetime& expiration);
そのメソッドは、ショートポジションを開く条件をチェックするためのアルゴリズムを実行する必要があります。もし条件が満たされれば、その価格変数やsiもし条件が満たされなければ、そのメソッドはfalseを返します。
ベースクラスCExpertSignalは、ショートポジションのオープンに関するシグナルを生成する内蔵アルゴリズムを持たないため、そのクラスメソッドは常にfalseを返します。
1.3. ポジションのクローズのシグナルをチェックするメソッド
CheckCloseLong()メソッドは、ロングポジションのクローズシグナルを生成し、エグジットレベルを定義します。ロングポジションをクローズする必要があるかを決定するためエキスパートから呼び出されます。そのメソッドは、もしロングポジションのシグナルが生成されれば再定義される必要があります。
virtual bool CheckCloseLong(double& price);
そのメソッドは、ロングポジションのクローズ条件をチェックするアルゴリズムを実行します。もし条件が満たされれば、その変動価格は、適切な値がわりあてられ、メソッドはtrueを返さなければなりません。もし条件が満たされなければ、そのメソッドはfalseを返します。
CExpertSignalベースクラスは、ロングポジションのクローズ用シグナルの生成のためのアルゴリズムを持っておらず、そのベースクラスメソッドは常にfalseを返します。
CheckCloseShort()メソッドは、ショートポジションのクローズ用シグナルを生成し、エグジットレベルを定義します。ショートポジションをクローズする必要があるかを決定するためにエキスパートにより呼ばれます。そのメソッドは、もしショートポジションのクローズ用シグナルが生成されれば、再定義される必要があります。
virtual bool CheckCloseShort(double& price);
そのメソッドはショートポジションをクローズするための条件をチェックするためのアルゴリズムを実行します。もし条件が満たされれば、その変動価格は、適切な値がわりあてられ、メソッドはtrueを返さなければなりません。もし条件が満たされなければ、そのメソッドはfalseを返します。
ベースクラスCExpertSignalショートポジションのクローズ用シグナルの生成のためのアルゴリズムを持っておらず、そのベースクラスメソッドは常にfalseを返します。
1.4. ポジションのリバース用シグナルのチェックにおけるメソッド:
CheckReverseLongメソッドは、ロングポジションのリバース用シグナルを生成し、リバースや保護的注文のレベルの設定を行います。ロングポジションのリバースの必要があるかを決定するためにエキスパートにより呼ばれます。そのメソッドは、ロングポジションのリバース用シグナルが生成されれば、再定義される必要があります。
virtual bool CheckReverseLong(double& price, double& sl, double& tp, datetime& expiration);
そのメソッドは、ロングポジションのリバース条件をチェックするアルゴリズムを実行します。もし条件が満たされれば、その価格変数やsiもし条件が満たされなければ、そのメソッドはfalseを返します。
CExpertSignalベースクラスでは、ロングポジションのリバースシグナルを生成するための以下のアルゴリズムが実行されます:
- シグナルがロングポジションをクローズするためのチェック
- シグナルがロングポジションをオープンするためのチェック
- もし両方のシグナルがアクティブ(条件が満たされている)で、クローズとオープン価格がマッチしている場合、その価格、sl、tpと期限は、適切な値が渡され、そのメソッドはtrueを返します。
CheckReverseShortメソッドは、ショートポジションのリバースシグナルを生成し、リバースや保護的注文のレベルを設定します。ショートポジションをリバースする必要があるかを決定するためエキスパートにより呼ばれます。そのメソッドは、ベースクラスで実行されたものとは異なるアルゴリズムに沿って、ロングポジションのリバースシグナルが生成されれば、再定義されます。
virtual bool CheckReverseShort(double& price, double& sl, double& tp, datetime& expiration);
そのメソッドは、ショートポジションのリバース条件をチェックするアルゴリズムを実行します。もし条件が満たされれば、その価格変数やsiもし条件が満たされなければ、そのメソッドはfalseを返します。
CExpertSignalベースクラスでは、以下のアルゴリズムがショートポジションのリバースシグナルのために実行されます。
- ショートポジションのクローズ用シグナルのチェック
- ショートポジションのオープン用シグナルのチェック
- もし両方のシグナルがアクティブ(条件が満たされている)で、クローズとオープン価格がマッチしている場合、その価格、sl、tpと期限は、適切な値が渡され、そのメソッドはtrueを返します。
もし条件が満たされなければ、そのメソッドはfalseを返します。
1.5. 未決注文の修正用シグナルのチェックメソッド
CheckTrailingOrderLong()メソッドは、買い未決注文の修正用シグナルの生成をし、新規注文を設定します。買い未決注文を修正する必要があるかを決定するためにエキスパートより呼ばれます。そのメソッドは、もし買い未決注文の修正シグナルが生成されれば、再定義されなければなりません。
virtual bool CheckTrailingOrderLong(COrderInfo* order, double& price)
そのメソッドは、買い未決注文の修正条件をチェックするアルゴリズムを実行します。もし条件が満たされれば、その変動価格は、適切な値がわりあてられ、メソッドはtrueを返さなければなりません。もし条件が満たされなければ、そのメソッドはfalseを返します。
ベースクラスCExpertSignalは、買い未決注文の修正シグナルを生成するためのアルゴリズムを持たず、ベースクラスのメソッドはfalseを返します。
CheckTrailingOrderShort()売り未決注文の修正シグナルを生成し、新規注文を設定します。売り未決注文の修正が必要かを判断するため、エキスパートより呼ばれます。そのメソッドは、もし売り未決注文のシグナルが生成されれば、再定義されなければなりません。
virtual bool CheckTrailingOrderShort(COrderInfo* order, double& price)
そのメソッドは、売り未決注文の修正条件をチェックするアルゴリズムを実行しなければなりません。もし条件が満たされれば、その変動価格は、適切な値がわりあてられ、メソッドはtrueを返さなければなりません。もし条件が満たされなければ、そのメソッドはfalseを返します。
ベースクラスCExpertSignal売り未決注文の修正シグナルを生成するためのアルゴリズムを持たず、ベースクラスのメソッドはfalseを返します。
2. 自分のトレーディングシグナルジェネレーターを開発する
CExpertSignalベースクラスの構造をチェックした次は、自分のトレーディングシグナルジェネレーターを作成し始めるkとができます。
上述の通り、CExpertSignalクラスは、パブリック型の仮想「ロープ」メソッドであり、それにより、エキスパートはトレーディングシグナルジェネレーターのある方向でのマーケット参入についての意見を知ることができます。
そのため、主要なゴールは、自分のトレーディングシグナルジェネレーターのクラスを、CExpertSignalクラスから継承し、適切な仮想メソッドをオーバーライドし、必要なアルゴリズムを実行しながら作成することです。
私たちの抱える二つ目の問題は、私たちのクラスを MQL5ウィザード.に「見える」ようにすることです。しかし、まずは一つ目から始めます。
2.1. トレーディングシグナルジェネレーターのクラスの作成
始めましょう
まず、(例えば、同じMQL5ウィザード使用し)mqh拡張のインクルードファイルを作成します。
ファイルメニューにて、「Create」を選択(か、Ctrl+N を同時に押す)し、そして、インクルードファイルの作成を指示してください。
図2MQL5ウィザードを使用してインクルードファイルを作成する
ファイルがMQL5ウィザードにシングルジェネレーターとして「発見」されるために、Include\Expert\Signal\フォルダー内に作成されなければなりません。
標準ライブラリを捨てないよう、Include\Expert\Signal\MySignalsフォルダーを作成し、SampleSignal.mqhファイルをその中に作成し、MQL5ウィザードにてこれらのパラメーターを明記します。
図3. インクルードファイルの位置を設定する
MQL5ウィザードの操作の結果、以下のパターンを持つようになります:
//+------------------------------------------------------------------+ //| SampleSignal.mqh | //| Copyright 2010, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2010, MetaQuotes Software Corp." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| defines | //+------------------------------------------------------------------+ // #define MacrosHello "Hello, world!" // #define MacrosYear 2010 //+------------------------------------------------------------------+ //| DLL imports | //+------------------------------------------------------------------+ // #import "user32.dll" // int SendMessageA(int hWnd,int Msg,int wParam,int lParam); // #import "my_expert.dll" // int ExpertRecalculate(int wParam,int lParam); // #import //+------------------------------------------------------------------+ //| EX5 imports | //+------------------------------------------------------------------+ // #import "stdlib.ex5" // string ErrorDescription(int error_code); // #import //+------------------------------------------------------------------+
以下は「手動による」作業のみです。不必要な部分を削除し、必要な(標準ライブラリのExpertSignal.mqhファイルと空のクラスの記述内容)ものを追加します。
//+------------------------------------------------------------------+ //| SampleSignal.mqh | //| Copyright 2010, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2010, MetaQuotes Software Corp." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| include files | //+------------------------------------------------------------------+ #include <Expert\ExpertSignal.mqh> //+------------------------------------------------------------------+ //| The CSampleSignal class. | //| Purpose: Class of trading signal generator. | //| It is derived from the CExpertSignal class. | //+------------------------------------------------------------------+ class CSampleSignal : public CExpertSignal { }; //+------------------------------------------------------------------+
それでは、アルゴリズムを選択する必要があります。
トレーディングシグナルジェネレーターの基礎として、普及しているモデルである「移動平均通過価格」を使用します。しかし、もう一つの想定をします。「移動平均を超えたのち、価格は戻り、右方向のみに進む」という想定です。これをファイルに反映させます。
一般的に、何かを記述している際は、コメントをたくさん使うべきです。しばらくしてコメントを呼ぶと理解の助けになります。
//+------------------------------------------------------------------+ //| SampleSignal.mqh | //| Copyright 2010, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2010, MetaQuotes Software Corp." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| include files | //+------------------------------------------------------------------+ #include <Expert\ExpertSignal.mqh> //+------------------------------------------------------------------+ //| Class CSampleSignal. | //| Purpose: Class of trading signal generator when price | //| crosses moving average, | //| entering on the subsequent back movement. | //| It is derived from the CExpertSignal class. | //+------------------------------------------------------------------+ class CSampleSignal : public CExpertSignal { }; //+------------------------------------------------------------------+
それでは、トレーディングシグナルの生成についての決定を行うために必要なデータを定義しましょう。この場合、これは、オープン価格や一つ前のバーのクローズ価格、同じバーでの移動平均値にあたります。
これらのデータへのアクセスを取得するために、標準ライブラリクラスCiOpen、CiCloseやCiMAを使用します。インジケーターやタイムシリーズはのちのち紹介します。
その間、ジェネレーターの設定リストについて設定しましょう。まずは、移動平均をセットしなければなりません。これらのパラメーターは、期間、時間軸に沿った移動、平均化メソッド、平均オブジェクトを含みます。未決注文を扱うため、二番目に、エントリーレベルや、保護的注文の発行レベル、未決注文の期間をセットする必要が有ります。
ジェネレーターの設定は、そのクラス.の保護されたデータメンバーに保存されています。その設定へのアクセスは、適切なパブリックメソッドにて実行されます。
これらの変化をファイルに加えましょう:
//+------------------------------------------------------------------+ //| SampleSignal.mqh | //| Copyright 2010, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2010, MetaQuotes Software Corp." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| include files | //+------------------------------------------------------------------+ #include <Expert\ExpertSignal.mqh> //+------------------------------------------------------------------+ //| The CSampleSignal class. | //| Purpose: Class of trading signal generator when price | //| crosses moving average, | //| entering on the subsequent back movement. | //| It is derived from the CExpertSignal class. | //+------------------------------------------------------------------+ class CSampleSignal : public CExpertSignal { protected: //--- Setup parameters int m_period_ma; // averaging period of the MA int m_shift_ma; // shift of the MA along the time axis ENUM_MA_METHOD m_method_ma; // averaging method of the MA ENUM_APPLIED_PRICE m_applied_ma; // averaging object of the MA double m_limit; // level to place a pending order relative to the MA double m_stop_loss; // level to place a stop loss order relative to the open price double m_take_profit; // level to place a take profit order relative to the open price int m_expiration; // lifetime of a pending order in bars public: //--- Methods to set the parameters void PeriodMA(int value) { m_period_ma=value; } void ShiftMA(int value) { m_shift_ma=value; } void MethodMA(ENUM_MA_METHOD value) { m_method_ma=value; } void AppliedMA(ENUM_APPLIED_PRICE value) { m_applied_ma=value; } void Limit(double value) { m_limit=value; } void StopLoss(double value) { m_stop_loss=value; } void TakeProfit(double value) { m_take_profit=value; } void Expiration(int value) { m_expiration=value; } }; //+------------------------------------------------------------------+
Since we are using protected data members, we need to add a class constructor, in which we will initialize these data by default values.
パラメーターをチェックするために、仮想メソッドValidationSettings^をベースクラスの記述に沿って、再定義しましょう。
クラスの内容:
class CSampleSignal : public CExpertSignal { protected: //--- Setup parameters int m_period_ma; // averaging period of the MA int m_shift_ma; // shift of the MA along the time axis ENUM_MA_METHOD m_method_ma; // averaging method of the MA ENUM_APPLIED_PRICE m_applied_ma; // averaging object of the MA double m_limit; // level to place a pending order relative to the MA double m_stop_loss; // level to place a stop loss order relative to the open price double m_take_profit; // level to place a take profit order relative to the open price int m_expiration; // lifetime of a pending order in bars public: CSampleSignal(); //--- Methods to set the parameters void PeriodMA(int value) { m_period_ma=value; } void ShiftMA(int value) { m_shift_ma=value; } void MethodMA(ENUM_MA_METHOD value) { m_method_ma=value; } void AppliedMA(ENUM_APPLIED_PRICE value) { m_applied_ma=value; } void Limit(double value) { m_limit=value; } void StopLoss(double value) { m_stop_loss=value; } void TakeProfit(double value) { m_take_profit=value; } void Expiration(int value) { m_expiration=value; } //--- Methods to validate the parameters virtual bool ValidationSettings(); };
ValidationSettings()メソッドの実行:
//+------------------------------------------------------------------+ //| Validation of the setup parameters. | //| INPUT: No. | //| OUTPUT: true if the settings are correct, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::ValidationSettings() { //--- Validation of parameters if(m_period_ma<=0) { printf(__FUNCTION__+": the MA period must be greater than zero"); return(false); } //--- ok return(true); } //+------------------------------------------------------------------+
それでは、準備作業が終われば、インジケーターとタイムシリーズについて詳しく紹介します。
インジケーターとタイムシリーズは、意思決定のための主要な情報源です。(コイントスを使用するか、月の状態を見ることもできます。)
すでに定義した通り、意思決定のためには、以下の情報が必要です:以前のバーのオープン価格、以前のバーのクローズ価格、そして、同じバーの移動平均値
これらのデータへアクセスするために、標準ライブラリの以下のクラスを使用します:
「なぜクラス内のインジケーターやタイムシリーズをシングル値を得るために使用するのか」と思うかもしれません。
これから明らかになる隠された意味があるのです。
インジケーターかタイムシリーズのデータの使用方法
まずは、インジケーターを作成する必要があります。
に番目に、必要な量のデータを中間バッファーへコピーする必要があります。
3番目に、コピーを完成する必要があります。
これらのステップのちに、データを使用できます。
標準ライブラリのクラスを使用し、インジケーターの作成の必要性や、中間バッファーの使用可能性やデータローディングやハンドルの解放などについて気にすることを避けます。適切なクラスのオブジェクトはそれを行ってくれます。すべての必要なインジケーターは、シグナルジェネレーターにより初期化ステージにて生成され、インジケーターは、必要な一時的バッファーに提供されます。そして、加えて、一旦インジケーターやタイムシリーズオブジェクトをコレクション内に加えると、データの関連性を気にすることをやめることができます。(データーは自動的に更新されます。)
これらのクラスのオブジェクトをデータメンバー内に配置します。それぞれのオブジェクトにおいて、初期化のメソッドやデータアクセスのメソッドを作成します。(ベースクラスの記述に沿って)仮想メソッドInitIndicators を再定義します。
クラスの内容:
class CSampleSignal : public CExpertSignal { protected: CiMA m_MA; // object to access the values om the moving average CiOpen m_open; // object to access the bar open prices CiClose m_close; // object to access the bar close prices //--- Setup parameters int m_period_ma; // averaging period of the MA int m_shift_ma; // shift of the MA along the time axis ENUM_MA_METHOD m_method_ma; // averaging method of the MA ENUM_APPLIED_PRICE m_applied_ma; // averaging object of the MA double m_limit; // level to place a pending order relative to the MA double m_stop_loss; // level to place a stop loss order relative to the open price double m_take_profit; // level to place a take profit order relative to the open price int m_expiration; // lifetime of a pending order in bars public: CSampleSignal(); //--- Methods to set the parameters void PeriodMA(int value) { m_period_ma=value; } void ShiftMA(int value) { m_shift_ma=value; } void MethodMA(ENUM_MA_METHOD value) { m_method_ma=value; } void AppliedMA(ENUM_APPLIED_PRICE value) { m_applied_ma=value; } void Limit(double value) { m_limit=value; } void StopLoss(double value) { m_stop_loss=value; } void TakeProfit(double value) { m_take_profit=value; } void Expiration(int value) { m_expiration=value; } //--- Method to validate the parameters virtual bool ValidationSettings(); //--- Method to validate the parameters virtual bool InitIndicators(CIndicators* indicators); protected: //--- Object initialization method bool InitMA(CIndicators* indicators); bool InitOpen(CIndicators* indicators); bool InitClose(CIndicators* indicators); //--- Methods to access object data double MA(int index) { return(m_MA.Main(index)); } double Open(int index) { return(m_open.GetData(index)); } double Close(int index) { return(m_close.GetData(index)); } };
InitIndicators、InitMA、InitOpen、InitCloseの実行:
//+------------------------------------------------------------------+ //| Initialization of indicators and timeseries. | //| INPUT: indicators - pointer to the object - collection of | //| indicators and timeseries. | //| OUTPUT: true in case of success, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::InitIndicators(CIndicators* indicators) { //--- Validation of the pointer if(indicators==NULL) return(false); //--- Initialization of the moving average if(!InitMA(indicators)) return(false); //--- Initialization of the timeseries of open prices if(!InitOpen(indicators)) return(false); //--- Initialization of the timeseries of close prices if(!InitClose(indicators)) return(false); //--- Successful completion return(true); } //+------------------------------------------------------------------+ //| Initialization of the moving average | //| INPUT: indicators - pointer to the object - collection of | //| indicators and timeseries. | //| OUTPUT: true in case of success, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::InitMA(CIndicators* indicators) { //--- Initialization of the MA object if(!m_MA.Create(m_symbol.Name(),m_period,m_period_ma,m_shift_ma,m_method_ma,m_applied_ma)) { printf(__FUNCTION__+": object initialization error"); return(false); } m_MA.BufferResize(3+m_shift_ma); //--- Adding an object to the collection if(!indicators.Add(GetPointer(m_MA))) { printf(__FUNCTION__+": object adding error"); return(false); } //--- Successful completion return(true); } //+------------------------------------------------------------------+ //| Initialization of the timeseries of open prices. | //| INPUT: indicators - pointer to the object - collection of | //| indicators and timeseries. | //| OUTPUT: true in case of success, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::InitOpen(CIndicators* indicators) { //--- Initialization of the timeseries object if(!m_open.Create(m_symbol.Name(),m_period)) { printf(__FUNCTION__+": object initialization error"); return(false); } //--- Adding an object to the collection if(!indicators.Add(GetPointer(m_open))) { printf(__FUNCTION__+": object adding error"); return(false); } //--- Successful completion return(true); } //+------------------------------------------------------------------+ //| Initialization of the timeseries of close prices. | //| INPUT: indicators - pointer to the object - collection of | //| indicators and timeseries. | //| OUTPUT: true in case of success, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::InitClose(CIndicators* indicators) { //--- Initialization of the timeseries object if(!m_close.Create(m_symbol.Name(),m_period)) { printf(__FUNCTION__+": object initialization error"); return(false); } //--- Adding an object to the collection if(!indicators.Add(GetPointer(m_close))) { printf(__FUNCTION__+": object adding error"); return(false); } //--- Successful completion return(true); } //+------------------------------------------------------------------+
すべての準備作業が終了しました。ご覧の通り、クラスが著しく大きくなりました。
そして、トレーディングクラスの生成の準備ができました。
図4. 移動平均をクロスする価格のためのトレーディングシグナル
より詳細にもう一度アルゴリズムを見てみましょう。
1. 買いシグナルは、一つ手間のバーにて以下の条件が満たされ際に現れます。
- バーのオープン価格は移動平均値より小さい.
- バーのクローズ価格は、移動平均値より大きい.
- 移動平均が上昇している.
この場合、設定されたパラメーターでの買い未決注文をセットすることになります。この目的のために、CheckOpenLong仮想メソッドをオーバーライドし、一致する機能で満たします。
2. 一つ前のバーにて以下の条件が満たされ際に売りシグナルが現れます。
- バーのオープン価格が移動平均値より大きい.
- バーのクローズ価格が非道平均値より小さい.
- 移動平均値が減少している.
この場合、設定したパラメーターにて売り未決注文を配置します。この目的のために、CheckOpenShort仮想メソッドを再定義し、そして、一致する機能で満たします。
3. ポジションをクローズするためにシグナルを生成しません。ストップロス・利取りордерам.によりポジションはクローズさせます。
それに従って、CheckCloseLongやCheckCloseShort仮想メソッドはオーバーライドしません。
4. 未決注文の修正を設定により明記されている「距離」の移動平均に沿って行います。
この目的のために、仮想メソッドCheckTrailingOrderLongやCheckTrailingOrderShortオーバーライドし、一致する機能で満たします。
クラスの内容:
class CSampleSignal : public CExpertSignal { protected: CiMA m_MA; // object to access the values of the moving average CiOpen m_open; // object to access the bar open prices CiClose m_close; // object to access the bar close prices //--- Setup parameters int m_period_ma; // averaging period of the MA int m_shift_ma; // shift of the MA along the time axis ENUM_MA_METHOD m_method_ma; // averaging method of the MA ENUM_APPLIED_PRICE m_applied_ma; // averaging object of the MA double m_limit; // level to place a pending order relative to the MA double m_stop_loss; // level to place a stop loss order relative to the open price double m_take_profit; // level to place a take profit order relative to the open price int m_expiration; // lifetime of a pending order in bars public: CSampleSignal(); //--- Methods to set the parameters void PeriodMA(int value) { m_period_ma=value; } void ShiftMA(int value) { m_shift_ma=value; } void MethodMA(ENUM_MA_METHOD value) { m_method_ma=value; } void AppliedMA(ENUM_APPLIED_PRICE value) { m_applied_ma=value; } void Limit(double value) { m_limit=value; } void StopLoss(double value) { m_stop_loss=value; } void TakeProfit(double value) { m_take_profit=value; } void Expiration(int value) { m_expiration=value; } //--- Method to validate the parameters virtual bool ValidationSettings(); //--- Method to validate the parameters virtual bool InitIndicators(CIndicators* indicators); //--- Methods to generate signals to enter the market virtual bool CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration); virtual bool CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration); //--- Methods to generate signals of pending order modification virtual bool CheckTrailingOrderLong(COrderInfo* order,double& price); virtual bool CheckTrailingOrderShort(COrderInfo* order,double& price); protected: //--- Object initialization method bool InitMA(CIndicators* indicators); bool InitOpen(CIndicators* indicators); bool InitClose(CIndicators* indicators); //--- Methods to access object data double MA(int index) { return(m_MA.Main(index)); } double Open(int index) { return(m_open.GetData(index)); } double Close(int index) { return(m_close.GetData(index)); } };
CheckOpenLong、CheckOpenShort、CheckTrailingOrderLong、CheckTrailingOrderShortメソッドの実行:
//+------------------------------------------------------------------+ //| Check whether a Buy condition is fulfilled | //| INPUT: price - variable for open price | //| sl - variable for stop loss price, | //| tp - variable for take profit price | //| expiration - variable for expiration time. | //| OUTPUT: true if the condition is fulfilled, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration) { //--- Preparing the data double spread=m_symbol.Ask()-m_symbol.Bid(); double ma =MA(1); double unit =PriceLevelUnit(); //--- Checking the condition if(Open(1)<ma && Close(1)>ma && ma>MA(2)) { price=m_symbol.NormalizePrice(ma-m_limit*unit+spread); sl =m_symbol.NormalizePrice(price-m_stop_loss*unit); tp =m_symbol.NormalizePrice(price+m_take_profit*unit); expiration+=m_expiration*PeriodSeconds(m_period); //--- Condition is fulfilled return(true); } //--- Condition is not fulfilled return(false); } //+------------------------------------------------------------------+ //| Check whether a Sell condition is fulfilled. | //| INPUT: price - variable for open price, | //| sl - variable for stop loss, | //| tp - variable for take profit | //| expiration - variable for expiration time. | //| OUTPUT: true if the condition is fulfilled, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration) { //--- Preparing the data double ma =MA(1); double unit=PriceLevelUnit(); //--- Checking the condition if(Open(1)>ma && Close(1)<ma && ma<MA(2)) { price=m_symbol.NormalizePrice(ma+m_limit*unit); sl =m_symbol.NormalizePrice(price+m_stop_loss*unit); tp =m_symbol.NormalizePrice(price-m_take_profit*unit); expiration+=m_expiration*PeriodSeconds(m_period); //--- Condition is fulfilled return(true); } //--- Condition is not fulfilled return(false); } //+------------------------------------------------------------------+ //| Check whether the condition of modification | //| of a Buy order is fulfilled. | //| INPUT: order - pointer at the object-order, | //| price - a variable for the new open price. | //| OUTPUT: true if the condition is fulfilled, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::CheckTrailingOrderLong(COrderInfo* order,double& price) { //--- Checking the pointer if(order==NULL) return(false); //--- Preparing the data double spread =m_symbol.Ask()-m_symbol.Bid(); double ma =MA(1); double unit =PriceLevelUnit(); double new_price=m_symbol.NormalizePrice(ma-m_limit*unit+spread); //--- Checking the condition if(order.PriceOpen()==new_price) return(false); price=new_price; //--- Condition is fulfilled return(true); } //+------------------------------------------------------------------+ //| Check whether the condition of modification | //| of a Sell order is fulfilled. | //| INPUT: order - pointer at the object-order, | //| price - a variable for the new open price. | //| OUTPUT: true if the condition is fulfilled, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::CheckTrailingOrderShort(COrderInfo* order,double& price) { //--- Checking the pointer if(order==NULL) return(false); //--- Preparing the data double ma =MA(1); double unit=PriceLevelUnit(); double new_price=m_symbol.NormalizePrice(ma+m_limit*unit); //--- Checking the condition if(order.PriceOpen()==new_price) return(false); price=new_price; //--- Condition is fulfilled return(true); } //+------------------------------------------------------------------+
最初の問題を解決し終えました。上記のコードは、メインの作業を満たすトレーディングシグナルジェネレーターのクラスソースコードになります。
2.2. MQL5ウィザードにおいてのトレーディングシグナルの作成したクラスの記述の準備
それでは二番目の問題の解決にあたります。私たちのシグナルは、MQL5ウィザードのトレーディング戦略ジェネレーターにより「認識」されなければなりません。
最初の必要な条件を満たしました:MQL5ウィザードによって「発見」されうる場所にファイルを配置することです。しかし、これだけでは十分ではありません。MQL5ウィザードは、ファイルを「発見」するだけではなく「認識」しなければなりません。このために、 MQL5ウィザードのため、原文テキストにクラス記述子 を追加しなければなりません。
クラス記述子は、あるルールに沿って成り立つコメントのブロックです。
それではこれらのルールを見てみましょう。
1. コメントのブロックは以下の文章で始まります。
// wizard description start //+------------------------------------------------------------------+ //| Description of the class |
2. 次の行は、「//| Title=<Text> |」のフォーマットでのテキスト記述子です。(これはシグナルを選ぶ際にMQL5ウィザードにて見ます。)もしテキストが一行では大きすぎれば、もう一行追加可能です。
以下のような形になります。
//| Title=Signal on the crossing of a price and the MA | //| entering on its back movement |
3. 「//| Type=<Type> |」という形式で明記されたクラス型の行が次にきます。<Type> フィールドは、Signal値を持っている必要があります(加えて、MQL5ウィザードは他のクラスの種類を知っています。)
Write:
//| Type=Signal |
4. 「//| Name=<Name> |」のフォーマットでの以下の行は、シグナルの短い名前です。(MQL5ウィザードによってエキスパートのグローバル変数名の生成のために使用されます。)
以下のようになります:
//| Name=Sample |
5. クラス名は重要な要素です。「//| Class=<ClassNameа> |」というフォーマットの一行にて、<ClassName>パラメーターは我々のクラス名と合致する必要があります:
//| Class=CSampleSignal |
6. この行を満たしませんが、存在している必要があります。(これは、言語リファレンスセクションへのリンクです):
//| Page= |
7. さらに、シグナル設定パラメーターの詳細です。
これは一つの列の塊です。(列数は、パラメーター数に等しいです。)
それぞれの行のフォーマットは「//| Parameter=<NameOfMethod>,<TypeOfParameter>,<DefaultValue> |」です。
こちらがパラメーターになります。
//| Parameter=PeriodMA,int,12 | //| Parameter=ShiftMA,int,0 | //| Parameter=MethodMA,ENUM_MA_METHOD,MODE_EMA | //| Parameter=AppliedMA,ENUM_APPLIED_PRICE,PRICE_CLOSE | //| Parameter=Limit,double,0.0 | //| Parameter=StopLoss,double,50.0 | //| Parameter=TakeProfit,double,50.0 | //| Parameter=Expiration,int,10 |
8. コメントブロックは、以下の行で終える必要があります:
//+------------------------------------------------------------------+ // wizard description end
ソースコードが記述子を追加しましょう。
//+------------------------------------------------------------------+ //| SampleSignal.mqh | //| Copyright 2010, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2010, MetaQuotes Software Corp." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| include files | //+------------------------------------------------------------------+ #include <Expert\ExpertSignal.mqh> // wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=Signal on crossing of the price and the MA | //| entering on the back movement | //| Type=Signal | //| Name=Sample | //| Class=CSampleSignal | //| Page= | //| Parameter=PeriodMA,int,12 | //| Parameter=ShiftMA,int,0 | //| Parameter=MethodMA,ENUM_MA_METHOD,MODE_EMA | //| Parameter=AppliedMA,ENUM_APPLIED_PRICE,PRICE_CLOSE | //| Parameter=Limit,double,0.0 | //| Parameter=StopLoss,double,50.0 | //| Parameter=TakeProfit,double,50.0 | //| Parameter=Expiration,int,10 | //+------------------------------------------------------------------+ // wizard description end //+------------------------------------------------------------------+ //| CSampleSignal class. | //| Purpose: Class of trading signal generator when price | //| crosses moving average, | //| entering on the subsequent back movement. | //| It is derived from the CExpertSignal class. | //+------------------------------------------------------------------+ class CSampleSignal : public CExpertSignal { protected: CiMA m_MA; // object to access the values of the moving average CiOpen m_open; // object to access the bar open prices CiClose m_close; // object to access the bar close prices //--- Setup parameters int m_period_ma; // averaging period of the MA int m_shift_ma; // shift of the MA along the time axis ENUM_MA_METHOD m_method_ma; // averaging method of the MA ENUM_APPLIED_PRICE m_applied_ma; // averaging object of the MA double m_limit; // level to place a pending order relative to the MA double m_stop_loss; // level to place a stop loss order relative to the open price double m_take_profit; // level to place a take profit order relative to the open price int m_expiration; // lifetime of a pending order in bars public: CSampleSignal(); //--- Methods to set the parameters void PeriodMA(int value) { m_period_ma=value; } void ShiftMA(int value) { m_shift_ma=value; } void MethodMA(ENUM_MA_METHOD value) { m_method_ma=value; } void AppliedMA(ENUM_APPLIED_PRICE value) { m_applied_ma=value; } void Limit(double value) { m_limit=value; } void StopLoss(double value) { m_stop_loss=value; } void TakeProfit(double value) { m_take_profit=value; } void Expiration(int value) { m_expiration=value; } //---Method to validate the parameters virtual bool ValidationSettings(); //--- Method to validate the parameters virtual bool InitIndicators(CIndicators* indicators); //--- Methods to generate signals to enter the market virtual bool CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration); virtual bool CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration); //--- Methods to generate signals of pending order modification virtual bool CheckTrailingOrderLong(COrderInfo* order,double& price); virtual bool CheckTrailingOrderShort(COrderInfo* order,double& price); protected: //--- Object initialization method bool InitMA(CIndicators* indicators); bool InitOpen(CIndicators* indicators); bool InitClose(CIndicators* indicators); //--- Methods to access object data double MA(int index) { return(m_MA.Main(index)); } double Open(int index) { return(m_open.GetData(index)); } double Close(int index) { return(m_close.GetData(index)); } }; //+------------------------------------------------------------------+ //| CSampleSignal Constructor. | //| INPUT: No. | //| OUTPUT: No. | //| REMARK: No. | //+------------------------------------------------------------------+ void CSampleSignal::CSampleSignal() { //--- Setting the default values m_period_ma =12; m_shift_ma =0; m_method_ma =MODE_EMA; m_applied_ma =PRICE_CLOSE; m_limit =0.0; m_stop_loss =50.0; m_take_profit=50.0; m_expiration =10; } //+------------------------------------------------------------------+ //| Validation of parameters. | //| INPUT: No. | //| OUTPUT: true if the settings are correct, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::ValidationSettings() { //--- Validation of parameters if(m_period_ma<=0) { printf(__FUNCTION__+": the MA period must be greater than zero"); return(false); } //--- Successful completion return(true); } //+------------------------------------------------------------------+ //| Initialization of indicators and timeseries. | //| INPUT: indicators - pointer to the object - collection of | //| indicators and timeseries. | //| OUTPUT: true in case of success, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::InitIndicators(CIndicators* indicators) { //--- Validation of the pointer if(indicators==NULL) return(false); //--- Initialization of the moving average if(!InitMA(indicators)) return(false); //--- Initialization of the timeseries of open prices if(!InitOpen(indicators)) return(false); //--- Initialization of the timeseries of close prices if(!InitClose(indicators)) return(false); //--- Successful completion return(true); } //+------------------------------------------------------------------+ //| Initialization of the moving average | //| INPUT: indicators - pointer to the object - collection of | //| indicators and timeseries. | //| OUTPUT: true in case of success, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::InitMA(CIndicators* indicators) { //--- Initialization of the MA object if(!m_MA.Create(m_symbol.Name(),m_period,m_period_ma,m_shift_ma,m_method_ma,m_applied_ma)) { printf(__FUNCTION__+": object initialization error"); return(false); } m_MA.BufferResize(3+m_shift_ma); //--- Adding an object to the collection if(!indicators.Add(GetPointer(m_MA))) { printf(__FUNCTION__+": object adding error"); return(false); } //--- Successful completion return(true); } //+------------------------------------------------------------------+ //| Initialization of the timeseries of open prices. | //| INPUT: indicators - pointer to the object - collection of | //| indicators and timeseries. | //| OUTPUT: true in case of success, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::InitOpen(CIndicators* indicators) { //--- Initialization of the timeseries object if(!m_open.Create(m_symbol.Name(),m_period)) { printf(__FUNCTION__+": object initialization error"); return(false); } //--- Adding an object to the collection if(!indicators.Add(GetPointer(m_open))) { printf(__FUNCTION__+": object adding error"); return(false); } //--- Successful completion return(true); } //+------------------------------------------------------------------+ //| Initialization of the timeseries of close prices. | //| INPUT: indicators - pointer to the object - collection of | //| indicators and timeseries. | //| OUTPUT: true in case of success, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::InitClose(CIndicators* indicators) { //--- Initialization of the timeseries object if(!m_close.Create(m_symbol.Name(),m_period)) { printf(__FUNCTION__+": object initialization error"); return(false); } //--- Adding an object to the collection if(!indicators.Add(GetPointer(m_close))) { printf(__FUNCTION__+": object adding error"); return(false); } //--- Successful completion return(true); } //+------------------------------------------------------------------+ //| Check whether a Buy condition is fulfilled | //| INPUT: price - variable for open price | //| sl - variable for stop loss price, | //| tp - variable for take profit price | //| expiration - variable for expiration time. | //| OUTPUT: true if the condition is fulfilled, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration) { //--- Preparing the data double spread=m_symbol.Ask()-m_symbol.Bid(); double ma =MA(1); double unit =PriceLevelUnit(); //--- Checking the condition if(Open(1)<ma && Close(1)>ma && ma>MA(2)) { price=m_symbol.NormalizePrice(ma-m_limit*unit+spread); sl =m_symbol.NormalizePrice(price-m_stop_loss*unit); tp =m_symbol.NormalizePrice(price+m_take_profit*unit); expiration+=m_expiration*PeriodSeconds(m_period); //--- Condition is fulfilled return(true); } //--- Condition is not fulfilled return(false); } //+------------------------------------------------------------------+ //| Check whether a Sell condition is fulfilled. | //| INPUT: price - variable for open price, | //| sl - variable for stop loss, | //| tp - variable for take profit | //| expiration - variable for expiration time. | //| OUTPUT: true if the condition is fulfilled, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration) { //--- Preparing the data double ma =MA(1); double unit=PriceLevelUnit(); //--- Checking the condition if(Open(1)>ma && Close(1)<ma && ma<MA(2)) { price=m_symbol.NormalizePrice(ma+m_limit*unit); sl =m_symbol.NormalizePrice(price+m_stop_loss*unit); tp =m_symbol.NormalizePrice(price-m_take_profit*unit); expiration+=m_expiration*PeriodSeconds(m_period); //--- Condition is fulfilled return(true); } //--- Condition is not fulfilled return(false); } //+------------------------------------------------------------------+ //| Check whether the condition of modification | //| of a Buy order is fulfilled. | //| INPUT: order - pointer at the object-order, | //| price - a variable for the new open price. | //| OUTPUT: true if the condition is fulfilled, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::CheckTrailingOrderLong(COrderInfo* order,double& price) { //--- Checking the pointer if(order==NULL) return(false); //--- Preparing the data double spread =m_symbol.Ask()-m_symbol.Bid(); double ma =MA(1); double unit =PriceLevelUnit(); double new_price=m_symbol.NormalizePrice(ma-m_limit*unit+spread); //--- Checking the condition if(order.PriceOpen()==new_price) return(false); price=new_price; //--- Condition is fulfilled return(true); } //+------------------------------------------------------------------+ //| Check whether the condition of modification | //| of a Sell order is fulfilled. | //| INPUT: order - pointer at the object-order, | //| price - a variable for the new open price. | //| OUTPUT: true if the condition is fulfilled, otherwise false. | //| REMARK: No. | //+------------------------------------------------------------------+ bool CSampleSignal::CheckTrailingOrderShort(COrderInfo* order,double& price) { //--- Checking the pointer if(order==NULL) return(false); //--- Preparing the data double ma =MA(1); double unit=PriceLevelUnit(); double new_price=m_symbol.NormalizePrice(ma+m_limit*unit); //--- Checking the condition if(order.PriceOpen()==new_price) return(false); price=new_price; //--- Condition is fulfilled return(true); } //+------------------------------------------------------------------+
これで終了です。そのシグナルは、使用できるようになっています。
MQL5ウィザード トレーディング用戦略ジェネレーターがシグナルを使用できるように、 MetaEditorを再起動しなければいけません。 (MQL5ウィザードは、Include\Expertのフォルダーをスキャンします).
MetaEditor再起動後、トレーディングシグナルの作成したモジュールはMQL5ウィザードにて使用されます:
図5. MQL5ウィザードの作成したトレーディングシグナル用ジェネレーター
トレーディングシグナル用ジェネレーターのパラメーターの詳細にて明記されている入力パラメーターは使用可能です:
図6. MQL5ウィザードにて作成したトレーディングシグナル用ジェネレーターの入力パラメーター
実行されたトレーディング戦略の入力パラメーターの最適な値は MetaTrader 5ターミナルのストラテジーテスターにて見つけることができます。
結論
MQL5ウィザードのトレーディングストラテジーのジェネレター は取引アイディアのテストを大いに簡潔化します。生成さえれたコードは、標準ライブラリのトレーディング戦略のクラスに基づいており、それは、資金・リスク管理用クラス、ポジションサポートクラス、トレーディングシグナルクラスの作成に使用されます。
この記事は、どのように価格や移動平均のクロス時におけるシグナルの実行とトレーディングシグナルのクラスの作成を行うか、それを MQL5ウィザードのトレーディングストラテジージェネレターに挿入するかについて、また、MQL5ウィザードの生成されたクラスの記述用フォーマットやストラクチャーを紹介します。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/226
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索