見出し画像

Pythonで指数平滑移動平均(Exponential Moving Average、略:EMA)を算出する

指数平滑移動平均(Exponential Moving Average、略:EMA)とは

指数平滑移動平均(以下、EMA)は、単純移動平均(以下、SMA)のデメリットである過去の値と直近の値を同等に扱うことを改めて、直近の値の寄与を大きくすることで変化に対する反応を早めた移動平均です。

数式で表すと次のようになります。
EMA = 直前のEMA×(1-2÷(算出期間+1)) + 最新の値×2÷(算出期間+1)
または
EMA = 直前のEMA + 2÷(算出期間+1)×(最新の値-直前のEMA)

EMAの向きは最新の値と直前のEMAの位置関係で決まります。
すなわち
最新の値>直前のEMA → EMAは上向き
最新の値<直前のEMA → EMAは下向き
になります。

メリットとしては、次のような点があります。
・最新の値の変化に対する反応がSMAよりも早くなります。

デメリットとしては、次のような点があります。
・算出期間が短いほど値の変化に大きく反応します。

ソースコードと実行結果

def calcEMA(**kwargs):
    """指数平滑移動平均(Exponential Moving Average)を算出する
    
    Args:
        data (pandas.Series): 算出する対象の値
        period (int): 算出する期間
    
    Returns:
        pandas.Series: 指数平滑移動平均
    """
    DATA = kwargs['data']
    period = kwargs['period']
    
    return DATA.ewm(span=period).mean()

出力用のソースコードも記載しておきます。
以前にこちらの記事で紹介したSMAのコードも呼び出せるように併記してください。

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 = fig.add_axes([0, 0, 1, 1])
    
    ax.plot(OHLCV['Close'][start:end], color='black', marker='.')
    ax.plot(calcSMA(data=OHLCV['Close'], period=20)[start:end], color='green', label='SMA')
    ax.plot(calcEMA(data=OHLCV['Close'], period=20)[start:end], color='orange', label='EMA')
    ax.tick_params(labelright=True)
    ax.grid(True)
    ax.set_ylabel(label)
    ax.legend(loc='best', fontsize='small')
    
    ax.set_xticks(OHLCV[start:end].index)
    ax.set_xticklabels(ax.get_xticks(), rotation=90, horizontalalignment='center', fontsize='small')
    ax.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)

すると、次のようなチャート画像が出力されます。
SMAとEMAの反応の違いがよく分かると思います。

ソースコードの解説

指数平滑移動平均の算出にはewm関数を使用します。
ewm関数の引数spanに算出期間を指定します。

ewm関数にさらにmean関数を適用して平均化します。

参考

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


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