パラボリックSAR(Parabolic SAR)
パラボリックSAR は、現行トレンドが継続する限り追随し、価格が逆転すればストップと同時にドテンする、トレーリングと反転を組み合わせたメカニカルなルールです。レンジ相場では逆転を乱発するため単体運用には向きません。エントリーのシグナルではなく撤退のシグナルとして使うのが実務的です。

架空データによるイメージ図(実際の相場データではありません)。上昇中は価格の下、下降中は価格の上にSARが付き、逆転でドテンする例。
定義
パラボリックSAR(Stop And Reverse)は Wilder が1978年に New Concepts in Technical Trading Systems で発表しました。放物線(parabola)を描くように、時間経過とともに損切ラインが加速する構造です。
基本ロジック
- ロングポジション中は SAR を価格の下にプロットする。SAR にタッチしたら損切とドテンショート
- ショートポジション中は SAR を価格の上にプロットする。SAR にタッチしたら損切とドテンロング
- 常にどちらかのポジションを持つ(Stop and Reverse)
更新則
現行トレンド中(ロングを例とする)。
- EP(Extreme Point):現行トレンド中の最高値(ロング)または最安値(ショート)
- AF(Acceleration Factor):加速係数。新しい EP 更新のたびにステップ分増える
- 初期 AF = 0.02、EP 更新のたびに +0.02、上限 0.20
AF 更新のルール。
- 現行トレンドで EP を更新(高値更新または安値更新)するたびに AF += 0.02
- AF は上限 0.20 に達したらそこで固定
- トレンド反転(SAR タッチ)で AF を 0.02 にリセット
トレンド反転条件(ロングの場合)。
- 当日安値 ≤ SAR_t なら反転
- 反転時、新しい SAR = 反転前トレンド中の EP(直近高値)
- 新しい EP = 反転を起こした足の安値
- AF リセット = 0.02
Wilder 追加ルール。
- 反転直後の SAR は直前2本の高値(または安値)の最大(最小)にクランプする
- ロング中の SAR は当日と前日の安値より上にならない(少なくともどちらか低い方まで)
- 通常はこれを SAR ≤ min(前日安値, 前々日安値) と実装する
数式的意味
AF が徐々に上がることで、時間経過とトレンド継続に応じて SAR が価格に近づいていきます。放物線的な加速です。
- トレンド初期は SAR が緩やかに追随する
- トレンド継続で SAR が加速して価格に近づく
- トレンド終盤は SAR が価格にほぼ張り付き、少しの反落で反転する
パラメータと期間表
| パラメータ | 標準 | 意味 |
|---|---|---|
| AF 初期値 | 0.02 | 開始時の加速係数 |
| AF ステップ | 0.02 | EP 更新時の増分 |
| AF 上限 | 0.20 | 最大加速係数 |
Wilder のデフォルトは、実際に手計算で回して調整した実務値です。他のセットも試されていますが、標準は変えない前提です。
派生設定(実務ではあまり推奨されない)。
| 設定 | 特徴 |
|---|---|
| (0.01, 0.01, 0.10) | より緩やか。フェイクに強いが反応遅い |
| (0.02, 0.02, 0.20) | Wilder 標準 |
| (0.04, 0.04, 0.40) | より攻撃的。すぐに刈られる |
USD/JPY での時間足別の使い分け。
| 時間足 | 標準 | 主な用途 |
|---|---|---|
| 5分 | (0.02, 0.02, 0.20) | 短期スキャルのトレーリング(ノイズ多い) |
| 15分 | (0.02, 0.02, 0.20) | デイトレのトレーリング(レンジで多発反転) |
| 1時間 | (0.02, 0.02, 0.20) | トレンド追随、日中トレーリング |
| 4時間 | (0.02, 0.02, 0.20) | スイングトレーリング(良好) |
| 日足 | (0.02, 0.02, 0.20) | 週次スイング、Turtle と類似の追随 |
シグナル
トレーリングストップ
パラボリックSAR の主目的はエントリーではなくトレーリング損切です。
- ロング中は SAR がストップライン。価格が SAR に触れたら決済
- ショート中は SAR がストップライン。価格が SAR に触れたら決済
- 決済後の反転エントリーは任意(Wilder 原典は自動ドテン、実務では任意)
反転シグナル(単体エントリー)
- SAR が価格の下から上に移った瞬間は売りエントリー
- SAR が価格の上から下に移った瞬間は買いエントリー
- 単体エントリーはレンジで大失敗する(下記の落とし穴を参照)
ADX との組み合わせ(実務推奨)
Wilder 自身が推奨した組み合わせです。
- ADX > 25 でトレンドを確認したうえで SAR 反転をエントリーシグナルに採用する
- ADX < 20 のレンジでは SAR 反転を無視する(騙し多発)
- ADX と傾き上昇と SAR 反転が揃うと、トレンド初期の高確度エントリー
ATR との組み合わせ
- SAR ベースの損切だと、普通の値幅で刈られることがある
- ATR × 2 の最低保証損切を SAR と併用する
- 実務では
stop = max(SAR, entry - ATR × 2)(ロングの場合)
USD/JPY での使いどころ
トレンド追随ストップとして
USD/JPY 4時間足の週次トレンドで SAR がよく機能します。
- 月曜寄付でトレンド発生、火曜以降に SAR が追随する
- 木曜、金曜の失速で SAR タッチとなり週内利確
- 週末クローズ前の反転を SAR で捉えると週次スイングが回りやすい
東京仲値(JST 09:55)前後
- 5分足 SAR は仲値の急変で頻繁に反転する
- 単体運用は不可(レンジで刈られる)
- 仲値後のトレンド確定は15分から1時間足の SAR で確認する
ロンドンオープン(JST 16:00)
- ロンドン初動のトレンド発生で15分足 SAR がトレンド追随する
- 初動でエントリーし、SAR ベースのトレーリングでロンドン終盤(JST 21:00から22:00)までに利確が典型
NYオープン(JST 22:30)と指標
- 指標発表直前は SAR が価格に張り付く(低ボラ収縮後の反転乱発)
- 指標直後の急変で SAR が一気に反転位置へジャンプする
- 指標日は SAR をエントリーシグナルとして使わない(騙しリスク大)
日足での長期スイング
- 日足 SAR は月次スイングのトレーリング
- 週5営業日と週末ギャップで SAR の急ジャンプが発生することがある
- 週末ギャップに配慮する場合は、金曜クローズ時点で一部利確する
落とし穴
- レンジ相場での逆転乱発:SAR はトレンド相場を前提としている。ADX < 20 のレンジで単体運用すると連続損切になる
- 単体エントリーシグナルとしての誤用:SAR は撤退シグナルとして設計されている。エントリーシグナルに使うなら ADX、ATR、移動平均線の方向との Confluence が必須
- AF 上限の重要性:AF 上限を 0.20 から 0.50 に上げると SAR が急激に価格に近づき、利益が乗る前に刈られる現象が多発する
- 反転直後の SAR ジャンプ:反転直後の SAR は直近トレンドの EP。数十 pips ジャンプすることがある。この初期 SAR が現在価格から離れすぎているとリスクが大きい
- Wilder 追加ルールの実装漏れ:反転後の SAR を前日または前々日の安値/高値でクランプする処理を実装しないと、SAR が価格を追い越す不正状態になる
- 時間足間の混同:5分足 SAR と15分足 SAR は全く別。上位足でエントリーシグナル、下位足でトレーリングという使い分けが必要
- 週末ギャップ:金曜終値から月曜寄付のギャップで SAR が飛ばされる。ギャップリスクをストップ幅に織り込む
- AF リセット忘れ:反転時に AF を 0.02 にリセットしないと、再スタート時から高加速で始まって即座に刈られる
- バックテストでの過剰最適化:AF ステップや上限を細かく最適化するとカーブフィッティングになる。Wilder 標準 (0.02, 0.02, 0.20) から動かさない
- 教科書シグナルの実データ有意性:他のトレンドフォロー系(移動平均線、MACD)が有意な edge を出せなかった経緯を踏まえると、SAR も単体の edge は薄いと推測される。エントリーではなく撤退に限定して使う
Python 実装スケッチ
import numpy as npimport pandas as pd
def parabolic_sar( high: pd.Series, low: pd.Series, af_start: float = 0.02, af_step: float = 0.02, af_max: float = 0.20,) -> pd.DataFrame: """Wilder's Parabolic SAR.
Returns DataFrame with columns: sar : SAR value at each bar trend : +1 for long, -1 for short af : current acceleration factor ep : extreme point """ n = len(high) sar = np.full(n, np.nan) trend = np.zeros(n, dtype=int) af = np.full(n, np.nan) ep = np.full(n, np.nan)
if n < 2: return pd.DataFrame( {"sar": sar, "trend": trend, "af": af, "ep": ep}, index=high.index, )
# 初期化: 最初の 2 本で方向を仮決め if high.iloc[1] >= high.iloc[0]: trend[1] = 1 sar[1] = low.iloc[0] ep[1] = high.iloc[1] else: trend[1] = -1 sar[1] = high.iloc[0] ep[1] = low.iloc[1] af[1] = af_start
for i in range(2, n): prev_trend = trend[i - 1] prev_sar = sar[i - 1] prev_ep = ep[i - 1] prev_af = af[i - 1]
# 仮 SAR 計算 new_sar = prev_sar + prev_af * (prev_ep - prev_sar)
# 反転判定 if prev_trend == 1: # ロング中: SAR を 前日・前々日の安値以下にクランプ new_sar = min(new_sar, low.iloc[i - 1], low.iloc[i - 2]) if low.iloc[i] <= new_sar: # ドテン → ショート開始 trend[i] = -1 sar[i] = prev_ep ep[i] = low.iloc[i] af[i] = af_start continue trend[i] = 1 sar[i] = new_sar if high.iloc[i] > prev_ep: ep[i] = high.iloc[i] af[i] = min(prev_af + af_step, af_max) else: ep[i] = prev_ep af[i] = prev_af else: # ショート中: SAR を 前日・前々日の高値以上にクランプ new_sar = max(new_sar, high.iloc[i - 1], high.iloc[i - 2]) if high.iloc[i] >= new_sar: # ドテン → ロング開始 trend[i] = 1 sar[i] = prev_ep ep[i] = high.iloc[i] af[i] = af_start continue trend[i] = -1 sar[i] = new_sar if low.iloc[i] < prev_ep: ep[i] = low.iloc[i] af[i] = min(prev_af + af_step, af_max) else: ep[i] = prev_ep af[i] = prev_af
return pd.DataFrame( {"sar": sar, "trend": trend, "af": af, "ep": ep}, index=high.index, )Wilder 追加ルール(SAR の前日、前々日の安値/高値クランプ)を実装しています。実装の落とし穴が多いため、業務利用時は ta-lib や pandas-ta の実装と結果を突き合わせて検証します。
ATR と組み合わせた最低保証損切の例。
def sar_with_atr_floor( close: pd.Series, sar_df: pd.DataFrame, atr_series: pd.Series, k: float = 2.0,) -> pd.Series: """SAR と ATR ベース損切の "遠い方" を採用する。
ロング中は max(SAR, close - k*ATR)、ショート中は min(SAR, close + k*ATR)。 """ stop = pd.Series(index=close.index, dtype=float) long_mask = sar_df["trend"] == 1 stop[long_mask] = pd.concat( [sar_df.loc[long_mask, "sar"], close[long_mask] - k * atr_series[long_mask]], axis=1, ).max(axis=1) stop[~long_mask] = pd.concat( [sar_df.loc[~long_mask, "sar"], close[~long_mask] + k * atr_series[~long_mask]], axis=1, ).min(axis=1) return stop参考
- J. Welles Wilder Jr., New Concepts in Technical Trading Systems, Trend Research, 1978 (Chapter 6)
- Investopedia — “Parabolic SAR” https://www.investopedia.com/terms/p/parabolicindicator.asp
- StockCharts — “Parabolic SAR” https://school.stockcharts.com/doku.php?id=technical_indicators:parabolic_sar
- pandas-ta —
psarhttps://github.com/twopirllc/pandas-ta - TA-Lib —
SARhttps://ta-lib.org/functions/sar