相場環境(トレンド・レンジ)別にバックテスト結果を分ける
同じ売買ルールでも、トレンド相場とレンジ相場では成績が逆になることがあります。バックテストの結果をエントリー時の相場環境ごとに分けると、その戦略がどの相場で稼ぎ、どの相場で負けているのかが分かります。この記事では、相場環境の判定方法と、分けるときの落とし穴をまとめます。
合計の成績だけでは分からないこと
ある戦略の損益が-2%だったとします。これは「どこでも少しずつ負ける戦略」かもしれませんし、「トレンドでは大きく勝ち、レンジでそれ以上に負ける戦略」かもしれません。2つは合計が同じでも、次に試すことがまったく違います。
後者なら、戦略そのものを捨てる必要はありません。レンジを避ける条件を加える、レンジ用の別ルールと組み合わせる、といった改善の余地があります。前者なら、ルールの考え方から見直すことになります。
例:ブレイクアウトを相場ごとに流した結果
Hawk Backtesterのデモで、直近40本の高値・安値を抜けたら入るブレイクアウトを、合成データの相場の種類だけ変えて流しました。データは乱数で作った合成データ(1時間足1,500本)で、実際の相場の成績ではありません。
| 相場 | 損益 | 勝率 |
|---|---|---|
| トレンド | +10.20% | 48% |
| レンジ | -6.10% | 23% |
| 急変動 | -4.73% | 27% |
| ミックス | -2.29% | 29% |
ブレイクアウトがトレンドに強く、レンジに弱いのは教科書どおりです。ただ、ミックス相場の-2.29%だけを見ていたら、この偏りには気づけません。自分の戦略がどの相場でどう負けているかは、実際に分けてみるまで分かりませんでした。

相場環境の判定方法
実データには「この足はトレンド」という正解ラベルがありません。自分で判定のルールを決める必要があります。よく使われるのは次の3つです。
ADXでトレンドの強さを見る
ADX(平均方向性指数)は、方向を問わずトレンドの強さを表す指標です。ADXが25以上ならトレンド、20未満ならレンジ、というように閾値で分けます。上昇か下降かは、+DIと-DIのどちらが大きいかで判定します。閾値の25や20は慣習的な値で、銘柄や時間足によって合う値は変わります。
移動平均の傾きで方向を見る
たとえば50本移動平均の、直近10本での変化率を使います。一定以上の上向きなら上昇トレンド、下向きなら下降トレンド、その間ならレンジとします。判定が分かりやすく、自分で検算しやすい方法です。
ボラティリティの水準で分ける
ATRや一定期間のリターンの標準偏差を、過去の分布と比べます。たとえば過去1年の中で上位10%に入るボラティリティの時期を「急変動」とします。トレンドかレンジかとは別の軸なので、上の2つと組み合わせて使えます。
# 例:エントリー時点の相場を判定する(未来のデータを使わない)
ma = close.rolling(50).mean()
slope = ma.pct_change(10) * 100 # 50本MAの直近10本での変化率(%)
vol = close.pct_change().rolling(20).std()
vol_rank = vol.rolling(24 * 250).rank(pct=True) # 過去の分布での位置
def regime_at(i):
if vol_rank.iloc[i] > 0.9:
return "shock"
if slope.iloc[i] > 0.3:
return "up"
if slope.iloc[i] < -0.3:
return "down"
return "range"
# 各トレードに、エントリーした足の判定を付ける
trades["regime"] = [regime_at(t.entry_index) for t in trades.itertuples()]
閾値(0.3%や上位10%)は例です。自分の銘柄・時間足で、判定結果をチャートに重ねて見て、違和感がないかを確かめてから使ってください。
「エントリー時」で分ける理由
相場で分けるときは、トレードが始まった時点の判定を使います。保有中に相場が変わることはよくありますが、戦略が判断に使えるのはエントリーした時点の情報だけです。エントリー時の相場で分けておけば、「この相場のときは入らない」という条件にそのまま置き換えられます。
相場で分けるときの落とし穴
未来のデータで判定してしまう
一番多い失敗は、判定に未来のデータが混ざることです。たとえば「その後50本で価格が5%以上動いた区間をトレンドとする」という判定は、後から見ればきれいですが、エントリーした時点では分かりません。この判定で「トレンドのときだけ入る」と条件を付けると、実際には使えない情報で成績を良く見せてしまいます。中心化した移動平均や、期間全体で計算した平均・標準偏差も同じ問題を持ちます。
1つの相場あたりの取引数が少ない
全体で60回の取引も、4つの相場に分けると1つあたり15回前後になります。急変動の時期は短いので、数回しかないこともあります。数件の大きな勝ち負けで結果がひっくり返るので、件数の少ない相場の結果は参考程度に見てください。Hawk Backtesterのデモでは、取引が3件未満の相場はヒントの判定に使いません。
判定ルールに合わせて戦略を調整しすぎる
相場の判定ルールそのものもパラメータです。閾値を細かく変えて一番成績の良い組み合わせを選ぶと、その期間に合わせすぎた結果になります。考え方は過剰最適化を避ける方法と同じです。
分けたあとに何をするか
- 負けている相場を避ける条件を加える:たとえばADXが20未満のときはブレイクアウトに入らない。加えたあと、別の期間でも効くかを確かめます。
- 負け方を相場ごとに見る:レンジでの負けが「一度は含み益だった負け」なのか「最初から逆行した負け」なのかで、直す場所が変わります。見分け方はMFE・MAEの解説にあります。
- 別の期間・銘柄で同じ傾向が出るか確かめる:1つの期間だけの偏りは、偶然のこともあります。

Hawk Backtesterのデモは合成データを使うため、相場の種類が正解として分かっています。判定のずれに悩まずに「相場で分けると何が見えるか」を確かめられるので、まず考え方をつかむのに向いています。自分のデータで試す場合は、上のような判定ルールを自分で決めることになります。
よくある質問
トレンドとレンジを判定する一番良い指標はどれですか?
どれか1つが常に優れているわけではありません。ADXは方向を問わない強さ、移動平均の傾きは方向、ボラティリティは値動きの大きさを見ています。何を知りたいかで選び、判定結果をチャートに重ねて目で確かめるのが確実です。
相場ごとに別のパラメータを使ってもよいですか?
使えますが、パラメータの数が増えるほど過去のデータに合わせやすくなります。相場ごとに分けたあとの取引数が十分にあるか、別の期間でも同じ結論になるかを確かめてください。
バックテストで相場別に勝っていれば、今後も勝てますか?
分かりません。バックテストは過去のデータでの振る舞いを調べるもので、将来の成績を保証するものではありません。相場別の分析は、戦略の性格を理解するための道具として使ってください。