AI EA スクール
0記事中 0記事 読了
カリキュラム 第4章 EAを作る MetaEditorで新規EAファイルを作る
4-1

MetaEditorで新規EAファイルを作る

読み終わるまでの目安 約20分

この記事でできるようになること

  • MetaEditorのウィザードで新しいEAファイルを作れる
  • 自動生成されたコードを消して、サンプルEAのコードを貼り付けられる
  • EAファイルがどこに保存されているか分かる

準備するもの

  • MT4(デモ口座でログイン済み)
  • この記事に載せているサンプルEAのコード(MA_Cross_Sample.mq4)

この章では、まずスクール共通のサンプルEA「MA_Cross_Sample」で練習します。第3章でChatGPTに作ってもらった自分のコードは、サンプルで一度成功したあとに、同じ手順で貼り付けてください。「まず確実に動くもので手順を覚える」ためです。

手順

手順1 MetaEditorを開く

MT4を起動し、キーボードの [F4] を押します。ツールバーの「MetaEditor」アイコンを押しても同じです。要確認

別ウィンドウでMetaEditorが開きます。画面は第2章で確認したとおり、左にファイル一覧(ナビゲータ)、中央にコード、下にメッセージ欄(ツールボックス)という構成です。要確認

ここに画面写真を入れてくださいMT4のツールバーのMetaEditorアイコンと、開いたMetaEditorの全体画面4-1-01.png

手順2 ウィザードで「エキスパートアドバイザ」を選ぶ

MetaEditorの左上「ファイル」→「新規作成」を押します([Ctrl]+[N] でも可)。「MQLウィザード」という画面が開きます。要確認

一覧の中から「エキスパートアドバイザ(テンプレート)」を選んで「次へ」を押します。要確認

似た名前の項目がいくつか並んでいますが、「カスタムインディケータ」「スクリプト」はEAではないので選ばないでください。

ここに画面写真を入れてくださいMQLウィザードの最初の画面で「エキスパートアドバイザ(テンプレート)」を選択した状態4-1-02.png

手順3 名前をつける

「名前」欄に MA_Cross_Sample と入力します。要確認

名前のルールは次のとおりです。

  • 半角英数字とアンダースコア(_)だけを使う(日本語やスペースは避ける)
  • 拡張子(.mq4)は自動で付くので入力しない

「作者」「リンク」欄は空欄でかまいません。下に「パラメータ」を追加する欄がありますが、ここも何も追加せずに「次へ」を押します。要確認

ここに画面写真を入れてくださいウィザードの名前入力画面に「MA_Cross_Sample」と入力した状態4-1-03.png

手順4 残りの画面はそのまま「完了」する

続けて「イベントハンドラ」「テスターのイベントハンドラ」といったチェックボックスの画面が出ます。要確認 どれもチェックを変えずに「次へ」→「完了」と進みます。

これから中身をすべて貼り替えるので、ここで何を選んでも結果は同じです。

完了すると、中央にコードがすでに書かれた状態で「MA_Cross_Sample.mq4」が開きます。これはMetaEditorが自動で作った「ひな形」です。

ここに画面写真を入れてくださいウィザード完了後、自動生成されたコードが表示されたMetaEditor4-1-04.png

手順5 自動生成されたコードをすべて消す

中央のコード部分を1回クリックしてから、[Ctrl]+[A](すべて選択)→ [Delete] を押します。コードが全部消えて、真っ白になればOKです。

「せっかく作られたコードを消していいの?」と思うかもしれませんが、ひな形は「何もしないEA」なので、消して問題ありません。

ここに画面写真を入れてくださいコードをすべて消して空になったMetaEditorの中央画面4-1-05.png

手順6 サンプルEAのコードを貼り付ける

下のコードが、このスクールの共通教材「MA_Cross_Sample.mq4」の全文です。移動平均線クロス(短期線が長期線を上抜けで買い、下抜けで売り)の、いちばん基本的なEAです。第3章の実例1のプロンプトで頼んだ内容と同じ仕様になっています。

コードブロックの右上の「コピー」を押すか、枠内をすべて選択してコピーし、真っ白になったMetaEditorの中央に [Ctrl]+[V] で貼り付けてください。

コードの内容は読まなくて大丈夫です。ただ、input で始まる行の数字(20、50、50、30、0.1、12345)が、前の章の仕様シートの値と同じであることだけ、眺めて確認しておいてください。ここは変えなくてOKです。

//+------------------------------------------------------------------+
//|                                          MA_Cross_Sample.mq4     |
//|  スクール用サンプルEA: 移動平均線クロス                          |
//|  短期MAが長期MAを上抜けで買い、下抜けで売り                        |
//+------------------------------------------------------------------+
#property strict

//--- 外部パラメータ(ストラテジーテスターから変更可能)
input int    FastMAPeriod = 20;      // 短期移動平均の期間
input int    SlowMAPeriod = 50;      // 長期移動平均の期間
input double TakeProfitPips = 50;    // 利確(pips)
input double StopLossPips   = 30;    // 損切り(pips)
input double Lots           = 0.1;   // ロット数
input int    MagicNumber    = 12345; // マジックナンバー
input int    Slippage       = 3;     // 許容スリッページ(ポイント)

double pipValue;

//+------------------------------------------------------------------+
//| 初期化                                                            |
//+------------------------------------------------------------------+
int OnInit()
  {
   // 3桁/5桁業者に対応した1pipの値を求める
   pipValue = (Digits == 3 || Digits == 5) ? Point * 10 : Point;
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| ティックごとの処理                                                 |
//+------------------------------------------------------------------+
void OnTick()
  {
   // 確定足でのみ判定する(新しい足ができた瞬間だけ処理)
   static datetime lastBarTime = 0;
   if(Time[0] == lastBarTime) return;
   lastBarTime = Time[0];

   // 1本前と2本前の確定足のMAを取得
   double fastPrev  = iMA(NULL, 0, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 2);
   double fastCurr  = iMA(NULL, 0, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
   double slowPrev  = iMA(NULL, 0, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 2);
   double slowCurr  = iMA(NULL, 0, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);

   bool goldenCross = (fastPrev <= slowPrev && fastCurr > slowCurr);
   bool deadCross   = (fastPrev >= slowPrev && fastCurr < slowCurr);

   int myPos = CountMyPositions();

   // 反対クロスが出たら保有ポジションを決済
   if(myPos > 0)
     {
      if(goldenCross) CloseMyPositions(OP_SELL);
      if(deadCross)   CloseMyPositions(OP_BUY);
      myPos = CountMyPositions();
     }

   // ポジションが無いときだけ新規エントリー
   if(myPos == 0)
     {
      if(goldenCross) OpenOrder(OP_BUY);
      if(deadCross)   OpenOrder(OP_SELL);
     }
  }

//+------------------------------------------------------------------+
//| 自分のEAのポジション数を数える                                     |
//+------------------------------------------------------------------+
int CountMyPositions()
  {
   int count = 0;
   for(int i = 0; i < OrdersTotal(); i++)
     {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
      if(OrderType() == OP_BUY || OrderType() == OP_SELL) count++;
     }
   return(count);
  }

//+------------------------------------------------------------------+
//| 新規注文                                                          |
//+------------------------------------------------------------------+
void OpenOrder(int type)
  {
   double price, sl, tp;
   color  arrowColor;

   if(type == OP_BUY)
     {
      price = Ask;
      sl = (StopLossPips   > 0) ? NormalizeDouble(price - StopLossPips   * pipValue, Digits) : 0;
      tp = (TakeProfitPips > 0) ? NormalizeDouble(price + TakeProfitPips * pipValue, Digits) : 0;
      arrowColor = clrBlue;
     }
   else
     {
      price = Bid;
      sl = (StopLossPips   > 0) ? NormalizeDouble(price + StopLossPips   * pipValue, Digits) : 0;
      tp = (TakeProfitPips > 0) ? NormalizeDouble(price - TakeProfitPips * pipValue, Digits) : 0;
      arrowColor = clrRed;
     }

   int ticket = OrderSend(Symbol(), type, Lots, price, Slippage, sl, tp,
                          "MA_Cross_Sample", MagicNumber, 0, arrowColor);
   if(ticket < 0)
      Print("注文失敗 エラーコード: ", GetLastError());
  }

//+------------------------------------------------------------------+
//| 指定タイプの自分のポジションを全て決済                             |
//+------------------------------------------------------------------+
void CloseMyPositions(int type)
  {
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if(OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
      if(OrderType() != type) continue;

      double closePrice = (type == OP_BUY) ? Bid : Ask;
      if(!OrderClose(OrderTicket(), OrderLots(), closePrice, Slippage, clrGray))
         Print("決済失敗 エラーコード: ", GetLastError());
     }
  }
//+------------------------------------------------------------------+

貼り付けたあと、1行目が //+--- で始まり、最後の行も //+--- で終わっていれば、全文が正しく入っています。

ここに画面写真を入れてくださいサンプルコードを貼り付けたMetaEditor。先頭行と最終行が見える状態4-1-06.png

手順7 保存して、保存場所を確認する

[Ctrl]+[S] で保存します。「ファイル」→「保存」でも同じです。タブのファイル名の横に「*」が付いていたら未保存のしるしなので、消えたことを確認してください。要確認

EAのファイルは、必ず次の場所に保存されます。

  • MT4のデータフォルダ → MQL4Experts

ウィザードから作ったファイルは自動でここに入るので、保存場所を自分で選ぶ必要はありません。

場所を確認したいときは、MT4の「ファイル」→「データフォルダを開く」を押すと、エクスプローラーでデータフォルダが開きます。要確認 その中の MQL4\ExpertsMA_Cross_Sample.mq4 があれば正解です。

MetaEditor左側のナビゲータでも、「Experts」フォルダの下に「MA_Cross_Sample.mq4」が表示されます。

ここに画面写真を入れてくださいエクスプローラーで MQL4\Experts フォルダを開き、MA_Cross_Sample.mq4 がある状態4-1-07.png

つまずきポイント

  • MetaEditorが開かない: MT4が起動しているか確認します。[F4] が効かないときは、MT4のツールバーのアイコンか、Windowsのスタートメニューの「MetaEditor」から開きます。要確認
  • ウィザードに「エキスパートアドバイザ」が2種類ある: 「(テンプレート)」と付いているほうを選びます。「(生成)」のほうは質問形式でコードを作る機能で、今回は使いません。要確認
  • 貼り付けたら日本語が文字化けした: コメント(// の行)の日本語が化けているだけなら、動作には影響しません。気になる場合は、MetaEditorの「ファイル」メニューからエンコードを UTF-8 にして保存し直します。要確認
  • 貼り付けが途中までしか入っていない: コピー元の範囲選択が足りていません。コードブロックの「コピー」ボタンを使ってやり直してください。
  • デスクトップなど別の場所に保存してしまった: MT4は MQL4\Experts の中しか見ません。エクスプローラーでファイルを MQL4\Experts に移動してください。

次の記事

次は、貼り付けたコードを「コンパイル」して、MT4が実行できる形(.ex4)に変換します。