※当サイトはアフィリエイト広告(Amazonアソシエイツ等)を利用しています。
こんにちは。trade-engineer.com 運営者のHです。
MT4でインジケーターを自作しようとすると、まず「どのツールを使えばいいか」で詰まる人が多い。MetaEditorはMT4に標準搭載されているので、追加コストゼロで今すぐMQL4コードを書いてコンパイルできる。ただしコード補完がほぼ機能しない・バージョン管理がしづらい・バックテスト用の過去データは別途取得が必要、という3つの問題が開発を進めるうちに出てくる。この記事では、私が実際に使っているMQL4インジケーター開発ツールの組み合わせと、環境構築の手順を具体的にまとめる。
- MetaEditorはMT4付属の無料IDEで、コンパイラ・エラーログ・MQL4リファレンスが統合されている
- VS Codeに無料のMQL拡張を導入するとコード補完・シンタックスハイライトが使えるようになる
- バックテスト用の過去データはDukascopyから無料でダウンロードしてMT4に取り込める
- 頻出エラー「array out of range」はバッファ添字の上限チェックをOnCalculateに組み込むことで防げる
MetaEditorとVS Codeで作るMQL4開発環境
MQL4の開発はMetaEditor単体で完結する。しかしコード補完・バージョン管理・ファイル横断検索を考えると、VS Codeを外部エディタとして組み合わせるのが効率的だ。「MetaEditorでコンパイルし、VS Codeで書く」という役割分担が、コストゼロで開発効率を上げる現実的な構成になる。
MetaEditorの機能と基本的な使い方
MetaEditorはMT4のインストールと同時に入る統合開発環境だ。MT4のメニューバーから「ツール → MetaEditor」またはF4キーで起動できる。主な機能は、MQL4専用のシンタックスハイライト・コンパイラ・エラーログの表示・MQL4リファレンスの参照の4つ。コンパイルはF7一発で完了し、エラーがあればウィンドウ下部に行番号付きで表示される。
MetaEditorでインジケーターを新規作成するには「ファイル → 新規」を選び、「カスタムインジケーター」を選択する。ウィザードでバッファ数・表示種別(チャートに重ねるか別ウィンドウか)を設定すると、OnInit / OnCalculate / OnDeinit の骨格コードが自動生成される。このテンプレートに処理を追記していくのが基本フローだ。
コンパイル成功後、生成された .ex4 ファイルはMT4の「MQL4/Indicators」フォルダに自動配置される。MT4側でチャートのインジケーター一覧をF5で更新すれば、そのままアタッチして動作確認できる。MetaEditorのコード補完(Ctrl+Space)は動作するが精度が低く、関数名の一部を打っても候補が絞り込まれないケースが多い。複数ファイルの横断検索も弱い。これがVS Codeを併用する理由になる。
MetaEditorにはMQL4リファレンスが内蔵されており、F1キーでキャレット位置の関数の仕様を参照できる。引数の型・戻り値・サンプルコードが英語で表示される。iMA・iRSI等の組み込み指標の引数順を確認したいときはこの機能を使うと早い。ウェブブラウザに切り替える必要がないので、開発中の集中を切らさずに済む。
VS CodeにMQL拡張を導入してコード補完を有効にする
Visual Studio CodeはMicrosoftが提供する無料エディタで、拡張機能によってMQL4開発環境として使えるようになる。code.visualstudio.com から無料でダウンロード・インストールできる。インストール後、左サイドバーの拡張機能アイコンをクリックし、検索欄に「MQL」と入力する。「MQL4 & MQL5 Language Support」などの拡張が表示されるのでインストールする。
インストール後は .mq4 ファイルを開くと、MQL4のキーワード・関数・定数がシンタックスハイライトされ、コード補完も機能するようになる。関数名の最初の2〜3文字を打つと候補リストが表示され、MetaEditorより格段に補完精度が高い。
ただしVS CodeはMQL4のコンパイル機能を持たない。コードを書くのはVS Code、コンパイルはMetaEditorという分担になる。MetaEditorの「ツール → オプション → エキスパート」にある「外部エディタ」にVS Codeの実行ファイルパス(例:AppData\Local\Programs\Microsoft VS Code\Code.exe)を設定すると、MetaEditorから直接VS Codeを呼び出せるようになる。
MQL4/Indicators フォルダをVS Codeのワークスペースとして開くと、複数の .mq4 ファイルをタブで管理できる。Ctrl+Shift+F でフォルダ内の全ファイルにわたってキーワード検索できるのも、MetaEditor単体にはない利点だ。「この変数はどのファイルで定義されているか」「この関数は何箇所で使われているか」を横断的に調べる作業が数秒で完了する。
VS Codeにはソース管理パネル(Git)が組み込まれており、MQL4コードの変更差分をコミット単位で管理できる。「動いていたバージョンに戻す」が確実にできるので、アルゴリズムの試行錯誤が怖くなくなる。MetaEditorではこのバージョン管理機能が使えない。
GitとSourcetreeでMQL4コードをバージョン管理する
MQL4インジケーターの開発で「動いていたバージョンに戻せない」問題は、Gitを導入することで完全に解消できる。GitはMicrosoftが管理するオープンソースのバージョン管理システムで無料、SourcetreeはGitをGUIで操作できるAtlassian製の無料ツールだ。どちらも商用利用可能で、個人開発では費用が一切かからない。
導入手順は以下のとおり。①Git本体を git-scm.com からダウンロードしてインストール(デフォルト設定でOK)、②Sourcetreeを sourcetreeapp.com からインストール(Atlassianアカウントが必要だが無料)、③MT4のMQL4フォルダをSourcetreeで「新しいリポジトリを作成」に登録する。MQL4フォルダの標準パスは AppData\Roaming\MetaQuotes\Terminal\(端末ID)\MQL4 だ。
コードを変更するたびにSourcetreeでコミット(スナップショットを記録)する。コミットメッセージは「RSI期間を14から21に変更・USDJPY5分足バックテスト確認」のように具体的に書くと、後で履歴を見たときに意味がわかる。ワンライナーで済ませずに変更理由まで記録しておくのが重要だ。
GitHubのプライベートリポジトリ(無料)にプッシュしておけば、PCが故障してもコードを失わない。複数PCで開発を続けたい場合は pull で同期できる。Sourcetreeであれば git の CLI コマンドを覚えなくても、ボタン操作だけでコミット・プッシュ・ブランチ切り替えができる。
MQL5.comの標準ライブラリからコードを再利用する方法
MQL5.comのコードベースには、MQL4で使える無料のインジケーター・EAのソースコードが数千件公開されている。ゼロから書く前に、目的に近い実装を検索して再利用するのが効率的だ。RSI・移動平均・ボリンジャーバンドなどの技術指標名で検索すると、MQL4ソース付きのインジケーターが多数ヒットする。
ライセンスはフリーのものが多いが、商用利用・再配布の条件はソースのヘッダに記載されている。個人使用・学習目的であれば問題ないケースが大半だが、配布する場合は確認する。
MetaEditorの標準ライブラリには、iMA・iRSI・iATR・iBandsなど基本的な技術指標の計算関数が組み込まれている。例えば iRSI(NULL, 0, 14, PRICE_CLOSE, i) と書けば、現在チャートのiバー前のRSI(期間14・終値ベース)が返ってくる。自前で計算ロジックを実装する必要がない。同様に iMA(NULL, 0, 20, 0, MODE_EMA, PRICE_CLOSE, i) で20期間EMAが取得できる。
MQL5.comのコードを参考にする際の注意点として、MQL5(MT5用)とMQL4(MT4用)を混同しないようにする。配列の方向(Series配列の扱い)や関数シグネチャが異なるため、MQL5コードをそのままMQL4で使うとコンパイルエラーになる。コードベースのフィルタで「MQL4」を選択するか、ファイル拡張子が .mq4 かどうかで判断する。
デバッグにPrintとCommentを使ったログ出力の実践
MQL4にはステップ実行デバッガが実質存在しない(MetaEditorのデバッガは動作が不安定で実用性が低い)。実践では Print() 関数を使ってエキスパートログに出力する方法が現実的だ。
例えば、バッファに正しく値が入っているかを確認したいときは次のように書く。
Print("i=", i, " rates_total=", rates_total, " prev_calculated=", prev_calculated, " Buffer=", Buffer[i]);
このコードをOnCalculateの処理ループ内に置いてMT4で動かすと、MT4のエキスパートタブに各変数の値が出力される。「どのバーを処理しているか」「バッファに期待値が入っているか」を順に確認できる。
Comment() を使うとチャート左上にリアルタイムで値を表示できる。ティック単位で変化する現在値の確認に向いており、Printのようにログが大量に流れることもない。
Comment("RSI=", DoubleToString(Buffer[0], 2), " Close=", DoubleToString(Close[0], 5));
デバッグが終わったらPrint / Comment 行を削除またはコメントアウトする。ループ内でPrintが走り続けると、チャートの動作が重くなる。特に全バー再計算時にPrintが数万回発火するケースには注意が必要だ。本番リリース前に必ず除去する。
インジケーター開発からバックテストまでの実践手順
ツールを揃えたら、実際に「開発 → 動作確認 → バックテスト」のサイクルを回す手順を把握しておく。OnCalculateの設計ミスやバッファの扱いを間違えると頻出エラーにつながる。事前に正しい実装パターンを知っておくと、デバッグで詰まる時間を大幅に減らせる。
OnCalculateとバッファ設計の基本パターン
MQL4インジケーターの核はOnCalculate関数だ。MT4はバーが更新されるたびにこの関数を呼び出してインジケーターの表示値を再計算する。引数のrates_total(全バー数)とprev_calculated(前回計算完了時のバー数)を比較することで、再計算が必要な範囲を特定できる。
基本的なパターンを示す。
int start = (prev_calculated > 0) ? prev_calculated - 1 : 0;for(int i = start; i < rates_total; i++) { if(i < Period - 1) { Buffer[i] = EMPTY_VALUE; continue; } Buffer[i] = iRSI(NULL, 0, Period, PRICE_CLOSE, rates_total - 1 - i);}
ここでBufferはSetIndexBuffer()でOnInitに登録したdouble型の配列だ。Series配列の場合、インデックス0が最新バー・インデックスが大きいほど古いバーに対応する。インデックスの方向を間違えると値が逆転して表示される。
バッファ数は #property indicator_buffers で宣言した数とSetIndexBuffer()の呼び出し回数を一致させる必要がある。例えば #property indicator_buffers 2 と書いたならSetIndexBufferを2回呼び出す。不一致があるとコンパイルは通るが実行時に「Invalid index」エラーが出てインジケーターが正常動作しない。ArrayInitialize(Buffer, EMPTY_VALUE) で初期化しておくと、計算対象外のバーに前回値が残る問題を防げる。
Series配列でアクセスする場合、インデックスが rates_total を超えると「array out of range」が発生する。ループ開始前に if(rates_total < Period + 1) return(prev_calculated); のようなガードを入れるのを必ず習慣にすること。
MT4の戦略テスターでビジュアルバックテストを実行する手順
MT4の戦略テスターはEA向けの機能だが、インジケーターのビジュアル確認にも活用できる。「表示 → 戦略テスター」またはCtrl+Rで開く。戦略テスターに直接インジケーターをセットすることはできないため、インジケーターをiCustom()で呼び出す最小構成のEAを用意する方法が現実的だ。
最もシンプルな確認方法として、インジケーターをチャートにアタッチした状態でF12キーを押すと、1ティックずつ手動で進めながら挙動を確認できる(Manual Backtestとも呼ばれる)。チャートの最古バーから順に追って、シグナルが期待した位置に出ているかを目視で確認する。
戦略テスターのビジュアルモードを使う場合、EAのOnTick内でiCustom(NULL, 0, “インジケーターファイル名”, バッファ番号, シフト) を呼び出して条件判定に使う形にする。戦略テスターの「ビジュアルモード」チェックボックスをONにして実行すると、チャートの動きに合わせてインジケーターのシグナルとエントリータイミングを同時に確認できる。
テスト期間は最低でも1年分のデータを使う。USDJPY5分足で1年間だと約75,000バーになる。エントリー条件次第でサンプル数は200〜2,000件程度が目安で、100件未満のサンプルでは統計的な信頼性が低い。テスト結果で「勝率63.2%(N=847)」のように母数を必ず記録する癖をつけておく。
Dukascopyから過去データを無料で取得しMT4に取り込む
MT4のデフォルトのヒストリーデータはブローカー提供のため欠損バーが多く、精度の高いバックテストには不向きだ。外部から過去データを取得してMT4に取り込む必要がある。Dukascopyはスイスのオンラインブローカーで、1分足(M1)のヒストリーデータを無料で提供している。MT4開発者の間では標準的なデータソースとして知られている。
取得手順を示す。①Dukascopyのヒストリーデータページにアクセス(「Dukascopy Historical Data Feed」で検索)、②通貨ペア・時間足・取得期間を選択してCSVまたはJForex形式でダウンロード、③CSVをMT4が読み込める .hst 形式に変換するツール(「History Center CSV Import」等の無料ツール)で変換、④MT4の「ファイル → データフォルダを開く」でhistoryフォルダに .hst ファイルを配置、⑤MT4を再起動して「表示 → 全履歴」を確認する。
Dukascopyのデータは1999年から現在まで存在し、EURUSD・USDJPY・GBPUSDなどメジャーペアは欠損がほぼない。1ティックデータも提供されているため、ティックベースのバックテストを行いたい場合にも使える。MT4のヒストリーセンターからのデータダウンロードもできるが、ブローカーによってはデータが不足しているケースがあるため、Dukascopyから取得するほうが確実だ。
インポート後は「表示 → 全履歴」でチャートの最左端まで確認し、意図した期間のデータが入っているか確認する。入っていない場合は .hst ファイルの命名規則(EURUSDなら EURUSD1.hst のようにシンボル名+時間足番号)と、MT4が参照しているブローカーフォルダが正しいかを確認する。
array out of rangeエラーの原因とバッファ添字チェックの実装
「array out of range」はMQL4でもっとも頻出するエラーのひとつだ。配列の範囲外インデックスにアクセスしようとすると発生する。エキスパートログに「array out of range」と行番号が表示されるので、MetaEditorでその行のインデックス処理を確認する。
典型的な発生パターンは2つある。①バッファ配列のインデックスがrates_totalを超える、②iMA・iRSI等の組み込み指標関数のshift引数(第6引数)が有効なバー数を超える、だ。
対処の基本は、ループを開始する前に十分なバー数が揃っているかをチェックするガードを入れることだ。
if(rates_total < Period + 2) return(prev_calculated);
これにより、バーがPeriod本に満たない状態では計算をスキップできる。インジケーター初期化直後や、ヒストリーデータが少ない通貨ペア・時間足では特に有効だ。
また iCustom() を使って別インジケーターの値を取得する場合も同様のエラーが出ることがある。iCustom の shift 引数には rates_total – 1 – i のように計算した値を渡すが、この値が0未満または配列範囲外にならないかを事前にチェックする。
エラーが断続的に発生する場合は、MT4を再起動してデータが正常に読み込まれているか確認する。ヒストリーデータが破損していると rates_total が実際より小さい値になるケースがある。その場合は「ツール → ヒストリーセンター」でデータを再ダウンロードするか、前述のDukascopyデータに入れ替えると解消することが多い。
よく出るコンパイルエラー一覧と解決策まとめ
MetaEditorでコンパイルした際に頻出するエラーと解決策を、実際の開発で遭遇した事例をもとにまとめる。エラーメッセージの意味を把握しておくとデバッグ時間が大幅に短縮できる。
| エラーメッセージ | 主な原因 | 解決策 |
|---|---|---|
| undeclared identifier | 変数名・関数名のタイポ、または宣言前に使用 | スペルを確認し、使用前に変数宣言を行う |
| unexpected token | 括弧・セミコロンの不足、または構文エラー | エラー行前後の括弧の対応と行末セミコロンを確認 |
| parameter conversion not allowed | 関数引数に渡す型が不一致(int→doubleなど) | (double)等でキャストを明示する |
| cannot convert to string | Printにint/double型を直接渡している | IntegerToString() / DoubleToString() で変換する |
| invalid number of parameters | SetIndexBufferや組み込み関数の引数数が不正 | MQL4リファレンス(F1)で正しいシグネチャを確認 |
| array out of range(実行時) | バッファ・iMA等のshift引数が配列範囲外 | ループ前に rates_total < Period + 2 のガードを追加 |
「undeclared identifier」はタイポが9割だが、残り1割は #property strict を使ったコードで暗黙の型変換が通らなくなったケースだ。#property strict を外すとコンパイルが通るが型安全性が下がるため、根本的に型を修正するほうが望ましい。
コンパイルエラーが出たらまずエラー行番号をダブルクリックしてMetaEditorで該当行に飛ぶ。1件ずつ上から解消していく。エラー数が多い場合でも、最初の1件を直すだけで連鎖的に解消されることが多い。
MT4の開発環境を一から整えたい場合はMT4インストール手順とポータブルモード設定|FX開発者向けを先に確認してほしい。ポータブルモードを使うと複数バージョンのMT4を共存させられる。
インジケーターでアローシグナルを表示する実装はMT4で未来時間に垂直線・ラベルを表示するMQL4実装手順が参考になる。DrawArrowとVertical Lineの描画ロジックは応用範囲が広い。
開発したインジケーターをバックテストで検証したい場合はMT4チャートカスタマイズ完全ガイド|配色・定型ファイル設計手順も合わせて確認してほしい。チャート設定を整えておくとバックテストの視認性が大きく上がる。

