見出し画像

Python で ATR(Average True Range)を算出する

ATR(Average True Range)は、TR(True Range)を指定期間で平均化した値です。

まずTRとは、1期間だけで算出した値幅に加えて、直前期間からの窓開け(ギャップアップやギャップダウン)を含めた値幅まで考慮した、まさしく「真の値幅」のことです。

具体的に考慮する値幅の数式は次の通りです。||は絶対値を表します。

  •  当期間の高値-当期間の安値

  • |当期間の高値-前期間の終値|

  • |当期間の安値-前期間の終値|

この3つのうちの最大値をTRとします。

そしてATRは、TRの移動平均から算出します。


ATRには次のような活用法があります。

  • 相場の荒れ具合を知る。
    ATRの水準を過去と比較することで、時化(しけ)ているのか、凪(なぎ)なのかが分かります。

  • 価格変動の傾向をつかむ。
    ATRの増加は変動の拡大であり、トレンドが継続する可能性があります。
    ATRの減少は変動の縮小であり、トレンドが消滅する可能性があります。

  • 1期間経過後の値幅として決済価格の目安にする。
    よく知られている話では、タートルズが用いていました。

ソースコードと実行結果

import pandas as pd

def calcTR(**kwargs):
    """TR (True Range) を算出する
    
    Args:
        data (pandas.DataFrame): 算出する対象の値('High','Low','Close'列が存在すること)
    
    Returns:
        pandas.Series: TR
    """
    DATA = kwargs['data']
    
    RANGE = pd.concat([ DATA['High'] - DATA['Low']
                      , abs(DATA['High'] - DATA['Close'].shift(1, axis=0))
                      , abs(DATA['Low'] - DATA['Close'].shift(1, axis=0))
                      ], axis=1)
    
    return RANGE.max(axis=1)


def calcATR(**kwargs):
    """ATR (Average True Range) を算出する
    
    Args:
        data (pandas.DataFrame): 算出する対象の値('High','Low','Close'列が存在すること)
        period (int): 算出する期間
    
    Returns:
        pandas.Series: ATR
    """
    DATA = kwargs['data']
    period = kwargs['period']
    
    return calcSMA(data=calcTR(data=DATA), period=period)

calcSMAは以前にこちらの記事で紹介した単純移動平均を算出する関数です。コードを呼び出せるように併記してください。

単純移動平均では変化が遅いと考える場合は指数平滑移動平均を用いても良いでしょう。

出力用のソースコードも記載しておきます。

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

def plotChart(**kwargs):
    OHLCV = kwargs['ohlcv']
    start = kwargs['start']
    end = kwargs['end']
    label = kwargs['label']
    file = kwargs['file']
    
    fig = plt.figure(figsize=(8, 6))
    ax_Price = fig.add_axes([0, 0.5, 1, 0.5])
    ax_Indicator = fig.add_axes([0, 0.0, 1, 0.5], sharex=ax_Price)
    
    ax_Price.plot(OHLCV['Close'][start:end], color='black', marker='.')
    ax_Price.tick_params(labelright=True)
    ax_Price.grid(True)
    ax_Price.set_ylabel(label)
    
    ax_Indicator.plot(calcATR(data=OHLCV, period=14)[start:end], color='red')
    ax_Indicator.tick_params(labelright=True)
    ax_Indicator.grid(True)
    ax_Indicator.set_ylabel('ATR')
    
    ax_Indicator.set_xticks(OHLCV[start:end].index)
    ax_Indicator.set_xticklabels(ax_Price.get_xticks(), rotation=90, horizontalalignment='center', fontsize='small')
    ax_Indicator.xaxis.set_major_formatter(mdates.DateFormatter('%m/%d'))
    
    fig.savefig(file, format='png', bbox_inches='tight')

次のようにplotChart関数を呼び出して実行してください。

plotChart(ohlcv=OHLCV_N225, start='20221001', end=None, label='Nikkei225', file=filename)

すると、次のようなチャート画像が出力されます。

ソースコードの解説

前期間の値はshift関数を使用します。

絶対値の算出にはabs関数を使用します。

3つ値幅のSeriesをconcat関数で列結合したDataFrameについて、max関数によって指定した軸の中で最大の値を返します。axis=1は列を示します。

参考

pandas.Series.shiftのリファレンス
https://pandas.pydata.org/docs/reference/api/pandas.Series.shift.html

組み込み関数absのドキュメント
https://docs.python.org/ja/3/library/functions.html#abs

pandas.concatのリファレンス
https://pandas.pydata.org/docs/reference/api/pandas.concat.html

pandas.DataFrame.maxのリファレンス
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.max.html


この記事が気に入ったらサポートをしてみませんか?