PlotlyとTA-libでテクニカル分析チャートを描く
前回はPythonを利用して株価のローソク足チャートを描くのに、PlotlyとCufflinksを使いました。Cufflinksを使うと、ローソク足チャートもテクニカル分析用のチャートもすごく簡単にきれいに描けました。
それはそれで良いのですが、今後、アルゴリズムトレードなどを研究していくにあたり、テクニカル分析のチャートだけでなく、データを利用できるといいですよね。
いろいろと調べていくと、テクニカル分析にはTA-Libというモジュールが良いようです。早速利用してみましょう。
TA-Libのインストール
これがうまくいかないですよね〜。私はMacを使っているのですが、conda install ta-lib
, pip install ta-lib
もうまくいかない。ネットで調べると、困っている方がそれなりにいて、それぞれ解決策が異なっているようです。私の環境ではうまくいかず、どこかのサイトにPythonのバージョンを下げたらインストールできたという記事が載っていたので、試してみました。
新たにPython 3.5の仮想環境を作ったら、なんと今回はインストールできました。環境は個々に異なりますので、うまくいかない方はPythonのダウングレードを試してみると良いかもしれません。
TA-Libを使ってみる
TA-Lib
こちらのサイトに、簡単な使い方が書かれています。
かなりのテクニカル分析が網羅されているようで、人気があるのもわかる気がします。
さて、必要なライブラリをインポートしておきます。
# TA-Libをインポート import talib as ta # 株価を取得するためにpandas_datareaderもインポート import pandas_datareader.data as web # numpyとpandasは必須 import numpy as np import pandas as pd # チャートを描くのにPlotlyを利用します import plotly.offline as pyo import chart_studio.plotly as py import plotly.graph_objs as go
Jupyter Notebookを利用してPlotlyのグラフを作成するには、以下のコマンドを実行しておきます。
pyo.init_notebook_mode()
さて、前回同様、pandas_datareaderを利用して、Yahooから日経225の株価データを入手します。
df = web.DataReader('^N225', 'yahoo', '2018-01-01')
これで2018/1/1以降、直近までの株価が入手できます。
さて、データの最後の5行を見ておきます。
問題ないですね。もし、最後の1行にデータがない(ゼロ)の場合には、以下の通り、最終行を除いておきます。
df = df.iloc[:-1]
さあ、それでは、テクニカル分析用にデータを作成していきます。TA-Libはnumpyのarray形式でしか入力を受け付けないようですので、高値・安値・終値をDataFrame, Series形式からnumpy.array形式に変換します。始値は使いません。
h = np.array(df['High']) l = np.array(df['Low']) c = np.array(df.loc[:, 'Close']) #このようにしても同じです。
単純移動平均 (Simple Moving Average)
sma20 = ta.SMA(c, timeperiod=20) sma50 = ta.SMA(c, timeperiod=50) sma200 = ta.SMA(c, timeperiod=200) # PlotlyではDataFrameを使うので、以下の通り、dfに追加しておきます。 df['SMA20'] = sma20 df['SMA50'] = sma50 df['SMA200'] = sma200
指数平滑化移動平均(Exponential Moving Average)
ema20 = ta.EMA(c, timeperiod=20) ema50 = ta.EMA(c, timeperiod=50) ema200 = ta.EMA(c, timeperiod=200) df['EMA20'] = ema20 df['EMA50'] = ema50 df['EMA200'] = ema200
MACD (Moving Average Convergence/Divergence)¶
macd, macd_sig, macd_hist = ta.MACD(c, fastperiod=12, slowperiod=26, signalperiod=9) df['MACD'] = macd df['MACD_SIG'] = macd_sig df['MACD_HIST'] = macd_hist
RSI (Relative Strength Index)¶
rsi_long = ta.RSI(c, timeperiod=14) rsi_short = ta.RSI(c, timeperiod=7) df['RSI_LONG'] = rsi_long df['RSI_SHORT'] = rsi_short
WILLR (Williams' %R)¶
willr = ta.WILLR(h, l, c, timeperiod=14) df['WILLR'] = willr
Stochastic (STOCH)
slowk, slowd = ta.STOCH(h, l, c, fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0) df['SLOWK'] = slowk df['SLOWD'] = slowd
Bolinger Bands (BBANDS)
u_band, m_band, l_band = ta.BBANDS(c, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0) df['BBAND_U'] = u_band df['BBAND_M'] = m_band df['BBAND_L'] = l_band
ADX, DI+ and DI-
adx = ta.ADX(h,l,c,timeperiod=14) df['ADX'] = adx DI_plus = ta.PLUS_DI(h, l, c, timeperiod=14) DI_minus = ta.MINUS_DI(h, l, c, timeperiod=14) df['DI_plus'] = DI_plus df['DI_minus'] = DI_minus
Plotlyでチャート化してみる
さて、テクニカル分析データを作成しましたので、チャート化してみましょう。
Plotlyではdata
とlayout
をそれぞれ作成してから、グラフ化します。
まずはlayout
から。
layout = { 'height':1000, 'title' : {'text':'日経225推移', 'x':0.5}, 'titlefont': {'size':25}, 'xaxis': {'title': "", 'rangeslider':{'visible':False}}, 'yaxis' : {'domain': [.55, 1], 'title': "価格(円)" ,'side':"left", 'tickformat':',' }, 'yaxis2': {'domain': [.45, .55], 'title': "RSI", 'side':"right"}, 'yaxis3': {'domain': [.35, .45], 'title': "MACD", 'side':"right"}, 'yaxis4': {'domain': [.25, .35], 'title': "Will%R", 'side':"right"}, 'yaxis5': {'domain': [.15, .25], 'title': "STOCHASTIC", 'side':"right"}, 'yaxis6': {'domain': [.05, .15], 'title': "ADX&DI", 'side':"right"}, }
height
で全体の高さを指定しておいて、各yaxis
のdomain
にて、全体を1.0としたときの、各チャートのy軸に占める位置を[.05, .15]のように指定します。
まずは、ローソク足チャートを作成します。plotlyにはローソク足用のメソッドが用意されています。
trace = go.Candlestick( x = df.index, open = df['Open'], high = df['High'], low = df['Low'], close = df['Close'], yaxis = 'y1', name = '日経225' )
そして、以下の通り、data
とlayout
を指定します。
fig = {'data':[trace] ,'layout':layout}
ここで一旦チャートを描いてみましょう。
ここにテクニカル分析チャートを追加します。一度に追加してしまいましょう。
fig['data'].extend([ go.Scatter(yaxis="y1" ,x=df.index ,y=df["EMA20"], name= 'EMA20', line=dict(color='lightblue' ,width=1)), go.Scatter(yaxis="y1" ,x=df.index ,y=df["EMA50"] ,name= 'EMA50', line=dict(color='cyan' ,width=1)), go.Scatter(yaxis="y1" ,x=df.index ,y=df["EMA200"] ,name= 'EMA200', line=dict(color='darkblue' ,width=1)), go.Scatter(yaxis="y2" ,x=df.index ,y=df["RSI_LONG"] ,name= 'RSI Long', line=dict(color='yellowgreen' ,width=1)), go.Scatter(yaxis="y2" ,x=df.index ,y=df["RSI_SHORT"] ,name= 'RSI Short', line=dict(color='orange' ,width=1)), go.Scatter(yaxis="y3" ,x=df.index ,y=df["MACD"] ,name= 'MACD', line=dict(color='cornflowerblue' ,width=1)), go.Scatter(yaxis="y3" ,x=df.index ,y=df["MACD_SIG"] ,name= 'MACD(SIG)', line=dict(color='red' ,width=1)), go.Scatter(yaxis="y4" ,x=df.index ,y=df["WILLR"] ,name= 'WILL%R', line=dict(color='blue' ,width=1)), go.Scatter(yaxis="y5" ,x=df.index ,y=df["SLOWK"] ,name= 'STOCHASTIC %K', line=dict(color='blue' ,width=1)), go.Scatter(yaxis="y5" ,x=df.index ,y=df["SLOWD"] ,name= 'STOCHASTIC %D', line=dict(color='red' ,width=1)), go.Scatter(yaxis="y6" ,x=df.index ,y=df["ADX"] ,name= 'ADX', line=dict(color='darkgreen' ,width=2)), go.Scatter(yaxis="y6" ,x=df.index ,y=df["DI_plus"] ,name= 'D+', line=dict(color='orange' ,width=2)), go.Scatter(yaxis="y6" ,x=df.index ,y=df["DI_minus"] ,name= 'D-', line=dict(color='lightgreen' ,width=2)), ]) pyo.iplot(fig)
こんな感じで、うまく描けました!Plotlyはカーソルをグラフの上に持っていくと、数値が表示されるし、一部を拡大・縮小したりできるので、便利ですよね。そして、Plotlyに利用者として登録しておくと、上記のように動くグラフをブログに貼り付けたりできますので、おすすめです。
[2020/7/8 追記]
前回のブログにも記載した通り、今回のグラフも、よくみるとx軸には土日祝日もプロットされています。すなわち、プロットがなくギャップがあいているグラフとなっています。これを解消する方法を偶然知りましたので、追加情報として共有いたします。実は、layoutのxaxisに'xaxis': {'type': 'category'}を追加すると、土日祝日がx軸から除外されるようになります。ご確認いただけると幸いです。