# 初めに
全部で4本の記事に分けて書いています!
- 第1回 株価予測_可視化編
- 第2回 株価予測_LSTM ver.1
- 第3回 株価予測_LSTM ver.2
- 第4回 株価予測_アプリ化編
実装コード
モチベーションとしては、時系列データをweb上から取得して、加工・集計、可視化、予測、アプリケーションへの組み込みまでをスムーズに実行できるようにすることです!今回は可視化編なので、得られたデータを可視化して細かく解析していきたいと思います。
このシリーズで行っている株価のチャート分析は意思決定のためのテクニカル指標に過ぎません。なので、予測に絶対は無いことと、株やFXで損する・得することの判断は自己責任でお願いします。ちなみに私は過去にFX(レバレッジ20倍)でテクニカル分析を過信し過ぎて。。。。なので皆さんも実際に取引する時はファンダメンタルズ分析もしっかり取り入れつつ、楽しく取引しましょう!!
今回の章立て
- 株価データについて
- 前提
- 実装
- データの期間:2005/01/01~2022/01/01
- データの期間:2021/01/01~2022/01/01
- 一目均衡表
- 最後に
- 参考文献
株価データについて
株価データといえばYahoo!ファイナンスを思い浮かべる人もいるかと思います。しかし、Yahoo!ファイナンスはWebスクレイピングが禁止されています(しかし、禁止を確認しながらスクレイピングしている強者もいました☜)。
以前の記事でも書きましたが、対象とするWebサーバに頻回アクセスするなど、過度な負担を与えると、DoS攻撃とみなされる場合があるのでスクレイピングは慎重に行う必要があります。現在、yahooファイナンスでは株価データのダウンロードを利用したい場合は、「VIP倶楽部」の「時系列データダウンロード」を利用すれば良いとのことです。
。。。pandas datareaderのこれは使用していいのでしょうか?
図1, from pandas-datareader -> Contents -> Remote Data Access
Yahoo Financeのデータが簡単に手に入る。。でも、私は怖いので使用しません!さて、今回の株価データの取得方法には、Pandas DataReaderを使用します。このライブラリは日経平均やナスダック、日本の個別銘柄のデータなど、経済データや金融商品(株とか指数とか)の価格データを取得することができるライブラリです(素晴らしい)。そして株価データ取得先はstooqです。stooqは各国インデックスや日本国内銘柄も取得可能です。
stooqで取得できるデータ
取得銘柄 | 指定コード |
---|---|
Apple | AAPL |
DOW30 | ^DJI |
NIKKEI225 | ^NKX |
極洋 | 1301.JP |
Zホールディングス | 4689.JP |
上場日経2倍 | 1358.JP |
前提
- 今回のコードは以前作成したDocker上のjupyter notebookで行なっています。
以前作成したディレクトリに入って、docker ps -a
で「CONTAINER ID」を確認します。コンテナを消していなければ、docker start CONTAINER ID
を実行します。消してしまっていたらdocker imagesから再度作成してください。その後、webブラウザ上でhttp://localhost:8888/
として環境に入ってください。
株価データやFXなどの分析指標は以下になります。
単純移動平均
移動平均線(Moving Average)は、ローソク足に絡むように描かれており、一定期間の価格の終値の平均値を繋ぎ合わせた折れ線グラフで、トレンド分析の代表格です。
https://www.jibunbank.co.jp/products/foreign_deposit/chart/help/sma/
ゴールデンクロス
移動平均線におけるゴールデンクロスとは、短期移動平均線が中長期移動平均線を下から上に突き抜ける現象のことです。一般的に買いシグナルとして利用され、ゴールデンクロスが発生すると相場が上昇する傾向があります。
デッドクロス
移動平均線におけるデッドクロスとは、短期移動平均線が中長期移動平均線を上から下に突き抜ける現象のことです。一般的に売りシグナルとして利用され、デッドクロスが発生すると相場が下落する傾向があります。
Volume
出来高とは、期間中に成立した売買の数量のこと。株式の場合、1日、1週間など、ある一定期間内に売買が成立した株数を指します。銘柄ごと以外に、市場全体や指標での出来高も評価されます。「出来高は株価に先行する」といわれることもあり、市場の活性度を測るバロメーターとして使われます。
https://www.ig.com/jp/glossary-trading-terms/volume-definition
MACD
トレンドを見る指標です。0以上なら上昇トレンド、0以下なら下降トレンドになる可能性が高いです。
https://www.jibunbank.co.jp/products/foreign_deposit/chart/help/macd/
RSI
RSI(Relative Strength Index)の頭文字をとった略語です。要するに、買われすぎか、売られすぎかを判断するための指標として利用されています。一般的に70~80%以上で買われすぎ、20~30%以下で売られすぎと判断されます。
https://www.jibunbank.co.jp/products/foreign_deposit/chart/help/rsi/
ボリンジャーバンド
終値は基本的に2本のライン(移動平均などの一定期間の尺度に対する±標準偏差の2倍の値の線)に収まるので、治らなかった時は、売られ過ぎ、買われ過ぎを判断する材料となります。
https://www.jibunbank.co.jp/products/foreign_deposit/chart/help/bollinger_band/
ローソク足
ローソク足とは、一定期間の相場の4本値(始値、高値、安値、終値)を用いて一本の棒状の足を生成したもので、このローソク足を並べていくことで、相場の状態や流れを一目でわかるようにしたチャートをローソク足チャートといいます。
https://www.jibunbank.co.jp/products/foreign_deposit/chart/help/candlestick/
一目均衡表
一目均衡表は、相場は「売り手」と「買い手」の『均衡』が崩れた方向へ動き、方向性が確立した後、相場の行方は『一目瞭然』である、という考え方に基づいています。
https://www.jibunbank.co.jp/products/foreign_deposit/chart/help/ichimoku/
# 実装
ライブラリのインポート
まずは必要なライブラリをインポートしていきます。
# ライブラリのインポート
import pandas as pd
import numpy as np
from pandas_datareader import data
import matplotlib.pyplot as plt
%matplotlib inline
# 今回Dockerを使用する原因を作ったやつ(テクニカル分析のためのライブラリ)
import talib as ta
# ローソク足、出来高、移動平均線、ボリンジャーバンドなどを表示できる便利なライブラリ
import mplfinance as mpf
# warningを消す
import warnings
warnings.simplefilter('ignore')
株価のデータをダウンロード
今回株価データを取得させていただいたのはZホールディングス(株)様です。Zホールディングス様はZホールディングスグループの重点課題(マテリアリティ)の特定において、ITによる社会課題の解決を重要視されていたので、今回の時系列モデル作成に株価データを使用させて頂きました。今回使用するデータは2005/01/01-2022/01/01までのデータに指定しています。
# データの期間:2005/01/01~2022/01/01
ここの部分df = data.DataReader('指定①', '指定②', start, end)
で取得したいデータを指定します。
- 指定①:AAPL, ^DJI, ^NKX, 4689.JP, 1358.JP(企業コードは検索すれば出てきます!)
- 指定②: 図1, from pandas-datareader -> Contents -> Remote Data Accessから選択
start = '2005-01-01'
end = '2022-01-01'
df = data.DataReader('4689.JP', 'stooq', start, end)
# データを確認していきます。
df.info()
df.head()
# df.tail() # 最後までデータたっぷり♪を確認します
移動平均, MACD, RSI, ボリンジャーバンド, ローソク足を作成します。
ta.MACDの引数にfastperiod=12:短期移動平均
, slowperiod=26:長期移動平均
, signalperiod=9:MACDシグナル
を渡します。matype=0
:単純移動平均、matype=1
:指数移動平均、matype=2
:加重移動平均です。
date=df.index
close = df['Close']
# 移動平均を作成(加重移動平均と指数平滑移動平均は今回は作成しない)
span5 = 5 # 5日移動平均
span25 = 25 # 25日移動平均
span50 = 50 # 50日移動平均
df['sma5'] = close.rolling(window=span5).mean() # min or max or mean
df['sma25'] = close.rolling(window=span25).mean()
df['sma50'] = close.rolling(window=span50).mean()
# MACD(トレンドの指標を見る)
df['macd'], df['macdsignal'], df['macdhist'] = ta.MACD(close, fastperiod=12, slowperiod=26, signalperiod=9)
# RSI(売られすぎ・買われすぎの判断材料)
df['RSI'] = ta.RSI(close, timeperiod=span25)
# ボリンジャーバンド(プラスナイナスの標準偏差の2倍を使用:基本的にはボリンジャーバンドに収まるが、治らない場合はRSI)
df['upper'], df['middle'], df['lower'] = ta.BBANDS(close, timeperiod=span25, nbdevdn=2, matype=0)
# candle(ローソク足で分析するために追記)
df_candle = df[['High', 'Low', 'Open', 'Close', 'Volume']]
作成した指標をプロットします。
plt.figure(figsize=(30, 15))
plt.subplot(5,1,1)
# 移動平均
plt.plot(date,close,label='Close',color='#99b898')
plt.plot(date,df['sma5'],label='sma5')
plt.plot(date,df['sma25'],label='sma25')
plt.plot(date,df['sma50'],label='sma50')
plt.legend()
# 出来高
plt.subplot(5,1,2)
plt.bar(date,df['Volume'],label='Volume',color='grey')
plt.legend()
# MACD
plt.subplot(5,1,3)
plt.fill_between(date, df['macdhist'], color = 'grey', alpha = 0.5, label='MACD_hist')
plt.hlines(0, start, end, "grey", linestyles="dashed")
plt.legend()
# RSI
plt.subplot(5,1,4)
plt.plot(date,df['RSI'],label='RSI',color='grey')
plt.ylim(0, 100)
plt.hlines([30, 50, 70], start, end, 'grey', linestyles='dashed')
plt.legend()
# ボリンジャーバンド
plt.subplot(5,1,5)
plt.plot(date, close, label = 'Close', color='#99b898')
plt.fill_between(date, df['upper'], df['lower'], color='grey', alpha=0.3)
plt.legend()
次にローソク足、MACD、RSI、出来高を表示します。
apds = [mpf.make_addplot(df['upper'], color='g'),
mpf.make_addplot(df['middle'], color='b'),
mpf.make_addplot(df['lower'], color='r'),
mpf.make_addplot(df['macdhist'], type='bar', color='gray',
width=1.0, panel=1, alpha=0.5, ylabel='MACD'),
mpf.make_addplot(df['RSI'], panel=2, type='line', ylabel='RSI'),
]
mpf.plot(df, type='candle', figsize=(30, 15), style='yahoo', volume=True,
addplot = apds, volume_panel=3, panel_ratios=(5,2,2,1))
しかし、データの期間が大きすぎるので上記の図ではイメージが湧きづらいと思います。私もFXで分析を行う際にはデータ軸を変化させたり、期間を指定します。なので、次はデータの期間を2021-01-01から2022-01-01に指定してより見やすく可視化していきます。
# データの期間:2021/01/01~2022/01/01
df.tail()
df = df.sort_index()
で日付の並び替えを行います。
df.head()
使用するデータの期間を指定します。
df2 = df[(df.index>='2021-01-01 00:00:00') & (df.index<='2022-01-01 00:00:00')]
df2.info()
先ほどと同様に移動平均, MACD, RSI, ボリンジャーバンド, ローソク足を作成します。
date2=df2.index
close = df2['Close']
# 移動平均を作成(加重移動平均と指数平滑移動平均は今回は作成しない)
span5 = 5 # 5日移動平均
span25 = 25 # 25日移動平均
span50 = 50 # 50日移動平均
df2['sma5'] = close.rolling(window=span5).mean() # min or max or mean
df2['sma25'] = close.rolling(window=span25).mean()
df2['sma50'] = close.rolling(window=span50).mean()
# MACD(トレンドの指標を見る)
df2['macd'], df2['macdsignal'], df2['macdhist'] = ta.MACD(close, fastperiod=12, slowperiod=26, signalperiod=9)
# RSI(売られすぎ・買われすぎの判断材料)
df2['RSI'] = ta.RSI(close, timeperiod=span25)
# ボリンジャーバンド(プラスナイナスの標準偏差の2倍を使用:基本的にはボリンジャーバンドに収まるが、治らない場合はRSI)
df2['upper'], df2['middle'], df2['lower'] = ta.BBANDS(close, timeperiod=span25, nbdevdn=2, matype=0)
# candle
df2_candle = df2[['High', 'Low', 'Open', 'Close', 'Volume']]
作成した図をプロットします。
plt.figure(figsize=(30, 15))
plt.subplot(5,1,1)
# 移動平均
plt.plot(date2,close,label='Close',color='#99b898')
plt.plot(date2,df2['sma5'],label='sma5')
plt.plot(date2,df2['sma25'],label='sma25')
plt.plot(date2,df2['sma50'],label='sma50')
plt.legend()
# 出来高
plt.subplot(5,1,2)
plt.bar(date2,df2['Volume'],label='Volume',color='grey')
plt.legend()
# MACD
plt.subplot(5,1,3)
plt.fill_between(date2, df2['macdhist'], color = 'grey', alpha = 0.5, label='MACD_hist')
plt.hlines(0, '2021-01-01', '2022-01-01', "grey", linestyles="dashed")
plt.legend()
# RSI
plt.subplot(5,1,4)
plt.plot(date2,df2['RSI'],label='RSI',color='grey')
plt.ylim(0, 100)
plt.hlines([30, 50, 70], '2021-01-01', '2022-01-01', 'grey', linestyles='dashed')
plt.legend()
# ボリンジャーバンド
plt.subplot(5,1,5)
plt.plot(date2, close, label = 'Close', color='#99b898')
plt.fill_between(date2, df2['upper'], df2['lower'], color='grey', alpha=0.3)
plt.legend()
さっきよりも見やすくなりました!
次にローソク足、ボリンジャーバンド、MACD、RSI、出来高も表示していきます。
apds = [mpf.make_addplot(df2['upper'], color='g'),
mpf.make_addplot(df2['middle'], color='b'),
mpf.make_addplot(df2['lower'], color='r'),
mpf.make_addplot(df2['macdhist'], type='bar', color='gray',
width=1.0, panel=1, alpha=0.5, ylabel='MACD'),
mpf.make_addplot(df2['RSI'], panel=2, type='line', ylabel='RSI'),
]
mpf.plot(df2, type='candle', figsize=(30, 15), style='yahoo', volume=True,
addplot = apds, volume_panel=3, panel_ratios=(5,2,2,1))
こちらも綺麗に見れますね!チャート分析の仕方などについては私が以前勉強した参考書を参考文献に記載しております。
#一目均衡表
- 一目均衡表で重要なワードとコンセプトについて
前述にもありますが、一目均衡表は、相場は「売り手」と「買い手」の『均衡』が崩れた方向へ動き、方向性が確立した後、相場の行方は『一目瞭然』である、という考え方に基づいています。
https://info.monex.co.jp/technical-analysis/indicators/004.html
https://www.jibunbank.co.jp/products/foreign_deposit/chart/help/ichimoku/
https://kabu.com/investment/guide/technical/04.html
###基準線
過去26日間の最高値と最安値の中心値を結んだ線で、中期的な相場の方向性を示します。
例えば、ドル・円相場の過去26日間の最高値が120円、最安値が100円だった場合、基準値は110円となります。
###遅行線
当日の終値を26日前に記入します。「前日比」は当日の価格と前日の価格を比較したものですが、「遅行線」は当日の価格と26日前の価格を比較していることになります。
###転換線
過去9日間の最高値と最安値の中心値を結んだ線で、短期的な相場の方向性を示します。
###先行スパン1
基準線と転換線の中心を、26日先に先行させて記入します。
基準線は過去26日間の中心、転換線は過去9日間の中心ですが、先行スパン1はそれぞれの中心となります。
###先行スパン2
過去52日間の最高値と最安値の中心を、26日先に先行させて記入します。
###雲
先行スパン1と2で囲まれた範囲のことを雲と呼び、抵抗帯として見ることができます。先行スパンが作り出す雲では、抵抗線と支持線を視覚的に捉えやすく分析しやすい指標となっています。
- まずは基準線を作成します。過去26日間の最高値、最安値を'df2['basic_line']'に渡します。
high =df2['High']
low = df2['Low']
max26 = high.rolling(window=26).max()
min26 = low.rolling(window=26).min()
df2['basic_line'] = (max26 + min26) / 2
データが生成できているか、確認します。
df2.tail()
転換線は過去9日間の最安値と最高値の平均を結んだ線です。
# 転換線
high9 = high.rolling(window=9).max()
low9 = low.rolling(window=9).min()
df2['turn_line'] = (high9 + low9) / 2
データが生成できているか確認します。
df2.tail()
基準線と転換線から先行スパン1を生成します。
# 先行スパン1
df2['sspan1'] = (df2['basic_line'] + df2['turn_line']) / 2
過去52日間の最安値と最高値の平均が先行スパン2です。
# 先行スパン2
high52 = high.rolling(window=52).max()
low52 = low.rolling(window=52).min()
df2['sspan2'] = (high52 + low52) / 2
データを確認してみます。
df2.tail()
遅行線を作成します。当日の終値を26日遅らせてプロットしていきます。
df2['slow_line'] = df2['Close'].shift(-25)
確認します。
df2.head()
最後に、一目均衡線を作成します。
lines = [mpf.make_addplot(df2['basic_line']), # 基準線
mpf.make_addplot(df2['turn_line']), # 転換線
mpf.make_addplot(df2['slow_line']), # 遅行線
]
labels = ['basic', 'turn', 'slow', 'span']
fig, ax = mpf.plot(df2, type='candle', figsize=(16,6), style='classic', xrotation=0, addplot=lines, returnfig=True,
fill_between=dict(y1=df2['sspan1'].values, y2=df2['sspan2'].values, alpha=0.5, color='gray'))
ax[0].legend(labels)
plt.show()
最後に
今回は株価予測_可視化編を行いました!結構長い記事になりましたが、こんな感じでデータは簡単に取得可能で、可視化も容易なのでどんどん分析できます!私は普段DMM FXを使用していますが、私のしたいことはPythonで大体できるな。。という印象です!次の記事ではLSTMで予測を行っています。
参考文献
FXデイトレード・スイングトレード
東大院生が考えたスマートフォンFX
ザ・トレーディング──心理分析・トレード戦略・リスク管理・記録管理
ガチ速FX 27分で256万を稼いだ“鬼デイトレ"
デイトレード
株とPython─自作プログラムでお金儲けを目指す本
Pythonで将来予測