【EA開発の失敗談】「どの通貨でも右肩上がり」だったEAが、テスト方法を1つ変えた瞬間に崩れた話
前回は、バックテストを開いたときに確認している5つの数字——最大DD、取引数、PF、勝率、検証期間——について書きました。
では、この5つを押さえたうえで、期間を変えても通貨を変えても成績が良かったEAなら、信用していいのか。
少し前、私はまさにそんなEAを作りました。5つの観点でも大きな違和感はなかった。
それでも、あるテスト条件を変えただけで崩れ、開発を止めました。
今回はその話です。
「かなり強いロジックかもしれない」
対象は、為替の短期スキャルピングEAでした。細かい条件は省きますが、水平線付近の短い反発を狙うもので、
水平線へ接近 → 5秒以内に1pip反発を確認 → エントリー
という、秒単位の値動きを使っていました。
最初の結果は良く見えました。ただ、1回の好成績だけでは安心できません。
「この期間だけじゃないか」「この通貨だけハマっているんじゃないか」を疑うのは、開発をしていると当たり前になります。
期間を変えてもプラス。通貨を広げてもプラス。最終的にUSDJPY、GBPUSD、EURUSD、GBPJPY、EURJPYの5通貨まで見ましたが、いずれもプラスでした。
ある検証では、5通貨合計で
1,939トレード
+7,009.5pips
PF 2.26
勝率58.3%
別の期間では
1,267トレード
+4,765.7pips
PF 2.26
後者は約2年8か月のうち、32か月中30か月がプラスでした。
取引数が極端に少ないわけでもなく、PFも不自然なほど高くなく、勝率も90%台ではありません。
前回書いた5つの観点で見ても、大きな違和感はありませんでした。
期間の違う2つの検証で、5通貨合算のPFがどちらも2.26だったこともあり、当時はこう思っていました。
「これは、かなり強いロジックを見つけたのではないか」
見落としていたもの
検証を続けるなかで、気になった点がありました。
MT5のストラテジーテスターには、価格の再現方法がいくつかあります。私はそれまで「全ティック」で回していました。
ただ、今回のEAは保有時間が長いタイプではありません。
「5秒以内に1pip動いたか」がエントリーの分岐になります。数秒の値動きの並び方が、結果を左右します。
「これ、生成されたティックじゃなくて、リアルティックで確認した方がいいんじゃないか」
そう思い、テスト方法だけを変えました。「全ティック」から「リアルティックに基づいたすべてのティック」へ。
ロジックもパラメータも同じです。テスト方法を変えただけです。
もう一度回した結果を見たとき、最初は何が起きたのかすぐには飲み込めませんでした。
PF2前後だったものが、PF0.82になった
最初に確認したリアルティックの結果では、
894トレード
純損失 −77,670円
PF 0.82
まで崩れました。右肩上がりに見えていたものが、普通に負ける側の数字になりました。
しかし、すぐに「リアルティックにしたからこのEAは終わり」とはしませんでした。
ヒストリー品質の問題もあり得たからです。期間を短くしたり、別の期間で見たりして調べましたが、同じ傾向だったので、データではなくロジック側の問題だと判断しました。
調べていくと、もっと厄介な差が見えてきました。
同じ「1pip反発」なのに、回数が約2.7倍
全ティックとリアルティックで、条件成立の回数を比べました。
全ティックで「5秒以内に1pip反発」が成立したのは509回。リアルティックでは1,375回。約2.7倍です。
最初はスプレッドを疑いました。リアルティックでは細かいBid/Askの動きが入り、スプレッドの影響が大きくなったのではないか、と。
ただ、スプレッドが狭い場面に絞っても、成績は戻りませんでした。
問題は、もう少し手前にありました。
「1pip反発」として拾っている現象そのものが、モードによって違って見えていた、ということです。
実際のティックでは、短い時間でも価格は細かく上下します。
その結果、水平線へ接近 → 一瞬だけ1pip戻る → EAが反発と判定してエントリー → また元の方向へ戻る
といったケースまで多く拾います。一方、全ティックのモードでは、ティックが生成される過程で、この細かな往復の見え方が違っていました。
同じ条件式を使っているつもりでも、相手にしている値動きの粒度がそもそも違っていた、というのが当時の実感です。
全ティックで勝っていた406件を、リアル側で追い直した
では、全ティックで利益になっていたトレードは、リアルティック上ではどう動いていたのか。
全ティック版で実際にエントリーしていた406件を取り出し、同時刻のリアルティック側を照合しました。
勝っていた側は、「触れて1pip戻った」だけの場面というより、強い値動きで水平線へ入っていく場面に偏っていました。
タッチ前60秒の値幅は、勝ち平均14.01pips、負け平均8.48pips。
20pips以上動いて到達したケースでは、全ティック版の勝率は87.3%まで上がっていました。
ここで、全ティック版が何を拾っていたのかが、少し見えてきました。
「5秒以内に1pip」は、狙っていた動きを表せていなかった
しかし、リアルティック上の平均を見ると、全ティック版の勝ちトレードでも、エントリー直後から素直に順行していたわけではありませんでした。
1秒後:−1.98pips 3秒後:−1.46pips 5秒後:−1.14pips 10秒後:−0.52pips
どちらかというと、最初は逆行気味です。それが
30秒後:+1.44pips 60秒後:+2.22pips
と、時間をかけて戻る形でした。
つまり、最初に置いていた「5秒以内に1pip戻ったら反発」という定義は、自分が取りたかった動きをうまく表せていなかった可能性があります。
特徴的だったのは、強い値動きで水平線へ入る→ライン付近で一度もむ→10〜60秒かけて反転する、といった動きでした。
ここまで来ると、最初のEAとは別物に近い話です。
もう一度組み直そうとして、止めた
調べた以上、すぐには手放しませんでした。リアルティック上の候補を集め、条件を組み直せないか見ました。
最終的に3,897件を材料に、タッチ前の値幅、反発幅、スプレッド、秒数などを比較しました。
フィルターなしでは、5秒後でも30秒後でも、PFはおおよそ0.55〜0.56でマイナス寄りでした。
そこから絞ると、
タッチ前60秒の値幅が20pips以上
10秒後に反転方向へ1pip以上
スプレッド2.0pips以下
では、44件/平均+3.21pips/勝率68.2%/PF1.43まで改善しました。
「まだいけるかもしれない」とは思いました。ただ、数千件から残ったのは44件です。
条件を緩めると、すぐ数字は落ちます。
ここからさらに条件を足せば、見た目の良いバックテストは作れたかもしれません。
そのとき感じたのは、「また成績に合わせて条件を足し始めている」ということでした。
そこで、このEAの開発はいったん止めました。
「リアルティックなら正解」という話にはしたくない
「全ティックの結果は信用するな」と言いたいのではありません。
EAによって、価格データに求める細かさは違います。
今回大きく揺れたのは、エントリーが「5秒以内の1pip」という、短い時間の並び方そのものに依存していたからです。
秒単位で判定するロジックでは、ティックの再現の仕方で結果が変わることがあります。
もっと長い時間軸のEAなら、同じ幅の差になるとは限りません。
また、リアルティックであれば常に正しいというわけでもありません。履歴の品質や取得環境によって、見え方が変わることもあります。
覚えるべきなのはモードの名前より、自分の条件が、データのどの粒度に依存しているかを見ることだ、というのが今の整理です。
正直、今でも完全に言語化しきれていない部分はあります。
数字の前に、その数字の作り方
前回書いた5つ——DD、取引数、PF、勝率、検証期間——は、今も見ます。
その手前に、もう一つ増えました。「その数字は、どんなテスト条件から出たのか」です。
今回のEAは、期間を変えても、通貨を変えても、取引数も、PFも、月別の見え方も、悪くない側でした。
それでも、テスト方法を変えただけで崩れました。
最初から怪しい曲線なら、ここまで印象に残らなかったと思います。
「かなり疑って検証した。それでも見落とした」経験だったから、今でも覚えています。
綺麗な右肩上がりを見ると、今でも正直うれしいです。ただ、その次に考えることが一つ増えました。
「この右肩上がりは、ロジックが作ったのか。それともテスト環境が作ったのか」という点です。
おわりに
このEAは完成しませんでした。何日も回して、CSVを出して、数千件を見て、最後は中止です。結果だけ見れば失敗です。
ただ、このあとバックテストを見るとき、成績だけでなくテスト方法そのものを以前より気にするようになりました。
完成したEAから学ぶこともありますが、完成しなかった側からしか来ない学びもあります。
むしろ開発をしていると、後者の方が多い気さえします。
次回は資金管理、なかでもナンピンについて書きます。
否定だけの記事にはしません。自分も触ってきたし、今も開発の途中にあるテーマだからです。
バックテスト上で魅力的に見えやすいところと、見誤らないために見ているところを、実体験ベースで整理します。