【python】株価チャートのテクニカル/ローソク足パターン分析

IT全般

以前の記事で、日本株の株価のデータの取得方法とローソク足チャートへの描画方法の紹介を行いました。

今回は、得られたチャートをもとに、TA-Libというパッケージを使用して、テクニカル分析やローソク足パターンを検出し、チャート上に描画する方法を紹介します。

データの準備

チャートデータ自体は以下のリンク先に記載の手順で、日付・Open・High・Low・Close・Volumeが含まれる価格データを用意します。

各指標の計算方法

tempというデータフレームに価格データを格納し、TA-Libを使用し、各指標を計算します。

TA-Libでは、インジケーターだけでなく、ローソク足パターンの判別も可能です。

ここでは、移動平均線・MACD・ストキャスティクス・4種のローソク足のパターンを計算しています。

ローソク足パターンでは、「-100」「0」「100」の値が返ってきます。

各値の意味は不確かですが、0はパターンなし、100は最新の曜日が陽線でパターン発生になった場合、-100は最新の曜日が陰線でパターンが発生した場合のようです。

import pandas as pd
import talib as ta

# 5,25,50日移動平均線の計算
temp["5D_SMA"] = ta.SMA(temp["Close"], timeperiod=5)
temp["25D_SMA"] = ta.SMA(temp["Close"], timeperiod=25)
temp["50D_SMA"] = ta.SMA(temp["Close"], timeperiod=50)


# MACD
temp['MACD'],temp['MACDSIGNAL'], temp['MACDHIST'] = ta.MACD(temp['Close'], fastperiod=12, slowperiod=26, signalperiod=9)

# ストキャスティクス
temp['stochRSI_k'], temp['stochRSI_d'] = ta.STOCH(temp['High'],temp['Low'],temp['Close'], 
                                           fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0)

# ローソク足パターン
temp['Marubozu'] = ta.CDLMARUBOZU(temp['Open'],temp['High'],temp['Low'],temp['Close'])
temp['Engulfing_Pattern'] = ta.CDLENGULFING(temp['Open'],temp['High'],temp['Low'],temp['Close'])
temp['Hammer'] = ta.CDLHAMMER(temp['Open'],temp['High'],temp['Low'],temp['Close'])
temp['Dragonfly_Doji'] = ta.CDLDRAGONFLYDOJI(temp['Open'],temp['High'],temp['Low'],temp['Close'])

TA-Libで計算可能な指標一覧

Site not found · GitHub Pages

チャート上への指標の可視化

記事の最後に記載のコードのように、チャート上に各指標を表示させたローソク足チャートを作成しました。

plotlyで作成しているため、表示部分の拡大縮小が可能で遊べる感じのチャートになっています。

コード全体

import pandas as pd
import talib as ta
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import datetime
import pandas_datareader as pdr

def candle_patt(df,x,all_fig,params):
    '''ローソク足パターンのローソク足チャートへの描画'''
    
    # パターンチェック & シグナル値を描画用に置き換え
    df['Marubozu'] = ta.CDLMARUBOZU(df['Open'],df['High'],df['Low'],df['Close']) * df['High'] / 100
    df['Engulfing_Pattern'] = ta.CDLENGULFING(df['Open'],df['High'],df['Low'],df['High']) * df['Close'] / 100
    df['Hammer'] = ta.CDLHAMMER(df['Open'],df['High'],df['Low'],df['Close']) * df['High'] / 100
    df['Dragonfly_Doji'] = ta.CDLDRAGONFLYDOJI(df['Open'],df['High'],df['Low'],df['Close']) * df['High'] / 100    
    
    # 列名を作成
    pattern_list = list(df.loc[:,'Marubozu':'Dragonfly_Doji'].columns)
    label_list = [ k+'_label' for k in list(df.loc[:,'Marubozu':'Dragonfly_Doji'].columns)]
    
    # 0をNaNで埋める
    df[pattern_list] = df[pattern_list].where(~(df[pattern_list] == 0.0), np.nan)
        
    # 売り買いラベルの作成
    df[label_list] = df[pattern_list]
    df[label_list] = df[label_list].where(~(df[label_list] > 0), 1)
    df[label_list] = df[label_list].where(~(df[label_list] < 0), -1)
    df[label_list] = df[label_list].where(~(df[label_list] == 1), '買い')
    df[label_list] = df[label_list].where(~(df[label_list] == -1), '売り')
    
    # 発生価格の絶対値化
    df[pattern_list] = df[pattern_list].abs()
    
    # 各シグナルを描画
    for pattern in list(df.loc[:,'Marubozu':'Dragonfly_Doji'].columns):
        all_fig.add_trace(go.Scatter(x=x, y=df[pattern],mode='markers+text',text=df[label_list],textposition="top center",name=pattern,
                                    marker = dict(size = 9),opacity=0.8),row=1, col=1)
    
    return all_fig


# 各指標の描画用関数
def call_indi(df,x,all_fig,params):
    '''テクニカル分析の描画'''
    
    # 移動平均線
    if 'SMA' in params.keys(): 
        # 移動平均線の計算と描画
        for day in params['SMA']:
            df[str(day) + 'D_SMA'] = ta.SMA(df["Close"], timeperiod=day) # 計算
            all_fig.add_trace(go.Scatter(x=x, y=df[str(day) + 'D_SMA'],mode='lines',name=str(day) + 'D_SMA'),row=1, col=1) # 描画
        
    # MACD
    if 'MACD' in params.keys():
        df['MACD'],df['MACDSIGNAL'],_ = ta.MACD(pdr['Close'], fastperiod=params['MACD']['short'], 
                                                slowperiod=params['MACD']['long'], signalperiod=9)# 計算

        all_fig.add_trace(go.Scatter(x=x, y=df['MACD'],name='MACD',mode='lines'),row=3, col=1) # MACD 描画
        all_fig.add_trace(go.Scatter(x=x, y=df['MACDSIGNAL'],name='SIGNAL',mode='lines'),row=3, col=1) # MACD シグナル描画
        
    # ストキャスティクス
    if 'ストキャスティクス' in params.keys():
        STOCH = params['ストキャスティクス']
        df['stoch_k'], df['stoch_d'] = ta.STOCH(df['High'],df['Low'],df['Close'], 
                                           fastk_period=STOCH['fastk_period'], slowk_period=STOCH['slowk_periodg'], slowk_matype=0, slowd_period=STOCH['slowd_period'], slowd_matype=0)

        all_fig.add_trace(go.Scatter(x=x, y=df['stoch_k'],name='%K',mode='lines'),row=4, col=1) # Slow%K 描画
        all_fig.add_trace(go.Scatter(x=x, y=df['stoch_d'],name='%D',mode='lines'),row=4, col=1) # Slow%D 描画    
                          
    return all_fig

def plot_chart(df,params):
    
    # 期間のデータの加工
    long_day = pd.Series(data=np.nan,index=pd.date_range(start=df.index[-1], end=df.index[-1] + datetime.timedelta(days=20), freq='D'),name='add_days')
    df = pd.merge(df, long_day, left_index=True, right_index=True,how='outer').drop(['add_days'],axis=1)
    
    # 土日でデータのスペースが空くのを補正するための設定
    x = np.arange(df.shape[0])
    interval = 20
    vals = np.arange(df.shape[0],step=interval)
    labels = list(df[::interval].index)
    
    # ローソク足チャート部分
    trace1 = go.Candlestick(
                    x=x,
                    open=df['Open'],
                    high=df['High'],
                    low=df['Low'],
                    close=df['Close']
                    )
    
    # 複数グラフの作図設定:4行1列
    all_fig = make_subplots(rows=4, cols=1,shared_xaxes=True,vertical_spacing=0.08,row_heights=[0.4,0.1,0.2,0.2])
    
    all_fig.add_trace(trace1,row=1, col=1)

    # 指標の描画
    all_fig = call_indi(df,x,all_fig,params)
    
    # ローソクパターンの描画
    all_fig = candle_patt(df,x,all_fig,params)
    
    # 描画の設定
    all_fig.update_xaxes(tickvals=vals,ticktext=labels,tickangle=-45, row=4, col=1) #軸の値
    all_fig.update_yaxes(range=[0, 100],dtick=20, row=4, col=1) #y軸の値
    all_fig.update_layout(width=1000,height=1000)
    
    all_fig.show()

#-----------------------------
# 株データの取得
pdr =pdr.stooq.StooqDailyReader(symbols='6701.jp', start='JAN-01-2019', end="JUL-3-2020").read().sort_values(by='Date',ascending=True)

# テクニカル分析のパラメータ設定
params = {
         'SMA':[5,25,50],
         'MACD':{'short':12,'long':26},
         'ストキャスティクス':{'fastk_period':14,'slowk_periodg':3,'slowd_period':3},
         }

# 描画関数の呼び出し
plot_chart(pdr,params)

コメント

  1. k より:

    勉強させて頂いております。

    このプログラムを走らせると横軸に時刻が出てきますが、時刻を出さないためにはどのようにすると良いでしょうか?

    分析ツールの関数を使わない場合は、CSV出力とインポートを噛ませることで解決できたのですが、この関数を使う場合は、期間のデータの加工のところでうまく動かないです。

    解決方法を教えて頂けますと助かります。

    • kiseno より:

      コメントいただきありがとうございます
      現在、諸事情で手元に環境がなく試せない状況で、確かな返答はできないのですが、
      x軸のラベルテキストのリストを作成する際(下記コード)に、strftime関数を使用して形式変更するなどで対応できないでしょうか?

      labels = list(df[::interval].index)

      参考:strftime
      https://techacademy.jp/magazine/18883

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