def init_engine_and_indicators(self): self.initializing = True try: self.cbpro_websocket.close() except: pass # Periods to update indicators for self.indicator_period_list = [] # Periods to actively trade on (typically 1 per product) self.trade_period_list = {} # List of products that we are actually monitoring self.product_list = set() fiat_currency = self.config['fiat'] if self.config['sandbox']: api_url = "https://api-public.sandbox.pro.coinbase.com" else: api_url = "https://api.pro.coinbase.com" auth_client = cbpro.AuthenticatedClient(self.config['key'], self.config['secret'], self.config['passphrase'], api_url=api_url) for cur_period in self.config['periods']: self.logger.debug("INITIALIZING %s", cur_period['name']) if cur_period.get('meta'): new_period = period.MetaPeriod( period_size=(60 * cur_period['length']), fiat=fiat_currency, product=cur_period['product'], name=cur_period['name'], cbpro_client=auth_client) else: new_period = period.Period(period_size=(60 * cur_period['length']), product=cur_period['product'], name=cur_period['name'], cbpro_client=auth_client) self.indicator_period_list.append(new_period) self.product_list.add(cur_period['product']) if cur_period['trade']: if self.trade_period_list.get(cur_period['product']) is None: self.trade_period_list[cur_period['product']] = [] self.trade_period_list[cur_period['product']].append( new_period) max_slippage = Decimal(str(self.config['max_slippage'])) self.trade_engine = engine.TradeEngine(auth_client, product_list=self.product_list, fiat=fiat_currency, is_live=self.config['live'], max_slippage=max_slippage) self.cbpro_websocket = engine.TradeAndHeartbeatWebsocket( fiat=fiat_currency, sandbox=self.config['sandbox']) self.cbpro_websocket.start() self.indicator_period_list[0].verbose_heartbeat = True self.indicator_subsys = indicators.IndicatorSubsystem( self.indicator_period_list) self.last_indicator_update = time.time() self.init_interface() self.initializing = False
new_period = period.Period(period_size=(60 * cur_period['length']), product=cur_period['product'], name=cur_period['name']) indicator_period_list.append(new_period) product_list.add(cur_period['product']) if cur_period['trade']: if trade_period_list.get(cur_period['product']) is None: trade_period_list[cur_period['product']] = [] trade_period_list[cur_period['product']].append(new_period) auth_client = gdax.AuthenticatedClient(config['key'], config['secret'], config['passphrase']) max_slippage = Decimal(str(config['max_slippage'])) trade_engine = engine.TradeEngine(auth_client, product_list=product_list, fiat=fiat_currency, is_live=config['live'], max_slippage=max_slippage) gdax_websocket = TradeAndHeartbeatWebsocket(fiat=fiat_currency) gdax_websocket.start() indicator_period_list[0].verbose_heartbeat = True indicator_subsys = indicators.IndicatorSubsystem(indicator_period_list) last_indicator_update = time.time() if config['frontend'] == 'curses': curses_enable = True else: curses_enable = False interface = curses_interface.cursesDisplay(enable=curses_enable) while(True): try: if gdax_websocket.error: raise gdax_websocket.error msg = gdax_websocket.websocket_queue.get(timeout=15) for product in trade_engine.products: product.order_book.process_message(msg) if msg.get('type') == "match":
def __init__(self): config_path = os.getenv("CBPRO_CONFIG", "/opt/project/config.yml") with open(config_path, 'r') as ymlfile: config = yaml.safe_load(ymlfile) self.logger = logging.getLogger('trader-logger') self.logger.setLevel(logging.DEBUG) if config['logging']: self.logger.addHandler(logging.StreamHandler()) if config['frontend'] == 'debug': self.logger.addHandler(logging.StreamHandler()) self.error_logger = logging.getLogger('error-logger') self.error_logger.addHandler(logging.StreamHandler()) # Periods to update indicators for self.indicator_period_list = [] # Periods to actively trade on (typically 1 per product) self.trade_period_list = {} # List of products that we are actually monitoring self.product_list = set() fiat_currency = config['fiat'] if config['sandbox']: api_url = "https://api-public.sandbox.pro.coinbase.com" else: api_url = "https://api.pro.coinbase.com" auth_client = cbpro.AuthenticatedClient(config['key'], config['secret'], config['passphrase'], api_url=api_url) for curr_period in config['periods']: if curr_period.get('meta'): new_period = period.MetaPeriod(period_size=(60 * curr_period['length']), fiat=fiat_currency, product=curr_period['product'], name=curr_period['name'], cbpro_client=auth_client) else: new_period = period.Period(period_size=(60 * curr_period['length']), product=curr_period['product'], name=curr_period['name'], cbpro_client=auth_client) self.indicator_period_list.append(new_period) self.product_list.add(curr_period['product']) if curr_period['trade']: if self.trade_period_list.get(curr_period['product']) is None: self.trade_period_list[curr_period['product']] = [] self.trade_period_list[curr_period['product']].append(new_period) max_slippage = Decimal(str(config['max_slippage'])) self.trade_engine = engine.TradeEngine(auth_client, product_list=self.product_list, fiat=fiat_currency, is_live=config['live'], max_slippage=max_slippage) self.cbpro_websocket = engine.TradeAndHeartbeatWebsocket(fiat=fiat_currency, sandbox=config['sandbox']) self.cbpro_websocket.start() self.indicator_period_list[0].verbose_heartbeat = True self.indicator_subsys = indicators.IndicatorSubsystem(self.indicator_period_list) self.last_indicator_update = time.time() if config['frontend'] == 'curses': curses_enable = True else: curses_enable = False self.interface = interface.cursesDisplay(enable=curses_enable) if config['frontend'] == 'web': web_interface = interface.web(self.indicator_subsys, self.trade_engine) server_thread = threading.Thread(target=web_interface.start, daemon=True) server_thread.start()
def main(config): logger = logging.getLogger('trader-logger') logger.setLevel(logging.DEBUG) if config['logging']: logger.addHandler(logging.FileHandler("debug.log")) if config['frontend'] == 'debug': logger.addHandler(logging.StreamHandler()) error_logger = logging.getLogger('error-logger') error_logger.addHandler(logging.FileHandler("error.log")) # Periods to update indicators for indicator_period_list = [] # Periods to actively trade on (typically 1 per product) trade_period_list = {} # List of products that we are actually monitoring product_list = set() fiat_currency = config['fiat'] for cur_period in config['periods']: if cur_period.get('meta'): new_period = period.MetaPeriod(period_size=(60 * cur_period['length']), fiat=fiat_currency, product=cur_period['product'], name=cur_period['name']) else: new_period = period.Period(period_size=(60 * cur_period['length']), product=cur_period['product'], name=cur_period['name']) indicator_period_list.append(new_period) product_list.add(cur_period['product']) if cur_period['trade']: if trade_period_list.get(cur_period['product']) is None: trade_period_list[cur_period['product']] = [] trade_period_list[cur_period['product']].append(new_period) auth_client = gdax.AuthenticatedClient(config['key'], config['secret'], config['passphrase']) max_slippage = Decimal(str(config['max_slippage'])) trade_engine = engine.TradeEngine(auth_client, product_list=product_list, fiat=fiat_currency, is_live=config['live'], max_slippage=max_slippage) gdax_websocket = TradeAndHeartbeatWebsocket(fiat=fiat_currency) gdax_websocket.start() indicator_period_list[0].verbose_heartbeat = True indicator_subsys = indicators.IndicatorSubsystem(indicator_period_list) last_indicator_update = time.time() if config['frontend'] == 'curses': interface = interfaces.cursesDisplay(enable=True) elif config['frontend'] == 'flask': interface = interfaces.flaskInterface(enable=True) else: interface = interfaces.cursesDisplay(enable=False) while (True): try: msg = gdax_websocket.websocket_queue.get(timeout=15) for product in trade_engine.products: product.order_book.process_message(msg) if msg.get('type') == "match": for cur_period in indicator_period_list: cur_period.process_trade(msg) if time.time() - last_indicator_update >= 1.0: for cur_period in indicator_period_list: indicator_subsys.recalculate_indicators(cur_period) for product_id, period_list in trade_period_list.items(): trade_engine.determine_trades( product_id, period_list, indicator_subsys.current_indicators) last_indicator_update = time.time() elif msg.get('type') == "heartbeat": for cur_period in indicator_period_list: cur_period.process_heartbeat(msg) for product_id, period_list in trade_period_list.items(): if len(indicator_subsys.current_indicators[ cur_period.name]) > 0: trade_engine.determine_trades( product_id, period_list, indicator_subsys.current_indicators) trade_engine.print_amounts() interface.update(trade_engine, indicator_subsys.current_indicators, indicator_period_list, msg) except KeyboardInterrupt: trade_engine.close(exit=True) gdax_websocket.close() interface.close() break except Exception as e: error_logger.exception(datetime.datetime.now()) trade_engine.close() gdax_websocket.close() # Period data cannot be trusted. Re-initialize for cur_period in indicator_period_list: cur_period.initialize() time.sleep(10) gdax_websocket.start()