Aroonとドンチャンチャネルを組み合わせる考え方 — 同じ高値安値を「時間」と「価格」で読み分ける

ドンチャンチャネルは、直近n本の最高値と最安値をそのまま線として引いた指標です。Aroonは、その最高値・最安値を「何本前につけたか」という経過本数に変換した指標です。素材はまったく同じで、出力する軸だけが違います。ドンチャンチャネルは価格軸に、Aroonは時間軸に投影しているという関係です。

この関係を意識しないまま2つを重ねると、条件を2つ書いたつもりで実質1つしか書けていない、という設計になりがちです。本記事では、まず両者が独立していないという前提を確認したうえで、それでも役割分担が成立する使いどころと、cBotへ落とし込む際の実装上の論点を整理します。特定の設定が成果を保証するという趣旨の記事ではありません。

上段に価格とドンチャンチャネルの上下限、下段にAroon UpとAroon Downを配置し、両方が低位に沈む停滞局面と、上限更新でAroon Upが跳ね上がる局面を左右で対比した模式図

ドンチャンチャネルの役割

ドンチャンチャネルは、直近n本の最高値を上限、最安値を下限として2本の線を引き、その内側を「これまでの値動きが収まってきた範囲」として示します。指標そのものの成り立ちはドンチャンチャネルの基礎にまとめています。

この組み合わせで担わせるのは、境界の水準を数値として与えるという仕事です。上限がいくらで、下限がいくらで、現在値がその間のどこにいるのか。いずれもチャートを見なくても数値で取り出せるため、条件分岐にそのまま書き下せます。

単独使用時の限界は2つあります。ひとつは、境界が過去n本の極値そのものである以上、たった1本の大きなヒゲが境界を長期間支配してしまう点です。もうひとつは、線が水平に伸びている状態と、じわじわ切り上がっている状態を、上限の値だけでは区別できない点です。「いまの境界がどれくらい古いものなのか」という情報を、チャネルは数値として持っていません。

Aroonの役割

Aroonは、直近n本の中で最高値をつけた足からの経過本数をAroon Up、最安値をつけた足からの経過本数をAroon Downとして、それぞれ0〜100に換算します。最高値が直近足なら100、n本前についたまま更新がなければ0に近づきます。基礎的な読み方はAroonインジケーターの基礎を参照してください。

ここでAroonに担わせるのは、境界がいつ作られたかという鮮度の情報です。チャネルが数値で答えられない「その上限は最近ついたものか、それとも置き去りにされた古い高値か」を、Aroonは経過本数として持っています。

単独使用時の限界は、更新の大きさをまったく持たないことです。前回高値を0.1だけ上回った足でも、大きく飛び抜けた足でも、Aroon Upは同じく100になります。値幅の情報が落ちている以上、Aroon単体で「どれくらいの更新だったか」は復元できません。また値は経過本数の比率なので、連続的に滑らかに動くのではなく、更新が途絶えるたびに一定幅ずつ階段を降りるように推移します。

なぜこの組み合わせか

最初に確認しておきたいのは、この2つが独立した確認になっていないことです。価格が上限を更新した瞬間、その足が直近n本の最高値になるのですから、定義上Aroon Upは100になります。「チャネル上限を上抜けし、かつAroon Upが高い」という条件は、書き手の感覚では二重確認でも、実際には同じ事実を2回述べているだけです。ダマシ対策として別系統の情報を重ねたいのであれば、ブレイクアウトとダマシの基礎で扱った値幅や上位足など、素材の違う指標を別途用意する必要があります。

そのうえで、この組み合わせが意味を持つのは、Aroonをブレイクの瞬間ではなく、その前後の文脈を読む側に配置したときです。

補完関係を一言でまとめると、境界の「位置」と「作られた時期」を1組にすることで、ブレイクを一点の出来事ではなく経過として扱えるようになる、という構図です。一般論として、整理局面と更新継続局面を仕分けるための状態分類として機能することが期待できます。

ただしトレードオフは明確です。素材が同じである以上、この組み合わせは新しい情報源を足すものではなく、既にある情報の読み替えを増やす構成にすぎません。得られるのは分類の解像度であって、独立した裏付けではない、という点は最初から織り込んでおくのが現実的です。

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

正解の数値はなく、検証を前提に設計上の分岐だけ整理します。

期間をそろえるか、ずらすかが最初の判断です。両者を同じnにそろえると、Aroonはチャネルの内部状態を説明する変数になり、解釈が一意に定まります。一方、Aroonだけ長めに取ると、短い期間のチャネルで起きたブレイクを、より長い更新履歴の中に位置づける読み方になります。前者は構造がわかりやすく、後者は文脈の幅が広がる、という性格の違いです。

Aroonの閾値には注意点があります。Aroonは経過本数の比率なので、期間を変えると1本あたりの刻み幅も変わります。期間25なら1本が4ポイント、期間50なら2ポイントです。閾値だけを固定したまま期間を動かすと、同じ数値が違う意味を持ってしまいます。

時間足によっても挙動は変わります。短い時間足ほど極値の更新頻度が上がるため、Aroonが高位に張り付く時間が長くなる傾向があります。いずれの設定も決め打ちにせず、バックテストで自分の対象銘柄と時間足での分布を確かめてから採用する流れが安全です。

cBot化する際の考慮点

cTraderのcBotとして実装する場合、この組み合わせに固有の落とし穴がいくつかあります。

当足を境界計算に含めない: 最高値の計算対象に評価中の足そのものを入れると、上限は常にその足の高値以上になります。すると「終値が上限を上回る」という条件は原理的に成立しなくなります。境界は評価対象の足より前のn本から作る、と決めておく必要があります。

両者で同じ窓を使う: 境界を当足抜きで計算しているのにAroonは当足込みで取得している、といった不一致があると、2つの指標が別の窓を見ている状態になります。素材が同じであることがこの組み合わせの前提なので、参照範囲の食い違いは設計そのものを崩します。

同値の扱い: 直近n本の中に同じ高値が複数並んだ場合、最も古い足を採用するか、最も新しい足を採用するかでAroonの値は変わります。既製の指標を使う場合はその実装の定義を確認し、自前で書く場合は定義を明文化しておくと、後から挙動を追いやすくなります。

更新の連続に対する多重発火: 上限の更新は、勢いのある局面では何本も連続して起こります。「初回の上抜けだけを拾う」のか「更新が続く限り評価し続ける」のかを決めず状態フラグも持たせないと、意図しない回数だけ処理が走ります。

ウォームアップと計算負荷: 境界の算出には当足を除いてn本、比較用の足を含めるとn+1本以上が必要です。また極値の探索は素朴に書くと足ごとにn回の走査になります。複数銘柄を同時に回す構成では、直前の結果を保持して差分だけ更新する形も検討対象になります。

private Aroon _aroon;
private const int Period = 25;

protected override void OnStart()
{
    _aroon = Indicators.Aroon(Period);
}

protected override void OnBar()
{
    if (Bars.Count < Period + 2) return;

    // 評価対象は直前の確定足 Last(1)。境界はそれより前の Period 本から作る
    double upper = double.MinValue;
    double lower = double.MaxValue;
    for (int i = 2; i <= Period + 1; i++)
    {
        upper = Math.Max(upper, Bars.HighPrices.Last(i));
        lower = Math.Min(lower, Bars.LowPrices.Last(i));
    }

    double aroonUp = _aroon.Up.Last(1);
    double aroonDown = _aroon.Down.Last(1);
    if (double.IsNaN(aroonUp) || double.IsNaN(aroonDown)) return;

    bool brokeUp = Bars.ClosePrices.Last(1) > upper;   // イベント
    bool stagnant = aroonUp < 30 && aroonDown < 30;    // 状態(両端とも更新が古い)
    // イベントと状態を組にして、後段のフィルターへ判断材料として渡す
}

実装の流れ

処理は、境界の算出から状態分類、イベント検出へと一方向に進む構造に整理できます。

  1. 入力: 対象銘柄と時間足を決め、確定足の高値・安値・終値を取得する
  2. 境界の算出: 評価対象の足を除いた直近n本から上限と下限を求める
  3. 鮮度の算出: 同じ窓に対応するAroon UpとDownを取得する
  4. 状態分類: 両方が低位なら整理局面、片側だけ高位なら偏りのある局面、として分類する
  5. イベント検出: 評価対象の終値が上限または下限を越えたかを判定する
  6. 出力: 状態とイベントの組を記録し、値幅や上位足など別系統のフィルターへ渡す

状態分類を先に済ませてからイベントを評価する順序にしておくと、「どの状態で発生したブレイクだったのか」がログにそのまま残ります。検証時に局面別の傾向を後から切り分けられるので、条件を足し引きする作業が進めやすくなります。

確定足の取得から、当足を除いた境界算出、Aroonによる状態分類、ブレイク検出、別系統フィルターへの受け渡しまでを順に示した戦略フロー図

どう活用するか

自作派の方は、Claude Codeを使ったcBot開発の設計メモとして、本記事の「同じ素材を別の軸に投影している指標は、独立した確認にならない」という視点をそのまま流用してみてください。手持ちのロジックに重ねている条件が、本当に別の情報を見ているかを点検する物差しになります。

委託派の方は、ai-programming.xyzへ開発相談を持ち込む際に、「境界の水準と更新の鮮度を分けて扱いたい」という一文を添えておくと、要件整理の往復が短くなります。体系的に学びたい方にとっては、極値の窓をどう切るかという本記事の題材は、時系列データの参照範囲を意識する練習として扱いやすいテーマです。実装の参考になれば幸いです。

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