def start(thread = False):
    channels = [
        InstrumentChannels2.tradeBin5m,
    ]

    print("load trade history")
    res = client.Trade.Trade_getBucketed(symbol='XBTUSD', binSize="5m", reverse=True, count=750).result()
    add_bins("tradeBin{}".format("5m"), res[0])

    XBTUSD = Instrument(symbol='XBTUSD', channels=channels, should_auth=False)
    XBTUSD.on('action', on_message)
    #wst = None

    def run_loop(c):
        print("Run loop")
        while True:
            try:
                XBTUSD.run_forever()
            except Exception as e:
                print(e)
                sleep(1)
                pass

    if thread:
        print("Loop with thread")
        wst = threading.Thread(target=lambda: run_loop(XBTUSD.run_forever))
        wst.daemon = True
        wst.start()
    else:
        run_loop(None)
Exemple #2
0
def test_on_partial_action_instrument_data(mocker):
    init_mock = mocker.patch('bitmex_websocket.Instrument.init')

    instrument = Instrument()
    partial_message = instrument_data['partial']

    instrument.on_action(partial_message)

    assert instrument.data['instrument']
Exemple #3
0
def test_on_partial_orderBookL2_action_data(mocker):
    init_mock = mocker.patch('bitmex_websocket.Instrument.init')
    instrument = Instrument()

    message = orderBookL2_data['partial']

    instrument.on_action(message)

    assert instrument.data['orderBookL2']
Exemple #4
0
    def test_does_not_raise_exception_when_subscribing_secure_channel(
            self, mocker):
        header_mock = mocker.patch(
            'bitmex_websocket._bitmex_websocket.BitMEXWebsocket.header')
        header_mock.return_value = []

        channels = [Channels.connected, SecureChannels.margin]

        instrument = Instrument(channels=channels, should_auth=True)
        instrument.emit('open')

        assert channels == instrument.channels
    def startRun(self, settingidc):
        if (self.isRun):
            return
        self.isRun = True
        print('开始运行', settingidc)

        # 下限价格
        self.lowcontrolPriceline = float(settingidc["low"])
        print("self.lowcontrolPriceline", self.lowcontrolPriceline)
        # 上限价格
        self.highcontrolPriceline = float(settingidc["high"])
        print("self.highcontrolPriceline", self.highcontrolPriceline)
        # 赚了多少点就卖
        self.targetProfit = float(settingidc["targetProfit"])
        print("self.targetProfit", self.targetProfit)
        # 每次加仓的价格间隔
        self.init_jiacanggap = float(settingidc["priceGap"])
        print("self.init_jiacanggap", self.init_jiacanggap)
        # 初始仓位
        self.initorderPos = float(settingidc["initPos"])
        print("self.initorderPos", self.initorderPos)
        API_KEY = settingidc["API_KEY"]
        print("API_KEY", API_KEY)
        API_SECRET = settingidc["API_SECRET"]
        print("API_SECRET", API_SECRET)
        print("1")
        self.n = 0
        self.retryposchangetimes = 0
        self.isInOrder = False
        self.isPosChange = False
        self.cengshu = 0
        websocket.enableTrace(True)
        print("2")
        self.XBTH17 = Instrument(
            symbol='XBTUSD',
            # subscribes to all channels by default, here we
            # limit to just these two
            channels=['margin', 'instrument'],
            # you must set your environment variables to authenticate
            # see .env.example
            shouldAuth=True)
        print("3")
        self.bc = bitmexclient(API_KEY, API_SECRET)
        print("4")
        pos = self.bc.getpos()
        print("pos = ", pos)
        self.prepos = pos
        orderBook10 = self.XBTH17.get_table('instrument')
        self.XBTH17.on('action', self.onMessage)
Exemple #6
0
    def test_raises_exception_if_secure_channels_are_specified_without_auth(
            self):
        with pytest.raises(SubscribeToSecureChannelException):
            channels = [Channels.connected, SecureChannels.margin]

            instrument = Instrument(channels=channels)

            assert channels == instrument.channels
Exemple #7
0
    def __init__(self, num_of_decimals=1, **config):
        base.InLoopPollText.__init__(self, "sample text", **config)
        self.update_interval = 1000000
        self.exception = None

        self.num_of_decimals = num_of_decimals
        self.direction_text = "-"
        self.candles = []
        self.message_received = False
        channels = [
            InstrumentChannels.tradeBin1m,
            InstrumentChannels.trade,
        ]
        self.XBTUSD = Instrument(symbol='XBTUSD', channels=channels)
        self.XBTUSD.on('action', self.on_message)
        websocket.enableTrace(True)

        threading.Thread(target=self.start).start()
Exemple #8
0
    def test_public_and_secure_channels_are_in_channels_list(self, mocker):
        header_mock = mocker.patch(
            'bitmex_websocket._bitmex_websocket.BitMEXWebsocket.header')
        header_mock.return_value = []

        channels = [Channels.connected, SecureChannels.margin]
        instrument = Instrument(should_auth=True, channels=channels)

        assert channels == instrument.channels
Exemple #9
0
    def test_subscribe_to_public_channels(self, mocker):
        header_mock = mocker.patch(
            'bitmex_websocket._bitmex_websocket.BitMEXWebsocket.header')
        header_mock.return_value = []

        subscribe_mock: MagicMock = mocker.patch(
            'bitmex_websocket._bitmex_websocket.BitMEXWebsocket.subscribe')

        channels = [
            Channels.connected, SecureChannels.margin,
            SecureInstrumentChannels.order
        ]

        instrument = Instrument(channels=channels, should_auth=True)

        instrument.subscribe_channels()

        assert channels == instrument.channels

        subscribe_mock.assert_has_calls(
            [mock.call('margin:XBTUSD'),
             mock.call('order:XBTUSD')])
Exemple #10
0
def test_on_update_action_instrument_data(mocker):
    init_mock = mocker.patch('bitmex_websocket.Instrument.init')
    partial_message = instrument_data['partial']
    update_message = instrument_data['update']

    instrument = Instrument()

    instrument.on_action(partial_message)
    assert instrument.data['instrument']

    instrument.on_action(update_message)

    updated_instrument_table = instrument.get_table('instrument')
    assert updated_instrument_table['impactAskPrice'] \
        == update_message['data'][0]['impactAskPrice']
Exemple #11
0
def test_average_latency(mocker):
    """
    The BitMEXWebsocket emits 'latency' events every time a 'ping'
    comes in. This allows for a calculation for message latency.

    Bitmex websocket uses Primus websocket lib which uses the
    following heartbeat scheme:

              client will disconnect
                if not recv within
                  `pingTimeout`

             primus::pong::{timestamp}
            +----------------------+
            |                      |
        +---v----+            +---------+
        | server |            |  client |
        +--------+            +----^----+
            |                      |
            +----------------------+
             primus::ping::{timestamp}

              sent at `pingInterval`
              server will disconnect
              if no response since
                   last ping
    """
    init_mock = mocker.patch('bitmex_websocket.Instrument.init')

    instrument = Instrument(shouldAuth=True)

    latency_handler = mocker.stub()
    instrument.on('latency', latency_handler)
    # some time elapses and the ping message is received
    instrument.on_latency(100)
    latency_handler.assert_called_once()
    instrument.get_latency()
Exemple #12
0
def test_on_orderBookL2_action_data(mocker):
    """
    Ensure orderBookL2 is updated on delete, insert and update actions.
    """
    init_mock = mocker.patch('bitmex_websocket.Instrument.init')
    instrument = Instrument()

    # Recieve partial action message
    partial_action_message = orderBookL2_data['partial']
    partial_data = partial_action_message['data']
    instrument.on_action(partial_action_message)
    table = 'orderBookL2'
    for partial_level in partial_data:
        level = next(level for level in instrument.get_table(table)
                     if level['id'] == partial_level['id'])
        assert level

    # Receive delete action message
    delete_action_message = orderBookL2_data['delete']
    delete_level_id = delete_action_message['data'][0]['id']

    instrument.on_action(delete_action_message)
    delete_level = next((level for level in instrument.get_table(table)
                         if level['id'] == delete_level_id), None)
    assert not delete_level

    # Receive insert action message
    insert_action_message = orderBookL2_data['insert']
    instrument.on_action(insert_action_message)
    insert_data = insert_action_message['data']

    for insert_level in insert_data:
        level = next(level for level in instrument.get_table(table)
                     if level['id'] == insert_level['id'])
        assert level

    # Receive update action message
    update_action_message = orderBookL2_data['update']
    update_data = update_action_message['data']
    level_update = update_data[0]
    instrument.on_action(update_action_message)
    updated_level = next(level for level in instrument.get_table(table)
                         if level['id'] == level_update['id'])

    assert updated_level['size'] == level_update['size']
class BitmexWS:
    def handleSupportAndPressurePrice(self, lastprice):
        if lastprice < self.lowcontrolPriceline:
            if self.bc.pos > 0 and self.cengshu >= 4:
                # 关键点位上,持仓逆向,且层数过高,平仓避避风头
                printlog("关键点位上,持仓逆向,且层数过高,平仓避避风头 self.bc.pos = " +
                         str(self.bc.pos) + " self.cengshu = " +
                         str(self.cengshu))
                self.orderClose()
                return True
        elif lastprice > self.highcontrolPriceline:
            if self.bc.pos < 0 and self.cengshu >= 4:
                printlog("关键点位上,持仓逆向,且层数过高,平仓避避风头 self.bc.pos = " +
                         str(self.bc.pos) + " self.cengshu = " +
                         str(self.cengshu))
                self.orderClose()
                return True

    def handlehaveLong(self, gap):
        # 大于止盈点数,平仓
        if gap > self.targetProfit:
            printlog("持有多仓,超过盈利点数,平仓:" + str(gap))
            self.orderClose()
            # 处理多单亏损
        else:
            # 如果亏损超过初始设定,则加多仓
            if gap < -self.init_jiacanggap:
                printlog("持有多仓,亏损超过设定点数,加仓: " + str(gap))
                self.order()
            else:
                pass
                # print("持有多仓,不触发平仓和加仓 gap = "+str(gap))

    def handlehaveShort(self, gap):
        if gap < -self.targetProfit:
            printlog("持有空仓,超过盈利点数,平仓:" + str(gap))
            self.orderClose()
            # 处理空单亏损
        else:
            # 价格上升到空仓开仓价格超过初始设定,则加空仓
            if gap > self.init_jiacanggap:
                printlog("持有空仓,亏损超过设定点数,加仓" + str(gap))
                self.order()
            else:
                pass
                # print("持有空仓,不触发平仓和加仓 gap = " + str(gap))

    def onMessage(self, message):
        a1 = message["data"]
        b = 'lastPrice' in a1[0]
        c = 'timestamp' in a1[0]
        # 过滤 websocket 信息,只需要最新价格
        if b and c:
            lastprice = float(a1[0]['lastPrice'])
            timestamp = a1[0]['timestamp']
            # 同步状态
            # sendToAll({
            #     "lastprice": lastprice
            # })
            # 如果存在仓位,gap就是当前仓位的盈利或者亏损的点数
            gap = lastprice - self.bc.avgPrice
            # 每十次websocket返回信息,就打印一次当前的状态信息
            if self.n % 10 == 0:
                printlog("lastprice = " + str(lastprice) + "self.bc.pos:" +
                         str(self.prepos) + " gap = " + str(gap) +
                         " self.init_zhiying = " + str(self.targetProfit) +
                         " self.cengshu = " + str(self.cengshu))
            self.n = self.n + 1

            # 如果仓位变化了,那么一直请求获得最新的仓位,如果仓位跟本地的对比,有变化了,才继续执行
            isshouldgo = self.isAfterOrderPosChange()
            if isshouldgo == False:
                return

            # 处理价格到了设定好的压力位,支撑位,平仓
            if self.handleSupportAndPressurePrice(lastprice) == True:
                return

            if self.prepos == 0:
                printlog("无仓位立刻开仓")
                self.order()
            else:
                # 为了处理没有仓位,gap会等于当前价格的时候
                if gap > 1000:
                    return
                # 当前持有多仓
                if self.prepos > 0:
                    self.handlehaveLong(gap)
                # 当前持有空仓
                elif self.prepos < 0:
                    self.handlehaveShort(gap)

    # 平仓
    def orderClose(self):
        self.isInOrder = True
        self.bc.orderClose()
        self.cengshu = 0
        self.mypos = 0
        self.init_jiacanggap = 10
        self.isPosChange = True

    # 下单

    def order(self):
        self.isInOrder = True
        printlog("self.cengshu = " + str(self.cengshu))
        if self.prepos == 0:
            self.bc.orderauto(1)
        else:
            self.bc.orderauto(abs(self.prepos) * 2)
        self.cengshu = self.cengshu + 1
        self.isPosChange = True

    def isAfterOrderPosChange(self):
        # printlog(" isAfterOrderPosChange 仓位改变,等待"+str(self.isPosChange)+"self.prepos = "+str(self.prepos))
        if self.isPosChange == True:
            p = self.bc.getpos()
            if self.prepos == p:
                self.retryposchangetimes = self.retryposchangetimes + 1
                if self.retryposchangetimes >= 10:
                    self.retryposchangetimes = 0
                    self.isPosChange = False
                    return True
                printlog(" 仓位改变,等待")
                return False
            else:
                printlog(" 仓位改变完毕")
                self.prepos = p
                self.retryposchangetimes = 0
                self.isPosChange = False
                return True
        else:
            return True

    def __init__(self):
        self.isRun = False

    def stopRun(sef):
        print('...')

    def startRun(self, settingidc):
        if (self.isRun):
            return
        self.isRun = True
        print('开始运行', settingidc)

        # 下限价格
        self.lowcontrolPriceline = float(settingidc["low"])
        print("self.lowcontrolPriceline", self.lowcontrolPriceline)
        # 上限价格
        self.highcontrolPriceline = float(settingidc["high"])
        print("self.highcontrolPriceline", self.highcontrolPriceline)
        # 赚了多少点就卖
        self.targetProfit = float(settingidc["targetProfit"])
        print("self.targetProfit", self.targetProfit)
        # 每次加仓的价格间隔
        self.init_jiacanggap = float(settingidc["priceGap"])
        print("self.init_jiacanggap", self.init_jiacanggap)
        # 初始仓位
        self.initorderPos = float(settingidc["initPos"])
        print("self.initorderPos", self.initorderPos)
        API_KEY = settingidc["API_KEY"]
        print("API_KEY", API_KEY)
        API_SECRET = settingidc["API_SECRET"]
        print("API_SECRET", API_SECRET)
        print("1")
        self.n = 0
        self.retryposchangetimes = 0
        self.isInOrder = False
        self.isPosChange = False
        self.cengshu = 0
        websocket.enableTrace(True)
        print("2")
        self.XBTH17 = Instrument(
            symbol='XBTUSD',
            # subscribes to all channels by default, here we
            # limit to just these two
            channels=['margin', 'instrument'],
            # you must set your environment variables to authenticate
            # see .env.example
            shouldAuth=True)
        print("3")
        self.bc = bitmexclient(API_KEY, API_SECRET)
        print("4")
        pos = self.bc.getpos()
        print("pos = ", pos)
        self.prepos = pos
        orderBook10 = self.XBTH17.get_table('instrument')
        self.XBTH17.on('action', self.onMessage)
Exemple #14
0
    def test_only_public_channels(self):
        instrument = Instrument(channels=[Channels.connected])

        assert [Channels.connected] == instrument.channels
Exemple #15
0
 def test_raises_exception_no_channel_subscribed(self):
     with pytest.raises(SubscribeToAtLeastOneChannelException):
         Instrument()
Exemple #16
0
class BitmexWidget(base.InLoopPollText):

    def get_average(self, series):
        sum = 0
        for i in series:
            sum += i
        return sum / len(series)

    def get_stdev(self, series):
        sum = 0
        mean = self.get_average(series)
        for i in series:
            sum += (i - mean) * (i - mean)
        return math.sqrt(1 / len(series) * sum)

    def on_message(self, message):
        self.message_received = True
        msg_type = -1
        try:
            if message['table'] == 'tradeBin1m' and message['action'] == 'partial':
                return
            elif message['table'] == "tradeBin1m":
                msg_type = 1
            elif message['table'] == "trade":
                msg_type = 2
        except:
            msg_type = -1

        if msg_type == 1:
            del self.candles[0]
            del self.candles[-1]
            self.candles.append([0, message['data'][0]['open'], message['data'][0]['high'], message['data'][0]['low'],
                                 message['data'][0]['close'], message['data'][0]['volume']])
            self.candles.append([0, message['data'][0]['open'], message['data'][0]['high'], message['data'][0]['low'],
                                 message['data'][0]['close'], message['data'][0]['volume']])
        elif msg_type == 2:
            try:
                current_price = message['data'][0]['price']
            except:
                current_price = -1
            if current_price > self.candles[-1][4]:
                self.direction_text = "▲"
            elif current_price < self.candles[-1][4]:
                self.direction_text = "▼"
            else:
                return
            self.candles[-1][4] = current_price
            series = [x[4] for x in self.candles]
            mean = self.get_average(series)
            stdev2 = self.get_stdev(series) * 2
            if current_price > mean + stdev2:
                self.background = "#859900"
            elif current_price < mean - stdev2:
                self.background = "#DC322F"
            else:
                self.background = '#073642'

            self.tick()

    def timer(self):
        while True:
            time.sleep(70)
            if self.message_received:
                self.message_received = False
            else:
                self.close()
                self.direction_text = "-"
                self.candles = None
                self.start()
                break

    def start(self):
        self.exception = None
        threading.Thread(target=self.timer).start()
        try:
            self.candles = ccxt.bitmex().fetchOHLCV("BTC/USD", '1m', (calendar.timegm(time.gmtime()) - 19 * 60) * 1000, 19)
            self.XBTUSD.run_forever()
        except Exception as e:
            self.exception = e
            file = open('/home/leon/scripts/bitmexWidget.log', 'a')
            file.write(str(self.exception))
            file.close()
            self.tick()

    def close(self):
        self.XBTUSD.close()
        self.exception = ''
        self.tick()

    def __init__(self, num_of_decimals=1, **config):
        base.InLoopPollText.__init__(self, "sample text", **config)
        self.update_interval = 1000000
        self.exception = None

        self.num_of_decimals = num_of_decimals
        self.direction_text = "-"
        self.candles = []
        self.message_received = False
        channels = [
            InstrumentChannels.tradeBin1m,
            InstrumentChannels.trade,
        ]
        self.XBTUSD = Instrument(symbol='XBTUSD', channels=channels)
        self.XBTUSD.on('action', self.on_message)
        websocket.enableTrace(True)

        threading.Thread(target=self.start).start()

    def poll(self):
        if self.exception is not None:
            return str(self.exception)
        if self.candles and self.candles[-1] and self.candles[-1][4]:
            price = self.candles[-1][4]
        else:
            price = 0
        return self.direction_text + ' ' + f"{price:.{self.num_of_decimals}f}"
Exemple #17
0
            #size = data[i]['size']
            side = data[i]['side']
            print([price,side])
        '''


while True:
    try:
        #time.sleep(10)
        clientBMX = bitmex.bitmex(
            test=False,
            api_key='PzhjOv7eIAKsjSLhmtz8Bx68',
            api_secret='Dy3ZWFOrG97ddefrx_9FVQMVGYow0DfpzhDXk7OcwsvRGZk3')

        #clientBMX = bitmex.bitmex(test=True, api_key='Lqv0J_ddAK0zog_yv0goLMG8', api_secret='eLcXefzEcDQNyk9Hooui92ZLNhYIXBKsV9xVLqv8TGeNoAr2')

        print('Initialize........')
        websocket.enableTrace(True)
        channels = [
            InstrumentChannels.orderBook10, InstrumentChannels.quoteBin1m
        ]
        Bitmex = Instrument(symbol='XBTUSD', channels=channels)
        Bitmex.on('action', lambda msg: process(msg['data']))
        Bitmex.run_forever()
    except:
        time.sleep(10)
'''
clientBMX.Order.Order_new(symbol='XBTUSD', orderQty = Amount, price=priceSell-12.5).result()
clientBMX.Order.Order_cancel(orderID=orders[k]['orderID']).result()
orders = clientBMX.Order.Order_getOrders(filter=json.dumps({"open": True,"symbol":"XBTUSD"})).result()[0]
'''

def update_orderbook_data(orderbook10):
    global orderbook
    ask = pd.DataFrame(orderbook10['asks'], columns=['price', 'volume'])
    bid = pd.DataFrame(orderbook10['bids'], columns=['price', 'volume'])
    ask['price'] += 0.5  # ask above price
    ask['volume'] = -ask['volume'].cumsum(
    )  # negative volume means pointing left
    bid['volume'] = -bid['volume'].cumsum()
    orderbook = [[len(df) + 0.5, pd.concat([bid.iloc[::-1], ask])]]


if __name__ == '__main__':
    df = pd.DataFrame(price_history())
    ws = Instrument(
        channels=[InstrumentChannels.trade, InstrumentChannels.orderBook10])

    @ws.on('action')
    def action(message):
        if 'orderBook' in message['table']:
            for orderbook10 in message['data']:
                update_orderbook_data(orderbook10)
        else:
            for trade in message['data']:
                update_candlestick_data(trade)

    thread = Thread(target=ws.run_forever)
    thread.daemon = True
    thread.start()
    fplt.create_plot('Realtime Bitcoin/Dollar 1m (BitMEX websocket)',
                     init_zoom_periods=75,
Exemple #19
0
from __future__ import absolute_import
from bitmex_websocket import Instrument
import asyncio
import websocket

websocket.enableTrace(True)


def on_table(table_name, table):
    print("recieved table: %s" % (table_name))
    print(table)


channels = ['quote', 'trade']
XBTUSD = Instrument(symbol='XBTUSD',
                    channels=channels,
                    max_table_length=1,
                    shouldAuth=False)

for channel in channels:
    XBTUSD.on(channel, on_table)


def ws_error_handler(loop, err):
    alog.debug('# asyncio error handler...')
    raise err


loop = asyncio.get_event_loop()

loop.set_exception_handler(ws_error_handler)
Exemple #20
0
import websocket

from bitmex_websocket import Instrument
from bitmex_websocket.constants import InstrumentChannels

websocket.enableTrace(True)


channels = [
    InstrumentChannels.quote,
    InstrumentChannels.trade,
    InstrumentChannels.orderBookL2
]

XBTUSD = Instrument(symbol='XBTUSD',
                    channels=channels)

XBTUSD.run_forever()
Exemple #21
0
                            if count == 1:
                                for cnclOrd in msg['data']:
                                    print(
                                        '\nMASTER ACCOUNT:: Cancelled order ' +
                                        cnclOrd['orderID'])
                                    if cnclOrd['orderID'] in mainOrders:
                                        mainOrders.pop(
                                            mainOrders.index(
                                                cnclOrd['orderID']))
                            cancel_order(cclient, msg)
            except Exception as ex:
                print(ex)
    except Exception as ex:
        print(ex)


for sym in symbols:
    new_sock = Instrument(
        symbol=sym,
        # subscribes to 'order' channel (order submission, update, cancellation etc.)
        channels=['order', 'position'],
        # environment must be set according to pdf
        shouldAuth=True)

    # subscribe to action events for this instrument
    # new_sock.on('action', lambda x: print("# action message: %s" % x))
    new_sock.on('action', lambda x: process_message(x))

loop = asyncio.get_event_loop()
loop.run_forever()
Exemple #22
0
        l = o if o < c else c
        df1 = pd.DataFrame(dict(t=[t], o=[o], c=[c], h=[l], l=[l]))
        df = pd.concat([df, df1], ignore_index=True, sort=False)
    else:
        # update last candle
        i = df.index.max()
        df.loc[i, 'c'] = c
        if c > df.loc[i, 'h']:
            df.loc[i, 'h'] = c
        if c < df.loc[i, 'l']:
            df.loc[i, 'l'] = c


if __name__ == '__main__':
    df = pd.DataFrame(price_history())
    ws = Instrument(channels=[InstrumentChannels.trade])

    @ws.on('action')
    def action(message):
        if not 'data' in message:
            return
        for trade in message['data']:
            update_candlestick_data(trade)

    thread = Thread(target=ws.run_forever)
    thread.daemon = True
    thread.start()
    fplt.create_plot('Realtime Bitcoin/Dollar 1m (BitMEX websocket)',
                     init_zoom_periods=100,
                     maximize=False)
    update_plot()
Exemple #23
0
class BitmexWS:
    def trigger(self):
        self.isInOrder = False

    def onMessage(self, message):
        # print(message)
        a1 = message["data"]
        # print(a1)
        # print(a1[0])
        b = 'lastPrice' in a1[0]
        c = 'timestamp' in a1[0]
        if b and c:
            lastprice = float(a1[0]['lastPrice'])
            #print("lastprice = "+str(lastprice))
            timestamp = a1[0]['timestamp']

            # 同步状态
            sendToAll({"lastprice": lastprice})

            gap = lastprice - self.bc.avgPrice
            if self.n % 10 == 0:
                printlog("lastprice = " + str(lastprice) + "self.bc.pos:" +
                         str(self.prepos) + " gap = " + str(gap) +
                         " self.init_zhiying = " + str(self.targetProfit) +
                         " self.cengshu = " + str(self.cengshu))
            self.n = self.n + 1
            if lastprice < self.lowcontrolPriceline:
                if self.bc.pos > 0 and self.cengshu >= 5:
                    # 关键点位上,持仓逆向,且层数过高,平仓避避风头
                    printlog("关键点位上,持仓逆向,且层数过高,平仓避避风头 self.bc.pos = " +
                             str(self.bc.pos) + " self.cengshu = " +
                             str(self.cengshu))
                    self.orderClose()
            elif lastprice > self.highcontrolPriceline:
                if self.bc.pos < 0 and self.cengshu >= 5:
                    printlog("关键点位上,持仓逆向,且层数过高,平仓避避风头 self.bc.pos = " +
                             str(self.bc.pos) + " self.cengshu = " +
                             str(self.cengshu))
                    self.orderClose()
            isshouldgo = self.isAfterOrderPosChange()
            if isshouldgo == False:
                return
                # 没有仓位,立刻开仓
            print("prepos", self.prepos)
            if self.prepos == 0:
                printlog("无仓位立刻开仓")
                self.order()
            else:
                if gap > 1000:
                    return
                # 当前持有多仓

                if self.prepos > 0:
                    # 大于止盈点数,平仓
                    if gap > self.zhiying():
                        printlog("持有多仓,超过盈利点数,平仓:" + str(gap))
                        self.orderClose()
                    # 处理多单亏损
                    else:
                        # 如果亏损超过初始设定,则加多仓
                        if gap < -self.init_jiacanggap:
                            printlog("持有多仓,亏损超过设定点数,加仓: " + str(gap))
                            self.order()
                        else:
                            pass
                            #print("持有多仓,不触发平仓和加仓 gap = "+str(gap))
                # 当前持有空仓
                elif self.prepos < 0:
                    # 价格下跌到空仓开仓价格100点,止盈
                    if gap < -self.zhiying():
                        printlog("持有空仓,超过盈利点数,平仓:" + str(gap))
                        self.orderClose()
                    # 处理空单亏损
                    else:
                        # 价格上升到空仓开仓价格超过初始设定,则加空仓
                        if gap > self.init_jiacanggap:
                            printlog("持有空仓,亏损超过设定点数,加仓" + str(gap))
                            self.order()
                        else:
                            pass
                            #print("持有空仓,不触发平仓和加仓 gap = " + str(gap))

    def orderClose(self):
        self.isInOrder = True
        self.bc.orderClose()
        self.cengshu = 0
        self.mypos = 0
        self.init_jiacanggap = 10
        self.isPosChange = True

    def order(self):
        self.isInOrder = True
        printlog("self.cengshu = " + str(self.cengshu))
        if self.prepos == 0:
            self.bc.orderauto(1)
        else:
            self.bc.orderauto(abs(self.prepos) * 2)
            # if self.bc.pos>self.mypos*3:
            #     self.bc.orderauto(self.mypos * 2)
            # else:
            #
            # #self.bc.orderauto(self.mypos*2)
            # self.mypos = self.mypos + self.mypos * 2
        self.cengshu = self.cengshu + 1
        if self.cengshu == 1:
            self.targetProfit = 10
            self.init_jiacanggap = 10
        elif self.cengshu == 2:
            self.targetProfit = 15
            self.init_jiacanggap = 15
        elif self.cengshu == 3:
            self.targetProfit = 50
            self.init_jiacanggap = 70
        elif self.cengshu == 4:
            self.targetProfit = 50
            self.init_jiacanggap = 70
        elif self.cengshu == 5:
            self.targetProfit = 50
            self.init_jiacanggap = 70
        elif self.cengshu == 6:
            self.targetProfit = 50
            self.init_jiacanggap = 70
        elif self.cengshu == 7:
            self.targetProfit = 50
            self.init_jiacanggap = 70
        elif self.cengshu == 8:
            self.targetProfit = 50
            self.init_jiacanggap = 70
        elif self.cengshu == 9:
            self.targetProfit = 20
            self.init_jiacanggap = 160
        elif self.cengshu == 10:
            self.targetProfit = 20
            self.init_jiacanggap = 160
        elif self.cengshu == 11:
            self.targetProfit = 20
            self.init_jiacanggap = 160
        elif self.cengshu == 12:
            self.targetProfit = 20
            self.init_jiacanggap = 160
        self.isPosChange = True

    def isAfterOrderPosChange(self):
        # printlog(" isAfterOrderPosChange 仓位改变,等待"+str(self.isPosChange)+"self.prepos = "+str(self.prepos))
        if self.isPosChange == True:
            p = self.bc.getpos()
            if self.prepos == p:
                self.retryposchangetimes = self.retryposchangetimes + 1
                if self.retryposchangetimes >= 10:
                    self.retryposchangetimes = 0
                    self.isPosChange = False
                    return True
                printlog(" 仓位改变,等待")
                return False
            else:
                printlog(" 仓位改变完毕")
                self.prepos = p
                self.retryposchangetimes = 0
                self.isPosChange = False
                return True
        else:
            return True

    def zhiying(self):
        return self.targetProfit

    def __init__(self):
        self.isRun = False

    def run(self, settingidc):
        if (self.isRun):
            return
        self.isRun = True
        print('开始运行', settingidc)
        # 下限价格
        self.lowcontrolPriceline = settingidc["low"]
        print("self.lowcontrolPriceline", self.lowcontrolPriceline)
        # 上限价格
        self.highcontrolPriceline = settingidc["high"]
        print("self.highcontrolPriceline", self.highcontrolPriceline)
        # 赚了多少点就卖
        self.targetProfit = settingidc["targetProfit"]
        print("self.targetProfit", self.targetProfit)
        # 每次加仓的价格间隔
        self.init_jiacanggap = settingidc["priceGap"]
        print("self.init_jiacanggap", self.init_jiacanggap)
        # 初始仓位
        self.initorderPos = settingidc["initPos"]
        print("self.initorderPos", self.initorderPos)
        API_KEY = settingidc["API_KEY"]
        print("API_KEY", API_KEY)
        API_SECRET = settingidc["API_SECRET"]
        print("API_SECRET", API_SECRET)
        print("1")
        self.n = 0
        self.retryposchangetimes = 0
        self.isInOrder = False
        self.isPosChange = False
        self.cengshu = 0
        websocket.enableTrace(True)
        print("2")
        self.XBTH17 = Instrument(
            symbol='XBTUSD',
            # subscribes to all channels by default, here we
            # limit to just these two
            channels=['margin', 'instrument'],
            # you must set your environment variables to authenticate
            # see .env.example
            shouldAuth=True)
        print("3")
        self.bc = bitmexclient(API_KEY, API_SECRET)
        print("4")
        pos = self.bc.getpos()
        print("pos = ", pos)
        self.prepos = pos
        orderBook10 = self.XBTH17.get_table('instrument')
        self.XBTH17.on('action', self.onMessage)