戦略のMonte Carloシミュレーション — 1回のバックテストが隠すリスク
ある読者が、自慢のバックテストを送ってきたことがあります。勝率55%、平均利益100ユーロ、平均損失80ユーロ、紙の上では年間およそ3,800ユーロの期待利益。手堅い数字に見えたので、彼はライブ口座を開き、1トレードあたり5%のリスクを取り、半年で口座を吹き飛ばしました。間違いは戦略そのものではなく、1回のバックテストを唯一の真実として扱ったことでした。Monte Carloを回していれば、そのポジションサイズなら口座を破綻させる確率がおよそ25%あったと分かったはずです。
戦略のMonte Carloシミュレーションとは、実際のところ何か
Monte Carloは、モナコのカジノにちなんで名付けられた確率論的な手法です。トレードにおける発想は拍子抜けするほど単純で、過去のデータがたまたま描いた1本の資産曲線を眺める代わりに、同じ統計値を持ちながら順序だけが異なる新しいシーケンスを1,000本生成します。一本一本が異なる口座の姿を描き、それらが束になることで、1回の実践的な検証(バックテスト)の領域だけでは決して見えない「可能性の雲」を形づくります。
1回のバックテストは、ランダムな過程のたった1つの実現値にすぎません。その周囲のばらつきは、ときに膨大になり得ます。優位性のある勝負を繰り返すとはそういうものです。Monte Carloは、そのばらつきを、行動の指針にできる具体的な数字へと変えてくれます。
Monte Carloが本当に答えてくれる問い
このシミュレーションは、1回のバックテストでは得られない3つのものを与えてくれます。1つ目は95%の信頼水準における現実的なドローダウン、つまり100回のシミュレーションのうち95回ではそれ以上深くならない水準です。2つ目は口座の相当部分を失う確率、たとえば資金が半分を割り込む確率です。3つ目は、優位性が一定のまま推移したときのもっともらしい年間成績の振れ幅です。
私の説明用シナリオ(明確に仮想のものです)では、勝率55%、平均利益100ユーロ、平均損失80ユーロ、年間200トレードの戦略は、1トレードあたりおよそ19ユーロのリスク管理の考え方に基づく期待値を持ち、紙の上では3,800ユーロになります。1,000回のシミュレーションでは、中央値は3,750ユーロ付近に出ました。最悪の5%のランは利益およそ500ユーロで終わり、最悪の1%は800ユーロの損失、最良の5%は7,500ユーロに達しました。同じ優位性でありながら、5倍の開きです。
Excelでシミュレーションを回す方法
マクロなしのバージョンでも、自分の戦略を理解するには十分です。セルA1からA5にパラメータを入れます。勝率0.55、平均利益100、平均損失-80、トレード数200、初期資金10,000です。セルB1には =IF(RAND()<A1, A2, A3) と入力します。ExcelのRAND関数は0から1の値を返し、それが勝率を下回るたびに勝ちトレードに、そうでなければ負けトレードになります。
セルC1では、初期資金にB1の値を足します。これが資産曲線の最初の点です。B2は同じ数式を使い回し、C2はC1の値にB2を足します。両方の列を200行目までドラッグします。これで1年分の完全なシーケンスが1本できあがります。
この2列を横方向に1,000回コピーすれば(B–C列、D–E列、F–G列……というように)、独立した1,000本の資産曲線が得られます。最終値から、中央値には =PERCENTILE.INC(範囲, 0.5) を、最悪の5%と1%にはそれぞれ0.05と0.01を読み取ります。F9キーを押すとすべての乱数が再計算されるので、押すたびに新たな1,000ラン分の研究になります。これで本当に十分なのです。
Pythonとブートストラップで同じことをする方法
Pythonは、Excelにはできない2つのものを与えてくれます。1つ目は速度で、数千ランが数秒で終わります。2つ目は、より重要なことに、ブートストラップが可能になる点です。仮定したパラメータからではなく、実際の過去トレードのリストから抽出できるのです。
NumPyをインポートし、ジャーナルから100以上の実際のP/L値を読み込み、new_sequence = np.random.choice(history, size=200, replace=True) と書きます。np.cumsum 関数はP/L値のリストを資産曲線に変え、その周りにループを回せば独立した1,000ランが得られます。パーセンタイルは np.percentile で読み取り、Matplotlibを使ってスパゲッティプロットを描きます。1,000本すべての曲線を重ね、中央値と5〜95パーセンタイルの帯を強調したものです。
ブートストラップは、分布の本当の裾を保ちます。分厚い損失、固まって現れる値動き、ボラティリティの高い週にときおり出る記録的な勝ちトレードといったものです。パラメトリックな仮定では、あなたのトレードが実際に持つ分布を仮定していないため、これらを再現できません。
「リスクリワード比は、ポジションサイジングを式に組み込まなければ、ほとんど意味をなさない。ポジションサイジングを通じて、あなたはほぼ望みどおりのどんな目標でも達成できる」 — Van K. Tharp, 2007
正直な限界 — Monte Carloができないこと
パラメトリックなシミュレーションは、2つの仮定の上に成り立っています。トレードが互いに独立であること、そして結果の分布が定常であることです。現実の市場では、この両方が同時に崩れます。損失は固まって現れます。市場のレジームが変わると、数トレードが連続して同じ方向に動くことがあり、同じ分布から独立に標本を引くモデルではこれを再現できません。だからこそ、現実のトレードで最も暗いドローダウンは、Monte Carloの1%パーセンタイルより良くなるのではなく、しばしば悪く見えるのです。
2つ目の問題は、シミュレーションがあなたの与えたまさにその過去データを使う点です。あなたの100トレードがEUR/USDの上昇トレンドだけを対象にしているなら、長い保ち合いや米国指標後の急な200pipsの動きで戦略がどう振る舞うかについて、Monte Carloは何も教えてくれません。だからこそ、ローリングウィンドウで戦略を検証し優位性の劣化を捉える戦略の堅牢性を確かめる手法と組み合わせる価値があります。
最も暗いドローダウンは、しばしばクリーンなMonte Carloランの1%パーセンタイルよりも深く掘り下げます。シミュレーションは天井ではなく確率的な床として扱い、長文の文脈についてはForexMechanicsのリスク管理に関する解説と併せて読んでください。
これを実際に使うために、明日からできること
- ジャーナルやプラットフォームのエクスポートから、少なくとも100件のクローズ済みトレードの履歴を取り出してください。100件を下回ると、統計値のノイズが大きすぎて、Monte Carloが裾について有益なことを語れなくなります。もし足りなければ、あと6〜12週間トレードを続け、より充実したサンプルを持ってこの作業に戻ってきてください。
- 空のExcelシートを開き、上で説明したパラメトリック版を組み立ててください。自分自身の勝率、平均利益、平均損失、資金を入力し、列を1,000回コピーしてF9を押し、最終値のばらつきを観察します。その1時間の作業が、あなたの「平均的な年」の裏で振れ幅が実際どれほど広いかを明らかにします。
- その1,000回のシミュレーションから、最大ドローダウンの5%パーセンタイルを読み取ってください。それが30%の凹みを示す一方、あなたの心理的な耐性が15%あたりで尽きるなら、問題は戦略ではなくポジションサイズです。1トレードあたりのリスクを半分にし、5%の床があなたの痛みの閾値の内側に収まるまで回し直してください。
- 1年間のライブトレードのあと、新しい履歴で再びシミュレーションを回し、前年のものと比較してください。中央値が下がり、裾が広がっているなら、あなたの優位性は劣化しています。それは、戦略をだましだまし延命させる方法ではなく、その戦略がまだ機能するのかを問うべき瞬間です。
出典・参考文献
-
Bank for International Settlements Minimum capital requirements for market risk (d457) · Bazylejski standard pokazujący, jak instytucje liczą ryzyko rynkowe za pomocą expected shortfall i historycznej symulacji — analog Monte Carlo dla portfela. www.bis.org ↗
-
Van Tharp Institute About Van K. Tharp · Strona biograficzna potwierdzająca autorstwo książki „Trade Your Way to Financial Freedom" (McGraw-Hill) i jego pracę nad position sizingiem oraz symulacją Monte Carlo dla traderów detalicznych. www.vantharp.com ↗
-
NumPy Developers numpy.random.choice — Random sampling · Oficjalna dokumentacja funkcji losowania z powtórzeniami; podstawowe narzędzie do bootstrap resampling listy transakcji w Pythonie. numpy.org ↗
-
Python Software Foundation random — Generate pseudo-random numbers · Oficjalna dokumentacja biblioteki standardowej Pythona z funkcjami random.choices i random.sample, używanymi do prostych symulacji Monte Carlo bez NumPy. docs.python.org ↗
よくある質問
トレード戦略のMonte Carloシミュレーションとは何ですか?
Monte Carloは、モナコのカジノにちなんで名付けられた確率論的な手法です。トレードでは、過去トレードのリストや戦略のパラメータ(勝率、平均利益、平均損失)を取り、過去のデータがたまたま生み出した1本の資産曲線を眺める代わりに、ランダムな順序で1,000本の新しいシーケンスを生成します。それぞれは同じ統計値を持ちながら勝ち負けの順序が異なるため、異なる口座の姿を描きます。何のために?:単独のバックテストは1つの実現値にすぎません。その周囲のばらつきは膨大になり得ます。1トレードあたりおよそ19ユーロの期待値と年間200トレードを持つ同じ戦略が、Monte Carloシミュレーションでは3,750ユーロ付近の中央値を出す一方、最悪の5%は500ユーロまで下がり、最良の5%は7,500ユーロまで跳ね上がります。優位性が一定でも振れ幅は広いのです。最もよくある誤解:「去年この戦略は5,000ユーロ稼いだから、今年も同じくらいだろう」。Monte Carloは、優位性を一定に保っても現実的な範囲が1,000ユーロから10,000ユーロにまで広がり得ること、そしてそこに何ら異常はないことを示します。それは単なるばらつきなのです。
ExcelでMonte Carloシミュレーションを回すにはどうすればよいですか?
最もシンプルなバージョンは、マクロもVBAも必要としません。セルA1からA5にパラメータを入力します。戦略の勝率(たとえば0.55)、平均利益(たとえば100)、平均損失(たとえば-80)、シーケンス内のトレード数(たとえば200)、そして初期資金(たとえば10,000)です。セルB1には数式 =IF(RAND()<A1, A2, A3) を入力します。これが1トレードをシミュレートします。ExcelのRAND関数は0から1の数を返し、それが勝率を下回れば利益、そうでなければ損失になります。セルC1では、初期資金にB1の結果を足します。B2とC2の数式も同様に作りますが、C2はC1を参照します。200行目まで下にドラッグします。こうして1年分の完全なシーケンスができあがります。この2列を横方向に1,000回複製すれば、独立した1,000本の資産曲線が得られます。最終値から、中央値には =PERCENTILE.INC(範囲, 0.5) を、最悪の5%と1%を見るには0.05と0.01を計算します。F9キーはすべての乱数を再計算するので、押すたびに新しい1,000ラン分の研究になります。Excelはこれを問題なく処理し、自分の戦略を理解するにはこれで十分です。
PythonでMonte Carloをどう実装すればよいですか?
Pythonは同じ仕事をより速くこなし、パラメータだけでなく実際のトレード履歴からのブートストラップ(復元抽出による再標本化)を可能にします。NumPyをインポートし、戦略のパラメータを定義し、結果のシーケンスを1本生成する関数を書きます。0から1の値からなるランダムな配列を勝率と比較すると0と1のベクトルが得られ、関数 np.where がそのベクトルを平均利益と平均損失に変換します。関数 np.cumsum は個々のP/Lのリストを資産曲線に変えます。この関数をループで1,000回実行し、最終値を集め、np.percentile でパーセンタイルを計算します。100件以上の実際のトレードのリストがあれば、np.random.choice(history, size=200, replace=True) を使ってブートストラップします。自分自身の履歴から復元抽出で200トレードの新しい連なりを引くことで、パラメトリックな仮定では再現できない分布の本当の裾を保てます。Matplotlibライブラリを使えばスパゲッティプロット、すなわち1,000本すべての曲線を重ね、中央値と5〜95パーセンタイルの帯を強調した図を描けます。1枚の画像は、戦略のリスクについて10枚の表よりも多くを語ります。
トレードにおけるMonte Carloの限界は何ですか?
Monte Carloは占いではありません。これははっきり言っておくべきことです。パラメトリックなシミュレーションの基本的な仮定は、トレードが独立であること、そして結果の分布が定常であることです。現実の市場では、この両方の条件が同時に崩れます。損失は固まって現れます。市場のレジームが変わると、数トレードが連続して同じ方向に動くことがあり、同じ分布から独立に標本を引くモデルではこれを再現できません。だからこそ、現実のトレードで最も暗いドローダウンは、Monte Carloの1%パーセンタイルより良くなるのではなく、しばしば悪く見えるのです。2つ目の問題は、シミュレーションがあなたの過去データから取り出したまさにその統計値を使う点です。その履歴がEUR/USDの上昇トレンドだけを対象にしているなら、保ち合い局面で戦略がどう振る舞うかについて、Monte Carloは何も教えてくれません。実務上の帰結:Monte Carloの結果は天井ではなく確率的な床として扱ってください。最悪の5%シナリオが30%の下落を示すなら、実戦ではさらに深い下落を見ると想定してください。ポジションサイズは、平均的な期待結果ではなく、その確率的な床に合わせて決めること。そうすれば、現実の挫折に打ちのめされずにすみます。