From 8a6d0d7ca0b315c5a7e733b5ce556058aaccf4f8 Mon Sep 17 00:00:00 2001 From: Victor Grau Serrat Date: Wed, 18 Oct 2017 21:25:27 -0600 Subject: [PATCH] Catch NoData on Exchange + formatting of errors --- catalyst/exchange/bundle_utils.py | 15 +++++++++++---- catalyst/exchange/data_portal_exchange.py | 14 ++++++++------ catalyst/exchange/exchange.py | 14 +++++++------- catalyst/exchange/exchange_errors.py | 9 +++++++-- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/catalyst/exchange/bundle_utils.py b/catalyst/exchange/bundle_utils.py index 725123a2..0aa05661 100644 --- a/catalyst/exchange/bundle_utils.py +++ b/catalyst/exchange/bundle_utils.py @@ -12,7 +12,7 @@ import pytz from catalyst.data.bundles import from_bundle_ingest_dirname from catalyst.data.bundles.core import download_without_progress from catalyst.exchange.exchange_errors import ApiCandlesError, \ - PricingDataBeforeTradingError + PricingDataBeforeTradingError, NoDataAvailableOnExchange from catalyst.exchange.exchange_utils import get_exchange_bundles_folder from catalyst.utils.deprecate import deprecated from catalyst.utils.paths import data_path @@ -134,10 +134,17 @@ def get_adj_dates(start, end, assets, data_frequency): if end is None or (last_entry is not None and end > last_entry): end = last_entry - if start >= end: + if end is None: + raise NoDataAvailableOnExchange( + exchange=asset.exchange.title(), + symbol=[asset.symbol.encode('utf-8')], + data_frequency=data_frequency, + ) + + if end is None or start >= end: raise PricingDataBeforeTradingError( - symbols=[asset.symbol], - exchange=asset.exchange, + symbols=[asset.symbol.encode('utf-8')], + exchange=asset.exchange.title(), first_trading_day=earliest_trade, dt=end ) diff --git a/catalyst/exchange/data_portal_exchange.py b/catalyst/exchange/data_portal_exchange.py index b1b13dbc..ce8ab3ab 100644 --- a/catalyst/exchange/data_portal_exchange.py +++ b/catalyst/exchange/data_portal_exchange.py @@ -301,7 +301,7 @@ class DataPortalExchangeBacktest(DataPortalExchangeBase): reader = bundle.get_reader(data_frequency) if reader is None: raise BundleNotFoundError( - exchange=exchange.name, + exchange=exchange.name.title(), data_frequency=data_frequency ) @@ -321,9 +321,10 @@ class DataPortalExchangeBacktest(DataPortalExchangeBase): raise PricingDataNotLoadedError( field=field, first_trading_day=first_trading_day, - exchange=exchange.name, + exchange=exchange.name.title(), symbols=symbols, - symbol_list=symbol_list + symbol_list=symbol_list, + data_frequency=data_frequency ) series = dict() @@ -340,7 +341,7 @@ class DataPortalExchangeBacktest(DataPortalExchangeBase): if dt < first_trading_day: raise PricingDataBeforeTradingError( first_trading_day=first_trading_day, - exchange=assets[0].exchange, + exchange=assets[0].exchange.title(), symbols=[asset.symbol.encode('utf-8') for asset in assets], dt=dt, ) @@ -365,10 +366,11 @@ class DataPortalExchangeBacktest(DataPortalExchangeBase): raise PricingDataNotLoadedError( field=field, first_trading_day=self._get_first_trading_day(assets), - exchange=exchange.name, + exchange=exchange.name.title(), symbols=[asset.symbol.encode('utf-8') for asset in assets], symbol_list=''.join( - [asset.symbol.encode('utf-8') for asset in assets]) + [asset.symbol.encode('utf-8') for asset in assets]), + data_frequency=data_frequency ) return values diff --git a/catalyst/exchange/exchange.py b/catalyst/exchange/exchange.py index 0552bcc1..d21cace4 100644 --- a/catalyst/exchange/exchange.py +++ b/catalyst/exchange/exchange.py @@ -130,7 +130,7 @@ class Exchange: if not symbol: raise ValueError('Currency %s not supported by exchange %s' % - (asset['symbol'], self.name)) + (asset['symbol'], self.name.title())) return symbol @@ -174,10 +174,10 @@ class Exchange: asset = self.assets[key] if not asset: - supported_symbols = [pair.symbol for pair in self.assets.values()] + supported_symbols = [pair.symbol.encode('utf-8') for pair in self.assets.values()] raise SymbolNotFoundOnExchange( symbol=symbol, - exchange=self.name, + exchange=self.name.title(), supported_symbols=supported_symbols ) @@ -529,7 +529,7 @@ class Exchange: reader = self.bundle.get_reader(data_frequency) if reader is None: raise BundleNotFoundError( - exchange=self.name, + exchange=self.name.title(), data_frequency=data_frequency ) @@ -570,7 +570,7 @@ class Exchange: elif field == 'volume': agg = 'sum' else: - raise ValueError('invalid field') + raise ValueError('Invalid field.') df = df.resample('{}T'.format(candle_size)).agg(agg) @@ -592,7 +592,7 @@ class Exchange: if base_position_available is None: raise BaseCurrencyNotFoundError( base_currency=self.base_currency, - exchange=self.name + exchange=self.name.title() ) portfolio = self._portfolio @@ -682,7 +682,7 @@ class Exchange: style = ExchangeStopOrder(stop_price, exchange=self.name) elif style is not None: - raise InvalidOrderStyle(exchange=self.name, + raise InvalidOrderStyle(exchange=self.name.title(), style=style.__class__.__name__) else: raise ValueError('Incomplete order data.') diff --git a/catalyst/exchange/exchange_errors.py b/catalyst/exchange/exchange_errors.py index b121acc6..602582d2 100644 --- a/catalyst/exchange/exchange_errors.py +++ b/catalyst/exchange/exchange_errors.py @@ -4,7 +4,7 @@ from catalyst.errors import ZiplineError def silent_except_hook(exctype, excvalue, exctraceback): if exctype in [PricingDataBeforeTradingError, PricingDataNotLoadedError, - SymbolNotFoundOnExchange, ]: + SymbolNotFoundOnExchange, NoDataAvailableOnExchange, ]: fn = traceback.extract_tb(exctraceback)[-1][0] ln = traceback.extract_tb(exctraceback)[-1][1] print "Error traceback: {1} (line {2})\n" \ @@ -197,9 +197,14 @@ class PricingDataNotLoadedError(ZiplineError): 'exchange {exchange} since {first_trading_day} is unavailable. ' 'The bundle data is either out-of-date or has not been loaded yet. ' 'Please ingest data using the command ' - '`catalyst ingest-exchange -x {exchange} -i {symbol_list}`. ' + '`catalyst ingest-exchange -x {exchange} -f {data_frequency} -i {symbol_list}`. ' 'See catalyst documentation for details.').strip() class ApiCandlesError(ZiplineError): msg = ('Unable to fetch candles from the remote API: {error}.').strip() + +class NoDataAvailableOnExchange(ZiplineError): + msg = ('Requested data for trading pair {symbol} is not available on exchange {exchange} ' + 'in `{data_frequency}` frequency at this time. ' + 'Check `http://enigma.co/catalyst/status` for market coverage.').strip()