平均足とATRを組み合わせる考え方 — 保有の継続判定と損切り幅を実勢価格で設計する
平均足(Heikin Ashi)で流れを見ながらポジションを持つ設計にすると、多くの場合「損切りと手仕舞いを何で決めるか」という問題に行き着きます。平均足は計算で作り直された足であり、チャート上に描かれる高値・安値は実際に約定する価格とは一致しないためです。本記事では、保有を続けるかどうかの判断材料を平均足に、損切り幅とトレーリングの距離をATR(アベレージ・トゥルー・レンジ)に割り当てる組み合わせを整理します。エントリーの選別よりも「持ってからの管理」に重心を置いた構成で、平均足ベースのcBotを設計する方や、決済ロジックの考え方を整理したい方を想定しています。特定の設定が成果につながることを示すものではありません。
平均足の役割
平均足は、終値を当該足の4本値の平均に、始値を前の平均足の始値と終値の中間に置き換えて描く手法です。計算の詳細は平均足の基本で解説しています。置き換えによって細かな上下動が吸収され、同じ色の足が続きやすくなるため、「いまの流れが続いているか」を色と連続本数で表現できます。保有中のポジションに対して「まだ持ち続ける理由があるか」を問う用途と相性の良い性質です。
単独で使う場合の限界は大きく3つあります。第一に、平滑化の代償として、色の反転は実際の転換より遅れて現れます。反転を見てから手仕舞うと、そのぶん含み益を相場に返す場面が出てきます。第二に、方向感の乏しい局面では色が短い周期で入れ替わり、反転を手仕舞いの合図にすると出入りが増えます。第三に、実装上もっとも影響が大きいのが、平均足の4本値が実勢価格ではない点です。平均足の安値の少し下に損切りを置いたつもりでも、実際の価格がどこにあるかとは別の話になります。平均足は「状態を読む道具」であり、「価格を決める道具」ではないと割り切ると扱いやすくなります。
ATR の役割
ATRは、前の足の終値との差も含めた1本あたりの実質的な値動き幅(トゥルーレンジ)を、一定期間で平均した指標です。基本はATRとはにまとめています。
ATRの特徴は、方向を持たず、出力が価格と同じ単位で得られることです。「ATRの何倍」という指定がそのまま値幅として使えるため、損切りまでの距離やトレーリングの間隔を、相場の荒さに合わせて伸縮させる設計に向いています。静かな時間帯には近く、荒れた時間帯には遠くに置かれるので、固定幅で起きやすい「静かな相場では広すぎ、荒い相場ではノイズで刈られる」というずれを緩和する材料になります。トレーリングの仕組み自体はトレーリングストップとはで整理しています。
一方でATRは、いつ入るか・いつまで持つかについては何も教えてくれません。値動きが大きいことは分かっても、それが流れの継続なのか転換の前触れなのかは区別できないのが、単独使用時の限界です。また、ATRの距離だけでトレーリングすると、流れが明らかに鈍っていても価格がストップに届くまでは保有が続くため、反応が一段遅くなる場面もあります。
なぜこの組み合わせか
2つを並べると、平均足は「状態」は読めるが「価格」を持たず、ATRは「価格の幅」は持つが「状態」を読めない、という対称的な関係になっています。欠けている部分を互いに受け持たせるのが、この組み合わせの骨格です。
1. 手仕舞いを二層に分ける
平均足の反転を「流れが崩れた可能性」を示すソフトな手仕舞い条件、ATRで算出したストップを「想定を超えて逆行した」ことを示すハードな損切りとして分離します。平均足の判定は確定足でしか行えないため、足の途中で急な逆行が起きたときには間に合いません。その空白を、ポジションに付与したATRベースのストップが埋めるという役割分担です。反対に、ストップに届く前に流れが鈍った場面では、平均足の反転が一段早い判断材料になります。
2. 損切りの基準を実勢価格に戻す
ストップ位置は、平均足ではなく実際の高値・安値とATRから計算します。たとえば買いポジションなら「実際の高値 − ATR × 倍率」をトレーリングの候補とし、有利な方向にだけ動かす形です。考え方はChandelier Exitに近く、可視化の例はATR Trailing Stop Visualizerでも扱っています。
3. 平均足の実体をATRで正規化する
平均足の実体(始値と終値の差)は価格単位なので、銘柄や時間帯が変わると大小を比較できません。実体をATRで割った比率にすると、「いまの足は普段の値動きに対して勢いのある足か」を共通の尺度で表せます。同じ陽線でも、比率の小さい足が続く場面は勢いの鈍化を疑う材料、比率の大きい足が並ぶ場面は流れが明確な状態と読む材料になります。エントリー条件にも保有継続の条件にも組み込める、汎用的な尺度です。
なお、この2指標には「そもそもトレンドが出ているか」を測る軸がありません。レンジ相場での出入りを抑えたい場合は、平均足とADXの組み合わせのように、強度の判定を別の層として重ねる拡張が検討対象になります。
パラメータをどう考えるか
ここに正解の数値はなく、以下は検証を始めるための方向性です。
平均足の連続本数: 平均足自体には期間パラメータがないため、実質的な調整項目は「何本の同色で流れありとみなすか」と「何本の反対色で手仕舞い候補とするか」です。反転を1本で判定すると反応は速くなる一方、方向感の乏しい局面で出入りが増えます。2本にすると落ち着く代わりに遅れます。エントリー側と手仕舞い側で本数を非対称にする設計も選択肢です。
ATRの期間と倍率: 期間は14本が出発点として広く使われます。短くすると直近の荒れに敏感になり、ストップ幅が頻繁に伸縮します。倍率は初期損切り用とトレーリング用で別々に持たせておくと調整しやすくなります。倍率を小さくすると早く刈られやすく、大きくすると含み益を返す幅が広がるというトレードオフがあり、適正は銘柄・時間足・想定保有時間によって大きく変わります。
実体/ATR比のしきい値: 比率の分布は銘柄と時間足で異なるため、決め打ちするより、過去データで分布を確認してから決めるほうが根拠を持ちやすくなります。
いずれも、細かく詰めるほど過去データに合わせ込むリスクが高まります。バックテストの基本を踏まえ、調整に使った期間とは別の期間で挙動を確かめてから採用を判断してください。
cBot化する際の考慮点
設計上の急所を5点挙げます。
ATRと損切りは通常の4本値から計算する: 平均足の4本値からATRを作ると、平滑化された分だけ幅が小さく出ます。ストップ計算の入力は実際の高値・安値・終値にそろえます。平均足表示のチャートにcBotを載せた場合に Bars がどの値を返すかは環境によって確認が必要なので、実装の最初に値をログへ出して、通常のローソク足と照合しておくと安全です。
平均足は自前で再計算し、ウォームアップを取る: 平均足は前の足の値を引き継ぐ再帰計算のため、計算を始めた位置によって序盤の値が変わります。起動時に過去の足をさかのぼって計算を進めておかないと、チャートに表示される平均足とcBot内部の色がしばらく一致しないことがあります。
判定は確定足、損切りはポジション側: 色の判定はOnBarで確定足に対して行い、損切りはポジションに付与したストップとして持たせます。OnTickで自前監視する方式は、接続断や再起動の間は機能しないためです。また、平均足の反転による手仕舞いは次の足で執行されるため、窓が空いた場面などでは想定と離れた価格になる場合があります。
ストップは不利な方向へ戻さない: ATRが拡大した足では、トレーリング候補が現在のストップより不利な位置に出ることがあります。有利な方向への更新だけを受け付ける条件を入れておきます。
丸めと最小距離: 計算結果はティックサイズに丸め、現在値との距離がブローカーの許容範囲に収まっているかを確認してから変更をかけます。
// 抜粋: 平均足は自前で更新し、ATR とストップは実際の4本値から計算する
private AverageTrueRange _atr;
private double _haOpen = double.NaN;
private double _haClose = double.NaN;
protected override void OnStart()
{
_atr = Indicators.AverageTrueRange(14, MovingAverageType.Exponential);
// 過去の足で平均足を先に計算しておく処理(ウォームアップ)は省略
}
protected override void OnBar()
{
double o = Bars.OpenPrices.Last(1), h = Bars.HighPrices.Last(1);
double l = Bars.LowPrices.Last(1), c = Bars.ClosePrices.Last(1);
double prevOpen = _haOpen, prevClose = _haClose;
_haClose = (o + h + l + c) / 4.0;
_haOpen = double.IsNaN(prevOpen) ? (o + c) / 2.0 : (prevOpen + prevClose) / 2.0;
double atr = _atr.Result.Last(1);
if (double.IsNaN(atr) || atr <= 0) return;
bool bullish = _haClose > _haOpen;
double bodyRatio = Math.Abs(_haClose - _haOpen) / atr; // 実体を ATR で正規化
var pos = Positions.Find(BotLabel, SymbolName);
if (pos == null || pos.TradeType != TradeType.Buy) return;
// トレーリング候補は実際の高値から算出し、有利な方向にだけ動かす
double candidate = RoundToTick(h - atr * TrailMultiplier);
if (pos.StopLoss == null || candidate > pos.StopLoss)
pos.ModifyStopLossPrice(candidate);
// 平均足の反転(bullish == false)はソフトな手仕舞い候補として別に扱う
}
BotLabel・TrailMultiplier・RoundToTick の定義と、現在値との最小距離チェックは省略しています。
実装の流れ
処理を段階に分けると、次の6つになります。
- 入力: 確定足の4本値を取得します
- 計算: 平均足を1本ぶん更新し、ATRを実際の4本値から取得します
- 環境判定(未保有時): 同色の連続本数と実体/ATR比が条件を満たすかを確認し、満たさなければ次の確定足を待ちます
- 初期損切り: エントリー候補が立ったら、ATR × 初期倍率で損切り距離を決め、ストップ付きで発注または通知します
- 保有管理: 確定足ごとにトレーリング候補を計算し、有利な方向にだけストップを更新します
- 手仕舞い: 平均足の反対色が規定本数続いたら手仕舞い候補とし、足の途中の急な逆行はATRストップに任せます
「状態判定(平均足)」「幅の計算(ATR)」「注文操作」を別々の関数に分けておくと、手仕舞い条件だけを差し替えたり、強度判定を前段に足したりする変更が局所的な修正で済みます。最初は発注せず、手仕舞い候補とストップ更新のタイミングをログに書き出すだけの構成で動かし、チャート上の見え方と照合する段階を挟むと、平均足の遅れがどの程度影響しているかを把握しやすくなります。
どう活用するか
自作する方は、「平均足は状態、ATRは価格」という役割分担と上の6段階を、そのままClaude Codeへの指示の骨格として使えます。とくにウォームアップとストップ更新の条件は抜けやすいので、要件として明記しておくと手戻りが減ります。開発を委託する方は、ai-programming.xyz への相談時に「手仕舞いをソフト条件とハードストップの二層にするか」「倍率を初期損切りとトレーリングで分けるか」を先に決めておくと、仕様のすり合わせが早く進みます。体系的に学びたい方には、再帰計算のウォームアップと片方向のストップ更新が、状態管理を学ぶ演習題材としてちょうどよい難易度です。
エントリー側の組み立て方は平均足とRSIの組み合わせ、利確幅の考え方はATRベースの利確幅設計もあわせて参照してみてください。
本記事は一般的な情報提供を目的としています。投資助言ではありません。 取引判断はご自身の責任で行ってください。