我每天都会提取大量股票和 ETF 的历史数据。Quandl 对美国股票有很好的免费报道,但他们没有 ETF 的历史数据,所以我使用 Google API 作为 Quandl 的备份。
最近的谷歌金融“革新”并没有给我留下一个很好的选择,所以我试图将布拉德所罗门的工作(感谢布拉德,下面的链接)应用到符号列表中。鉴于他正在创建 URL,假设没有循环是不可能的。欢迎任何聪明的想法。
相关问题:为什么谷歌的 pandas_datareader 不起作用?
谢谢。
我每天都会提取大量股票和 ETF 的历史数据。Quandl 对美国股票有很好的免费报道,但他们没有 ETF 的历史数据,所以我使用 Google API 作为 Quandl 的备份。
最近的谷歌金融“革新”并没有给我留下一个很好的选择,所以我试图将布拉德所罗门的工作(感谢布拉德,下面的链接)应用到符号列表中。鉴于他正在创建 URL,假设没有循环是不可能的。欢迎任何聪明的想法。
相关问题:为什么谷歌的 pandas_datareader 不起作用?
谢谢。
在后台,pandas-datareader 循环遍历您传递的每个符号,并一个一个地发出 http 请求。
这是在基类中执行此操作的函数,与 google 和 yahoo 相关的类从中继承:base._DailyBaseReader._dl_mult_symbols
.
神奇的是这些被附加到一个列表中,然后聚合成一个 pandas Panel
。
但是,我要注意的是,Panel 已被弃用,您可以在具有 MultiIndex 的 DataFrame 中获得相同的功能,MultiIndex 结构在技术上是二维的,但在实践中复制了更高的维度。
所以,下面是你可以做的事情的准系统。 请注意,我跳过了包本身内嵌的许多功能,例如将字符串日期解析为日期时间。
import datetime
from io import StringIO
import requests
from pandas.io.common import urlencode
import pandas as pd
BASE = 'http://finance.google.com/finance/historical'
def get_params(sym, start, end):
params = {
'q': sym,
'startdate': start.strftime('%Y/%m/%d'),
'enddate': end.strftime('%Y/%m/%d'),
'output': "csv"
}
return params
def build_url(sym, start, end):
params = get_params(sym, start, end)
return BASE + '?' + urlencode(params)
def get_one_data(sym, start=None, end=None):
if not start:
start = datetime.datetime(2010, 1, 1)
if not end:
end = datetime.datetime.today()
url = build_url(sym, start, end)
data = requests.get(url).text
return pd.read_csv(StringIO(data), index_col='Date',
parse_dates=True).sort_index()
def get_multiple(sym, start=None, end=None, return_type='Panel'):
if isinstance(sym, str):
return get_one_data(sym, start=start, end=end)
elif isinstance(sym, (list, tuple, set)):
res = {}
for s in sym:
res[s] = get_one_data(s, start, end)
# The actual module also implements a 'passed' and 'failed'
# check here and also using chunking to get around
# data retreival limits (I believe)
if return_type.lower() == 'panel':
return pd.Panel(res).swapaxes('items', 'minor')
elif return_type.lower() == 'mi': # MultiIndex DataFrame
return pd.concat((res), axis=1)
一个例子:
syms = ['AAPL', 'GE']
data = get_multiple(syms, return_type='mi')
# Here's how you would filter down to Close prices
# on MultiIndex columns
data.xs('Close', axis=1, level=1)
AAPL GE
Date
2010-01-04 30.57 15.45
2010-01-05 30.63 15.53
2010-01-06 30.14 15.45
2010-01-07 30.08 16.25
2010-01-08 30.28 16.60
...