pandasで複数銘柄の株価データ(pandas.DataFrame型)をpandas.DataFrame型で保持する

同様の内容は以前も扱った。

Pythonでの時系列データの扱い7 〜 まとめ(WEBからの株価データ取得、プロット、移動平均の作成)
pandas_datareader.dataのDataReaderを使用して株価を取得する 〜 pandas.Panel型で取得したデータ構造からpandas.Panel.minor_xsを使用して特定の銘柄のDataFrameを取得する

結局、「pandas_datareader.dataのDataReaderを使用」すれば良い。
今回も基本的には同じだが、「Pythonでの時系列データの扱い7 〜 まとめ(WEBからの株価データ取得、プロット、移動平均の作成)」で触れたように「pandas_datareader.data.DataReader」の引数にtickerリストを渡して複数銘柄の株価を取得した際の戻り値はpandas.Panel型となる。

今回は、pandas-datareaderを使用して1銘柄ずつ株価データをpandas.DataFrame型として取得し、それら複数銘柄の株価データをpandas.DataFrame型のデータ構造で保持する。

流れは次。

1.単一銘柄の株価データをpandas_datareader.data.DataReaderを使ってpandas.DataFrame型として取得する
2.取得したい銘柄リストを作成し、1の処理をそれぞれの銘柄毎に実行する(pythonの組み込み関数mapを使用して、銘柄リストの1つ1つの要素に対して1の処理を適用して結果をリストとして受け取る)
3.2で取得した(pandas.DataFrameの)リストをpandas.concatを使用して結合する

1.単一銘柄の株価データをpandas_datareader.data.DataReaderを使ってpandas.DataFrame型として取得する

#coding:utf-8
import pandas as pd
import datetime as dt
import pandas_datareader.data as pdd

ticker = 'AAPL'
stockData = pdd.DataReader(ticker, 'yahoo', start, end)
<<
stockDataは次のようなpandas.DataFrame型。
>>
                  Open        High         Low       Close    Volume 
Date                                                                   
2016-09-26  111.639999  113.389999  111.550003  112.879997  29869400   
2016-09-27  113.000000  113.180000  112.339996  113.089996  24607400   
2016-09-28  113.690002  114.639999  113.430000  113.949997  29641100   
2016-09-29  113.160004  113.800003  111.800003  112.180000  35887000   
2016-09-30  112.459999  113.370003  111.800003  113.050003  36379100   
・・・・・・・・・・・・
<<

<span class="deco" style="font-weight:bold;">2.取得したい銘柄リストを作成し、1の処理をそれぞれの銘柄毎に実行する(pythonの組み込み関数mapを使用して、銘柄リストの1つ1つの要素に対して1の処理を適用して結果をリストとして受け取る)</span>
さて、単一銘柄の株価データは取得できたが、今度は複数銘柄の株価データを繰り返し取得する。
これは、単純に1の処理を繰り返し実行するわけだが、<span class="deco" style="color:#FF0000;">pythonの組み込み関数mapを使用</span>すると楽。
<span class="deco" style="color:#FF0000;">map関数の第2引数に銘柄リストを渡し、銘柄リストの各要素に作用させる関数を第1引数に渡し、結果をリストとして受け取る</span>。1の処理の結果がpandas.DataFrame型なので、<span class="deco" style="color:#FF0000;">map関数の戻り値はpandas.DataFrame型のリスト</span>となる。
>|python|
#coding:utf-8
import pandas as pd
import datetime as dt
import pandas_datareader.data as pdd



######## Define Method ########
def getMultiStockData(tickerList, date_from, date_to):
    def getStockData(ticker):
        stockData = pdd.DataReader(ticker, 'yahoo', date_from, date_to)
        return stockData
    datas = map(getStockData, tickerList)
    print datas

######### 処理#########
# 期間設定
date_from = dt.date(2016, 9, 24)
date_to = dt.date(2016, 10, 6)

# 複数銘柄の取得
tickerList = ['AAPL', 'MSFT', 'IBM']
allData = getMultiStockData(tickerList, date_from, date_to)

結果は、次のようにpandas.DataFrameのリストとなる。

[ Open High Low Close Volume
Date
2016-09-26 111.639999 113.389999 111.550003 112.879997 29869400
2016-09-27 113.000000 113.180000 112.339996 113.089996 24607400
・・・・・・・・・・
2016-10-03 111.945245
2016-10-04 112.422796
2016-10-05 112.472544
2016-10-06 113.308249 ,

Open High Low Close Volume Adj Close
Date
2016-09-26 57.080002 57.139999 56.830002 56.900002 21688700 56.518189
2016-09-27 56.930000 58.060001 56.680000 57.950001 28065100 57.561143
・・・・・・・・・・
2016-10-05 57.290001 57.959999 57.259998 57.639999 16726400 57.253222
2016-10-06 57.740002 57.860001 57.279999 57.740002 16212600 57.352553,

Open High Low Close Volume Adj Close
Date
2016-09-26 154.460007 154.460007 153.460007 153.979996 2533300
2016-09-27 154.320007 156.770004 153.809998 156.770004 2987200
・・・・・・・・・・
2016-10-05 157.070007 157.830002 156.720001 157.080002 1684500
2016-10-06 156.839996 157.429993 155.889999 156.880005 1950100
]

3.2で取得した(pandas.DataFrameの)リストをpandas.concatを使用して結合する
2で取得したpandas.DataFrameの銘柄リストだとどの銘柄のDataFrameなのかが分からないので、キーをtickerとしたDataFrameとして結合する。
そのために、「 pd.concat(datas, keys=tickerList, names=['Ticker', 'Date'])」を戻すように2で使用したメソッドを少し変更する。

#coding:utf-8
import pandas as pd
import datetime as dt
import pandas_datareader.data as pdd

######## Define Method ########
def getMultiStockData(tickerList, date_from, date_to):
    def getStockData(ticker):
        stockData = pdd.DataReader(ticker, 'yahoo', date_from, date_to)
        return stockData
    datas = map(getStockData, tickerList)
    return pd.concat(datas, keys=tickerList, names=['Ticker', 'Date'])

######### 処理#########
# 期間設定
date_from = dt.date(2016, 9, 24)
date_to = dt.date(2016, 10, 6)

# 株価取得
tickerList = ['AAPL', 'MSFT', 'IBM']
multiStockData = getMultiStockData(tickerList, date_from, date_to)

print multiStockData

次のように、tickerをキーとしたpandas.DataFrameのリストが取得できる。

Open High Low Close Volume
Ticker Date
AAPL 2016-09-26 111.639999 113.389999 111.550003 112.879997 29869400
2016-09-27 113.000000 113.180000 112.339996 113.089996 24607400
2016-09-28 113.690002 114.639999 113.430000 113.949997 29641100
・・・・・・・・

MSFT 2016-09-26 57.080002 57.139999 56.830002 56.900002 21688700
2016-09-27 56.930000 58.060001 56.680000 57.950001 28065100
2016-09-28 57.880001 58.060001 57.669998 58.029999 20536400
・・・・・・・・
IBM 2016-09-26 154.460007 154.460007 153.460007 153.979996 2533300
2016-09-27 154.320007 156.770004 153.809998 156.770004 2987200
2016-09-28 156.990005 158.630005 156.229996 158.289993 3310000
・・・・・・・・