ボラティリティ収縮からのブレイクアウトを設計する — 収縮の検出と突破基準の決め方

市場が静かな時間は、ずっと静かなままではありません。値幅が縮んだあとに大きく動き出すという交代は多くの市場で観察されており、その切り替わりを起点にするのがボラティリティブレイクアウトの発想です。本記事では「収縮をどう検出するか」と「どこを抜けたら突破と見なすか」という性格の違う2つの判定を組み合わせ、cBotへ落とし込める形の設計として整理します。想定読者は、ブレイクアウト型のロジックを自作したい方、一度組んでみたもののダマシの多さに手を焼いている方です。特定の設定が成果を保証するという話ではなく、判定の骨組みと実装上の落とし穴を共有することが目的です。

値幅が収縮した局面から拡張へ移る過程と、バッファを加えた突破判定の位置関係を示す模式図

ボラティリティ収縮の役割

収縮の検出は、「いつ狙うか」という時期の絞り込みを担当します。使う材料はいくつかあり、一定期間の値幅を平均したATR、直近の高値と安値の差、バンド幅などが代表的です。ATRの読み方そのものはATRとボラティリティの基礎にまとめています。

ここで外せないのが、絶対値ではなく相対値で判定するという点です。値幅の大きさは銘柄や時間足によって桁が違うため、「この数値を下回ったら収縮」という固定のしきい値は他の対象へ持ち運べません。ATRを自身の長期平均と比べた比率で見るか、過去の分布の中での順位で見るかたちにすると、対象をまたいでも同じ基準を使い回せます。順位で見る方式はATR Percentile Rankの設定ガイドでも扱っています。

一方で、収縮の検出そのものには限界があります。第一に、収縮は方向をまったく示しません。静かになったことは分かっても、次に上下どちらへ動き出すのかについては何も語らない指標です。第二に、収縮が何本続くかは事前に分かりません。「縮んだから次は伸びる」という因果があるわけではなく、静かな状態がそのまま長く続く局面も普通に存在します。収縮はあくまで候補を絞る材料であって、動き出しの合図ではありません。

突破基準の役割

もう一方の突破基準は、「どこで入るか」という水準の定義を担当します。よく使われるのは直近N本の高値・安値、前日の高値・安値、レンジの上下端といった水平の基準です。多くのトレーダーが同じ水準を見ているため注文が集まりやすく、機械的に算出できる点も実装向きです。チャネルとして扱う考え方はドンチャンチャネルの基礎が参考になります。

こちらにも固有の弱点があります。最大の問題は、「抜けた」という事実だけではダマシと本物の動き出しを区別できないことです。瞬間的にヒゲだけが水準を越えて戻る値動きは頻繁に起こり、これを毎回拾うと約定だけが積み上がります。用語と典型パターンの整理はブレイクアウトとダマシの基礎にまとめました。

もう一つは、参照本数の取り方で判定の回数が大きく変わることです。本数を短くすれば水準は価格に近づき、判定は頻発します。長くすれば水準は遠のき、判定は稀になります。突破基準は単体では「回数の多さ」を調整するつまみでしかなく、質を担保する仕組みを持ちません。

なぜこの組み合わせか

この2つを重ねる意味は、時期の絞り込みと水準の定義という、重複しない役割を分担させることにあります。収縮の検出が「今は狙う場面か」を判断し、突破基準が「どこを越えたら判定するか」を定義します。片方だけでは埋まらない空白を、もう片方が持っているという関係です。

実際の効き方は次の3点に整理できます。

ただし、この構成で解決できない部分もはっきりしています。収縮の判定は過去の値幅の集計に基づくため、状態の変化に対して必ず遅れます。また、拡張が始まったとしてもその方向は事前には分かりません。経済指標の発表など外的要因で一瞬だけ値幅が広がる場面は、性質が違う動きとして別途扱う必要があります。判定軸をさらに足したい場合の考え方はダマシを減らす二重確認の設計で扱っています。

パラメータをどう考えるか

決める値は多くありません。数を絞り、それぞれが何を動かすのかを理解したうえで検証するほうが、結果を解釈しやすくなります。

「この数値が正解」という組み合わせはありません。挙動はバックテストの基礎の手順で確かめる工程が前提になります。特に、少し値を変えただけで結果が大きく振れる設定は、その水準に依存しすぎていないかを疑う視点を持っておきたいところです。

cBot化する際の考慮点

判定の理屈は単純ですが、ブレイクアウトは発注周りの条件が結果を左右しやすい設計です。実装で気を配る点を整理します。

骨組みを疑似コードで示します。

// OnBar内: 確定足の値だけで判定する
double atr    = _atr.Result.Last(1);
double atrAvg = _atrAvg.Result.Last(1);   // ATR自身の長期平均
if (double.IsNaN(atr) || atr <= 0 || atrAvg <= 0) return;

// 1) 収縮しているか(絶対値ではなく比率で見る)
if (atr / atrAvg >= squeezeRatio) { _fired = false; return; }

// 2) 直近レンジの上下端を確定足から求める
double upper = double.MinValue, lower = double.MaxValue;
for (int i = 1; i <= lookback; i++)
{
    upper = Math.Max(upper, Bars.HighPrices.Last(i));
    lower = Math.Min(lower, Bars.LowPrices.Last(i));
}

// 3) 余白を加えた突破判定(ヒゲだけの接触を除外する)
double buffer = atr * breakBuffer;
double close  = Bars.ClosePrices.Last(1);
bool up   = close > upper + buffer;
bool down = close < lower - buffer;
if ((!up && !down) || _fired) return;
_fired = true;   // 同一レンジでの再判定を抑止する
// この先でストップ幅 → ロット → 発注の順に処理する

実装の流れ

処理を上流から並べると、次のようになります。

  1. 確定足の取得: OnBarで前足までの値を取り出し、形成中のバーによる判定のブレを避けます。
  2. ボラティリティ水準の判定: ATRを自身の長期平均と比べ、収縮している場面かどうかを相対値で確認します。
  3. 上下端の算出: 参照本数の範囲で高値の最大と安値の最小を求め、突破基準の水準を確定します。
  4. 突破判定: ATRの一定倍を余白として上乗せし、その外側へ終値が出たかどうかを見ます。
  5. リスク幅とロットの算出: ATRの倍率からストップ幅を決め、リスク許容額から数量を逆算して刻みに丸めます。利確側の考え方はATRベースの利確幅設計にまとめています。
  6. 発注と管理: 発注後はフラグを立てて多重エントリーを抑止し、判定時のATRと水準をログへ残して後から検証できるようにします。

確定足の取得からボラティリティ判定、上下端の算出、突破判定、リスク算出、発注までの処理フロー図

どう活用するか

「時期を絞る指標」と「水準を定義する指標」を分けて設計する骨格は、収縮の判定材料をバンド幅に置き換えても、突破基準を前日の高値・安値に置き換えても崩れません。自分で組んでみたい方は、Claude Codeを併走させたcBot開発の設計メモとして、本記事の構成をそのまま流用してみてください。時間帯ごとの値幅の傾向を先に把握しておきたい場合は、曜日別ボラティリティヒートマップの設定ガイドも合わせて役立ちます。作るより相談したいという方に向けては、ai-programming.xyzで個別の開発相談を承っています。体系的に学びたい方は、スクールでこうした判定とリスク設計の実装を段階的に学べます。

本記事は一般的な情報提供を目的としています。投資助言ではありません。 取引判断はご自身の責任で行ってください。