예제 #1
0
def run():
    logger = setup_logger()

    # Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.
    ws = BitMEXWebsocket(
        endpoint="https://testnet.bitmex.com/api/v1",
        symbol="XBTUSD",
        api_key='-H4GmpGWNC505KogaaKyxoch',
        api_secret='GBM8hOsE9PYnKj374IHqv7M096sEpRSfoLZvA3hvY6oIHizJ')

    logger.info("Instrument data: %s" % ws.get_instrument())

    # Run forever
    while (ws.ws.sock.connected):
        # print("test")
        logger.info("Ticker: %s" % ws.get_ticker())
        data = ws.get_ticker()
        data = [str(data[k]) for k in data]
        with open(r'bitmex.csv', 'a') as f:
            writer = csv.writer(f)
            writer.writerow(data)
        f.close()
        # if ws.api_key:
        #     logger.info("Funds: %s" % ws.funds())
        # logger.info("Market Depth: %s" % ws.market_depth())
        # logger.info("Recent Trades: %s\n\n" % ws.recent_trades())
        sleep(10)
예제 #2
0
파일: bitmex_ws.py 프로젝트: R2FREE/Ritchi
def run_ws(queue, evt_init_1min, testing=config.testing):
    setup_logger()
    endpoint = endpoint_real if not testing else endpoint_test

    ws = BitMEXWebsocket(
        endpoint=endpoint, symbol="XBTUSD",
        # api_key='',
        # api_secret='')
    )

    df_tick_null = pandas.DataFrame(columns=['timestamp', 'price'])

    df_tick = df_tick_null

    time_now = datetime.datetime.strptime(ws.get_ticker()[0], UTC_FORMAT)  # get the timestamp return with WS
    time_init = (time_now + timedelta_1min).replace(microsecond=0, second=0)  # get the time which add 1min
    time_cyc = time_init + timedelta_1min  # get the time added 2min
    '''may got some bug in this sleep, could cause sleep less'''
    sleep((time_init - datetime.datetime.strptime(ws.get_ticker()[0], UTC_FORMAT)).total_seconds())

    evt_init_1min.set()

    while 1:
    # while ws.ws.sock.connected:
    #     if ws.api_key:
    #         logger.info("Funds: %s" % ws.funds())

        price = ws.get_ticker()[1]
        time_now = datetime.datetime.strptime(ws.get_ticker()[0], UTC_FORMAT)

        # '>=' will contain the whole point time situation
        if time_now >= time_cyc:
            df_1min = df_tick.set_index(['timestamp'])  # get all the tick in 1 min by DataFrame form
            # convert to 1_min ohlc
            df_1min = df_1min['price'].resample(rule='1Min').ohlc()

            # # if got 2 row, delete first row
            # if df_1min.shape[0] == 2:
            #     df_1min = df_1min.iloc[1:]

            queue.put(df_1min)
            logging.debug(df_1min)
            # logging.info('******WS put 1-min kline******')

            time_cyc = time_cyc + timedelta_1min  # rest the time used for judge
            time_init = time_init + timedelta_1min
            df_tick = df_tick_null  # reset the df_tick for the next LOOP
            df_temp = pandas.DataFrame([[time_now, price]], columns=['timestamp', 'price'])  # to put the time_now's data to df
            df_tick = df_tick.append(df_temp)  # append the last tick to the temporary df

        elif time_now >= time_init:
            df_temp = pandas.DataFrame([[time_now, price]], columns=['timestamp', 'price'])
            df_tick = df_tick.append(df_temp)  # append the last tick to the temporary df

        sleep(0.5)
예제 #3
0
def update_ticker():
    ws_ticker = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1", symbol="XBTUSD",
                         api_key=None, api_secret=None)
    while (ws_ticker.ws.sock.connected):
        ws_ticker.get_instrument()
        ticker=ws_ticker.get_ticker()
        db.mkt.update_one({"_id":"ticker"},{"$set":ticker})
        logging.info("ticker done")
        sleep(5)
예제 #4
0
def run():
    logger = setup_logger()
    config = configparser.ConfigParser()
    config.read('config.ini')
    client = bitmex.bitmex(api_key=config['AUTH']['api_key'],
        api_secret=config['AUTH']['api_secret'])

    # Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.
    ws = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1", symbol="XBTUSD",
                         api_key=config['AUTH']['api_key'],
                         api_secret=config['AUTH']['api_secret'])

    # logger.info("Instrument data: %s" % ws.get_instrument())

    a1 = config['VALUES']['a1']
    a2 = config['VALUES']['a2']
    aQty = config['VALUES']['aQty']
    b1 = config['VALUES']['b1']
    b2 = config['VALUES']['b2']
    bQty = config['VALUES']['bQty']

    # Run forever
    triggered = False
    try:

        (body, response) = client.Order.Order_new(
                symbol='XBTUSD', orderQty=aQty, price="8999",
                contingencyType="OneTriggersTheOther", clOrdLinkID="Triggered").result()
        while(ws.ws.sock.connected):
            price = ws.get_ticker()
            print(price['mid'])
            if not triggered and price['mid'] > float(a1):
                (body, response) = client.Order.Order_new(
                    symbol='XBTUSD', orderQty=aQty, price=a1,
                    contingencyType="OneTriggersTheOther", clOrdLinkID="Triggered").result()
                (body, response) = client.Order.Order_new(
                    symbol='XBTUSD', orderQty=aQty, price=a2, side="Sell",
                    clOrdLinkID="Triggered").result()
                triggered = True
            elif not triggered and price['mid'] < float(b1):
                (body, response) = client.Order.Order_new(
                    symbol='XBTUSD', orderQty=bQty, price=b1, side="Sell",
                    contingencyType="OneTriggersTheOther", clOrdLinkID="Triggered").result()
                (body, response) = client.Order.Order_new(
                    symbol='XBTUSD', orderQty=bQty, price=b2,
                    clOrdLinkID="Triggered").result()
                triggered = True

            pp = pprint.PrettyPrinter(indent=4)
            sleep(1)
    except KeyboardInterrupt as e:
        print(client.Order.Order_cancelAll().result())
예제 #5
0
def run(mexbot):

    mexbot.logger.debug("Started Ticker thread")

    # Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.
    ws = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1",
                         symbol=mexbot.symbol,
                         api_key=mexbot.config.get("api_key"),
                         api_secret=mexbot.config.get("api_secret"))

    mexbot.logger.debug("Instrument data: %s" % ws.get_instrument())

    # Run forever
    while (ws.ws.sock.connected):
        mexbot.update_ticker(ws.get_ticker())
    mexbot.logger.error("Websocket disconnected")
예제 #6
0
def run(mexbot):
    print("in thread")
    logger = setup_logger()

    # Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.
    ws = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1",
                         symbol=mexbot.symbol,
                         api_key=None,
                         api_secret=None)

    logger.info("Instrument data: %s" % ws.get_instrument())

    # Run forever
    while (ws.ws.sock.connected):
        # logger.info("Ticker: %s" % ws.get_ticker())
        mexbot.updateTicker(ws.get_ticker())
예제 #7
0
def run():
    logger = setup_logger()

    # Instantiating the WS will make it connect. Be sure to add an auth method. You can use login/password
    # or api_key/api_secret.
    ws = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1", symbol="XBT24H",
                         login="******", password="******", api_key=None, api_secret=None)

    logger.info("Instrument data: %s" % ws.get_instrument())

    # Run forever
    while(ws.ws.sock.connected):
        logger.info("Ticker: %s" % ws.get_ticker())
        logger.info("Funds: %s" % ws.funds())
        logger.info("Market Depth: %s" % ws.market_depth())
        logger.info("Recent Trades: %s\n\n" % ws.recent_trades())
        sleep(10)
예제 #8
0
def run():
    logger = setup_logger()

    # Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.
    ws = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1", symbol="XBTUSD",
                         api_key=None, api_secret=None)

    logger.info("Instrument data: %s" % ws.get_instrument())

    # Run forever
    while(ws.ws.sock.connected):
        logger.info("Ticker: %s" % ws.get_ticker())
        if ws.config['api_key']:
            logger.info("Funds: %s" % ws.funds())
        logger.info("Market Depth: %s" % ws.market_depth())
        logger.info("Recent Trades: %s\n\n" % ws.recent_trades())
        sleep(10)
예제 #9
0
def run():
    logger = setup_logger()

    # Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.
    ws = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1", symbol="XBTUSD",
                         api_key=None, api_secret=None)

    logger.info("Instrument data: %s" % ws.get_instrument())

    # Run forever
    while(ws.ws.sock.connected):
        logger.info("Ticker: %s" % ws.get_ticker())
        if ws.api_key:
            logger.info("Funds: %s" % ws.funds())
        logger.info("Market Depth: %s" % ws.market_depth())
        logger.info("Recent Trades: %s\n\n" % ws.recent_trades())
        sleep(10)
예제 #10
0
파일: main.py 프로젝트: jnst/bitmex-ws-bot
def run():
    logger = setup_logger()

    config = configparser.ConfigParser()
    config.read('config/config.ini')

    ws = BitMEXWebsocket(endpoint=config['bitmex']['endpoint'], symbol="XBTUSD",
                         api_key=config['bitmex']['api_key'], api_secret=config['bitmex']['api_secret'])

    logger.info("Instrument data: %s" % ws.get_instrument())

    # Run forever
    while(ws.ws.sock.connected):
        logger.info("Ticker: %s" % ws.get_ticker())
        if ws.api_key:
            logger.info("Funds: %s" % ws.funds())
        logger.info("Market Depth: %s" % ws.market_depth())
        logger.info("Recent Trades: %s\n\n" % ws.recent_trades())
        sleep(10)
예제 #11
0
def run():
    logger = setup_logger()

    # Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.
    ws = BitMEXWebsocket(
        endpoint="wss://testnet.bitmex.com/realtime",
        symbol="XBTUSD",
        api_key="wwvS30igJDo6Ksxa0h2EP1Eq",
        api_secret="-DOHRIUObpSQilqyr2y18YcTRi5NWFIV95du4i8rG4VveOBI")

    logger.info("Instrument data: {}".format(ws.get_instrument()))

    # Run forever
    while (ws.ws.sock.connected):
        logger.info("Ticker: %s" % ws.get_ticker())
        if ws.config['api_key']:
            logger.info("Funds: %s" % ws.funds())
        logger.info("Market Depth: %s" % ws.market_depth())
        logger.info("Recent Trades: %s\n\n" % ws.recent_trades())
        sleep(10)
예제 #12
0
def run():
    logger = setup_logger()

    # Instantiating the WS will make it connect. Be sure to add an auth method. You can use login/password
    # or api_key/api_secret.
    ws = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1",
                         symbol="XBT24H",
                         login="******",
                         password="******",
                         api_key=None,
                         api_secret=None)

    logger.info("Instrument data: %s" % ws.get_instrument())

    # Run forever
    while (ws.ws.sock.connected):
        logger.info("Ticker: %s" % ws.get_ticker())
        logger.info("Funds: %s" % ws.funds())
        logger.info("Market Depth: %s" % ws.market_depth())
        logger.info("Recent Trades: %s\n\n" % ws.recent_trades())
        sleep(10)
예제 #13
0
class BitMexWS(object):
    """
    适合订阅数据
    """

    def __init__(self, api_key=None, api_secret=None, symbol="XBTUSD"):
        endpoint = "https://testnet.bitmex.com/api/v1"
        if api_key:
            endpoint = "https://www.bitmex.com/api/v1"
        self.ws = BitMEXWebsocket(endpoint=endpoint,
                                  symbol=symbol,
                                  api_key=api_key,
                                  api_secret=api_secret)

    def run(self):
        logger = self.setup_logger()
        # Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.

        logger.info("Instrument data: %s" % self.ws.get_instrument())

        # Run forever
        while self.ws.ws.sock.connected:
            logger.info("Ticker: %s" % self.ws.get_ticker())
            if self.ws.api_key:
                logger.info("Funds: %s" % self.ws.funds())
            logger.info("Market Depth: %s" % self.ws.market_depth())
            logger.info("Recent Trades: %s\n\n" % self.ws.recent_trades())
            sleep(10)

    def setup_logger(self):
        # Prints logger info to terminal
        logger = logging.getLogger()
        logger.setLevel(logging.INFO)  # Change this to DEBUG if you want a lot more info
        ch = logging.StreamHandler()
        # create formatter
        formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
        # add formatter to ch
        ch.setFormatter(formatter)
        logger.addHandler(ch)
        return logger
예제 #14
0
class Algorithm(object):
    def __init__(self, value_pair):
        global Flag_of_begining
        Flag_of_begining = False
        api_key = '6AnZMBW9F-a2Yf1cH28v_l8j'
        self.value_pair = value_pair
        self.Flag_of_begining = False
        secret_key = 'JsFkkeg2AMQziEsWioNmQzGm9LDNS5310NkXAT1FRxZdpu6k'
        self.ws = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1",
                                  symbol=f'{self.value_pair}',
                                  api_key=api_key,
                                  api_secret=secret_key)
        self.ws.get_instrument()
        self.counter = 0
        self.shoulder = 50
        self.start_money = 10

        pass

    def currancy_value(self, count=1):
        start_time = time.time()
        time.sleep(1.05)
        price_response = self.ws.get_ticker()
        #print(self.counter,'    ',price_response['last'])
        self.counter += 1
        return (time.time() - start_time), price_response['last'],

    def currancy_value1(self, value='XBT', count=1):
        start_time = time.time()
        time.sleep(2.05)
        price_response = requests.get(
            f'https://testnet.bitmex.com/api/v1/trade?symbol={value}&filter=%7B%22side%22%3A%22Sell%22%7D&count={count}&reverse=true'
        ).json()
        return (time.time() - start_time), price_response[0]['price'],

    def first_proizvod(self, mass, time):
        return (mass[-1] - mass[-2]) / (time[-1] - time[-2])

    def second_proizvod(self, mass, time):
        buf=((mass[-1]-mass[-2])/(time[-1]-time[-2])-(mass[-2]-mass[-3])/(time[-2]-time[-3]))/\
            (time[-1]-time[-3])
        return buf

    def dt(self, mas):
        return mas[-1] - mas[-2]

    def analysis(self):

        iteracia = 0
        Flag = False

        f = open(f'calculation_{self.value_pair}.txt', 'w')
        f.write(
            'итерация  цена                     dt                         первая производная     вторая производная \n'
        )
        f1 = open('analysis.txt', 'w')
        f1.write(
            'первая производная            вторая производная           доход в $     доход в процентах %        плечо      \n'
        )
        time, price = self.currancy_value()
        self.price_mas, self.time_mas = [price], [0]
        while True:
            if iteracia > 10:
                self.Flag_of_begining = True
            print(iteracia + 1)
            time, price = self.currancy_value()
            self.price_mas.append(price)

            self.time_mas.append(time + self.time_mas[-1])
            #print(self.price_mas,self.time_mas)
            if len(self.price_mas) > 1:
                try:
                    first_proizvod_mas
                except:
                    first_proizvod_mas = [
                        self.first_proizvod(self.price_mas, self.time_mas)
                    ]

                else:
                    first_proizvod_mas.append(
                        self.first_proizvod(self.price_mas, self.time_mas))
                    if abs(first_proizvod_mas[-1]) > 0:
                        print('первая производная = ', first_proizvod_mas[-1])
                    #print('dt',self.time_mas[-1]-self.time_mas[-2])

                    if len(first_proizvod_mas) > 1:

                        try:
                            second_proizvod_mas
                        except:
                            second_proizvod_mas = [
                                self.second_proizvod(self.price_mas,
                                                     self.time_mas)
                            ]

                        else:
                            second_proizvod_mas.append(
                                self.second_proizvod(self.price_mas,
                                                     self.time_mas))
                            if abs(first_proizvod_mas[-1]) > 0:
                                print('вторая производная = ',
                                      second_proizvod_mas[-1])


#            begining of analysis' calculatios with 1st and 2nd derivative

            if len(self.price_mas) > 5:
                if first_proizvod_mas[-1] > 0 and first_proizvod_mas[
                        -2] > 0 and first_proizvod_mas[-3] > 0:
                    if second_proizvod_mas[-1] > 0 and second_proizvod_mas[
                            -2] > 0:
                        print('!!!!!!!!!!!!')
                        winsound.MessageBeep()
                        winsound.MessageBeep()
                        purchase_price = self.price_mas[-1]
                        flag_purchase = True
            '''if Flag:
                if first_proizvod_mas[-1]<0:
                    profit_L=(self.price_mas[-1]-purchase_price)/purchase_price
                    f1.write(f'{first_proizvod_mas[-4]}        ----        -------     --------    {self.shoulder} \n')
                    f1.write(f'{first_proizvod_mas[-3]}        {second_proizvod_mas[-3]}        -------     --------    {self.shoulder} \n')
                    f1.write(f'{first_proizvod_mas[-2]}        {second_proizvod_mas[-2]}        -------     --------    {self.shoulder} \n')
                    f1.write(f'{first_proizvod_mas[-1]}        {second_proizvod_mas[-1]}        {(1+profit_L)*self.start_money}     {profit_L*100}    {self.shoulder} \n')
                    f.close()
                    f1.close()
                    winsound.MessageBeep()
                    winsound.MessageBeep()
                    winsound.MessageBeep()
                    exit()'''
            if iteracia > 2:
                f.write(
                    f'{iteracia}         {self.price_mas[-1]}                  {self.dt(self.time_mas)}          {first_proizvod_mas[-1]}                     {second_proizvod_mas[-1]} \n'
                )
            if iteracia == 500:
                f.close()
                exit()
            iteracia += 1

            if (iteracia % 500) == 0:
                print('очистка массивов')
                buf_1 = first_proizvod_mas[-10:]
                buf_2 = second_proizvod_mas[-10:]
                buf_p = self.price_mas[-10:]
                buf_t = self.time_mas[-10:]
                first_proizvod_mas = buf_1
                second_proizvod_mas = buf_2
                self.price_mas = buf_p
                self.time_mas = buf_t
예제 #15
0
    parsedURL = urllib.parse.urlparse(url)
    path = parsedURL.path
    if parsedURL.query:
        path = path + '?' + parsedURL.query
    # print("Computing HMAC: %s" % verb + path + str(nonce) + data)
    message = (verb + path + str(nonce) + data).encode('utf-8')
    print("Signing: %s" % str(message))

    signature = hmac.new(apiSecret.encode('utf-8'),
                         message,
                         digestmod=hashlib.sha256).hexdigest()
    print("Signature: %s" % signature)
    return signature


def test():
    expires = int(time.time()) + 5
    # See signature generation reference at https://www.bitmex.com/app/apiKeys
    signature = bitmex_signature(secret_key, VERB, ENDPOINT, expires)
    print(signature)
    # Initial connection - BitMEX sends a welcome message.
    ws = websocket.create_connection(BITMEX_URL + ENDPOINT)


#test()
ws = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1",
                     symbol="XBTUSD",
                     api_key=api_key,
                     api_secret=secret_key)
ws.get_ticker()
예제 #16
0
class Market_maker():
    def __init__(self, symbol):
        self.ctr = 0
        self.symbol = symbol
        #self.logger = self.setup_logger()

        # hoang: wbFfEOkZqut7OG8rueCPTmEsCsYHyqxakxlg1dNoZbz7EJ6w
        # hoang: ZJ7ZG0bDrem884wQkNnvv2PB

        api_key = "ZJ7ZG0bDrem884wQkNnvv2PB"  #"9FR7reF9F71NDZG_BDoMsfm9" # 8vXVw923QlDRoRtXSwvwbXlU
        api_secret = "wbFfEOkZqut7OG8rueCPTmEsCsYHyqxakxlg1dNoZbz7EJ6w"  #"TiXEEabXxJ_KX5ev_RoOnB-JVQqDdj4AAMJvRBXpPhtAKGVH" # nFZS4qiArohuyY_4J9oGBk49X2iL5LteAXCrHcHveF6j5Gwi

        # Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.
        self.ws = BitMEXWebsocket(endpoint="https://www.bitmex.com/api/v1",
                                  symbol=self.symbol,
                                  api_key=api_key,
                                  api_secret=api_secret)
        self.ws.get_instrument()

        #self.logger.info("Instrument data: %s" % self.ws.get_instrument())
        self.client = bitmex.bitmex(test=False,
                                    api_key=api_key,
                                    api_secret=api_secret)
        self.last_r = None
        self.last_spread = None
        #self.clean = False

        self.tick = []
        self.cur_volatility = None
        self.act_volatility = None
        self.streak = 0
        self.prev_len = 0
        self.cur_len = 0
        self.idle = 0
        self.first = True
        self.sleep_ctr = 0
        self.general_ctr = 0

        exchange = ccxt.bitmex()
        date_N_days_ago = (
            datetime.datetime.now() -
            datetime.timedelta(hours=2)).strftime("%Y-%m-%d %H:%M:%S")
        since = time.mktime(
            datetime.datetime.strptime(date_N_days_ago,
                                       "%Y-%m-%d %H:%M:%S").timetuple()) * 1000
        df = exchange.fetch_ohlcv('ETH/USD',
                                  timeframe='1m',
                                  since=since,
                                  limit=500)
        df = pd.DataFrame(df)
        df.columns = ["Timestamp", "Open", "High", "Low", "tick", "Volume"]

        self.df = pd.DataFrame({'tick': df.tick.values.tolist()})
        #print (df.tail())
        #print (self.df.tail())

        # always fetch df using ccxt
        # check number of pos: if len(pos) > 0 : self.first = False
        logging.info("App Initiated!")

    def restart(self):
        # api_key = "ZJ7ZG0bDrem884wQkNnvv2PB" #"9FR7reF9F71NDZG_BDoMsfm9" # 8vXVw923QlDRoRtXSwvwbXlU
        # api_secret = "wbFfEOkZqut7OG8rueCPTmEsCsYHyqxakxlg1dNoZbz7EJ6w" #"TiXEEabXxJ_KX5ev_RoOnB-JVQqDdj4AAMJvRBXpPhtAKGVH" # nFZS4qiArohuyY_4J9oGBk49X2iL5LteAXCrHcHveF6j5Gwi

        # # Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.
        # self.ws = BitMEXWebsocket(endpoint="https://www.bitmex.com/api/v1", symbol=self.symbol,
        #                      api_key=api_key, api_secret=api_secret)
        # self.ws.get_instrument()
        # self.client = bitmex.bitmex(test=False, api_key=api_key, api_secret=api_secret)
        print('Restart finished.')
        logging.info("Restarting the market maker...")
        self.clean()
        os.execv(sys.executable, [sys.executable] + sys.argv)

    def round_to(self, n, precision):
        correction = 0.5 if n >= 0 else -0.5
        return int(n / precision + correction) * precision

    def round_to_05(self, n):
        return self.round_to(n, 0.05)

    def test(self):
        print('Restarting')
        logging.info('Restarting')
        return self.restart()

    def run(self):
        threading.Timer(15.0, self.run).start()
        sys.stdout.write("---------------------\n")
        logging.info("---------------------\n")
        #sys.stdout.flush()
        # TODO 1: write check_file_change & add settings.

        #self.check_file_change()
        #sleep(settings.LOOP_INTERVAL)

        # This will restart on very short downtime, but if it's longer,
        # the MM will crash entirely as it is unable to connect to the WS on boot.
        if not self.check_connection():
            print('No connection detected! Restarting...')
            logging.error(
                "Realtime data connection unexpectedly closed, restarting.")
            self.restart()

            # TODO 2: sanity_check, print_status
        self.ctr += 1
        self.general_ctr += 1
        ticker = self.ws.get_ticker()
        self.test = False

        print('Mid: ', ticker['mid'])
        #logging.info('New Ticker: ', ticker['mid'])

        start_cond = (self.ctr == 1 and len(self.df) > 60)

        if self.ctr == 4:
            print('FULL MINUTE')
            logging.info('FULL MINUTE')
            self.ctr = 0
            #print ("Df length: ", len(self.df))
            #print(self.df)
            self.df = self.df.append(pd.DataFrame({'tick': [ticker['mid']]}),
                                     ignore_index=True)
            if len(self.df) > 60:
                # self.write = True
                self.df = self.df.iloc[-80:]
                self.df['ret'] = (self.df['tick'] - self.df['tick'].shift())**2
                self.df['vola'] = self.df['ret'].rolling(60).apply(np.mean)
                self.cur_volatility = self.df.iloc[-1].vola
                print("Volatility: ", self.cur_volatility)
                logging.info('Full minute -- Volatility: {}'.format(
                    self.cur_volatility))
            if self.first:
                print(self.df.tail(5))
                print(self.df.iloc[-1], self.df.iloc[-1].tick,
                      self.df.iloc[-2], self.df.iloc[-2].tick)
        try:
            pos = self.client.Position.Position_get().result(
            )[0][-1]['currentQty']
        except:
            pos = 0

        try:
            ord_list = self.client.Order.Order_getOrders(
                filter=json.dumps({"open": True})).result()[0]
            #print(ord_list)
            #print (len(ord_list))
        except Exception as e:
            ord_list = []
            logging.info('Error when getting OrderList: {}'.format(e))

        if self.test:
            print('TEST! RESTART TRIGGERING')
            logging.info('TEST! RESTART TRIGGERING')
            self.restart()

        if self.first == True and pos != 0:
            self.first = False
        if self.first == True and len(ord_list) != 0:
            self.first = False

        if (self.df.iloc[-1].tick
                == self.df.iloc[-2].tick) and (self.df.iloc[-3].tick
                                               == self.df.iloc[-2].tick):
            print('Repetition! RESTART TRIGGERING')
            logging.info('Repetition! RESTART TRIGGERING')
            self.restart()

        if self.general_ctr == 2880:
            print('RAN FOR 12 HRS! RESTART TRIGGERING')
            logging.info('RAN FOR 12 HRS! RESTART TRIGGERING')
            self.general_ctr = 0
            self.restart()

        self.cur_len = len(ord_list)
        if (self.cur_len
                == self.prev_len) and (self.cur_len > 0):  # could incur errors
            self.idle += 1
        elif (self.cur_len < self.prev_len):
            self.streak += 1
            self.idle = 0  #wont use idle for now
        else:
            self.idle = 0

        logging.info(
            'Subminute -- Mid price {}; Position Size: {}; OrderList: {}; OrderLength: {}'
            .format(ticker['mid'], pos, ord_list, len(ord_list)))

        if self.act_volatility != None:  #abrupt change in volatility
            cond1 = self.cur_volatility > self.act_volatility * 1.25
            cond2 = self.cur_volatility < self.act_volatility * .75
        else:
            cond1 = cond2 = False

        cond3 = (self.cur_volatility != None) and (
            self.first
        )  # no order placed before + enough data to calc volatility
        cond4 = (ord_list !=
                 None) and (ord_list != []) and (len(ord_list) < 2) and (
                     self.cur_len < self.prev_len
                 )  # 1 order just filled --> left 1 order on the other side
        #cond5 = (self.idle == 60) # if orders don't get filled for too long
        cond5 = False
        cond6 = (ord_list == []
                 and self.first == False)  # no orders after the first trade
        cond7 = (ord_list !=
                 None) and (ord_list != []) and (len(ord_list) < 2) and (
                     ord_list[0]['side'] == 'Buy') and (pos != 0) and (
                         pos > 0)  # 1 order left + on the same side of the pos
        cond8 = (ord_list !=
                 None) and (ord_list != []) and (len(ord_list) < 2) and (
                     ord_list[0]['side'] == 'Sell') and (pos != 0) and (
                         pos < 0)  # 1 order left + on the same side of the pos
        cond9 = (len(ord_list) >= 10)

        if self.streak == 3:
            logging.info('Sleep to prevent successive market orders.')
            cond4 = False
            self.sleep_ctr += 1

        logging.info(
            'assess conditions: {}, {}, {}, {}, {}, {}, {}, {}, {}'.format(
                cond1, cond2, cond3, cond4, cond5, cond6, cond7, cond8, cond9))
        if cond1 or cond2 or cond3 or cond4 or cond5 or cond6 or cond7 or cond8 or cond9:
            if cond3:
                logging.info('First Trade!')
                self.first = False
            if cond4 or cond1 or cond2 or cond7 or cond8 or cond9:
                logging.info('Revise')
                self.client.Order.Order_cancelAll().result()
            if cond5:
                logging.info('Idle')
                self.idle = 0
            r, spread = self.calc_res_price(ticker["mid"], pos,
                                            self.cur_volatility)
            print('Real mid: ', r)
            print('Spread: ', spread)
            buy_qty, sell_qty = self.get_qty(pos)
            self.post_orders(spread, r, buy_qty, sell_qty, pos)
            self.act_volatility = self.cur_volatility
            self.cur_len += bool(buy_qty) + bool(sell_qty)
            logging.info('Orders post: {}, {}, {}, {}'.format(
                r, spread, buy_qty, sell_qty))
        else:
            pass

        self.prev_len = self.cur_len
        """
        if self.write:
            self.df.to_csv()
        """

        # if self.ws.api_key:
        #     self.logger.info("Funds: %s" % self.ws.funds())
        #logger.info("Market Depth: %s" % self.ws.market_depth())
        #logger.info("Recent Trades: %s\n\n" % self.ws.recent_trades())

    def collect(self):
        threading.Timer(10.0, self.collect).start()
        self.ctr += 1
        ticker = self.ws.get_ticker()['mid']
        self.tick.append(ticker)
        print('ticker collected: ', ticker)
        if self.ctr == 360:
            df = pd.DataFrame({'tick': ticker})
            df.to_csv('collected.csv')
            print('Done!')

    def clean(self):
        print("CANCEL ALL ORDERS")
        logging.info('CANCEL ALL ORDERS')
        #self.clean = True
        return self.client.Order.Order_cancelAll().result()

    def calc_res_price(self, mid, qty, vola):
        #print (qty)
        VAR = vola
        r = mid - (qty * GAMMA * VAR * D) / MAX_POS
        spread = max(0.1, GAMMA * VAR * D + np.log(1 + GAMMA / K))
        return r, spread

    def post_orders(self, spread, mid, buy_qty, sell_qty, pos):
        getcontext().prec = 4
        if pos > 0:
            buy = {
                'orderQty':
                buy_qty,
                'price':
                self.round_to_05(
                    float(Decimal(mid) - Decimal(spread) / Decimal(2))),
                'side':
                'Buy',
                'symbol':
                self.symbol,
                'execInst':
                'ParticipateDoNotInitiate'
            }
            sell = {
                'orderQty':
                sell_qty,
                'price':
                self.round_to_05(
                    float(Decimal(mid) + Decimal(spread) / Decimal(2))),
                'side':
                'Sell',
                'symbol':
                self.symbol
            }
        elif pos < 0:
            buy = {
                'orderQty':
                buy_qty,
                'price':
                self.round_to_05(
                    float(Decimal(mid) - Decimal(spread) / Decimal(2))),
                'side':
                'Buy',
                'symbol':
                self.symbol
            }
            sell = {
                'orderQty':
                sell_qty,
                'price':
                self.round_to_05(
                    float(Decimal(mid) + Decimal(spread) / Decimal(2))),
                'side':
                'Sell',
                'symbol':
                self.symbol,
                'execInst':
                'ParticipateDoNotInitiate'
            }
        else:
            buy = {
                'orderQty':
                buy_qty,
                'price':
                self.round_to_05(
                    float(Decimal(mid) - Decimal(spread) / Decimal(2))),
                'side':
                'Buy',
                'symbol':
                self.symbol,
                'execInst':
                'ParticipateDoNotInitiate'
            }
            sell = {
                'orderQty':
                sell_qty,
                'price':
                self.round_to_05(
                    float(Decimal(mid) + Decimal(spread) / Decimal(2))),
                'side':
                'Sell',
                'symbol':
                self.symbol,
                'execInst':
                'ParticipateDoNotInitiate'
            }
        if buy_qty == 0:
            to_create = [sell]
        elif sell_qty == 0:
            to_create = [buy]
        else:
            to_create = [buy, sell]
        print('Buy: {}; Sell: {}'.format(buy['price'], sell['price']))
        logging.info('Buy: {}; Sell: {}'.format(buy['price'], sell['price']))
        self.client.Order.Order_newBulk(orders=json.dumps(to_create)).result()

    def get_qty(self, qty):
        buy_qty = THETA * np.exp(-ETA2 * qty) if qty < 0 else THETA * np.exp(
            -ETA * qty)
        sell_qty = THETA * np.exp(ETA2 * qty) if qty > 0 else THETA * np.exp(
            ETA * qty)
        return int(round(buy_qty)), int(round(sell_qty))

    def setup_logger(self):
        # Prints logger info to terminal
        logger = logging.getLogger()
        logger.setLevel(
            logging.INFO)  # Change this to DEBUG if you want a lot more info
        ch = logging.StreamHandler()
        # create formatter
        formatter = logging.Formatter(
            "%(asctime)s - %(name)s - %(levelname)s - %(message)s")
        # add formatter to ch
        ch.setFormatter(formatter)
        logger.addHandler(ch)
        return logger

    def check_connection(self):
        """Ensure the WS connections are still open."""
        print('STATUS: ', not self.ws.exited)
        logging.info('STATUS: ', not self.ws.exited)
        return not self.ws.exited

    def run_loop(self):
        while True:
            sys.stdout.write("-----\n")
            sys.stdout.flush()
            # TODO 1: write check_file_change & add settings.

            #self.check_file_change()
            #sleep(settings.LOOP_INTERVAL)

            # This will restart on very short downtime, but if it's longer,
            # the MM will crash entirely as it is unable to connect to the WS on boot.
            if not self.check_connection():
                print('No connection detected! Restarting...')
                logging.error(
                    "Realtime data connection unexpectedly closed, restarting."
                )
                self.restart()

            # TODO 2: sanity_check, print_status

            self.run()
예제 #17
0
print("Instrument: %s" % ws.get_instrument())

connection = pymysql.connect(
    unix_socket='/opt/local/var/run/mysql57/mysqld.sock',
    host=db_host,
    user=db_user,
    password=db_password,
    db=db,
    charset='latin1',
    cursorclass=pymysql.cursors.DictCursor)

current_minute = time.gmtime()[4]

while current_minute != 0:

    ticker = ws.get_ticker()
    print(strftime("%Y-%m-%d %H:%M:%S", gmtime()), ':::', ticker)

    l = ticker['last']
    b = ticker['buy']
    s = ticker['sell']
    m = ticker['mid']

    cnt = 0
    with connection.cursor() as cursor:
        # Create a new record
        # sql = "INSERT INTO `ticker` (`symbol`, `dt`, `l`, `b`, `s`, `m`) VALUES (%s, now(), %s, %s, %s, %s)"
        # cursor.execute(sql, (symbol,l,b,s,m))

        # connection is not autocommit by default. So you must commit to save your changes.
        # connection.commit()
예제 #18
0
파일: main.py 프로젝트: kz0/BITMEX
class MyRobot:
    lever = 5
    contract_name = 'XBTZ18'
    new_position_thd = 350
    re_position_thd = 30
    price_table = {
        '8': [4, 10, 21, 43],
        '12': [6, 15, 31, 64],
        '16': [8, 20, 42, 85],
        '24': [12, 30, 63, 127],
        '32': [16, 40, 84, 170]
    }
    open_price_list = 'open_price_list'
    base_price_list = 'base_price_list'
    base_price = 'base_price'
    filled_order_set = 'filled_order_set'

    unit_amount_list = 'unit_amount_list'

    def __init__(self):
        self.logger = setup_logger()
        test = False
        api_key = os.getenv('API_KEY')
        api_secret = os.getenv('API_SECRET')
        test_url = 'https://testnet.bitmex.com/api/v1'
        product_url = 'https://www.bitmex.com/api/v1'

        self.logger.info('APIKEY: %s' % api_key)
        if test:
            url = test_url
        else:
            url = product_url
        self.cli = bitmex(test=test, api_key=api_key, api_secret=api_secret)
        self.ws = BitMEXWebsocket(endpoint=url,
                                  symbols=["XBTUSD", self.contract_name],
                                  api_key=api_key,
                                  api_secret=api_secret)

        # init redis client
        self.redis_cli = redis.Redis(host='35.230.143.112',
                                     password='******',
                                     port=6379,
                                     decode_responses=True)

        self.last_sms_time = 0

    """
    2018/6/14 更新
    每次选取最邻近的订单
    
    2018/7/23 更新
    解决当价格变动很大,订单没有按照顺序成交,导致重复订单
    """

    def get_filled_order(self,
                         last_trans_qty=0,
                         last_trans_side='',
                         last_trans_type=''):
        recent_order = None
        for order in self.ws.open_orders():
            if order['ordStatus'] == 'Filled' and (
                    not self.redis_cli.sismember('filled_order_set',
                                                 order['orderID'])):
                # 目前仅考虑买单
                if last_trans_side == 'Sell' and order['ordType'] == 'Limit':
                    if order[
                            'side'] == 'Buy' and last_trans_type == 'Limit' and order[
                                'cumQty'] != last_trans_qty:
                        continue
                elif last_trans_side == 'Buy' and order['ordType'] == 'Limit':
                    if order[
                            'side'] == 'Buy' and last_trans_type == 'Limit' and order[
                                'cumQty'] != last_trans_qty * 2:
                        continue
                if not recent_order:
                    recent_order = order
                else:
                    if order['timestamp'] > recent_order['timestamp']:
                        recent_order = order
        return recent_order

    # 2018/7/26 添加
    def get_unfilled_order(self):
        unfilled_orders = []
        for o in self.ws.open_orders():
            if o['ordStatus'] == 'New' or o['ordStatus'] == 'PartiallyFilled':
                unfilled_orders.append(o)
        return unfilled_orders

    """
    2018/7/23 更新
    增加异常多次请求
    
    2018/7/25
    修改过滤条件, 增加PartiallyFilled
    
    2018/7/26
    重写函数,并命名为get_unfilled_order
    """

    def get_delegated_orders(self):
        times = 0
        result = []
        while times < 200:
            self.logger.info('第%s次获取未成交委托' % (times + 1))
            try:
                orders = self.cli.Order.Order_getOrders(reverse=True).result()
            except Exception as e:
                self.logger.error('get orders error: %s' % e)
                time.sleep(1)
            else:
                for o in orders[0]:
                    if o['ordStatus'] == 'New' or o[
                            'ordStatus'] == 'PartiallyFilled':
                        result.append(o)
                break
            times += 1

        return result

    def get_ticker(self, symbol):
        # tickers = self.ws.get_ticker()
        while True:
            tickers = self.ws.get_ticker()
            if len(tickers) > 0:
                for ticker in tickers[::-1]:
                    if ticker['symbol'] == symbol:
                        return ticker
            time.sleep(0.5)

    def send_order(self, symbol, side, qty, price, ordtype='Limit'):
        times = 0
        result = 0
        for o in self.get_delegated_orders():
            if o['side'] == side and o['price'] == price:
                self.logger.info('委托已存在, orderid: %s' % o['orderID'])
                return 1
        while times < 500:
            self.logger.info('第%s次发起订单委托' % (times + 1))
            if ordtype == 'Limit':
                try:
                    order = self.cli.Order.Order_new(symbol=symbol,
                                                     side=side,
                                                     orderQty=qty,
                                                     price=price,
                                                     ordType=ordtype).result()
                except Exception as e:
                    self.logger.error('订单error: %s,1秒后重试' % e)
                    time.sleep(1)
                else:
                    self.logger.info('委托成功')
                    result = order[0]['orderID']
                    break
            else:
                try:
                    order = self.cli.Order.Order_new(symbol=symbol,
                                                     side=side,
                                                     orderQty=qty,
                                                     ordType=ordtype).result()
                except Exception as e:
                    self.logger.error('订单error: %s,1秒后重试' % e)
                    time.sleep(1)
                else:
                    result = order[0]['orderID']
                    break
            times += 1
        return result

    def cancel_order(self, orderid):
        times = 0
        result = False
        while times < 500:
            self.logger.info('第%s次发起撤销委托, orderId: %s' % (times + 1, orderid))
            try:
                self.cli.Order.Order_cancel(orderID=orderid).result()
            except Exception as e:
                self.logger.error('撤销错误: %s, 1秒后重试' % e)
                time.sleep(1)
            else:
                result = True
                break
            times += 1
        return result

    def amend_order(self, orderid, qty):
        times = 0
        while times < 500:
            self.logger.info('第%s次修改订单信息, orderID: %s' % (times + 1, orderid))
            try:
                self.cli.Order.Order_amend(orderID=orderid,
                                           orderQty=qty).result()
            except Exception as e:
                logging.error('修改订单错误: %s' % e)
                time.sleep(1)
            else:
                self.logger.info('修改成功')
                break
            times += 1

    def sms_notify(self, msg):
        if int(time.time() - self.last_sms_time > 900):
            self.logger.info('短信通知: %s' % msg)
            url = 'http://221.228.17.88:8080/sendmsg/send'
            params = {'phonenum': '18118999630', 'msg': msg}
            # requests.get(url, params=params)
            self.last_sms_time = int(time.time())

    """
    2018/6/28
    修改使支持len>3的情形
    """

    def get_current_index(self, price):
        key = 'open_price_list'
        index = 0
        for i in range(10):
            if i < self.redis_cli.llen(key) and price < float(
                    self.redis_cli.lindex(key, i)):
                index = i
        return index

    def run(self):
        self.logger.info('start')
        last_trans_qty = 0
        last_trans_side = ''
        last_trans_type = ''
        last_unit_amount = 0
        while True:
            filled_order = self.get_filled_order(last_trans_qty,
                                                 last_trans_side,
                                                 last_trans_type)
            if filled_order:
                cum_qty = filled_order['cumQty']
                order_px = filled_order['price']
                avg_px = adjust_price(filled_order['avgPx'])
                side = filled_order['side']
                ord_type = filled_order['ordType']
                self.logger.info(
                    '--------------------------------------------------------------------------------'
                )
                self.logger.info(
                    'side: %s, type: %s, cum_qty: %s, order_px: %s, avg_px: %s, orderID: %s'
                    % (side, ord_type, cum_qty, order_px, avg_px,
                       filled_order['orderID']))
                index = self.get_current_index(order_px)
                price_base = 8
                if self.redis_cli.llen('open_price_list') > 0:
                    price_base = int(
                        self.redis_cli.lindex('base_price_list', index))
                    self.logger.info('index: %s, price_base: %s' %
                                     (index, price_base))
                price_table = self.price_table[str(price_base)]

                if ord_type == 'Market':
                    if side == 'Buy':
                        self.logger.info('建仓  仓位: %s, 价格: %a' %
                                         (cum_qty, avg_px))
                        self.logger.info('rpush')
                        self.redis_cli.rpush('open_price_list', avg_px)
                        self.redis_cli.rpush('unit_amount_list', cum_qty)
                        if self.redis_cli.get('base_price'):
                            self.redis_cli.rpush(
                                'base_price_list',
                                self.redis_cli.get('base_price'))
                        else:
                            self.logger.info('base_price未赋值')
                            time.sleep(300)
                        price_base = float(self.redis_cli.get('base_price'))
                        self.logger.info('买入: %s,价格: %s' %
                                         (cum_qty, avg_px - price_base))
                        orderid = self.send_order(self.contract_name, 'Buy',
                                                  cum_qty, avg_px - price_base)
                        if orderid == 0:
                            self.logger.info('委托失败,程序终止')
                            break
                    else:
                        self.logger.info('平仓  仓位: %s, 价格: %s' %
                                         (cum_qty, avg_px))
                        self.logger.info('市价开启新的仓位  仓位: %s' % last_unit_amount)
                        orderid = self.send_order(self.contract_name, 'Buy',
                                                  last_unit_amount, 0,
                                                  'Market')
                        if orderid == 0:
                            self.logger.info('委托失败,程序终止')
                            break

                else:
                    if side == 'Buy':
                        if cum_qty % 16 == 0:
                            self.logger.info(
                                '卖出: %s,价格: %s' %
                                (cum_qty * 2, order_px + price_table[3]))
                            orderid = self.send_order(
                                self.contract_name, 'Sell', cum_qty * 2,
                                order_px + price_table[3])
                            if orderid == 0:
                                self.logger.info('委托失败,程序终止')
                                break
                        elif cum_qty % 2 == 0:
                            if cum_qty % 8 == 0:
                                price_buy = order_px - price_base * 8
                                price_sell = order_px + price_table[2]
                            elif cum_qty % 4 == 0:
                                price_buy = order_px - price_base * 4
                                price_sell = order_px + price_table[1]
                            else:
                                price_buy = order_px - price_base * 2
                                price_sell = order_px + price_table[0]
                            self.logger.info('卖出: %s,价格: %s' %
                                             (cum_qty, price_sell))
                            orderid = self.send_order(self.contract_name,
                                                      'Sell', cum_qty,
                                                      price_sell)
                            if orderid == 0:
                                self.logger.info('委托失败,程序终止')
                                break

                            self.logger.info('买入: %s,价格: %s' %
                                             (cum_qty * 2, price_buy))
                            orderid = self.send_order(self.contract_name,
                                                      'Buy', cum_qty * 2,
                                                      price_buy)
                            if orderid == 0:
                                self.logger.info('委托失败,程序终止')
                                break
                    else:
                        if cum_qty % 32 == 0:
                            self.logger.info('撤销多余Buy委托')
                            open_price = float(
                                self.redis_cli.lindex('open_price_list',
                                                      index))
                            unfilled_orders = self.get_delegated_orders()
                            if open_price < order_px:
                                self.logger.info('open price: %s' % open_price)
                                for o in unfilled_orders:
                                    if o['side'] == 'Buy' and o[
                                            'price'] < open_price:
                                        self.logger.info(
                                            'cancel order orderID: %s, price: %s'
                                            % (o['orderID'], o['price']))
                                        self.cancel_order(o['orderID'])
                                self.logger.info('rpop')
                                self.redis_cli.rpop('open_price_list')
                                self.redis_cli.rpop('base_price_list')
                                self.redis_cli.rpop('unit_amount_list')

                                open_price = float(
                                    self.redis_cli.lindex(
                                        'open_price_list', index))
                            else:
                                self.logger.info('没有多余的Buy委托')

                            self.logger.info('撤销多余Sell委托')
                            self.logger.info('open price: %s' % open_price)
                            for o in unfilled_orders:
                                if o['side'] == 'Sell' and order_px < o[
                                        'price'] < open_price:
                                    self.logger.info(
                                        'cancel order orderID: %s, price: %s' %
                                        (o['orderID'], o['price']))
                                    self.cancel_order(o['orderID'])
                            #
                            self.logger.info('rpop')
                            self.redis_cli.rpop('open_price_list')
                            self.redis_cli.rpop('base_price_list')
                            self.redis_cli.rpop('unit_amount_list')
                            self.logger.info('已全部平仓,待重建仓位')
                        elif cum_qty % 2 == 0:
                            if cum_qty % 16 == 0:
                                buy_price = order_px - price_table[3]
                            elif cum_qty % 8 == 0:
                                buy_price = order_px - price_table[2]
                            elif cum_qty % 4 == 0:
                                buy_price = order_px - price_table[1]
                            else:
                                buy_price = order_px - price_table[0]
                            self.logger.info('买入: %s,价格: %s' %
                                             (cum_qty, buy_price))
                            orderid = self.send_order(self.contract_name,
                                                      'Buy', cum_qty,
                                                      buy_price)
                            if orderid == 0:
                                self.logger.info('委托失败,程序终止')
                                break
                #
                self.redis_cli.sadd('filled_order_set',
                                    filled_order['orderID'])
                last_trans_side = side
                last_trans_qty = cum_qty
                last_trans_type = ord_type

            if self.redis_cli.llen('open_price_list') > 0:
                ticker = self.get_ticker(self.contract_name)
                bid_price = ticker['bidPrice']
                last_open_price = float(
                    self.redis_cli.lindex('open_price_list', -1))
                unit_amount = int(self.redis_cli.lindex(
                    'unit_amount_list', -1))

                if bid_price - last_open_price < -1 * self.new_position_thd:
                    self.sms_notify(
                        '开启新的仓位 bid_price: %s, last_open_price: %s' %
                        (bid_price, self.redis_cli.lindex(
                            'open_price_list', -1)))
                #
                if bid_price - last_open_price > self.re_position_thd:
                    min_sell_price = 100000
                    for o in self.get_delegated_orders():
                        if o['side'] == 'Sell' and o['price'] < min_sell_price:
                            min_sell_price = o['price']
                    if min_sell_price - bid_price > 100:
                        self.logger.info('rpop')
                        open_price = float(
                            self.redis_cli.rpop('open_price_list'))
                        self.redis_cli.rpop('base_price_list')
                        self.redis_cli.rpop('unit_amount_list')
                        self.logger.info('撤销多余委托')
                        # PartiallyFilled 需要特别处理
                        unfilled_amount = 0
                        for o in self.get_delegated_orders():
                            if o['price'] < open_price and o['side'] == 'Buy':
                                if o['ordStatus'] == 'PartiallyFilled':
                                    self.logger.info('已部分成交: %s' % o['cumQty'])
                                    unfilled_amount += o['cumQty']

                                self.logger.info(
                                    'cancel order, orderID: %s, price: %s' %
                                    (o['orderID'], o['price']))
                                self.cancel_order(o['orderID'])
                        # self.sms_notify('重建仓位, bid_price: %s, last_open_price: %s' % (
                        #     bid_price, self.redis_cli.lindex('open_price_list', -1)))
                        orderid = self.send_order(
                            self.contract_name, 'Sell',
                            unit_amount + unfilled_amount, 0, 'Market')
                        if orderid == 0:
                            self.logger.info('委托失败,程序终止')
                            break
                        last_unit_amount = unit_amount
            time.sleep(0.2)