• カテゴリー別アーカイブ 「新MT4対応ライブラリによるメタトレーダーEA実践プログラミング」
  • MQL4/MQL5共通EAライブラリを使って月毎の損益を算出する

    MT5のストラテジーテスターでは、月毎の損益がグラフで表示されて便利なのですが、その損益のデータそのものをEAのプログラム中で参照することができません。

    ところでMT5では、OnTester()という関数を定義しておくと、バックテスト終了時にその関数を実行してバックテストの各種データを取得したり、適当に計算させたりした結果を「OnTester結果」として表示してくれます。(最適化の評価基準として使う場合、MT4でも利用できます。)

    これを使って月毎の損益を算出できないか、というのが今回の記事の目的です。

    そのために作ったわけではないのですが、拙作のMQL4/MQL5共通EAライブラリに次のような関数があります。

    //過去の総損益(金額)の取得
    double MyOrderTotalProfit(datetime from_date, datetime to_date, int pos_id=0)
    from_dateからto_dateまでの期間で、ポジション番号pos_idの取引の総損益を取得します。

    これを使うと、割と簡単に月毎の損益が算出できたのでご紹介します。

    まず、以下のように、共通EAライブラリを使った、とあるEAがあるとします。

    これに以下のコードを追加します。

    追加したコードを簡単に説明します。

    まず、OnInit()でEA開始時刻をStartTimeに取得しておきます。

    MonthlyProfit()関数では、EA開始時から何番目の月かを入力して、その月の損益を出力します。ここでは、最後に前述のMyOrderTotalProfit()を使うために、損益を求める期間をfrom_dateとto_dateに求めます。年と月を求めるためにちょっとした計算式がありますが、要はその月の1日から次の月の1日までを期間として設定しています。

    あとは、OnTester()関数中に月毎の損益を保存する配列profit[]を用意して、iを0から月数分変えて配列に代入します。profit[]をPrintさせているのは確認のためです。ここでは、profit[]を合計したものをreturnで返していますが、お好みに合わせて加工して使ってください。

    なおEAでは、テスト期間が終わったときのオープンポジションは強制決済されますが、上記のコードを使った月毎の損益には反映されません。合計した損益がEAの出力する総損益と異なることがあるので、注意してください。

    (追記)上のコード、そのままMT4でも動きます。バックテストのレポートにはOnTesterの結果は表示されませんが、OnTester()でPrintさせた月毎損益は操作履歴に表示されます。



  • MQL4/MQL5共通EAライブラリ(181031版)

    今週、MT5がbuild1930にアップデートされました。(現在、build1932です。)

    それに伴い、新メタトレ実践本用のMQL4/MQL5共通EAライブラリをMT5で利用する場合、テクニカル指標関数の戻り値が常にEMPTY_VALUEとなってしまう不具合が発生しました。

    そこで、その不具合を修正した対応版をアップロードします。ライブラリファイルは、以下からダウンロードできます。

    ライブラリ関数の仕様、およびライブラリの使用方法に変更はありません。以下の記事をご参考にしてください。

    なお、MT4用のライブラリには修正はありませんので、MT4でご利用の方はライブラリ更新の必要はありません。



  • MQL4/MQL5共通EAライブラリ(180619版)

    今週、MT5がbuild1860にアップデートされました。(現在、build1861です。)

    それに伴って、新メタトレ実践本用のMQL4/MQL5共通EAライブラリがそのままでは使えなくなったので、取り急ぎ対応版をアップロードします。ライブラリファイルは、以下からダウンロードできます。

    ライブラリ関数の変更点、追加点は以下の通りです。

    1. iOpen(), iLow(), iHigh(), iClose(), iTime(), iVolume(), iHighest(), iLowest(), iBarShift()の各関数がMQL5でサポートされたため、LibMQL4.mqhから削除しました。
    2. LibOrder4.mqhとLibOrder5.mqhに次の関数を追加しました。
      //過去の総損益(金額)の取得
      double MyOrderTotalProfit(datetime from_date, datetime to_date, int pos_id=0)
      from_dateからto_dateまでの期間で、ポジション番号pos_idの取引の総損益を取得します。
    3. #define UseOrderComment を記述し、以下の関数を定義することにより、各注文のコメントをマジックナンバー以外に設定できるようにしました。
      string MagicToComment(long magic)
      使用方法については、別の記事で説明します。
    4. 許容スリッページ SlippagePips を#defineでも設定できるようにしました。

    ライブラリの基本的な使い方は変わっていません。以下の記事をご参考にしてください。

    以上です。



  • MT5のタイムフレームをMT4で使う場合の注意点

    前回の記事でMT5のタイムフレームをMT4で使うためのライブラリを紹介しました。

    最近は、互換性のないMT4とMT5で、いかに互換性のあるソースファイルが作れるかが研究テーマ(?)となっていますが、今回のライブラリの仕組みは次のようになっています。

    モメンタムを算出するテクニカル指標関数 iMomentum()の引数を iMomentum(PERIOD_M10, MomPeriod, 1)のように変えたのは、MQL4/MQL5の組み込み関数を直接呼び出すのではなく、別に定義した関数を呼び出すためです。

    追加したライブラリLibTF5.mqhには、次のような関数の定義が書かれています。

    MQL4/MQL5では、関数のオーバーロードの機能があり、同じ関数名でも引数の数が違えば、別の関数として定義できるのです。なので、iMomentum()の引数の数が5個であれば、組み込み関数(MQL5の場合、LibMQL4.mqhで定義した関数)が呼ばれるのですが、今回のように3個にすれば、このライブラリの関数が呼ばれるのです。

    symbolの引数を省略したのは、通常チャート上のシンボル_Symbolを使うことが多いからです。またapplied_priceの引数を省略したのは、テクニカル指標を算出するデータを終値に限定したからです。

    それで、このライブラリで定義したiMomentum()関数では、同じくライブラリ中のCheckTF()という関数の戻り値により、組み込み関数のiMomentum()と、iMomentumOnArray()のどちらを呼ぶかを場合分けしています。

    ここで、CheckTF()は、引数のタイムフレームがMT4,MT5でそれぞれ対応しているかどうかをチェックする関数で、対応していればtrueを返すので、そのまま組み込みのテクニカル指標関数を呼び出します。

    今回のライブラリでは、タイムフレームが対応していない場合の処理が重要ですが、ちょっと強引な方法をとっています。あとあまりコードが複雑にもならないようにもしているので、実行効率はよくありません。

    簡単にいうと、タイムフレームが対応していない場合、1分足の終値を使って指定したタイムフレームの終値の配列を作成します。そして、その配列に対してモメンタムを算出するiMomentumOnArray()を使って、指定したタイムフレームでのテクニカル指標値を求めているのです。

    ということなので、テクニカル指標といっても、配列に対して算出できる関数があるものしか現状では対応できないということになります。つまり、MQL4で使えるのは、iBandsOnArray(), iCCIOnArray(), iEnvelopesOnArray(), iMomentumOnArray(), iMAOnArray(), iRSIOnArray(), iStdDevOnArray()の7つということになります。これ以外のテクニカル指標に対応させたい場合は、自作する必要があるでしょう。

    あと、終値配列を毎回作成するので、結構時間がかかります。売買ルールが単純であれば、EA実行に支障をきたすことはありませんが、ストラテジーテスターでのバックテストは時間がかかりすぎて実用的ではありません。1分足の終値の配列サイズをRATES_SIZEという定数で1000に指定してあり、それを小さくすることで多少速くできるかもしれませんが、逆に小さくすると、大きいタイムフレームの終値のサイズが少なくなり、テクニカル指標が算出できないという問題も生じます。

    以上、色々と使用上の注意点があるので、それらを解決できるまでは、このライブラリはβ版のままかもしれません。

    とりあえず、興味のある方は使える範囲でお使いください。



  • MT5のタイムフレームをMT4で使うためのMQL4/MQL5共通EAライブラリの拡張

    MT4とMT5の違いの一つに、タイムフレームの数があります。

    MT4で対応しているタイムフレームは、M1,M5,M15,M30,H1,H4,D1,W1,MN1の9個ですが、MT5ではさらに M2,M3,M4,M6,M10,M12,M20,H2,H3,H6,M8,M12 の12個が追加されています。

    そんなにたくさんのタイムフレームをどう使い分けるのか、という疑問もありますが、ネットで調べると、MT4で対応していないタイムフレームを使おうとする記事がいくつか見つかります。全く需要がないわけでもなさそうです。

    筆者は基本的にMT5でEAを開発して、それをMT4で動かしています。そのため、どちらでも同じソースプログラムが使えるようにと、MQL4/MQL5共通EAライブラリを作りました。

    ただ、MT5で色々とタイムフレームを変えてみて、例えば、10分足がいいかなと思っても、MT4では10分足に対応していないので、そのままでは動きません。

    MT4でも、1分足データから10分足データを作って、オフラインチャートから強引にEAを動かすということもできるようですが、あまり面倒なことはしたくありません。

    今回の記事では、拙作のMQL4/MQL5共通EAライブラリに追加してインクルードするだけで、MT5のタイムフレームをMT4で使えるようにする方法を紹介します。

    まずは、「新メタトレ実践本用のMQL4/MQL5共通ライブラリ(β版)」で取り上げたEAのプログラムです。

    このEAは、ファイルの拡張子を「mq4」にすればMT4で、「mq5」にすればMT5でコンパイルし、動かすことができます。ただし、チャートに挿入したタイムフレームのテクニカル指標を使うので、MT4では対応している9種類のタイムフレームしか使えません。

    チャートのタイムフレームと関係なく、決まったタイムフレームのテクニカル指標を使いたい場合、iMomentum()関数の2番目の引数にタイムフレームの定数を代入します。例えば、10分足にしたければ、次のようにします。

    MT5は10分足に対応しているので、この変更だけで10分足のテクニカル指標を使うことができます。ただし、MT4の場合、コンパイルは通るのですが、10分足に対応していないので、iMomentum()の値は常に0になってしまい、EAとして機能しません。

    そこで、新たに作った次のヘッダファイルをインクルードしてみます。

    あと、iMmentum()関数の最初の引数「_Symbol」と、4番目の引数「PRICE_CLOSE」を削除してみます。全体のコードは次のようになります。

    変更箇所は2行のみですが、このプログラムだと、MT4、MT5両方で、10分足のテクニカル指標を使ったEAとして機能します。

    ただし、このライブラリはまだβ版ですので、今後変更になる可能性が高いです。またどんなテクニカル指標でも対応できるわけではなく、色々と制約があります。そのあたりについては、ライブラリの仕組みと関係するものですので、別の機会に解説したいと思います。