【移植#87】最適化パスごとにSL・TP決済を数える — コメントではなく決済理由を見る¶

この記事の3行まとめ
- MT5の決済履歴には、SL・TPなどの実行理由を示す
DEAL_REASONがあります - 各最適化パスの決済ディールだけを理由別に数え、実pass IDと入力値をCSVに残します
- 専用MT5の9パスで、履歴集計と取引通知、CSVとテスターレポートの対応を確かめました
勝率の次に「何で閉じたか」を見る¶
前回の移植#86は、現在のBid・Askから離れた水平線を表示しました。今回の元記事は2010年4月26日の「Optimization 時の各PASSテストでのS/L回数を知る。」です。
元記事「Optimization 時の各PASSテストでのS/L回数を知る。」を読む
元記事は、最適化の各パスでストップロス(S/L)が何回起きたかを知るため、MT4の注文コメントに含まれる[sl]や[tp]を探していました。これは移植#73の「各パスの勝率」を補う問いです。同じ勝率でも、SL、TP、EAの判断による決済がどれだけあるかで戦略の動きは変わります。
MT5では注文コメントの文字列から推測せず、決済ディールのDEAL_REASONを読みます。この記事で数える単位はポジション数でも注文数でもなく、決済ディール数です。部分決済があれば1ポジションが複数の決済ディールになるため、この違いを残します。
集計対象を絞ってから理由を分ける¶
各パスの終了時にOnTester()からHistorySelect()で履歴を取得します。銘柄とEAのマジック番号を確認し、売買ディールのうちDEAL_ENTRY_OUT、OUT_BY、INOUTだけを対象にします。入場ディールや残高調整は数えません。
| 分類 | MT5の理由 | このCSVでの意味 |
|---|---|---|
| SL | DEAL_REASON_SL | ストップロス発動 |
| TP | DEAL_REASON_TP | テイクプロフィット発動 |
| EA | DEAL_REASON_EXPERT | EAの取引要求による決済 |
| その他 | 上記以外 | ストップアウトなど、勝手にEA決済へまとめない理由 |
したがって各行で次の式が成立する必要があります。
たとえばpass 0は、3,333 = 2,232 + 1,093 + 8 + 0です。テスターの総取引数は3,334でしたが、こちらは決済理由を持つディールだけの件数ではありません。今回の9パスは各行で総取引数が決済ディール数を1件上回りました。両方を同じ名前の「取引回数」として扱わないことが大切です。
理由と損益は別の軸
SL決済だから必ず同じ損失額、TP決済だから必ず同じ利益額になるわけではありません。スプレッド、滑り、手数料なども損益に関係します。理由別件数だけで戦略の良し悪しを決めないでください。
パスを取り違えずCSVへ集める¶
移植#73と同じく、各テストエージェントのOnTester()から最適化フレームを送ります。端末側のOnTesterPass()とOnTesterDeinit()でフレームを読み、最後に届く結果も回収します。
CSVに記録するpass IDは行番号から作らず、FrameNext()が返す値です。FrameInputs()の高速・低速EMA期間と、フレームに含めた期間も照合します。今回の到着順は0, 4, 1, 5, 2, 6, 3, 7, 8でした。行番号をpass IDとみなすと、2行目から対応が崩れます。
配布EAはテスター専用です。EMA期間を変える9条件の測定用売買を行い、各ポジションに80 pointsのSLと120 pointsのTPを置きます。最大12本保有した場合はEAが閉じます。通常チャートでは初期化を拒否し、ライブ口座で動かす用途ではありません。
専用MT5で9パスを検証¶
MT5 Build 6182、EURUSD H1、2025年1月1日〜12月31日、Open prices onlyで、EMAの高速期間8/10/12と低速期間24/28/32を3×3の完全最適化にしました。配布EAと表示用EAはどちらも0エラー・0警告でコンパイルしています。
| 到着順 | pass ID | Fast | Slow | 決済 | SL | TP | EA |
|---|---|---|---|---|---|---|---|
| 1 | 0 | 8 | 24 | 3,333 | 2,232 | 1,093 | 8 |
| 2 | 4 | 10 | 28 | 3,356 | 2,253 | 1,095 | 8 |
| 3 | 1 | 10 | 24 | 3,333 | 2,235 | 1,090 | 8 |
| 4 | 5 | 12 | 28 | 3,358 | 2,248 | 1,102 | 8 |
| 5 | 2 | 12 | 24 | 3,341 | 2,239 | 1,094 | 8 |
| 6 | 6 | 8 | 32 | 3,352 | 2,250 | 1,094 | 8 |
| 7 | 3 | 8 | 28 | 3,338 | 2,239 | 1,091 | 8 |
| 8 | 7 | 10 | 32 | 3,352 | 2,240 | 1,104 | 8 |
| 9 | 8 | 12 | 32 | 3,347 | 2,232 | 1,107 | 8 |
9パス合計は決済30,110件、そのうちSL 20,168件、TP 9,870件、EA決済72件、その他0件でした。各パスの履歴を最後に走査した件数は、売買発生時のOnTradeTransaction()で積み上げた件数と一致しました。さらに別の表示用EAがCSVを読み直し、9個の実pass ID、9組の入力値、各行の件数式を検査したうえで冒頭の画面を撮影しています。
CSVと最適化レポートのpass ID、入力値、総取引数、Custom値も9件すべて一致しました。検証時に既存の最適化キャッシュを対象EA分だけ整理し、変更後のEAで計算しています。画像を撮る通常チャートでは注文数・ポジション数は変わっていません。
使い方¶
87_Optimization_Exit_Reasons_v1_00.mq5 をダウンロード
- MT5のデータフォルダにある
MQL5/Expertsへ保存し、MetaEditorでコンパイルします。 - ストラテジーテスターでEURUSD H1を選び、最適化を有効にします。
- 高速EMA期間を
8, 10, 12、低速EMA期間を24, 28, 32に設定すると、記事と同じ9組を検査できます。 - 終了後、端末のFilesフォルダに出力したCSVで、各pass IDのSL・TP・EA決済数を確認します。
| 入力 | 既定値 | 役割 |
|---|---|---|
InpFastPeriod / InpSlowPeriod | 8 / 24 | サンプル売買のEMA期間 |
InpHoldBars | 12 | EAが決済するまでの最大保有本数 |
InpStopPoints / InpTakePoints | 80 / 120 | SL・TPの距離。単位はpoints |
InpLots | 0.10 | サンプル注文量 |
InpMagic | 870022 | 履歴の対象を絞る識別子 |
InpCsvFile | 87_Optimization_Exit_Reasons.csv | 出力CSVのファイル名 |
自分のEAへ組み込む場合は、売買ロジックを移す必要はありません。決済ディールの抽出、DEAL_REASON別の集計、フレームでのpass ID対応付けが中心です。OnTester()の戻り値は、このサンプルでは#73と同じ勝率にしています。SL回数の少なさだけを最適化基準にする設計ではありません。
集計の限界¶
このCSVは決済理由別のディール件数を示します。ポジション単位の勝敗数、部分決済をまとめた回数、取引条件を変えた場合の将来成績を表しません。また、ここではテスターのOpen prices onlyを使った再現可能な教材として検証しました。実ティックや別銘柄ではSL・TPの発動件数が変わり得ます。
まずは自分の戦略で「何を1回と数えるか」を決め、勝率・損益・DDと並べて理由の内訳を見てください。
あわせて読みたい記事¶
次: 【移植#88】前週最後のバーは何本前? — 日曜0時と実在する足で探す