【Python】移動平均(SMA)と指数移動平均(EMA)を計算する

この記事は約7分で読めます。

 

Pythonでテクニカル指標を計算する

 

今回はPythonでよく使うテクニカル指標をライブラリの関数で一発で計算するのではなく、計算式をコードに実装していこうと思います。

 

データを用意する

 

まずは計算に使用するデータを用意します。今回はビットコインのビットコインの価格データを使います。コードは↓

 

#ライブラリの読み込み
from datetime import datetime
import pandas as pd
import requests
import json
import pandas as pd

def get_btcprice(ticker,_max):
    url = ('https://api.coingecko.com/api/v3/coins/')+ticker+('/market_chart?vs_currency=jpy&days=')+_max
    r = requests.get(url)
    r2 = json.loads(r.text)
    return r2

#jsonから価格データだけをPandasに変換して抽出する
def reshape_pricedata(r2):
    s = pd.DataFrame(r2['prices'])
    s.columns = ['date','price']
    date = []
    for i in s['date']:
        tsdate = int(i/1000)
        loc = datetime.utcfromtimestamp(tsdate)
        date.append(loc)
    s.index = date
    del s['date']
    return s

#ビットコインの全期間の価格データを取得する
r2 = get_btcprice('bitcoin','max')
btcprice = reshape_pricedata(r2)
btcprice.head()

 

 

Pythonで移動平均線を計算する

 

まずは定番の移動平均線から実装していきます。移動平均の計算式は↓のようになっています。

 

 

移動平均線の計算式=直近の終値+1本前の終値+2本前の終値・・・+(N-1)本目の終値)÷N

引用元:https://info.monex.co.jp/technical-analysis/indicators/001.html

 

 

(例)5日移動平均線の場合
5日移動平均線 = (当日終値+前日終値+2日前終値+3日前終値+4日前終値)÷5

 

 

これをPythonで実装すると↓のようになります。

 

# 移動平均をPythonで計算する関数
def calc_sma(price_data, terms=5, index=True):
    """
    price_data :DataFrame
        pandasのデータフレーム
    terms : int
        移動平均線の期間
    index :bool値
        戻り値のindexをdatetime型にするかどうか
    """
    rolling_means = []
    for i in range(len(price_data)):
        data = price_data['price'][i-terms:i]
        sum_ = 0
        if data.empty:
            pass
        else:
            for e in data:
                sum_ += e
                rolling_terms = [data.index[-1], sum_/terms]
                rolling_means.append(rolling_terms)

    # データフレームのindexをそのままにしておく
    if index:
        return pd.DataFrame(rolling_means, columns=['date', 'price'])
    #データフレームのINDEXを日付データにする
    else:
        df = pd.DataFrame(rolling_means)
        df.index = df[0].values
        df = df.drop(0, axis=1)
        df.columns = ['price']
    return df


# 25日移動平均線を計算する
SMA25 =calc_sma(terms=25, index=True)
SMA25

 

 

Pythonで指数移動平均を計算する

 

次は指数移動平均線の計算を行っていきます。指数移動平均線はMACDなど有名なテクニカル指標に用いられており、テクニカル指標の計算ではよく出てくる指標です。

 

 

指数移動平均の計算式:

n日間の指数平滑移動平均
1日目=(当日も含め)n日の終値の平均
2日目以降=前日の指数平滑移動平均+α×{当日終値-前日の指数平滑移動平均}
※α(平滑定数)=2÷(n+1)

引用元:https://www.sevendata.co.jp/shihyou/technical/heikatsuidou.html

 

 

これをPythonで実装すると↓のようになります。

 

# 指数移動平均線を計算する関数
def calc_ema(price_data, terms, index=True):
    # 移動平均を計算する
    sma = calc_sma(price_data=price_data, terms=terms, index=False)
    # 指数移動平均の計算に使うαを求める    
    a = 2 / (terms + 1)

    # 指数移動平均を計算する
    ema = []
    for i in range(len(sma)+1):
        if i==0:
            ema_data = float(sma.iloc[0].values)
            ema.append([sma.index[0], ema_data])
        else:
            ema_data = ema[i-1][1] + a*(float(price_data.iloc[(i)+(terms-1)].values)-ema[i-1][1])
            ema.append([price_data.index[terms-1+i], ema_data])

    # 出力形式を変える
    if index:
        return pd.DataFrame(ema, columns=['date', 'price'])
    else:
        df = pd.DataFrame(ema)
        df.index = df[0].values
        df = df.drop(0, axis=1)
        df.columns = ['price']
    return df

# 5日指数移動平均線を計算する
ema5 = calc_ema(price_data=btcprice, terms=5, index=True)
ema5

 

 

EMAの計算式が2通りあるのか、サイトによって表現が違っていてよくわかりませんでしたが、とりあえず戻り値のデータフレームの値はPandasのEMAを算出する関数であるbtcprice.ewm(span=5).mean()とほぼ同じ数値になっているので、これであってると思います。

 

ですが、最初の方の数値が若干違っていてそれが少し気になるので、関数の中身とか要検証って感じです。

 

 

終わり

 

30分程度で書いたので処理速度とか最適化のロジックとかはがばがばですが、
こんな感じでテクニカル指標はPythonを使わずとも実装することが可能です。

 

まあPythonでのテクニカル指標の計算はtalibとPandasで事足りますが、こういうのもたまにはやっておくといいかもしれないです。

 

 

関連記事:【Python】テクニカル指標が簡単に計算できるTa-libの使い方

関連記事: Pythonを使って有名なテクニカル指標を計算してみる

関連記事:【Python】pandasでビットコイン価格のローソク足と移動平均線を計算してプロットする

 

 

コメント

タイトルとURLをコピーしました