EA解析の実務
市販EAの中身は、どこまで測れるのか
.ex5 は逆コンパイルできません。それでも、発注ロジックを数式として取り出すことはできます。
実際に使っている10手順を、用語解説つきで公開します。
はじめに — 何ができて、何ができないのか
3行でいうと:
① EAは注文という形で必ず痕跡を残すので、それを数千件集めれば計算式を逆算できる。
② ただし「当たった」の大半は偶然なので、偶然かどうかを判定する手続きが要る。
③ 再現できても売り物になるとは限らないので、最後に別の基準で落とす。
最初に、期待の水準を合わせておきます。
できないこと:EA本体(.ex5)を逆コンパイルしてソースを見ること。
これは技術的にも規約的にも、やりません。
できること:そのEAが「何をしたか」を全件観測し、そこから規則を復元すること。 EAはチャート上で必ず注文を出します。注文には時刻・価格・方向・損切り幅・ 決済理由が残ります。それを数千件ぶん集めれば、 「この価格はどう計算されたのか」を逆算できます。
たとえば、こういうことが分かります。ある金EAの発注水準は 「直近N時間の高値そのもの」でした。オフセット(ずらし幅)は ちょうど 0.000。Nは単一ではなく 1/3/5/6/8/15/30時間の集合。 検証期間での一致率は 74.2% です。
ソースコードは一行も見ていません。注文表だけから出しています。
ただし、解けないこともあります。本記事の手順で解析した対象のうち、 3本は「再現不能」または「製品化に値しない」と結論して打ち切りました。 その判定も含めて、以下が実際の手順です。
目次(本文 約20分)
- ① そもそも解く価値があるか確かめる
- ② 本家を自分のテスターで走らせ、生の記録を取る
- ③ 照合用の価格データを、自分で書き出す
- ④ 「動かない数字」を探す — 指紋になる
- ⑤ 水準の候補式を、総当たりで当てはめる
- ⑥ 帰無検定 — 「それ、偶然じゃないの?」に答える
- ⑦ 頭打ちになったら、残差の中央値を見る
- ⑧ 発注ゲートを探す — 「どこに置くか」より難しい「いつ置くか」
- ⑨ 出口を測る — 決済がどう動いたか
- ⑩ クローンを組んで、注文を1件ずつ突合する
- そして、判定する(採用基準6項目・打ち切った3件)
- この手法の限界
- 使っているもの、全部
- この一式を、そのままお渡しします
用語(先に読んでおくと迷いません)
以降で使う言葉です。初めての方はここだけ流し読みしてから本文へ進んでください。
初めての方は、ここを開いてから本文へ進んでください。本文中の用語は、クリックするとこの一覧の該当項目が開きます。
1. まずこれだけ — EAとMT5
- EA(エキスパートアドバイザ)
- MT4/MT5で動く自動売買プログラム。市販品はコンパイル済みで配布され、中身は読めません。
本記事が対象にするのはMT5用(
.ex5)だけです(理由は末尾)。 - バックテスト / ストラテジーテスター
- 過去の価格データでEAを走らせ、成績を出すMT5の機能。本記事の観測データは、ほぼすべてここから出ます。
- レポート(注文表・約定表)
- テスター結果のHTMLファイル。2つの表があります。 注文表=EAが「置こうとした」もの全部(約定しなかったものも含む)。 約定表=実際に成立したもの。この違いが後で決定的になります。
- ティック
- 価格が動いた瞬間ごとの記録。1件が
時刻・Bid・Ask。ローソク足よりはるかに細かい生データです。 - M1バー
- 1分足。1分間の始値・高値・安値・終値。
- 保留注文(指値・逆指値)
- 「この価格まで来たら買う」とあらかじめ置いておく注文。置いた位置そのものが、EAの計算結果です。
- ロット
- 取引量の単位。1ロット=10万通貨が標準。0.01ロットが最小のことが多いです。
- 建値(たてね)
- ポジションを持った価格。「建値まで戻す」=損益ゼロの位置にSLを動かすこと。
- スプレッド
- 買値と売値の差。取引ごとに必ず取られるコスト。
2. 解析で使う言葉
- 水準(レベル)
- EAが注文を置いた価格のこと。本記事の主役です。これを説明する数式を見つけるのが「同定」です。
- 同定
- 観測から規則を特定すること。「たぶんこうだろう」ではなく、一致率という数字で示せる状態を指します。
- スイング / ピボット
- チャートの高値・安値の折り返し点。多くのEAが「直近の折り返し点」を基準に注文を置きます。
- オフセット
- 基準点からどれだけずらして注文を置くかの幅。
- 一致率
- 「候補の数式で計算した価格」と「実際に置かれた価格」が許容誤差内で一致した割合。
- 許容誤差
- 「一致とみなす」幅。本記事では価格の0.02%を使っています (金が3,000ドルなら0.60ドル)。この幅を甘くすれば一致率はいくらでも上がるので、 必ず明示すべき数字です(⑤で検証しています)。
- SL / TP
- 損切り(Stop Loss)/利確(Take Profit)。SLが常に同じ値なら、それは固定値であり強い手がかりになります。
- 変動係数(CV)
- ばらつきの度合い。CVがゼロ=毎回まったく同じ値=ハードコードされた定数、と読めます。
- 発注ゲート
- 「いつ注文を出すか」の条件。水準(どこに置くか)とは別問題で、たいていこちらのほうが難物です。
- クローン
- 同定した規則で組み直したEA。本家のコードは使いません。ゼロから書きます。
3. 数字の読み方 — ここが本記事の核心です
聞き慣れない言葉が並びますが、 やっていることは「その数字、偶然じゃないの?」の一点だけです。
- 学習期間 / 検証期間(holdout)
- 数式を探すのに使った期間と、探索に一切使わずに取っておいた期間。 検証期間でも当たって初めて「解けた」と言えます。
- 帰無検定(きむけんてい)
- 「その一致は偶然でも出るのか」を確かめる手続き。 わざと成立しないはずの条件で同じ計算をやり直し、そこでも高い数字が出るなら、 元の数字は実力ではなかったと判断します(⑥)。
- パーセンタイル(p10・p50・p90 など)
- 小さい順に並べて何%目か。p50=中央値。 p5とp95が同じ値なら、それは「ばらついていない=固定値」という意味になります。
- 変動係数がゼロ / p5=p95
- どちらも「毎回まったく同じ値」を指す言い方です。定数を見つけたサインです。
- 効果量 d
- 2つのグループがどれくらい離れているかの目安。 0.2で小、0.5で中、0.8で大。0.1未満は実質「差が無い」と考えます。
- p値
- 「偶然でもこれくらい出る確率」。小さいほど偶然では説明しにくい。 ただしデータが少ないと当てになりません(⑥に実例)。
- 再現率 / 適合率
- クローンが本家の注文をどれだけ拾えたか(再現率)と、 クローンが出した注文のうち本家にもあった割合(適合率)。 片方だけでは評価できません(全部に注文を出せば再現率は100%になるため)。
4. 成績の言葉
- PF(プロフィットファクタ)
- 総利益 ÷ 総損失。1.0で損益ゼロ。
- ドローダウン(DD)
- 資産が最も落ち込んだ幅。MT5の「残高DD%」は分母がその時点の残高なので、 資金が増えた後の落ち込みは小さく見えます。元手基準か金額で見てください。
- 損益分岐勝率
- そのEAが損益ゼロになる勝率。 利益が損失の2倍なら33%勝てば足りますが、半分しかないなら67%勝たないと負けます。 勝率だけを見ても意味が無いのはこのためです。
- 勝率の余裕(マージン)
- 実測の勝率 − 損益分岐勝率。これが薄いEAは、コストが少し悪化しただけで崩れます。 単位の「pt」はパーセントの差を指します。
- スプレッド耐性
- 1取引あたりの期待値 ÷ 典型スプレッド。1.0倍なら、スプレッドがその分広がった時点で利益が消えます。
手順①〜⑩
順番には意味があります。後半ほどコストが高いので、 早い段階で打ち切れるように並べてあります。
そもそも解く価値があるか確かめる
要するに:再現に成功しても取引数が足りなければ売り物になりません。 本家の成績を先に測り、割に合わなければ始めません。
いきなり解析を始めません。本家自身の成績を先に測ります。
ある対象は、5年間で882取引しかしていませんでした。 当方の採用基準は「5年で1,500取引以上」です。 どれだけ完璧に再現しても、基準を満たしようがない。 この時点で打ち切りました。
これは実際に順序を間違えて学んだことです。 以前は「再現できるか」を先に何時間もやり、あとから「そもそも取引数が足りない」と気づきました。 今は必ず①を先にやります。
使う道具:summary.py(レポートから純益・取引数・勝率・DDを抽出)/
report_profile.py(採用基準6項目に照らす)/yearly.py(年別に分解)
本家を自分のテスターで走らせ、生の記録を取る
要するに:販売ページの成績は使いません。 自分のPCで走らせて、注文を全件取り出します。
販売ページに載っている成績は使いません。自分の環境で走らせた記録だけを使います。 理由は単純で、販売者の掲載成績は期間も設定も選べるからです。
ここで欲しいのは成績ではなく、注文の一件一件です。 ある対象からは 保留注文3,901件・約定1,947件を取り出しました。 これが以降すべての入力になります。
テスターは同じ設定でも結果が完全には一致しません。 実測で PF が ±0.03 程度ぶれます(取引数が半減する条件では ±0.16)。 1回の結果でしきい値を判断してはいけない、というのが実務上の結論です。
使う道具:run_tester.py(設定を書き、MT5がその設定を本当に使ったか検証し、
結果が空なら失敗として報告する)/drain_queue.py(複数条件を順に流す)/
concurrency.py(同時実行数を縛り、PCを固めない)
照合用の価格データを、自分で書き出す
要するに:答え合わせに使う価格データを、 本家EAが見ていたのとまったく同じ場所から自分で吸い出します。
ここがこの手法の土台です。「EAが置いた価格」を説明するには、 その瞬間に市場がどうだったかを、EAと同じ精度で持っていなければなりません。
そこで、MT5から直接データを吸い出す専用ツールを自作しています。
| ツール | 取り出すもの | なぜ要るか |
|---|---|---|
ExportBidAskTicks.mq5 |
ティック(時刻・Bid・Ask)をCSVで全期間 | ローソク足では足りない場面があります。 スプレッドが実際いくらだったか、SLがどこで滑ったかは、Bid/Ask の両方が無いと測れません |
ExportM1Bars.mq5 |
1分足の始値・高値・安値・終値 | 水準式の当てはめは、ほぼこれで行います |
ExportM1EA.mq5 |
同上(EA形式・長期間向け) | スクリプト版が時間切れになる長期の書き出し用 |
ExportEconomicCalendar.mq5 |
経済指標の予定表 | 「指標前は発注しない」というゲートを検証するため |
なぜ既製のヒストリカルデータを使わないのか。 照合相手はテスターの中で動いた本家EAです。本家が見ていたのは、 そのMT5に入っている価格系列そのもの。別のデータで照合すると、 ズレが「EAの規則の違い」なのか「データの違い」なのか区別できなくなります。 だから同じ場所から吸い出します。
使う道具:上記MQL5スクリプト4本/bars.py(Python側の読み込み)/
ProbeSymbolTool.mq5(銘柄の仕様=桁数・最小ロット・ストップレベルを取得)
「動かない数字」を探す — 指紋になる
要するに:数千件を並べて一度も変わらない数字を探します。 それはコードに直接書き込まれた定数です。
数千件の注文を並べて、ばらつきがゼロの値を探します。 毎回まったく同じ値なら、それはコードに直接書かれた定数です。
実例:
| 対象 | 見つかった定数 | 読み取れること |
|---|---|---|
| EA-M | 初期SL 30.00ドル固定 | ボラティリティで変えていない |
| EA-O | 初期SL 1.20ドル固定(p5もp95も1.20)/TP 40.00 | SL 1.20 に対し TP 40.00 で勝率58.8%は、そのままでは成立しません。 決済が全件「SL」だったことと合わせて、利益はSLを引き上げて確定していると分かりました |
| EA-C | SLが建値のちょうど9.0000% | CVが0.0000。戦略ごとに調整した値ではなく、単一の定数 |
この段階で、EAの骨格の半分は見えます。
使う道具:orders_table.py(注文表と約定表を分けて読む)/
exit_mechanism.py(保持時間・決済時刻・決済理由の分布から、隠れた時間決済や日次手仕舞いを検出)/
stopline_fit.py/lot_check.py(ロットが本当に固定か、約定表から数える)
水準の候補式を、総当たりで当てはめる
要するに:「この価格はどう計算されたのか」の候補式を 大量に試し、実際に置かれた価格と一致する式を探します。
ここが解析の中心です。「この価格はどう計算されたのか」を、 候補となる数式を大量に試して探します。
試す家族(ファミリー)はたとえば——
- 直近N時間の高値/安値(Nを変えて総当たり)
- スイングピボット + 当日始値のk%(ずらし幅を「ドル」ではなく「当日始値に対する%」で持つ)
- フィボナッチ比率
- 直近N本の極値
足の選び方で結果が変わりました。ある対象は、 H1(1時間足)のピボットで当てると16.9%で頭打ち。 ところが注文時刻の「秒」を見たら 14:15:28 のように散っていた—— つまりバー確定ではなくティックで動いている。 参照する足をM30まで下げたら 55.2%、M1で時間長を精密化して 57.4% になりました。
「秒を見る」。これだけで解けた案件です。
「一致」の定義を先に固定する
一致率という数字を出す以上、「どこまでを一致とみなすか」を決めておかないと、 その数字は読めません。甘くすれば、いくらでも上がるからです。
本手法では価格の 0.02% を使っています。金が3,000ドルなら0.60ドル、 ドル円150円なら3銭です。
そして、その幅が結果を作っていないことを確かめます。 許容を 0.02% → 0.10%(5倍に緩める)と広げても、 一致率は2.7ポイントしか伸びませんでした。
これは「ギリギリで一致している注文がほとんど無い」ということです。 当たっているものはぴったり当たっており、外れているものは幅を緩めても当たらない。 一致率が許容幅の産物ではない証拠になります。
使う道具:generic_level_fit.py(ピボット+%オフセットの当てはめ)/
fit_by_count.py/fib_fit.py/candidates.py/hypotheses.py(仮説を宣言して管理)/
model_select.py
帰無検定 — 「それ、偶然じゃないの?」に答える
要するに:わざと成立しないはずの条件で、まったく同じ計算をやり直します。 そこでも当たってしまうなら、最初の一致は式の正しさではありませんでした。
この手順が無い一致率には、意味がありません。
候補式を何千通りも試せば、何かは必ず当たります。 だから、当たったあとに必ずこれをやります。
価格データの参照時刻だけを、+45日 / −45日 / +120日 / −120日 ずらして まったく同じ当てはめをやり直す
時計をずらせば、規則との対応関係は壊れます。 それでも一致率が高いままなら、その「一致」は式の正しさではなく、 価格が滑らかであることによる偶然です。
| 対象 | 本来の一致率 | 時計をずらした場合 | 判定 |
|---|---|---|---|
| EA-O | 74.2% | 0.0〜0.5% | 合格 |
| EA-M | 98.7% | 0〜1.4% | 合格 |
| 別の対象 | 72〜81% | 崩れなかった | 不合格・打ち切り |
最後の行が重要です。一致率72〜81%は、数字だけ見れば有望に見えます。 帰無検定を通さなければ、そのまま「解けた」と発表していたはずです。
同じ理由で、件数が少ないときの検定も入れてあります。 ある探索は6件のデータで「5.0倍・p=0.020」という結果を出しましたが、 12件に増やしたら 1.8倍・p=0.208 に崩れました。 最初の結果は少数サンプルのノイズだったわけです。
この検定が保証すること・しないこと
保証すること。時計をずらした系列でも価格の性質(トレンド・ボラティリティ・ 値動きの滑らかさ)は保たれます。にもかかわらず一致率が0%付近まで落ちるなら、 当たっていたのは「価格が滑らかだから」ではなく「時刻と価格の対応が正しいから」です。
保証しないこと。これは「その式が本家の式である」ことまでは示しません。 示せるのは「本家の注文位置を説明する規則性が実在する」ところまでです。 同じ位置を出す別の式があり得ます。だから⑩で注文そのものと突合します。
検定は探索と同じ条件で回します。候補を数千通り試したなら、 帰無のほうも同じ数千通りを同じ手続きで走らせ、同じ件数で比べる。 本命だけ厳しく検定しても意味がありません。
使う道具:各fitスクリプトの --shift-days オプション/
ea_identify.py(候補が何個生き残り、どの制約で死んだかを報告し、
必ず並べ替え検定を添える)
頭打ちになったら、残差の中央値を見る
要するに:当たらない原因は「式が違う」だけではありません。 「答えは1つ」と思い込んでいるせいのことがあります。
単一のパラメータをいくら振っても一致率が上がらない——というとき、 普通は「式が違う」と考えます。が、もう一つ可能性があります。
式は正しく、パラメータが1つではない場合です。
見分け方があります。予測値と実測値の差(残差)の中央値を取る。 ある対象では、6〜24時間のすべての設定で残差の中央値がちょうど 0.000 でした。
これは「水準は極値そのもので、ずらしていない」ことを意味します。 つまり式は合っている。合っていないのは「Nが1つだけ」という前提のほうでした。
| やったこと | 一致率 |
|---|---|
| 単一の窓(15〜16時間) | 57.4% |
| 窓の集合(1/3/5/6/8/15/30時間) | 74.2% |
同じ発見はもう1件でも起きました(63% → 98.7%)。 「頭打ち=残差の中央値を見る」は、いまや定型手順です。
同定が「たまたま」でないことの示し方
その98.7%の案件は、1つの数字ではなく12個の数字で示せました。 このEAは戦略が6つ、それぞれ買いと売りがあり、合計12の系統がそれぞれ独立した注文列を持っていたからです。 同じ形の式が、12すべてに当たりました。
| 系統 | 検証期間の一致率 | 件数 | 時計をずらした場合 |
|---|---|---|---|
| A1買 / A1売 | 98.7% / 98.1% | 1,927 / 2,254 | 0.3% / 1.4% |
| A2買 / A2売 | 97.7% / 97.0% | 1,486 / 1,755 | 0.4% / 1.3% |
| A3買 / A3売 | 98.0% / 96.1% | 2,637 / 3,207 | 1.1% / 1.2% |
| B1買 / B1売 | 91.8% / 91.6% | 2,888 / 3,104 | 1.1% / 1.2% |
| B2買 / B2売 | 98.4% / 97.5% | 698 / 720 | 1.1% / 1.2% |
| B3買 / B3売 | 99.8% / 96.8% | 484 / 473 | 0.8% / 0.0% |
12系統・合計21,633件。ずらした場合はすべて1.4%以下。 1つの高い数字より、12個そろっていることのほうが証拠として強いと考えています。
各系統のずらし幅と窓の組み合わせ(実際のパラメータ)は伏せています。 この同定結果は当方の出荷済み製品の中核であるためです。公開しているのは手順と、 その手順が機能したことの証拠までです。
この12系統を解いて出荷までもっていくのに使った道具と基準を、そのまま一式でお渡ししています。
この工程一式の詳細を見る →
使う道具:fit_by_count.py/divergence.py/contrast.py
発注ゲートを探す — 「どこに置くか」より難しい「いつ置くか」
要するに:置く場所が解けても、いつ置くかは別問題です。 しかもこれは、後から条件を探すと必ず「それらしいもの」が見つかってしまいます。
水準が解けても、まだ足りません。 EAは水準に常時注文を置いているわけではないからです。
ここでの落とし穴は「探せば何か出る」こと。 条件を後から探すと、ほぼ確実に「効いているように見える」ものが見つかります。 そこで、次のやり方に固定しています。
- 調べる特徴量を先に宣言する(時刻・曜日・直近騰落・ATR・MA乖離・水準までの距離・スプレッドなど10項目)。 あとから足しません
- EAが実際にチェックできるものだけにする。 「この週はトレンドだった」はEAには判定できないので候補外
- 学習期間と検証期間を分ける
- 見つかった条件はクローンに入れて走らせて確かめる。表を眺めて納得しない
ラベルの取り方で結果が変わりました。 「価格が一致した/しなかった」でラベルを付けたときの分離度は |d| = 0.09(ほぼ差が無い)。 「注文が置かれていた時間帯/置かれていなかった時間帯」に変えたら d = +0.52 になり、そこから時刻ゲートと距離ゲートが出ました。
この2つを入れたクローンは、本家の PF 1.82 に対して 2.11 になりました。
逆に、無いものを「無い」と示すのも結果です。 別の対象では時刻ゲートを探しましたが、24時間中22時間が2%以上を占め、合計98.5%。 ピーク(14時 10.1%)も一様分布(4.2%)の2.4倍まで。削れるものが無い=時刻ゲートは無い、と確定しました。
使う道具:gatelab_label.py(ラベル生成)/
gatelab_scan.py・gatelab_scan2.py(分離度の走査)/
rule_discovery.py(決定木を深さ3〜4に制限し、読めるルールに変換する)/
gate_depth.py・gate_simplify.py/arm_gap.py/
sell_gate.py/jpy_intervention.py
出口を測る — 決済がどう動いたか
要するに:損切り注文がどう動かされたかを、 建値・最終的なSL位置・その取引での最大到達幅、この3つから逆算します。
決済理由が全件「SL」なのに勝っているEAがあります。 これはSLを利益方向へ動かして確定しているということです。 その動かし方(トレール則)を測ります。
方法は、建値・最終的なSL位置・その取引中の最高到達点の3つを並べること。
ロック幅 = SL − 建値 最大到達 = 建値から最も伸びた幅 トレールが作動した取引: ロック幅 ≈ 最大到達 − T → T がトレール幅 作動しなかった取引: ロック幅 = −初期SL(動いていない)
ある対象の実測では、451件(23%)が初期SLのまま終了し、 中央値は建値+0.108——つまり大半は建値のすぐ上で確定していました。 保持時間は中央1分・p90で5分。
この測定には落とし穴があります。MT5のレポートには ポジションIDが無いので、入りと出は先入先出で対応づけるしかありません。 同じ秒に複数のポジションを開くEAでは、間違った入りと出がペアになります。
そのため「その方向にポジションが1本しか無かった取引」だけを使います。 ある対象では4,009件中1,232件。 この絞り込みをせずに測った初期の版では、SLが建値より下へ動いているように見えました—— 測定のアーティファクトです。
使う道具:trail_law.py/trail_fit.py/
exit_mechanism.py/split_entry.py/ExitEngineCheck.mq5
クローンを組んで、注文を1件ずつ突合する
要するに:組み直したEAを走らせ、 成績ではなく注文を1件ずつ突き合わせます。損益が似ているのは、証拠として弱いからです。
最後に、ここまでで同定した規則だけでEAをゼロから書きます。 本家のコードは使いません(見られません)。
そして成績ではなく、注文を突き合わせます。
成績の一致は、いちばん弱い証拠です。 まったく違う規則でも、似た損益になることはあります。 本当に再現できているなら、損益ではなく「一件ごとの判断」が合うはずです。
だから見る順番を固定してあります:エントリ → 方向 → タイミング → 決済 → SL → ロット → 順序、 損益は最後。
ついでに、「バー単位の的中率」は意図的に出しません。 25,000本のバーに対してエントリが700件なら、「何もしない」だけで97%当たるからです。
ずれの原因は、注文表と約定表を分けると特定できます。
| 症状 | 原因はどこか |
|---|---|
| 置いた数が本家と近いのに、約定数が多い | 置く位置が近すぎる、または置きっぱなしの時間が長い |
| 置いた数そのものが多い | 発注ゲート(⑧)が足りない |
ここで実際にやらかした例を書いておきます。 ⑦で「窓の集合」が答えだと分かったので、7つの窓すべてに買いと売りを同時に置いたクローンを作りました。 結果は取引66,994件(本家の34倍)、DD 100%、口座が飛びました。
窓の集合は「候補の集合」であって「同時に張る本数」ではありません。 本家の設置は5年で3,901件=1日3件です。この間違いは、以前にも別の対象で一度やっています。 「集合」と書いてある同定結果を、実装時に「同時」と読む——という罠として記録しました。
直したのは2点だけで、どちらも「置く量を減らす」方向でした。
| 版 | 変更 | 取引 | 最大DD | PF |
|---|---|---|---|---|
| v0.30 | 7窓×売買を同時 | 66,994 | 100% | 0.80 |
| v0.40 | 片側1本だけ | 12,861 | 6% | 1.09 |
| v0.50 | +再設置まで684分待つ(実測の中央値) | 4,645 | 3% | 1.21 |
使う道具:EaSkeleton.mq5(クローンの骨格)/
diff_test.py(注文ストリームの再現率・適合率)/
fidelity.py(上記の優先順で照合する)/headtohead.py/
ExecutionGuardCheck.mq5
そして、判定する
再現できたとしても、それが売り物になるとは限りません。最後に基準へ照らします。
採用基準(6項目・実行前に宣言してある)
| 項目 | 基準 | なぜその値か |
|---|---|---|
| PF | ≥ 1.60 | コスト悪化に耐える余地 |
| 最大DD | ≤ 10% | 元手基準。運用継続の可否 |
| 取引数 | ≥ 1,500 / 5年 | これ未満は統計として弱い |
| 勝率の余裕 | ≥ 10pt | 損益分岐勝率との差 |
| RR | ≥ 0.50 | 平均利益 ÷ 平均損失 |
| マイナス年 | なし | 年単位で崩れないこと |
そして、しばしばここで落ちます
短期売買のEAで最初に見るべきはPFではなく、スプレッド耐性です。
| 対象 | 1取引あたり期待値 | 典型スプレッド | 耐性 |
|---|---|---|---|
| EA-P | — | — | 9.7倍 |
| EA-O(本家) | +0.308 USD | 0.25 USD | 1.23倍 |
| EA-O(クローン) | +0.107 USD | 0.25 USD | 0.43倍 |
耐性1.23倍とは、スプレッドが0.31ドル悪化したら利益がゼロになるという意味です。 この対象は、水準式が holdout 74.2%・帰無0.0〜0.5% で綺麗に解けていました。 それでも打ち切りました。
「耐性2.0倍を超えなければ打ち切る」と、測る前に宣言してありました。 結果は0.43倍。宣言してあったので、粘らずに終われました。
基準を後から決めると、人は必ず出た数字に合わせて基準を動かします。 先に書いておくこと自体が手法の一部です。
打ち切った3件
| 対象 | どこまで行ったか | 打ち切りの理由 |
|---|---|---|
| EA-K | 距離ゲートでDDを28%改善するところまで到達 | 本家自身が5年で882取引。取引数の基準を満たしようがない |
| EA-Q | PF 2.53・DD 1.5%・2,304取引。候補中で最良の数字 | 最悪ケースを縛れない。安全装置を効かせると必ず悪化した(DD上限を付けると3.0倍に悪化)。 さらに必要な期間の価格履歴が存在せず、測ることもできなかった |
| EA-O | 水準式 holdout 74.2%・帰無 0.0〜0.5% | スプレッド耐性 0.43倍(宣言基準2.0倍) |
再現できたかどうかと、売れるかどうかは別問題です。 そして「これは駄目だ」と証拠つきで示せることは、それ以上時間を使わずに済むという意味で成果です。
ここで使っている採用基準6項目と、それを1コマンドで出す道具も同梱しています。
この工程一式の詳細を見る →
この手法の限界
経験のある方ほど気になる点を、先に書いておきます。
検証期間は、使うたびに減っていきます
「探索に使っていない期間」は一度照合に使った時点で、もう純粋な検証期間ではありません。 そこで落ちた案を作り直して再び同じ期間に当てれば、回数ぶんだけ、その期間に適合していきます。
そのため検証期間を何回消費したかを記録し、最終判定用の期間を別に取り置いています。 これは道具では防げず、記録と規律でしか担保できません。
テスターの約定は、現実より優しい
テスターは指定した価格で約定させますが、実際にはずれます。 ある対象の実測では、最悪の1件が初期SL 1.20ドルに対して −17.36ドル—— 14倍まで滑っていました。窓開けかスプレッド拡大です。
したがってバックテストの成績は上振れとして読みます。 ⑤で解いた水準の正しさとは別に、その水準で本当に約定できるかは別途の問題です。
価格履歴が無い期間は、測れません(が、成功したように見えます)
これは実際に引っかかりました。ある対象を2018〜2021年で走らせたところ、 「取引ゼロで正常終了」と報告されました。コロナショックに耐えたのではありません。 その銘柄の履歴が2021年7月以降しか存在せず、1,121本(約7週間)で回っていただけでした。
さらに厄介なことに、この症状には原因が2つあります。 履歴が無い場合と、口座が破綻してテスターが止まった場合で、レポート上は同じに見えます。 履歴ファイルのサイズと最終残高の両方を見ないと切り分けられません。
この取り違えは致命的なので、約定ゼロを検出したら失敗として報告するようにしました。 最初の実装は、初期入金の行を約定1件と数えていて素通りしていました。
MT4のEAには使えません
これは道具の都合ではなく、手法の前提です。
本記事の解析は、③で書き出す価格データと、②で取り出す「EAが置こうとした注文」を 入力にしています。後者が要になります——約定しなかった注文こそ、EAがどこを狙ったかを示すからです (④⑤⑧⑩はすべてこれを使います)。
MT5のレポートには注文表と約定表が別々にあります。MT4のレポートには、 約定した取引の一覧しかありません。置いたが約定しなかった注文は残らないので、 MT4では、この手法の中心にあるデータが最初から存在しません。
考え方(固定値を探す・帰無検定で偶然を潰す・成績ではなく判断を突合する)は プラットフォームに依存しませんが、手順としてはMT5専用です。
解析対象そのものへの前提
- デモ版と製品版が同一である保証はありません。解析対象がデモ版なら、その前提つきの結論になります
- パラメータを変えれば別のEAになります。同定は「その設定における挙動」の同定です
- 同定が成功する保証はありません。本記事の3件の打ち切りは、その実例です
使っているもの、全部
| 種別 | 本数 | 中身 |
|---|---|---|
| Python | 62本 / 8,956行 | レポート解析、水準式の当てはめ、帰無検定、ゲート探索、トレール則の測定、 クローン突合、テスター実行管理、採用基準・開示基準の判定 |
| MQL5 | 10本 | ティック/M1バー/経済カレンダーの書き出し、銘柄仕様の取得、 チャートオブジェクトの吸い出し、執行チェック、ボラティリティ走査、EAの骨格 |
| 文書 | 10本 / 1,632行 | 採用基準6項目とその根拠、開示基準26項目、実際に踏んだ罠の記録、 テスターのばらつきの実測、DD表記の落とし穴 |
| 合計 | 89ファイル | |
この記事に出てきた「実際に踏んだ罠」(10件)
- 解ける前に、解く価値を確かめる(①)— 順序を間違えて数時間を失った
- 1回のテスト結果でしきい値を決めない(②)— 同条件でPFが±0.03ぶれる
- 注文時刻の「秒」を見る(⑤)— バー駆動かティック駆動かが分かり、16.9%→55.2%
- 帰無検定を通さない一致率は結果ではない(⑥)— 72〜81%が崩れなかった案件がある
- 頭打ちなら残差の中央値(⑦)— 57.4%→74.2%、63%→98.7%
- ラベルの取り方で分離度が変わる(⑧)— |d|=0.09 → d=+0.52
- ポジションIDが無いので、入りと出のペアを絞る(⑨)— 4,009件中1,232件だけ使う
- 「集合」を「同時」と読むと口座が飛ぶ(⑩)— 取引66,994件・DD 100%
- バー単位の的中率は見ない(⑩)— 何もしなければ97%当たる
- 基準は測る前に宣言する(判定)— 後から決めると数字に合わせて動かしてしまう
これらはすべて、うまくいかなかった経験から書かれています。 手順そのものより、こちらのほうが実用価値が高いかもしれません。
この一式を、そのままお渡しします
⑦で挙げた12系統・21,633件の案件は、 そのまま当方の出荷済み製品になりました。 本記事で説明した①〜⑩と判定の工程は、その1本を出すために実際に使ったものです。 その工程一式を、道具と基準ごとお渡しするのがこの商品です。
中身は Python 62本(8,956行)、MQL5 12本、設計・開示文書 13本の計89ファイル。 解析(①〜⑩)を使わず、 EAの骨格・テスターの実行管理・判定基準だけを使うこともできます。
| セット | システム単体 | |
|---|---|---|
| 価格 | 298,000円 | 198,000円 |
| EA開発 システム |
◯ 89ファイル |
◯ 89ファイル |
| EA 7本の ソース |
◯ 差額10万円で付く (単体なら198,000円) |
— |
| 向く方 | 実装を読んで 答え合わせしたい |
自分のロジックが すでにある |
| 枠 | 2つ合わせて限定5名 どちらを買っても枠は1つ消えます | |
ソースコード7本だけのご購入(198,000円・人数制限なし)もできます。
残り5名 (システム単体・セットの合算)
前提:Python と MQL5 のコードを、 自分で読み書きできる方向けです。
Pythonのスクリプトを実行し、MQL5のコードを編集する場面があります。 ゼロから書ける必要はありませんが、コードを一行も触らずに済む商品ではありません。 初心者向けではないことを、先に申し上げておきます。
購入前によくあるご質問
より詳しい12問は商品ページにあります。
| ご質問 | 回答 |
|---|---|
| 動作環境は? | MT5専用・Windowsが必要です。MT5のターミナルと ストラテジーテスターを動かすためです。解析側のPythonは他のOSでも動きますが、 入力を作る工程がMT5に依存します。 またEA開発システムのご利用には Claude Code の契約が別途必要で、 料金は当方の価格に含まれません(ソースコード単体には不要)。 |
| MT4のEAには使えますか? | 使えません。道具の都合ではなく、 手法そのものがMT4では成立しないためです。 理由は本記事の「この手法の限界」と、 ②の図をご覧ください。 |
| 受け渡しは? | 即納です。ソースコードはご購入後すぐマイページから ダウンロードいただけます。 EA開発システムは [要確認: 受け渡し経路(マイページ/メール)] でお渡しします。 |
| 「個別対応」はどこまで? | ご購入後のご相談に個別で対応します(枠を5名にしている理由です)。 対応期間は [要確認: 対応期間]。 EAの成績、解析の成功、利益は保証しません。 |
| 限定5名の枠は? | システム単体とセットの合算で5名です。 埋まった場合は受付を止め、再開する場合は 「第2期」として価格は据え置きでご案内します。 ソースコード7本だけのご購入は人数制限がありません。 |
| 返金はできますか? | デジタルコンテンツの性質上、提供開始後のお客様都合による 返品・返金・キャンセルはお受けできません。 だからこそ、購入前にご相談ください。 動作環境と、できること・できないことを先に確認していただけます。 |