見出し画像

無料グリッド・マーチンゲールEA「Grid Free」を修正してみた

Grid Free→Grid Free2

Grid Freeは、「海外FX大全」というサイトで無料公開されているMT4用のEA(自動売買ツール)です。

Grid Freeが公開されているページはこちら

このGrid Freeのソースコードをそのままコピペしてコンパイルし、MT4でバックテストしてみたら、動きがおかしい事に気が付きました。

AUDCADのM5で2023年の1年間のバックテスト結果

どこがおかしいかというと、

売りポジションが332もあるのに、
買いポジションが30しかない


というところです。

これはソースコードのどこかに書き間違いがあると思い、よく見てみたら修正しなければいけない所を発見しました。

修正箇所はソースコードの57行目の最後にある

if(0 > mom100 && 0 > mom200)

のところです。

ここを次の行に改行しなければ、売りエントリーのフィルターが効いていない状態になります。

だから売りポジションばかり多くなっていたんですね。

最低限この一か所だけ直せば機能的には正常になりますが、他にも改行した方がいい箇所があったので、全体的にソースコードを整えて、さらにスプレッドフィルターを追加し、パラメーターで最大スプレッドとマジックナンバーを設定できるようにしてみました。

このGrid Freeの修正+機能追加バージョンをGrid Free2として保存、コンパイルし、もう一度バックテストしてみました。

AUDCADのM5で2023年の1年間のバックテスト結果

これで売りポジションが84、買いポジションが120で正常になりました。
これが本来のGrid Freeの成績です。

Grid Free2のソースコード

Grid Freeの修正+機能追加バージョン、Grid Free2のソースコードとファイルはこちら


#property strict

input double lots = 0.1;//ロット数
input int MaxSpread = 45;//最大スプレッド
input int MagicNumber = 777999;//マジックナンバー

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//エントリー処理

   if(MarketInfo(Symbol(),MODE_SPREAD) < MaxSpread)
     {

      if(is_buy() && is_up_trend() && posi_count(OP_BUY) == 0 && posi_count(OP_SELL) == 0)
        {
         position_entry(OP_BUY);
        }
     
      if(is_sell() && is_down_trend() && posi_count(OP_BUY) == 0 && posi_count(OP_SELL) == 0)
        {
         position_entry(OP_SELL);
        }
     }

//決済処理

   if(posi_count(OP_BUY) > 0)
     {
      if(position_average_price(0) + 150 * _Point < Bid)
        {
         position_close(0);
        }
     }

   if(posi_count(OP_SELL) > 0)
     {
      if(position_average_price(1) - 150 * _Point > Ask)
        {
         position_close(1);
        }
     }

//ナンピンマーチン

   nanpin_martin_judge();

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool is_buy()
  {
   double rsi = iRSI(NULL,0,14,0,1);

   if(rsi < 30)
     {
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool is_sell()
  {
   double rsi = iRSI(NULL,0,14,0,1);
   if(rsi > 70)
     {
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool is_up_trend()
  {

   double close = iClose(NULL,0,0);
   double close100 = iClose(NULL,0,100);
   double close200 = iClose(NULL,0,200);

   double mom100 = close - close100;
   double mom200 = close - close200;

//「momが0超え」なら上昇トレンド

   if(0 < mom100 && 0 < mom200)
     {
      return true;
     }
   return false;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool is_down_trend()
  {

   double close = iClose(NULL,0,0);
   double close100 = iClose(NULL,0,100);
   double close200 = iClose(NULL,0,200);

   double mom100 = close - close100;
   double mom200 = close - close200;

//「momが0未満」なら下降トレンド

   if(0 > mom100 && 0 > mom200)
     {
      return true;
     }
   return false;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int posi_count(int side)
  {

   int count = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderType() == side)
           {
            if(OrderSymbol()==Symbol())
              {
               if(OrderMagicNumber()==MagicNumber)
                 {
                  count++;
                 }
              }
           }
        }
     }
   return count;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void position_entry(int side)
  {
   double qty = lots;
   if(side==0)
     {
      bool res= OrderSend(NULL,side,qty,Ask,0,0,0,NULL,MagicNumber,0,clrGreen);
     }
   if(side==1)
     {
      bool res= OrderSend(NULL,side,qty,Bid,0,0,0,NULL,MagicNumber,0,clrRed);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void position_entry_nanpin(int side,double bairitu)
  {
   double qty = lots;

   if(side==0)
     {
      bool res= OrderSend(NULL,side,qty * bairitu,Ask,0,0,0,NULL,MagicNumber,0,clrGreen);
     }
   if(side==1)
     {
      bool res= OrderSend(NULL,side,qty * bairitu,Bid,0,0,0,NULL,MagicNumber,0,clrRed);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void position_close(int side)
  {
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderType() == side)
           {
            if(OrderSymbol()==Symbol())
              {
               if(OrderMagicNumber()==MagicNumber)
                 {
                  bool res=  OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0, clrBlue);
                 }
              }
           }
        }
     }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double position_average_price(int side)
  {

   double lots_sum = 0;
   double price_sum = 0;
   double average_price = 0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderType() == side)
           {
            if(OrderSymbol()==Symbol())
              {
               if(OrderMagicNumber()==MagicNumber)
                 {
                  lots_sum += OrderLots();
                  price_sum += OrderOpenPrice() * OrderLots();
                 }
              }
           }
        }
     }
   if(lots_sum && price_sum)
     {
      average_price = price_sum/lots_sum;
     }
   return average_price;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double position_entry_price(int side)
  {
   double entry_prices[50];
   double entry_price=0;

   ArrayInitialize(entry_prices,0.0);
   if(side ==1)
     {
      ArrayInitialize(entry_prices,9999999.0);
     }

   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderType() == side)
           {
            if(OrderSymbol()==Symbol())
              {
               if(OrderMagicNumber()==MagicNumber)
                 {
                  entry_prices[i] = OrderOpenPrice();
                 }
              }
           }
        }
     }
   if(side==0)
     {
      entry_price = entry_prices[ArrayMaximum(entry_prices,WHOLE_ARRAY,0)];
     }
   if(side==1)
     {
      entry_price = entry_prices[ArrayMinimum(entry_prices,WHOLE_ARRAY,0)];
     }
   return entry_price;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void nanpin_martin_judge()
  {

   if(posi_count(OP_BUY) > 0)
     {
      int position_num = posi_count(OP_BUY);
      double entry_price = position_entry_price(OP_BUY);
      double nanpin_price = entry_price - (300 * _Point) * position_num;
      double lots_bairitu = MathPow(1.5,position_num);

      if(nanpin_price > Ask)
        {
         position_entry_nanpin(OP_BUY,lots_bairitu);
        }
     }
   if(posi_count(OP_SELL) > 0)
     {
      int position_num = posi_count(OP_SELL);
      double entry_price = position_entry_price(OP_SELL);
      double nanpin_price = entry_price + (300 * _Point) * position_num;
      double lots_bairitu = MathPow(1.5,position_num);
      if(nanpin_price < Bid)
        {
         position_entry_nanpin(OP_SELL,lots_bairitu);
        }
     }
  }
//+------------------------------------------------------------------+

EA作成初心者なので、もしかしたら間違っているところがあるかもしれません。見つけたら教えてください。

Grid Free2で試しに2017~2023年の長期間のバックテストをしてみました。
設定は、初期証拠金150万円で0.03lot、スプレッドはXMのスタンダード口座を目安にAUDCADは35、AUDNZDとNZDCADは40でやってみました。

まずはAUDCAD↓

AUDCADは破綻せず完走できました。

次はAUDNZD↓

AUDNZDは完走しましたが、何回か危ない場面があります。

次はNZDCAD↓

NZDCADは破綻してしまいました。

できればNZDCADで破綻せずに完走し、AUDNZDでドローダウンを少なくしたいので、次回もう少しこのEAを改造してみたいと思います。

もしよかったら、どうか記事の下の「記事をサポート」をお願い致します。お金が稼げなくて困っています。奨学金の返済、生活費、病院代、勉強代などに使いたいと思っております。


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