我目前正在寻找一种方法来加载雅虎财经的多年股价历史。我将有100多个自动收报机符号,我将从1985年下载数据到当前日期。我想将Open,High,Low,Close,Adj Close,Volume加载到单个DataFrames(pandas)中,并将数据框的名称命名为当前股票代码。
我的问题是我的变量自动收报机不起作用,即使它确实有效,我怎样才能存储这些数据?
import csv
import pandas as pd
import pandas_datareader.data as web
import datetime
#This represents the start and end date for the data
start = datetime.datetime(1985, 1, 1)
end = datetime.datetime(2016, 1, 27)
ticker = ['aapl','tvix','ugaz']
i= 0
while i < len(ticker):
f = web.DataReader(ticker, 'yahoo', start, end)
print(f)
i+=1
我希望能够永久存储所有这些数据,例如,如果我今天为100个股票代码加载30年的价格历史,那么明天我只需追加一天的数据而不是全部30年。数据帧似乎是组织数据的最有效方式,但我不太确定,但我想做机器学习和数据分析。
答案 0 :(得分:6)
如果雅虎上有数据,您可以使用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多个代码时,你想要命名每个返回的数据框。为什么在 上帝的绿色地球 你想要在命名空间中拥有100多个名字?您可以非常轻松地将所有这些名称集中到一个dictionary
(就像我上面推荐的那样),并随时使用.get()
并提供代码来访问任何data.frame。
回顾:1)不需要while-loop
。 2)如果您只是向DataReader()
函数提供整个代码列表,则无法知道哪个data.frame适用于哪个代码。 3)您不希望命名100+ data.frames。
建议:通过使用字典(代码是keys
并且返回的数据将是values
)和列表理解来循环遍历代码并获取其数据来简化整个事情。我怀疑,这可以使你的脚本更容易阅读和缩短。
这是尝试提供一个解决方案,希望运行一次作业,然后每天使用最新的价格增加数据。这不是唯一的方法,但我认为这是一个好方法。首先,您需要制作一个脚本,从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.")
第二个脚本应该使用第一个脚本将最新价格附加到先前保存的每个数据文件中。
请注意,我正在假设雅虎(或任何其他数据源)只要市场在任何地方关闭,即可获得当天的价格。
我希望这会有所帮助。