プログラミング経験がない方を対象に自作EAの作成方法を1から説明したいと思います。
EAを動かしてみたいけど、販売されているEAは高いから自分で作りたい!と思っている方が多いかと思います。
かつては私もプログラミングが分からず、MQLを1から勉強した身です。MQLの学習で苦戦した点も交えて解説できたらと思います。
プログラミング経験がある方はプログラミングの基礎知識の部分は読み飛ばしていただいて大丈夫です。
準備するもの
今回はMT4(MetaTrader 4)の環境構築に必要な準備物についてご説明します。以下の2つが必要となります。
- Windowsのパソコン
- MT4※
※MT4とは、MetaQuotesが開発した外国為替取引(FX)のチャートソフトウェアです。リアルタイムで価格の動き表示し、自動売買が可能なツールです。MT4のダウンロードはこちらから行えます。
MT4を稼働させるためには、Windowsが搭載されたパソコンが必要となります。もちろん、Mac版のMT4も存在します。しかし、今回はWindowsでの使用を前提として進めていきます。Macの方は、Windows環境を整備するか、専用のMac版MT4をご利用ください。
新規EA作成
まずはEAの原型となるファイルを作っていきます。
MT4を開いたらメタクォーツ言語エディタのボタンを押します。

MeTaEditorが開いたら「New」ボタンを押します。

EAを作成するのでエキスパートアドバイザーを選択します。

「Experts¥」の文字の後に入力するのがEAの名前になります。適当にEAの名前をつけて「次へ」ボタンを押します。

「次へ」ボタンを押して進めます。

「完了」ボタンを押します。

すると下のようなEAの元となるソースが作成されます。

今回はわかりやすくするために「int OnInit()」だけを記述したソースを元に説明します。

プログラミングの基礎知識
MT4はMQLと呼ばれるプログラミング言語を使います。MQLはC言語と呼ばれる言語に似ています。
C言語に触れたことがあればとっつきやすいのかな、と思います。ここではプログラミングが全く分からない方向けにお話しますのでご安心下さい。
MQLでEAを作成していく前に、まずはプログラミングで知っておきたい基本的な知識を紹介します。
変数、型とは?
変数とは、情報(値)を格納するための「箱」のようなものです。
プログラミングにおいて、様々な種類の情報(例えば数字や文字)をこれらの変数に保存し、変数を使って処理を行います。変数を作る際には、それがどのような情報を格納するかを表す「型」と、その変数自体を指し示す「名前」が必要となります。
型とは、変数が保持する情報の種類を明示するためのラベルのようなものです。これにより、プログラムが変数にどのようなデータが入っているかを瞬時に理解することができます。例えば、型が「int」である変数は、整数のみを格納することができます。
型の主な種類としては以下のようなものがあります:
- int(整数型)
- string(文字型)
- double(少数点を含む数値型)
これらの型と変数名を組み合わせて、「型 + 変数名」の形で変数を作成します。
型 + 変数名
で変数を作成することできます。
例えば:
文字列型変数 string mojihensu
数値型変数 int suutihensu
変数を作成したら、その「箱」に具体的な値を格納します。これは以下のように記述します:
mojihensu = "文字列";
suutihensu = 1;
これにより、mojihensuという変数には"文字列"という文字データが、suutihensuという変数には1という数値データがそれぞれ格納されます。
コメントとは?
プログラミングの記述をしていると自分がどんな意図や意味でコードを書いているのか忘れるときがあります。その対策として、コメント(メモ)を書いておけば忘れるのを防ぐことができます。
コメントの書き方は2つのスラッシュの後に記載します。
例)
// 数値変数に1を入れるよ
suutihensu = 1;
関数とは?
関数とは何か入れると何かを返してくれる機能のようなものです。具体的に言うとスマートスピーカーのようなイメージです。スマートスピーカーに何か喋りかけると応答してくれます。関数もこれと同じです。
関数の書き方は
型 + 関数名 + (入力) + { + }
です。
型は関数を実行した時に返してくれる変数の型になります。何も値を返したくない場合は型のところをvoidと記述します。
何か値を返す関数は{}の最後にreturnという記述をします
例)
入力された文字をそのまま返す関数(オウム返しみたいな関数)
String mojiwokaesuyo(String nyuuryoku) {
return nyuuryoku;
}
何も返さず、処理だけ実行する関数
void mojiwokaesuyo(String nyuuryoku) {
//~なんかの処理
}
引数とは?
引数とは関数に入力する変数のことです。例えば、先ほど説明したオウム返しの関数を見てみましょう。この関数で言うと「String nyuuryoku」の部分が引数と呼ばれるものです。
String mojiwokaesuyo(String nyuuryoku) {
return nyuuryoku;
}
初期化関数とは?
int init(){ }
EAを起動させるときに最初に呼び出される関数のことを初期化関数と言います。関数名はinitとなっております。(関数名はMT4のバージョン等により異なります)
初期化関数はEAを起動させる前や、最初にやっておきたい処理がある場合などに使います。
スタート関数とは?
int start(){ }
チャートのティックが動くたびに呼び出しされる関数をスタート関数と言います。
EAの注文とかを出すメインの処理は基本的にこの関数に書きます。
終了関数とは?
int denit() { }
EAを終了させるときに呼び出しされる関数を終了関数と言います。
EAがトラブルによって終了して、ポジションをクローズしたい時などに使います。
注文関数とは?
int OrderSend(string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit, string comment, int magic, datetime expiration, color arrow_color );
とりあえずこの関数を使えば注文を出すことができます。
詳細はここでは省きます。
サンプルソース
ここまで説明した知識を使って注文を出すEAを作成してみましょう。
// 使う値を変数に格納する
// 売買ロット数
double Lots = 0.1;
// 許容スリッページ
int Slippage = 0.3;
// マジックナンバー
int MagicNo = 1;
int start() {
// 買い処理
OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,0,0,"buy",MagicNo,0,Blue);
// 戻り値
return(0);
}
これだけの記述でひたすら買い注文を出すだけのEAが完成です。絶対本番では動かしてはいけません。
コンパイルをする
ソースコードを書いたらソースを機械語に変換するためにコンパイルという作業を行います。コンパイルという作業をしないままだと記述したプログラムは実行できません。

「コンパイル」ボタンを押すとコンパイルできますが、このときソースの記述ミスがあった場合エラーとなります。
エラーがでた場合はソースを修正して再度コンパイルしましょう。エラーが解消されない限りコンパイルは成功しません。
よくあるエラー
- 全角スペースがある
- 型の不一致
バックテストする
EAが完成したらバックテストをしましょう。
バックテストの方法はこちらに記載しております。
EAの基本的なコードがわかったら今度はもう一歩踏み出して実際にEAを作成してみましょう。
EAの外部パラメータを記述してみよう
extern int MagicNo = 1; // 買いマジックナンバー
extern int Slippage = 30; // 許容スリッページ
extern double LotSize = 0.1; // 売買ロット数
変数の前にexternと記載することで変数を外部パラメータとして定義することができます。外部パラメータで定義した変数にはEA稼働時にパラメータとして指定できるようになります。
インジケータの値を取得してみよう
インジケータを取得する場合は専用の関数が用意されていますので関数をそのまま記述するだけで簡単にインジケータの値が取得できます。
今回はボリンジャーバンドの値を取得してみます。 ボリンジャーバンドはiBandsという関数を使えばボリンジャーバンドの値を取得できます。 iBandsという関数を詳しく見ていきましょう。
double iBands(string symbol,int timeframe,int period,double deviation,int bands_shift,int applied_price,int mode,int shift);
string symbol
通貨ペアを指定するための引数です。現在のチャートの通貨ペアの値を取得したい場合はNULLを指定します。
int timeframe
時間軸を指定するための引数です。現在のチャートの時間軸を指定したい場合は0を指定します。
int period
ボリンジャーバンドの期間を指定するための引数です。
double deviation
σ(シグマ)を指定するための引数です。
int bands_shift
ボリンジャーバンドの値を右にいくつシフトするかを指定するための引数です。
int applied_price
ボリンジャーバンドの計算に適用する価格を指定するための引数です。
int mode
ボリンジャーバンドの上下バンドを指定するための引数です。
int shift
ボリンジャーバンドの計算結果の取得位置を指定するための引数です。
実際にボリンジャーバンドの値を取得してみましょう。
// 1つ前の足のボリンジャーバンドの+2σで上バンドの値を取得
double BollingerBand = iBands(NULL,0,60,2,0,PRICE_CLOSE,MODE_UPPER,1);
エントリーの条件を決めよう
今回はボリンジャーバンドの+2σで逆張りとしてみます。
if(High[1] >= BollingerBand){
OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,Close[0] + 0.5,Close[0] - 0.5,"sell",MagicNo,0,Red);
}
High[1]
一つ前の足の高値を取得します。
ifを使用して括弧の中の条件を満たした場合に指定する処理を実行することができます。
OrderSendという関数を用いることで注文を出すことができます。 OrderSend を詳しく見ていきましょう。
int OrderSend(string symbol,int cmd,double volume,double price,int slippage,double stoploss,double takeprofit,string comment=NULL,int magic=0,datetime expiration=0,color arrow_color=clrNONE);
string symbol
通貨ペアを指定するための引数です。現在のチャートの通貨ペアの値を取得したい場合はNULLを指定します。
int cmd
注文方法を指定します。
double volume
ロットを指定します。
double price
注文価格を指定します。
int slippage
最大スリッページを指定します。
double stoploss
ストップロスを指定します。
double takeprofit
テイクプロフィットを指定します。
string comment
注文時のコメントを指定します。
int magic
マジックナンバーを指定します。
datetime expiration
注文の有効期限を指定します。
color color arrow_color
注文が通った時にチャート上に表示する矢印の色をしています。
クローズ条件を決めよう
今回はボリンジャーバンドの逆側のバンドに達したら決済してみます。
// クローズ処理 for(int i = OrdersTotal() - 1; i >= 0; i--){
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)){ // 本EAのポジションの場合
if(OrderMagicNumber() == MagicNo){
if(OrderType() == OP_BUY){
if(High[1] >= iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,1)){
OrderClose(OrderTicket(),OrderLots(),Bid,pSlippage,White);
}
}
if(OrderType() == OP_SELL){
if(Low[1] <= iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_LOWER,1)){
OrderClose(OrderTicket(),OrderLots(),Ask,pSlippage,White);
}
}
}
}
}
for分を使うことで処理を繰り返すことができます。
for(int i = OrdersTotal() - 1; i >= 0; i--)は注文の最大数から0まで処理を繰り返すという意味なのでつまり、今の注文すべてに対して処理することになります。
最後に全体のコードを見てみましょう。
後はコンパイルすれば完成です。
extern int MagicNo = 018907; // 買いマジックナンバー
extern int Slippage = 30; // 許容スリッページ
extern double LotSize = 0.1; // 売買ロット数
//+------------------------------------------------------------------+
//| スタート関数 |
//+------------------------------------------------------------------+
int start(){
static datetime time = Time[0]; //バーの始値でトレード可能かチェック
if(time != Time[0]){
time = Time[0];
if(!IsTradeAllowed() || OrdersTotal()!=0){
return(0);
}
// クローズ処理
for(int i = OrdersTotal() - 1; i >= 0; i--){
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)){
// 本EAのポジションの場合
if(OrderMagicNumber() == MagicNo){
if(OrderType() == OP_BUY){
if(High[1] >= iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,1)){
OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White);
}
}
if(OrderType() == OP_SELL){
if(Low[1] <= iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_LOWER,1)){
OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,White);
}
}
}
}
}
// ボリンジャーバンドの+2σで上バンドの値を取得
double BollingerBand = iBands(NULL,0,60,2,0,PRICE_CLOSE,MODE_UPPER,1);
if(High[1] >= BollingerBand){
OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Close[0] + 0.5,0,"sell",MagicNo,0,Red);
}
}
return(0);
}
EA自作ツールの活用
もし、コードの理解が難しい場合は、EAつくーるというソースコードを自動生成してくれるソフトをオススメします。EAつくーるを用いれば、自分の作りたい条件でEAをプログラミングなしで作成できます。
できた後のソースコードの参考にしてEA作成の勉強をしていくのもありです。また、プログラミングができない人でもEAを簡単に作成することができます。
実は、私自身はプログラミングの知識があるため、このツールには頼らなかったのですが、後になってその効率の良さに驚きました。挫折しそうになる前に、この商品を使ってみてください。
また、一通りの知識が身についた後も、このツールはコード作成の時短ツールとして非常に役立ちます。プログラミング学習の加速には欠かせない商品ですよ。
使い方も動画で解説されているので安心です。
書籍で学ぶ
もし1からしっかりと学びたいならば、入門として「FXメタトレーダー入門 現代の錬金術師シリーズ」という書籍の購入をおすすめします↓
私も初心者時代にお世話になった書籍です。こちらの書籍をマスターした後に次のステップに進みましょう。
EAを作っている時間を短縮したい場合
EA作成代行を使用して、代わりに自分の作りたいEAを作ってくれるサービスの活用をオススメします。
スキルも時間もないけど、アイデアがあるという方はサクッと依頼するだけでEAを作成することができます。
ただし、代行は作りたいEAの仕様を明確に言語化する必要がありますので、全くの初心者がいきなり代行を頼むのはハードルが高いかもしれません。