EAを作り込んでいくうちに、
1つのファイルが1000行を超えて、
「この関数どこに書いたっけ」と探す時間が増えていないでしょうか。
この記事では、関数を`.mqh`ファイルに切り出し、
`#include`で読み込んで整理する方法を解説します。
なぜEAのコードは肥大化するのか、#includeとは何か
損切り計算、ロット計算、通知処理などを1つずつ足していくと、
メインファイルはあっという間に見通しの悪い長さになります。
1ファイルに全部書くとどうなるか
注意: 1ファイルに機能を詰め込み続けると、
同じような計算関数を別のEAでも一から書き直すことになりがちです。
修正が必要になったとき、どのEAのどこを直したか分からなくなる原因にもなります。
#include命令は単なる「コピー&貼り付け」
`#include`は、指定したファイルの中身を、
コンパイル時にその場へそのまま展開するプリプロセッサ命令です。
補足: 実行時に読み込むのではなく、
コンパイルの前段階でテキストとして貼り付ける処理です。
C言語のプリプロセッサと同じ仕組みで、MQL4・MQL5で共通です。
#includeの書き方と.mqhファイルの置き場所
書き方によって検索されるフォルダが変わります。
山括弧とダブルクォートの違い
#include <RiskUtils.mqh> //標準のIncludeフォルダから検索 #include "RiskUtils.mqh" //メインファイルと同じフォルダから検索
自作の`.mqh`ファイルをメインファイルと同じフォルダに置く場合は、
ダブルクォート表記を使います。
二重インクルード対策(#ifndef/#define/#endifガード)
同じ`.mqh`を複数のファイルから`#include`すると、
関数の「再定義エラー」が発生することがあります。
#ifndef __RISKUTILS_MQH__ #define __RISKUTILS_MQH__ //ここに関数を書く #endif
このガードを付けておけば、
2回目以降の`#include`では中身が展開されず、エラーを防げます。
関数を.mqhに切り出す実例(損切り幅計算関数)
複数のEAで使い回したい、
損切り価格を計算する関数を例に、切り出し方を確認します。
要点: 切り出す関数は、
グローバル変数に依存しない「引数だけで完結する」形にしておくと、
どのEAに`#include`しても安全に動きます。
実際に動くコード全体(メインEA+分離した.mqhファイル)
損切り幅計算の関数を`RiskUtils.mqh`に切り出し、
メインのEAファイルから呼び出す、
実際にMetaEditorでコンパイルできる2ファイル構成です。
//+------------------------------------------------------------------+
//| RiskUtils.mqh |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#ifndef __RISKUTILS_MQH__
#define __RISKUTILS_MQH__
//損切りpipsから、実際の損切り価格を計算する(引数だけで完結)
double CalcStopLossPrice(double entryPrice, double stopLossPips, bool isBuy)
{
double pipValue = _Point * 10; //5桁/3桁ブローカーを想定
if(isBuy)
return(entryPrice - stopLossPips * pipValue);
return(entryPrice + stopLossPips * pipValue);
}
#endif
//+------------------------------------------------------------------+
//| IncludeDemoEA.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link "https://creator.fx-ea-system-project.com/"
#property version "1.00"
#property strict
#include "RiskUtils.mqh"
input double InpStopLossPips = 20;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
double sl = CalcStopLossPrice(Bid, InpStopLossPips, true);
Print("買いエントリー想定時の損切り価格: ", DoubleToString(sl, Digits));
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
MetaEditorで実際に動かす手順
- MetaEditorの「ファイル」→「新規作成」→「インクルードファイル」で「RiskUtils」を作成し、中身を上のコードで置き換える
- 同じフォルダに「IncludeDemoEA」という名前でEAを新規作成し、中身を上のコードで置き換える
- F7キーでIncludeDemoEAをコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
- チャートへ適用し、「エキスパート」タブに損切り価格のログが出ることを確認する
よくあるエラーと対処
- 「cannot open include file」エラー: `.mqh`ファイルがメインファイルと同じフォルダにあるか確認してください。ダブルクォート表記は同じフォルダしか検索しません
- 「function already defined」エラー: `#ifndef`ガードを付け忘れているか、同じ関数名を別の`.mqh`にも書いていないか確認してください
- 修正したのに反映されない: MetaEditorのキャッシュが原因のことがあります。メインファイルを再コンパイルしてください
よくある質問
#includeでのファイル整理の実装でよく検索されている疑問を、
3つにまとめて回答します。
MQL5でも同じ書き方ができますか?
はい。`#include`・`#ifndef`ガードともにMQL5と共通の構文です。
この記事のコードは引数だけで完結する関数のため、
拡張子を`.mq5`に変えるだけでそのまま動きます。
クラスも.mqhに切り出せますか?
はい。CTradeクラスなど標準ライブラリのクラスも、
`Include`フォルダ内の`.mqh`ファイルとして提供されています。
自作クラスも同じ方法で切り出せます。
何行を超えたら分割すべきですか?
明確な基準はありませんが、
「複数のEAで使い回したい関数」ができた時点が分割の目安です。
行数よりも、再利用したいかどうかで判断してください。
【MQL4/MQL5共通】EAのコードが1000行を超えたら?#includeで.mqhファイルに分割整理する方法:まとめ
この記事では、肥大化したEAのコードを、
`#include`で`.mqh`ファイルに切り出して整理する方法を解説しました。
`#ifndef`ガードを付けておけば、
複数のEAから同じ`.mqh`を安全に読み込めます。
引数だけで完結する関数にしておくことが、
MQL4・MQL5どちらでも使い回せる設計のポイントです。
コメント