
MQL5 ウィザード:リスクおよび資金管理モジュール作成方法
はじめに
MetaTrader 5 は様々なトレーディングの考えを確認することができるようになる力強いツールを提供してくれます。これは既製のトレーディング戦略に基づく MQL5 ウィザード を用いたExpert Advisorsの世代です。
MQL5 ウィザードを用いて作成されるExpert Advisorは4本の柱の上に成り立っています。すなわち4つの 基本クラスです。
図1 基本クラスCExpert のストラクチャ
- CExpert クラス(またはその派生クラス)はExpert Advisorの主要な『駆動部』です。CExpert のインスタンスには各クラスのコピーが一部含まれます。そのクラスというのは CExpertSignal、 CExpertMoney 、 CExpertTrailing(またはその派生クラス)です。
- CExpertSignal はトレーディングシグナル生成の基本となるものです。CExpertにインクルードされる派生クラス CExpertSignal のインスタンスは Expert Advisor に対し、内蔵アルゴリズムに基づくマーケット参加可能性に関する情報、開始レベル、逆指し値注文のセットを行います。Expert Advisor がマーケット参加可否を判断するのです。CExpertSignal クラスについての詳細および連携に関して『MQL5 ウィザード:トレーディングシグナルのモジュール作成方法』稿に記載があります。
- CExpertMoney クラスはリスクおよび資金管理メカニズムの基本です。CExpertにインクルードされる派生クラス CExpertMoney のインスタンスは Expert Advisor に対し、内蔵アルゴリズムに基づくポジションをオープンするのに可能なボリューム情報、未決注文のセットを行います。Expert Advisor がボリュームに関する判断をするのです。
- CExpertTrailing クラスはオープンポジションメカニズムの基本です。CExpertにインクルードされる派生クラス CExpertTrailing のインスタンスは Expert Advisor に対し、内蔵アルゴリズムに基づくポジションの逆指し値注文の変更可能性に関する情報を提供します。Expert Advisor が注文変更に関する判断をするのです。CExpertTrailing クラスについての詳細および連携に関しては別記事に記載があります。
また CExpert クラスのメンバは以下のクラスのインスタンスとなっています。
- CExpertTrade (for trading)
- CIndicators (EA動作に関わるインディケータおよび時系列の管理を行います。)
- CSymbolInfo (インスツルメントに関する情報を取得します。)
- CAccountInfo (トレーディングアカウント状況についての情報を取得します。)
- CPositionInfo (ポジションに関する情報を取得します。)
- COrderInfo (未決注文に関する情報を取得します。)
以下、"expert"とは CExpert またはその派生クラスを意味します。
CExpertクラスについての詳細および連携に関しては別記事に記載があります。
1. 基本クラスCExpertMoney
上述sのように CExpertMoney クラスはリスクおよび資金管理メカニズムの基本となっています。「外界」と通信するために、CExpertMoney クラスはパブリックな仮想メソッドを備えています。
初期化 | 内容 |
仮想 Init | クラスインスタンスの初期化により、EAデータとモジュールデータの同期が可能となります。 |
パーセント | 「リスク割合」パラメータ値の設定 |
仮想 ValidationSettings | 設定パラメータの有効化 |
仮想 InitIndicators | リスクおよび資金管理メカニズム開始に対して要求されるすべてのインディケータと時系列の作成と初期化 |
ポジションのオープン/転換/クローズの必要性を確認するためのメソッド | |
仮想 CheckOpenLong | ロングポジションをオープンするボリューム決定 |
仮想 CheckOpenShort | ショートポジションをオープンするボリューム決定 |
仮想 CheckReverse | ポジションをリバースするボリューム決定 |
仮想 CheckClose | ポジションをクローズする必要性判断 |
メソッド内容
1.1. 初期化メソッド
expertにクラスインスタンスが追加される直後 自動で Init() メソッドが呼ばれます。メソッドのオーバーライドは要求されません。
virtual bool Init(CSymbolInfo* symbol, ENUM_TIMEFRAMES period, double adjusted_point);
Percent() メソッドは適切なパラメータを構成するのに呼ばれます。その値は包括的な 0.0 ~ 100.0です。初期設定値は 100.0です。メソッドのオーバーライドは要求されません。
void Percent(double percent);
ValidationSettings() メソッドはすべてのパラメータが設定された後 expertから直接 呼ばれます。他に設定パラメータがある場合は、このメソッドのオーバーライドが必要です。
virtual bool ValidationSettings();
オーバーライドされたメソッドは全ポジションが有効(使用可)であれば trueを返します。パラメータに一つでも誤りがあると false (以後の作業は不可)を返します。オーバーライドされたメソッドは結果をチェックし基本クラスメソッドを呼ぶ必要があります。
InitIndicators() メソッドは、必要なインディケータと時系列を作成し実装します。それはすべてのパラメータが設定され、正確性が確認された後 expertから呼ばれます。このメソッドはリスクおよび資金管理メカニズムが少なくとも1つのインディケータまたは時系列を使用するとオーバーライドされる必要があります。
virtual bool InitIndicators(CIndicators* indicators);
インディケータおよび/または時系列は Standard Libraryの適切なクラスによって使用されます。全インディケータおよび/または時系列のポインターは expert (パラメータとして渡される先のポインター)のインディケータ集積に追加される必要があります。
オーバーライドされたメソッドは全インディケータおよび/または時系列の操作に問題がなければ(使用に適しているなら)trueを返します。インディケータおよび/または時系列処理にひとつで失敗するとこのメソッドは false (以後の作業は不可)を返します。
1.2. ポジションのボリュームを決定するメソッド
CheckOpenLong() メソッドはロングポジションをオープンするボリュームを計算します。ロングポジションをオープンするボリュームを判断するようexperによって呼ばれます。基本クラスに実装されているものと別のアルゴリズムを用いてロングポジションをオープンするボリュームを計算しようとするなら、このメソッドはオーバーライドされる必要があります。
\virtual double CheckOpenLong(double price, double sl);
このメソッドはロングポジションをオープンするボリュームを計算するためのアルゴリズムを導入する必要があります。そしてメソッドは計算されたボリュームを返します。
CheckOpenShort() メソッドはショートポジションをオープンするボリュームを計算します。ショートポジションをオープンするボリュームを判断するようexperによって呼ばれます。基本クラスに実装されているものと別のアルゴリズムを用いてショートポジションをオープンするボリュームを計算しようとするなら、このメソッドはオーバーライドされる必要があります。
virtual double CheckOpenShort(double price, double sl);
このメソッドはショートポジションをオープンするボリュームを計算するためのアルゴリズムを導入する必要があります。そしてメソッドは計算されたボリュームを返します。
CheckReverse() メソッドはポジションをリバースするボリュームを計算します。このメソッドはポジションをリバースするためのトレードポジションボリュームを判断するようexperによって呼ばれます。基本クラスに実装されているものと別のアルゴリズムを用いてポジションをリバースするボリュームを計算しようとするなら、このメソッドはオーバーライドされる必要があります。
virtual double CheckReverse(CPositionInfo* position, double sl);
このメソッドはポジションをリバースするボリュームを計算するためのアルゴリズムを導入する必要があります。それはpositionポインターによって取得可能な情報です。そしてメソッドは計算されたリバースするポジションボリュームを返します。
CheckClose() メソッドはポジションをクローズする必要があるかどうか確認します。(資金管理とリスク管理に関して)ポジションをクローズする必要があるか判断するのにexperによって呼ばれます。基本クラスに実装されているものと別のアルゴリズムを用いてポジションをクローズするなら、このメソッドはオーバーライドされる必要があります。(たとえば部分的クローズ)
virtual double CheckClose(CPositionInfo* position);
このメソッドはポジションをクローズする必要性を明確にするためのアルゴリズムを導入する必要があります。それはポインターによって取得可能な情報です。そしてメソッドは計算されたクローズするポジションボリュームを返します。
2. 資金およびリスク管理のメカニズム作成
基本クラス CExpertMoney のストラクチャの見直しをしたところで、独自のリスクおよび資金管理メカニズムを作成することが可能です。以下、リスクおよび資金管理メカニズムを「マネー・マネージャ」と称します。
前述のようにCExpertMoney クラスはパブリックな仮想「ロープ」のセットです。それを使用することでexpert はいずれの方向でもマーケットに参加するボリュームに関するマネー・マネージャの意向を知りうるのです。
ここでの最初の目標はCExpertMoney クラスから派生する適切な仮想メソッドをオーバーライドし、要求されるアルゴリズムを導入して独自のマネー・マネージャを作成することです。
二番目の課題(これはそれほど重要ではありませんが)は、作成するクラスをMQL5 ウィザードに対して可視化することです。まず、重要な件からとりかかります。
2.1. トレーディングシグナルを生成するクラスの作成
では始めます。
最初に、(たとえば同じ MQL5 ウィザード を使用して)拡張子 mqh を伴うインクルードファイルを作成します。
ファイルメニューで『作成』を選択(またはキーを組み合わせてCtrl+N を押します。)し、インクルードファイル作成を指示します。
図2 MQL5 ウィザードを用いたインクルードファイルの作成
MQL5 ウィザードをマネー・マネージャとして用い、ファイルを『検出』にするには、フォルダ Include\Expert内に作成する必要があります。
標準ライブラリで廃棄しないためには、独自のファイルInclude\Expert\Money\MyMoneysを作成し、その中にファイルSampleMoney.mqh を作成し、MQL5ウィザードでこれらパラメータを指定します。
図3 インクルードファイルの位置設定
MQL5 ウィザード 処理の結果、以下のパターンを取得します。
//+------------------------------------------------------------------+ //| SampleMoney.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 //+------------------------------------------------------------------+
以下は「マニュアル」作業のみです。不要な部分は消去し、要求される部分、すなわち空のクラス記述のある 標準ライブラリ のインクルードファイルExpertMoney.mqhを追加します。
//+------------------------------------------------------------------+ //| SampleMoney.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\ExpertMoney.mqh> //+------------------------------------------------------------------+ //| Class CSampleMoney. | //| Purpose: Class for risk and money management. | //| It is derived from the CExpertMoney class. | //+------------------------------------------------------------------+ class CSampleMoney : public CExpertMoney { }; //+------------------------------------------------------------------+
そして必要なのは、アルゴリズムの選択です。
マネー・マネージャの基本として、以下のアルゴリズムを取ります。「通常」条件では、固定的にあらかじめ定められた取引きボリュームが提案されます。ただし、前回のポジションが損失を伴ってクローズしている場合は、二倍のボリュームでポジションをオープンするのがよいでしょう。
これをファイルに反映します。
//+------------------------------------------------------------------+ //| SampleMoney.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\ExpertMoney.mqh> //+------------------------------------------------------------------+ //| Class CSampleMoney. | //| Purpose: Class for risk and money management | //| doubling the volume after a loss deal. | //| It is derived from the CExpertMoney class. | //+------------------------------------------------------------------+ class CSampleMoney : public CExpertMoney { }; //+------------------------------------------------------------------+
われわれのネー・マネージャ用設定リスト定義実際リストはありません。すべての設定は「通常」条件でのトランザクションボリュームを決定する単一パラメータに含まれています。
パラメータはクラスの保護されたデータメンバに格納されます。パラメータへのアクセスは適切なパブリックメソッドによって実装されます。クラスのコンストラクタでは、パラメータはデフォルト値によって初期化されます。パラメータチェックには、基本クラスの記述に従い、仮想メソッド ValidationSettings をオーバーライドします。
われわれのファイルでこれをインクルードします。
//+------------------------------------------------------------------+ //| SampleMoney.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\ExpertMoney.mqh> //+------------------------------------------------------------------+ //| Class CSampleMoney. | //| Purpose: Class for risk and money management | //| doubling the volume after a loss deal. | //| It is derived from the CExpertMoney class. | //+------------------------------------------------------------------+ class CSampleMoney : public CExpertMoney { protected: //--- setup parameters double m_lots; // deal volume for "normal" conditions public: CSampleMoney(); //--- methods to set the parameters void Lots(double lots) { m_lots=lots; } }; //+------------------------------------------------------------------+ //| Constructor CSampleMoney. | //| INPUT: no. | //| OUTPUT: no. | //| REMARK: no. | //+------------------------------------------------------------------+ void CSampleMoney::CSampleMoney() { //--- setting the default values m_lots=0.1; } //+------------------------------------------------------------------+
別に ValidationSettings() メソッドの実装方法を考えます。重要なことは、基本クラスがすでに構成パラメータをひとつ有していることで、これはまた検証を要求します。
ValidationSettings() メソッドの実装
//+------------------------------------------------------------------+ //| Validation of the setup parameters. | //| INPUT: no. | //| OUTPUT: true if the settings are correct, otherwise false. | //| REMARK: no. | //+------------------------------------------------------------------+ bool CSampleMoney::ValidationSettings() { //--- Call the base class method if(!CExpertMoney::ValidationSettings()) return(false); //--- Validation of parameters if(m_lots<m_symbol.LotsMin() || m_lots>m_symbol.LotsMax()) { printf(__FUNCTION__+": the deal volume must be in the range %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax()); return(false); } if(MathAbs(m_lots/m_symbol.LotsStep()-MathRound(m_lots/m_symbol.LotsStep()))>1.0E-10) { printf(__FUNCTION__+": the volume of the deal must be multiple of %f",m_symbol.LotsStep()); return(false); } //--- Successful completion return(true); }
設定はできました。ここからマネー・マネージャの処理に進んでいきます。前回取引が損失を招いたか判断し、必要であれば損失ボリュームを明確にするメソッドが必要です。クラス記述でそれを宣言します。
class CSampleMoney : public CExpertMoney { protected: //--- Setup parameters double m_lots; // deal volume for "normal" conditions public: CSampleMoney(); //--- Methods to set parameters void Lots(double lots) { m_lots=lots; } //--- Methods to validate parameters virtual bool ValidationSettings(); protected: double CheckPrevLoss(); };
メソッドの実装
//+------------------------------------------------------------------+ //| Defines whether the prev. deal was losing. | //| INPUT: no. | //| OUTPUT: volume of the prev. deal if it's losing, otherwise 0.0 | //| REMARK: no. | //+------------------------------------------------------------------+ double CSampleMoney::CheckPrevLoss() { double lot=0.0; //--- Request the history of deals and orders HistorySelect(0,TimeCurrent()); //--- variables int deals=HistoryDealsTotal(); // Total number of deals in the history CDealInfo deal; //--- Find the previous deal for(int i=deals-1;i>=0;i--) { if(!deal.SelectByIndex(i)) { printf(__FUNCTION__+": Error of deal selection by index"); break; } //--- Check the symbol if(deal.Symbol()!=m_symbol.Name()) continue; //--- Check the profit if(deal.Profit()<0.0) lot=deal.Volume(); break; } //--- Return the volume return(lot); }
では、われわれのアルゴリズムをもっと詳しく(すでに詳しく述べていますが)みていきましょう。
細かい点はさておき、ここでのマネー・マネージャは前回取引の損失を受けて取引ボリュームを増やすことを提案している、という点に留意します。前回取引に損失が出ていなければ、固定ボリュームでポジションをオープンします。それは特定のパラメータで定義されているものです。
このために、対応する機能を書き込み、仮想メソッドCheckOpenLong および CheckOpenShortをオーバーライドします。
クラス記述
//+------------------------------------------------------------------+ //| Class CSampleMoney. | //| Purpose: Class for risk and money management | //| doubling the volume after a loss deal. | //| It is derived from the CExpertMoney class. | //+------------------------------------------------------------------+ class CSampleMoney : public CExpertMoney { protected: //--- Setup parameters double m_lots; // Deal volume for "normal" conditions public: CSampleMoney(); //--- Methods to set the parameters void Lots(double lots) { m_lots=lots; } //--- Methods to validate the parameters virtual bool ValidationSettings(); //--- Methods to define the volume virtual double CheckOpenLong(double price,double sl); virtual double CheckOpenShort(double price,double sl); protected: double CheckPrevLoss(); };
CheckOpenLong と CheckOpenShort の実装は事実上同一です。両者ともに前に実装されているCheckPrevLoss メソッドを呼び出してボリューム増加の必要性を判断します。
次に、トレードボリュームは無制限に増やすことはできないことを考慮する必要があります。ポジションボリュームについては2つ制限があります。
- シンボルに対しサーバー設定で指定された取引きの最大ボリューム for the symbol, (SYMBOL_VOLUME_MAX)
- デポジットで要求される自由資金額の利用可能性
CheckOpenLong および CheckOpenShortメソッドの実装
//+------------------------------------------------------------------+ //| Defining the volume to open a long position. | //| INPUT: no. | //| OUTPUT: lot-if successful, 0.0 otherwise. | //| REMARK: not. | //+------------------------------------------------------------------+ double CSampleMoney::CheckOpenLong(double price,double sl) { if(m_symbol==NULL) return(0.0); //--- Select the lot size double lot=2*CheckPrevLoss(); if(lot==0.0) lot=m_lots; //--- Check the limits double maxvol=m_symbol.LotsMax(); if(lot>maxvol) lot=maxvol; //--- Check the margin requirements if(price==0.0) price=m_symbol.Ask(); maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,price,m_percent); if(lot>maxvol) lot=maxvol; //--- Return the trade volume return(lot); } //+------------------------------------------------------------------+ //| Defining the volume to open a short position. | //| INPUT: no. | //| OUTPUT: lot-if successful, 0.0 otherwise. | //| REMARK: no. | //+------------------------------------------------------------------+ double CSampleMoney::CheckOpenShort(double price,double sl) { if(m_symbol==NULL) return(0.0); //--- Select the lot size double lot=2*CheckPrevLoss(); if(lot==0.0) lot=m_lots; //--- Check the limits double maxvol=m_symbol.LotsMax(); if(lot>maxvol) lot=maxvol; //--- Check the margin requirements if(price==0.0) price=m_symbol.Bid(); maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,price,m_percent); if(lot>maxvol) lot=maxvol; //--- Return the trade volume return(lot); }
これで最初の問題は解決しました。上記コードはここでの主要タスクを満たすマネー・マネージャクラスの「ソースコード」です。
2.2. MQL5 ウィザード用マネー・マネージャクラス記述の作成
ここから第二の課題に取り組みます。ここでのマネー・マネージャは MQL5 ウィザードのトレーディング戦略生成によるものと「認識」する必要があります。
第一の必要条件を行いました。MQL5 ウィザードによって「見つけられる」ファイルの配置です。が、これではまだ十分ではありません。MQL5 ウィザードはただファイルを「見つける」のではなく、それを「認識」する必要があります。このために、MQL5 ウィザードに元のテキストクラスデスクリプタを追加します。
結果を見ていきます。
1. コメントブロックは以下のような行で始まります。
// wizard description start //+------------------------------------------------------------------+ //| Description of the class |
2. 次の行は"//| Title=<Text> |"形式のテキストデスクリプタ(シグナル選択にあたり MQL5 ウィザードで見るもの)です。テキストが一行で収まらない場合は、その後にもう一行(それ以上は不可)追加することが可能です。
この場合は、以下です。
//| Title=Trade with a doubling of lot after a loss |
3. それから "//| Type=<Type> |"形式で指定されるクラスタイプの行です。<Type> フィールドは資金値(マネー・マネージャに加え、MQL5 ウィザードはその他のクラスタイプも認識します。)を持つ必要があります。
それを書きます。
//| Type=Money |
4. "//| Name=<Name> |" 形式の以下の行はシグナルの短縮名(expertのグローバル変数名を生成するためにMQL5ウィザードで使用されます)です。
それは以下のようになります。
//| Name=Sample |
5. クラス名は記述の重要な要素です。"//| Class=<ClassNameа> |"形式の行では、<ClassName> パラメータはここでのクラス名と一致する必要があります。
//| Class=CSampleMoney |
6. この行には書き込みはしませんが、残しておく必要があります。(これは 言語参照 部へのリンクです。)
//| Page= |
7. その後、シグナル設定パラメータの記述がきます。
これは行のセットです。(行数はパラメータ数と一致します。)
各行のフォーマットは次のようなものです。"//| Parameter=<NameOfMethod>、<TypeOfParameter>、<DefaultValue> |"
パラメータセットは下記です。
//| Parameter=Lots,double,0.1 |
//| Parameter=Percent,double,100.0 |
8. コメントブロックは以下のような行で終わります。
//+------------------------------------------------------------------+ // wizard description end
2-7 2~7についてはもっと説明が必要です。クラスデスクリプタのセクションにはキーワードがあります。(タイトル、タイプ、名前、クラス、ページ、パラメータ)残念ながら、MQL5 ウィザード はクラス記述の一部として文字の可能な組合せすべてを読解することはできません。
そこで、不要なエラーを避けるために以下のように書きます。<Description> にはキーワード「タイトル」だけのためにスペースを設けます。1段落目と8段落目は「そのまま」コピーします。
クラスデスクリプタ(最初の行)は20行目以前にくる必要があります。ソースコードにデスクリプタを追加します。
//+------------------------------------------------------------------+ //| SampleMoney.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\ExpertMoney.mqh> #include <Trade\DealInfo.mqh> // wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=Trading with lot doubling after a loss | //| Type=Money | //| Name=Sample | //| Class=CSampleMoney | //| Page= | //| Parameter=Lots,double,0.1 | //| Parameter=Percent,double,100.0 | //+------------------------------------------------------------------+ // wizard description end //+------------------------------------------------------------------+ //| Class CSampleMoney. | //| Purpose: Class for risk and money management | //| doubling the volume after a loss deal. | //| It is derived from the CExpertMoney class. | //+------------------------------------------------------------------+ class CSampleMoney : public CExpertMoney { protected: //--- Setup parameters double m_lots; // Deal volume for "normal" conditions public: CSampleMoney(); //--- Methods to set the parameters void Lots(double lots) { m_lots=lots; } //--- Methods to validate the parameters virtual bool ValidationSettings(); //--- Methods to define the volume virtual double CheckOpenLong(double price,double sl); virtual double CheckOpenShort(double price,double sl); protected: double CheckPrevLoss(); }; //+------------------------------------------------------------------+ //| Constructor CSampleMoney. | //| INPUT: no. | //| OUTPUT: no. | //| REMARK: no. | //+------------------------------------------------------------------+ void CSampleMoney::CSampleMoney() { //--- Setting default values m_lots=0.1; } //+------------------------------------------------------------------+ //| Validation of the setup parameters. | //| INPUT: no. | //| OUTPUT: true if the settings are correct, otherwise false. | //| REMARK: no. | //+------------------------------------------------------------------+ bool CSampleMoney::ValidationSettings() { //--- Call the base class method if(!CExpertMoney::ValidationSettings()) return(false); //--- Validating the parameters if(m_lots<m_symbol.LotsMin() || m_lots>m_symbol.LotsMax()) { printf(__FUNCTION__+": The deal volume must be in the range %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax()); return(false); } if(MathAbs(m_lots/m_symbol.LotsStep()-MathRound(m_lots/m_symbol.LotsStep()))>1.0E-10) { printf(__FUNCTION__+": The deal volume must be multiple of %f",m_symbol.LotsStep()); return(false); } //--- Successful completion return(true); } //+------------------------------------------------------------------+ //| Defining the volume to open a long position. | //| INPUT: no. | //| OUTPUT: lot-if successful, 0.0 otherwise. | //| REMARK: no. | //+------------------------------------------------------------------+ double CSampleMoney::CheckOpenLong(double price,double sl) { if(m_symbol==NULL) return(0.0); //--- Select the lot size double lot=2*CheckPrevLoss(); if(lot==0.0) lot=m_lots; //--- Check the limits double maxvol=m_symbol.LotsMax(); if(lot>maxvol) lot=maxvol; //--- Check the margin requirements if(price==0.0) price=m_symbol.Ask(); maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,price,m_percent); if(lot>maxvol) lot=maxvol; //--- Return the trade volume return(lot); } //+------------------------------------------------------------------+ //|Defining the volume to open a short position. | //| INPUT: no. | //| OUTPUT: lot-if successful, 0.0 otherwise. | //| REMARK: no. | //+------------------------------------------------------------------+ double CSampleMoney::CheckOpenShort(double price,double sl) { if(m_symbol==NULL) return(0.0); //--- Select the lot size double lot=2*CheckPrevLoss(); if(lot==0.0) lot=m_lots; //--- Check the limits double maxvol=m_symbol.LotsMax(); if(lot>maxvol) lot=maxvol; //--- Check the margin requirements if(price==0.0) price=m_symbol.Bid(); maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,price,m_percent); if(lot>maxvol) lot=maxvol; //--- Return the trade volume return(lot); } //+------------------------------------------------------------------+ //| Defines whether the prev. deal was losing. | //| INPUT: no. | //| OUTPUT: Volume of the prev. deal if it's losing, otherwise 0.0 | //| REMARK: no. | //+------------------------------------------------------------------+ double CSampleMoney::CheckPrevLoss() { double lot=0.0; //--- Request the history of deals and orders HistorySelect(0,TimeCurrent()); //--- variables int deals=HistoryDealsTotal(); // Total number of deals in the history CDealInfo deal; //--- Find the previous deal for(int i=deals-1;i>=0;i--) { if(!deal.SelectByIndex(i)) { printf(__FUNCTION__+": Error of deal selection by index"); break; } //--- Check the symbol if(deal.Symbol()!=m_symbol.Name()) continue; //---Check the profit if(deal.Profit()<0.0) lot=deal.Volume(); break; } //--- Return the volume return(lot); } //+------------------------------------------------------------------+
以上です。これでマネー・マネージャを使用できます。
MQL5 ウィザードのトレーディング戦略ジェネレータ がわれわれのマネー・マネージャを使うことができるように、MetaEditor (MQL5 ウィザードが起動時のみInclude\Expert フォルダをスキャンします。)を再起動します。
MetaEditorの再起動後、作成したマネー・マネージャモジュールは MQL5 ウィザードで使用可能です。
図5 MQL5 ウィザードで作成したマネー・マネージャ
マネー・マネージャパラメータの記述セクションで指定した入力パラメータはこれで使用可能です。
図6 MQL5 ウィザードで作成したマネー・マネージャの入力パラメータ
実装されたトレーディング戦略の入力パラメータの最良値は MetaTrader 5 端末の Strategy Testerを用いて検索可能です。
図7には本資金管理システム(URUSD H1、検証期間:2010年1月1日~2011年1月5日)に従ってトレードを行う Expert Advisor の検証結果を示しています。
図7 損失後ボリュームを2倍にした資金管理モジュールを用いた戦略履歴における検証結果
Expert Advisor作成にあたり、,『MQL5 ウィザード:トレーディングシグナルのモジュール作成方法』稿で導入したトレーディングシグナルのモジュールを使用しました。Expert Advisorパラメータ:PeriodMA=12, ShiftMA=0, MethodMA=MODE_EMA, AppliedMA=PRICE_CLOSE, Limit=-70, StopLoss=145, TakeProfit=430, Expiration=10, Lots=0.1, Percent=100
おわりに
MQL5ウィザードのトレーディング戦略ジェネレータ はトレーディングの考え方を検証することをひじょうに簡素化します。生成された expert のコードは標準ライブラリのトレーディング戦略クラス に基づきます。それはトレーディングシグナルクラス、資金およびリスク管理クラス、ポジションサポートクラスの特定の実装を作成するのに使用されます。
本稿では独自のリスクおよび資金管理モジュールの作成と、MQL5 ウィザードでそれを有効にする方法について述べました。例として、資金管理アルゴリズムを取り上げました。そこではトレードボリュームが前回ディールの結果を基に決定されます。MQL5 ウィザード用に作成されたクラスのストラクチャおよび記述フォーマットについても述べてきました。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/230





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索