我正在尝试使用python和pandas从Yahoo Finance下载证券价格数据,以期以一个时间序列的月末调整价格结束。
我的代码如下所示。我已经使用ix来过滤数据框以生成业务月底日期的列表。这适用于时间序列中除2个日期以外的所有日期,其中2010年5月31日和2013年3月29日都显示为空白,我认为是因为这些是美国的联邦假日。
您可以创建一个自定义频率或日历,而该频率或日历仅查找月末日期,而不用尝试为交易日创建日历,而如果不可用,则检查以前的日期,直到找到为止一个值?例如,2013年3月31日没有数据,因此请检查3月30日(无数据),3月29日(无数据),3月28日(数据)-> 3月28日显示。
import io
import requests
from datetime import datetime
import pandas
ticker = 'SPY'
start_date = '2009-12-31'
end_date = '2016-12-08'
s_dt = datetime.strptime(start_date, '%Y-%m-%d')
e_dt = datetime.strptime(end_date, '%Y-%m-%d')
url = 'http://chart.finance.yahoo.com/table.csv?s={0}&a={1}&b={2}&c={3}&d={4}&e={5}&f={6}&g=d&ignore=.csv'
url = url.format(ticker, s_dt.month-1, s_dt.day, s_dt.year, e_dt.month-1, e_dt.day, e_dt.year)
data = requests.get(url).content
df = pandas.read_csv(io.StringIO(data.decode('utf-8')))
df.drop('Open', 1, inplace=True)
df.drop('High', 1, inplace=True)
df.drop('Low', 1, inplace=True)
df.drop('Volume', 1, inplace=True)
df.drop('Close', 1, inplace=True)
df.columns = ['date', ticker]
df['date'] = pandas.to_datetime(df['date'], format='%Y-%m-%d')
df = df.set_index('date')
df = df.ix[pandas.date_range(start=start_date, end=end_date, freq='BM')]
最佳答案
我想出了一种通过使用fillna方法实现我想要的方法的方法。
我的原始代码的最后一行应替换为:
# expand series to add all dates in date range
df = df.ix[pandas.date_range(start=start_date, end=end_date, freq='d')]
# fill in the NaN values with the last available value
df = df.fillna(method='pad')
# reduce series to just business month-end dates
df = df.ix[pandas.date_range(start=start_date, end=end_date, freq='BM')]