MQL4MQL5 EA(エキスパートアドバイザー) ポジション管理
前回の取引が勝ちか負けかを調べたい
結論:MQL4 は口座履歴(MODE_HISTORY)、MQL5 は HistorySelect() で読んだ決済のディールから、いちばん新しいものの損益を調べます。
考え方
前回の取引の勝ち負けは、マーチンゲール(負けたらロットを増やす)や連敗での停止などに使います。MQL4 では決済済みの注文、MQL5 では決済のディール(DEAL_ENTRY_OUT)の中から、この EA のもので決済時刻がいちばん新しいものを探します。ここでは、直前の損益と連敗数を表示する EA を例にしています。
- 決済履歴を読み込む
- この EA の決済だけを、新しいものから順に調べる
- 損益がマイナスの間は連敗数を数え、プラスが出たら止める
そのまま使えるコード
MetaEditor の「新規作成」で「エキスパートアドバイザ(テンプレート)」を選び、できたファイルの中身をすべてこのコードに置き換えてコンパイル(F7)します。ファイルは Experts フォルダに保存され、ナビゲーターからチャートにドラッグして使います。
MQL4(MT4)
#property strict
// 直前の取引の損益と連敗数を表示する EA(MT4)
input int InpMagic = 1001; // マジックナンバー
// 新しい順に見て、負けが何回続いているか
int LossStreak(double &lastProfit)
{
lastProfit = 0;
int streak = 0;
datetime lastTime = 0;
// 口座履歴は時刻順とは限らないので、新しい順に並べて調べる
int n = OrdersHistoryTotal();
datetime times[]; double profits[];
ArrayResize(times, 0); ArrayResize(profits, 0);
for(int i = 0; i < n; i++)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
if(OrderMagicNumber() != InpMagic || OrderSymbol() != _Symbol || OrderType() > OP_SELL) continue;
int k = ArraySize(times);
ArrayResize(times, k + 1); ArrayResize(profits, k + 1);
times[k] = OrderCloseTime();
profits[k] = OrderProfit() + OrderSwap() + OrderCommission();
}
for(int done = 0; done < ArraySize(times); done++)
{
int best = -1;
for(int j = 0; j < ArraySize(times); j++) // まだ見ていない中で最も新しいもの
if(times[j] != 0 && (best < 0 || times[j] > times[best])) best = j;
if(best < 0) break;
if(lastTime == 0) { lastProfit = profits[best]; lastTime = times[best]; }
if(profits[best] >= 0) break;
streak++;
times[best] = 0;
}
return streak;
}
int OnInit()
{
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
Comment("");
}
void OnTick()
{
double last;
int streak = LossStreak(last);
Comment("直前の損益:", DoubleToString(last, 0), " 連敗数:", streak);
}MQL5(MT5)
// 直前の取引の損益と連敗数を表示する EA(MT5)
input ulong InpMagic = 1001; // マジックナンバー
// 新しい順に見て、負けが何回続いているか
int LossStreak(double &lastProfit)
{
lastProfit = 0;
int streak = 0;
bool first = true;
if(!HistorySelect(0, TimeCurrent() + 60)) return 0;
for(int i = HistoryDealsTotal() - 1; i >= 0; i--) // ディールは時刻順に並んでいる
{
ulong d = HistoryDealGetTicket(i);
if(d == 0) continue;
if(HistoryDealGetInteger(d, DEAL_ENTRY) != DEAL_ENTRY_OUT) continue;
if((ulong)HistoryDealGetInteger(d, DEAL_MAGIC) != InpMagic || HistoryDealGetString(d, DEAL_SYMBOL) != _Symbol) continue;
double p = HistoryDealGetDouble(d, DEAL_PROFIT) + HistoryDealGetDouble(d, DEAL_SWAP) + HistoryDealGetDouble(d, DEAL_COMMISSION);
if(first) { lastProfit = p; first = false; }
if(p >= 0) break;
streak++;
}
return streak;
}
int OnInit()
{
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
Comment("");
}
void OnTick()
{
double last;
int streak = LossStreak(last);
Comment("直前の損益:", DoubleToString(last, 0), " 連敗数:", streak);
}MT4 版・MT5 版とも MetaEditor でコンパイル(エラー・警告なし)を確認済みです。実際の口座で使う前に、デモ口座やストラテジーテスターで動作を確かめてください。
カスタマイズのポイント
- 連敗数でロットを増やすなら、ロット=基本ロット × MathPow(2, 連敗数) のように計算します(上限を必ず設けます)。
- 毎ティック履歴を調べると重くなるので、実際の EA では新しい足ができたときや決済のあとだけ調べます。
注意点
- MT4 で調べられるのは、ターミナルの「口座履歴」タブに読み込まれている期間だけです。タブで「全履歴」にしておきます。
- MT5 の手数料は、エントリー側のディールにも記録されます。ここでは決済側のディールの値だけを足しています。












