MQL5注文・ポジション・履歴管理完全ガイド|OrderSend・Position・Deal・Historyの基本
MQL5でEAを開発する時、注文を出す処理だけでなく、注文後のポジション確認、約定履歴、決済履歴、Magic Number、チケット番号、Order・Deal・Position・Historyの違いを理解しておくことが重要です。
EAがOrderSendやCTradeで注文を送った後、MT5内部では「注文」「約定」「ポジション」「履歴」が別の情報として扱われます。注文要求を送ったこと、注文が受け付けられたこと、約定したこと、現在ポジションとして残っていること、決済後に履歴へ移ったことは、それぞれ確認する場所が異なります。
この記事では、MQL5で注文・ポジション・履歴を管理する時に確認したい基本を整理します。Order、Deal、Position、History、OrderSend、CTrade、PositionSelect、PositionSelectByTicket、HistorySelect、HistoryOrderGet、HistoryDealGet、Magic Number、order ticket、deal ticket、position id、OnTradeTransaction、Hedging / Netting、ログ設計、バックテスト時の確認までを実務目線でまとめます。
なお、この記事はMT5 / MQL5のEA開発、注文管理、ポジション管理、履歴確認、ログ確認を目的とした技術記事です。特定の売買判断、利益、勝率、損失回避、推奨ロット、推奨銘柄を案内するものではありません。
- この記事で確認すること
- MQL5の注文管理で混同しやすい4つの要素
- OrderSend後に確認すること
- MqlTradeRequestとMqlTradeResultを分けて見る
- CTrade利用時も結果確認は必要
- Positionとは何か
- PositionSelectとPositionSelectByTicket
- Magic Numberで自EAの対象だけを抽出する
- Dealとは何か
- HistorySelectで履歴を確認する
- HistoryOrdersとHistoryDealsを分けて見る
- order ticket・deal ticket・position ticket・position id の違い
- OnTradeTransactionで取引イベントを追う
- Hedging口座とNetting口座の違いに注意する
- 決済後に履歴を確認する
- 注文・ポジション・履歴のログ設計
- バックテストで履歴管理を確認する
- よくある不具合と確認ポイント
- 開発依頼前に整理する情報
- 注文・ポジション・履歴管理の実務チェック表
- よくある質問
- 関連ページ
- まとめ
この記事で確認すること
- Order・Deal・Position・Historyの違い
- OrderSend後に確認するretcode、order、deal、comment
- CTrade利用時のResultRetcode確認
- PositionSelectとPositionSelectByTicketの使い分け
- HistorySelectで注文履歴・約定履歴を確認する考え方
- order ticket、deal ticket、position ticket、position id の違い
- Magic Numberで自EAの対象だけを抽出する方法
- Hedging口座とNetting口座の違い
- 決済後に履歴を追跡する方法
- OnTradeTransactionで注文・約定イベントを確認する方法
- 注文・約定・ポジション・履歴のログ設計
- バックテストで履歴確認する時の注意点
- 開発依頼前に整理する情報
MQL5の注文管理で混同しやすい4つの要素
MQL5の注文管理では、Order、Deal、Position、Historyを分けて考える必要があります。MT4に慣れている場合や、EAを初めて作る場合は、この違いで混乱しやすくなります。
注文要求を送った時点ではOrderが中心になります。実際に売買が成立するとDealが発生します。約定によって現在保有している建玉がPositionとして扱われます。決済済みの注文や約定はHistoryから確認します。
EA開発では、「注文を送った」「約定した」「ポジションが残っている」「履歴へ移った」を同じものとして扱わないことが重要です。たとえば、OrderSendの戻り値がtrueに見えても、実際の約定やポジション状態は別途確認する必要があります。
| 要素 | 意味 | 確認する場面 |
|---|---|---|
| Order | 注文です。成行、指値、逆指値などの注文要求や未約定注文を扱います。 | 注文を送ったか、未約定注文が残っているか、注文番号を確認する時。 |
| Deal | 約定です。実際に売買が成立した記録です。 | どの価格で約定したか、どのロットが成立したか、決済損益を確認する時。 |
| Position | 現在保有中のポジションです。 | 現在の建玉、ロット、建値、SL/TP、損益、対象チケットを確認する時。 |
| History | 過去の注文や約定の履歴です。 | 決済済み取引、過去注文、約定履歴、検証結果を確認する時。 |
OrderSend後に確認すること
OrderSendを使った場合、MqlTradeRequestで注文要求を作り、MqlTradeResultで注文送信結果を受け取ります。ここで確認すべきなのは、OrderSendの戻り値だけではありません。result.retcode、result.order、result.deal、result.comment、GetLastErrorを確認します。
OrderSendを呼び出したとしても、注文が約定したとは限りません。注文が拒否された、価格が不正、SL/TP距離が不正、証拠金不足、取引不可、ロット不正、約定方式が合わないなど、さまざまな理由で失敗することがあります。
注文処理のログでは、「何を注文しようとしたか」と「注文結果がどうだったか」を分けて残します。注文方向、ロット、価格、SL/TP、Magic Number、retcode、order ticket、deal ticket、commentを確認できるようにしておくと、バックテストや不具合調査で原因を追いやすくなります。
bool SendBuyOrder(double lots)
{
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = lots;
request.type = ORDER_TYPE_BUY;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
request.magic = 123456;
ResetLastError();
bool ok = OrderSend(request, result);
PrintFormat("ORDER_SEND ok=%s retcode=%d order=%I64u deal=%I64u last_error=%d comment=%s",
ok ? "true" : "false",
result.retcode,
result.order,
result.deal,
GetLastError(),
result.comment);
return ok;
}この例では、OrderSendの戻り値、retcode、order、deal、GetLastError、commentをログに出しています。実務では、これに加えて、注文前チェックのログ、ロット、価格、SL/TP、Magic Number、銘柄、時間足、発注理由も必要に応じて記録します。
MqlTradeRequestとMqlTradeResultを分けて見る
OrderSendを読む時は、MqlTradeRequestとMqlTradeResultを分けて確認します。MqlTradeRequestは、EAが送ろうとした注文要求です。MqlTradeResultは、送信後に返ってきた結果です。
注文できない時に、request側が間違っているのか、result側で拒否されているのかを分けないと、原因を追いにくくなります。たとえば、volumeが銘柄仕様に合っていない、SL/TPが近すぎる、priceの扱いがBUY / SELLで逆になっている、type_fillingが合っていない、といった問題はrequest側で確認します。
| 区分 | 主な項目 | 確認ポイント |
|---|---|---|
| MqlTradeRequest | action、symbol、volume、type、price、sl、tp、magic、comment。 | EAがどの注文を送ろうとしたか確認します。 |
| MqlTradeResult | retcode、order、deal、volume、price、bid、ask、comment。 | 注文送信後に何が返ったか確認します。 |
| GetLastError | MQL関数側のエラー情報。 | retcodeとは別に確認します。 |
| Expertsログ | EA側のログ。 | シグナル、発注前チェック、注文結果を確認します。 |
| Journalログ | MT5側のログ。 | 取引許可、接続、プラットフォーム側の状態を確認します。 |
CTrade利用時も結果確認は必要
CTradeを使う場合、Buy、Sell、PositionClose、PositionModifyなどのメソッドで注文や決済を行えます。ただし、CTradeを使っても結果確認は必要です。BuyやSellの戻り値だけで判断せず、ResultRetcode、ResultRetcodeDescription、ResultOrder、ResultDeal、GetLastErrorを確認します。
CTradeは注文処理を読みやすく整理できますが、発注前チェックや対象ポジション確認を自動で十分に行ってくれるわけではありません。EA側で、スプレッド、ロット、証拠金、SL/TP距離、Magic Number、最大ポジション数を確認してください。
#include <Trade/Trade.mqh>
CTrade trade;
bool TrySell(double lots)
{
ResetLastError();
bool ok = trade.Sell(lots, _Symbol);
PrintFormat("CTRADE_SELL ok=%s retcode=%d desc=%s order=%I64u deal=%I64u last_error=%d",
ok ? "true" : "false",
trade.ResultRetcode(),
trade.ResultRetcodeDescription(),
trade.ResultOrder(),
trade.ResultDeal(),
GetLastError());
return ok;
}CTradeで注文した後は、ResultRetcodeだけでなく、ResultOrderとResultDealも確認すると、注文と約定の追跡がしやすくなります。決済や変更でも同様に、PositionCloseやPositionModifyの戻り値だけで判断しないようにします。
Positionとは何か
Positionは、現在保有している建玉を表します。EAが現在のポジションを確認する時は、PositionSelect、PositionSelectByTicket、PositionGetInteger、PositionGetDouble、PositionGetStringなどを使います。
現在ポジションを確認する時は、単に「ポジションがあるか」だけでなく、銘柄、Magic Number、方向、チケット、ロット、建値、SL/TP、損益を確認します。複数EAや手動ポジションが混在する環境では、Magic Numberと銘柄で対象を絞ることが重要です。
特に、EAが注文しない、重複発注する、誤って決済する、手動ポジションまで触る、といった問題は、Positionの対象範囲が曖昧な時に起きやすくなります。ポジション管理では、必ず「このEAが管理すべき対象か」を確認してください。
| 確認項目 | 見る内容 | 注意点 |
|---|---|---|
| POSITION_TICKET | ポジションのチケット番号。 | 決済や変更対象の特定に使います。 |
| POSITION_SYMBOL | 対象銘柄。 | 複数銘柄EAでは必ず確認します。 |
| POSITION_MAGIC | Magic Number。 | 自EAのポジションだけを抽出します。 |
| POSITION_TYPE | BUY / SELL方向。 | 決済条件や反対売買判定に使います。 |
| POSITION_VOLUME | 保有ロット。 | 部分決済や最大保有数確認に使います。 |
| POSITION_PRICE_OPEN | 建値。 | 建値移動、損益計算、トレーリングに使います。 |
| POSITION_SL / POSITION_TP | 設定中のSL / TP。 | 変更処理や安全確認に使います。 |
| POSITION_PROFIT | 現在損益。 | 決済条件や状態表示に使います。 |
PositionSelectとPositionSelectByTicket
PositionSelectは、指定した銘柄の現在ポジションを選択する時に使います。PositionSelectByTicketは、チケット番号を指定してポジションを選択する時に使います。EAの構造によって、どちらを使うべきかが変わります。
単一銘柄・単一ポジション前提のEAではPositionSelectで足りる場合があります。一方、複数ポジション、複数銘柄、Hedging口座、個別チケット決済を扱うEAでは、PositionSelectByTicketで対象を明確にする方が安全です。
PositionSelectで取得できたとしても、そのポジションが自EAの対象とは限りません。取得後にPOSITION_MAGICとPOSITION_SYMBOLを確認し、対象外であれば処理しないようにします。
void PrintCurrentPosition(string symbol)
{
if(!PositionSelect(symbol))
{
PrintFormat("POSITION_NONE symbol=%s", symbol);
return;
}
ulong ticket = (ulong)PositionGetInteger(POSITION_TICKET);
long magic = PositionGetInteger(POSITION_MAGIC);
long type = PositionGetInteger(POSITION_TYPE);
double volume = PositionGetDouble(POSITION_VOLUME);
double profit = PositionGetDouble(POSITION_PROFIT);
PrintFormat("POSITION_FOUND symbol=%s ticket=%I64u magic=%d type=%d volume=%.2f profit=%.2f",
symbol,
ticket,
magic,
type,
volume,
profit);
}この例では、指定銘柄のポジションを選択し、チケット、Magic Number、方向、ロット、損益をログに出しています。実際のEAでは、このポジションが自EAの対象かどうかをMagic Numberで確認してください。
Magic Numberで自EAの対象だけを抽出する
Magic Numberは、EAごとの注文やポジションを識別するために使います。複数EA、複数チャート、手動ポジションが混在する場合、Magic Numberを確認しないと、他EAのポジションを数えたり、決済したりする可能性があります。
EAで最大ポジション数を確認する場合、PositionsTotalだけを見るのではなく、対象銘柄とMagic Numberに一致するポジションだけを数える必要があります。PositionsTotalは口座全体のポジション数として扱われるため、自EAの保有数とは一致しないことがあります。
int CountMyPositions(string symbol, ulong magic)
{
int count = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(ticket == 0)
continue;
if(!PositionSelectByTicket(ticket))
continue;
string pos_symbol = PositionGetString(POSITION_SYMBOL);
long pos_magic = PositionGetInteger(POSITION_MAGIC);
if(pos_symbol == symbol && (ulong)pos_magic == magic)
count++;
}
PrintFormat("POSITION_SCOPE symbol=%s magic=%I64u count=%d",
symbol,
magic,
count);
return count;
}このように、ポジション数を確認する時は、対象範囲をログに残すと安全です。特に、複数EA、コピーEA、半裁量EA、裁量補助パネルでは、対象外ポジションを誤って扱わないことが重要です。
Dealとは何か
Dealは、実際に約定した記録です。注文を送っただけではDealが発生しない場合があります。成行注文が約定した時、指値注文が約定した時、決済が成立した時などにDealとして履歴に残ります。
EAの履歴確認では、Dealの方向、約定価格、ロット、損益、手数料、スワップ、Magic Number、コメントなどを確認します。注文が成功したかどうかだけでなく、どの価格で約定し、どの履歴として残ったかを見ることが重要です。
決済後にポジションが消えていても、Deal履歴を確認しなければ、どの価格で決済されたのか、手数料やスワップを含めた損益がどうだったのか、EAによる決済なのか手動決済なのかを追いにくくなります。
| 確認項目 | 内容 | 使いどころ |
|---|---|---|
| DEAL_TICKET | Dealのチケット番号。 | 約定履歴の識別に使います。 |
| DEAL_ORDER | 関連する注文番号。 | 注文と約定の対応確認に使います。 |
| DEAL_POSITION_ID | 関連するポジションID。 | ポジション単位の追跡に使います。 |
| DEAL_SYMBOL | 対象銘柄。 | 複数銘柄の履歴確認に使います。 |
| DEAL_MAGIC | Magic Number。 | 自EAの約定だけを抽出します。 |
| DEAL_TYPE | BUY / SELLなどの約定種別。 | エントリー・決済の方向確認に使います。 |
| DEAL_ENTRY | エントリーか決済かなどの区分。 | IN / OUT / INOUTの確認に使います。 |
| DEAL_VOLUME | 約定ロット。 | 部分決済や分割約定の確認に使います。 |
| DEAL_PRICE | 約定価格。 | 想定価格との差を確認する時に使います。 |
| DEAL_PROFIT | 約定損益。 | 決済結果の確認に使います。 |
HistorySelectで履歴を確認する
HistorySelectは、指定した期間の履歴を選択するために使います。過去の注文や約定を確認するには、まずHistorySelectで期間を指定し、その後、HistoryOrdersTotalやHistoryDealsTotalで件数を確認します。
履歴確認では、期間指定が重要です。期間が狭すぎると対象履歴が取れず、広すぎると不要な履歴まで含まれて確認しにくくなります。バックテストや不具合調査では、発生時刻の前後を含めて期間指定するのが基本です。
また、HistorySelectで履歴を選択した後は、注文履歴と約定履歴を分けて確認します。注文履歴はHistoryOrderGet系、約定履歴はHistoryDealGet系で確認します。OrderとDealを混同すると、注文は存在するが約定していない状態や、約定は存在するが現在ポジションはない状態を誤って判断することがあります。
void PrintRecentDeals(datetime from_time, datetime to_time, ulong magic)
{
if(!HistorySelect(from_time, to_time))
{
PrintFormat("HISTORY_SELECT_FAIL from=%s to=%s last_error=%d",
TimeToString(from_time),
TimeToString(to_time),
GetLastError());
return;
}
int total = HistoryDealsTotal();
PrintFormat("HISTORY_DEALS total=%d from=%s to=%s",
total,
TimeToString(from_time),
TimeToString(to_time));
for(int i = 0; i < total; i++)
{
ulong deal_ticket = HistoryDealGetTicket(i);
if(deal_ticket == 0)
continue;
long deal_magic = HistoryDealGetInteger(deal_ticket, DEAL_MAGIC);
if((ulong)deal_magic != magic)
continue;
string symbol = HistoryDealGetString(deal_ticket, DEAL_SYMBOL);
double volume = HistoryDealGetDouble(deal_ticket, DEAL_VOLUME);
double profit = HistoryDealGetDouble(deal_ticket, DEAL_PROFIT);
long type = HistoryDealGetInteger(deal_ticket, DEAL_TYPE);
PrintFormat("DEAL_FOUND ticket=%I64u symbol=%s magic=%I64d type=%d volume=%.2f profit=%.2f",
deal_ticket,
symbol,
deal_magic,
type,
volume,
profit);
}
}この例では、指定期間のDeal履歴から、Magic Numberが一致する約定だけをログに出しています。実務では、銘柄、position id、deal entry、deal reason、手数料、スワップなども必要に応じて確認します。
HistoryOrdersとHistoryDealsを分けて見る
履歴確認では、HistoryOrdersとHistoryDealsを分けて見ます。注文履歴は、過去に出された注文の情報を確認するために使います。約定履歴は、実際に成立した売買の情報を確認するために使います。
たとえば、指値注文を出したが約定せずにキャンセルされた場合、注文履歴には残ってもDealとしては残らないことがあります。逆に、成行注文が約定した場合は、OrderとDealの両方を追う必要があります。
| 履歴種別 | 主な確認関数 | 見る内容 |
|---|---|---|
| 注文履歴 | HistoryOrdersTotal、HistoryOrderGetTicket、HistoryOrderGetInteger、HistoryOrderGetDouble、HistoryOrderGetString。 | 過去注文、注文種別、注文状態、価格、ロット、Magic Number。 |
| 約定履歴 | HistoryDealsTotal、HistoryDealGetTicket、HistoryDealGetInteger、HistoryDealGetDouble、HistoryDealGetString。 | 約定、約定価格、約定ロット、損益、手数料、スワップ、Magic Number。 |
| 現在ポジション | PositionsTotal、PositionGetTicket、PositionSelectByTicket、PositionGetInteger。 | 現在保有中のポジション、ロット、建値、SL/TP、損益。 |
| 取引イベント | OnTradeTransaction。 | 注文追加、約定、履歴追加、ポジション変化など。 |
order ticket・deal ticket・position ticket・position id の違い
MQL5では、order ticket、deal ticket、position ticket、position id を混同しないことが重要です。注文番号、約定番号、ポジションの識別番号、ポジション単位のIDは役割が異なります。ログでこれらを分けて残しておくと、注文後の追跡がしやすくなります。
不具合調査では、「注文番号はあるがDealがない」「Dealはあるが現在Positionがない」「PositionはないがHistoryには残っている」といった状態を分けて確認します。ログにorder、deal、positionを同じ名前で出してしまうと、後から混乱しやすくなります。
| 項目 | 意味 | 使いどころ |
|---|---|---|
| order ticket | 注文の識別番号です。 | 注文要求や未約定注文を追う時に使います。 |
| deal ticket | 約定の識別番号です。 | 実際の売買成立記録を追う時に使います。 |
| position ticket | 現在ポジションの識別番号です。 | 決済や変更対象を指定する時に使います。 |
| position id | ポジション単位で履歴を追うための識別情報です。 | 注文・約定・ポジションの関連確認に使います。 |
| Magic Number | EA識別用の番号です。 | 自EA対象の注文・約定・ポジションを抽出します。 |
OnTradeTransactionで取引イベントを追う
OnTradeTransactionは、注文、約定、ポジション変化などの取引イベントを受け取るためのイベント関数です。注文処理後に何が起きたかをリアルタイムに追いたい場合に役立ちます。
OrderSendやCTradeの結果ログだけでは、注文後のイベントを十分に追えないことがあります。OnTradeTransactionを使うと、注文追加、約定、履歴追加、ポジション変化などのイベントをログ化できます。
ただし、OnTradeTransactionのログは多くなりやすいため、常時すべてを詳細出力するとExpertsログが読みにくくなります。開発時、検証時、異常時でログ粒度を切り替える設計が現実的です。
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
PrintFormat("TRADE_TRANSACTION type=%d order=%I64u deal=%I64u position=%I64u symbol=%s retcode=%d",
trans.type,
trans.order,
trans.deal,
trans.position,
trans.symbol,
result.retcode);
}OnTradeTransactionを使う場合は、trans.type、trans.order、trans.deal、trans.position、trans.symbol、result.retcodeを確認します。必要に応じて、注文追加、約定追加、履歴追加などのイベント種別ごとにログを分けてください。
Hedging口座とNetting口座の違いに注意する
MT5では、口座タイプによってポジションの扱いが異なる場合があります。Hedging口座では同一銘柄に複数ポジションを持てることがあり、Netting口座では同一銘柄のポジションが集約されることがあります。
EAでポジション管理を行う場合、口座タイプの違いを考慮しないと、ポジション数、決済対象、反対売買、履歴確認で想定と違う動きになることがあります。複数ポジションや部分決済を扱うEAでは、特に注意してください。
開発依頼や検証時には、対象口座がHedgingなのかNettingなのかを確認しておくと、仕様の食い違いを減らせます。特に、ナンピン、グリッド、分割決済、両建て、コピーEAでは、口座タイプの違いが重要になります。
| 口座タイプ | 特徴 | EA側の注意点 |
|---|---|---|
| Hedging | 同一銘柄で複数ポジションを持てる場合があります。 | チケット単位、Magic Number単位で管理します。 |
| Netting | 同一銘柄のポジションが集約される場合があります。 | 反対売買やポジション更新の扱いを確認します。 |
| 複数EA運用 | 同じ銘柄で複数EAが動く場合があります。 | Magic Numberと対象銘柄で範囲を絞ります。 |
| 手動ポジション混在 | EA外で建てたポジションが混ざる場合があります。 | EA対象外ポジションを誤決済しないようにします。 |
| コピーEA | コピー元・コピー先で口座タイプが異なる場合があります。 | チケット対応、ロット同期、決済同期の仕様を明確にします。 |
決済後に履歴を確認する
EAで決済処理を行った後は、現在ポジションがなくなったかを見るだけでなく、履歴にどのように残ったかを確認します。決済Deal、損益、手数料、スワップ、決済理由、コメント、Magic Numberを確認すると、後から検証しやすくなります。
特に、部分決済、トレーリング、建値決済、時間決済、一括決済を行うEAでは、決済理由をログと履歴で対応させることが重要です。履歴に残った結果だけでは、EAがどの理由で決済したのか分からない場合があります。
決済後の確認では、決済Dealが発生しているか、Positionが消えているか、Historyに損益が反映されているか、手数料やスワップが想定どおりかを確認します。バックテストレポートとログを照合する時にも、この整理が役立ちます。
| 確認項目 | 内容 | 理由 |
|---|---|---|
| 決済Deal | 決済として発生した約定。 | 決済が成立したか確認します。 |
| 決済理由ログ | TP、SL、トレーリング、時間決済、手動決済など。 | EA内部の決済理由を追うため。 |
| 損益 | DEAL_PROFIT、手数料、スワップ。 | レポートとの照合に使います。 |
| position id | 対象ポジションとの対応。 | エントリーと決済を結び付けるため。 |
| Magic Number | 自EAの履歴かどうか。 | 他EAや手動取引を除外するため。 |
| コメント | 注文・決済コメント。 | 補助的な識別に使います。 |
| 決済後Position | 現在ポジションが残っているか。 | 部分決済か全決済かを確認するため。 |
注文・ポジション・履歴のログ設計
注文・ポジション・履歴管理では、ログ設計が重要です。EAが注文を出したか、約定したか、ポジションを持っているか、決済されたか、履歴に残ったかを追えるようにします。
ログ名を統一しておくと、Expertsログ内で検索しやすくなります。ORDER、DEAL、POSITION、HISTORY、CLOSE、MODIFY、TRANSACTIONなど、処理の種類ごとに接頭辞を分けると原因追跡がしやすくなります。
また、通常運用ではログを出しすぎないようにし、検証時や不具合発生時に詳細ログをONにできる構成にすると扱いやすくなります。取引履歴の追跡では、order ticket、deal ticket、position id、Magic Numberを同じログ行に含めると照合しやすくなります。
| ログ名 | 残す内容 | 目的 |
|---|---|---|
ORDER_SEND | 注文方向、ロット、価格、retcode、order、deal。 | 注文送信結果を確認します。 |
CTRADE_BUY | CTradeのBuy結果、ResultRetcode、order、deal。 | CTrade利用時の発注結果を確認します。 |
CTRADE_CLOSE | 決済対象チケット、ResultRetcode、deal。 | 決済処理の結果を確認します。 |
POSITION_FOUND | ticket、symbol、magic、type、volume、profit。 | 現在ポジションを確認します。 |
POSITION_SCOPE | 対象銘柄、Magic Number、保有数。 | 自EA対象範囲を確認します。 |
DEAL_FOUND | deal ticket、symbol、magic、volume、profit。 | 約定履歴を確認します。 |
HISTORY_SELECT | 検索期間、件数、失敗時のGetLastError。 | 履歴取得範囲を確認します。 |
TRADE_TRANSACTION | 注文・約定イベントの種類、order、deal、position。 | 取引イベントを追跡します。 |
バックテストで履歴管理を確認する
バックテストでは、最終損益だけでなく、注文履歴、約定履歴、ポジション管理、決済理由を確認します。EAが想定どおりに注文しているか、決済しているか、Magic Numberの対象範囲が正しいかを確認してください。
バックテストで履歴を確認する時は、銘柄、時間足、期間、スプレッド、モデル、初期証拠金、setファイル、Expertsログ、Testerログを保存します。注文・決済履歴だけを見ても、EA内部の見送り理由や決済理由が分からない場合があるため、ログもセットで確認します。
バックテスト結果は将来の結果を保証するものではありません。ここでは、EAの注文・決済・履歴管理が想定どおりに動いているか、再現条件を整理できるか、ログで原因を追えるかを確認する材料として扱います。
- EA名とバージョンを記録する
- 使用したsetファイルを保存する
- 銘柄、時間足、期間、スプレッドを記録する
- 注文履歴と約定履歴を確認する
- 現在ポジションと決済履歴を分けて確認する
- 決済理由をExpertsログで確認する
- Magic Numberで自EAの履歴だけを抽出できるか確認する
- Position、Deal、Historyの対応を確認する
- order ticket、deal ticket、position idをログに残す
- バックテスト結果を将来成績保証として扱わない
よくある不具合と確認ポイント
注文・ポジション・履歴管理では、EAが注文しない、決済されない、履歴が取得できない、Magic Numberで絞れない、バックテストと通常チャートで結果が違う、といった問題が起きることがあります。
このような時は、注文処理だけを疑うのではなく、発注前チェック、OrderSend / CTrade結果、現在ポジション、履歴取得期間、Magic Number、口座タイプ、ログ粒度を順番に確認します。
| 症状 | 確認する場所 | 主な原因候補 |
|---|---|---|
| 注文したはずなのにポジションがない | OrderSend / CTradeログ、retcode、Deal履歴。 | 注文失敗、約定していない、即時決済、履歴確認漏れ。 |
| DealはあるがPositionがない | HistoryDeals、現在ポジション。 | 決済済み、Netting口座で相殺、短時間でクローズ。 |
| Positionはあるが自EAのものではない | POSITION_MAGIC、POSITION_SYMBOL。 | 他EA、手動ポジション、Magic Number未設定。 |
| 履歴が取得できない | HistorySelectの期間、GetLastError。 | 期間指定ミス、サーバー時間のずれ、履歴未選択。 |
| 決済対象を間違える | ticket、symbol、magic、type。 | 対象範囲の絞り込み不足。 |
| バックテストと通常チャートで違う | set、スプレッド、口座タイプ、ログ。 | 検証条件差、約定条件差、外部環境差。 |
| OnTradeTransactionログが多すぎる | ログ粒度、イベント種別。 | すべての取引イベントを常時出力している。 |
開発依頼前に整理する情報
注文・ポジション・履歴管理の不具合を相談する場合は、対象EA、setファイル、注文履歴、Expertsログ、Journalログ、バックテスト条件、発生時刻を整理してください。単に「決済されない」「履歴が取れない」だけでは、原因を確認しにくくなります。
特に、注文後の追跡では、order ticket、deal ticket、position id、Magic Number、決済理由、発生時刻が重要です。履歴確認のためには、HistorySelectで指定すべき期間も分かるようにしておく必要があります。
| 整理する情報 | 内容 | 理由 |
|---|---|---|
| EA名・バージョン | 対象ファイル名、更新日、バージョン。 | 確認対象を特定するため。 |
| setファイル | input設定一式。 | 同じ条件を再現するため。 |
| 注文履歴 | 注文番号、約定番号、ポジションID。 | Order・Deal・Positionを照合するため。 |
| Expertsログ | EA内部の注文・決済・履歴ログ。 | EA側の判断を確認するため。 |
| Journalログ | MT5側の取引・環境ログ。 | プラットフォーム側の状態を確認するため。 |
| バックテスト条件 | 銘柄、時間足、期間、スプレッド、モデル。 | 検証条件を再現するため。 |
| 発生時刻 | 問題が起きたサーバー時間・ローカル時間。 | 履歴検索期間を指定するため。 |
| 口座タイプ | HedgingまたはNetting。 | ポジション管理仕様に影響するため。 |
| 送らない情報 | 口座番号、パスワード、APIキー、Webhook URL。 | 機密情報を保護するため。 |
注文・ポジション・履歴管理の実務チェック表
- Order、Deal、Position、Historyの違いを確認した
- OrderSend後にretcode、order、deal、commentを確認している
- CTrade利用時にResultRetcodeを確認している
- PositionSelectまたはPositionSelectByTicketで対象を確認している
- Magic Numberで自EAの対象だけを抽出している
- PositionsTotalだけで保有数を判断していない
- HistorySelectの期間指定を確認している
- HistoryOrderGet系とHistoryDealGet系を分けて確認している
- HistoryDealGetTicketでDeal履歴を確認している
- order ticket、deal ticket、position ticket、position idを混同していない
- OnTradeTransactionで取引イベントを必要に応じて追跡している
- Hedging口座とNetting口座の違いを考慮している
- 決済理由をログと履歴で照合できる
- バックテスト条件とsetファイルを保存している
- 口座情報や認証情報をログへ出していない
よくある質問
MQL5のOrderとPositionは何が違いますか?
Orderは注文を表し、Positionは現在保有している建玉を表します。注文が送られても、必ず現在ポジションになるとは限りません。注文、約定、ポジション、履歴を分けて確認してください。
Dealとは何ですか?
Dealは実際に約定した記録です。注文が成立した時や決済が成立した時にDealとして履歴に残ります。約定価格、ロット、損益、Magic Numberなどを確認できます。
PositionSelectだけでポジション管理できますか?
単一銘柄・単一ポジション前提なら確認できる場合があります。ただし、複数ポジションやHedging口座では、PositionSelectByTicketやMagic Numberによる絞り込みが重要です。
HistorySelectで履歴が取れない時は何を確認しますか?
指定期間、サーバー時間、履歴の種類、HistorySelectの戻り値、GetLastErrorを確認してください。期間が狭すぎると対象履歴が含まれないことがあります。
Magic Numberは履歴確認にも必要ですか?
必要です。複数EAや手動ポジションが混在する場合、Magic Numberを見ないと自EAの注文・約定・ポジションだけを抽出できません。履歴確認でもMagic Numberを使って対象を絞ると安全です。
OnTradeTransactionは必ず使うべきですか?
必須ではありませんが、注文・約定・ポジション変化をリアルタイムに追いたい場合に役立ちます。ログが多くなりやすいため、開発時・検証時・異常時で粒度を分けるとよいです。
Hedging口座とNetting口座でEAの作り方は変わりますか?
変わる場合があります。Hedging口座では同一銘柄に複数ポジションを持てることがあり、Netting口座では同一銘柄のポジションが集約される場合があります。複数ポジション、分割決済、両建て、コピーEAでは特に注意が必要です。
関連ページ
注文・ポジション・履歴管理を整理する時は、CTrade、OrderSend、OrderCheck、ロット・証拠金、ログ確認、EA設計、バックテストをあわせて確認すると、EAの注文後追跡がしやすくなります。
| 確認したい内容 | 関連ページ |
|---|---|
| CTradeを使った注文・決済を確認する | MQL5標準ライブラリ・CTrade完全ガイド |
| OrderSendや取引構造体を確認する | MQL5注文関数・取引構造体辞典 |
| ロット・証拠金・銘柄仕様を確認する | MQL5ロット・証拠金・銘柄仕様完全ガイド |
| EA設計の責務分離を確認する | MQL5 EA設計パターン完全ガイド |
| ログ確認とデバッグを確認する | MQL5デバッグ・ログファースト開発完全ガイド |
| EA自作前の確認をする | 自動売買EAを自作する前に確認すること |
| MQL5開発環境を確認する | MQL5開発入門 |
| バックテストと最適化を確認する | MT5ストラテジーテスター・最適化完全ガイド |
| イベント処理を確認する | MQL5イベント処理完全ガイド |
| setファイル送付前の確認をする | MT5でEAのsetファイルを送る前に確認すること |
| EAログを問い合わせ前に確認する | EAのログを問い合わせ前に確認する方法 |
| 取引履歴の基本用語を確認する | EAの取引履歴とは |
| 不具合報告・サポート依頼の入口を確認する | 不具合報告・サポート依頼 |
| 開発・改修相談の入口を確認する | 開発・改修の相談ページ |
まとめ
MQL5でEAの注文処理を作る時は、Order、Deal、Position、Historyを分けて理解することが重要です。注文を送ったこと、約定したこと、現在ポジションがあること、履歴に残ったことは、それぞれ確認する場所が異なります。
OrderSendやCTradeを使った後は、retcode、order ticket、deal ticket、position ticket、position id、Magic Number、commentをログに残してください。PositionSelectやHistorySelectを使う時も、対象銘柄、Magic Number、期間指定を確認することで、自EAの注文・約定・ポジションだけを抽出しやすくなります。
バックテストや不具合調査では、注文履歴だけでなく、Expertsログ、Journalログ、setファイル、検証条件、決済理由をあわせて確認してください。注文・約定・ポジション・履歴を分けて追跡できるようにしておくと、EA開発や改修時の原因確認が進めやすくなります。
