指数平滑移動平均(Exponentially weighted Moving Average)

 

概要
図1 EMA(5)とEMA(25)

使用する全てのデータを平等に評価する単純移動平均(SMA)とは異なり、直近のデータを重視して移動平均を計算する方法の1つを指数平滑移動平均 Exponentially weighted Moving Average(EMAもしくはEWMA)といいます (図1)。例えば、10日間のデータを使用する際に、10日前のデータより直近である昨日のデータを重視してデータの新しさに応じた重みを与えて加重平均を計算します。EMAはMACDやATRなど他のテクニカル指標でベースとなる数値として使われています。

EMAの基本的な使い方はSMAと同様です。EMAに対してどちらに現在のレートがあるかで相場の勢いを判断したり、複数のEMAを使って売買のトレンドを計ったりします。より詳しくはSMAの項をご覧ください。

n区間に対するEMAの計算方法(5日分のデータからEMAを計算する場合)

5日分の価格データを使ったEMAを計算してみましょう。表と計算例を見てください。5日分の価格を使うため4日目以前は5日分の価格データがないので計算ができず、計算が出来るのはデータの揃った5日目からとなります。

日数      価格  SMA  EMA
1日目1.00
2日目5.00
3日目9.00
4日目3.00
5日目7.005.005.00
6日目10.006.807.23
7日目2.006.205.37
8日目8.006.006.28
9日目4.006.205.50
10日目(最新)6.00  6.005.67
図2 EMA(5)を追加した例

計算式は下の通りとなります。ここで5日目の計算値は定義からSMAと同様となります。6日目以降は5日目までの価格を使用しEMAを計算しますが、6日目のEMAを計算するためには前日である5日目までのEMAが必要となります。また、 平滑化の定数としてαを定義し、5日目までのデータを使ったEMA(n-1)と6日目の価格のどちらをの重視するかの度合いを決める必要があります。通常は、α=2/(n+1)、つまり、最新の6日目の価格に2倍のウェイトを付けて足し合わせます。6日目の価格を2倍して加えているので、期間は5日間ですが、6日分の価格を使って計算するのと同様になります。図2がEMA(5)をレートに重ねたものとなります。

$$ \rm{} \begin{align} 5日目の計算  \\ \rm{} EMA(5) &= \rm{\frac{1}{5}(1日目の価格+2日目の価格 \\ +3日目の価格+4日目の価格+5日目の価格)}\\ 6日目以降の計算\\ \rm{} EMA(5) &= \rm{(前日のEMA)\times (1 – \alpha) + (当日価格) \times \alpha}\\ \end{align} \\ \alpha(平滑化定数):2/(5+1)\\ $$ $$ \begin{align} \rm{} EMA(5) &= \rm{前日のEMA + 2/6 (当日価格 – 前日のEMA)} \\ &= \rm{1/6(2 \times 当日価格 + 4 \times 前日のEMA)} \end{align} $$

EMA(5)の結果なかでそれぞれの日のデータが占める割合をα=2/6に対して計算すると次のようになります。古いデータほど係数αが複数回掛かるので重視されなくなっていくことが分かります。 100%にならないのは5日前以前のデータが含まれるからです。

当日1日前2日前3日前4日前
データが結果に占める割合33.3%22.2%14.8%9.9%6.6%

上の例をn日間のEMAの計算に拡張すると式を以下のように書くことが出来ます。

$$ \rm{} EMA(n) = EMA(n-1) \times (1-\alpha) + (当日価格) \times \alpha \\ \alpha:2/(n+1)\\ $$

EMAとSMAを比較してみます。図3を見てください。レートの値動きに対してEMA(暗い緑)の方がSMA(マゼンタ)よりレートの変動に対する感度が強いことが分かります。

図3 EMA(25)とSMA(25)の比較
Pythonによる実装

必要なライブラリを読み込みます

!pip install mpl_finance #Collaboratoryに入っていないライブラリを読み込みます
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd
import mpl_finance
import sys
import numpy as np
from datetime import datetime
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
import requests
import io

データをcsvファイルから読み込みます

#ファイルの読み込み
URL = "https://neulab.co.jp/wp-content/uploads/pseudo_data.csv" #csvファイルのURL

datafile = requests.get(URL)#ファイルの読み込み

#データフレームの作成
df_temp = pd.read_csv(io.BytesIO(datafile.content), header=0, index_col=0, parse_dates=True, encoding="UTF-8")

df = df_temp.loc[:,['Open','High','Low','Close']]
df.head()

EMAを計算します

df_ema_5  = df['Close'].ewm(span=5).mean()
df_ema_25 = df['Close'].ewm(span=25).mean()

チャートの表示と保存例です

canvas_color = '#fffafa'
line_color = '#c8ced1'
font_color = '#171510'
colorup = '#bf0000'
colordown = '#006fbf'

n_data = -100
data = df[n_data:]
ohlc = np.vstack((range(len(data)), data.T)).T

fig = plt.figure(figsize=(12, 8))
fig.patch.set_facecolor(canvas_color)
ax = fig.add_subplot(1, 1, 1)
ax.patch.set_facecolor(canvas_color)
mpl_finance.candlestick_ohlc(ax, ohlc, width=0.5, alpha=1, colorup=colorup, colordown=colordown)
#ax.plot(range(len(data)), df_ema_5.values[n_data:], color='darkorange', ls='-', label='EMA(5)')
ax.plot(range(len(data)), df_ema_25.values[n_data:], color='darkgreen', ls='-', label='EMA(25)')
ax.plot(range(len(data)), df_sma_25.values[n_data:], color='magenta', ls='-', label='SMA(25)')
ax.grid()

#ロゴ読み込み
logoURL = "https://neulab.co.jp/wp-content/uploads/logo.png" #logoファイルのURL
img_c = plt.imread(logoURL)
imagebox = OffsetImage(img_c, zoom=0.020) #画像をimageboxにいれる。
imagebox.image.axes = ax
im_sabo = AnnotationBbox(imagebox, (0, 9850), xybox=(0, 9950), xycoords="data", boxcoords="data", pad=0.3, frameon=False)

l1,l2 = ax.get_legend_handles_labels()
ax.legend(l1,l2, loc='upper right', fontsize=14, edgecolor='none', facecolor=canvas_color)

ax.set_ylabel("Price of Something", fontsize=22)
ax.set_ylim(9000., 10000.)
ax.yaxis.tick_right()
ax.yaxis.set_label_coords(0, 0.5)
ax.tick_params(labelsize=24, labelcolor=font_color, color=line_color)

ax.spines['left'].set_linewidth(0)
ax.spines['right'].set_linewidth(0)
ax.spines['top'].set_linewidth(0)
ax.spines['bottom'].set_linewidth(0)

xtick0 = 2
plt.xticks(range(xtick0,len(data),12), [x.strftime('%m/%d') for x in df_ema_5.index][xtick0::12])

plt.subplots_adjust(left=0.03, right=0.92, bottom=0.1, top=0.99)
plt.grid(which='major',color=line_color,linestyle='-')
plt.grid(which='minor',color=line_color,linestyle='-')

ax.set_axisbelow(True)

plt.savefig('Ema.png')

以上のコードをGoogle社の提供しているColaboratory上で公開しており、実際に動作させることができます。

リンクはこちら

EMAの基本的な使い方

EMAでもSMAと同様に移動平均線の位置関係やグランビルの法則を使って売買予想を行うことが出来ます。EMAが上向きの時は上昇局面、下向きの時は下落局面、横ばいなら方向感のない相場と考えます。また、複数のEMAの組み合わせ、ゴールデンクロス、デッドクロスなどもSMAと同様に使って予想をすることが出来ます。予想の方法についてより詳しくはSMAの項をご覧ください。

注意点

EMAは直近のデータを重視するためSMAよりは反応速度が改善されていますが、やはり移動平均を計算しているため急な相場の値動きには対応できません。


※このHPページで紹介しているテクニカル指標を使った取引ルールや売買シグナルの見方は一般的な考え方に基づくものであり、利益の増加や損失の減少を保証するものではありません。ご自身の判断にてお取引いただきますようお願いいたします。


現在、ニューラボでは人工知能による取引アルゴリズムを開発中です。11月にリリース予定。乞うご期待!
自動取引にご興味を持たれましたら お問い合わせページよりお気軽にお問合せください。