diff --git a/catalyst/data/loader.py b/catalyst/data/loader.py index ff3f34a8..e58127f7 100644 --- a/catalyst/data/loader.py +++ b/catalyst/data/loader.py @@ -142,8 +142,10 @@ def load_crypto_market_data(trading_day=None, trading_days=None, if exchange is None: # This is exceptional, since placing the import at the module scope # breaks things and it's only needed here - from catalyst.exchange.poloniex.poloniex import Poloniex - exchange = Poloniex('', '', '') + from catalyst.exchange.factory import get_exchange + exchange = get_exchange( + exchange_name='poloniex', base_currency='usdt' + ) benchmark_asset = exchange.get_asset(bm_symbol) diff --git a/catalyst/examples/simple_loop.py b/catalyst/examples/simple_loop.py index bfd2d4f0..75f55092 100644 --- a/catalyst/examples/simple_loop.py +++ b/catalyst/examples/simple_loop.py @@ -9,7 +9,7 @@ from catalyst.exchange.stats_utils import get_pretty_stats, \ def initialize(context): print('initializing') - context.asset = symbol('neo_usd') + context.asset = symbol('neo_eth') context.base_price = None @@ -19,17 +19,14 @@ def handle_data(context, data): price = data.current(context.asset, 'close') print('got price {price}'.format(price=price)) - try: - prices = data.history( - context.asset, - fields='price', - bar_count=14, - frequency='15T' - ) - rsi = talib.RSI(prices.values, timeperiod=14)[-1] - print('got rsi: {}'.format(rsi)) - except Exception as e: - print(e) + prices = data.history( + context.asset, + fields='price', + bar_count=20, + frequency='15T' + ) + rsi = talib.RSI(prices.values, timeperiod=14)[-1] + print('got rsi: {}'.format(rsi)) # If base_price is not set, we use the current value. This is the # price at the first bar which we reference to calculate price_change. @@ -110,24 +107,25 @@ def analyze(context, perf): pass -run_algorithm( - capital_base=250, - start=pd.to_datetime('2017-11-1 0:00', utc=True), - end=pd.to_datetime('2017-11-10 23:59', utc=True), - data_frequency='daily', - initialize=initialize, - handle_data=handle_data, - analyze=analyze, - exchange_name='bitfinex', - algo_namespace='simple_loop', - base_currency='usd' -) # run_algorithm( +# capital_base=250, +# start=pd.to_datetime('2017-11-1 0:00', utc=True), +# end=pd.to_datetime('2017-11-10 23:59', utc=True), +# data_frequency='daily', # initialize=initialize, # handle_data=handle_data, -# analyze=None, -# exchange_name='poloniex', -# live=True, +# analyze=analyze, +# exchange_name='bitfinex', # algo_namespace='simple_loop', -# base_currency='eth', -# live_graph=False +# base_currency='usd' +# ) +run_algorithm( + initialize=initialize, + handle_data=handle_data, + analyze=None, + exchange_name='binance', + live=True, + algo_namespace='simple_loop', + base_currency='eth', + live_graph=False, +) diff --git a/catalyst/exchange/ccxt/ccxt_exchange.py b/catalyst/exchange/ccxt/ccxt_exchange.py index 6db774c1..d04c346f 100644 --- a/catalyst/exchange/ccxt/ccxt_exchange.py +++ b/catalyst/exchange/ccxt/ccxt_exchange.py @@ -16,7 +16,8 @@ from catalyst.constants import LOG_LEVEL from catalyst.exchange.exchange import Exchange, ExchangeLimitOrder from catalyst.exchange.exchange_bundle import ExchangeBundle from catalyst.exchange.exchange_errors import InvalidHistoryFrequencyError, \ - ExchangeSymbolsNotFound, ExchangeRequestError, InvalidOrderStyle + ExchangeSymbolsNotFound, ExchangeRequestError, InvalidOrderStyle, \ + ExchangeNotFoundError from catalyst.exchange.exchange_utils import mixin_market_params, \ from_ms_timestamp @@ -50,8 +51,9 @@ class CCXT(Exchange): 'apiKey': key, 'secret': secret, }) + except Exception: - raise ValueError('exchange not in CCXT') + raise ExchangeNotFoundError(exchange_name=exchange_name) markets = self.api.load_markets() log.debug('the markets:\n{}'.format(markets)) @@ -122,24 +124,27 @@ class CCXT(Exchange): delta = start_dt - pd.to_datetime('1970-1-1', utc=True) ms = int(delta.total_seconds()) * 1000 - ohlcvs = self.api.fetch_ohlcv( - symbol=symbols[0], - timeframe=timeframe, - since=ms, - limit=bar_count, - params={} - ) + candles = dict() + for asset in assets: + ohlcvs = self.api.fetch_ohlcv( + symbol=symbols[0], + timeframe=timeframe, + since=ms, + limit=bar_count, + params={} + ) + + candles[asset] = [] + for ohlcv in ohlcvs: + candles[asset].append(dict( + last_traded=pd.to_datetime(ohlcv[0], unit='ms', utc=True), + open=ohlcv[1], + high=ohlcv[2], + low=ohlcv[3], + close=ohlcv[4], + volume=ohlcv[5] + )) - candles = [] - for ohlcv in ohlcvs: - candles.append(dict( - last_traded=pd.to_datetime(ohlcv[0], unit='ms', utc=True), - open=ohlcv[1], - high=ohlcv[2], - low=ohlcv[3], - close=ohlcv[4], - volume=ohlcv[5] - )) return candles def _fetch_symbol_map(self, is_local): diff --git a/catalyst/exchange/exchange.py b/catalyst/exchange/exchange.py index fd2be234..317175d0 100644 --- a/catalyst/exchange/exchange.py +++ b/catalyst/exchange/exchange.py @@ -357,10 +357,10 @@ class Exchange: tickers = self.tickers(assets) if field == 'close' or field == 'price': - return [t['last'] for t in tickers] + return [tickers[asset]['last'] for asset in tickers] elif field == 'volume': - return [t['volume'] for t in tickers] + return [tickers[asset]['volume'] for asset in tickers] else: raise NoValueForField(field=field) diff --git a/catalyst/exchange/factory.py b/catalyst/exchange/factory.py index 72c66bd8..8099b208 100644 --- a/catalyst/exchange/factory.py +++ b/catalyst/exchange/factory.py @@ -1,38 +1,31 @@ -from catalyst.exchange.bitfinex.bitfinex import Bitfinex -from catalyst.exchange.bittrex.bittrex import Bittrex -from catalyst.exchange.exchange_errors import ExchangeNotFoundError -from catalyst.exchange.exchange_utils import get_exchange_auth -from catalyst.exchange.poloniex.poloniex import Poloniex +import os + +from catalyst.exchange.ccxt.ccxt_exchange import CCXT +from catalyst.exchange.exchange_errors import ExchangeAuthEmpty +from catalyst.exchange.exchange_utils import get_exchange_auth, \ + get_exchange_folder -def get_exchange(exchange_name, base_currency=None): +def get_exchange(exchange_name, base_currency=None, portfolio=None, + must_authenticate=False): exchange_auth = get_exchange_auth(exchange_name) - if exchange_name == 'bitfinex': - return Bitfinex( - key=exchange_auth['key'], - secret=exchange_auth['secret'], - base_currency=base_currency, - portfolio=None + + has_auth = (exchange_auth['key'] != '' and exchange_auth['secret'] != '') + if must_authenticate and not has_auth: + raise ExchangeAuthEmpty( + exchange=exchange_name.title(), + filename=os.path.join( + get_exchange_folder(exchange_name), 'auth.json' + ) ) - elif exchange_name == 'bittrex': - return Bittrex( - key=exchange_auth['key'], - secret=exchange_auth['secret'], - base_currency=base_currency, - portfolio=None - ) - - elif exchange_name == 'poloniex': - return Poloniex( - key=exchange_auth['key'], - secret=exchange_auth['secret'], - base_currency=base_currency, - portfolio=None - ) - - else: - raise ExchangeNotFoundError(exchange_name=exchange_name) + return CCXT( + exchange_name=exchange_name, + key=exchange_auth['key'], + secret=exchange_auth['secret'], + base_currency=base_currency, + portfolio=portfolio + ) def get_exchanges(exchange_names): diff --git a/catalyst/utils/run_algo.py b/catalyst/utils/run_algo.py index 288c09bc..404b21c0 100644 --- a/catalyst/utils/run_algo.py +++ b/catalyst/utils/run_algo.py @@ -13,6 +13,7 @@ from catalyst.data.bundles import load from catalyst.data.data_portal import DataPortal from catalyst.exchange.bittrex.bittrex import Bittrex from catalyst.exchange.bitfinex.bitfinex import Bitfinex +from catalyst.exchange.factory import get_exchange from catalyst.exchange.poloniex.poloniex import Poloniex try: @@ -164,42 +165,15 @@ def _run(handle_data, if portfolio is None: portfolio = ExchangePortfolio( - start_date=pd.Timestamp.utcnow() + start if start is not None else pd.Timestamp.utcnow() ) - # This corresponds to the json file containing api token info - exchange_auth = get_exchange_auth(exchange_name) - - if live and (exchange_auth['key'] == '' \ - or exchange_auth['secret'] == ''): - raise ExchangeAuthEmpty( - exchange=exchange_name.title(), - filename=os.path.join( - get_exchange_folder(exchange_name, environ), 'auth.json')) - - if exchange_name == 'bitfinex': - exchanges[exchange_name] = Bitfinex( - key=exchange_auth['key'], - secret=exchange_auth['secret'], - base_currency=base_currency, - portfolio=portfolio - ) - elif exchange_name == 'bittrex': - exchanges[exchange_name] = Bittrex( - key=exchange_auth['key'], - secret=exchange_auth['secret'], - base_currency=base_currency, - portfolio=portfolio - ) - elif exchange_name == 'poloniex': - exchanges[exchange_name] = Poloniex( - key=exchange_auth['key'], - secret=exchange_auth['secret'], - base_currency=base_currency, - portfolio=portfolio - ) - else: - raise ExchangeNotFoundError(exchange_name=exchange_name) + exchanges[exchange_name] = get_exchange( + exchange_name=exchange_name, + base_currency=base_currency, + portfolio=portfolio, + must_authenticate=live, + ) open_calendar = get_calendar('OPEN')