見出し画像

FX億トレーダーの「しん」さんのスキャル手法をEAにしてみた【勝てるロジックのEA化】


ChatGPT担当のナナミです。

前回の動画では、ヒロシさんのボリンジャーバンドとRSIを使用したスキャルのEAに、フィボナッチリトレースメントを追加することで勝てるデイトレEAを作るところまでやりました。

今回は、FX億トレーダーの「しん」さんのスキャル手法をEAにしたいと思います。


FX億トレーダーの「しん」さんのYouTubeチャンネル

「しん」さんのYouTubeチャンネル

しんさんとヒロシさんは共に伝説の億トレスキャルパーです。

ボリンジャーバンドを使用した1分足トレードという共通のスタイルを持っています。

また、動画にするかは未定ですが、2人以外の億トレスキャルパーの方も、同じようなプライスアクション手法を使うことから、秒スキャ・分スキャトレードでの勝ち方というのは、共通の考え方というのがあるのかもしれませんね。

わたしはEAクリエイターなので、スキャルピングは得意ではないのですが、億トレスキャルパーの方々が手法を公開してくれているので、ChatGPTを使って勝てるEAにすることが出来れば、こんな幸せなことないですよね。

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

■ブログURL
https://fx.reform-network.net/2024/07/23/【新連載】fx手法をchatgptでea化する【勝てるロジックの/

■前回記事
https://note.com/aimjey/n/nba7220808550

本日行う作業は、以下の通りです。

しんさんのトレードルールをChatGPTに伝えて、スキャルのEAを作成する。
その後、完成したスキャルのEAにテクニカル指標の売買フィルターを追加してデイトレEAにする。

この流れは、ヒロシさんのスキャル手法にフィボナッチリトレースメントを追加して、デイトレEAを完成させた時と同じですね。

しんさんの代表的なトレードルールのまとめた内容をChatGPTに送信したところ、バグだらけのEAが生成されました。

【逆張りトレード】
1、ボリンジャーバンドの±2シグマが9pips以上開いているレンジ相場の時は逆張りでトレードを行います。
2、ボリンジャーバンドの±2シグマのレンジの上限で売り、下限で買ってボリンジャーバンドの中心線の手前で利確します。
3、利食い幅は値動きの小さい時は2pips、値動きの大きな時は5pipsとします。
4、ヒゲが2本3本続くと反転しやすいので逆張りでエントリーします。
5、キリバン手前も反発しやすいので逆張りでエントリーします。この時は、キリバンタッチで損切りします。
6、ヒゲがない陰の丸坊主の時はショート、陽の丸坊主が出現した時はロングエントリーします。

【順張りトレード】
7、トレンド相場ではボリンジャーバンドの中心線近くまで
引き付けての押し目買い、戻り売りとします。

さすがに複雑すぎます。難し過ぎですね。

とりあえず、エラーが出ないように修正はしたものの、まともにトレードしてくれません。

もはや、EAとして機能しないので、やり方を変えます。

前回作成したEAに、しんさんのプライスアクション手法を追加して、成績がアップするか検証したいと思います。
以下のソースコードは、前回記事と同じプログラムです。

//+------------------------------------------------------------------+
//|                                    Masayan EA Generator_1.01.mq4 |
//|17.フィボナッチリトレースメント+スパイク
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Masayan."
#property version   "1.01"
#property strict
#property description "https://fx.reform-network.net"

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

//ここから改変可能
extern int RsiPeriod = 14; // RSIの期間
extern int BollingerBandsPeriod = 30; // ボリンジャーバンドの期間
extern int BollingerBandsDeviation = 2; // ボリンジャーバンドのシグマ値
extern int FibonacciLookBack = 500; // フィボナッチリトレースメント計算のための過去の期間500か1000
extern double FibonacciLevel = 0.5; // フィボナッチリトレースメントのレベル (例: 0.5 = 50%)
extern int SpikeLookBackPeriod = 5; // スパイクを確認する過去のバーの数(無効)
extern double SpikeThreshold = 0.006; // スパイクの閾値(パーセンテージ)(無効)
//ここまで改変可能

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;

// フィボナッチリトレースメントを計算する関数
double CalculateFibonacciLevel(double high, double low, double level)
{
   return high - (high - low) * level;
}

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

   if (StopLossRequest <= 0.01)
   {
      StopLossRequest = 0.01;
   }
   if (TakeProfitRequest <= 0.01)
   {
      TakeProfitRequest = 0.01;
   }
   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 highestHigh = iHigh(NULL, 0, iHighest(NULL, 0, MODE_HIGH, FibonacciLookBack, 0));
   double lowestLow = iLow(NULL, 0, iLowest(NULL, 0, MODE_LOW, FibonacciLookBack, 0));
   
   // フィボナッチレベルを計算
   double fibonacciLevel = CalculateFibonacciLevel(highestHigh, lowestLow, FibonacciLevel);

   // RSIとボリンジャーバンドを計算
   double rsi = iRSI(NULL, 0, RsiPeriod, PRICE_CLOSE, 1);
   double upperBand = iBands(NULL, 0, BollingerBandsPeriod, BollingerBandsDeviation, 0, PRICE_CLOSE, MODE_UPPER, 1);
   double lowerBand = iBands(NULL, 0, BollingerBandsPeriod, BollingerBandsDeviation, 0, PRICE_CLOSE, MODE_LOWER, 1);
   double currentPrice = Close[0];

/*
   // スパイクフィルターの追加
   bool spikeDetected = false;
   for (int i = 1; i <= SpikeLookBackPeriod; i++)
   {
      double priceChange = MathAbs((Close[i] - Open[i]) / Open[i]);
      if (priceChange >= SpikeThreshold)
      {
         spikeDetected = true;
         break;
      }
   }
*/
 //if (!spikeDetected){
   // ロングサインの条件
   if (rsi <= 30 && currentPrice <= lowerBand && currentPrice >= fibonacciLevel)
   {
      LongSign = true;
      ShortSign = false;
   }
   // ショートサインの条件
   else if (rsi >= 70 && currentPrice >= upperBand && currentPrice <= fibonacciLevel)
   {
      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をベースに、以下の条件を一つ一つ付け加えて、成績を記録しました。

結果は、、、。

【逆張りトレード】
NG ボリンジャーバンドの±2シグマが9pips以上開いているレンジ相場の時は逆張りでトレードを行います。
NG ボリンジャーバンドの±2シグマのレンジの上限で売り、下限で買ってボリンジャーバンドの中心線の手前で利確します。
NG 利食い幅は値動きの小さい時は2pips、値動きの大きな時は5pipsとします。
NG ヒゲが2本3本続くと反転しやすいので逆張りでエントリーします。
NG キリバン手前も反発しやすいので逆張りでエントリーします。この時は、キリバンタッチで損切りします。
NG ヒゲがない陰の丸坊主の時はショート、陽の丸坊主が出現した時はロングエントリーします。

【順張りトレード】
NG トレンド相場では順張りトレードを行い、ボリンジャーバンドの中心線近くまで引き付けての押し目買い、戻り売りとします。

全滅しました。
撃沈です。

プライスアクション手法を用いたEAの開発は難易度が高いです。
MT4自体が、テクニカル指標を得意とするシステムなので、キリバンとか瞬間的な値動きをとらえるのとか、めちゃくちゃ大変です。
坊主頭の陰線とか、ローソク足が確定する前にエントリーしたり、レートパネルを見てのトレードとか、これはもう裁量トレードでやるしかないですよね。

というわけで、今回のEA開発は成果なしで終わりました。

このままこの企画を終わってしまっては皆様に申し訳ないので、次回の動画ではわたしのEA開発スキルの80%の力を出して、フィボナッチリトレースメントのEAを手動でカスタマイズして更なる高性能EAへと進化させます。

もちろん完成したEAは、「Fibonacci Retracement USDJPY Ver2」として皆様にプレゼントします。

もちろん、本格運用可能なEAをご希望の方は、ゴゴジャンで有料で販売しているので、購入をご検討ください。

リアル口座で成績を公開しています。
https://www.gogojungle.co.jp/users/626040/realtrade

参考にしたYouTube動画URL
https://www.youtube.com/watch?v=BboSZ96vKGE

ゆかてぃんコラボ動画(オススメ!)
https://www.youtube.com/watch?v=EoGkZKJ2wW4

MT4のEA開発に役に立つ情報を配信しています。

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

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

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