見出し画像

【スーパートレンド】アベレージ・トゥルー・レンジ(ATR)の手法を検証してみた【あなたの考えたFX手法をEAにする】

YouTube動画
https://youtu.be/d2Dhe0F_qLM

ChatGPT担当のナナミです。


前回の動画では、3本のパラボリックSARを使用した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にする」/

■前回記事(3本のパラボリックSARを使用した372手法)
https://note.com/aimjey/n/n71b67986a455

まず初めに、ジェンスパークでスーパートレンド手法について検索してみます。

スーパートレンド手法はアベレージ・トゥルー・レンジ(ATR)のテクニカル指標を使用し相場の変動率を元に売買する手法です。

インジケーターとしてのスーパートレンドは、価格の上下にラインを引くことでトレンドを視覚的に判断できるという特徴があります。

エントリー条件は、価格がスーパートレンドのラインを上回ると上昇トレンド、下回ると下降トレンドと判断し順張り方向にエントリーします。

インジケーターならトレンドラインを見ながらエントリーすることになりますが、EAの場合インジケーターのロジックをそのままEAにすることが出来ません。

ChatGPTがスーパートレンドをどのように判断し、ロジックを構築するのか楽しみですね。

まず初めに、Masayan EA Generator for MT4に、スーパートレンドを使用したEAを作成してとプロンプトを送信します。

今回は、トレードの条件を詳しく入力しました。

どうやらATRのテクニカル指標はMT4の関数で対応できるようです。

ATRを使用したロジックが構築されました。

エラーは無いみたいなので、バックテストをまわしてみます。

1分足から4時間足まで順番にバックテストをまわしてみましたが、エントリー回数が極端に少ないです。

設定をいろいろと変更してみたところ、スーパートレンドの乗数を3から1に変更することで、トレード回数を増やすことが出来ました。

1分足から4時間足まで順番にバックテストをまわしたところ、15分足チャートだけプラスになりました。

TDSによる全ティックバックテストの結果は、このページの最後にあります。

完成したロジックは、スーパートレンドというよりATR手法のEAになっています。

リクエストの内容とは違うEAになってしまいました。

もう一度、ChatGPTに作成してもらいましょう。

ATRでなく、スーパートレンドを使用したEAを作成してとプロンプトを送信します。

すると今度はスーパートレンドインジケーターとしてiCustom関数を使用してEAを作成しましたとの回答が。

嫌な予感がします。

インジケーター用の関数はEAでは機能しないことは、フラクタルズのEA検証で実証済みです。

フラクタルズの場合、高値安値が拾えないという問題が発生したわけですが、MT4の仕様ということであれば何をやっても無駄ということです。

関数が使用できない以上、別の方法でロジックを構築するしかありません。

とりあえず、完成したコードでバックテストをまわします。

エントリー回数が少ないです。

いろいろと設定を変えてみましたが、エントリー回数が増えません。

ChatGPTに iCustom関数の中身を聞いてみます。

気になった点として、SuperTrendというカスタムインジケーターを呼び出してとありました。

念のためSuperTrendのインジケーターをネットでダウンロードしてMT4にインストールします。

これで、チャート上にSuperTrendのインジケーターを表示させることが出来ました。

バックテストを行います。

やっぱりトレード回数が少ないです。

どうやらロングのみエントリーして、ショートのトレードが発生していないことが原因だと分かりました。

調べたところsuperTrendDownとsuperTrendUpの値が正しく取得されていないことが分かりました。

MT4の仕様なのか、設定上の問題なのか継続して調査が必要です。

原因が分かる人いましたら、コメントお願いします。

SuperTrendのEAはエントリーしない不具合があるので、配布は見送ります。

ATRのロジックを使用したEAは問題なく動作しますので、概要欄にあるnoteの記事リンクよりダウンロードできます。

ドル円15分足チャートでのバックテスト結果はこちらです。


ATRを使用したEAのバックテスト

ATRを使用したEAのソースコードはこちらです。

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

//+---------------------------------------+
//|Masayan EA Generator_1.01.mq4          |
//+---------------------------------------+
#property copyright "Copyright 2024, Masayan."
#property version   "1.01"
#property strict
#property description "https://fx.reform-network.net"

extern int Magic = 20240925;// 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 = "ATR EA";

extern int ATRPeriod = 14; // ATRの期間
extern double Multiplier = 1.0; // スーパートレンドの乗数

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;
     }

//ここから改変可能
   double atr = iATR(NULL, 0, ATRPeriod, 0); // ATRを取得
   double superTrendUp = (High[1] + Low[1]) / 2 - Multiplier * atr; // スーパートレンドの上値ライン
   double superTrendDown = (High[1] + Low[1]) / 2 + Multiplier * atr; // スーパートレンドの下値ライン

   if(Close[1] > superTrendDown)
     {
      LongSign = true;
      ShortSign = false;
     }
   else if(Close[1] < superTrendUp)
     {
      ShortSign = true;
      LongSign = false;
     }
   else
     {
      LongSign = false;
      ShortSign = false;
     }
//ここまで改変可能

/*ここに決済ロジックを挿入*/

   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のご利用は無料となりますので、ぜひあなたのEAポートフォリオに組み込んでいただけると幸いです。

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


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

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