1. HistoryDealSelect関数の概要と実務での活用法
MQL5において、過去の取引情報を取得することは、単に収益を確認するだけでなく、システムの堅牢性を高めるために不可欠です。HistoryDealSelectは、指定した「約定(ディール)チケット番号」に基づいて、特定の約定情報を参照可能にする関数です。
MQL4から移行した開発者が最もつまずきやすいのが、MQL5における「注文(Order)」「約定(Deal)」「ポジション(Position)」の分離です。
– 注文(Order): 売買の指示。
– 約定(Deal): 注文が執行された結果(履歴に残る事実)。
– ポジション(Position): 約定の結果として保有している現在の持ち分。
実務では、「決済したばかりのトレードの正確な利益(スワップや手数料を含む)を取得したい」場合や、「特定のポジションIDに関連するすべての約定履歴を遡って分析したい」といった場面で、このHistoryDealSelectが活躍します。
2. 構文と戻り値
HistoryDealSelectの構文は非常にシンプルですが、引数の型に注意が必要です。
bool HistoryDealSelect(
ulong ticket // 約定チケット番号
);
パラメーター
- ticket: 取得したい約定のチケット番号を指定します。これは
ulong(符号なし64ビット整数)型です。
戻り値
- true: 指定したチケット番号の約定が履歴の中から見つかり、選択に成功した場合。
- false: 失敗した場合。エラーの詳細は
GetLastError()関数で確認できます。
この関数を実行してtrueが返ってくると、それ以降、HistoryDealGetDoubleやHistoryDealGetIntegerといった関数を使用して、その約定の価格、数量、利益、手数料などの詳細データを読み取ることができるようになります。
3. 具体的な使い方・実践サンプルコード
以下は、最後に発生した約定(ディール)の情報を取得し、その利益と手数料をエキスパートログに出力する実用的なコード例です。
void OnDeinit(const int reason)
{
// 履歴全体にアクセスするために、まずはHistorySelectでキャッシュを構築する必要がある
// ここでは全履歴を対象とする例
if(!HistorySelect(0, TimeCurrent()))
{
Print("履歴の取得に失敗しました。");
return;
}
// 履歴内の総約定数を取得
int totalDeals = HistoryDealsTotal();
if(totalDeals > 0)
{
// 最後に発生した約定のチケット番号を取得(インデックスは0から始まるため -1)
ulong lastDealTicket = HistoryDealGetTicket(totalDeals - 1);
if(lastDealTicket > 0)
{
// ★HistoryDealSelectで特定の約定を選択
if(HistoryDealSelect(lastDealTicket))
{
// 選択された約定から各種データを抽出
double profit = HistoryDealGetDouble(lastDealTicket, DEAL_PROFIT);
double commission = HistoryDealGetDouble(lastDealTicket, DEAL_COMMISSION);
double swap = HistoryDealGetDouble(lastDealTicket, DEAL_SWAP);
long magic = HistoryDealGetInteger(lastDealTicket, DEAL_MAGIC);
string symbol = HistoryDealGetString(lastDealTicket, DEAL_SYMBOL);
PrintFormat("約定チケット #%d | 通貨ペア: %s | 利益: %.2f | 手数料: %.2f | スワップ: %.2f",
lastDealTicket, symbol, profit, commission, swap);
}
else
{
Print("HistoryDealSelectの実行に失敗しました。");
}
}
}
}
4. 使用上の注意点とよくあるエラー
① HistorySelectとの併用が必須
HistoryDealSelectは、既に端末のメモリ(キャッシュ)に読み込まれている履歴の中から特定のチケットを探す関数です。そのため、事前にHistorySelect関数(期間指定)やHistorySelectByPosition関数を呼び出して、履歴をメモリ上にロードしておかないと、正しいチケット番号を指定してもfalseを返すことがあります。
② チケット番号の型違い
チケット番号はulong型です。MQL4時代のクセでint型で扱おうとすると、大きな数値になった際にオーバーフローを起こし、正しく参照できなくなるバグの原因となります。
③ 「約定」はエントリーと決済の両方で発生する
MQL5では、エントリー時にも約定(Deal)が発生し、決済時にも約定が発生します。DEAL_PROFITが0だからといって失敗ではありません。それは「エントリー(IN)」の約定である可能性があるからです。DEAL_ENTRYプロパティを確認して、それがIN(新規)かOUT(決済)かを判別するロジックを組むのがプロの定石です。
5. 【重要】自動売買における約定スピードと環境の罠
アルゴリズムトレードにおいて、ロジックの正確さと同等、あるいはそれ以上に重要なのが「実行環境のレスポンス」です。どんなに優れたEAを開発し、HistoryDealSelectで緻密な計算を行っても、自宅のPC環境から一般的なインターネット回線で注文を出している場合、数ミリ秒から数十ミリ秒のネットワーク遅延(レイテンシ)が避けられません。
FX市場は一瞬で価格が変動します。このわずかな遅延が原因で、プログラムが意図した価格と実際の約定価格が乖離する「スリッページ」が発生し、期待利得を大きく削り取ります。特にスキャルピングや高頻度取引を行う場合、自宅PCでの運用は致命的な損失を生むリスクがあります。
極限まで約定スピードを高め、優位性を確保するためには、取引サーバーに物理的に近いデータセンター内に設置された専用のVPS(仮想専用サーバー)を利用することが必須条件です。24時間安定稼働させるだけでなく、物理的な距離による遅延を最小化することこそが、プロのクオンツエンジニアが最初に行う「勝つためのインフラ投資」なのです。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント