普段は会社員として働きながら、休日にPythonでコツコツとバックテストを書いている。今回から数回に分けて、その検証の過程を記事にしていこうと思う。テーマは「テクニカル分析は本当に長期的な資産形成の役に立つのか?」という、投資をやっている人なら一度は気になる問いだ。
検証の出発点になった問い
チャート分析の本を読むと、移動平均線やMACDのようなテクニカル指標を使えば「トレンドに乗って利益を伸ばせる」という話がよく出てくる。ただし、天井や底をピンポイントで当てられるとは誰も思っていない。現実的なところを言えば、
天井・底を完璧に当てるのではなく、トレンドの60〜80%程度を機械的に取り続ければ、長期的にBuy & Holdより良い結果になるのか?
という問いのほうが、実務的には意味がある。「感覚」や「後知恵」ではなく、実際に過去データへ機械的なルールを当てはめたらどうなるのか、を手を動かして確かめてみようというのが、このシリーズの出発点だ。
まずはSPY・ドル円で試したが、除外した
最初に検証したのは、王道中の王道であるS&P500(SPY)と、身近なドル円(JPY=X)だった。戦略はテクニカル分析の基本であるMACD(12, 26, 9)。「MACDがシグナルを下から上に抜けたら買い、上から下に抜けたら売って現金化する」という、教科書どおりのシンプルなルールだ。
結果は、正直に言うと期待外れだった。
| 銘柄 | 期間 | Buy&Hold CAGR | MACD CAGR | Buy&Hold Sharpe | MACD Sharpe |
|---|---|---|---|---|---|
| SPY | 1993〜2026 | 8.91% | 3.58% | 0.55 | 0.37 |
| ドル円(JPY=X) | 1996〜2026 | 1.10% | -0.77% | 0.15 | -0.05 |
SPYはCAGR・Sharpe・最大ドローダウンのすべてでBuy & Holdに負けた。緩やかな右肩上がりの中に短期的なノイズが多く、MACDが細かく売買を繰り返す(この期間だけで369回)ことでリターンを削ってしまう。ドル円に至ってはMACDのCAGRがマイナスに転落している。長期のレンジ相場や急激な相場変動が、トレンドフォロー型の戦略には構造的に不利に働くようだ。
Train/Test分割によるWalk-forward検証(学習期間だけでパラメータを選び、見ていない検証期間で試す方式)でも同じ傾向が再現された。「たまたま12/26/9というパラメータが悪かった」のではなく、SPY・ドル円という資産そのものに対してMACDが構造的に優位性を持たない、という結論に至った。
ここで一度、正直に立ち止まることにした。都合の良い銘柄だけを探して優位性を「発見」するのは、後知恵バイアスと紙一重だ。SPY・ドル円は検証対象から外し、現在はBTC-USD・ETH-USDに絞って検証を続けている。
BTC-USDでは何が起きたか
同じMACD(12, 26, 9)をBTC-USD(2014年〜)に適用すると、様相が変わる。
| Buy & Hold | MACD(サイジングなし) | |
|---|---|---|
| CAGR | 51.56% | 65.75% |
| Sharpe | 0.96 | 1.34 |
| 最大ドローダウン | -83.40% | -48.71% |
CAGR・Sharpe・最大ドローダウンのすべてでMACDがBuy & Holdを上回る。強い片方向トレンドが繰り返し発生しやすい資産では、機械的な追随がうまく機能するようだ。
ただし、ここで話を終わらせると誠実ではない。実弾投入を想定して、ボラティリティに応じてポジションサイズを調整する仕組み(VolatilityTargetSizer)と、致命傷を避けるためのストップロス(15%)を組み込んだ「本番構成」で同じ期間を測り直すと、数字は次のように変わる。
| Buy & Hold | MACD(本番構成) | |
|---|---|---|
| CAGR | 51.56% | 46.88% |
リスク管理を組み込んだ本番構成では、CAGRという単純な比較でBuy & Holdに負ける。得られているのはSharpe・最大ドローダウンで測った「リスク当たりの効率」であって、絶対リターンでの優位性ではない。下落局面でいったん現金化するコスト(その後の急反発を取り逃す機会損失)が積み重なるためで、これはトレンドフォロー戦略に共通する弱点だ。
一方で、最大ドローダウンをおおむね-70〜80%台から-40%前後まで抑える効果は、検証した期間や通貨建てを変えてもかなり一貫して確認できた。「トレンドの一部を機械的に取り続けることで、暴落時の傷を浅くする」という、地味だが実務的には一番使える効果だ。
つまり冒頭の問いへの答えは、単純なYes/Noではない。生のMACDシグナルだけを見ればYesだが、実弾投入に耐えるリスク管理を組み込んだ構成ではNo、というのが今のところの誠実な結論だ。
検証で気をつけていること
このシリーズを通して、次の3点は一貫して意識している。
- Look-ahead bias(未来情報の混入)を入れない — 当日の終値で計算したシグナルは、翌営業日のポジションから反映する。「今日の終値を見てから今日のうちに売買できる」という現実にはあり得ない前提を排除する。
- 過学習(overfitting)を疑う — パラメータを全期間で最適化すると、その期間のノイズにフィットしただけの見せかけの優位性が生まれやすい。学習期間と検証期間を分けるWalk-forward方式で、見ていないデータでも効くかを確認する。
- Winner’s curse(選定バイアス)を疑う — 複数パラメータの中からSharpe最良の1つを選ぶ作業自体が、その期間固有のノイズを拾いやすい。学習期間のSharpeが高くても検証期間で大きく崩れるケースが実際に何度もあった。
このリポジトリには自動テストスイートはない。小規模なリサーチスクリプトという位置づけなので、その代わりにこの3つの警戒姿勢を毎回の検証で崩さないようにしている。
次回予告
次回は「ポジションサイジング・ストップロス編」。本番構成で使っているVolatilityTargetSizerとストップロスが、具体的にどういう理屈で最大ドローダウンを圧縮しているのか、パラメータをどう選んだのかを掘り下げる。