diff --git a/zipline/data/benchmarks.py b/zipline/data/benchmarks.py index 7bcd28a5..ee2da2ae 100644 --- a/zipline/data/benchmarks.py +++ b/zipline/data/benchmarks.py @@ -45,18 +45,17 @@ def format_yahoo_index_url(symbol, start_date, end_date): def get_benchmark_returns(symbol, start_date, end_date): """ Get a Series of benchmark returns from Yahoo. + + Returns a Series with returns from (start_date, end_date]. + + start_date is **not** included because we need the close from day N - 1 to + compute the returns for day N. """ - data = pd.read_csv( + return pd.read_csv( format_yahoo_index_url(symbol, start_date, end_date), parse_dates=['Date'], index_col='Date', - usecols=["Open", "Close", "Date"], - ).sort_index().tz_localize('UTC') - - returns = data["Close"].pct_change() - # Calculate the returns for the first day using the open of that day since - # we don't have the close of the previous day. - first_open, first_close = data.ix[0, ["Open", "Close"]] - returns.iloc[0] = (first_close - first_open) / first_open - - return returns + usecols=["Adj Close", "Date"], + squeeze=True, # squeeze tells pandas to make this a Series + # instead of a 1-column DataFrame + ).sort_index().tz_localize('UTC').pct_change(1).iloc[1:] diff --git a/zipline/data/loader.py b/zipline/data/loader.py index 57be8129..1f529596 100644 --- a/zipline/data/loader.py +++ b/zipline/data/loader.py @@ -149,6 +149,9 @@ def load_market_data(trading_day=trading_day_nyse, bm_symbol, first_date, last_date, + # We need the trading_day to figure out the close prior to the first + # date so that we can compute returns for the first date. + trading_day, ) treasury_curves = ensure_treasury_data( bm_symbol, @@ -158,7 +161,7 @@ def load_market_data(trading_day=trading_day_nyse, return benchmark_returns, treasury_curves -def ensure_benchmark_data(symbol, first_date, last_date): +def ensure_benchmark_data(symbol, first_date, last_date, trading_day): """ Ensure we have benchmark data for `symbol` from `first_date` to `last_date` @@ -170,6 +173,9 @@ def ensure_benchmark_data(symbol, first_date, last_date): First required date for the cache. last_date : pd.Timestamp Last required date for the cache. + trading_day : pd.CustomBusinessDay + A trading day delta. Used to find the day before first_date so we can + get the close of the day prior to first_date. We attempt to download data unless we already have data stored at the data cache for `symbol` whose first entry is before or on `first_date` and whose @@ -197,7 +203,7 @@ def ensure_benchmark_data(symbol, first_date, last_date): path=path, ) - data = get_benchmark_returns(symbol, first_date, last_date) + data = get_benchmark_returns(symbol, first_date - trading_day, last_date) data.to_csv(path) if not has_data_for_dates(data, first_date, last_date): logger.warn("Still don't have expected data after redownload!")