見出し画像

3本のパラボリックSARを使用した372手法を検証してみた【あなたの考えたFX手法をEAにする】


ChatGPT担当のナナミです。

前回の動画では、パラボリックSARを使用したEAの開発を行いました。

本日は、リクエストのあったパラボリックSARを3本使用した372手法の検証を行いたいと思います。


完成したEAはこのページで無料でコピーできます。

GPTsのリンクはこちら(GPT Store)
https://chatgpt.com/g/g-VYNEupgws-masayan-ea-generator-for-mt4-ver1-01

■ブログURL
https://fx.reform-network.net/2024/08/29/新シリーズ「あなたの考えたfx手法をeaにする」/

■前回記事(パラボリックSARを使用したEAを作成してみた)
https://note.com/aimjey/n/nab0f9e29071f


372手法は以下の3つのパラボリックSARを使用するそうです。

15分足のパラボリックSAR
1時間足のパラボリックSAR
4時間足のパラボリックSAR

エントリーは、15分足でパラボリックSARが上昇トレンドを示し、1時間足と4時間足も同様の方向性を持つ場合にエントリーします。
決済は、1時間足または4時間足でパラボリックSARが反転した際にエグジットするとあります。

なるほど、これはマルチタイムフレーム分析のパラボリック版ということですね。

パラボリックSARはEAとの相性が良いので、期待できます。

3本の移動平均線を使用するパーフェクトオーダーのロジックをイメージすると分かりやすいです。

それでは早速EAを作ってみましょう。

Masayan EA Generator for MT4のプロンプトに372手法と入力します。

ここで、ChatGPTが正しくコードを生成してくれません。

テンプレートを使用してEAを作ってほしいのに、テンプレートを省略してしまいます。

これではバグのEAができあがってしまいます。

何回かやり直したのですが、ダメでした。

仕方ないので、ロジックの部分だけ移植します。

完成したコードでバックテストします。

ドル円15分足でのバックテストですね。

最初はステップの値を0.02でテストします。

微妙ですね。

プロフィットファクターは1.05です。

次にステップの値を0.001でテストします。

こちらもダメですね。

どうやら、各時間足において、適切なステップの値を決めないといけないようです。

というわけで、手動でEAを完成させて、MT4の最適化機能を使い、ベストな値を探そうと思います。

プロパティ設定で決済のロジックを有効にするか選べるようにしました。

おそらくドテン方式の方が好成績になると思います。

何パターンか試しましたがやはりドテン方式の方が好成績ですね。

最適な設定は、15分足が 0.001、1時間足が 0.01、4時間足が 0.035でした。


ただしこの設定だと、前回作成したEAとほとんど成績が同じです。

決済の条件をいろいろと変えてはみたものの、成績は下がるだけです。

SAR以外のテクニカル指標などを使用しないといけないかもしれません。

前回完成したTDSによる全ティックバックテストの結果はコチラです。


トレード回数は4065回、プロフィットファクターは1.16、総利益は13228ドルと高いパフォーマンスとなっております。


今回作成したEAの成績です。
トレード回数は4124回、プロフィットファクターは1.15、総利益は13009ドルです。

ほとんど変わりないですね。


EAの名前は372手法です。

わたしの経験上、このEAはすでに完成の域に達しています。

これ以上カスタマイズを行っても成績は改善しない可能性が高いです。

EA開発に自信のある方は、決済ロジックのところを変更するなどしてカスタマイズしてみてください。

好成績のEAが完成した際には、コメント頂けると幸いです。

完成したEAのソースコードです。

//+---------------------------------------------+
//|Masayan EA Generator_1.01.mq4  372手法       |
//372手法は以下の3つのパラボリックSARを使用します。
//15分足のパラボリックSAR
//1時間足のパラボリックSAR
//4時間足のパラボリックSAR
//+---------------------------------------------+
#property copyright "Copyright 2024, Masayan."
#property version   "1.01"
#property strict
#property description "https://fx.reform-network.net"

extern int Magic = 20240924;// Magic number
extern double Lots = 0.1;//1.0=100000 0.1=10000 0.01=1000
extern double StopLossRequest = 4.0;// StopLoss 0.5=50pips 10=1000pips
extern double TakeProfitRequest = 5.0;// TakeProfit 0.5=50pips 10=1000pips
extern int MaxSpread = 50;// Max spread (50=5pips)
extern int MaxError = 100;// Continuous order count limit (Max=100)
extern string CommentPositions = "372 SAR";

extern double Step15m = 0.001; // パラボリックSARのステップ(15分足)
extern double Step1h = 0.01; // パラボリックSARのステップ(1時間足)
extern double Step4h = 0.035; // パラボリックSARのステップ(4時間足)
extern double Maximum = 0.2; // パラボリックSARの最大値

input bool Doten = true; // ドテン方式にする場合true、決済ロジックを追加する場合false

string tmpstr;
string error_msg;
string spread_msg;
string position_msg;
bool LongSign = false;
bool ShortSign = false;
double Pips = 0.01;
int e = 0;
int Adjusted_Slippage= 0;

// ティックが動くごとに処理
void OnTick()
  {
   if(Bars < 10)
     {
      return;
     }

   if(StopLossRequest <= 0.1)
     {
      StopLossRequest = 0.1;
     }
   if(TakeProfitRequest <= 0.1)
     {
      TakeProfitRequest = 0.1;
     }
   if(MaxError >= 100)
     {
      MaxError = 100;
     }

   double Info_Spread = MarketInfo(Symbol(),MODE_SPREAD);
   string value = Symbol();
   string target = "JPY";
   int pos = StringFind(value, target);
   double Symbol_RATE = Close[1];
   if(pos > 0)
     {
     Pips = 1.00;// ドルストレートは0.010(100pips)、クロス円は1.0(100pips)で判定
     }else if(Symbol_RATE > 10 && Symbol_RATE <= 100)
     {
     Pips = 0.1;
     }else if(Symbol_RATE > 100 && Symbol_RATE <= 1000)
     {
     Pips = 1.0;
     }else if(Symbol_RATE > 1000 && Symbol_RATE <= 10000)
     {
     Pips = 10.0;
     }else if(Symbol_RATE > 10000 && Symbol_RATE <= 100000)
     {
     Pips = 100.0;
     }else if(Symbol_RATE > 100000 && Symbol_RATE <= 1000000)
     {
     Pips = 1000.0;
     }else if(Symbol_RATE > 1000000 && Symbol_RATE <= 10000000)
     {
     Pips = 10000.0;
     }else if(Symbol_RATE > 10000000 && Symbol_RATE <= 100000000)
     {
     Pips = 100000.0;
     }else if(Symbol_RATE > 100000000)
     {
     Pips = 1000000.0;
     }

//ここから改変可能
   double sarValue15m = iSAR(NULL, 0, Step15m, Maximum, 1);
   double sarValue1h = iSAR(NULL, 0, Step1h, Maximum, 1);
   double sarValue4h = iSAR(NULL, 0, Step4h, Maximum, 1);
   double closePrice = Close[1];

   if(closePrice > sarValue15m && closePrice > sarValue1h && closePrice > sarValue4h)
     {
      LongSign = true;
      ShortSign = false;
     }
   else if(closePrice < sarValue15m && closePrice < sarValue1h && closePrice < sarValue4h)
     {
      ShortSign = true;
      LongSign = false;
     }
   else
     {
     LongSign = false;
     ShortSign = false;
     }
//ここまで改変可能

/*ここに決済ロジックを挿入*/
if(Doten == false){
   // 決済のロジックを有効にする場合(未完成)
   if(CalculateCurrentOrders() == 1 && (Close[0] < sarValue15m && Close[0] < sarValue1h && Close[0] < sarValue4h))
     {
      CloseLongPosition();// ロングポジションを決済
     }
   else if(CalculateCurrentOrders() == -1 && (Close[0] > sarValue15m && Close[0] > sarValue1h && Close[0] > sarValue4h))
     {
      CloseShortPosition();// ショートポジションを決済
     }
}
/*ここまで決済ロジックを挿入*/
   if(MaxSpread < Info_Spread)
     {
      LongSign = false;
      ShortSign = false;
      spread_msg = "Max spread Orber\n";
     }
   else
     {
      spread_msg = "";
     }

   if(Hour() == 4 && Minute() == 0 && Seconds() < 6)
     {
      e = 0;
     }
   if(Hour() == 11 && Minute() == 0 && Seconds() < 6)
     {
      e = 0;
     }
   if(Hour() == 18 && Minute() == 0 && Seconds() < 6)
     {
      e = 0;
     }
   if(e > MaxError)
     {
      LongSign = false;
      ShortSign = false;
      error_msg = "Continuous order count limit\n";
     }
   else
     {
      error_msg = "";
     }
   if(LongSign == true)
     {
      position_msg = "LongSign = true\n";
     }
   else
      if(ShortSign == true)
        {
         position_msg = "ShortSign = true\n";
        }
      else
         if(LongSign == false && ShortSign == false)
           {
            position_msg = "No Sign\n";
           }

//売買指示
   if(LongSign == true)
     {
      if(CalculateCurrentOrders() == 0)
        {
         // ポジション無し
         CheckForOpenLong();// 新規ロングオーダー処理
         e ++;
        }
      else
        {
         // ポジション保有中
         CloseShortPosition();// ショートポジションを決済
        }
     }
   if(ShortSign == true)
     {
      if(CalculateCurrentOrders() == 0)
        {
         // ポジション無し
         CheckForOpenShort();// 新規ショートオーダー処理
         e ++;
        }
      else
        {
         // ポジション保有中
         CloseLongPosition();// ロングポジションを決済
        }
     }

   tmpstr = StringConcatenate(error_msg,spread_msg,position_msg);
   Comment(tmpstr);
  }

//保有中のポジションを計算
int CalculateCurrentOrders(void)
  {
   int buys=0;
   int sells=0;
   int icount;
   for(icount = 0 ; icount < OrdersTotal() ; icount++)
     {
      if(OrderSelect(icount,SELECT_BY_POS,MODE_TRADES) == false)
        {
         break;
        }
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
        {
         if(OrderType()==OP_BUY)
           {
            buys++;
           }
         if(OrderType()==OP_SELL)
           {
            sells++;
           }
        }
     }
   if(buys > 0)
     {
      return(buys);
     }
   else
     {
      return(-sells);
     }
  }

//ショートポジション⇒ロングクローズ処理
void CloseShortPosition()
  {
   int    icount;
   bool   ret;
   for(icount = 0; icount < OrdersTotal(); icount++)
     {
      if(OrderSelect(icount, SELECT_BY_POS, MODE_TRADES) == false)
        {
         break;
        }
      if(OrderMagicNumber() != Magic || OrderSymbol() != Symbol())
        {
         continue;
        }
      if(OrderType() == OP_SELL)
        {
         ret = OrderClose(
         OrderTicket(),
         OrderLots(),
         Ask,
         Adjusted_Slippage,
         clrBlue);
         if(ret == false)
           {
            Print("エラーコード=",GetLastError());
           }
         break;
        }
     }
  }

//ロングポジション⇒ショートクローズ処理
void CloseLongPosition()
  {
   int    icount;
   bool   ret;
   for(icount = 0; icount < OrdersTotal(); icount++)
     {
      if(OrderSelect(icount, SELECT_BY_POS, MODE_TRADES) == false)
        {
         break;
        }
      if(OrderMagicNumber() != Magic || OrderSymbol() != Symbol())
        {
         continue;
        }
      if(OrderType() == OP_BUY)
        {
         ret = OrderClose(
         OrderTicket(),
         OrderLots(),
         Bid,
         Adjusted_Slippage,
         clrRed);
         if(ret == false)
           {
            Print("エラーコード=",GetLastError());
           }
         break;
        }
     }
  }

//ロングオーダー処理
void CheckForOpenLong()
  {
   int    res;
   double entrylot;
   entrylot = NormalizeDouble(Lots,2);
   res = OrderSend(
   Symbol(),
   OP_BUY,
   entrylot,
   Ask,
   Adjusted_Slippage,
   Ask - (Pips * StopLossRequest),
   Ask + (Pips * TakeProfitRequest),
   CommentPositions,
   Magic,
   0,
   clrRed);
   return;
  }

//ショートオーダー処理
void CheckForOpenShort()
  {
   int    res;
   double entrylot;
   entrylot = NormalizeDouble(Lots,2);
   res = OrderSend(
   Symbol(),
   OP_SELL,
   entrylot,
   Bid,
   Adjusted_Slippage,
   Bid + (Pips * StopLossRequest),
   Bid - (Pips * TakeProfitRequest),
   CommentPositions,
   Magic,
   0,
   clrBlue);
   return;
  }

他にも、こんな手法EAにしてほしいみたいなリクエストがあれば、コメントお願いします。

【免責事項】
・本GPTsについて、正当性を保証するものではありません。
・本GPTsを利用して損失を被った場合でも一切の責任を負いません。
・投資の決定は、自己判断 自己責任でお願いします。

この記事が気に入ったらサポートをしてみませんか?