python

PythonでQuandlから株価を取得する

投稿日:2017年11月3日 更新日:

今回は、巷で流行りのプログラミング言語であるPythonの勉強として、Pythonを利用して株価を取得するコードを作成しました。

環境は以下です。

  • OS:Ubuntu16.04
  • Python:3.6.3 [GCC 4.9.2]

要件と仕様

要件

  • 日本株を、python上で合法な範囲で取得可能なこと
  • 日本株以外の情報(各種経済指標等)の取得が可能なこと
    • 今回の実装においては、日本株以外の取得部分は対象外とする
    • あくまで拡張可能なように設計することにとどめる
  • 日本株を取得後、各種解析が可能な形に出力すること

仕様

  • 日本株をQuandlから取得する
  • 取得する情報は、日付と終値とする
  • 取得した情報はcsvファイルに出力すること

Quandlについて

Quandlは、世界の金融情報や統計情報をまとめているサイトです。

大きな特徴として、各種情報を取得するためのPythonやRubyのAPIを提供しており、しかもかなりの部分を無料で使用することができます。
日本の金融関係のサービスではAPIを提供しているものは少なく、あったとしても有料であることがほとんどです。

Quandlで取得できる情報の大部分は外国株式や海外の統計情報ですが、実は日本株も取得する事ができます。
東証がデータを提供していて、API経由で東証のデータ(日経平均や各種日本株式)を取得できます。

QuandlからAPI経由でデータを取得する前準備として、APIキーを発行する必要があります。Quandlのサイトで無料会員登録を行い、事前にAPIキーを入手してください。

設計・実装

下記に設計・実装したコード「get_stock.py」を掲載します。
(美しくない一本ソースで申し訳ありません。。。)

import quandl
import datetime
import pandas as pd
import re
import sys
import csv

class Stock :
  def __init__(self, code):
    self.code_ = code

  def Get(self, start_date, end_date, api_key):
    year, month, day = start_date.split("-")
    start = datetime.date(int(year), int(month), int(day))
    year, month, day = end_date.split("-")
    end = datetime.date(int(year), int(month), int(day))

    quandl.ApiConfig.api_key = api_key
    data = quandl.get(self.code_, start_date = start, end_date = end)
    print(data.head())

    date, values = self.Shape(data)
    return (date, values)

  def Shape(self, data):
    return


class TseStock(Stock) :
  def __init__(self, code):
    self.code_ = code

  def Shape(self, data):
    date = data.index.strftime('%Y-%m-%d')
    values = data['Close']
    return (date, values)


def main():
  args = sys.argv
  codelist_file = str(args[1])
  start_date = str(args[2])
  end_date = str(args[3])
  api_key = str(args[4])
  print("get stocks")
  print("codelist file = " + codelist_file)
  print("date  = " + start_date + " to " + end_date)
  print("api_key  = " + api_key)

  code_list = pd.read_csv(codelist_file)
  print(code_list)

  for key, codes in code_list.iteritems():
    for code in codes:
      if str(key) == "TSE":
        print("TSE " + str(code))
        stock = TseStock(code)

      date, values = stock.Get(start_date, end_date, api_key)

      filename_code = re.sub(r'[\\|/|:|?|.|"|<|>|\|]', '-', str(code))
      f = open("code_" + filename_code + "_" + start_date + "_" + end_date + ".csv", 'w')
      writer = csv.writer(f, lineterminator='\n')
      for d, c in zip(date[::-1], values[::-1]):
        csv_row = [d,c]
        writer.writerow(csv_row)
      f.close()


if __name__ == "__main__":
    main()

本ソースは大きく分けて2つの要素で成り立っています。

  • 〜36行目まで:Quandlを用いて株価を取得する役割をもつStockクラスとその関連クラス
  • 39行目〜:Stockクラスを使い、得た株価をcsvに出力するmain文

8~10行目:Stockクラスは、Quandlの株価コードを引数にインスタンスを生成します。pythonにおいては、クラスのコンストラクタはinitで定義します。

class Stock :
  def __init__(self, code):
    self.code_ = code

self.(メンバ変数名)でクラスのメンバ変数を定義します。Stockクラスでは、株価コードをcodeというメンバ変数に代入しています。

12行目:Stockクラスのメンバ関数としてGetというメンバ関数を定義します。引数として、取得する株価の期間(取得開始日時と終了日時)の文字列、およびAPIキーを受け取ります。

def Get(self, start_date, end_date, api_key):
  year, month, day = start_date.split("-")
  start = datetime.date(int(year), int(month), int(day))
  year, month, day = end_date.split("-") 
  end = datetime.date(int(year), int(month), int(day))

  quandl.ApiConfig.api_key = api_key
  data = quandl.get(self.code_, start_date = start, end_date = end)
  print(data.head())

  date, values = self.Shape(data)
  return (date, values)

Get関数の中身では、

  • 文字列として受け取った日時を、pythonのdatetime型に変換
  • quandlのAPIをコール
  • 日付と終値の抽出

を行っています。このうち、日付と終値の抽出に関しては、Stockクラスを継承したサブクラスであるTseStockを定義し、そこで実装しています。デザインパターンにおけるテンプレートメソッドパターンに相当します。

29行目:StockクラスのサブクラスであるTseStockクラスの実装です。メンバ関数Shapeを作成し、オーバーライドしています。

class TseStock(Stock) :
  def __init__(self, code):
    self.code_ = code

  def Shape(self, data):
    date = data.index.strftime('%Y-%m-%d')
    values = data['Close']
    return (date, values)

今回取得する東証提供の株価において、終値は「Close」キーに格納されています。Shape関数では日付と終値をindexとCloseキーから抽出しています。

39行目以降は、Stockクラスらを実際に使用するmain文となります。
まず、コマンドライン引数を取得して各種変数に代入します。

def main():
  args = sys.argv
  codelist_file = str(args[1])
  start_date = str(args[2])
  end_date = str(args[3])
  api_key = str(args[4])
  print("get stocks")
  print("codelist file = " + codelist_file)
  print("date  = " + start_date + " to " + end_date)
  print("api_key  = " + api_key)

コマンドライン引数は、sysライブラリのargvから取得します。
引数の種類は以下としています。

  • Quandlの株価コードが記述されたcsvファイルのパス
  • 取得開始日時
  • 取得終了日時
  • APIコード

このうち、Quandlの株価コードが記述されたcsvファイルについて、例として次のようなものを用意します(codelist.csv)。
今回は、トヨタ自動車(TSE/7203)、みずほフィナンシャルグループ(TSE/8411)、ソフトバンクグループ(TSE/9984)を取得することとします。

TSE
TSE/7203
TSE/8411
TSE/9984

コマンドライン引数取得後、実際の株取得・データ出力の処理を行います。

code_list = pd.read_csv(codelist_file)
print(code_list)

for key, codes in code_list.iteritems():
  for code in codes:
    if str(key) == "TSE":
      print("TSE " + str(code))
      stock = TseStock(code)

    date, values = stock.Get(start_date, end_date, api_key)

    filename_code = re.sub(r'[\\|/|:|?|.|"|<|>|\|]', '-', str(code))
    f = open("code_" + filename_code + "_" + start_date + "_" + end_date + ".csv", 'w')
    writer = csv.writer(f, lineterminator='\n')
    for d, c in zip(date[::-1], values[::-1]):
      csv_row = [d,c]
      writer.writerow(csv_row)
    f.close()

50~59行目:引数で取得した株価コードのファイルから株価コードを読み出し、それぞれTseStockクラスのインスタンスを作成してGet関数で日付と終値を取得します。
ファイル読み出し時には、一行目をDataFrameのヘッダとして読み出します。今回は、ヘッダに「TSE」がある列は、TseStockクラスを使用する、というコードを記述しています。
61〜67行目:取得した日付と終値は、csvファイルとして出力します。

実行方法

以下のように実行ください。

user@hostname:~/# python get_stock.py codelist.csv 2010-04-30 2015-05-30 Your-API-Key

標準出力に各種情報が出たあと、該当する株価情報が記されたファイルが出力されるはずです。

標準出力:

get stocks
codelist file = codelist.csv
date  = 2010-04-30 to 2015-05-30
api_key  = Your-API-Key
        TSE
0  TSE/7203
1  TSE/8411
2  TSE/9984
TSE TSE/7203
              Open    High     Low   Close      Volume
Date                                                  
2010-04-30  3685.0  3685.0  3645.0  3665.0   8061400.0
2010-05-06  3560.0  3580.0  3545.0  3550.0  10418300.0
2010-05-07  3440.0  3500.0  3430.0  3480.0  12016200.0
2010-05-10  3470.0  3540.0  3460.0  3520.0  11365500.0
2010-05-11  3565.0  3575.0  3485.0  3495.0   8524000.0
TSE TSE/8411
             Open   High    Low  Close       Volume
Date                                               
2010-04-30  183.0  184.0  180.0  182.0  136203000.0
2010-05-06  178.0  179.0  172.0  174.0  172128900.0
2010-05-07  167.0  172.0  166.0  170.0  166291200.0
2010-05-10  170.0  175.0  170.0  171.0  171159900.0
2010-05-11  169.0  169.0  162.0  163.0  299762800.0
TSE TSE/9984
              Open    High     Low   Close      Volume
Date                                                  
2010-04-30  2149.0  2150.0  2099.0  2110.0   5272300.0
2010-05-06  2050.0  2078.0  2041.0  2074.0   8434100.0
2010-05-07  2000.0  2071.0  1997.0  2070.0   9994200.0
2010-05-10  2131.0  2166.0  2123.0  2163.0  10394600.0
2010-05-11  2213.0  2221.0  2168.0  2181.0  14253900.0

ファイル:

user@hostname:~/# ls
(中略)
code_TSE-7203_2010-04-30_2015-05-30.csv
code_TSE-8411_2010-04-30_2015-05-30.csv
code_TSE-9984_2010-04-30_2015-05-30.csv

終わりに

今回はPythonを用いて、Quandlから東証の株式情報を取得しました。
Quandlには、他にも統計情報(世界の人口等)や外国株式の情報を取得する機能が備わっています。データソースによってデータの整形方法を変えなければならないため注意が必要です。

-python
-

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

関連記事

Travis CIを使ったPythonプロジェクト構築

Travis CIを使ってみたかったのでメモ。 目次1 概要2 前準備2.1 Travis CIのアカウントを作成3 リポジトリ作成4 テストのための設定4.1 Travis CI用の設定5 コミット …

PyQueryを使用し株式会社の決算速報をスクレイピング

今回はpythonを利用したスクレイピングの練習として、PyQueryを利用したスクレイピングを行うコードを作成しました。 目次1 注意2 要件と仕様3 PyQueryとは4 設計・実装5 テスト5. …

pythonで有価証券報告書(XBRL形式)をパースする

今年最後の更新になります。 pythonを使用して、株式会社の財務情報をパースするコードを作成しました。 目次1 要件・仕様2 XBRLとは3 有価証券報告書の会計基準について4 設計・実装5 テスト …