本記事では、MT4(MetaTrader4)で自動売買を行うために、標準搭載されている基本的なインジケーターを使ってEA(エキスパートアドバイザー)を自作する方法を解説します。プログラミング未経験の方でも、全体像をつかみやすいように構成し、実際に動くサンプルコードも掲載します。
MT4自動売買とEAの全体像
MT4では、自動売買ロジックを「EA(エキスパートアドバイザー)」というプログラムとして実装します。EAはチャートにセットすることで、事前に決めた条件に従って自動的に売買や決済を行います。
EAの大まかな役割は次の通りです。
- エントリー条件(買い・売り)を判定する
- ポジション保有中の決済条件を判定する
- 資金管理(ロット数、損切り・利確幅など)を一貫して適用する
裁量トレードと違い、EAは感情に左右されず、同じ条件を淡々と繰り返します。その一方で、ロジックが間違っていたり、想定外の相場環境に合わないと、大きなドローダウンを招く可能性もあります。そのため、設計とテストが非常に重要です。
自動売買を始めるための準備
EA開発に入る前に、最低限以下の環境を整えておきます。
- MT4がインストールされたPC
- デモ口座(本番前にテストするため)
- MT4内の「MetaEditor」が使用できること
MT4を起動したら、メニューの「ツール」→「MetaQuotes Language Editor」からMetaEditorを開きます。ここでEAのソースコード(MQL4)を編集・保存・コンパイルします。
EA開発の基本構造(MQL4の考え方)
MQL4のEAは、大きく以下の3つの関数から成り立っています。
- OnInit():EAをチャートにセットしたときに一度だけ呼ばれる初期化処理
- OnDeinit():EAをチャートから外したときや停止するときに呼ばれる終了処理
- OnTick():価格が更新されるたびに呼ばれるメイン処理(売買ロジックはここに書く)
もっとも重要なのがOnTick()で、ここで「エントリー条件に合致したら注文を出す」「ポジションの決済条件を満たしたら決済する」といったロジックを記述します。
EAの骨組みサンプル
//+------------------------------------------------------------------+
//| シンプルEAの骨組みサンプル |
//+------------------------------------------------------------------+
#property strict
int OnInit()
{
// 初期化処理(パラメータチェックなど)
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
// 後片付け処理
}
void OnTick()
{
// メインの売買ロジック
}
//+------------------------------------------------------------------+
この骨組みに対して、インジケーターの値を取得して条件分岐を書くことで、さまざまなEAを構築できます。
基本インジケーターを使ったEA作りの考え方
MT4には、移動平均線、RSI、MACDなど、代表的なテクニカル指標が標準で搭載されています。EAからは、これらのインジケーターの値を関数を通じて取得し、その値に基づいて売買条件を判定します。
ここでは以下の3つのパターンを例に、EAの組み立て方を解説します。
- 移動平均線クロスEA(トレンドフォロー)
- RSI逆張りEA(オシレーター逆張り)
- MACDトレンドフォローEA
移動平均線クロスEAの作り方
最も基本的で分かりやすい自動売買ロジックが「短期移動平均線と長期移動平均線のゴールデンクロス/デッドクロス」を利用したEAです。
ロジックの概要
典型的なロジックは次のようになります。
- 短期MAが長期MAを下から上に抜けたら買いエントリー(ゴールデンクロス)
- 短期MAが長期MAを上から下に抜けたら売りエントリー(デッドクロス)
- ストップロス(損切り)とテイクプロフィット(利確)をpips指定で設定
- 既にポジションを持っているときは新規エントリーをしない(ナンピンしない)
MQL4でのインジケーター取得
移動平均線の値は、iMA() 関数で取得します。
double fastMA = iMA(NULL, 0, FastPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
double slowMA = iMA(NULL, 0, SlowPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
double fastMA_prev = iMA(NULL, 0, FastPeriod, 0, MODE_EMA, PRICE_CLOSE, 2);
double slowMA_prev = iMA(NULL, 0, SlowPeriod, 0, MODE_EMA, PRICE_CLOSE, 2);
ここでは、1本前と2本前の足の移動平均を比較することでクロスを判定します。
移動平均クロスEAのシンプル実装例
//+------------------------------------------------------------------+
//| 移動平均線クロスEA |
//+------------------------------------------------------------------+
#property strict
extern int FastPeriod = 10;
extern int SlowPeriod = 40;
extern double Lots = 0.1;
extern int StopLossPips = 50;
extern int TakeProfitPips = 100;
int OnInit()
{
return(INIT_SUCCEEDED);
}
void OnTick()
{
// 既存ポジション数を確認
int total = OrdersTotal();
if(total > 0) return; // このEAは常に最大1ポジションのみ
// 移動平均線の値を取得
double fastMA = iMA(NULL,0,FastPeriod,0,MODE_EMA,PRICE_CLOSE,1);
double slowMA = iMA(NULL,0,SlowPeriod,0,MODE_EMA,PRICE_CLOSE,1);
double fastMA_prev = iMA(NULL,0,FastPeriod,0,MODE_EMA,PRICE_CLOSE,2);
double slowMA_prev = iMA(NULL,0,SlowPeriod,0,MODE_EMA,PRICE_CLOSE,2);
// クロス判定
bool goldenCross = (fastMA_prev < slowMA_prev) && (fastMA > slowMA);
bool deadCross = (fastMA_prev > slowMA_prev) && (fastMA < slowMA);
double sl, tp;
int ticket;
// 買いエントリー
if(goldenCross)
{
sl = Bid - StopLossPips * Point;
tp = Bid + TakeProfitPips * Point;
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, sl, tp, "MA Cross Buy", 0, 0, clrBlue);
}
// 売りエントリー
if(deadCross)
{
sl = Ask + StopLossPips * Point;
tp = Ask - TakeProfitPips * Point;
ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 3, sl, tp, "MA Cross Sell", 0, 0, clrRed);
}
}
//+------------------------------------------------------------------+
このEAは、あくまで「最も基本的な形」です。実際の運用では、トレンドフィルターの追加(上位足のトレンド方向にのみエントリーする)、時間帯フィルター(スプレッドが広がる時間帯を避ける)などの工夫が有効です。
RSI逆張りEAの作り方
次に、オシレーター指標の代表格であるRSIを使った逆張りEAを考えます。レンジ相場での反発を狙うシンプルな戦略です。
ロジックの概要
- RSIが「買われ過ぎ」水準(例えば70以上)から下抜けたら売り
- RSIが「売られ過ぎ」水準(例えば30以下)から上抜けたら買い
- ストップロスと利確をpips指定
- トレンドの強い相場ではダマシが増えるため、移動平均線などでトレンドフィルターを併用すると安定しやすい
MQL4でのRSI取得とシンプル実装
extern int RSIPeriod = 14;
extern int BuyLevel = 30;
extern int SellLevel = 70;
extern double Lots = 0.1;
extern int StopLossPips = 40;
extern int TakeProfitPips = 60;
void OnTick()
{
// 既存ポジション数をチェック(シンプル化のため1つだけ)
if(OrdersTotal() > 0) return;
double rsi = iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,1);
double rsi_prev = iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,2);
bool buySignal = (rsi_prev < BuyLevel) && (rsi > BuyLevel);
bool sellSignal = (rsi_prev > SellLevel) && (rsi < SellLevel);
double sl, tp;
int ticket;
if(buySignal)
{
sl = Bid - StopLossPips * Point;
tp = Bid + TakeProfitPips * Point;
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, sl, tp, "RSI Buy", 0, 0, clrBlue);
}
if(sellSignal)
{
sl = Ask + StopLossPips * Point;
tp = Ask - TakeProfitPips * Point;
ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 3, sl, tp, "RSI Sell", 0, 0, clrRed);
}
}
RSI逆張りEAは、トレンド相場よりもレンジ相場で機能しやすい特徴があります。そのため、上位足の移動平均線の傾きが小さい(=レンジに近い)ときだけ動かすようにするなど、フィルタリングを加えると安定性が高まります。
MACDトレンドフォローEAの作り方
MACDはトレンドとモメンタムの両方を把握しやすいインジケーターです。EAでは、MACDラインとシグナルラインのクロスやゼロライン抜けを用いてトレンドフォロー戦略を構築できます。
ロジックの例
- MACDラインがシグナルラインを下から上に抜け、かつMACDがゼロラインより上なら買い
- MACDラインがシグナルラインを上から下に抜け、かつMACDがゼロラインより下なら売り
- 損切り・利確は移動平均線と同様にpips指定
MQL4でのMACD取得とエントリー判定
extern double Lots = 0.1;
extern int StopLossPips = 60;
extern int TakeProfitPips = 120;
void OnTick()
{
if(OrdersTotal() > 0) return;
double macd_current, signal_current, macd_prev, signal_prev;
macd_current = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
signal_current = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1);
macd_prev = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2);
signal_prev = iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,2);
bool buySignal = (macd_prev < signal_prev) && (macd_current > signal_current) && (macd_current > 0);
bool sellSignal = (macd_prev > signal_prev) && (macd_current < signal_current) && (macd_current < 0);
double sl, tp;
int ticket;
if(buySignal)
{
sl = Bid - StopLossPips * Point;
tp = Bid + TakeProfitPips * Point;
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, sl, tp, "MACD Buy", 0, 0, clrBlue);
}
if(sellSignal)
{
sl = Ask + StopLossPips * Point;
tp = Ask - TakeProfitPips * Point;
ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 3, sl, tp, "MACD Sell", 0, 0, clrRed);
}
}
MACDはトレンドの強さを捉えるのに適している一方で、レンジ相場ではダマシが増えやすい傾向があります。移動平均線クロスや価格のブレイクアウト条件と組み合わせることで、より安定したEAに発展させることができます。
EAに必須のリスク管理ロジック
どれほど優れたロジックでも、リスク管理が不十分だと長期的に資金を守ることは難しくなります。EAに組み込むべき基本的なリスク管理の考え方を整理します。
1トレードあたりのリスク許容度を決める
一般的には、1回のトレードで口座残高の1〜2%を超えるリスクを取らないようにすると、連敗が続いても資金が急激に減りにくくなります。EAでは、ストップロスの幅と口座残高からロット数を自動計算する関数を用意すると便利です。
最大ポジション数・最大ドローダウンの制限
同時に保有するポジション数を制限したり、一定以上のドローダウンが発生したらEAを自動停止する仕組みを組み込むことで、想定外の連敗から資金を守りやすくなります。
スプレッド・約定品質のチェック
EAは、スプレッドが急に広がった局面でも条件を満たせば注文を出してしまいます。スプレッドが一定以上のときはエントリーしない、重要指標発表前後は取引を避けるなどの制御も検討します。
バックテストと最適化の進め方
EAを実際に運用する前に、過去チャートでシミュレーション(バックテスト)を行うことは必須です。MT4の「ストラテジーテスター」を使えば、過去データを用いたEAの検証が可能です。
バックテストの基本手順
- テストしたい通貨ペアと期間(例:EURUSDの過去5年)を選択する
- モデル(ティック、1分足など)を選ぶ
- パラメータを設定してテストを実行する
- 損益グラフ、勝率、最大ドローダウン、プロフィットファクターなどを確認する
良さそうな結果が出たら、パラメータを少し変えても傾向が崩れないかを確認します。ごく狭い範囲でしか成績が良くないEAは、過去データへの「当てはめすぎ(過剰最適化)」である可能性が高くなります。
フォワードテストの重要性
バックテストで良い結果が出ても、本番と同じような条件でデモ口座に一定期間動かしてみる「フォワードテスト」を行うことで、実際の約定やスプレッドの変動を含めた挙動を確認できます。バックテストと大きく乖離する場合は、ロジックや前提条件を見直す必要があります。
実運用前にチェックしたいポイント
EAを本番口座で動かす前に、次のような点をチェックしておきます。
- VPSなど常時稼働できる環境を用意しているか
- ブローカーの約款や取引条件(最小ロット、最大ロット、スプレッド、マージンコール水準など)を把握しているか
- 想定外の急変動時に、EAが連続発注をしてしまわないか
- メンテナンス時間帯やサーバーダウン時の振る舞いを確認しているか
また、運用開始後も定期的に成績をモニタリングし、「バックテストやフォワードテストで想定していた挙動と大きく異なっていないか」を確認することが重要です。
よくある失敗パターンと改善のヒント
EAを初めて自作・運用する際によくある失敗パターンとして、次のようなものがあります。
- 過去データで成績が良くなるまでパラメータをいじり続けてしまう(過剰最適化)
- 損切りが極端に狭く、スプレッドやノイズで簡単にヒットしてしまう
- 逆に損切りが広すぎて、1回の損失が大きくなりすぎる
- ナンピンやマーチンゲールを安易に取り入れてしまい、急変動で大きな含み損を抱える
改善の一歩として、「単一インジケーターのシグナルに頼り過ぎない」「異なるタイプのインジケーター(トレンド系+オシレーター系)を組み合わせる」「上位足の環境認識を取り入れる」といった工夫が挙げられます。
まとめ:まずはシンプルなEAを1つ完成させる
MT4の基本インジケーターを使ったEA作りは、決して難解なものではありません。移動平均線クロス、RSI逆張り、MACDトレンドフォローなど、シンプルなロジックでも、ルールを明確にして機械的に実行することで、裁量トレードでは見えなかった課題や可能性が見えてきます。
まずは本記事のサンプルコードを参考に、1つのEAを完成させ、バックテストとフォワードテストを丁寧に重ねてみてください。その過程で、「どのような相場環境に強いのか」「どこでドローダウンが発生しやすいのか」が具体的に把握でき、ロジック改善や新しい戦略のヒントにつながります。
シンプルなEAを出発点に、インジケーターの組み合わせやリスク管理の工夫を重ねながら、自分のスタイルに合った自動売買戦略を構築していくことが、長く市場に残り続けるための近道となります。


コメント