From 43b85cffb06bfb90db48bbc9ac9f3ea242a01ef1 Mon Sep 17 00:00:00 2001 From: Eddie Hebert Date: Mon, 11 Nov 2013 14:55:45 -0500 Subject: [PATCH] MAINT: Calculate tradingcalendar with days beyond the current day. To make 'next open' calculations more straight ahead, calculate more than enough days in the trading calendar. --- zipline/data/loader.py | 17 ++++++++++++----- zipline/utils/tradingcalendar.py | 24 +++++++++++------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/zipline/data/loader.py b/zipline/data/loader.py index d53a3623..74cb2940 100644 --- a/zipline/data/loader.py +++ b/zipline/data/loader.py @@ -29,7 +29,10 @@ from . treasuries import get_treasury_data from . import benchmarks from . benchmarks import get_benchmark_returns -from zipline.utils.tradingcalendar import trading_days +from zipline.utils.tradingcalendar import ( + trading_day, + trading_days +) logger = logbook.Logger('Loader') @@ -152,15 +155,19 @@ Fetching data from Yahoo Finance. saved_benchmarks = saved_benchmarks.tz_localize('UTC') fp_bm.close() + most_recent = pd.Timestamp('today', tz='UTC') - trading_day + most_recent_index = trading_days.searchsorted(most_recent) + days_up_to_now = trading_days[:most_recent_index + 1] + # Find the offset of the last date for which we have trading data in our # list of valid trading days last_bm_date = saved_benchmarks.index[-1] - last_bm_date_offset = trading_days.searchsorted( + last_bm_date_offset = days_up_to_now.searchsorted( last_bm_date.strftime('%Y/%m/%d')) # If more than 1 trading days has elapsed since the last day where # we have data,then we need to update - if len(trading_days) - last_bm_date_offset > 1: + if len(days_up_to_now) - last_bm_date_offset > 1: benchmark_returns = update_benchmarks(bm_symbol, last_bm_date) if ( benchmark_returns.index.tz is None @@ -192,12 +199,12 @@ Fetching data from data.treasury.gov # Find the offset of the last date for which we have trading data in our # list of valid trading days last_tr_date = saved_curves.index[-1] - last_tr_date_offset = trading_days.searchsorted( + last_tr_date_offset = days_up_to_now.searchsorted( last_tr_date.strftime('%Y/%m/%d')) # If more than 1 trading days has elapsed since the last day where # we have data,then we need to update - if len(trading_days) - last_tr_date_offset > 1: + if len(days_up_to_now) - last_tr_date_offset > 1: treasury_curves = dump_treasury_curves() else: treasury_curves = saved_curves.tz_localize('UTC') diff --git a/zipline/utils/tradingcalendar.py b/zipline/utils/tradingcalendar.py index 17afa9c2..0fc54a00 100644 --- a/zipline/utils/tradingcalendar.py +++ b/zipline/utils/tradingcalendar.py @@ -20,9 +20,11 @@ import pytz from datetime import datetime, timedelta from dateutil import rrule -start = datetime(1990, 1, 1, tzinfo=pytz.utc) -end_dln = pd.Timestamp('today', tz='UTC') -end = end_dln - timedelta(days=1) +start = pd.Timestamp('1990-01-01', tz='UTC') +end_base = pd.Timestamp('today', tz='UTC') +# Give an aggressive buffer for logic that needs to use the next trading +# day or minute. +end = end_base + timedelta(days=365) def canonicalize_datetime(dt): @@ -246,18 +248,14 @@ def get_non_trading_days(start, end): non_trading_days.sort() return pd.DatetimeIndex(non_trading_days) +non_trading_days = get_non_trading_days(start, end) +trading_day = pd.tseries.offsets.CDay(holidays=non_trading_days) -def get_trading_days(start, end): - start = canonicalize_datetime(start) - end = canonicalize_datetime(end) - - business_days = pd.DatetimeIndex(start=start, end=end, - freq=pd.datetools.BDay()) - - non_trading_days = get_non_trading_days(start, end) - - return business_days - non_trading_days +def get_trading_days(start, end, trading_day=trading_day): + return pd.date_range(start=start.date(), + end=end.date(), + freq=trading_day).tz_localize('UTC') trading_days = get_trading_days(start, end)