def initialize_arb(): welcome_message = "\n\n---------------------------------------------------------\n\n" welcome_message += "Binance auto trading bot\n" bot_start_time = str(datetime.now()) welcome_message += "\nBot Start Time: {}\n\n\n".format(bot_start_time) logger.info(welcome_message) time.sleep(1) status = client.get_system_status() logger.info("\nExchange Status: {}" % status) # step1 第一入口 # 1.2 借出币 if loan_enabled: loan_asset(coin_symbol, loan) # step2 监听杠杆交易 global bm, conn_key bm = BinanceSocketManager(client) conn_key = bm.start_margin_socket(process_message) logger.info("websocket Conn key: {}".format(conn_key)) bm.setDaemon(True) bm.start() # 根据KDJ线 + Bolling线 定期执行, 主进程 t = threading.Thread(target=kdj_signal_loop, args=(pair_symbol, )) t.start() # 30分钟ping user websocket,key可以存活1个小时 l = threading.Thread(target=get_margin_stream_keepalive, args=(conn_key, )) l.setDaemon(True) l.start() # 30分钟检查一下过期的订单,主动取消。保证可以挂新订单。 t = threading.Thread(target=outdated_order_clear, args=(pair_symbol, )) t.setDaemon(True) t.start()
class BinanceDataListener(ExchangeDataListener): PORTFOLIO_UPDATE_STRING = 'outboundAccountInfo' ORDER_UPDATE_STRING = 'executionReport' def __init__(self, exchangeClient, marketDataManager, marketRulesManager, portfolioManager, orderManager): super(BinanceDataListener, self).__init__(exchangeClient, marketDataManager, marketRulesManager, portfolioManager, orderManager) self.binanceSocket = BinanceSocketManager( self.exchangeClient.getRawClient()) self.binanceSocket.setDaemon(True) self.log.init(logForceDebug=False) def dispatchUserDataUpdate(self, msg): self.log.debug('User data message received: ' + str(msg)) if msg['e'] == self.PORTFOLIO_UPDATE_STRING: self.processPortfolioUpdate(msg) elif msg['e'] == self.ORDER_UPDATE_STRING: self.processOrderUpdate(msg) def parseOrderUpdate(self, msg): symbol = msg['s'] quoteAsset = SupportedQuoteAsset.getQuoteAsset( symbol, BINANCE_SUPPORTED_QUOTE_ASSET) baseAsset = symbol[:len(symbol) - len(quoteAsset)] orderResponse = OrderResponse( baseAsset=baseAsset, quoteAsset=quoteAsset, orderSide=BinanceOrderSideMapper.getCretenValue(msg['S']), orderType=BinanceOrderTypeMapper.getCretenValue(msg['o']), origQty=msg['q'], lastExecutedQty=msg['l'], sumExecutedQty=msg['z'], price=msg['p'], orderTmstmp=datetime.fromtimestamp(msg['T'] / 1000), orderState=BinanceOrderStateMapper.getCretenValue(msg['X']), clientOrderId=msg['c'], extOrderRef=msg['i'], rawData=msg) return orderResponse def parsePortfolioUpdate(self, msg): positions = [] for balance in msg['B']: asset = balance['a'] free = float(balance['f']) locked = float(balance['l']) # TODO do only for subscribed pairs positions.append(Position(asset, free, locked)) return positions def parseCandleUpdate(self, msg): symbol = msg['s'] quoteAsset = SupportedQuoteAsset.getQuoteAsset( symbol, BINANCE_SUPPORTED_QUOTE_ASSET) baseAsset = symbol[:len(symbol) - len(quoteAsset)] interval = msg['k']['i'] kline = msg['k'] cretenInterval = BinanceIntervalMapper.getCretenValue(interval) candle = Candle( baseAsset=baseAsset, quoteAsset=quoteAsset, interval=cretenInterval, openTime=datetime.fromtimestamp(int(kline['t']) / 1000), open=kline['o'], high=kline['h'], low=kline['l'], close=kline['c'], volume=kline['v'], closeTime=datetime.fromtimestamp(int(kline['T']) / 1000), quoteAssetVolume=kline['q'], tradesNb=kline['n'], takerBuyBaseAssetVol=kline['V'], takerBuyQuoteAssetVol=kline['Q'], isClosing=kline['x']) return candle def start(self): # subsribe candle listeners for candleSubscription in self.candleSubscriptions: binanceInterval = BinanceIntervalMapper.getBinanceValue( candleSubscription.cretenInterval) self.binanceSocket.start_kline_socket( candleSubscription.pair.getSymbol(), self.processCandleUpdate, binanceInterval) # subscribe user data listener self.binanceSocket.start_user_socket(self.dispatchUserDataUpdate) # start listening self.binanceSocket.start()