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)
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()
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}"
#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] '''
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()
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) loop.run_forever()
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)
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)