2
Help us understand the problem. What are the problem?

posted at

【Python】株価データ分析 株価チャートを描く~mplfinance編 その3~

はじめに

前回は,mplfinance を使ってローソク足,ボリンジャーバンド,MACD,RSI チャートを描いてみた

今回は一目均衡表チャートを描いてみる

一目均衡表チャートとは

五本の線とローソク足をあわせて一目均衡表チャートという
詳しい説明はこちらなどにおまかせるとして

一目均衡表チャートを描く上での最低限の用語と計算式を整理しておく

一目均衡表の五線と抵抗帯

  • 基準線: (当日を含めた過去26日間の最高値+最安値) $\div$ 2
  • 転換線: (当日を含めた過去9日間の最高値+最安値) $\div$ 2
  • 先行スパン1: {(転換値+基準値) $\div$ 2}を26日先行させて表示
  • 先行スパン2: {(当日を含めた過去52日間の最高値+最安値) $\div$ 2}を26日先行させて表示
  • 遅行スパン: 当日の終値を26日遅行させて表示
  • 抵抗帯: 先行スパン1と先行スパン2の間(先行スパン1と先行スパン2の間の色を塗る)

一目均衡表の五線の値を求める関数

def ichimoku(o, h, l, c):
    ## 当日を含めた過去26日間の最高値
    ## 当日を含めた過去 9日間の最高値
    ## 当日を含めた過去52日間の最高値
    max26 = h.rolling(window=26).max()
    max9  = h.rolling(window=9).max()
    max52 = h.rolling(window=52).max()
    ## 当日を含めた過去26日間の最安値
    ## 当日を含めた過去 9日間の最安値
    ## 当日を含めた過去52日間の最安値
    min26 = l.rolling(window=26).min()
    min9  = l.rolling(window=9).min()
    min52 = l.rolling(window=52).min()

    ## 基準線=(当日を含めた過去26日間の最高値+最安値)÷2
    ## 転換線=(当日を含めた過去9日間の最高値+最安値)÷2
    kijun = (max26 + min26) / 2
    tenkan = (max9 + min9) / 2
    ## 先行スパン1={(転換値+基準値)÷2}を26日先行させて表示
    senkospan1 = (kijun + tenkan) / 2
    senkospan1 = senkospan1.shift(26)
    ## 先行スパン2={(当日を含めた過去52日間の最高値+最安値)÷2}を26日先行させて表示
    senkospan2 = (max52 + min52) / 2
    senkospan2 = senkospan2.shift(26)
    ## 遅行スパン= 当日の終値を26日遅行させて表示
    chikouspan = c.shift(-26)

    return kijun, tenkan, senkospan1, senkospan2, chikouspan

前回の,【Python】株価データ分析 株価チャートを描く~mplfinance編 その2~のコードからの主な変更点を書いておく

一目均衡表の五線の値を求める関数を呼び出し

# 一目均衡表
kijun, tenkan, senkospan1, senkospan2, chikouspan = ichimoku(o, h, l, c)

プロットを作成する際に,mplfinance.make_addplot を呼ぶが,
一目均衡表の五線をプロットする際のパラメータ辞書を用意して,プロットする
ボリンジャーバンドは ±2σ のみの表示に変更する(チャートがゴチャゴチャするので)

# 一目均衡表 axes No.1 に描く
ichimokuargs = dict(ax=ax1, width=.5)

# プロットを作成する(ボリンジャーバンド,MACD,RSI,一目均衡表)
ap = [
##    mpf.make_addplot(bbh1, **bbargs),
##    mpf.make_addplot(bbl1, **bbargs),
    mpf.make_addplot(bbh2, **bbargs),
    mpf.make_addplot(bbl2, **bbargs),
##    mpf.make_addplot(bbh3, **bbargs),
##    mpf.make_addplot(bbl3, **bbargs),
    mpf.make_addplot(macd_, **macdargs, color='blue'),
    mpf.make_addplot(macdsignal, **macdargs, color='orange'),
    mpf.make_addplot(histogramplus, **macdargs, color='red', type='bar'),
    mpf.make_addplot(histogramminus, **macdargs, color='green', type='bar'),
    mpf.make_addplot(rsi_, **rsiargs, color='blue'),
    mpf.make_addplot(kijun, **ichimokuargs, color='orange'),
    mpf.make_addplot(tenkan, **ichimokuargs, color='royalblue'),
    mpf.make_addplot(senkospan1, **ichimokuargs, color='black'),
    mpf.make_addplot(senkospan2, **ichimokuargs, color='purple'),
    mpf.make_addplot(chikouspan, **ichimokuargs, color='red')
]

先行スパン1と先行スパン2の間を塗りつぶす

# 一目均衡表(axes=1)の先行スパン1と先行スパン2の間を塗りつぶす
ax1.fill_between(x=range(0, len(df.index)), y1=senkospan1.values, y2=senkospan2.values, alpha=0.5, color='gray')

まとめ

import numpy as np
import pandas as pd
import pandas_datareader.data as pdr
import datetime
from dateutil.relativedelta import relativedelta
import matplotlib.pyplot as plt
import mplfinance as mpf

# 12か月チャート
month = 12
# チャートの基本設定
kwargs = dict(type = 'candle', style = 'yahoo') ## starsandstripes, yahoo

# 12か月前から本日までのデータを取得する
ed = datetime.datetime.now()
st = ed - relativedelta(months = month)
# トヨタ
df = pdr.DataReader('7203.T', 'yahoo', st, ed)

def bollingerband(c, period):
    bbma = c.rolling(window=period).mean() ## 平均
    bbstd = c.rolling(window=period).std() ## 標準偏差
    bbh1 = bbma + bbstd * 1
    bbl1 = bbma - bbstd * 1
    bbh2 = bbma + bbstd * 2
    bbl2 = bbma - bbstd * 2
    bbh3 = bbma + bbstd * 3
    bbl3 = bbma - bbstd * 3
    return bbh1,bbl1,bbh2,bbl2,bbh3,bbl3

def macd(c, n1, n2, ns):
    ema_short = c.ewm(span=n1,adjust=False).mean()
    ema_long = c.ewm(span=n2,adjust=False).mean()
    macd = ema_short - ema_long
    signal = macd.ewm(span=ns,adjust=False).mean()
    histogram = macd - signal
    histogramplus = histogram.where(histogram > 0, 0)
    histogramminus = histogram.where(histogram < 0, 0)
    return macd,signal,histogram,histogramplus,histogramminus

def rsi(c, period):
    diff = c.diff() #前日比
    up = diff.copy() #上昇
    down = diff.copy() #下落
    up = up.where(up > 0, np.nan) #上昇以外はnp.nan
    down = down.where(down < 0, np.nan) #下落以外はnp.nan
    #upma = up.rolling(window=period).mean() #平均
    #downma = down.abs().rolling(window=period).mean() #絶対値の平均
    upma = up.ewm(span=period,adjust=False).mean() #平均
    downma = down.abs().ewm(span=period,adjust=False).mean() #絶対値の平均
    rs = upma / downma
    rsi = 100 - (100 / (1.0 + rs))
    return rsi

def ichimoku(o, h, l, c):
    ## 当日を含めた過去26日間の最高値
    ## 当日を含めた過去 9日間の最高値
    ## 当日を含めた過去52日間の最高値
    max26 = h.rolling(window=26).max()
    max9  = h.rolling(window=9).max()
    max52 = h.rolling(window=52).max()
    ## 当日を含めた過去26日間の最安値
    ## 当日を含めた過去 9日間の最安値
    ## 当日を含めた過去52日間の最安値
    min26 = l.rolling(window=26).min()
    min9  = l.rolling(window=9).min()
    min52 = l.rolling(window=52).min()

    ## 基準線=(当日を含めた過去26日間の最高値+最安値)÷2
    ## 転換線=(当日を含めた過去9日間の最高値+最安値)÷2
    kijun = (max26 + min26) / 2
    tenkan = (max9 + min9) / 2
    ## 先行スパン1={(転換値+基準値)÷2}を26日先行させて表示
    senkospan1 = (kijun + tenkan) / 2
    senkospan1 = senkospan1.shift(26)
    ## 先行スパン2={(当日を含めた過去52日間の最高値+最安値)÷2}を26日先行させて表示
    senkospan2 = (max52 + min52) / 2
    senkospan2 = senkospan2.shift(26)
    ## 遅行スパン= 当日の終値を26日遅行させて表示
    chikouspan = c.shift(-26)

    return kijun, tenkan, senkospan1, senkospan2, chikouspan

# float 型に
df['Open'] = df['Open'].astype(float)
df['High'] = df['High'].astype(float)
df['Low'] = df['Low'].astype(float)
df['Close'] = df['Close'].astype(float)
o = df['Open']
c = df['Close']
l = df['Low']
h = df['High']

'''
チャートを描く
'''
# ボリンジャーバンド(移動平均25日線)
bbh1, bbl1, bbh2, bbl2, bbh3, bbl3 = bollingerband(c, 25)
# MACD(短期=12,長期=26,シグナル=9)
macd_, macdsignal, histogram, histogramplus, histogramminus = macd(c, 12, 26, 9)
# RSI(14日)
rsi_ = rsi(c, 14)
# 一目均衡表
kijun, tenkan, senkospan1, senkospan2, chikouspan = ichimoku(o, h, l, c)

# 高さの比を 3:1:1 で GridSpec を用意する
fig = mpf.figure(figsize=(9.6, 9.6), style='starsandstripes')
gs = fig.add_gridspec(3, 1, hspace=0, wspace=0, height_ratios=(3, 1, 1))
(ax1,ax2,ax3) = gs.subplots(sharex='col')

# ボリンジャーバンドは axes No.1 に描く
bbargs = dict(ax=ax1, width=.5, linestyle='dashdot', color='black')
# MACD は axes No.2 に描く
macdargs = dict(ax=ax2, width=1, ylabel='MACD')
# RSI は axes No.3 に描く
rsiargs = dict(ax=ax3, width=1, ylabel='RSI')
# 一目均衡表 axes No.1 に描く
ichimokuargs = dict(ax=ax1, width=.5)

# プロットを作成する(ボリンジャーバンド,MACD,RSI,一目均衡表)
ap = [
    mpf.make_addplot(bbh2, **bbargs),
    mpf.make_addplot(bbl2, **bbargs),
    mpf.make_addplot(macd_, **macdargs, color='blue'),
    mpf.make_addplot(macdsignal, **macdargs, color='orange'),
    mpf.make_addplot(histogramplus, **macdargs, color='red', type='bar'),
    mpf.make_addplot(histogramminus, **macdargs, color='green', type='bar'),
    mpf.make_addplot(rsi_, **rsiargs, color='blue'),
    mpf.make_addplot(kijun, **ichimokuargs, color='orange'),
    mpf.make_addplot(tenkan, **ichimokuargs, color='royalblue'),
    mpf.make_addplot(senkospan1, **ichimokuargs, color='black'),
    mpf.make_addplot(senkospan2, **ichimokuargs, color='purple'),
    mpf.make_addplot(chikouspan, **ichimokuargs, color='red')
]

# RSI(axes=3) の25%と75%に線を引く
ax3.hlines(xmin=0, xmax=len(df.index), y=25, linewidth=1, color='red')
ax3.hlines(xmin=0, xmax=len(df.index), y=75, linewidth=1, color='red')

# 一目均衡表(axes=1)の先行スパン1と先行スパン2の間を塗りつぶす
ax1.fill_between(x=range(0, len(df.index)), y1=senkospan1.values, y2=senkospan2.values, alpha=0.5, color='gray')

# ローソク足を描く,用意したプロットを渡す
mpf.plot(df, ax=ax1, addplot=ap, style='starsandstripes', type='candle', xrotation=30, ylabel='Price')
mpf.show()

このようなチャートが描かれる

image.png

おわりに

一目均衡表を描くことはできたが,
抵抗帯の未来の部分が描けていないのがいけてない…

次回はこの問題を解決してみたい

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
2
Help us understand the problem. What are the problem?