def __connect(self, wsURL): '''Connect to the websocket in a thread.''' self.logger.debug("Starting thread") ssl_defaults = ssl.get_default_verify_paths() sslopt_ca_certs = {'ca_certs': ssl_defaults.cafile} self.ws = websocket.WebSocketApp(wsURL, on_message=self.__on_message, on_close=self.__on_close, on_open=self.__on_open, on_error=self.__on_error, header=self.__get_auth() ) setup_custom_logger('websocket', log_level=settings.LOG_LEVEL) self.wst = threading.Thread(target=lambda: self.ws.run_forever(sslopt=sslopt_ca_certs)) self.wst.daemon = True self.wst.start() self.logger.info("Started thread") # Wait for connect before continuing conn_timeout = 5 while (not self.ws.sock or not self.ws.sock.connected) and conn_timeout and not self._error: sleep(1) conn_timeout -= 1 if not conn_timeout or self._error: self.logger.error("Couldn't connect to WS! Exiting.") tg_send_important_message("Couldn't connect to WS! Exiting.") self.exit() sys.exit(1)
def send_tg_message(self): now = datetime.datetime.now() mybalance = '%.6f' % XBt_to_XBT(self.start_XBt) message = 'BitMEX交易状态\n' + \ '时间:' + now.astimezone(datetime.timezone(datetime.timedelta(hours=8))).strftime('%Y-%m-%d %H:%M:%S') + '\n' + \ '保证金余额:' + mybalance + '\n' + \ '合约数量:' + str(self.running_qty) + '\n' + \ '开仓价格:' + str(self.exchange.get_position()['avgCostPrice']) + '\n' + \ '风险等级:' + str(self.position_grade) + '\n' + \ '最新价格:' + str(self.get_ticker()['last']) + '\n' + \ '指数价格:' + str(self.exchange.get_portfolio()['XBTUSD']['markPrice']) + '\n' + \ '今日盈利:' + '%.6f' % (float(mybalance) - self.yesterday_balance) + '\n' + \ '作日盈利:' + '%.6f' % (self.yesterday_balance - self.before_yesterday_balance) tg_send_message(message) if self.position_grade > 4: tg_send_important_message(message)
def write_mybalance(self): now = datetime.datetime.now() mybalance = '%.6f' % XBt_to_XBT(self.start_XBt) with open(r'/root/mybalance2.txt', 'a') as f: f.write(now.strftime('%Y-%m-%d %H:%M:%S') + ' ' + mybalance + '\n') message = 'BitMEX今日交易统计' + ACCOUNT_NAME + '\n' + \ '时间:' + now.strftime('%Y-%m-%d %H:%M:%S') + '\n' + \ '保证金余额:' + mybalance + '\n' + \ '合约数量:' + str(self.running_qty) + '\n' + \ '开仓价格:' + str(self.exchange.get_position()['avgCostPrice']) + '\n' + \ '最新价格:' + str(self.get_ticker()['last']) + '\n' + \ '指数价格:' + str(self.exchange.get_portfolio()['XBTUSD']['markPrice']) + '\n' + \ '今日盈利:' + '%.6f' % (float(mybalance) - self.yesterday_balance) + '\n' + \ '作日盈利:' + '%.6f' % (self.yesterday_balance - self.before_yesterday_balance) tg_send_important_message(message) self.before_yesterday_balance = self.yesterday_balance self.yesterday_balance = float(mybalance)
def exit(self): logger.info("Shutting down. All open orders will be cancelled.") now = datetime.datetime.now() message = 'BitMEX交易机器人2异常退出\n' + \ '时间:' + now.astimezone(datetime.timezone(datetime.timedelta(hours=8))).strftime('%Y-%m-%d %H:%M:%S') + '\n' + \ '合约数量:' + str(self.running_qty) + '\n' + \ '开仓价格:' + str(self.exchange.get_position()['avgCostPrice']) + '\n' + \ '最新价格:' + str(self.get_ticker()['last']) + '\n' + \ '指数价格:' + str(self.exchange.get_portfolio()['XBTUSD']['markPrice']) tg_send_important_message(message) try: self.exchange.cancel_all_orders() self.exchange.bitmex.exit() except errors.AuthenticationError as e: logger.info("Was not authenticated; could not cancel orders.") except Exception as e: logger.info("Unable to cancel orders: %s" % e) sys.exit()
def place_orders(self): """Create order items for use in convergence.""" buy_orders = [] sell_orders = [] buy_stop_order = {} sell_stop_order = {} order_status = 0 """order_status参数说明 0: running_qty为0, 维持原样 1: self.running_qty > 0, 买卖都变化, 买单按照offset2, 卖单按照offset3 2: 买单维持不变, 卖单按照offset3 3: self.running_qty < 0, 买卖都变化, 买单按照offset3, 卖单按照offset2 4: 卖单维持不变, 买单按照offset3 5: 追加指定订单 6: 取消指定订单 7: self.running_qty > 0, 买单按照offset2, 卖单不变 8: self.running_qty < 0, 买单不变, 卖单按照offset2 9: self.running_qty > 0, 买单维持不变, 卖单变化, 不追加 10: self.running_qty < 0, 卖单维持不变, 买单变化, 不追加 11: 订单变化, 不可追加 """ # Create orders from the outside in. This is intentional - let's say the inner order gets taken; # then we match orders from the outside in, ensuring the fewest number of orders are amended and only # a new order is created in the inside. If we did it inside-out, all orders would be amended # down and a new order would be created at the outside. avgCostPrice = self.exchange.get_position()['avgCostPrice'] print ('running_qty: %s ' % self.running_qty) print ('ORDER_START_SIZE: %s ' % self.ORDER_START_SIZE) print ('wave_coefficient: %s ' % self.get_wave_coefficient()) self.mode_number = self.select_mode() print ('select_mode: %s ' % self.mode_number) schedule.run_pending() if(((self.get_ticker()['last'] - self.get_MA20()) > 100) and self.running_qty == 0 and self.stop_market_maker_flag == False): self.stop_market_maker_flag = True if (len(self.exchange.get_orders()) != 0): self.exchange.cancel_all_orders() tg_send_important_message('超涨模式大于100,暂停交易') self.stop_price_flag = True elif(self.get_ticker()['last'] < (self.stop_order_price+50) and self.running_qty == 0 and self.stop_market_maker_flag == False): self.stop_market_maker_flag = True if (len(self.exchange.get_orders()) != 0): self.exchange.cancel_all_orders() tg_send_important_message('触发止损,暂停交易') self.stop_price_flag = True elif(self.stop_market_maker_flag == True and self.cancel_all_orders_flag == True): if (len(self.exchange.get_orders()) != 0): self.exchange.cancel_all_orders() logger.info("Cancel all orders") elif(self.stop_market_maker_flag == True and self.clear_position_flag == True): if(self.running_qty != 0): self.clear_position(buy_orders, sell_orders) else: if (len(self.exchange.get_orders()) != 0): self.exchange.cancel_all_orders() logger.info("Market_maker has stopped. No orders, no positions now") elif(self.stop_market_maker_flag == True): if(self.running_qty > 0): if avgCostPrice != None: sell_stop_order = self.prepare_stop_order(math.toNearest(avgCostPrice - STOP_SIZE, self.instrument['tickSize']), "Sell", abs(self.running_qty)) order_status = 4 elif(self.running_qty < 0): if avgCostPrice != None: buy_stop_order = self.prepare_stop_order(math.toNearest(avgCostPrice + STOP_SIZE, self.instrument['tickSize']), "Buy", abs(self.running_qty)) order_status = 2 elif(self.running_qty == 0 and self.last_running_qty == 0): if(self.stop_price_flag == True): pass elif (len(self.exchange.get_orders()) != 0): self.exchange.cancel_all_orders() logger.info("Market_maker has stopped. No orders, no positions now") elif(self.running_qty == 0 and self.restart_flag == False): self.ORDER_START_SIZE = self.start_XBt // 100000 * START_SIZE_MAGNIFICATION #新算法, 每次初始交易重新设定ORDER_START_SIZE order_status = 0 if not(self.sell_only_flag == True): buy_orders.append(self.prepare_order(-1, order_status)) if not(self.buy_only_flag == True): sell_orders.append(self.prepare_order(1, order_status)) self.restart_flag = True self.countdown_restart = 5 if(self.change_order_flag == True and self.last_mode_number2 == self.mode_number): order_status = 11 self.change_order_flag = True if(self.last_running_qty > 0): tg_send_message_alias('最后成交价格:%s' % self.last_sell_orders[0]['price']) elif(self.last_running_qty < 0): tg_send_message_alias('最后成交价格:%s' % self.last_buy_orders[0]['price']) self.countdown_180 = 180 elif(self.running_qty == 0 and self.restart_flag == True): self.countdown_restart = self.countdown_restart - 1 if(self.countdown_restart <= 0): self.restart_flag = False return elif(self.running_qty != 0 and self.last_running_qty == 0): if(self.running_qty > 0): order_status = 2 sell_orders.append(self.prepare_order(1, order_status)) if avgCostPrice != None: sell_stop_order = self.prepare_stop_order(math.toNearest(avgCostPrice - STOP_SIZE, self.instrument['tickSize']), "Sell", abs(self.running_qty)) elif(self.running_qty < 0): order_status = 4 buy_orders.append(self.prepare_order(-1, order_status)) if avgCostPrice != None: buy_stop_order = self.prepare_stop_order(math.toNearest(avgCostPrice + STOP_SIZE, self.instrument['tickSize']), "Buy", abs(self.running_qty)) self.restart_flag = False self.change_order_flag = False elif(self.running_qty != 0 and self.running_qty == self.last_running_qty and self.delay_order_check == True and False): #可以重新挂非清仓方向的价格, 目前只有一级仓位,所以不需要 i = abs(self.running_qty) // (self.ORDER_START_SIZE) + 1 if(self.running_qty > 0): order_status = 7 if(i <= 1): buy_orders.append(self.prepare_order(-i, order_status)) if(self.running_qty < 0): order_status = 8 if(i <= 1): sell_orders.append(self.prepare_order(i, order_status)) self.cycleclock = 30 self.delay_order_check = False else: if(self.running_qty > 0): if(self.running_qty != self.ORDER_START_SIZE): #部分成交, 不操作等待全部成交 return if(self.reset == True): order_status = 0 else: if(self.countdown_180 > 0): self.countdown_180 = self.countdown_180 - 1 return else: self.countdown_180 = 180 order_status = 9 sell_orders.append(self.prepare_order(1, order_status)) if(self.buy_only_flag == True): #仅挂买单的场合, 成交后平仓的卖单价格不降低 if(sell_orders[0]['price'] < self.last_sell_orders[0]['price']): return if avgCostPrice != None: sell_stop_order = self.prepare_stop_order(math.toNearest(avgCostPrice - STOP_SIZE, self.instrument['tickSize']), "Sell", abs(self.running_qty)) elif(self.running_qty < 0): if(abs(self.running_qty) != self.ORDER_START_SIZE): #部分成交, 不操作等待全部成交 return if(self.reset == True): order_status = 0 else: if(self.countdown_180 > 0): self.countdown_180 = self.countdown_180 - 1 return else: self.countdown_180 = 180 order_status = 10 buy_orders.append(self.prepare_order(-1, order_status)) if avgCostPrice != None: buy_stop_order = self.prepare_stop_order(math.toNearest(avgCostPrice + STOP_SIZE, self.instrument['tickSize']), "Buy", abs(self.running_qty)) if(self.last_running_qty != self.running_qty): self.send_tg_message() self.last_running_qty = self.running_qty self.last_mode_number2 = self.last_mode_number self.reset = False buy_orders = list(filter(None.__ne__, buy_orders)) #去除None sell_orders = list(filter(None.__ne__, sell_orders)) #去除None print(buy_orders) print(sell_orders) if((self.last_buy_orders == buy_orders and self.last_sell_orders == sell_orders) or (buy_orders == [] and sell_orders == [])): print('order no change, return') return else: self.last_buy_orders = buy_orders self.last_sell_orders = sell_orders self.converge_stop_order(buy_stop_order, sell_stop_order) return self.converge_orders(buy_orders, sell_orders, order_status)