Example #1
0
    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)
Example #3
0
 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)
Example #4
0
    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()
Example #5
0
    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)