EAで処理を書いていたら多くなりそうなので別ファイルにまとめることにした。はじめは共通処理ライブラリを作ろうとしたが作成したライブラリがエラーとなり呼び出せない問題が発生。結論を言うとライブラリを使わずにヘッダに処理を記述して解決した。あまりスマートな方法ではないがとりあえず動いたのでよしとする。
本記事はFXの自動売買に使用されるプログラムについて解説していますが内容を保証するものではありません。金銭にかかわる内容であるためご注意ください。参考にする場合は自己責任でお願いします。
本記事ではMT4を使用する。
FXDD – MetaTrader
・Version: 4.00 build 1322
・8Feb 2021
MetaEditor
・Version 5.00 build 2375
・7 Jan 2021
関数の管理と別ファイル化
汎用的な処理を別ファイルにまとめメンテナンス性を向上させる。
汎用的な処理は別ファイルへ
汎用的な処理(関数)を別ファイルで管理しておけば色々なEAから再利用できる。同一ファイルで管理するとコピペで同じコードがどんどん増えてしまう。バグがあって修正した場合コピーしたすべてのファイルに修正が必要になってしまう。通常はひとつのEAだけでテストすることはないと思うので汎用的な処理は基本的に別ファイルで管理すべき。
汎用処理をライブラリとして管理
汎用的な処理が増えてくるとこれまた煩雑になってきてしまう。EAから取り出した汎用処理が多くなってきたらグループ分けして管理する。例えば日付関連の処理をまとめるとか、スキャルピング関連をまとめるなど。一般的なプログラムだと1ファイルは2,000ステップ以内が適正と呼ばれている。最低でも2,000ステップ超えたらライブラリファイルの分割を考えよう。
EAから別ファイルに記述された処理を呼び出す例
メッセージを出力するだけの簡単な処理を別ファイルに記述しEAから呼び出す。
(1) メタエディターの起動
MT4を起動し「ツール」の「メタエディター」をクリック。
(2) ライブラリの作成(呼び出される側)
ツールバーの「新規作成」をクリック。
「インクルード」を選択し「次へ」をクリック。
ファイル名を入力し「完了」をクリック。
以下のファイルが作成される。
関数を入力。メッセージ「Hello!!」を出力するだけ。
ExFunction.h
//+------------------------------------------------------------------+ //| ExFunction.mqh | //| Copyright 2021, zerokara-blog. | //| https://zerokara-blog.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, zerokara-blog." #property link "https://zerokara-blog.com/" #property strict //+------------------------------------------------------------------+ //| 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 //+------------------------------------------------------------------+ // プリントテスト void printTest() { Print("Hello!!"); }
ツールバーの「コンパイル」をクリック。
エラーが出ていないことを確認。
(3) ライブラリの作成(呼び出し側)
ツールバーの「新規作成」をクリック。
「エキスパートアドバイザ」を選択し「次へ」をクリック。
ファイル名を入力し「次へ」をクリック。
「次へ」をクリック。
「完了」をクリック。
作成されたEAのひな形。
先ほど作成した関数を呼び出す処理を追加。
11行目は先ほど作った呼び出し側関数のファイル名を指定。
19行目で別ファイルの関数を呼び出す。
ExExec.mq4
//+------------------------------------------------------------------+ //| ExExec.mq4 | //| Copyright 2021, zerokara-blog. | //| https://zerokara-blog.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, zerokara-blog." #property link "https://zerokara-blog.com/" #property version "1.00" #property strict #include <ExFunction.mqh> //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- printTest(); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+
ツールバーの「コンパイル」をクリックしエラーがでないことを確認。
テスターを使ってEAを実行。さきほど作成したEAを選択し「スタート」をクリック。
別ファイルで作成した関数から「Hello!!」が出力されたことが確認できる。
この方法を使えば共通処理を別ファイルでまとめて管理することができる。
まとめ
実はライブラリをヘッダーとライブラリ別でつくっていたが呼び出し時にエラーになりヘッダに処理を書くことにした。丸一日調べて解決しなかったのであきらめた。ヘッダに処理を書いてもとりあえず動くので良しとする。ちゃんとしたい場合はライブラリを作った方がよい。
- 共通処理をコピーして使うとメンテナンスが困難になる
- 共通処理は基本的に別ファイルでまとめて管理
- 共通処理が多くなったらファイルをグループ分けする
EAの開発環境がちょっと使いづらいです。