ROCとATRを組み合わせる — 変化率をボラティリティで正規化して勢いを比べる設計

同じ「1パーセント動いた」でも、静かな相場とざわついた相場では意味が変わります。ROC(Rate of Change/変化率)は一定期間前と比べて価格が何パーセント動いたかを示し、ATR(Average True Range)は1本あたりの平均的な値幅を示します。この2つを重ねる目的は、シグナルを1つ増やすことではありません。ROCが示す「動きの速さ」を、ATRが示す「その相場では何が普通か」で割り、銘柄や時間足をまたいでも比較できる形に整えることにあります。複数銘柄を1つのcBotで回したい方や、対象を変えるたびに閾値を作り直している方に向けた内容です。特定の設定が成果を約束するという話ではなく、物差しの作り方を言語化することが目的です。

上段に価格、下段にROCを配置し、値幅が小さい局面と大きい局面でROCの振れが同水準になる様子を対比した模式図

ROCの役割

ROCは、n本前の終値と現在の終値の差を、n本前の終値に対する割合として表した指標です。ゼロを中心に上下する形で描かれ、プラス圏なら基準の足より価格が高い、マイナス圏なら低いという素直な読み方になります。方向の確認役と組み合わせる使い方はROCと移動平均の組み合わせで扱っています。

この構成でROCに任せるのは、動きの速さを1つの数値に落とすことです。何本かけてどれだけ進んだかを割合で表せるため、値動きの勢いを時系列で比べられます。

単独使用時の限界は、その数値が置かれている文脈を持たないことです。ROCはRSIのように0〜100の固定レンジに収まらないため、「この値を超えたら強い」という閾値が銘柄ごと・時間足ごとに変わってしまいます。ある銘柄で妥当だった数値を別の銘柄にそのまま持ち込むと、判定の厳しさが意図せず変わります。加えて、比較対象がn本前のたった1本である以上、その基準の足が大きく動いていた場合、現在の値動きが静かでもROCだけが跳ねることがあります。

ATRの役割

ATRは、値幅(True Range)を一定期間平均した指標で、「この銘柄・この時間足では1本あたりどの程度動くのが普通か」を数値化します。指標そのものの読み方はATRの基礎にまとめています。

ここでATRが担うのは、シグナルを出すことではなく、比較の分母になることです。ATRは上下どちらの方向にも肩入れせず、相場の「普段の歩幅」だけを示します。方向の情報を持たないという性質が、ここではむしろ都合よく働きます。

ATR単独の限界も明確です。ATRは価格と同じ単位を持つ絶対値なので、値幅そのものを銘柄間で比べても意味がありません。指数と通貨ペアではATRの桁が違い、大小を並べて論じられないためです。銘柄をまたいで扱いたい場合は、ATRを価格で割って割合に直すか、後述するようにROC側の分母として使う形に持ち込む必要があります。

なぜこの組み合わせか

両者は、片方が分子、もう片方が分母という関係で噛み合います。ROCが「どれだけ進んだか」、ATRが「1本あたりどれだけ進むのが普通か」を持っているので、割り算をすると 「普段の歩幅の何個分を、この期間で進んだのか」 という無次元の値になります。

作り方は2通りありますが、どちらも意味は同じです。

この形にすると、図1のような場面の区別がつきます。値幅の小さい局面で出た同じ変化率は「普段の歩幅から大きく逸脱した動き」として大きな値になり、荒れた局面で出た同じ変化率は「普段の範囲に収まる動き」として小さな値に落ち着きます。ROCの生の数値だけを見ていると同じに見える2つが、別物として整理されるわけです。一般論として、ATRがROCの文脈を補う関係になります。

実務上の効き目は移植性に表れます。閾値が無次元になるため、銘柄や時間足を変えても同じ数値を出発点として使いやすくなり、対象ごとに設定表を作り直す手間が減ります。レンジとトレンドの切り分けを別の指標に任せている構成でも、その前段の「動きの大きさ」の評価だけを共通化できます。

一方でトレードオフもあります。第一に、この値は方向を持たないため、これ単独ではエントリー判定になりません。符号は分子から受け継ぎますが、相場の構造は何も見ていないので、方向の確認役は別に必要です。第二に、分母が急変する局面では比が不安定になります。ボラティリティが急拡大した直後はATRの追随が遅れ、比が一時的に過大に出ることがあります。第三に、ROCもATRも同じ価格系列から作られており、情報源としての独立性は高くありません。判断材料の総量が増えるというより、既存の材料の読み方が揃うと考えるのが実態に近い理解です。

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

決めるのは、ROCの期間n、ATRの期間、そして閾値の3つです。いずれも正解があるものではなく、方向性だけ整理します。

ROCの期間nは、短くすれば直近の変化に敏感になり、長くすれば大きな流れを拾う代わりに反応が遅れます。ATRの期間は分母側なので、nより長めに置いて基準を安定させる考え方が素直です。分母が分子と同じ速さで動くと、比の変化が打ち消し合って何も見えなくなることがあります。

閾値は、この設計でいちばん扱いを間違えやすい部分です。無次元になったとはいえ、適切な水準まで自動で決まるわけではありません。固定値を置くより、過去一定期間の正規化値の分布を取り、その中で上位のどのあたりかという相対評価に置き換えるほうが、対象を変えたときの挙動が安定します。分位で見る発想はATR Percentile Rankの設定ガイドでも扱っている考え方です。

どの値を採用するにせよ、バックテストで自分の銘柄・時間足での挙動を確かめる工程は省略できません。この設計は分子と分母の両方に期間があるため、同時に動かすとどちらが効いたのか分からなくなります。片方を固定して振る進め方が現実的です。

cBot化する際の考慮点

割り算が1つ入るだけですが、実装上の注意点はその割り算に集中します。

計算順序: ATRの確定値を取得 → ROC(または終値の差)を取得 → 正規化 → 閾値判定、の順に固定します。正規化した値をログに残しておくと、後から閾値を見直すときの材料になります。

ゼロ除算と極小ATR: 値動きがほとんど無い時間帯やデータ欠損の直後は、ATRがゼロ付近まで落ちることがあります。そのまま割ると比が発散し、異常な値がそのまま判定に流れ込みます。下限を設けて、それを下回ったら判定自体を見送る安全弁を必ず入れます。

確定足で揃える: 形成中のバーはROCもATRも値が動き続けます。両方をLast(1)の確定足に統一し、参照タイミングをずらさないようにします。

履歴不足: 必要本数はROCの期間とATRの期間の大きいほうが基準です。起動直後はBars.Countを確認し、足りなければ判定に進みません。

ギャップとイベント: 週明けや指標発表の直後は分子だけが跳ね、分母のATRは遅れて追随します。この時間帯を除外するフィルターと併用するか、比に上限を設けて外れ値として扱う設計を検討する価値があります。

// 例: 変化率をATRで正規化してから判定する(すべて確定足ベース)
var atr = Indicators.AverageTrueRange(AtrPeriod, MovingAverageType.Exponential);

if (Bars.Count < Math.Max(RocPeriod, AtrPeriod) + 5) return;   // 履歴不足のガード

double atrValue = atr.Result.Last(1);
double minAtr   = Symbol.PipSize * MinAtrPips;                  // 極小ATRの下限
if (double.IsNaN(atrValue) || atrValue < minAtr) return;        // ゼロ除算の回避

double change = Bars.ClosePrices.Last(1) - Bars.ClosePrices.Last(1 + RocPeriod);
double normalized = change / atrValue;                          // 何ATR分動いたか(無次元)

bool strongMove = Math.Abs(normalized) > MoveThreshold;         // 閾値は検証対象
bool upward     = normalized > 0;                               // 符号は分子由来

計算負荷はどちらの指標も軽く、OnBarでの運用なら問題になりません。このnormalizedを、エントリー可否そのものではなく「いまの動きの大きさ」を返す部品として切り出しておくと、方向判定を差し替えるときに影響範囲を小さく保てます。

実装の流れ

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

  1. 入力: 対象銘柄と時間足を決め、確定足で終値系列とATRを更新します。
  2. 算出: 同じ足に対して、変化幅(またはROC)とATRをそれぞれ求めます。
  3. 正規化: 変化幅をATRで割り、無次元の値に変換します。ここで下限ガードを通します。
  4. 閾値判定: 正規化した値の絶対値を閾値と比べ、動きの大きさを分類します。
  5. 方向の整合: 符号と、移動平均などの方向フィルターが一致するかを確認します。整合しなければ見送りへ分岐します。
  6. リスク設計: 損切り幅とロットを決めて発注・管理へ引き渡します。幅を決める際もATRを使えますが、判定用と決済用でパラメータを分けておくと検証が楽になります(ロットサイズの基礎)。

確定足の受信からROCとATRの算出、ATRによる正規化、閾値判定、方向フィルターとの整合確認、リスク幅とロットの決定へ進む処理フロー図

正規化を判定より前に置くことがポイントです。順序が逆になると、対象ごとに閾値を作り直す作業が残り、共通化の利点が失われます。

どう活用するか

「絶対値を無次元に直してから判定する」という型は、ROCとATRに限らず応用が利きます。自作派の方は、Claude Codeを使ったcBot開発の題材として、既存ロジックの閾値のうち価格単位のものを洗い出し、ATR基準に置き換える練習から始めてみてください。移動平均による方向判定と組み合わせれば、そのまま2層構成として成立します。

委託派の方は、ai-programming.xyzへの開発相談時に「複数銘柄で同じ閾値を使いたい」という要件を先に共有しておくと、設計の方針が固まりやすくなります。教育派の方は、同じロジックを正規化あり・なしで実装し、対象を変えたときに挙動がどう変わるかを比較する課題として扱うと、パラメータの移植性という論点を手を動かしながら確認できます。

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