11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OHLCデータからテクニカル指標を求める

Last updated at Posted at 2019-05-09

検証環境

  • MacOS Mojave 10.14.4
  • Python 3.6.8
  • numpy 1.15.0
  • pandas 0.23.4
  • matplotlib 2.2.2
  • mpl-finance 0.10.0

OHLCデータ

OHLCデータは、Cryptowatchから取得したBTCFX/JPYの1分足データを使用しました。
https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc?periods=60&after=1557172800&before=1557176340

import json
import requests
import datetime
import numpy as np
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
from datetime import datetime, timedelta, timezone
from pandas import DataFrame, Series, to_datetime, concat
from mpl_finance import candlestick_ohlc

if __name__ == '__main__':
    response = json.loads(requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc?periods=60&after=1557172800&before=1557176340").text)

    # 7番目の要素はdocsに記載がないので何なのか不明
    df = pd.DataFrame(response['result']['60'], columns=['date','open','high','low','close','volume','unknown']).dropna().drop(columns=['volume','unknown'])
    # print(df.head(3))
    #         date    open    high     low   close
    # 0  1557432000  664434  665011  663901  664755
    # 1  1557432060  664826  664826  663800  663834
    # 2  1557432120  663834  664117  663723  664069

    # レスポンスのタイムスタンプがUnixTimestamp形式なのでdatetime型に変換し、pandas.DatetimeIndexを設定する
    df['date'] = pd.to_datetime(df['date'], unit='s', utc=True)
    df.set_index('date', inplace=True)
    df.index = df.index.tz_convert('Asia/Tokyo')
    # print(df.head(3))
    #                             open    high     low   close
    # date                                                     
    # 2019-05-10 05:00:00+09:00  664434  665011  663901  664755
    # 2019-05-10 05:01:00+09:00  664826  664826  663800  663834
    # 2019-05-10 05:02:00+09:00  663834  664117  663723  664069

    plt.style.use('ggplot')

    ax = plt.subplot()
    ax.xaxis.set_major_locator(mdates.AutoDateLocator())
    ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M', tz=timezone(timedelta(hours=9))))

    # candlestick_ohlc の第二引数に渡すタプルイテレータを生成
    # @see https://github.com/matplotlib/mpl_finance/blob/master/mpl_finance.py
    quotes = zip(mdates.date2num(df.index), df['open'], df['high'], df['low'], df['close'])
    candlestick_ohlc(ax, quotes, width=(1/24/len(df))*0.7, colorup='g', colordown='r')

    plt.show()

Figure_1.png

単純移動平均 (SMA)

def sma(ohlc: DataFrame, period=21) -> Series:
    return Series(
        ohlc['close'].rolling(period).mean(),
        name=f'SMA {period}',
    )
sma(df, 5).plot.line(color='y', legend=True)
sma(df, 10).plot.line(color='c', legend=True)
sma(df, 21).plot.line(color='m', legend=True)

Figure_2.png

指数平滑移動平均 (EMA)

def ema(ohlc: DataFrame, expo=21) -> Series:
    return Series(
        ohlc['close'].ewm(span=expo).mean(),
        name=f'EMA {expo}',
    )
ema(df, 5).plot.line(color='y', legend=True)
ema(df, 10).plot.line(color='c', legend=True)
ema(df, 21).plot.line(color='m', legend=True)

Figure_3.png

加重移動平均 (WMA)

def wma(ohlc: DataFrame, period: int = 9) -> Series:
    # WMA = ( 価格 * n + 価格(1) * n-1 + ... 価格(n-1) * 1) / ( n * (n+1) / 2 )
    denominator = (period * (period + 1)) / 2
    weights = Series(np.arange(1, period + 1)).iloc[::-1]

    return Series(
        ohlc['close'].rolling(period, min_periods=period).apply(lambda x: np.sum(weights * x) / denominator, raw=True),
        name=f'WMA {period}'
    )
wma(df, 5).plot.line(color='y', legend=True)
wma(df, 10).plot.line(color='c', legend=True)
wma(df, 21).plot.line(color='m', legend=True)

Figure_4.png

標準偏差

標準偏差
def sd(ohlc: DataFrame, period=10, ddof=0) -> float:
    return ohlc['close'].tail(period).std(ddof=ddof)

ddofは減算する自由度の数を示します。ddof=1を指定することで、不偏分散による標準偏差となります。
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.std.html

Delta Degrees of Freedom. The divisor used in calculations is N - ddof, where N represents the number of elements.

>>> sd(df, ddof=0)
232.7845570479279
>>> sd(df, ddof=1)
245.37646812828467

参考文献

11
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?