AI EA スクール
0記事中 0記事 読了
カリキュラム 第4章 EAを作る コンパイルする
4-2

コンパイルする

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

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

  • MetaEditorでコンパイルを実行できる
  • 「エラー」タブを見て、成功か失敗かを判断できる
  • error と warning の違いが分かる

準備するもの

  • 前の記事で保存した MA_Cross_Sample.mq4 をMetaEditorで開いた状態
  • (前の記事を飛ばした方は、手順1でサンプルEAの全文を貼り付けられます)

手順

手順1 サンプルEAが開いていることを確認する

MetaEditorの中央に、前の記事で貼り付けた「MA_Cross_Sample.mq4」が表示されていることを確認します。上部のタブにファイル名が出ています。要確認

まだ貼り付けていない方は、前の記事の手順1〜5に従って新規EAファイル(名前: MA_Cross_Sample)を作り、ひな形を全消ししてから、下のコードを丸ごと貼り付けて [Ctrl]+[S] で保存してください。中身は読まなくて大丈夫です。「まずはこのコードを貼ってコンパイルしてみる」のがこの記事のゴールです。

//+------------------------------------------------------------------+
//|                                          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());
     }
  }
//+------------------------------------------------------------------+
ここに画面写真を入れてくださいMetaEditorでMA_Cross_Sample.mq4が開いており、タブにファイル名が見える状態4-2-01.png

手順2 コンパイルとは何かを知る

.mq4ファイルは、人間(とAI)が読み書きするための「設計図」です。MT4はこの設計図を直接動かせないので、MT4が実行できる形(.ex4ファイル)に変換する必要があります。この変換作業が「コンパイル」です。

コンパイルのとき、MetaEditorはコードの文法をすべてチェックします。つづりの間違いや記号の抜けがあると、その場で「どの行に何の問題があるか」を教えてくれます。つまりコンパイルは、変換であると同時に、AIが書いたコードの「検品」でもあります。

ここに画面写真を入れてください図: .mq4(設計図)→ コンパイル → .ex4(MT4が動かせる形)の流れ図4-2-02.png

手順3 コンパイルボタンを押す

MetaEditorで MA_Cross_Sample.mq4 が開いていることを確認して、キーボードの [F7] を押します。ツールバーの「コンパイル」ボタンでも同じです。要確認

コンパイルの前に自動で保存されるので、保存し忘れの心配はありません。要確認 処理は1〜2秒で終わります。

ここに画面写真を入れてくださいMetaEditorのツールバーの「コンパイル」ボタンに印をつけた画面4-2-03.png

手順4 下部の「エラー」タブを見る

コンパイルが終わると、画面下のツールボックスに結果が表示されます。「エラー」タブを選んでください。要確認

ここに表示される各行には、次の情報が並んでいます。

意味
説明 何が起きたか(エラーの内容)
ファイル どのファイルで起きたか
何行目か
その行の何文字目か

列名の表記はMetaEditorのバージョンによって異なることがあります。要確認

いちばん下の行に「0 error(s), 0 warning(s)」のような集計が出ます。要確認 ここを見るのが、成功・失敗を判断するいちばん簡単な方法です。

ここに画面写真を入れてください「エラー」タブに集計行「0 error(s), 0 warning(s)」が表示された画面4-2-04.png

手順5 成功したときの画面を確認する

サンプルEAをそのまま貼り付けていれば、次のようになるはずです。

  • 「エラー」タブに赤いエラー行がない
  • 集計が「0 error(s), 0 warning(s)」
  • MetaEditor左側のナビゲータの「Experts」フォルダに、MA_Cross_Sample.ex4 が増えている要確認

.ex4 ができていれば、コンパイルは成功です。これがEAの完成形で、MT4はこのファイルを読み込みます。

ここに画面写真を入れてくださいコンパイル成功時のMetaEditor全体。ナビゲータに .mq4 と .ex4 が並んでいる状態4-2-05.png

手順6 わざと失敗させて、失敗時の画面を見ておく

エラーがあると、「エラー」タブに赤いアイコンの行が表示され、集計が「1 error(s)」のようになります。このとき新しい .ex4 は作られません(前回の .ex4 が残っている場合はありますが、今回の変更は反映されていません)。

試しにわざと壊してみましょう。コードの上のほうにある #property strict という行の末尾を1文字消して #property stric にし、[F7] を押してみてください。赤い行が出るはずです。

確認したら、消した文字を戻して #property strict にし、もう一度 [F7] を押して「0 error(s)」に戻ることを確認しておきます。

こうしておくと、自分のEAでエラーが出たときに「これがあの画面か」と落ち着いて対応できます。

ここに画面写真を入れてくださいわざとエラーを出したときの「エラー」タブ。赤い行と「1 error(s)」の集計4-2-06.png

手順7 error と warning の違いを知る

集計には「error」と「warning」の2種類があります。

種類 意味 どうするか
error(エラー) 文法の間違い。.ex4 が作られず、EAは動かない 必ず直す(次の記事)
warning(警告) 動くけれど気になる点がある、という注意 基本は直さなくてOK

warning は、たとえば「使っていない変数がある」「数値の型が変換されている」といった内容です。動作に影響しないことがほとんどなので、0 warning にこだわる必要はありません。内容が気になる場合は、エラー文と同じようにChatGPTに貼れば説明してもらえます。

ゴールは「0 error」。「0 warning」はできれば、で十分です。

ここに画面写真を入れてくださいwarning だけが出ている「エラー」タブの例(黄色いアイコンの行と「0 error(s), 1 warning(s)」)4-2-07.png

手順8 自分のEAでも同じことをする

サンプルで「0 error」が出せたら、第3章でChatGPTに作ってもらった自分のコードでも同じ手順を繰り返します。

  1. 前の記事の手順で新規EAファイルを作る(名前は例えば MyEA_v1
  2. ひな形を全消しして、ChatGPTのコードを貼り付ける
  3. [Ctrl]+[S] → [F7]
  4. 「エラー」タブを確認する

エラーが出ても、それは普通のことです。AIが書いたコードは一発で通らないことのほうが多いくらいです。次の記事で、ChatGPTに直してもらう方法を説明します。

ここに画面写真を入れてください自分のEA(MyEA_v1.mq4)をコンパイルしてエラーが数行出た画面4-2-08.png

つまずきポイント

  • [F7] を押しても何も起きない: MetaEditorのコード部分をクリックして、ウィンドウが選ばれている状態にしてから押してください。ツールバーの「コンパイル」ボタンでも同じです。
  • 「エラー」タブが見当たらない: ツールボックス自体が閉じていることがあります。「表示」→「ツールボックス」で表示します。要確認
  • サンプルなのにエラーが出る: 貼り付けが途中で切れているか、余計な文章が混ざっています。前の記事の手順5〜6をやり直して、先頭行と最終行が //+--- になっているか確認してください。
  • warning がたくさん出る: 動作には影響しません。「0 error」なら先に進んで大丈夫です。
  • .ex4 が見当たらない: ナビゲータの「Experts」を右クリックして更新するか、MetaEditorを開き直すと表示されます。要確認

次の記事

次は、エラーが出たときにエラー文をChatGPTに貼って直してもらう方法と、よくあるエラー3選を説明します。