def retrieve_backward(end, product_id, granularity, offset): adapter = CoinbaseAdapter() storage_manager = StorageManager('mongodb') while True: start = end - timedelta(days=offset) logger.info('Importing from: {start} to end: {end}'.format(start=start, end=end)) response = adapter.get_historic_rates(product_id, start.replace(microsecond=0).isoformat(), end.replace(microsecond=0).isoformat(), granularity) if not response: break for candle in response: storage_manager.create_candle(candle[0], candle[1], candle[2], candle[3], candle[4], candle[5], product_id, granularity) min_time = response[-1][0] end = datetime.fromtimestamp(min_time)
def retrieve_forward(start, product_id, granularity, offset): adapter = CoinbaseAdapter() storage_manager = StorageManager('mongodb') while True: yesterday = datetime.utcnow() - timedelta(days=1) if start + timedelta(days=offset) > yesterday: end = yesterday else: end = start + timedelta(days=offset) logger.info('Importing from: {start} to end: {end}'.format(start=start, end=end)) response = adapter.get_historic_rates(product_id, start.replace(microsecond=0).isoformat(), end.replace(microsecond=0).isoformat(), granularity) for candle in response: storage_manager.create_candle(candle[0], candle[1], candle[2], candle[3], candle[4], candle[5], product_id, granularity) max_time = response[0][0] start = datetime.fromtimestamp(max_time) if start.date() == yesterday.date(): break
def consume(self): with open(self.filename, 'r') as f: signal_dict = json.load(f) logger.info('Received signal: %s', signal_dict) trade_signal = TradeSignal(signal_id=signal_dict['order_id'], product_id=signal_dict['product_id'], order_type=signal_dict['type'], side=signal_dict['side'], size=signal_dict['size']) self.order_manager.process(trade_signal)
def check_orders(self): statuses = [self.STATUS_PENDING, self.STATUS_OPEN] orders = self.storage.get_orders(statuses) for order in orders: logger.info("Order: " + str(order)) # TODO: order_result['id'] already in db, decrease API calls. order_result = self.exchange.get_order(order['order_id']) exchange_fills = self.exchange.get_fills(order_result['id']) persisted_fills = order.get('fills') new_fills = self._get_new_fills(exchange_fills, persisted_fills) if not new_fills: continue logger.info('New Fills: %s', new_fills) self.storage.update_order(order['order_id'], new_fills, order_result['status'])
def consume(self): while True: messages = self.queue.receive_messages( MaxNumberOfMessages=config['aws']['sqs'] ['max_number_of_messages'], WaitTimeSeconds=config['aws']['sqs']['wait_time_seconds']) for message in messages: signal_dict = json.loads(message.body) logger.info('Received message %s', signal_dict) trade_signal = TradeSignal( signal_id=signal_dict['order_id'], product_id=signal_dict['product_id'], order_type=signal_dict['type'], side=signal_dict['side'], size=signal_dict['size']) self.order_manager.process(trade_signal) message.delete()
def process(self, trade_signal: TradeSignal): self.storage.create_signal(trade_signal) account = self.exchange.get_account(trade_signal.currency) # TODO: Can process only size='all' # get maximum amount of balance with scale of 8 digits and rounding down it. if trade_signal.size == 'all': order_size = Decimal(account['balance']).quantize(Decimal('.0001'), rounding=ROUND_DOWN) else: order_size = trade_signal.size order = { 'size': str(order_size), 'type': trade_signal.order_type, 'side': trade_signal.side, 'product_id': trade_signal.product_id, } logger.info('Submitting order: %s', order) submitted_order = self.exchange.submit_order(order) if submitted_order is None: logger.error('Submitted order is None!') return logger.info('Received order: %s', submitted_order) # TODO: Are all timestamps UTC? trade_order = TradeOrder( trade_signal.signal_id, submitted_order['id'], # TODO: Coinbase specific. Make this more generic. submitted_order.get('price'), submitted_order['side'], submitted_order['size'], submitted_order['product_id'], submitted_order['created_at'], submitted_order.get('done_at'), submitted_order['status'], submitted_order['type'] ) self.storage.create_order(trade_order)
def main(): parser = argparse.ArgumentParser() parser.add_argument('--logging-level', default='info', choices=['debug', 'info', 'warning', 'error'], type=str.lower, help='Print logs') parser.add_argument( '--worker', choices=['signal-consumer', 'order-checker', 'backtesting-importer'], type=str.lower, help='Workers') parser.add_argument('--database', choices=StorageManager.storage_types.keys(), help='Database', default='mongodb') parser.add_argument('--signal-source', choices=Receiver.source_types.keys(), help='Signal source', default='sqs') parser.add_argument('--source-filename', help='JSON formatted file as a file source') parser.add_argument('--log-file', help='Log file name') parser.add_argument('--config-file', type=str.lower, help='Config file') parser.add_argument('--exchange', help='Exchange check orders', choices=OrderManager.exchange_types.keys(), type=str.lower, default='coinbase') args = parser.parse_args() # Logging setup setup_logging(args.logging_level, filename=args.log_file) # Load config file load_config(args.config_file) # Create storage manager. storage_manager = StorageManager(storage=args.database) logger.info('Starting storage => %s', storage_manager) logger.info('Exchange => %s', args.exchange) logger.info('Signal source => %s', args.signal_source) if args.worker == 'signal-consumer': logger.info('Starting signal consumer...') receiver = Receiver(storage_manager, args.exchange, args.signal_source, filename=args.source_filename) receiver.consume() logger.info('Exiting..') return if args.worker == 'order-checker': logger.info('Starting order checker...') order_manager = OrderManager(storage_manager, args.exchange) while True: order_manager.check_orders() logger.info('Sleeping for 5 seconds...') time.sleep(5) logger.info('Exiting..') return if args.worker == 'backtesting-importer': logger.info('Starting data importer') import_rates()