表示されている業者は日本の金融庁に登録されていない海外業者の場合があります。
利用にはご自身で取引リスク・条件をご確認ください。
【リスクに関するご注意】FXは元本保証のない金融商品です。
為替変動やレバレッジにより損失が発生する可能性があります。
契約条件やリスク内容を十分にご確認のうえ、ご判断ください。
FXの自動売買ツールはMT4というFX取引ソフトのメタエディタというソフトで自動売買のプログラムを作ります。
自分は昔、EAのプログラムを作る講座に参加していたけど心折れ挫折した過去があります。
でも今はAIがある!
AIを使ってEAのプログラムを作ってみようと考えました。
ChatGPTにFX自動売買ツールのコードを書いてもらうには
表示されている業者は日本の金融庁に登録されていない海外業者の場合があります。
利用にはご自身で取引リスク・条件をご確認ください。
【リスクに関するご注意】FXは元本保証のない金融商品です。
為替変動やレバレッジにより損失が発生する可能性があります。
契約条件やリスク内容を十分にご確認のうえ、ご判断ください。
ChatGPTにただ単に売買ルールをプロンプトにして「作って」だけだとダメらしく、前もってコードテンプレート(土台)を作って、そこに売買ルールの部分を差し替えて作るのがいいみたいです。
プログラムに必要内容を指示しないと土台も作ってくれない。
そこで昔経験したプログラムに必要な内容を書き出してみました
〇EA設計
順番
①
#property strict
②変数を宣言
マジックナンバー
ロット
テイクプロフィットpips設定
ストップロスpips設定
利確定設定
損切設定
スリッページ設定(最大Xポイント(=0.Xpipsまで)のズレなら許容して注文を通していいよ)
過去のバーと別のロジックでのバー数をゼロにする
最大ポジション保有数
ローソク足始値のみに稼働させるかどうかの選択
エントリールールの各変数
エントリーフィルターの各変数
決済ルールの各変数
③価格が1回でも動いたら、この中の処理を1回実行する
小数点以下の桁数に応じてPipsの値を調整する
ポジションにテイクプロフィット, ストップロスをセットする
オーダー選択(エラーを生じた場合、ループから抜け出す)
オーダー確認(通貨ペアが一致しない場合は、ポジションにテイクプロフィット, ストップロスをセットするに戻る)
マジックナンバー確認(マジックナンバーが一致しない場合は、ポジションにテイクプロフィット, ストップロスをセットするに戻る)
買いポジションのルールとフィルターに合致しているか確認し買いエントリー
買いポジションと同時に買いポジションだった場合の、含み損益を計算する
TP, SLがどちらも設定されていなければ、TP, SLを設定する
売りポジションのルールとフィルターに合致しているか確認し売りエントリー
売りポジションと同時に売りポジションだった場合の、含み損益を計算する
TP, SLがどちらも設定されていなければ、TP, SLを設定する
買いポジションがあった場合、決済ルールに合致していたら決済
売りポジションがあった場合、決済ルールに合致していたら決済
コードに必要な要素を書き出しました
一目では何が何だかわかりませんよね?
でも一つ一つをかみ砕いて読めば理解できると思います
理解しなきゃダメ?
いえいえ、わからなくてもいいように自分がテンプレートを作りました。
自分が書き出した必要要素を使ってChatGPTに指示して作ってもらいました。
作ったコードを公開します!!
一応必要要素が不十分だといけないので、
「EAを販売して生計を立てている経験豊富なEA作成者として完璧にコードが書かれているかディベート形式で対立意見を書いてください」
とChatGPTに指示し”なるだけ”(自信がないから)完璧な(つもりの)コードにしました
更に、プログラムコードは上から下に順番に処理されるものなので通常は売買ルールを貼り付ける場所がコードの中ほどになりますが、それを一番下に移動し売買ルールを貼り付ける場所をわかりやすくしました。
テンプレートコードを使ってEAを作るには
で、テンプレートコードをプロンプトに含め、ChatGPTに売買ルールを伝えてコードを書いてもらうわけです。
ただテンプレートを含めた売買ルールEAのコード全部を書いてもらうと全体のコードが崩れることがあるらしく、「エントリー条件」と「決済条件」だけを別々に書いてもらうほうがいいみたいです。
「ぜってーテンプレートのコードを崩すなよ」
とChatGPTに指示してもChatGPTは崩してきます。
コードの上部にあるinputパラメータや変数追加も必要なので別途出力します。
下記のように
・【MainEntryCondition】および【CheckExit】関数のロジック部分だけをMQL4形式で出力してください。
・MainEntryConditionとCheckExit関数は売買ルールに従って書き換えてください。
・inputパラメータや変数追加が必要なら別途出力してください。
自分はプロンプトの書き方が完璧ではないので、皆さんでなんとかやってみてください。
EAのテンプレートコード
テンプレートコードはメタエディタでコンパイルしてもエラーはでないはずです。
しかぁし!!
注意、くれぐれも、いきなりそのまま使わないでください。
コード内の売買ルールは超いいかげんなものです。
何でもコードを書いてエラーが無ければ儲かるFX自動売買ツールとはならないのです。
売買ルールを自分で変更して使っていただいて構いませんが、テンプレートコードを使って何かしらの損害が出てもこちらは関知しませんし責任は負えません。
そこをご理解の上、ご使用ください。
//+-----------------------------------------------------------------+
//| シンプルな単一通貨・時間足EAテンプレート(通知付き) |
//+-----------------------------------------------------------------+
#property strict
//+--------------------------------------------------------------------------+
//|入力パラメータ(ユーザーが自由に変更可能な設定) |
//|必要な追加(input パラメータと変数)があったら、この”下の部分”に追加する|
//+--------------------------------------------------------------------------+
input int MagicNumber = 123456; // マジックナンバー(識別用)
input double LotSize = 0.1; // ロット数(取引量)
input int TakeProfitPips = 30; // 利確幅(pips)
input int StopLossPips = 15; // 損切幅(pips)
input int Slippage = 3; // スリッページ許容範囲
input int EntryInterval = 300; // エントリー間隔(秒)
input int MaxPositions = 1; // 最大ポジション数
input double MaxSpreadPips = 2.0; // 許容スプレッド(pips)
input bool UseEmailNotify = true; // メール通知を使うかどうか
//--- グローバル変数(過去のエントリー時間保存用)
datetime lastEntryTime = 0; // 最後にエントリーした時間
//+--------------------------------------------------------------------------+
//入力パラメータ(ユーザーが自由に変更可能な設定) |
//必要な追加(input パラメータと変数)があったら、この”上部部分”に追加する |
//+--------------------------------------------------------------------------+
//+------------------------------------------------------------------+
// EAの初期化処理(チャートにセットされたときに1度だけ実行) |
//+------------------------------------------------------------------+
int OnInit()
{
Print("EA初期化完了。単一通貨・時間足監視開始。");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
// 毎ティックごとに実行されるメイン処理関数 |
//+------------------------------------------------------------------+
void OnTick()
{
string symbol = Symbol(); // 現在の通貨ペア
int timeframe = Period(); // 現在の時間足
if(!IsNewBar()) return; // 新しいバーでなければ何もしない
if(!CheckSpreadFilter(symbol)) return; // スプレッドが広すぎると取引しない
if(CountOpenPositions(symbol) >= MaxPositions) return; // 保有ポジション制限
if((TimeCurrent()-lastEntryTime) < EntryInterval) return; // エントリー間隔未満ならスキップ
// --- 買い注文条件 ---
if(!HasPosition(symbol, "Buy") && MainEntryCondition(symbol, timeframe, "Buy"))
{
if(SendOrder(symbol, timeframe, "Buy")) // 買いエントリーを実行
{
lastEntryTime = TimeCurrent(); // 最後のエントリー時間更新
if(UseEmailNotify) SendMail("EA Entry Buy", symbol + " Buy entry at: " + DoubleToString(Close[1],Digits));
}
}
// --- 売り注文条件 ---
if(!HasPosition(symbol, "Sell") && MainEntryCondition(symbol, timeframe, "Sell"))
{
if(SendOrder(symbol, timeframe, "Sell")) // 売りエントリーを実行
{
lastEntryTime = TimeCurrent(); // 最後のエントリー時間更新
if(UseEmailNotify) SendMail("EA Entry Sell", symbol + " Sell entry at: " + DoubleToString(Close[1],Digits));
}
}
ManagePositions(symbol, timeframe); // 保有ポジションの管理(決済条件の判定など)
}
//+------------------------------------------------------------------+
// 新しいバー(足)が始まったかどうかを判定 |
//+------------------------------------------------------------------+
bool IsNewBar()
{
static datetime prevTime = 0;
datetime currentTime = iTime(Symbol(), Period(), 0);
if(currentTime != prevTime)
{
prevTime = currentTime;
return true;
}
return false;
}
//+------------------------------------------------------------------+
// スプレッドチェック(許容pips以内か) |
//+------------------------------------------------------------------+
bool CheckSpreadFilter(string symbol)
{
double spreadPoints = (MarketInfo(symbol,MODE_ASK) - MarketInfo(symbol,MODE_BID)) / MarketInfo(symbol,MODE_POINT);
double maxAllowed = MaxSpreadPips * Point2Pips(symbol);
return (spreadPoints <= maxAllowed);
}
//+------------------------------------------------------------------+
// 注文送信関数 |
//+------------------------------------------------------------------+
bool SendOrder(string symbol, int timeframe, string direction)
{
int cmd = (direction=="Buy") ? OP_BUY : OP_SELL; // 買い/売りコマンド識別
double price = (direction=="Buy") ? MarketInfo(symbol,MODE_ASK) : MarketInfo(symbol,MODE_BID);
double pips2point = Point2Pips(symbol) * MarketInfo(symbol,MODE_POINT);
double sl = (direction=="Buy") ? price - StopLossPips * pips2point : price + StopLossPips * pips2point;
double tp = (direction=="Buy") ? price + TakeProfitPips * pips2point : price - TakeProfitPips * pips2point;
int ticket = OrderSend(symbol, cmd, LotSize, price, Slippage, sl, tp, "EA order", MagicNumber, 0, clrBlue); // 注文実行
return (ticket > 0);
}
//+------------------------------------------------------------------+
// 保有ポジションの決済管理 |
//+------------------------------------------------------------------+
void ManagePositions(string symbol, int timeframe)
{
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol()!=symbol || OrderMagicNumber()!=MagicNumber) continue; // 他の通貨や別EAの注文は無視
string dir = (OrderType()==OP_BUY) ? "Buy" : (OrderType()==OP_SELL) ? "Sell" : "";
if(dir=="") continue;
if(CheckExit(symbol, timeframe, dir)) // 決済条件を満たしたか
{
bool closed = OrderClose(OrderTicket(), OrderLots(),
(dir=="Buy") ? MarketInfo(symbol,MODE_BID) : MarketInfo(symbol,MODE_ASK),
Slippage, clrRed); // 決済実行
if(closed && UseEmailNotify)
SendMail("EA Exit " + dir, symbol + " exit at: " + DoubleToString(Close[1],Digits)); // 決済通知
}
}
}
}
//+------------------------------------------------------------------+
// 指定通貨・方向のポジション保有確認 |
//+------------------------------------------------------------------+
bool HasPosition(string symbol, string direction)
{
for(int i=OrdersTotal()-1;i>=0;i--)
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
if(OrderSymbol()==symbol && OrderMagicNumber()==MagicNumber)
if((direction=="Buy" && OrderType()==OP_BUY) ||
(direction=="Sell" && OrderType()==OP_SELL))
return true;
return false;
}
int CountOpenPositions(string symbol) // 現在の保有ポジション数カウント
{
int count=0;
for(int i=OrdersTotal()-1;i>=0;i--)
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
if(OrderSymbol()==symbol && OrderMagicNumber()==MagicNumber)
count++;
return count;
}
//+------------------------------------------------------------------+
// ブローカー仕様に応じてポイントをpipsに換算 |
//+------------------------------------------------------------------+
double Point2Pips(string symbol)
{
int digits = (int)MarketInfo(symbol,MODE_DIGITS);
if(digits==3 || digits==5) return 10.0;
else return 1.0;
}
//+------------------------------------------------------------------------------------------------------------------+
//+------------------------------------------------------------------------------------------------------------------+
//--- 【売買ロジック】(自分のルールを入れる場所)★ このロジックは例です。自分のルールに書き換えて使ってください----|
//+------------------------------------------------------------------------------------------------------------------+
//+------------------------------------------------------------------------------------------------------------------+
//+-------------------------------------------------------------------------------+
// エントリー条件 ★ このロジックは例です。自分のルールに書き換えて使ってください |
//+-------------------------------------------------------------------------------+
bool MainEntryCondition(string symbol, int timeframe, string direction)
{
double close = iClose(symbol, timeframe, 1); // 直近の終値
double open = iOpen(symbol, timeframe, 1); // 直近の始値
if(direction=="Buy") return (close>open); // 上昇なら買い
if(direction=="Sell") return (close<open); // 下降なら売り
return false;
}
//+-------------------------------------------------------------------------+
// 決済条件 ★ このロジックは例です。自分のルールに書き換えて使ってください |
//+-------------------------------------------------------------------------+
bool CheckExit(string symbol, int timeframe, string direction)
{
double close = iClose(symbol, timeframe, 1); // 直近の終値
double open = iOpen(symbol, timeframe, 1); // 直近の始値
if(direction=="Buy") return (close<open); // 下落で買い決済
if(direction=="Sell") return (close>open); // 上昇で売り決済
return false;
}
//+------------------------------------------------------------------+
再度注意
くれぐれも、いきなりそのまま使わないでください。
いきなり金を突っ込んで稼働なんてもってのほかです。
コード内の売買ルールは超いいかげんなものです。
売買ルールを自分で変更して使っていただいて構いませんが、コードに問題があるなどして何かしらの損害が出てもこちらは関知しませんし責任は負えません。
そこをご理解の上、ご使用ください。
自分の売買ルールをテンプレートコードに反映したら
コードをメタエディタのコードを書く部分に貼り付けて一応は出来上がりです
コンパイルしてエラーがでなければ一応動きます
詳しいやり方ですか?
ググればわかりやすく説明しているページがいくらでもでてきますので、そちらを参考にしてください。
後日、気が向いたら一連の作業の流れ的なブログ記事を書くかもです。
ごめんなさい。
とりあえずは許してください。
テンプレートコード作るのに精も近も尽き果てました。
最後に
数年前までAIが無かった時代、コードは自らの手でキーボードをたたきゼロから書いていました。
でも今やコードを自分の手で書けなくてもコードを作ることができる時代になりました。
しかし現状AIは万能ではなく工夫が必要だと思います。
今回テンプレートを作成するにあたり実際に動く部分のコードは一切自分の手で書いていません。
「//」を付けて自由に半角でも全角でもコメントが書ける部分だけ自分で分かりやすく書きました。
なのでどうゆう処理をする部分かもわかり自分的にもいい復習になりました。
今は、売買ルールをテンプレートにはめ込んで色々やっている段階です。
売買ルールもYouTubeなどで発信している人の言うことを参考にしてChatGPTに考えてもらいましたけど。
その作業も進展がありましたら記事にしていこうと考えています。
コメント