您可以使用pandas_datareader 模块下载所需的数据(如果它在雅虎上可用)。你可以pip install它或以任何你喜欢的方式安装它。
以下是获取一小部分交易品种数据的示例脚本:
from pandas_datareader import data as dreader
symbols = ['GOOG', 'AAPL', 'MMM', 'ACN', 'A', 'ADP']
pnls = {i:dreader.DataReader(i,'yahoo','1985-01-01','2016-09-01') for i in symbols}
这会将数据保存在 python 字典中,允许您使用 .get 方法访问数据。
例如,如果你想获取GOOG 的数据,你可以这样做:
print(pnls.get('GOOG').head())
得到以下结果:
Open High Low Close Volume \
Date
2004-08-19 100.000168 104.060182 95.960165 100.340176 44871300
2004-08-20 101.010175 109.080187 100.500174 108.310183 22942800
2004-08-23 110.750191 113.480193 109.050183 109.400185 18342800
2004-08-24 111.240189 111.600192 103.570177 104.870176 15319700
2004-08-25 104.960181 108.000187 103.880180 106.000184 9232100
Adj Close
Date
2004-08-19 50.119968
2004-08-20 54.100990
2004-08-23 54.645447
2004-08-24 52.382705
2004-08-25 52.947145
请记住,如果给定的代码在某个时间间隔内没有数据,则返回的数据将省略那些年或日(显然)。
编辑:
您的脚本的主要问题(以及许多其他问题)是您多次(len(ticker) 次)进行相同的调用,并且一遍又一遍地返回相同的输出。这是因为DataReader() 函数在提供list 时,将出去并为list 中的每个元素获取一个data.frame。所以,当你写的时候:
i = 0
while i < len(ticker):
f = web.DataReader(ticker, 'yahoo', start, end)
print(f)
i+=1
您实际上是在说:对于i = 0,我希望您继续进行web.DataReader(ticker, 'yahoo', start, end) 调用并获取相同的数据,然后打印它直到(通过递增)i 的值达到我的列表的长度行情。使用f = web.DataReader(ticker, 'yahoo', start, end),您可能会得到同样的结果。但即便如此,您也不会知道哪个 data.frame 用于哪个股票代码。
另外,我发现另一件令人震惊的事情是,当您处理 100 多个股票代码时,您想要命名每个返回的 data.frame。为什么在 God's Green Earth 上您的命名空间中有 100 多个名称?您可以非常轻松地将所有这些名称集中到一个 dictionary 中(就像我上面推荐的那样),并随时使用 .get() 并提供代码来访问其中的任何 data.frame。
回顾:1) 不需要while-loop。 2) 如果您只是将整个代码列表提供给DataReader() 函数,您将无法知道哪个 data.frame 用于哪个代码。 3) 您不想命名 100 多个 data.frames。
建议:仅使用字典(代码为keys,返回的数据为values)和一个列表推导来循环代码并获取它们的数据,从而简化整个事情。我怀疑这可以使您的脚本更易于阅读并且更短。
编辑 2:
这是一种尝试提供一种解决方案,以满足运行一次作业然后每天使用可用的最新价格增加数据的愿望。这不是唯一的方法,但我认为这是一个好方法。首先,您需要编写一个脚本来获取从 1985 年到昨天的所有股票代码的数据。该脚本需要在市场交易时间之后(或深夜)运行以获取最新价格。这可能与我上面的脚本非常相似。您唯一需要添加的是几行代码,以将机器上的数据保存在当前工作目录中。应该这样做:
from pandas_datareader import data as dreader
symbols = ['GOOG', 'AAPL', 'MMM', 'ACN', 'A', 'ADP']
pnls = {i:dreader.DataReader(i,'yahoo','1985-01-01','2016-09-01') for i in symbols}
for df_name in pnls:
pnls.get(df_name).to_csv("{}_data.csv".format(df_name), index=True, header=True)
然后,您可以编写另一个脚本,该脚本仅获取今天相同股票代码的数据。它也需要在晚上(午夜之前)运行,以便捕获今天的数据。
from datetime import datetime
from pandas_datareader import data as dreader
from pandas_datareader._utils import RemoteDataError
symbols = ['GOOG', 'AAPL', 'MMM', 'ACN', 'A', 'ADP']
try:
pnls = {i:dreader.DataReader(i,'yahoo',datetime.today(),datetime.today()) for i in symbols}
except RemoteDataError:
pnls = None
if pnls is not None:
for df_name in pnls:
with open("{}_data.csv".format(df_name),"a") as outfile:
pnls.get(df_name).to_csv(outfile,header=False)
else:
print("No data available yet. Please run later.")
第二个脚本应该将最新价格附加到之前使用第一个脚本保存的每个数据文件中。
请注意,我的假设是雅虎(或任何其他数据源)将在收市后立即获得当天的价格。
我希望这会有所帮助。