カスタム関数シリーズでは、便利なオリジナル関数を紹介しています。
※カスタム関数は、一般的には「ユーザー定義関数」と呼ばれています
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など優れた解析方法がありますので、今後掲載していきたいと思います。
コメント