[Python] 株価データをプロットし,さらにCSVファイルを出力する

  • 6
    Like
  • 0
    Comment

はじめに

Web上で長期間の株価データを探してもなかなか見つからないので,Pythonを用いて株価のヒストリカルデータを取得し,CSV形式で出力,さらに出力したデータをプロットするプログラムを作成しました.
日本株・外国株いずれにも対応しています.
参考までに,例として出力した日経平均株価のCSVファイルはこちら,さらにプロットすると以下のようになります.
Nikkei225.png

ソースコードの紹介

まず,作成したソースコードを紹介します.

stockprice.py
#!usr/bin/python3
# -*- coding: utf-8 -*-

'''
株価データのプロット・CSVへの出力
'''

import datetime as dt
import pandas as pd
import jsm
import pandas_datareader.data as web
import matplotlib.pyplot as plt

def jpstock(code, start_date, end_date):
    year, month, day = start_date.split("-")
    start = dt.date(int(year), int(month), int(day))
    year, month, day = end_date.split("-")
    end = dt.date(int(year), int(month), int(day))

    print('CSVを出力中...')
    q = jsm.Quotes()
    target = q.get_historical_prices(code, jsm.DAILY, start_date=start, end_date=end)

    date = [data.date for data in target]
    open = [data.open for data in target]
    high = [data.high for data in target]
    low = [data.low for data in target]
    close = [data.close for data in target]
    volume = [data.volume for data in target]
    adj_close = [data._adj_close for data in target]

    Date = date[::-1]
    Open = open[::-1]
    High = high[::-1]
    Low = low[::-1]
    Close = close[::-1]
    Adj = adj_close[::-1]
    Vol = volume[::-1]

    cdf = pd.DataFrame(index=Date)
    cdf.index.name = "Date"
    cdf["Open"] = Open
    cdf["High"] = High
    cdf["Low"] = Low
    cdf["Close"] = Close
    cdf["Adj Close"] = Adj
    cdf["Volume"] = Vol

    cdf.to_csv(code + '.csv')
    print(code + '.csvを出力しました.')

    print('株価データをプロット中...')
    df = pd.DataFrame(index=Date)
    df['Adj Close'] = Adj

    return df

def usstock(ticker, start_date, end_date):
    year, month, day = start_date.split("-")
    start = dt.date(int(year), int(month), int(day))
    year, month, day = end_date.split("-")
    end = dt.date(int(year), int(month), int(day))

    print('CSVを出力中...')
    df2 = web.DataReader(ticker, 'yahoo', start, end)

    df2.to_csv(ticker + '.csv')
    print(ticker + '.csvを出力しました.')

    print('株価データをプロット中...')
    df3 = pd.DataFrame(index=[])
    df3['Adj Close'] = df2['Adj Close']

    return df3

def main():
    country = str(input('日本株の場合は「ja」,そうでない場合は「us」を入力 [ja/us]: '))
    if country == 'ja':
        code = input('証券コード? ')
        start_date = input('取得期間の初めの日付を入力 [yyyy-mm-dd]: ')
        end_date = input('取得期間の終わりの日付を入力 [yyyy-mm-dd]: ')
        try:
            jstock = jpstock(code, start_date, end_date)
            jstock['Adj Close'].plot()
            plt.show()
        except:
            print('データの取得中にエラーが発生しました.')
            main()

    elif country == 'us':
        ticker = input('Ticker Symbol?: ')
        start_date = input('取得期間の初めの日付を入力 [yyyy-mm-dd]: ')
        end_date = input('取得期間の終わりの日付を入力 [yyyy-mm-dd]: ')
        try:
            ustock = usstock(ticker, start_date, end_date)
            ustock['Adj Close'].plot()
            plt.show()
        except:
            print('データの取得中にエラーが発生しました.')
            main()

    else:
        print('エラーが発生しました.')
        main()

if __name__ == "__main__":
    main()

このソースコードは,Githubにて管理しています.

必要な環境・ライブラリと,そのインストール方法

必要なものは主に以下の通りです.

  • Python 3.x
  • matplotlib
  • pandas
  • pandas_datareader
  • jsm

まず,Python 3.x について,これは Python 3.x でのみ実行の検証をしているという意味であり,Python 2.x で問題なく動くかどうかは不明です.
おそらく print関数を修正すれば動くと思います.

また,他4つについて,Python 単体の環境ではデフォルトでは入っていません.さらにjsm ライブラリを使用するために BeautifulSoup もインストールする必要があります.
一方,Anaconda の環境では,デフォルトで matplotlib,pandas,BeautifulSoup が含まれているため,Anaconda 環境の導入を推奨します.Anaconda のダウンロードはこちらから.

ここでは Anaconda 環境に含まれていない pandas_datareader と,jsm のインストールのしかたを紹介します.
まず,デスクトップ左下の Windows マークを右クリックし,「Windows PowerShell(管理者)」または「コマンドプロンプト(管理者)」を起動し,Anaconda のプログラムファイルの置かれたディレクトリに移動します.
例えば Anaconda のプログラムファイルが C:\Program Files\Anaconda3\Scripts にあるのならば,

C:\Windows\System32> cd \
C:\> cd "Program Files"
C:\Program Files> cd Anaconda3\Scripts
C:\Program Files\Anaconda3\Scripts>

次に,pipコマンドを使ってライブラリをインストールします.

C:\Program Files\Anaconda3\Scripts> .\pip install pandas_datareader

さらに,

C:\Program Files\Anaconda3\Scripts> .\pip install jsm

これで必要な環境は揃いました.

使用方法

まずstockprice.pyがあるディレクトリと同じディレクトリにて,何も選択していない状態でShift+右クリックします.
出てきた右クリックメニューのうち,「Windows PowerShellをここに開く」または「コマンドプロンプトをここに開く」を選択します.
次のコマンドで実行してください.

python stockprice.py

このコマンドで実行できなかった場合は,python.exeにパスが通っていない可能性があります.
Windowsキーを押して環境変数を検索し,「環境変数を編集」を選択します.
ユーザー環境変数のうち,「Path」を選択して「編集」をクリック,さらに出てきた「環境変数名の編集」ウィンドウの右側「新規」をクリックします.
そこに Anaconda のプログラムファイルの置いてあるディレクトリのパスを書き込みます.
先ほどの例でいうとC:\Program Files\Anaconda3となります.
その後 PowerShell またはコマンドプロンプトを再起動してもう一度試すと,実行できるはずです.

実行すると,まず取得したいデータが日本株であるか外国株であるかの選択が求められます.
これは日本株と外国株の株価データの取得方法が異なるからです.
次に日本株の場合は証券コード,外国株の場合はティッカーシンボルを入力し,さらに取得したい期間を指定してしばらく待つと,データのプロット・CSV出力が実行されます.

エラーに関して

株価データの取得中にエラーが発生することがあります.
その場合はもう一度実行してください.

また,ライブラリ jsm を原因として,以下のようなエラーが発生することがあります.

/Program Files/anaconda3/lib/site-packages/bs4/__init__.py:166: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system ("lxml"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.

To get rid of this warning, change this:

 BeautifulSoup([your markup])

to this:

 BeautifulSoup([your markup], "lxml")

  markup_type=markup_type))

この場合は,先程の例でいうと,C:\Program Files\Anaconda3\lib\site-packages\jsm\util.pyの10行目から,

util.py
def html_parser(html):
    try:
        soup = BeautifulSoup(html)
    except:
        soup = BeautifulSoup(html, "html5lib")
    return soup

となっているのを以下のように変更してください.

util.py
def html_parser(html):
    try:
        soup = BeautifulSoup(html, "html5lib")
    except:
        soup = BeautifulSoup(html)
    return soup

これで jsm によるエラーは発生しなくなるはずです.

おわりに

以上で紹介は終わりです.
jsm や pandas_datareader 便利なので使ってみてください.