Yahoo!Japan ファイナンス から株価の取得

ふと株価を取得してみたくて試行錯誤していたところ、ちょうど参考になるブログを見つけました。

・Python pandas で日本の株価情報取得とローソク足チャート描画
http://sinhrks.hatenablog.com/entry/2015/02/04/002258

これをそのままやっていくとWarningがでてきたので修正しました。

■環境
Python 3.5.1
Anaconda 4.2.0

pandas.io をインポートすると削除予定と表示される。

C:\Anaconda2\envs\py35\lib\site-packages\pandas\io\data.py:35: FutureWarning: 
The pandas.io.data module is moved to a separate package (pandas-datareader) and will be removed from pandas in a future version.
After installing the pandas-datareader package (https://github.com/pydata/pandas-datareader), you can change the import ``from pandas.io import data, wb`` to ``from pandas_datareader import data, wb``.
  FutureWarning)

なのでpandas.ioを使わないように修正しました。

# coding: utf-8
from __future__ import unicode_literals
import numpy as np
import pandas as pd
#import pandas.io.data as web
import pandas.tools.plotting as plotting
import datetime as dt


def get_quote_yahoojp(code, start=None, end=None, interval='d'):
    base = 'http://info.finance.yahoo.co.jp/history/?code={0}.T&{1}&{2}&tm={3}&p={4}'
    #start, end = web._sanitize_dates(start, end)
    start = pd.to_datetime(start)
    if end == None:
        end = pd.to_datetime(pd.datetime.now())
    else :
        end = pd.to_datetime(end)
    start = 'sy={0}&sm={1}&sd={2}'.format(start.year, start.month, start.day)
    end = 'ey={0}&em={1}&ed={2}'.format(end.year, end.month, end.day)
    p = 1
    results = []

    if interval not in ['d', 'w', 'm', 'v']:
        raise ValueError("Invalid interval: valid values are 'd', 'w', 'm' and 'v'")

    while True:
        url = base.format(code, start, end, interval, p)
        tables = pd.read_html(url, header=0)
        if len(tables) < 2 or len(tables[1]) == 0:
            break
        results.append(tables[1])
        p += 1
    result = pd.concat(results, ignore_index=True)

    result.columns = ['Date', 'Open', 'High', 'Low', 'Close', 'Volume', 'Adj Close']
    if interval == 'm':
        result['Date'] = pd.to_datetime(result['Date'], format='%Y年%m月')
    else:
        result['Date'] = pd.to_datetime(result['Date'], format='%Y年%m月%d日')
    result = result.set_index('Date')
    result = result.sort_index()
    return result

2016/10/2から直近までのマクドナルドの株価を取得する場合

start ='2016-10-02'
mac_tse = get_quote_yahoojp(2702, start=start)
mac_tse.head()

Out[3]: 
            Open  High   Low  Close  Volume  Adj Close
Date                                                  
2016-10-03  2981  3005  2979   2989  177100       2989
2016-10-04  2990  2998  2975   2985  222700       2985
2016-10-05  2980  3010  2980   2984  291900       2984
2016-10-06  2985  2990  2965   2971  259600       2971
2016-10-07  2985  2989  2935   2935  439900       2935

できました。

“みたけ山トレイルラン”のCDF

“みたけ山トレイルラン”のCDFをグラフにしてみます。

以下の内容の続きです
”みたけ山トレイルラン”のPMF

”みたけ山トレイルラン”のPMF

再びの”みたけ山トレイルラン”のヒストグラム

再びの”みたけ山トレイルラン”のヒストグラム

#CDF
累積分布関数(CDF)
 値をパーセンタイル順位に対応づける関数

パーセンタイル順位とは
 分布中の与えられた値以下の値が分布中に占めるパーセント

たとえば、テストの順位で90パーセンタイル順位だった場合、受験者の90パーセントの人と同じかより良い結果をだしたということ。

CDFのグラフの出し方

#秒に変換
df['D'] = df['A'] / pd.to_timedelta('00:00:01') //1

df.head(10)
Out[133]: 
         A     B        C       D
0 01:05:03  13.0 01:05:00  3903.0
1 01:07:10  13.0 01:05:00  4030.0
2 01:07:52  13.0 01:05:00  4072.0
3 01:12:00  14.0 01:10:00  4320.0
4 01:12:14  14.0 01:10:00  4334.0
5 01:12:31  14.0 01:10:00  4351.0
6 01:12:54  14.0 01:10:00  4374.0
7 01:13:23  14.0 01:10:00  4403.0
8 01:13:44  14.0 01:10:00  4424.0
9 01:13:54  14.0 01:10:00  4434.0


cdf = thinkstats2.Cdf(df['D'])
thinkplot.Cdf(cdf)


#グラフ化の体裁を整える
plt.xticks([3600, 4500, 5400, 6300, 7200, 8100,9000,9900], ['1:00:00','1:15:00','1:30:00','1:45:00','2:00:00','2:15:00','2:30:00','2:45:00'])
plt.xlabel('TIME') 
plt.ylabel('CDF')

最初にデータフレームのD列で秒表示にしているのはthinkplotでグラフにできないからです。

グラフはこうなります。

mitake_cdf

CDFを計算すればパーセンタイル順位の計算は簡単にできまうす。Cdfクラスには2つのメソッドが用意されています。

パーセンタイル順位
PercentileRank(X)
 値xについてパーセンタイル順位を計算する。

Percentile(p)
 パーセンタイル順位について対応する値xを計算する

パーセンタイル順位を計算するにはA列でCDFを計算しておいたほうがよいです。

cdf2 = thinkstats2.Cdf(df['A'])

パーセンタイル順位の計算

cdf2.PercentileRank(pd.to_timedelta('1:45:00'))
Out[143]: 25.518925518925517

#今回はタイムが早いほうが順位が高いので、パーセンタイル順位は

100 - 25.518925518925517
Out[144]: 74.48107448107449

になります。

逆は例えば90パーセンタイル順位を知りたいとすると
以下のようにできます。

#パーセンタイル順位から対応する時間を計算
cdf2.Percentile(10)
Out[57]: Timedelta('0 days 01:30:00')

こんな感じです。

以上

”みたけ山トレイルラン”のPMF

”みたけ山トレイルラン”の結果をヒストグラムにしてみたので、今回は確率質量関数にしてグラフをつくってみます。

前回
再びの”みたけ山トレイルラン”のヒストグラム
http://jbclub.xii.jp/?p=573

PMFとは
 確率質量関数(probability mass function, PMF)

PMFは正規化されているので全体としての確率は1となる。
thinkstats2が提供するPmfクラスを使うと簡単です。
↓のデータフレームは前回と一緒です。

df.head(10)
Out[81]: 
         A     B        C
0 01:05:03  13.0 01:05:00
1 01:07:10  13.0 01:05:00
2 01:07:52  13.0 01:05:00
3 01:12:00  14.0 01:10:00
4 01:12:14  14.0 01:10:00
5 01:12:31  14.0 01:10:00
6 01:12:54  14.0 01:10:00
7 01:13:23  14.0 01:10:00
8 01:13:44  14.0 01:10:00
9 01:13:54  14.0 01:10:00

pmf = thinkstats2.Pmf(df['B'])
pmf2 = thinkstats2.Pmf(df['C'])
※CはTimedelta型になっているので、プロットするときにthinkiplotクラスを使うことができない。そのため、プロットする際はBを使用する。

Pmfを棒グラフで描画するときはthinkplot.Histを使う。
Pmfをステップ関数として描画する場合はthink.Pmfを使う。

thinkplot.Hist(pmf)
plt.xticks([12, 15, 18, 21, 24,27,30,33], ['1:00:00','1:15:00','1:30:00','1:45:00','2:00:00','2:15:00','2:30:00','2:45:00'])
plt.xlabel('TIME') 
plt.ylabel('PMF') 

mitake_pmf_hist

thinkplot.Pmf(pmf)
plt.xticks([12, 15, 18, 21, 24,27,30,33], ['1:00:00','1:15:00','1:30:00','1:45:00','2:00:00','2:15:00','2:30:00','2:45:00'])
plt.xlabel('TIME') 
plt.ylabel('PMF') 

mitake_pmf

PMFにすると何がよいのでしょうか。おそらく、二つのグラフを比較するときに分かりやすくなるのだと思います。確率なので標本サイズの違いで紛らわしくなることなく比較できます。今回はほかの比較する用のデータがないので描画してませんが、データがあれば描画してみたいです。ただ、こういう大会結果のデータはPDFで掲載されているので、PDFからCSVへ変換するところが物凄い大変なんですよね。大会関係者は、CSVファイルで掲載してほしいところです。

以上

ThinkStats2のコードは以下からダウンロードできます。
https://github.com/AllenDowney/

return top