From b3dcb7a9ad5e5700092168ca3c07c81e7b82b824 Mon Sep 17 00:00:00 2001 From: fredfortier Date: Wed, 18 Oct 2017 23:26:24 -0400 Subject: [PATCH] Fixed issue with overlapping chunks --- catalyst/examples/simple_loop.py | 4 +-- catalyst/exchange/exchange_bundle.py | 43 ++++++++++++++++------------ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/catalyst/examples/simple_loop.py b/catalyst/examples/simple_loop.py index 84ed01c5..7081178f 100644 --- a/catalyst/examples/simple_loop.py +++ b/catalyst/examples/simple_loop.py @@ -7,7 +7,7 @@ from catalyst.api import symbol def initialize(context): print('initializing') - context.asset = symbol('etc_eth') + context.asset = symbol('btc_usdt') def handle_data(context, data): @@ -29,7 +29,7 @@ def handle_data(context, data): run_algorithm( capital_base=250, - start=pd.to_datetime('2017-9-01', utc=True), + start=pd.to_datetime('2015-2-19', utc=True), end=pd.to_datetime('2017-9-30', utc=True), data_frequency='daily', initialize=initialize, diff --git a/catalyst/exchange/exchange_bundle.py b/catalyst/exchange/exchange_bundle.py index c4128696..b6e16ce0 100644 --- a/catalyst/exchange/exchange_bundle.py +++ b/catalyst/exchange/exchange_bundle.py @@ -265,12 +265,10 @@ class ExchangeBundle: return data - def download_bundle(self, name): - """ - - :param name: - :return: - """ + def get_calendar_periods_range(self, start_dt, end_dt, data_frequency): + return self.calendar.minutes_in_range(start_dt, end_dt) \ + if data_frequency == 'minute' \ + else self.calendar.sessions_in_range(start_dt, end_dt) def ingest_ctable(self, asset, data_frequency, period, start_dt, end_dt, writer, empty_rows_behavior='strip', cleanup=False): @@ -297,10 +295,9 @@ class ExchangeBundle: period=period ) - periods = self.calendar.minutes_in_range(start_dt, end_dt) \ - if data_frequency == 'minute' \ - else self.calendar.sessions_in_range(start_dt, end_dt) - + periods = self.get_calendar_periods_range( + start_dt, end_dt, data_frequency + ) reader = self.get_reader(data_frequency, path=path) if reader is None: raise TempBundleNotFoundError(path=path) @@ -384,6 +381,8 @@ class ExchangeBundle: def prepare_chunks(self, assets, data_frequency, start_dt, end_dt): """ + Split a price data request into chunks corresponding to individual + bundles. :param assets: :param data_frequency: @@ -402,17 +401,25 @@ class ExchangeBundle: except PricingDataBeforeTradingError: continue - sessions = get_periods_range(asset_start, asset_end, - data_frequency) + # Aligning start / end dates with the daily calendar + sessions = get_periods_range(start_dt, end_dt, data_frequency) \ + if data_frequency == 'minute' \ + else self.calendar.sessions_in_range(start_dt, end_dt) - periods = [] + if asset_start < sessions[0]: + asset_start = sessions[0] + + if asset_end > sessions[-1]: + asset_end = sessions[-1] + + chunk_labels = [] dt = sessions[0] while dt <= sessions[-1]: - period = '{}-{:02d}'.format(dt.year, dt.month) \ + label = '{}-{:02d}'.format(dt.year, dt.month) \ if data_frequency == 'minute' else '{}'.format(dt.year) - if period not in periods: - periods.append(period) + if label not in chunk_labels: + chunk_labels.append(label) # Adjusting the period dates to match the availability # of the trading pair @@ -451,13 +458,13 @@ class ExchangeBundle: ) if not has_data: - log.debug('adding period: {}'.format(period)) + log.debug('adding period: {}'.format(label)) chunks.append( dict( asset=asset, period_start=period_start, period_end=period_end, - period=period + period=label ) )