【新連載】ChatGPTでMT4インジケーターをEAに変換してバックテストを徹底解説
ChatGPT担当のナナミです。
本日は、新連載「ChatGPTでMT4のインジケーターを開発する」シリーズの第2回目の動画ということで、MT4インジケーターをEAに変換してバックテストするやり方を徹底解説したいと思います。
MT4を使っている人なら、インジケーターは日常的に使用していると思います。
ですが、そのインジケーターの売買サインに従ってトレードしていると、本当に勝てるのか不安になりますよね?
もし、売買サインに従ってトレードしたと仮定し、過去10年以上も前にさかのぼってバックテスト検証できるとしたらどうしますか?
そこで今回、AIの力を活用して、初心者でも簡単にインジケーターのロジックをEAに変換できるやり方を徹底解説することにしました。
使用するツールは『Masayan EA Generator for MT4』と『Masayan Indicator Generator for MT4』というGPTsになります。
ChatGPTを使用するので、プログラミングの知識がなくてもMT4のEAやインジケーターを簡単に作成できます。
ChatGPTのアカウントがあれば、無料でご利用いただけます。
ぜひ、この機会にChatGPTを使ったインジケーターのEA化にチャレンジしてみてください。
GPTsのリンクはこちら(GPT Store)
■Masayan EA Generator for MT4
https://chatgpt.com/g/g-VYNEupgws-masayan-ea-generator-for-mt4-ver1-01
■Masayan Indicator Generator for MT4
https://chatgpt.com/g/g-t1m5iewUY-masayan-indicator-generator-for-mt4
■ゴゴジャンでEA・インジケーター販売中!
https://www.gogojungle.co.jp/users/626040/products
■ブログURL(MT4初心者向け!GPTsのMasayan EA Generatorを使った自動売買講座)
https://fx.reform-network.net/2024/10/16/mt4初心者向け!gptsのmasayan-ea-generatorを使った自動売買講座/
■ブログURL【無料】MT4対応の新ツール登場!ノーコードでインジケーター作成!
https://fx.reform-network.net/2024/10/30/【無料】mt4対応の新ツール登場!ノーコードでイ/
まず初めに、ゴールデンクロスでロング、デッドクロスでショートのインジケーターを作成してみましょう。
Masayan Indicator Generator for MT4で簡単に作ることが出来ます。
生成されたコードをコンパイルしてMT4のチャートに表示させます。
移動平均線の期間は50と200にします。
きちんとクロスしたタイミングで売買サインが出ているか確認します。
MT4に標準搭載されているMoving Averageの期間をインジケーターと同じ設定にします。
デッドクロスでショート、ゴールデンクロスでロングのサインが正しい位置で表示されていることが確認できました。
次に、このインジケーターのロジックで動くEAを作成します。
Masayan EA Generator for MT4のページに行きます。
試しに、インジケーターのソースコードを丸ごとコピペで貼り付けてみます。
ここで問題が発生しました。
ChatGPTがテンプレートを使用せずにEAのコードを書き出しているではありませんか。
これだとコンパイルした時に、このようなエラーが出てEAが正常に動きません。
こうなるともう、いくらテンプレートを使用してとお願いしても言うことを聞いてくれません。
この場合の対処方法は、プロンプトをシンプルにすることです。
ロジックの部分だけ抜き出して送信します。
今度はきちんとテンプレートを使用したEAが生成されました。
あとは、EAとインジケーターのパラメーターを同じ値にすれば、同期するはずです。
次に、フラクタルズのロジックを使用したインジケーターを作成してみましょう。
インジケーターは問題なく生成されたみたいです。
コンパイルもうまくいきました。
MT4のチャートにインジケーターを表示させてみます。
問題なさそうですね。
次に、完成したロジックのEAを作成します。
インジケーターのロジックの部分だけコピーして、Masayan EA Generator for MT4に貼り付けします。
ここでまたしても問題が発生。
テンプレートを使用せずEAを作っています。
コンパイルでエラーが出ました。
ロジックが複雑になると、うまくいかないことがあります。
何度かやり直して、ようやくエラーが消えました。
試しに、今作成した2つのロジック「ゴールデンクロス」と「フラクタルズ」のEAに優位性があるかバックテストで確認してみます。
初めに、ゴールデンクロスでロング、デッドクロスでショートのEAです。
これはすばらしい!見事なプラスのEAが完成しました。
きちんと、ゴールデンクロスでロング、デッドクロスでショートしています。
次に、フラクタルズのEAを見てみましょう。
ここで、またしても問題が発生しました。
トレードしないEAになってしまいました。
原因を調べます。
ここのフラクタルズの高値安値が拾えているか確認します。
チャート画面の左上に表示されるコメント部分に、高値fractalUpの値を入れてみます。
レートが取得されていると、ここにレートが表示されます。
やっぱりです。ゼロ、つまり値が取得できていません。
試しに、1本前のバーのHighとLowの値を入れてみます。
今度はきちんとレートが表示されました。
つまり、この現象は以前の動画でもあった事象、iFractalsの関数がEAだと拾えない問題になります。
iFractalsの値がEAだと拾えない問題について、ChatGPTの新機能GPTサーチで検索してみました。
するとこのような回答が。
なるほど、直近のフラクタル値を取得するには、shiftを2に設定すればいいのですね。
このやり方で、値を取得できるようになったのですが、やっぱりエントリーしないEAになってしまいました。
というわけで、iFractalsの関数が機能しない問題は、今後の課題としておきます。
次に、ATRを使用したインジケーターとEAを作ってみましょう。
ATR(Average True Range)は、価格の変動幅、すなわちボラティリティを測定するためのテクニカル指標です。
ATRの数値が高い場合、市場の価格変動が大きく、ボラティリティが高いことを示します。
逆に、ATRの数値が低い場合、価格変動が小さく、ボラティリティが低いことを示します。
以前の動画で登場したEA、グリッドラッシュのロジックにも採用しているテクニカル指標になります。
インジケーターの表示は問題なさそうです。
続いて、EAのバックテスト結果を見てみます。
どうやらトレード回数が少ないEAに仕上がってしまいました。
ChatGPTに改善方法を聞いてみます。
なるほど、ATRの倍率を小さくするといいのですね。
ということで、ドル円5分足チャートでMT4の最適化機能を使い、一番良いパラメータ値を探してみます。
と、ここで、なんということでしょう!
ものすごい好成績のパラメーターを発見しました。
ここです、ATR倍率が0.3のところです。
始値のみのバックテスト結果は、プロフィットファクター1.16となかなかの数字です。
ですが、全ティックでバックテストすると無駄なエントリーが頻発し、このように右肩下がりの資産チャートになります。
始値のみでは好成績なので、EAではなくインジケーターとして使用すると良さそうですね。
EAの場合、エントリーするタイミングを絞り込む必要がありそうです。
考えられる方法として、バーが確定した瞬間だけエントリーするとか、他のテクニカル指標と組み合わせるとかですね。
ATR倍率が0.3のパラメーターは、それなりに優位性がありそうなので、今後詳しく調査をしていきたいと思います。
完成したATRのインジケーターは下記より無料でダウンロードできます。
/*
完成前のインジケーターです。
不具合あると思います。
バグの報告はnoteにコメントお願いします。
アラートはデフォルトでオフにしています。
*/
//---START--------
#property copyright "Copyright 2024, Masayan."
#property version "1.01"
#property strict
#property description "ATRチャネル逆張りインジケーター"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red // 天井シグナルの色
#property indicator_color2 Aqua // 底シグナルの色
//ここから改変可能
extern int ATRPeriod = 7; // ATRの期間
extern double ChannelMultiplier = 0.3; // チャネル幅の倍率
//ここまで改変可能
input bool AlertOnOff = false; // アラート通知音 オンtrue オフfalse
extern int AlertTime = 2; // アラートの鳴る秒数(範囲1~10)
bool UpdateOnOff = false; // 新しいバーが更新されたタイミングでサインを出す処理
double TopBuffer[];
double BottomBuffer[];
int OnInit()
{
SetIndexBuffer(0, TopBuffer);
SetIndexBuffer(1, BottomBuffer);
SetIndexStyle(0, DRAW_ARROW);
SetIndexArrow(0, 233); // 天井シグナル矢印
SetIndexStyle(1, DRAW_ARROW);
SetIndexArrow(1, 234); // 底シグナル矢印
return(INIT_SUCCEEDED);
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if (rates_total < ATRPeriod) return 0;
int start = prev_calculated > 0 ? prev_calculated - 1 : 0;
if (AlertTime <= 1) AlertTime = 1;
if (AlertTime >= 10) AlertTime = 10;
if (Seconds() < AlertTime) {
UpdateOnOff = true; // アラートあり
} else {
UpdateOnOff = false; // アラートなし
}
bool TopSign = false;
bool BottomSign = false;
//■□■□■□■□■ 現在チャートに反映 ■□■□■□■□■
double ATRValue = iATR(NULL, 0, ATRPeriod, 1);
double upperChannel = close[1] + (ATRValue * ChannelMultiplier);
double lowerChannel = close[1] - (ATRValue * ChannelMultiplier);
if (UpdateOnOff) { // サインを点灯させる時間のみ
if (high[1] > upperChannel) {
TopSign = true;
} else if (low[1] < lowerChannel) {
BottomSign = true;
}
}
if (TopSign) {
TopBuffer[1] = high[1];
BottomBuffer[1] = EMPTY_VALUE;
if (UpdateOnOff && AlertOnOff) {
Alert("Top sign alert: Indicator = ATR Channel Indicator");
UpdateOnOff = false; // サインを表示したらリセット
}
} else if (BottomSign) {
BottomBuffer[1] = low[1];
TopBuffer[1] = EMPTY_VALUE;
if (UpdateOnOff && AlertOnOff) {
Alert("Bottom sign alert: Indicator = ATR Channel Indicator");
UpdateOnOff = false; // サインを表示したらリセット
}
}
//■□■□■□■□■ 過去チャートにのみ反映 ■□■□■□■□■
for (int i = start; i < rates_total; i++)
{
TopSign = false;
BottomSign = false;
// ATRを計算
ATRValue = iATR(NULL, 0, ATRPeriod, i);
upperChannel = close[i] + (ATRValue * ChannelMultiplier);
lowerChannel = close[i] - (ATRValue * ChannelMultiplier);
// チャネルの条件に基づきサインを判定
if (high[i] > upperChannel) {
TopSign = true;
} else if (low[i] < lowerChannel) {
BottomSign = true;
}
if (TopSign) {
TopBuffer[i] = high[i];
BottomBuffer[i] = EMPTY_VALUE;
} else if (BottomSign) {
BottomBuffer[i] = low[i];
TopBuffer[i] = EMPTY_VALUE;
} else {
TopBuffer[i] = EMPTY_VALUE;
BottomBuffer[i] = EMPTY_VALUE;
}
}
return rates_total;
}
//---END---
今後インジケーターの精度を上げる為のカスタマイズを行っていきます!
【免責事項】
・本GPTsについて、正当性を保証するものではありません。
・本GPTsを利用して損失を被った場合でも一切の責任を負いません。
・投資の決定は、自己判断 自己責任でお願いします。