diff --git a/catalyst/examples/buy_the_dip_live.py b/catalyst/examples/buy_the_dip_live.py index 369f5b6a..77398734 100644 --- a/catalyst/examples/buy_the_dip_live.py +++ b/catalyst/examples/buy_the_dip_live.py @@ -29,7 +29,7 @@ def initialize(context): def handle_data(context, data): - log.info('handling bar {data}'.format(data=data)) + log.info('handling bar {}'.format(data.current_dt)) # price_history = data.history(symbol('iot_usd'), # fields='price', # bar_count=20, @@ -129,8 +129,8 @@ def analyze(context, stats): exchange_conn = dict( name='bitfinex', - key='', - secret=b'', + key='yCN1b2LsLpjt8jmS4xi2ZZSfW9DRq4r9h2Aa9WOrKFr', + secret=b'VOW6R7zbmBGsLh49FIK76qkHrwr2ovNb4FQ1N1d3cyC', base_currency='usd' ) run_algorithm( diff --git a/catalyst/exchange/algorithm_exchange.py b/catalyst/exchange/algorithm_exchange.py index ee65e255..d1841a74 100644 --- a/catalyst/exchange/algorithm_exchange.py +++ b/catalyst/exchange/algorithm_exchange.py @@ -29,7 +29,7 @@ from catalyst.utils.api_support import ( from catalyst.utils.calendars.trading_calendar import days_at_time from catalyst.exchange.exchange_errors import ( - ExchangeRequestError + ExchangeRequestError, ) log = logbook.Logger("ExchangeTradingAlgorithm") @@ -164,6 +164,8 @@ class ExchangeTradingAlgorithm(TradingAlgorithm): if attempt_index < self.retry_check_open_orders: sleep(self.retry_delay) return self._check_open_orders(attempt_index + 1) + else: + return list() def handle_data(self, data): if not self.is_running: @@ -222,6 +224,8 @@ class ExchangeTradingAlgorithm(TradingAlgorithm): return self._order( asset, amount, limit_price, stop_price, style, attempt_index + 1) + else: + return None @api_method @disallowed_in_before_trading_start(OrderInBeforeTradingStart()) @@ -255,6 +259,8 @@ class ExchangeTradingAlgorithm(TradingAlgorithm): if attempt_index < self.retry_get_open_orders: sleep(self.retry_delay) return self._get_open_orders(asset, attempt_index + 1) + else: + return [] @error_keywords(sid='Keyword argument `sid` is no longer supported for ' 'get_open_orders. Use `asset` instead.') diff --git a/catalyst/exchange/exchange_errors.py b/catalyst/exchange/exchange_errors.py index cdb6734c..42d960f8 100644 --- a/catalyst/exchange/exchange_errors.py +++ b/catalyst/exchange/exchange_errors.py @@ -7,6 +7,12 @@ class ExchangeRequestError(ZiplineError): ).strip() +class ExchangeRequestErrorTooManyAttempts(ZiplineError): + msg = ( + 'Request failed: {error}, giving up after {attempts} attempts' + ).strip() + + class InvalidHistoryFrequencyError(ZiplineError): msg = ( 'History frequency {frequency} not supported by the exchange.' diff --git a/catalyst/utils/run_algo.py b/catalyst/utils/run_algo.py index c1e0d674..252af115 100644 --- a/catalyst/utils/run_algo.py +++ b/catalyst/utils/run_algo.py @@ -3,6 +3,7 @@ import re from runpy import run_path import sys import warnings +from time import sleep import pandas as pd @@ -39,6 +40,10 @@ from catalyst.exchange.data_portal_exchange import DataPortalExchange from catalyst.exchange.bitfinex import Bitfinex from catalyst.exchange.asset_finder_exchange import AssetFinderExchange from catalyst.exchange.exchange_portfolio import PortfolioMemoryStore +from catalyst.exchange.exchange_errors import ( + ExchangeRequestError, + ExchangeRequestErrorTooManyAttempts +) from logbook import Logger log = Logger('run_algo') @@ -246,14 +251,35 @@ def _run(handle_data, first_trading_day=pd.to_datetime('today', utc=True) ) choose_loader = None + + def fetch_portfolio(attempt_index=0): + """ + Fetch the portfolio for the exchange + We can't continue on error because it is required to bootstrap + the algorithm. + :param attempt_index: + :return: + """ + try: + return exchange.portfolio + except ExchangeRequestError as e: + if attempt_index < 20: + sleep(5) + return fetch_portfolio(attempt_index + 1) + else: + raise ExchangeRequestErrorTooManyAttempts( + attempts=attempt_index, + error=e + ) + + portfolio = fetch_portfolio() sim_params = create_simulation_parameters( start=start, end=end, - capital_base=exchange.portfolio.starting_cash, + capital_base=portfolio.starting_cash, emission_rate='minute', data_frequency='minute' ) - # sim_params = None else: env = TradingEnvironment(environ=environ) choose_loader = None