MQL4MQL5 EA(エキスパートアドバイザー) 注文・決済
注文に失敗したら何回か再試行したい
結論:一時的なエラー(リクオート・サーバー混雑など)のときだけ、少し待って価格を取り直してから再送します。
考え方
リクオートや取引サーバーの混雑など、少し待てば通るエラーがあります。そのようなエラーのときだけ、Sleep() で待ち、最新の価格を取り直してから注文を送り直します。証拠金不足やロット数の誤りなど、何度送っても通らないエラーでは再試行しません(連打するとサーバーから制限されることがあります)。
- 注文を送り、失敗したらエラー番号(MQL5 はリターンコード)を調べる
- 一時的なエラーなら、少し待って価格を取り直し、回数の上限まで再送する
- それ以外のエラーは、すぐにあきらめてログに出す
そのまま使えるコード
MetaEditor の「新規作成」で「エキスパートアドバイザ(テンプレート)」を選び、できたファイルの中身をすべてこのコードに置き換えてコンパイル(F7)します。ファイルは Experts フォルダに保存され、ナビゲーターからチャートにドラッグして使います。
MQL4(MT4)
#property strict
// 一時的なエラーのときだけ最大3回再試行して買う関数(MT4)
input double InpLots = 0.1; // ロット
bool IsTemporary(int err)
{
return err == 4 || err == 6 || err == 128 || err == 129 || err == 135 || err == 136 || err == 137 || err == 138 || err == 146;
}
int BuyWithRetry(double lots, int tries = 3)
{
for(int i = 0; i < tries; i++)
{
RefreshRates(); // 最新の Ask を取り直す
int ticket = OrderSend(_Symbol, OP_BUY, lots, Ask, 30, 0, 0);
if(ticket >= 0) return ticket;
int err = GetLastError();
Print("注文失敗 ", i + 1, "回目 error=", err);
if(!IsTemporary(err)) break; // 待っても通らないエラー
Sleep(1000);
}
return -1;
}
int OnInit()
{
return INIT_SUCCEEDED;
}
void OnTick()
{
// 例:ポジションがなければ買う(実際には売買条件を入れる)
if(OrdersTotal() == 0)
BuyWithRetry(InpLots);
}MQL5(MT5)
// 一時的なエラーのときだけ最大3回再試行して買う関数(MT5)
#include <Trade\Trade.mqh>
input double InpLots = 0.1; // ロット
CTrade trade;
bool IsTemporary(uint rc)
{
return rc == TRADE_RETCODE_REQUOTE || rc == TRADE_RETCODE_PRICE_CHANGED || rc == TRADE_RETCODE_PRICE_OFF
|| rc == TRADE_RETCODE_TIMEOUT || rc == TRADE_RETCODE_CONNECTION || rc == TRADE_RETCODE_TOO_MANY_REQUESTS;
}
bool BuyWithRetry(double lots, int tries = 3)
{
for(int i = 0; i < tries; i++)
{
if(trade.Buy(lots) && trade.ResultRetcode() == TRADE_RETCODE_DONE) // price=0 で毎回最新の Ask
return true;
uint rc = trade.ResultRetcode();
Print("注文失敗 ", i + 1, "回目 ", rc, " ", trade.ResultRetcodeDescription());
if(!IsTemporary(rc)) break; // 待っても通らないエラー
Sleep(1000);
}
return false;
}
int OnInit()
{
return INIT_SUCCEEDED;
}
void OnTick()
{
// 例:ポジションがなければ買う(実際には売買条件を入れる)
if(PositionsTotal() == 0)
BuyWithRetry(InpLots);
}MT4 版・MT5 版とも MetaEditor でコンパイル(エラー・警告なし)を確認済みです。実際の口座で使う前に、デモ口座やストラテジーテスターで動作を確かめてください。
カスタマイズのポイント
- 待つ時間は 0.5〜2 秒程度にします。長く待つと、その間に相場が動きます。
注意点
- MT5 でリターンコード 10012(タイムアウト)のときは、実際には約定している場合があります。再送する前にポジションが増えていないか確認すると安全です。
- ストラテジーテスターでは Sleep() は実際には待ちません。












