FX

パラボリックSARの計算方法とZigZagの作成・詳細解説

パラボリックSAR(Parabolic Stop And Reversal、以下”SAR”と略します)という、おそらくどのチャートソフトでも表示できる、とてもよく知られた トレンド系のインジケータがあります。私はインジケータにはあまり関心がありませんが、例外的にSARは気になっていました。

SARとはこんなやつです(この図はMT4のもの)。

赤い点々の部分がSARです。

値動きのトレンドに追従するという意味では、移動平均線に似ていますが、より局所的なトレンドを表現します。

レートがSARの値とクロスすると、SARは方向が反転します。一般には、この反転時が、決済のシグナルとして有効といわれています。

また、裁量トレードの汎用的なツールとしても評判がよいとききます。

ただ、私は反転やエントリーシグナルとしてではなく、押しや戻り、あるいはトレンドを統計的に検証するツールとしてSARを使えないか、という点で気になっていました(くわしくは後述します)。

パラボリックSARの計算はめんどくさい!?

そんなわけで、SARの計算方法は簡単そうだし、自分であれこれ計算してみよう、とおもったところ・・・さっそく手が止まってしまいました。

そもそもの計算開始時のやり方すら、私は理解できていなかったのです。

なので、例によってGoogle先生にお問い合わせしてみたのですが、主要の計算式のみ示されているものが多く、とくに計算開始時についての説明が全くない、説明不足、あるいは正しいようには思えない記述・・・そんな情報しか見当たりませんでした。

そこで詳しく調べていくと、計算開始時以外でもSARの計算は私が考えていたよりずっと複雑でした。

これはもしかすると、SARのロジックを詳細に説明しようとすると、相当めんどくさいので、説明がおもいっきり省略されているのではないか?そう思えてきました。

そこで今回は、SARを自分で計算してみたいという方に向けて、その応用などもふくめて次の内容でお話ししていきたいとおもいます。

  • SARを自力で計算できるように、煩雑なSARの計算ロジックを整理
  • SARの応用としてZigZagを作成し、加速係数とZigZagの関係を調べる

パラボリックSARの計算方法

平均的なSARの計算方法の説明文として、例えば、以下のMetaTraderのヘルプページがあげられます。

以下、MetaTrader5のヘルプ Parabolic SAR(パラボリックSAR)からの抜粋です


買いポジション

SAR (i) = SAR (i -1) + ACCELERATION * (HIGH (i -1) – SAR (i -1))

売りポジション

SAR (i) = SAR (i -1) + ACCELERATION * (LOW (i -1) – SAR (i -1))

ここで

SAR (i -1) — 1つ前の足のパラボリックSARの値
ACCELERATION — 加速係数
HIGH (i -1) — 1つ前の足の高値
LOW (i -1) — 1つ前の足の安値 です。

買いポジションの式ではSARが上昇を描き、売りポジションの式ではSARが下降を描くのは容易に想像できます。

ですが、買いポジションの状態と売りポジションの状態を最初にどのように決めるのでしょうか? 計算開始時のやりかたは説明されていません。

マネーパートナーズのページも詳しいようですけれど大差なく、たとえば、”上昇トレンドの初期値・・・”と、唐突にトレンドの存在を前提に説明しています。

MetaTraderのコードを参考にする

結局、面倒がらずに、MetaTrader(MT)のパラボリックSARのMQLコードを参考にしてロジックを調べることにしました(でも、まさかパラボリックの計算方法をコードで調べるハメになるとは・・・トホホな感じでございました)。

下の図は、MT4のメタエディターを開き、“Parabolic.mq4”のコードを表示したところです。

プログラミングができるかたは、このコードをなぞっていけば、ご自分の得意なプログラム言語に落とし込めますので、以下の説明は読む必要はないかとおもいます。ただ、コメントがほとんどないので、コードの解釈に困ったら、参考になさってみてください。

ところで、もしかするとですが、このコードはMetaquotes社の独自のやり方である可能性もなくはありません。その可能性についてはご了承くださいませ。

以下では、EXCELの関数だけならOKという方から、何らかのプログラミングができる方までを想定して、図と言葉での説明を試みました。

データはローソク足データ(ヒストリカルデータ)を使用することを前提とします。

SARのロジックについては、大きく次の二つに分けて説明します。

  • 初期処理(最初のトレンドを決定し、1個目のSARを計算する)
  • メインループ(2個目以降のSARを計算する)

処理の順序は、 概ね”Parabolic.mq4″ に従っています。

入力と出力・用語

計算方法の説明のまえに入力と出力を決めておきます。

入力は、次の4つとします。

入力
  • ローソク足の高値・安値のデータセット(RDBやcsv等の時系列順のデータを想定)
  • 加速係数の初期値
  • 加速係数の最大値
  • 加速係数の増分

出力は、

出力

ローソク足ごとのSARの値(レート値)

ローソク足ひとつに対し1つのSARが定まります。ただし、初期処理で説明しますが、最も過去のデータから1つ以上のローソク足についてはSARを決定できません。

用語

以下は便宜的な計算ロジックの説明用語です。

  • 加速係数(ACCELERATION FACTOR)⇒ AF
  • SARが上向きに描かれる場合 ⇒ 上昇トレンド
  • SARが下向きに描かれる場合 ⇒ 下降トレンド

初期処理

最初のSARの点と、最初の最高値、最安値を決定するまでを初期処理とします。

1. トレンドの決定

まず、データを2つ読み込んで、連続する2つのローソク足でトレンドを決定します。例えば、

つまり、次のようにトレンドを決定します。

  • 現在の足の高値、安値がともに前の足より高ければ、上昇トレンド
  • 現在の足の高値、安値がともに前の足より安ければ、下降トレンド

このため、次のような場合はトレンドが決定できないとします。

図示してませんが、高値・安値のラインのどちらかが完全に水平な場合もトレンドなしになります。

トレンドが決定できるまでデータを逐次読みこんでいきます。トレンドを決定できたら、最初の1個目のSARを決定します。

1個目のSARの値は、

  • 上昇トレンドの場合、 1個目のSARのレートは前の足の安値とする
  • 下降トレンドの場合、 1個目のSARのレートは前の足の高値とする

2. 最高値・最安値の記録

SARが決定できたら、上昇トレンドの場合は現在の足の高値を最高値として、下降トレンドの場合は最安値として、別途変数に記録しておきます。

メインループの処理

2つ目以降のSARの計算をメインループの処理とします。

処理内容をおおまかに7つにわけて説明します。以下に説明する1~7の処理順序は、おおむね、”Parabolic.mq4″に沿っています。

ところで、私は当初、出だしのところが分かりさえすれば、あとはサクサクいく、と思っていたのですが、考えが甘く、細部まで理解するのは大変でした。

以下の説明のうち、とくに5の処理は分かりにくいかもしれません。加速に対し、ブレーキをかけるような処理です。ふつうのパラボリックSARのロジックの説明では、見かけないルールだとおもいます(私が知らないだけかもしれませんが、個人的には見たことがなかったです)。

1. データの読み込み

次のローソク足の安値・高値のデータを読みだします。始値や終値は使いません。

2. SARの反転処理・その1(データを読み込んだ直後)

MetaTraderの”Parabolic.mq4″には、SARの反転処理が2か所あります。私の推測ですが、おそらく主に処理効率が理由かとおもわれます。

基本的には、現在のトレンド方向にもとづいて計算した現在の足のSARが、現在の足とクロスしたとき、トレンド方向が反転したと判定します。なので、現在の足のSARを計算してから反転チェックするという処理順序になります。

しかしながら、現在の足の安値や高値が、ひとつ前の足のSARのレートに達している場合は、現在の足のSARを計算するまでもなく反転が確定となるので、ただちに反転処理できる、このタイミングでの反転チェックは、そのように解釈できます。

下の図は、このショートカット処理について、上昇トレンドから下降トレンドへ反転する場合を説明したものです。

下降トレンドから上昇トレンドに反転する場合も同様に処理します。

トレンドが反転し1つ目のSARを決定したら、以下の処理をおこなってから1に戻ります。

  • AFの値を、加速係数の初期値にもどす
  • トレンドのフラグを反転させる
  • 上昇トレンドに変わった場合
    • 最高値を反転の起点となった足の高値とする
  • 下降トレンドに変わった場合
    • 最安値を反転の起点となった足の安値とする

トレンドが反転しなかった場合、3以降の処理を行います。

3. SARの仮計算(2の反転条件を満たさない場合)

次の図は、例として、2個目のSARの計算方法を説明したものです。ただし、SARの計算後に反転条件が成立するかもしれないので、この段階では仮計算の位置づけです (別の理由もあります)

下降トレンドの場合も考え方は全く同じです。

3個目以降のSARの計算方法も、2個目のSARの計算と全く同様です。ひとつ前のSARの値と現在の最高値または最安値、そして更新したAFを使って計算します。計算式は、

  • 上昇トレンドの場合
    • SAR = ひとつ前のSAR + (最高値 - ひとつ前のSAR)× AF
  • 下降トレンドの場合
    • SAR = ひとつ前のSAR + (最安値 - ひとつ前のSAR)× AF

この式は、1式にまとめた表現もあります。パラボリックSARの説明として必ずでてくるので、ご存知の方も多いかとおもいます。

繰り返しになりますが、この時点では、SARの値は確定していません。

4. AFの値を更新

次の条件を満たすとき、AFの値を更新します 。

  • 上昇トレンドの場合、現在の高値が、すでに記録されている最高値より高い
  • 下降トレンドの場合、現在の安値が、すでに記録されている最安値より安い

つまり、現在の足で、最安値または最高値が更新されることが確定している場合に限り、次の式で、AFを更新します。

更新後のAF = 更新前のAF+ 加速係数の増分

ただし、更新後のAFが、入力として与えられたAFの最大値を超える場合、

更新後のAF > AFの最大値、のとき、 更新後のAF = AFの最大値

とします。デフォルトの値として 、AFの初期値を0.02、増分を0.02、AFの最大値を0.2とすることが多いようです。

蛇足ですが、 加速係数の増分をゼロ(加速させない)としても、AFの初期値がゼロでなければ、やはりSARはトレンドに追従するように描かれます。

5. 仮計算したSARの調整

ここがSARにブレーキをかける、問題の処理になります。

2つ前までのローソク足の高値安値と仮計算したSARの値を比較し、一定の条件を満たす場合、 SARの値を変更します 。下の図は上昇トレンドの場合の説明です。

つまり、上昇トレンドのSARの値が、1本前と2本前の足の、安い方の安値を超えることがないように調整します。

下降トレンドの場合も同様に処理します。

以上の図のいずれにも該当しない場合、3で仮計算したSARの値はそのままです(ただし、まだ確定値ではありません)。

前の足の安値や高値へのSARの変更は、こうしないとSARがローソク足に近づきすぎて、トレンドの軌跡が途切れがちになるためでしょう。

また、トレンド開始から2点目以降のSARは、入力したAFに関するパラメータ設定とは無関係に値が決まることがある、ということになります。

・特殊処理(1度だけ実行の可能性あり)

メインループに入って1本目のローソク足データ(初期処理で2本でトレンドが決まり、通算3本目のデータ)についてのみ、

  • トレンドと関係なく、 通算3本目の足の2個目のSARを初期処理で決めた1個目のSARと同値にする。

これは少々分かりにくいとおもいますが、前述の調整と同じ意味の処理です。

現在が3本目ということは、最初の2本でトレンドが決定しているので、3本目のSARの仮計算がどのような値にせよ、2本前(つまり1本目のデータ)の安値または高値に調整することが確定しています。

その高値または安値は、1個目のSARの値と同じですよね、という意味です。

もっとも、この調整ルールのもとでは3本目のデータに限らず、反転1個目のSARが1本前の足の安値や高値と同じならば、2個目のSARは1個目と同値になります。

実際、MT4でパラボリックSARをよくみると、とくにトレンド開始時部分でSARが完全に横並びになっていることがありますが、この調整処理が行われたためです。

しかし、反転1個目のSARの参照先が何本前の足かを常に見張るコードを加えるのは効率的なやり方とはいえないので、ループ最初のデータであることが自明な3本目のみ、この処理を設けているとおもわれます。

なお、2の処理で、ループ最初のデータでSARが反転するならば、この処理は1度も実行されません。

6. SARの反転処理・その2

リアルタイムの処理(ティック単位の処理)まで広げて考えると、この2つ目の反転処理は、足が確定した直後にのみ実行されます。

仮計算したSARが、現在の足とクロスしていれば反転処理をします。2の反転処理と異なるのはこの点だけで、他は2と同じです。

下図は上昇トレンドから下降トレンドへ反転した場合の説明です。

下降トレンドから上昇トレンドへ反転する場合も同様に処理します

トレンドが反転した場合、2と全く同じの次の処理を実施した後、1に戻ります。

  • AFの値を、加速係数の初期値にもどす
  • トレンドのフラグを反転させる
  • 上昇トレンドに変わった場合
    • 最高値を反転の起点となった足の高値とする
  • 下降トレンドに変わった場合
    • 最安値を反転の起点となった足の安値とする

トレンドが反転しなかった場合、仮計算したSARの値を現在の足のSARとして確定します。

7. 最高値・最安値の更新

6でトレンドが反転しなかった場合、最高値または最安値の更新処理をします。

  • 上昇トレンドの場合:現在の高値が、すでに記録されている最高値より高いとき、最高値を現在の高値で更新
  • 下降トレンドの場合:現在の安値が、すでに記録されている最安値より安いとき、最安値を現在の安値で更新

1に戻ります。

以上、すべてのデータについて、1~7を繰り返して処理を行います。

ここまで、”Parabolic.mq4″のロジックは、効率を追求しているという意味で無駄がなく、よく考えられているコードという印象を持ちました。

計算例

ということで、私もようやく自分でSARを計算できるようになりました。

下の図は、Pythonで作成したSARの計算例です。1分のヒストリカルデータに対し、一般的とされる、AFの初期値0.02、増分0.02、最大0.2のパラメータ設定で計算しています。

AFの初期値=0.02、増分=0.02、最大=0.2のパラボリックSAR

次の図は、メインループの5で説明した最高値・最安値の調整を行わずにSARを計算したものです。

前図で、最高値・最安値の調整をせずにSARを計算

図中の円で囲んだ部分をみると、前の図とくらべてSARのトレンドがより細分化されてしまっており、前の図では調整処理の効果があったことがわかります。

逆に、AFを使わず、2つ前までの足の最高値または最安値に合わせただけの点を描いたら、どうなるでしょうか。

AFを使わずに2つ前までの足の最高値・最安値でSARを計算した結果

このように、値動きに従うだけになると、バラバラな感じで滑らかさを失います。トレンドを描けているとはいい難い結果です。

最後に、AFを初期値0.02で固定、つまり増分をゼロ(加速させない)にしたらどうなるかを試してみます。

AF=0.02で固定してSARを計算

SARが直線状になりました。最初の図と比べると値動きへの追従が鈍いですが、それだけにトレンドは途切れにくくなっています。

これはむしろ逆張りではなく順張りシグナルとしたほうがよいかも?

反転処理のタイミングについて

例えばシステムトレードでエントリーまたはエグジットにSARの反転シグナルを利用することを考えたとき、前述のメインループの処理でいうと、反転処理の2と6は、実行できるタイミングが異なります。

2は、理屈上はティック単位でリアルタイムに反転条件をチェックできます。一方6は、現在の足が確定した直後にのみ処理ができます。




SARを利用してZigZagを作成

ある上昇トレンド、または下降トレンドの一連のSARは、1つ目のSARが直近の最高値または最安値のレートを示しています。このことを利用して、高値安値を結んだ折れ線グラフ、いわゆる”ZigZag(ジグザグ)”を作成できます。

これまでみてきた、パラボリックSARのロジックから、SARがZigZagに応用できることは容易に理解していただけるでしょう。SAR反転ポイントで最高値や最安値のデータを集めていけばよいわけです。

あまりに明らかなことなので、おそらくツールがあるだろうと探してみますと、確かにあります。

例えば、以下の参考リンクは、MetaTraderでパラボリックSARをもとにしたZigZagを作成するカスタムインジケータです。

上記のページによれば、標準的なZigZagに比べて遅れがすくないとのことです。個人的には、考え方がパラボリックSARのほうが分かりやすいというのも長所だとおもいます。

ZigZagの計算例

下の図は、前述の計算例で示した、AFの初期値=0.02、増分=0.02、最大=0.2のSARに基づくZigZag(緑のライン)のプロットです。

AFの初期値=0.02、増分=0.02、最大=0.2のSARと対応するZigZag

ZigZagのデータを作成するには、計算方法で説明したメインループ中に、以下の処理を加えます

  1. 最高値・最安値を更新するとき、付随する情報として、足の位置(例えばデータのインデックス)を別途記録する。
  2. 反転処理時に、別途ZigZag用に1の情報を記録する

次に、AF=0.02固定のSARに対応するZigZagを作成してみます。

AF=0.02固定のSARと対応するZigZag

前の図から細かい波が消えているのがわかります。かなりすっきりしました。

このように、AFとZigZagの関係を簡単にいうと、

  • AFを小さくすると、小さい波が少くなる
  • AFを大きくすると、小さい波が多くなる

つまり、AFがZigZagの波の大きさ(波長的な意味)に関するフィルター調整の役割をはたします。

少々語弊がありますが、パラボリックSARのZigZagには、単純移動平均同様、一種のローパスフィルターとしての使い勝手の良さがあります。もちろん、AFと波長スケールの関係を理論だてることは、かなり難解なことでしょう。

ZigZagを調整する目的では、AFを加速(増分>0)させる積極的な意味はないようにおもいます。AFを固定値として調整したほうがわかりやすいかもしれません。

包絡線

ZigZagの高値のみ、または安値のみを線で結んでいけば、下の図のようにZigZagの包絡線(オレンジの点線)も作成することができます。

AF=0.02固定のSARに対応するZigZagと包絡線

この包絡線それ自体の活用は、正直、私はこれといって思いつきません。ですが、包絡線のデータを支持線や抵抗線の計算に活用することはできるとおもいます。

押しや戻りの割合が計算可能になる

ZigZagに基づいた高値と安値の間の値幅、トレンドの角度や時間長さが計算できます。押しや戻りの割合も計算できるようになります。これらは、裁量トレード的な考え方を具体的な数字に落とし込むのに役立ちます。

なお、ZigZagについては他にもさまざまなロジックがあります。この方法でなければ誤り、ということはありません。

パラボリックSARのみで機械的にトレードしてみると?

今回のお話の主旨とは少々ズレるのですが、逆張り指標として、パラボリックSARのみで機械的にトレードしたらどのような結果になるのでしょうか?

この点は気になる方も結構いるのではないかとおもいましたので、ついでに確認しておこうとおもいます。

シミュレートの設定は次の通り非常にシンプルです。

  • SAR反転でエントリー、エグジット
  • SARのパラメータ:初期値0.02、増分0.02、最大0.2
  • ポジション数は1
  • ドル円1分足、2018年の1年間でシミュレート
  • スプレッドは0.3pips

シミュレートに使うデータは、XMTradingのMT4から取得したMetaQuotesのドル円、1分足・371926本のヒストリカルデータです。

バカ正直に、パラボリックSARで1分足スキャルピングしたらどうなるか?といった感じの実験です。

下図が結果のグラフです。上段が損益推移、下段が終値のグラフです。

AF初期値=0.02, 増分0.02, 最大0.2のSARによるトレードの損益グラフ(上)と2018年のドル円チャート(下)

トレード内容は、

  • トレード数:21843回
  • 損益:-6761.03pips
  • 1トレード平均獲得pips: -0.31pips
  • 勝率:48.95%
  • リスクリワード:0.87

1トレード平均が -0.31pipsですので、スプレッド分負ける、というある意味順当な結果になります。

順当、といいますのは、こうした簡単なシステムトレード実験は、スプレッドなしでイーブン、ちょっと負けくらいが普通、という意味です。

おもいっきり負けるようなら、逆のことやればいいかも?という可能性がでてきますが、そんなうまい話はそうそうないですよね、といえば分かりやすいでしょうか。

また、結果だけいいますと、AFのパラメータを変えたくらいでは、1トレード平均の成績はほぼ変わりません。

AFと波のスケール

勝ち負けだけでいうと、つまらない結果をお見せしましたが、ちょっとした御利益があり、この実験結果から、ZigZagの波(SARのトレンド)の平均的なスケールを統計的に調べることができます。

この単純なシミュレートでは、トレード回数がすなわちSARの反転回数です。

したがって、1分足の本数をトレード回数で割れば、SARのトレンド1つあたりの平均時間長さ(あるいはSARの個数)が求まります。2018年ドル円では、

SARがAF初期値0.02、増分0.02、最大0.2の場合

371926分 ÷ 21843回 = 17.03分/回

SARがAF初期値0.02固定の場合は次のようになります、

371926分 ÷ 5238回  = 71.01分/回

このシミュレートでは、数値的近似として、両者はZigZagのスケールが4倍ほど違うといえます。

さきほどのZigZagの説明の中で、AFと波長スケールの関係を理論だてることは難しい、と申しましたが、 このようにして、 SARの反転回数をもとにして、AFと波のスケールの関係について、統計的な目安は得られるでしょう。

参考までに、ドル円の17分、71分をそれぞれ平均値幅に換算すると

  • 平均値幅
    • 17分: 5.8pips
    • 71分:11.8pips
  • 標準偏差
    • 17分: 9.5pips
    • 71分:19.4pips

この換算は、次のトピックで紹介しましたが、値幅がおよそ時間の平方根に比例することと、約20年間の1分の値幅の統計値から概算したものです。

SARにより定量化できる情報のまとめ

以上、パラボリックSARを描けるようになったことで、ZigZagが作成でき、次の情報を一定のルール下(AFの設定)で定量化できるようになります。

  1. トレンドの長さ
  2. トレンドの角度(≒値動きの速度)
  3. 押しや戻りの割合
  4. 高値安値の値幅

とくに、3、4は、裁量トレード上、誰もが注意を払う重要なポイントではないでしょうか。

どんなことがSARで考察できそうか

上記の数字を環境条件として、システムトレード・裁量トレードの両方に通じる次のような考察が可能だとおもいます。

  • フィボナッチリトレースメントって、あれ、ホントなの?
  • トレンドラインブレークの検証
  • トレンドラインにぶつかったのだからSARで逆張りではなく、順張りが有効な場合もありえるか?

など、以上はほんの一例ですが、他にも数字で検証できそうな仮説がありそうです。

異なるタイムフレームを組み合わせたり、ボラティリティの観点を加えると、さらにアイデアの幅も広がるでしょう。

裁量トレードの検証、アルファモデルのロジック、あるいは機械学習の入力として、いろいろな用途がありそうだとおもいます。

今回の記事は以上になりますが、ご興味のある方は、ご自身のアイデアやインスピレーションを活かすツールとして、自分が得意とするフレームワーク上でパラボリックSARの計算を試してみてはいかがでしょうか。


追記・パラボリックSARのPythonコード(2019/11/9)

最近、アナリティクスを見ていたら、Qiitaからこの記事をご覧いただいている方がいるようだ、ということに気づきました。調べてみると、次のページで引用していただいておりました。

Qiita: [python3] matplotlibでパラボリックSARを描画

https://qiita.com/siruku6/items/76f4072c06a988dfe2cb

当方の記事をもとに、Ver.2として、パラボリックSARのPythonのコードを提供しておられます。大変ありがたいことなので、Pythonのコードをお求めの方は、上記のページをご参考になさってみてください。

以上です。