
Lite_EXPERT2.mqh:エキスパートアドバイザー開発者のためのファンクションキット
はじめに
「ポピュラーなトレードシステムに基づくエキスパートアドバイザーとトレーディングロボット最適化の錬金術」シリーズ 1、 2、 3、4、5、6、 7において、トレード戦略を、すでに用意されているLite_EXPERT1.mqhのカスタムトレード関数を使って、とてもシンプルに素早く実行するプログラムコードに変えるエキスパートアドバイザーを作成することを、初心者EA開発者に私なりに紹介しました。情報の最大平易化のために、このファイルで使われているカスタム関数の数は最小で、かつ十分であり、つまり、何のトラブルもなく把握できるというのはごく自然なことです。
しかしながら、このファイルによって提供される機能性は幅広いスケールでプログラムコードを動かすには少し十分ではありません。Lite_EXPERT2.mqhはこの目的のために書かれたと言え、初見のユーザーにとってはまだ複雑なものですがより普遍的なカスタム関数のセットを含んています。読者は「ポピュラーなトレードシステムに基づくエキスパートアドバイザーとトレーディングロボット最適化の錬金術その1」で提供された情報に既に詳しく、この新稿は将来の発展とカスタム関数を使用するのに必要なスキルの向上のための次のステップであるとみなします。
The Lite_EXPERT2.mqh ファイルコンテンツ
おおむね、GLite_EXPERT2.mqhにおける利用可能なすべての関数は以下のフローチャートのかたちで表すことができます。:
関数に加え、Lite_EXPERT2.mqhはグローバルスコープで宣言したすべてのトレード関数で使われている整数の変数int LastTimeを含んでいます。整数の変数はスリッページポイントのためint Slippageに格納されます。これはエキスパートアドバイザーの外部パラメーターとして表示ことができます。
1. ポジションオープン関数
このブロックのすべての関数は2つの大きなグループに分けることができます。最初のグループの関数は名前の最初に「Open」を持っています。2番目のグループの関数名は「dOpen」です。最初のグループの関数はポジションをオープンした値とストップロスや利益確定の外部変数としてのポイントまでの相対距離を使用します。つまりこれらは整数の変数として表します。
bool OpenBuyOrder1_ (bool& BUY_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT) bool OpenSellOrder1_ (bool& SELL_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT) bool OpenBuyOrder2_ (bool& BUY_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT) bool OpenSellOrder2_ (bool& SELL_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT)
2番目のグループの関数におけるストップロスと利益確定は浮動小数の変数によって表します。このケースでは、これらの変数の値はプライスチャートから得られた対応注文の絶対値です。これは特定の目的をより利用しやすくさせるエキスパートアドバイザーのコードを書かせます。
bool dOpenBuyOrder1_ (bool& BUY_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT) bool dpenSellOrder1_ (bool& SELL_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT) bool dOpenBuyOrder2_ (bool& BUY_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT) bool dOpenSellOrder2_ (bool& SELL_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT)
おわりに「 1_ 」と付けられたすべての関数は、取引を実行する際にストップロスと利益確定注文の設定をブローカーに許可するためのものです。「 2_ 」を名にふくむ関数はすでにオープンしているポジションのためのオーダー設定をブローカーに許可するために使われます。
Lite_EXPERT1.mqhで使用された関数とは対照的に、これらの8つの関数は2つの新しい外部変数(日時の変数TimeLevelとint Margin_Mode)を持っています。したがって最初にすべきことはこれらをより詳しくみていくことです。TimeLeve変数の値は現在の取引の実行後のある時間期限を表します。lこのファイルのすべてのトレード関数は特定の時間期限に到達するまで新たなポジションやオーダーを現在のマジックナンバーと共にオープンすることはありません。取引が実行される際のこの外部変数のはコンピューターのハードドライブにグローバル変数として保存され、その結果トレードターミナルやウィンドウズのオペレーティングシステムを再起動してもその値は失われません。この変数のもっとも基本的な使用はポジションの再オープンや同じバーでの指値の設定をブロックすることです。
//---- static datetime TimeLevel; TimeLevel = Time[0] + Period() * 60; //---- if (!OpenBuyOrder1_ (BUY_Signal, MagicNumber, TimeLevel, Money_Management, Margin_Mode, STOPLOSS, TAKEPROFIT)) return(-1);
TimeLevel静的変数はBUY_Signal変数として同じブロックに初期化されます。 ここで、もしOpenBuyOrder1_()関数がポジションを持つと、ハードドライブにグローバル変数としてTimeLevel変数の値を保存します。そしてポジションや指値注文をオープンするLite_EXPERT2.mqhファイルの関数は、直近の相場時間がこの値以上になるまでマジックナンバーとともにオーダーをオープンしません。
したがって、基本的に、このファイルのトレード関数はbool& BUY_Signalタイプの外部変数を必要ないので初期化(ゼロアウト)しません。初期化はTimeLevel変数に「-1」が割り当てられた場合のみに行われます。もしこの変数の値がゼロに設定されたら、ポジションオープン関数は初期化(ゼロアウト)も保存もせず、マジックナンバーがint MagicNumber外部変数の値と同じでないどんな時にもBUY_Signal外部変数のシグナルに基づきポジションをオープンするでしょう。
ハードドライブに保存するグローバル変数のために使われるストリングネームは以下の式を使うテストと最適化のために作成されます。:
string G_Name_ = "TimeLevel", "_", AccountNumber(), "_", "_Test_", OrderSymbol(), "_", OrderMagicNumber());
他のケース:
string G_Name_ = "TimeLevel", "_", AccountNumber(), "_", OrderSymbol(), "_", OrderMagicNumber());
このネームは他のグローバル変数のために使ってはいけません!
Lite_EXPERT1.mqhで利用できるトレード関数はロット計算一つの方法のみに使います(フリーマージンに基づくMM)。このロットサイズ計算方法はどんな戦略にも適している分けではないかもしれません。このことはLite_EXPERT2.mqhで提供されるトレード関数を考慮に入れる必要があり、ロットサイズ計算方法はint Margin_Mode外部変数を利用することで決定します。 ロットサイズ計算の決定において、Margin_Mode外部変数はゼロからまでの値が与えられます:
- 0 - フリーマージンに基づくMM
- 1 - アカウント残高に基づくMM
- 2 -フリーマージンの損失に基づくMM
- 3 - アカウント残高の損失に基づくMMe
- 4 - 0から2のあいだの最小ロット数
- 5 - 1から3のあいだの最小ロット数
- デフォルト - フリーマージンに基づくMM
2番目か3番目のロットサイズ計算方法を使用するとストップロスはダイナミックになることに注意してください。つまり、それは取引によって変化し、例えばストップロスとMMの境界値を考慮すべきだということです。もし変数が以下のような値:Money_Management = 0.1, Margin_Mode = 3 and int STOPLOSS = 100 (少数第5位)の場合、エキスパートアドバイザーはポジションをオープンするのにすべてのディポジットを使うことになるでしょう!
念のため、Margin_Mode変数(2と3)の値のためこれら2つの変数を再度説明しましょう。ロットサイズ計算関数はフリーマージンかアカウント残高のどちらかの値とそれを Money_Management変数の値で掛けることをします。計算結果値はポジションがストップロスレベルに近づくと増える損失合計になります!これらの損失はストップロスサイズに依りません。したがって、ロットサイズ計算関数はストップロスサイズに基づいてポジション量を決定するのでストップロスの損失は受け入れがたい設定になります!
Margin_Mode変数の値が4か5のとき、トレード関数は同時に2変数を使ってロットサイズを計算することができもっとも小さい値を選びます。例えば、 Margin_Mode = 5ならば、トレード関数はアカウントバランスとその損失に基づいてロットサイズを計算し、最も小さい値を使います。
ここで、Money_Management変数の値が負であるなら、すべてのこれらの関数はMargin_Mode変数の値をないものとみなしMoney_Management変数の値をロットサイズとみなして使うことに言及しておきます。このような値を使う際、マイナスのサインは放棄され、値自体はその利用可能な値より大きくなることができない近似値になります。ロットサイズの計算において、これら8つの関数は取引の実行のためフリーマージンが十分にあるか常にチェックし、必要であれば許容できる値まで計算したロットサイズを小さくします。
2. 指値注文のための関数
これは2番目の、前のものと同じように2つの大きなグループに分けられた関数のグループです。
bool OpenBuyLimitOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration) bool OpenBuyStopOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration) bool OpenSellLimitOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration) bool OpenSellStopOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, int STOPLOSS, int TAKEPROFIT, int LEVEL, datetime Expiration)
bool dOpenBuyLimitOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT, double dLEVEL, datetime Expiration) bool dOpenBuyStopOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT, double dLEVEL, datetime Expiration) bool dOpenSellLimitOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT, double dLEVEL, datetime Expiration) bool dOpenSellStopOrder1_ (bool& Order_Signal, int MagicNumber, datetime TimeLevel, double Money_Management, int Margin_Mode, double dSTOPLOSS, double dTAKEPROFIT, double dLEVEL, datetime Expiration)
前の関数について先ほど言及したすべてのこともまた、これら8つの関数について真実です。例外として考慮できることはただ2つのことだけです。注文が発注されたときに何が起きるのか、ということに基づいてロットサイズを計算するのは不可能です。そして指値注文がだされたポイントでロットサイズが計算された場合、どうやってそれがなされるのか、Money_Management変数の値と厳密な一致をすべき計算を期待することなどできません。同じ理由により、これらの関数はロットサイズに十分な資金があるかどうかチェックしません。
3. ポジションクローズのための関数
このブロックはたった4つの関数で構成されています。
bool CloseBuyOrder1_(bool& CloseStop, int MagicNumber) bool CloseSellOrder1_(bool& CloseStop, int MagicNumber) bool CloseAllBuyOrders1_(bool CloseStop) bool CloseAllSellOrders1_(bool CloseStop)
これらの関数はとても単純で追加説明は要求されないでしょう。最初の2つの関数はエキスパートアドバイザーが稼働中のチャートのシンボルによって特定されたマジックナンバーとともにポジションをクローズさせます。他2つの関数はすべてのオープンポジションをクローズさせます。
4. 指値注文取り消しのための関数
このセクションにおける関数リストはたった2つの基本的な関数からなっています。
bool CloseOrder1_(bool& CloseStop, int cmd, int MagicNumber) bool CloseAllOrders1_(bool CloseStop, int cmd)
新たな変数を含む外部変数 - int cmd. その値は以下のとおりです。:
- OP_BUYLIMIT 2 Pending order BUY LIMIT
- OP_SELLLIMIT 3 Pending order SELL LIMIT
- OP_BUYSTOP 4 Pending order BUY STOP
- OP_SELLSTOP 5 Pending order SELL STOP
5. ポジション修正とトレーリングストップ関数
このブロックは3つの関数グループを含んでいます。:
1) ポジション修正
bool dModifyOpenBuyOrder_ (bool& Modify_Signal, int MagicNumber, datetime ModifyTimeLevel_, double dSTOPLOSS, double dTAKEPROFIT) bool dModifyOpenSellOrder_ (bool& Modify_Signal, int MagicNumber, datetime ModifyTimeLevel_, double dSTOPLOSS, double dTAKEPROFIT) bool dModifyOpenBuyOrderS (bool& Modify_Signal, double dSTOPLOSS, double dTAKEPROFIT) bool dModifyOpenSellOrderS(bool& Modify_Signal, double dSTOPLOSS, double dTAKEPROFIT)
このグループのすべて4つの関数はプライスチャート上でストップロスと利益確定の絶対値を使用し浮動小数の変数によって表せられます。最初と2番目のグループの変数について記述したことすべては真実でありこのグループの変数に応用することもできます。
日時を表すModifyTimeLevel_変数の値はこのグループの最初2つの関数にのみ利用されることに注意してください。他のどこにも使われません!この変数は最後2つの関数からは全く同様に使われません。エキスパートアドバイザーのコードで最後2つの関数の1つを呼び出せるようにするために、最初にOP_BUYかOP_SELLを選択し、OrderSelect()関数を使ってそれらと稼働し続ける必要があります!これらの関数はマジックナンバーを持たないオープンポジションを扱うものです。ハードドライブ上でModifyTimeLevel_変数の値を保存する目的のグローバル変すのストリングネームのための式は以下です。:
string G_Name_ = "ModifyTimeLevel_", "_", AccountNumber(), "_", "_Test_", Symbol(), "_", MagicNumber;
string G_Name_ = "ModifyTimeLevel_", "_", AccountNumber(), "_", Symbol(), "_", MagicNumber;
2)トレーリングストップ
bool Make_BuyTrailingStop_ (bool& TreilSignal, int MagicNumber, datetime TrailTimeLevel, int TRAILINGSTOP) bool Make_SellTrailingStop_ (bool& TreilSignal, int MagicNumber, datetime TrailTimeLevel, int TRAILINGSTOP) bool dMake_BuyTrailingStop_ (bool& TreilSignal, int MagicNumber, datetime TrailTimeLevel_, double dTRAILINGSTOP) bool dMake_SellTrailingStop_ (bool& TreilSignal, int MagicNumber, datetime TrailTimeLevel_, double dTRAILINGSTOP)
このグループは現在値に対しストップロスを強制する4つの古典的なトレーリングストップを含んでいます。これらのうち2つは外部パラメーターとして現在値に関係したトレーリングストップの小数値をもっています。その一方で他2つは同じ目的で絶対値をもっています。前の関数と同様に、これら4つの関数はTrailTimeLevelのフォームで時間制限を使い、同じ値でTrailTimeLevel_変数を使います。毎時間トレーリングストップを変えたいならば、これらの変数はゼロに設定すべきです。.
3)さらに4ポジション修正のグループ
bool BuyStoplossCorrect (int MagicNumber, int ExtPointProfit, int StoplossProfit) bool SellStoplossCorrect (int MagicNumber, int ExtPointProfit, int StoplossProfit) bool AllBuyStoplossCorrects (int ExtPointProfit, int StoplossProfit) bool AllSellStoplossCorrects(int ExtPointProfit, int StoplossProfit)
ストップロスレベルを一度に変更する最初2つの関数は固定のマジックナンバーを持つオープンポジションの利益を小数単位でチェックします。そしてもしそれがExtPointProfit変数の値より小さい場合、ストップロスは値をオープンしたポジションからStoplossProfit距離の現在値まで移動させられます。
このグループ最後2つの関数はどのマジックナンバーでも現在のシンボルのためすべてのオープンポジションの利益を追跡し、それらに応じたストップロスレベルを一度に変更します。
6. 追加関数
これはLite_EXPERT2.mqhファイルにおける関数のおそらく最後の最も大きなグループです. このグループの多くの関数は追加機能として上記の他の関数のコード内で利用されます。そのため多く場合、少ししか実際に使われないでしょう。したがって、これらの最も重要な部分の解説にとどめておきます。
まず最初に、みなさんの関心をTimeLevelGlobalVariableDel()関数に持っていってください。:
void TimeLevelGlobalVariableDel(string symbol, int MagicNumber)
テスト最適化の後、この関数はファイルで特徴づけられたトレード関数によって生成されたすべてのグロー版変数を削除し、コンピューターのハードドライブに保存します。この関数はエキスパートアドバイザー非初期化ブロックと呼ばれるべきでしょう。たとえば以下のとおりです。:
//+X================================================================X+ //| カスタムエキスパート非初期化関数 | //+X================================================================X+ int deinit() { //----+ TimeLevelGlobalVariableDel(Symbol(), 1); TimeLevelGlobalVariableDel(Symbol(), 2); TimeLevelGlobalVariableDel(Symbol(), 3); TimeLevelGlobalVariableDel(Symbol(), 4); //---- エキスパートアドバイザー非初期化完了 return(0); //----+ }
もしこれがなされなかった場合、テストまたは最適化の後に残っている直近の時間値のグローバル変数はエキスパートアドバイザーのテスト最適化をブロックします!!!
値の標準的シリーズから選ばれることのみできるチャート時間軸がエキスパートアドバイザーの外部変数として利用されることはよくあります。ある人は手動でやるといつもミスをし間違った値をセットします。このような場合、使っているTimeframeCheck()関数をチェックすることができます。
void TimeframeCheck(string TimeframeName, int Timeframe)
エキスパートアドバイザーを初期化する際に外部変数で時間軸の値をチェック
あらゆるプライスレベルのエキスパートアドバイザーで行われたすべての計算はもともとプライスチャートの値に基づいています。また、チャート上にどんな値が見えているか常にとても明らかに分かるわけではありません。 - ASKかBIDか。したがってプライスチャートから取得した値はトレード関数で利用される前にその差異を調整される必要があります。これはdGhartVelueCorrect()関数を使ってできます。:
double dGhartVelueCorrect(int cmd, double& GhartVelue)
Cmd変数の目的はメタエディターヘルプで見ることができる詳細に書いてあります。この関数を呼び出す場合、外部パラメーターGhartVelueは値が調整されたものに変更された変数に代表されるのみです。例えば、:
//---- GhartVelue_プライスレベルを取得 double GhartVelue_ = Low[0]; //---- 正確なGhartVelue_プライスレベル dGhartVelueCorrect(OP_BUY, GhartVelue_);
さらに使用を続けることができるオーダーを選択するもう2つの関数があります。:
bool OrderSelect_(string symbol, int cmd, int MagicNumber, int pool) bool Order_Select(string symbol, int MagicNumber)
プール変数はただ2つの値を取りえます: MODE_TRADES - オーダーはオープンオーダーと指値から選択させます。 MODE_HISTORY - オーダーはクローズオーダーと取り消したオーダーから選択させます。もし成功したら、関数はtrueを返し、さもなくばfalseを返します。
あるケースでは、MarginCheck()を使う必要があるかもしれません。口座で利用可能な資金からロットサイズをチェックする関数で、必要ならばロットサイズを利用可能な資金に応じて減らします。
bool MarginCheck(string symbol, int Cmd, double& Lot)
この関数におけるCmdパラメーターはただ2つの値を取りえます。: OP_BUYとOP_SELLです。もし計算が成功したら、関数はtrueを返します。関数のオペレーションにおいてエラーがあると、falseを返します。
ときどきロットサイズを計算したいかもしれません. この目的のため、さらに2つの関数があります。:
double BuyLotCount(double Money_Management, int Margin_Mode, int STOPLOSS) double SellLotCount(double Money_Management, int Margin_Mode, int STOPLOSS)
エラーがなければ関数はロットサイズの値を返します。さもばくば-1を返します。
エキスパートアドバイザーのコードにおいて、さらにインディケーターコードを利用したい人のためにもう3つの関数があります。:
int IndicatorCounted_(int Number, string symbol, int timeframe) int ReSetAsIndexBuffer(string symbol, int timeframe, double& array[]) int ReSetAsIndexBuffer_(string symbol, int timeframe, double& Array[], int ArrSize)
最初の関数はEA[で稼働するIndicatorCounted()関数に相当するものです。外部変数Numberはエキスパートアドバイザーのコードでナンバーを呼び出す関数を表しています(1インディケーターにつき1ナンバー)。2番目の関数の目的はグローバルスコープで宣言されたデータアレイをインディケーターバッファアナログにコンバートするためのものです。そのため関数は、その名前が対応するタイムシリーズアレイとともに変数double& array[]を代表するアレイの要素を同調させます。この関数はstart()関数と呼ばれるべきで、チャートバー上て繰り返すループオペレーターのレンジ外です。3番目の関数は2番目の関数の完全なアナログですが、Array[]アレイにおけるエレメントの数はArrSize変数の限定された値から得られるものです。言い換えれば、このケースではアレイは最後のバー、直近のバーのみにArrSizeナンバーを含んでいます。この関数は、インディケーターコードの値がアレイに加えられたり最後の値のArrSizeナンバーがエキスパートアドバイザーのコードに利用されている多くのケースで使われた前の関数より有用こもしれません。
そして最後、2つの関数です。:
bool IsNewBar(int Number, string symbol, int timeframe) bool MinBarCheck(string symbol, int timeframe, int MinBarTotal)
IsNewBar()関数はバーが対応するタイムシリーズアレイで変更される時のポイントでTrueを返します。他のすべてのケースでは、この関数はFalseを返します。Number変数はエキスパートアドバイザーのコード状のナンバーを呼び出す関数を表します。MinBarCheck()関数はMinBarTotal変数の値に対して関連するチャートのバーの本数を比べます。バーの数が少ない場合、Falseを返します。この関数はもし計算に必要なバーの本数が十分でなければエキスパートアドバイザーにトレードを許可しないようにするために使われます。
まとめ
便利で効果的なストラテジーテスターをMQL4で書くために必要十分な機能をもつLite_EXPERT2.mqh関数の全体リストを紹介しました。このシリーズの次の記事では、EAの上記ファイル関数の利用を説明する詳細な例を紹介します。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1380




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