ここでは簡単なEAの作成方法を紹介します。メタトレーダ上で動作するEAはMQLというC言語に非常に似ている言語で記載します。このため、以下の内容はC言語を理解している人を対象としています。また、サンプルとして作成するEAは残念ながら儲かりません。すいません・・・。


雛形の作成

 まず、雛形となる空のプログラムを作成します。

@メタトレーダーのナビゲーター画面から「Expert Advisors」を右クリックし「作成」をクリックします。




Aエディターが開くと同時に下記の画面で、どのようなプログラムを作るのか聞かれるので一番上の「Expert Advisor」を選択します。




B Nameの欄に適当な名前を書き込み「完了」ボタンを押します。




C次のような画面が開き何も処理をしない雛形のプログラムが完成します。



【参考】メタトレーダーに付いているメタエディターはインストール時には日本語が表示できません。
  「Tools」の「Options」から下記の設定をすることで日本語が表示可能となります。
  但し、日本語の利用はコメントの中のみでありAPIの引数に指定することは出来ません。



コンパイル

 とりあえず、何もしないプログラムだとコンパイルが上手くできているかも確認できないので画面に何か表示させてみます。

@先ほどのソースの上にあるinit()関数を下記のように変更してみてください。init()はEAが起動されて一番最初に実行される関数です。また、Comment() はチャートの左上に文字列を出力する関数、Alert()はメッセージをポップアップで知らせる関数、ObjectCreate()はチャート上に色々なオブジェクト(矢印や水平線、垂直線など)を引くことが出来ます。

int init()
  {
    Comment("EA test program.");
    Alert("EA Alert test.");
    ObjectCreate("test line",OBJ_HLINE,0,0,Close[0],0,0,0,0);
    return(0);
  }

A下記のようにサンプルコードを3行追加したらメニューボタンにある「Compile」を押してコンパイルを開始します。コンパイルは瞬間に終了しますので一番下の「Description」画面にerror,warning共に0件であることを確認します。




Bコンパイルが完了したらメタトレーダの画面に戻ると下記のように今作成したtestという名前のEAが存在しています。




Cこれをチャート上にのせて起動します。今回のEAは、どの通貨でも、何分足のチャートでもかまいません。




Dこれをチャート上にのせて起動します。今回のEAは、どの通貨でも、何分足のチャートでもかまいません。実行すると、Comment("EA test program.");によりチャートの左上に小さく"EA test program."と表示されます。



 また、Alert("EA Alert test.");によりポップアップ画面が表示されます。



そして、ObjectCreate("test line",OBJ_HLINE,0,0,Close[0],0,0,0,0); により現在値で水平線が表示されました。




一番簡単なEA

 ここではEAとして最低限の動きをするサンプルEAを作成していきます。このEAが儲かればよいのですが残念ながらバックテスト(後で実施方法も紹介します)を、色々なパラメータで頑張っても儲かりません。つまり、ロジック的に儲からないのです。まぁ、右肩上がりの良いEAが簡単にできたら簡単に公開なんてしないですけどね。

@EAのプログラム構成
 先ほど空の雛形プログラムを作成しましたがこの中には以下の3つの関数が出来ていました。
 init()  →EAを起動したときに一度だけ実行されます
 deinit() →EAをチャートから削除するときに実行されます
 start() →チャートの足が確定したら実行されます。5分足なら5分足が確定したタイミング(5分契機)
        で実行されます。

 つまり、start()関数にて買い、売りシグナルを判断してシグナルが発生したら売買操作をすればよいのです。


Aサンプルプログラム
 それでは、いきなりサンプルのstart()関数をお見せします。エラールートもなく実用には耐えませんが理解してしまえばそれらは自分で追加していけると思います。細かい説明は後にしていきますので全体の流れを理解してください。このstart()関数が設定するチャートの確定タイミングで呼び出されます。
 【ソースファイル】 demo-ea.txt




Bポジション確認処理
 まず最初はポジションを確認しています。これがないと、シグナルが発生すると何ポジションも持ってしまいます。ここで使用する関数はOrdersTotal()関数です。ちなみに、メタエディターでOrdersTotal()の箇所にカーソルを持って行きF1キーを押すと関数仕様が画面下部に表示されるので便利です。



Cシグナルチェック処理
 ここではボリンジャーバンドを使用してシグナル判定をしています。所詮、儲からないシグナルですからロジックはあまり気にしないでください。
 ここで使用している iBands()はボリンジャーバンドの値を返す関数です。第1引数から第3引数までは以下の通りです。それ以降は関数仕様をよんでください(^_^;)
 (1)通貨(NULLを指定したときは実行されたチャートの通貨となります)
 (2)ボリンジャーバンドを算出する期間(0を指定するとチャートの期間になりますが、ここではあえて
   PERIOD_M5(5分足)を指定しています)
 (3)ボリンジャーバンドの平均を出す回数です
   サンプルでは5分足×25回の平均としています。

また、Close[i]とか、Close[0]という配列を利用しています。これはメタトレーダがstart()関数を呼び出す度に最新の値を設定してくれる配列です。Close[0]は直前の終値、Close[1]はその前(5分なら最後の5分足の1つ前の足の終値)となります。同様にOpen[]、High[]、Low[]も存在して簡単にアクセスができます。
 また、これらは現在のチャートの通貨と足限定となりますがiOpen()、iClose()、iHigh()、iLow()を使うと
好きな通貨、好きな足、好きな位置の情報が取得できます。
 例えば、iHigh("GBPJPY",PERIOD_1H,0) としたら、現在のGBPJPY通貨で直近1時間足の最高値が取得できます。

 ※注意 通貨として指定している "GBPJPY" はやっかいなことにFX会社により異なっています。
       FOREX は"GBPJPYFXF"となりますし、121証券は素直に"GBPJPY"です。
       プログラム中で通貨を指定すると通貨を変更する度に再コンパイルが必要になることも
       面倒なので、殆どのEAはプログラム中ではNULLを指定してチャートの通貨を利用することに
       しているようです。


D売買処理
 実際の売買はOrderSend()関数を使用します。第1引数から第10引数までは以下の通りです。それ以降は関数仕様をよんでください(^_^;)
 (1)通貨(ここはNULL指定出来なかったような気が・・・
   Symbol()関数は現在のチャートの通貨を返します。なのでチャートの通貨で取引する指定です。
 (2)OP_BUY なら買い、OP_SELLなら売りとなります。
   OP_BUYLIMITで指値買い、OP_SELLLIMITで指値売りなども出来ますが使ったことはありません。
 (3)ロット数となります。
   一番最後に説明しますがロット数はSG_LOTという外部変数にしています。
   (プログラムの先頭にありますね)
 (4)買値、売値を指定します。但し成り行きの場合はAsk/Bidを設定します
 (5)許容するスリッページを指定します。どの程度の値がよいのか未だによく分かりません。
 (7)損切り価格を指定します。不要なときは0を入れます。サンプルでは終値(=売買値に近いだろう
   という手抜き)から許容損失(SG_LOSS)で指定した値を固定的に引いたものにしています。
 (8)利食い価格を指定します。不要なときは0を入れます。サンプルでは終値(=売買値に近いだろう
   という手抜き)から利食い価格(SG_STOP)で指定した値を固定的に足したものにしています。
 (9)コメントです。ここに書き込んだ文字列はメタトレーダの保持ポジションのイランで確認できます。
   自分は複数のEAを同一口座で動作させるためmagic番号を設定することが多いです。
 (10)マジック番号です。この値を元にEAは自分が生成したポジションかどうかを判断します。
   このサンプルでは使用していませんが。


E外部変数の定義
 プログラム先頭には外部変数を定義しています。externで定義した変数がそのままEAのパラメータとなり、EAを実行するタイミングで変更が可能となります。この為、ロジックに関連するパラメータや購入ロット数、magic番号などはexternにて宣言する事が定石となっています。







少し実用的にするために

 サンプルプログラムでは初めて見る人でもわかりやすく説明するために最低限の機能に絞り込みました。もう少し実用的にするための機能を紹介します。

@メール送信機能
 メタトレーダーにはプログラム中からメールを送信する機能があります。例えばシグナルが発生してポジションを保有したときなどに携帯にメールを飛ばすなどが可能です。
 プログラム中では SendMail("Buy position start" ) 等とします。少し工夫すると購入したときの値段なども付与できます。その時は下記のメタトレーダーのオプション画面のE-メールを設定する必要があります。但し、メタトレーダは「POP before SMTP」などのセキュリティが強化されたメールサーバは使用出来ません。(最近のプロバイダーが提供するメールは殆ど POP before SMTPなので事実上使えないのですが 正規のメールソフトを同時に起動させ定期的にPOPにてメール受信をしているとすり抜けは可能です)




A起動チャートのチェック
 EAを作るときに、時間足を決めて作成することも多いと思います。init()関数ないで次のように期待する時間足(下記の場合は5分足でない場合はエラーとしている)のチェックが可能となります。
  if(Period() != PERIOD_M5){
    Alert("Period is not M5 .");
    return(-1);
  }

Bログの出力
 プログラムを組むと必ずデバッグが必要です。バックテストでもデバッグは出来ますが実際に運用させると様々なことが発生します。特に取引関連のOrderSend()関数などは色々エラーも返してきます。このため、エラールートには必ず Print()関数を入れておくことをお勧めします。その時の引数やマジック番号、メタトレーダから返されるエラー番号(GetLastError()関数で取得)など必要な情報をPrint()関数で出力しておきます。これらはexpoerts画面に表示されると共に experts/logs 配下にファイルとして格納されます。

  Print("magic="+magic +" xxxx="+xxx , GetLastError());




C複数EAの同時起動
 サンプルのプログラムでは既にポジションを持っていた場合は、そのポジションが決済されるまでは新たなポジションは持たないように以下のようなガード処理を入れています。



 但し、この処理で使用しているOrdersTotal()は手動で保持したポジションや、他のEAのポジションもカウントされてしまいます。つまり、他のEAや手動で保持したポジションがあると新規の購入がされません。この問題を回避するには保持されているポジションが自分が売買したものかどうかチェックする必要があります。この方法としてマジックナンバーが役に立ちます。マジックナンバーは、OrderSend()関数で指定しポジションと対応させてシステムが覚えていてくれます。そこで、存在しているポジションについてマジックナンバーが同一であれば自分が保持したポジション、違えば他のEAや手動で売買したポジションと分かるわけです。



 この例では、OrdersTotal() 関数で保持されているポジションの数を取得し、OrderSelect()関数で着目するポジションを設定し、OrderMagicNumber()関数で着目しているポジションのマジックナンバーを取得しています。この値が自分が使用しているマジックナンバーと同じであれば自分が立てたポジションと判断するわけです。

 市販のEAの注意書きとして、「同一の口座で他のEAと同時に実行する場合にはマジックナンバーが重ならないようにしてください」と書いてあるのはこのためです。

Dエラー処理について
 サンプルプログラムでは下記のようにOrderSend()関数について全くエラー処理は入れていません。しかし、実際に動作させるとOrderSend()関数はエラーが返ることが多いです。特に値動きが激しい時間帯はエラーが返ってきて売買が出来ないこともしばしばあります。
 このような場合、サンプルプログラムの様に特にリトライせずに次の契機(5分足なら5分後)に再度、シグナル判定を行うということも出来ますが、せっかくのチャンスですので実運用するプログラムでは何回かリトライさせた方が良いかもしれません。





バックテスト

 EAの作成が完了したら過去の為替のデータと照らし合わせて過去にもしこのEAを動作させていたら、どのくらいの利益が上がるか(バックテスト)を確認していきます。バックテストのやり方は長くなるので別の章にまとめました。



EAを作成するメリット

  商品EAの紹介にもあるように巷では色々なEAが販売されており、安いものでは9,800円から安定稼働出来るものもあります。そのような中、時間と手間暇をかけてEAを自作するメリットは?と言われると、一番の理由は「作成する過程自体が楽しい」につきると思います。
 アイディアを考え、プログラムにより具現化し、バックテストを行って実際の運用でどのような傾向となるか確認する。そして実際に運用して利益が出れば出来の良い子供?のような感覚です。(逆に利益が今ひとつのEAは出来の悪い子供のよう(^_^;))
 また、販売されているEAはロジックが非公開のものも多い為、含み損が増加してくると不安が増します。例えバックテストが公開されていてもバックテストの罠に記載しましたが、もしかしてこのロジックは細工されていてバックテストはうまくいくが、最近の相場ではダメなんじゃないかなど余計な心配も生まれます。自分が作成したものはロジックが100%分かっているので、例え損失が出ても一時的なものなのか今の相場にあわないのか判断する材料はあります。