我目前正在寻找一种方法来加载雅虎金融的多年股价历史.我将有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
Run Code Online (Sandbox Code Playgroud)
我希望能够永久存储所有这些数据,例如,如果我今天为100个股票代码加载30年的价格历史,那么明天我只需要追加一天的数据而不是全部30年.数据帧似乎是组织数据的最有效方式,但我不太确定,但我想做机器学习和数据分析.
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}
Run Code Online (Sandbox Code Playgroud)
这将数据保存在python字典中,允许您使用该.get方法访问数据.
例如,如果您想获取数据GOOG,则可以执行以下操作:
print(pnls.get('GOOG').head())
Run Code Online (Sandbox Code Playgroud)
这得到以下内容:
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
Run Code Online (Sandbox Code Playgroud)
请记住,如果给定的股票代码没有时间间隔的数据,则返回的数据将省略这些年份或日期(显然).
你的脚本(以及许多其他事情)的主要问题是你多次(len(ticker)同一时间)进行相同的调用,并且一次又一次地返回相同的输出.这是因为DataReader()当提供a时list,该函数将出去并为其中的每个元素获取data.frame list.所以,当你写:
i = 0
while i < len(ticker):
f = web.DataReader(ticker, 'yahoo', start, end)
print(f)
i+=1
Run Code Online (Sandbox Code Playgroud)
你基本上是这样说的:i = 0我希望你继续web.DataReader(ticker, 'yahoo', start, end)拨打电话并获取相同的数据然后打印它,直到(通过递增)i达到我的代码列表长度的值.你可能刚刚得到同样的东西f = web.DataReader(ticker, 'yahoo', start, end).但即便如此,你也不知道哪个data.frame是哪个ticker.
另外,我发现另一件令人震惊的事情是,当你处理100多个代码时,你想要命名每个返回的data.frame.为什么在神的绿色地球上你想要在命名空间中拥有100多个名字?您可以非常轻松地将所有这些名称集中到一个dictionary(就像我上面推荐的那样)并随时通过使用.get()并提供自动收报机来访问任何data.frame .
回顾:1)不需要a while-loop.2)如果你只是为DataReader()函数提供整个代码列表,你无法知道哪个data.frame是哪个ticker .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)
Run Code Online (Sandbox Code Playgroud)
然后,您可以编写另一个脚本,它只是为今天的相同代码抓取数据.它也需要在夜间(午夜之前)运行,以便它可以从今天捕获数据.
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.")
Run Code Online (Sandbox Code Playgroud)
第二个脚本应该使用第一个脚本将最新价格附加到先前保存的每个数据文件中.
请注意,我正在假设雅虎(或任何其他数据源)将在市场收盘时尽快提供当天的价格.
我希望这有帮助.