見出し画像

ChatGPTを使ってMT4のEA自動売買プログラムを開発する方法

【記事更新】2025年2月6日
2024年当時、EA開発は、オープンAIのChatGPT 4を活用して行われていました。しかし、一年前はプログラミングの精度に課題があり、エラーが頻発したり、思い通りのロジックが組みにくいという問題がありました。結果として、多くの場合、手動での修正が必要となっていました。

進化するEA開発の現状
2025年にオープンAIからリリースされた「OpenAI o3-mini」の登場により、EA開発は大きな転換期を迎えました。この新技術により、プログラミングの知識がなくても、ノーコードでEAを開発できるようになりました。

昨日投稿した記事では、ノーコードでのEA開発手法について詳しく解説しています。こちらの記事もあわせてお読みいただくことで、EA開発の手助けになると思います。

それでは記事の続きをご覧ください。


先日noteに、Copilotという生成AIを使い、EAをカスタマイズする方法を投稿しました。

現役EAクリエーターのまさやんが教える生成AIを使ってEAを作る方法
https://note.com/aimjey/n/n12412e90bacd

使用するEAプログラムソースコードは、MT4に最初からある「Moving Average.ex4」というEAを使用します。

動画ではCopilotを使用していますが、はっきり言ってエラーが頻発して使い物になりません。

しかしながら、2024年5月にリリースされたChatGPT最新AIモデル GPT-4o(ジーピーティーフォーオー)が非常に優秀で、エラーの頻度は大幅に改善されました。

これなら生成AIだけでプログラミングできるのでは?との思いから、連載記事を書くことにしました。

前回作成したプログラムソースコード

このソースコードをベースに開発していきます。

//+------------------------------------------------------------------+
//|                                               Moving Average.mq4 |
//|                   Copyright 2005-2014, MetaQuotes Software Corp. |
//|                                              http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2005-2014, MetaQuotes Software Corp."
#property link        "http://www.mql4.com"
#property description "Moving Average sample expert advisor"

#define MAGICMA  20131111
//--- Inputs
input double Lots          =0.1;
input double MaximumRisk   =0.02;
input double DecreaseFactor=3;
input int    MovingPeriod  =12;
input int    MovingShift   =6;
int ShortMovingPeriod = 90;
int LongMovingPeriod = 300;
//+------------------------------------------------------------------+
//| Calculate open positions                                         |
//+------------------------------------------------------------------+
int CalculateCurrentOrders(string symbol)
  {
   int buys=0,sells=0;
//---
   for(int i=0;i<OrdersTotal();i++)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==MAGICMA)
        {
         if(OrderType()==OP_BUY)  buys++;
         if(OrderType()==OP_SELL) sells++;
        }
     }
//--- return orders volume
   if(buys>0) return(buys);
   else       return(-sells);
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double LotsOptimized()
  {
   double lot=Lots;
   int    orders=HistoryTotal();     // history orders total
   int    losses=0;                  // number of losses orders without a break
//--- select lot size
   lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);
//--- calcuulate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      for(int i=orders-1;i>=0;i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)
           {
            Print("Error in history!");
            break;
           }
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL)
            continue;
         //---
         if(OrderProfit()>0) break;
         if(OrderProfit()<0) losses++;
        }
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- return lot size
   if(lot<0.1) lot=0.1;
   return(lot);
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen()
{
   double shortMA, longMA;
   int res;
   
   // Get Moving Averages
   shortMA = iMA(NULL, 0, ShortMovingPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   longMA = iMA(NULL, 0, LongMovingPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   
   // Buy conditions (Golden Cross)
   if (shortMA > longMA)
   {
      res = OrderSend(Symbol(), OP_BUY, LotsOptimized(), Ask, 3, 0, 0, "", MAGICMA, 0, Blue);
      return;
   }
   
   // Sell conditions (Dead Cross)
   if (shortMA < longMA)
   {
      res = OrderSend(Symbol(), OP_SELL, LotsOptimized(), Bid, 3, 0, 0, "", MAGICMA, 0, Red);
      return;
   }
}

//+------------------------------------------------------------------+
//| Check for close order conditions                                 |
//+------------------------------------------------------------------+
void CheckForClose()
{
   double shortMA, longMA;
   // Get Moving Averages
   shortMA = iMA(NULL, 0, ShortMovingPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   longMA = iMA(NULL, 0, LongMovingPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   
   for (int i = 0; i < OrdersTotal(); i++)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false)
         break;
      
      if (OrderMagicNumber() != MAGICMA || OrderSymbol() != Symbol())
         continue;
      
      // Check order type
      if (OrderType() == OP_BUY)
      {
         if (shortMA < longMA)
         {
            if (!OrderClose(OrderTicket(), OrderLots(), Bid, 3, White))
               Print("OrderClose error ", GetLastError());
         }
         break;
      }
      
      if (OrderType() == OP_SELL)
      {
         if (shortMA > longMA)
         {
            if (!OrderClose(OrderTicket(), OrderLots(), Ask, 3, White))
               Print("OrderClose error ", GetLastError());
         }
         break;
      }
   }
}
//+------------------------------------------------------------------+
//| OnTick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- check for history and trading
   if(Bars<100 || IsTradeAllowed()==false)
      return;
//--- calculate open orders by current symbol
   if(CalculateCurrentOrders(Symbol())==0) CheckForOpen();
   else                                    CheckForClose();
//---
  }
//+------------------------------------------------------------------+

上記のEAのバックテスト結果 2007.01.02~2023.12.30 USDJPY 5分足

Moving Average.ex4改

noteで投稿した記事をYouTube動画にまとめる、告知はX 旧Twitterで行う予定です。

更新頻度は週1回から2回を予定しています。

プログラミング初心者にも分かるように丁寧に解説とはいかないと思います。

なぜなら、MT4のプログラミング言語MQL4自体の習得難易度がそれなりに高いこと。

また、エラーが出た時の対処方法としてGoogle検索して自力で解決することが従来のやり方です。

これに対して、エラーの内容をChatGPTに伝えて修正してもらう方法では限界があります。

プログラミングの知識が無いと問題の箇所が分からず開発がストップすることがあるからです。

更に問題点として、重大なバグが潜んでいるプログラムを生成する可能性があります。

優秀なプログラマーは想定されるバグや不具合を経験から知ることができ、バグ対策を行うことは当たり前の事です。

ですが、プログラミング初心者には何がバグに繋がるのか、また解決方法が分からないことが課題とされます。

当然、ChatGPTは聞かれたこと以外のことは答えないので、バグを予防するようなプログラムを書くために、適切なプロンプトを送信する必要があります。

本連載記事では、どのようなプロンプトを送信すればいいのか?に重点を置いて記事を書いていきます。

コツさえつかめればChatGPTを使ってMT4のEA自動売買プログラムを開発することは出来ると思います。

しばらくは無料にて公開しますので、応援よろしくお願いします。


いいなと思ったら応援しよう!