カスタム関数シリーズでは、便利なオリジナル関数を紹介しています。
※カスタム関数は、一般的には「ユーザー定義関数」と呼ばれています
read_stockdata() 無料で株価をダウンロードする関数を作る
株価データをダウンロードして、数値解析をしたり、グラフを描いたりすることはpythonでは簡単にできてしまいます。
まず株価データは、pndas_datareaderというライブラリーを使います。
ライブラリはインストールが必要ですが、pipを使えば、簡単に導入できます
pip install pandas_datareader
でOK。
def read_stockdata(code='7203.JP',start='2015-01-01',end='2020-07-25',graph=True): # ■株データダウンロード_stooq_J725
#!pip install pandas_datareader
from pandas_datareader import data
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df=data.DataReader(code,'stooq',start,end)
df=df.sort_index() #indexの日付をソートする
print(df)
if graph:
date=df.index
price=df['Close']
plt.figure(figsize=(30,10))
span01=5
span02=25
span03=75
df['sma05']=price.rolling(window=span01).mean()
df['sma25']=price.rolling(window=span02).mean()
df['sma30']=price.rolling(window=span03).mean()
plt.plot(date,price,label='7203',lw=5)
plt.plot(date,df['sma05'],label='sma05')
plt.plot(date,df['sma25'],label='sma25')
plt.plot(date,df['sma30'],label='sma75')
plt.title(code,color='blue',backgroundcolor='white',size=40,loc='center')
plt.xlabel('date',color='black',size=30)
plt.ylabel('price',color='black',size=30)
plt.grid()
plt.legend()
plt.plot(date,price)
plt.show()
return df
引数の説明:
code=’7203.JP’ → 銘柄コード番号+.JP 文字列で与えます
start=’2015-01-01’ → 株価データの開始年月日
end=’2020-07-25’ → 株価データの終了年月日
graph=True → 株価の終値の推移+移動平均(5日線、25日線、75日線)を折れ線でプロットする場合は、True。グラフを描かない場合はFalseにします。
8行目:
df=data.DataReader(code,'stooq',start,end)これによって、dfというpandasのデータフレームが戻ります。
データフレームはエクセルの表のような構造をしていて、列と行のデータです。
関数を使ってみる
それでは、この関数の使い方の例ですが、とても簡単ですよ。
def main():
import datetime
#今日の日付を指定
now = datetime.datetime.now()
end=now.strftime("%Y-%m-%d")
#code:銘柄コード番号.JP の書式文字列を設定する
code='7203.JP'
#start:株価データの先頭期日
start='2016-01-01'
print(code,start ,end)
df=read_stockdata(code,start,end,graph=True)
#df=read_stockdata(code,start,end,graph=False)
#最新の株価データ20個を表示させる
print(df.tail(20))
#■メインプログラム
if __name__ == '__main__':
main()
a=input('何かキーを押してください')
この場合、実行するコードをmain()という関数の形で書いていますが、メインプログラムの場所に直接書いても構いません。メインプログラムでは、main()を呼び出して、キー入力待ち状態にしています。input()関数でエンターキーが押されるまで、表示を維持するために使っています。
株価データのグラフを描いてみよう
df=read_stockdata(code,start,end,graph=True)
graphという引数にTrueを入れて実行するとグラフができます。
以下の通り、証券コード7203のトヨタ自動車の株価データをプロットできました。

証券コードの部分を変えたり、日付を変えたりすることはもちろん。グラフは、pythonで実行するとズームアップしたり、自由自在に閲覧できるところが優れています。
最近のデータ部分をズームアップしてみましょう。

2月の終わりから新型コロナウイルスの感染が増大して、経済が大きな打撃をうけました。ほとんどの株価は暴落してしまいました。5月後半から持ち直してきまていることがわかります。しかし、7月にかけて、ふたたびじわりと下がってるように見えますね。移動平均線25日線と75日線に注目しますと、25日線が75日線を下回って交差する「デッドクロス」が出ると、また株価が低下する可能性が出てきます。
課題:stooqはデータ更新がずれる?
stooqというのは、ポーランドのサイトです。残念ながら、最新データがリアルタイムで更新されないときがあるようです。たとえば、週の終わりのデータは次の週に更新。具体的には金曜日のデータは月曜日以降に更新されるということです。
これでは、週末の休日を使った次週の作戦を立てるのに支障が出ます。これは、なんとかしないといけないので、宿題です。
最新のデータを連結させる方法
なんとか課題を解決する方法を見つけました。
最新のデータだけをスクレイピングで取得して、先のデータに連結することで実現します。詳しい解説は、また今度(^^;)ということで・・・
import pandas as pd
import datetime
import numpy as np
from pandas_datareader import data
import pandas as pd
from urllib.request import urlopen
from bs4 import BeautifulSoup
import matplotlib.pyplot as plt
pd.set_option('display.width', 250) #表示幅を変更
pd.set_option("display.max_columns", 25) #最大表示列数
pd.set_option("display.max_colwidth", 80) #列の最大文字数
pd.set_option("display.max_rows", 200) #最大表示行数
def read_stockdata(code='7203.JP',start='2015-01-01',end='2020-07-25'): # ■株データダウンロード_stooq_J725
#!pip install pandas_datareader
#from pandas_datareader import data
#import pandas as pd
df=data.DataReader(code,'stooq',start,end)
df=df.sort_index() #indexの日付をソートする
return df
def append_data(code1):
#from urllib.request import urlopen
#from bs4 import BeautifulSoup
#import pandas as pd
def cook(code):
try:
tgt = 'https://kabutan.jp/stock/kabuka?code=' + str(code)
html = urlopen(tgt)
bsObj = BeautifulSoup(html, 'html.parser')
table = bsObj.findAll('table', {'class':'stock_kabuka0'})[0]
rows = table.findAll('tr')
for row in rows:
rec = []
for cell in row.findAll(['td', 'th']):
rec.append(cell.get_text())
del rec[5:7]
rec.insert(0, str(code) + '.JP')
dish.append(rec)
return 'Success'
except Exception as e:
return str(code) + ': ' + str(e)
dish=[]
l=[code1]
[cook(i) for i in l]
dish=pd.DataFrame(dish).rename(columns={0: 'code', 1: 'Date', 2:'Open', 3: 'High', 4: 'Low', 5:'Close', 6: 'Volume'})
dish['Date']=pd.to_datetime('20'+dish['Date'],format='%Y-%m-%d %H:%M:%S')
dish=dish.set_index('Date')
return dish
def stock_graph(df,code_s):
#import matplotlib.pyplot as plt
date=df.index
price=df['Close']
plt.figure(figsize=(30,10))
span01=5
span02=25
span03=75
df['sma05']=price.rolling(window=span01).mean()
df['sma25']=price.rolling(window=span02).mean()
df['sma30']=price.rolling(window=span03).mean()
plt.plot(date,price,label='7203',lw=5)
plt.plot(date,df['sma05'],label='sma05')
plt.plot(date,df['sma25'],label='sma25')
plt.plot(date,df['sma30'],label='sma75')
plt.title(code_s,color='blue',backgroundcolor='white',size=40,loc='center')
plt.xlabel('date',color='black',size=30)
plt.ylabel('price',color='black',size=30)
plt.grid()
plt.legend()
plt.plot(date,price)
plt.show()
return df
def main(code_s='7203.JP',start='2016-01-01',graph_flg=True):
#import pandas as pd
#import datetime
#import numpy as np
#今日の日付を指定
now = datetime.datetime.now()
end=now.strftime("%Y-%m-%d")
code=int(code_s[0:4])
print(code_s,start ,end)
df=read_stockdata(code_s,start,end)
#最新の株価情報を取得
df2=append_data(code)
df2["Open"] = df2["Open"].str.replace(',','').astype(np.int)
df2["High"] = df2["High"].str.replace(',','').astype(np.int)
df2["Low"] = df2["Low"].str.replace(',','').astype(np.int)
df2["Close"] = df2["Close"].str.replace(',','').astype(np.int)
df2["Volume"] = df2["Volume"].str.replace(',','').astype(np.int)
df=pd.concat([df, df2]) #結合
grouped = df.groupby(level=0)
df = grouped.last()
df=df.drop('code', axis=1)
#グラフの描画(データフレームとグラフタイトルを渡す)
if graph_flg:
df=stock_graph(df,code_s)
return df
#■メインプログラム
if __name__ == '__main__':
#code:銘柄コード番号.JP の書式文字列を設定する
#start:株価データの先頭期日
df=main(code_s='7203.JP',start='1999-01-01',graph_flg=True)
######## ここにはいろいろ解析するコードを入れてもよい ###########
print(df.head(10))
print(df.tail(30))
#################################################################
a=input('何かキーを押してください')
ソースコードのダウンロードができます。(.zipファイル)→ [download id=”311″]
まとめ
このように株価のテクニカル分析(株価データで分析すること)はpythonでさまざまな角度から行えます。もちろんファンダメンタル分析(企業業績などの情報から分析)も重要ですが、デイトレードやスイングトレードのような短期投資では、テクニカル分析がとても有効です。

pandasというデータ分析の徹底解説を以下の記事で紹介していますよ
今回、移動平均を使ったゴールデンクロス、デッドクロスについては詳しく述べませんでしたが、このほか、MACDなど優れた解析方法がありますので、今後掲載していきたいと思います。





コメント