ATRと移動平均を組み合わせる考え方 — 方向は移動平均、損切り幅はATRに分担させる設計
「どちらへ動きやすいか」を示す移動平均と、「1本あたりどれだけ動くのが普通か」を示すATR。本記事では、この2つを組み合わせ、エントリー方向の判断と損切り幅の設計を別々の指標に分担させる考え方を整理します。移動平均だけでcBotを組むと、方向は決まってもストップをどこに置くかが決まらず、結局は固定幅で妥協することになりがちです。そこにATRを持ち込むと、リスク幅が相場の状態に合わせて自動的に伸び縮みします。想定読者は、トレンドフォロー型のcBotを組みたい方、銘柄や時間足を変えるたびに設定を作り直している方です。特定の設定が成果を保証するという話ではなく、設計の骨組みを共有することが目的です。
移動平均の役割
移動平均(Moving Average)は、一定期間の価格を平均してならした線で、細かな上下動を落とした大まかな方向を示します。読み方の基本は移動平均線の基礎にまとめています。線の傾きが上向きで価格がその上にあれば上方向の流れが優勢、逆なら下方向が優勢、という素直な読み方ができます。条件が「傾き」と「上下関係」という2つの比較に還元できるため、コードへ落とし込みやすいことも実装上の利点です。
ただし移動平均単独には、はっきりした限界が2つあります。1つは、方向感の乏しい局面で線と価格が何度も交差し、同じ強さのシグナルが繰り返し出てしまうことです。トレンドとレンジの違いについてはトレンドとレンジの基礎も参考になります。もう1つは、距離の情報をまったく持たないことです。「上方向が優勢」とは言えても、その判断が崩れたと見なすまでにどれだけの値幅を許容すべきかについて、移動平均は何も答えてくれません。ストップ幅を固定値で決めてしまう設計は、この空白を埋めるための妥協であることが多いのです。
ATRの役割
ATR(Average True Range)は、一定期間の値動きの振れ幅(True Range)を平均した指標で、「この銘柄・この時間足では1本あたりどの程度動くのが普通か」を数値として表します。詳しくはATRの基礎で解説しています。
ATRの持ち味は、値幅を測るための物差しになれることです。相場が荒くなればATRは大きくなり、静かになれば小さくなるため、同じ「ATRの一定倍」という指定でも、実際の値幅は局面ごとに変わります。ストップ幅やトレール幅をこの物差しで表現しておくと、設定を触らないまま環境の変化に追従できます。
一方でATRの限界も明確です。ATRは方向をまったく持ちません。値動きが大きいことは分かっても、それが上下どちらへの動きなのかは示さないため、ATRだけではエントリーの向きが決まりません。また、ATRの絶対値は銘柄や時間足によって桁が違うため、「この値が大きい」と単体で判定するのは難しく、後述するように相対的な比較が必要になります。
なぜこの組み合わせか
この組み合わせの核心は、「方向の判断」と「値幅の設計」を別々の指標に分担させることにあります。移動平均が「どちらを向くか」を決め、ATRが「どれだけの幅を見込むか」を決める。互いに欠けている情報をもう一方が持っているため、役割が重複しません。
具体的には、次の3つの場面でATRが働きます。
- リスク幅の設計: エントリー価格からATRの一定倍だけ離した位置をストップの目安にします。静かな局面では自然と狭く、荒い局面では広くなり、通常の振れで建玉が閉じてしまう度合いを抑える設計になります。
- ロットサイズとの連動: ストップ幅が決まれば、リスク許容額から必要なロットを逆算できます。幅が広い局面ではロットが小さくなり、口座に対するリスクを一定に保ちやすくなります。考え方はロットサイズの基礎を参照してください。
- 環境フィルター: ATRが普段と比べて極端に小さい局面では、移動平均のクロスが起きても値幅が伸びにくく、見送りの判断材料になります。逆に極端に大きい局面ではストップ幅が想定を超えて広がるため、ロットを絞るか見送るかの判断が必要です。
副次的な効果として、設定の移植性が上がります。値幅をATRの倍数で表現しておけば、同じパラメータのまま別の銘柄や時間足へ持っていっても、意味がある程度保たれます。固定幅の設計では、対象を変えるたびに数値を作り直す作業が発生しがちです。
もっとも、この組み合わせが移動平均の弱点をすべて埋めるわけではありません。方向感の乏しい局面でクロスが繰り返される問題は、ATRでは解消できません。ATRが担うのは値幅の設計であって、シグナルの真偽の判定ではないからです。ダマシそのものを減らしたい場合は、別の判定軸を足す必要があります。この点はダマシ回避の二重確認で扱っています。
パラメータをどう考えるか
決めるべき値はそれほど多くありません。数を絞り、それぞれの意味を理解したうえで検証するほうが、結果を解釈しやすくなります。
- 移動平均の期間と種類: 期間を長くするほど反応は鈍くなり、シグナルの回数は減ります。単純移動平均(SMA)は素直に平均をとり、指数移動平均(EMA)は直近の価格に重みを置いて反応します。方向のフィルターとして使うなら、多少鈍くても向きが安定するほうが扱いやすい場合があります。
- ATRの期間: 14が広く使われる出発点です。短くすれば直近の変動に敏感になりますが、ストップ幅が1本ごとに大きく変わりやすくなります。物差しとして使う以上、ある程度の安定性は必要です。
- ATRの倍率: ストップ幅を決める係数です。小さくすれば通常の振れでも建玉が閉じやすく、大きくすれば1回あたりの損失許容が増えます。利確側の倍率設計はATRベースの利確幅設計で詳しく扱っています。
- ボラティリティ水準の判定基準: ATRの絶対値ではなく、ATR自身の長期平均との比で見ると、銘柄や時間足をまたいでも同じ基準を使い回せます。
「この数値が正解」という組み合わせは存在しません。時間足と狙う値動きの性質に合わせ、バックテストで挙動を確かめる工程が前提になります。特にATRの倍率は挙動への影響が大きいため、少し変えただけで結果が大きく振れる場合は、その設定に依存しすぎていないかを疑う視点も必要です。
cBot化する際の考慮点
方向判定そのものは単純ですが、ATRを絡めたリスク設計は発注直前の処理と密接に関わります。実装で気を配りたい点を整理します。
- 確定足を使う: 形成中のバーではATRも移動平均も更新され続けます。判定はOnBarで行い、
Last(1)の確定値を使うと挙動が安定します。 - 計算順序: 方向判定 → ATR取得 → ストップ幅の算出 → ロット計算 → 発注、の順に固定します。ロットはストップ幅に依存するため、順序を入れ替えると成立しません。
- ブローカー制約: 算出したストップ幅がブローカーの最小距離を下回ると、発注が拒否されることがあります。スプレッドの分も含め、幅に下限を設けておきます。
- ロットの丸め: 逆算したロットはそのままでは発注できません。
Symbol.NormalizeVolumeInUnitsで刻みに合わせ、最小ロットを下回る場合は見送る分岐を入れます。 - データ不足と異常値: 起動直後は指標の計算に必要な本数が揃っていません。ATRが0やNaNになるケースを含め、値が取れないときは判定を保留します。ゼロ除算はロット計算を破綻させる典型的な原因です。
- トレール更新の頻度: ATRでトレール幅を決める場合、毎ティックATRを取り直すとストップが小刻みに動き続けます。ATRは足の確定時に固定し、更新は一方向のみに限る設計が安全です。基本的な考え方はトレーリングストップの基礎にまとめています。
判定からロット算出までの骨組みを疑似コードで示します。
// OnBar内: 確定足の値で方向を判定する
double ma = _ma.Result.Last(1);
double maPrev = _ma.Result.Last(2);
double close = Bars.ClosePrices.Last(1);
double atr = _atr.Result.Last(1);
if (double.IsNaN(atr) || atr <= 0) return; // 値が取れない足は保留
// ボラティリティ水準はATR自身の平均との比で相対評価する
double atrAvg = _atrAvg.Result.Last(1);
if (atrAvg > 0 && atr / atrAvg < lowVolRatio) return; // 静かすぎる局面は見送り
bool up = ma > maPrev && close > ma;
bool down = ma < maPrev && close < ma;
if (!up && !down) return;
// ストップ幅 → ロットの順に決める(順序を崩さない)
double stopDistance = atr * atrMultiplier;
double stopInPips = stopDistance / Symbol.PipSize;
double riskAmount = Account.Balance * riskPercent / 100.0;
double units = riskAmount / (stopInPips * Symbol.PipValue);
var volume = Symbol.NormalizeVolumeInUnits(units, RoundingMode.Down);
if (volume < Symbol.VolumeInUnitsMin) return; // 最小ロット未満は発注しない
実運用ではこれにスプレッドの加味、同時保有数の制限、時間帯フィルターなどを重ねて、細部を詰めていくことになります。
実装の流れ
処理を上流から並べると、次のようになります。
- 足の確定: OnBarで確定バーの値のみを取得し、判定のブレを防ぎます。
- 方向判定: 移動平均の傾きと価格の上下関係から、上下どちらの流れが優勢かを判定します。どちらでもなければ、ここで処理を終えます。
- ボラティリティ水準の確認: ATRを長期平均と比べ、極端に静かな局面や荒い局面を見送りに回します。
- リスク幅の算出: ATRに倍率を掛けてストップ幅を求め、スプレッドとブローカーの制約を加味して下限を確保します。
- ロット計算と発注: リスク許容額をストップ幅で割ってロットを逆算し、刻みに丸めてから発注します。
- 管理と記録: 建玉後はATRベースのトレール幅で追随させ、判定時のATRと倍率をログに残して、後から検証できるようにします。
どう活用するか
「方向を決める指標」と「値幅を決める指標」を分けて設計する骨格は、移動平均を一目均衡表やドンチャンチャネルに置き換えても崩れません。自分で組んでみたい方は、Claude Codeを併走させたcBot開発の設計メモとして、本記事の構成をそのまま流用してみてください。ATRベースのストップ幅をチャート上で確認したい場合は、ATR Trailing Stop Visualizerの紹介記事も参考になります。作るより相談したいという方は、ai-programming.xyzで個別の開発相談を承っています。体系的に学びたい方に向けては、スクールでこうしたリスク設計の実装を段階的に学べます。
本記事は一般的な情報提供を目的としています。投資助言ではありません。 取引判断はご自身の責任で行ってください。