def initBitmexWebSocket(apiKey: str, apiSecret: str): """Instantiate a connection""" ws = BitMEXWebsocket(endpoint="wss://testnet.bitmex.com/realtime", symbol="XBTUSD", api_key=apiKey, api_secret=apiSecret) ws.get_instrument() return ws
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)
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)
def update_instrument(): ws_ins = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1", symbol="XBTUSD", api_key=None, api_secret=None) while (ws_ins.ws.sock.connected): instrument=ws_ins.get_instrument() db.mkt.update_one({"_id":"instrument"},{"$set":instrument}) logging.info("instrument done") sleep(60)
def run(): logger = setup_logger() #symbole symbol = "XBTUSD" # 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=symbol, login=None, password=None, api_key=None, api_secret=None) logger.info("Instrument data: %s" % ws.get_instrument())
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")
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())
def bitmex_funding_rate_trigger(ticker, sma_period, anomaly_threshold_percent, telegram_token, telegram_chat_id, bearish_bias_msg, bullish_bias_msg): ws = BitMEXWebsocket(endpoint=f'wss://www.bitmex.com/realtime', symbol=f'{ticker}') rolling_data_set = [] i = 0 messaging = 0 while ws.ws.sock.connected: snapshot = ws.get_instrument() data = { 'fundingRate': snapshot['fundingRate'], 'fundingTimestamp': snapshot['fundingTimestamp'], 'fundingInterval': snapshot['fundingInterval'], 'indicativeFundingRate': snapshot['indicativeFundingRate'], 'symbol': snapshot['symbol'] } if i < sma_period: rolling_data_set.append(data['indicativeFundingRate']) i = i + 1 else: diff = data['indicativeFundingRate'] - numpy.mean(rolling_data_set) # check if rolling average has a negative spike if diff < 0 and abs(diff / numpy.mean(rolling_data_set) ) > anomaly_threshold_percent / 100: # Send Telegram message based Rolling average msg = f'Current funding rate: {data["indicativeFundingRate"]}\nMean funding rate: {numpy.mean(rolling_data_set)}\n' \ f'Spike %: {abs(diff / numpy.mean(rolling_data_set)) * 100} below average\n<b>{bullish_bias_msg}</b> ' if messaging == 1: send_telegram(f'{telegram_token}', telegram_chat_id, msg) messaging = 0 # check if rolling average has a positive spike elif diff > 0 and abs(diff / numpy.mean(rolling_data_set) ) > anomaly_threshold_percent / 100: # Send Telegram message based Rolling average msg = f'Current funding rate: {data["indicativeFundingRate"]}\nMean funding rate: {numpy.mean(rolling_data_set)}\n' \ f'Spike %: {abs(diff / numpy.mean(rolling_data_set)) * 100} above average\n<b>{bearish_bias_msg}</b> ' if messaging == 1: send_telegram(f'{telegram_token}', telegram_chat_id, msg) messaging = 0 else: # Rolling data set. Discarding the oldest value and adding new value. rolling_data_set = rolling_data_set[1:] rolling_data_set.append(data['indicativeFundingRate']) messaging = 1
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)
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)
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)
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)
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)
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)
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
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=API_KEY, api_secret=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()) recent_trades = ws.recent_trades() print(f"Recent Trades: {recent_trades}") print(len(recent_trades)) sleep(1)
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()
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
class Future: def __init__(self, apiconfpth=kfpth): f = open(apiconfpth, 'r') lines = f.readlines() f.close() apikey = lines[0].replace('\r', '').replace('\n', '') secretkey = lines[1].replace('\r', '').replace('\n', '') self.client = bitmex.bitmex(test=True, api_key=apikey, api_secret=secretkey) # https://www.bitmex.com/realtime # https://www.bitmex.com/api/v1 self.ws = BitMEXWebsocket( endpoint="https://testnet.bitmex.com/realtime", symbol="XBTUSD", api_key=None, api_secret=None) self.logger = self.setup_logger() self.logger.info("Instrument data: %s" % self.ws.get_instrument()) AlarmPrice.initAlarmObj(self.ws) def startAlarm(self, price): AlarmPrice.startAlarm(price) def stopAlarm(self): AlarmPrice.stopAlarm() def isAlarmWork(self): return AlarmPrice.isWork() 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 future_trade(self, symbol, contractType, price='', amount='', tradeType='', matchPrice='', leverRate=''): if symbol == 'XBT': if contractType == 'XBTUSD': return self.future_trade_xbtusd(price, amount, tradeType) else: print('合约交易类型%s不可用:' % (contractType)) else: print('市场类型%s不可用:' % (symbol)) res = None return res def future_trade_xbtusd(self, price, amount, tradeType): res = None tmpprice = '%.1f' % (float(price)) print('-----------------------') print(self.client.Order.__dict__) print(dir(self.client.Order)) if tradeType == '1': #开多 print('开多:', tmpprice, amount) res = self.client.Order.Order_new(symbol='XBTUSD', orderQty=int(amount), price=float(tmpprice)).result() elif tradeType == '3': #平多 print('平多:', tmpprice, amount) res = self.client.Order.Order_new(symbol='XBTUSD', orderQty=-int(amount), execInst='Close', price=float(tmpprice)).result() elif tradeType == '2': #开空 print('开空:', tmpprice, amount) res = self.client.Order.Order_new(symbol='XBTUSD', orderQty=-int(amount), price=float(tmpprice)).result() elif tradeType == '4': #平空 print('平空:', tmpprice, amount) #Order_new res = self.client.Order.Order_new(symbol='XBTUSD', orderQty=int(amount), execInst='Close', price=float(tmpprice)).result() else: print('tradeType,下单类型设置错误:', tradeType) return res[0] #OKCoin期货市场深度信息 def future_depth(self, symbol, contractType, size): if symbol == 'XBT': if contractType == 'XBTUSD': return self.future_depth_xbtusd(size) else: print('合约交易类型%s不可用:' % (contractType)) else: print('市场类型%s不可用:' % (symbol)) return None def future_depth_xbtusd(self, size): if self.ws.ws.sock.connected: depthdat = self.ws.market_depth() # logger.info("Market Depth: %s" % depthdat) print(type(depthdat), len(depthdat)) sells = [] buys = [] for d in depthdat: if d['symbol'] == 'XBTUSD': if d['side'] == 'Buy': buys.append([d['price'], d['size']]) elif d['side'] == 'Sell': sells.append([d['price'], d['size']]) sells.sort() backsells = sells[:size] print(backsells) print('----------') buys.sort(reverse=True) backbuys = buys[:size] print(backbuys) return backbuys, backsells[::-1] else: print('websocket连接错误') # self.ws.ws.sock.connect() return None, None #期货取消所有定单订单 def future_cancel(self, symbol, contractType, orderId): res = None if orderId == '' or (not orderId): res = self.client.Order.Order_cancelAll().result() print(res) else: res = self.client.Order.Order_cancel(orderId).result() print(res) return res #期货获取订单信息 def future_orderinfo(self, symbol, contractType, orderId, status, currentPage, pageLength): pass # FUTURE_ORDERINFO = "/api/v1/future_order_info.do?" # params = { # 'api_key':self.__apikey, # 'symbol':symbol, # 'contract_type':contractType, # 'order_id':orderId, # 'status':status, # 'current_page':currentPage, # 'page_length':pageLength # } # params['sign'] = buildMySign(params,self.__secretkey) # return httpPost(self.__url,FUTURE_ORDERINFO,params) #------------- #OKCOIN期货行情信息 def future_ticker(self, symbol, contractType): pass # FUTURE_TICKER_RESOURCE = "/api/v1/future_ticker.do" # params = '' # if symbol: # params += '&symbol=' + symbol if params else 'symbol=' +symbol # if contractType: # params += '&contract_type=' + contractType if params else 'contract_type=' +symbol # return httpGet(self.__url,FUTURE_TICKER_RESOURCE,params) #OKCoin期货交易记录信息 def future_trades(self, symbol, contractType): pass # FUTURE_TRADES_RESOURCE = "/api/v1/future_trades.do" # params = '' # if symbol: # params += '&symbol=' + symbol if params else 'symbol=' +symbol # if contractType: # params += '&contract_type=' + contractType if params else 'contract_type=' +symbol # return httpGet(self.__url,FUTURE_TRADES_RESOURCE,params) #OKCoin期货指数 def future_index(self, symbol): pass # FUTURE_INDEX = "/api/v1/future_index.do" # params='' # if symbol: # params = 'symbol=' +symbol # return httpGet(self.__url,FUTURE_INDEX,params) #获取美元人民币汇率 def exchange_rate(self): pass # EXCHANGE_RATE = "/api/v1/exchange_rate.do" # return httpGet(self.__url,EXCHANGE_RATE,'') #获取预估交割价 def future_estimated_price(self, symbol): pass # FUTURE_ESTIMATED_PRICE = "/api/v1/future_estimated_price.do" # params='' # if symbol: # params = 'symbol=' +symbol # return httpGet(self.__url,FUTURE_ESTIMATED_PRICE,params) #期货全仓账户信息 def future_userinfo(self): pass # FUTURE_USERINFO = "/api/v1/future_userinfo.do?" # params ={} # params['api_key'] = self.__apikey # params['sign'] = buildMySign(params,self.__secretkey) # return httpPost(self.__url,FUTURE_USERINFO,params) #期货全仓持仓信息 def future_position(self, symbol, contractType): pass # FUTURE_POSITION = "/api/v1/future_position.do?" # params = { # 'api_key':self.__apikey, # 'symbol':symbol, # 'contract_type':contractType # } # params['sign'] = buildMySign(params,self.__secretkey) # return httpPost(self.__url,FUTURE_POSITION,params) #期货批量下单 def future_batchTrade(self, symbol, contractType, orders_data, leverRate): pass # FUTURE_BATCH_TRADE = "/api/v1/future_batch_trade.do?" # params = { # 'api_key':self.__apikey, # 'symbol':symbol, # 'contract_type':contractType, # 'orders_data':orders_data, # 'lever_rate':leverRate # } # params['sign'] = buildMySign(params,self.__secretkey) # return httpPost(self.__url,FUTURE_BATCH_TRADE,params) #期货逐仓账户信息 def future_userinfo_4fix(self): pass # FUTURE_INFO_4FIX = "/api/v1/future_userinfo_4fix.do?" # params = {'api_key':self.__apikey} # params['sign'] = buildMySign(params,self.__secretkey) # return httpPost(self.__url,FUTURE_INFO_4FIX,params) #期货逐仓持仓信息 def future_position_4fix(self, symbol, contractType, type1): pass
def get_and_store_data(): # get data from bitmex ws_btc = BitMEXWebsocket(endpoint="https://www.bitmex.com", symbol="XBTUSD", api_key=None, api_secret=None) data_btc = ws_btc.get_instrument() mex_mark = round(data_btc["markPrice"], 1) # [USD] mex_oi = round(data_btc["openInterest"] / 10 ** 6, 3) # [mil USD] mex_funding = round(data_btc["fundingRate"] * 100, 3) # [%] # ----------------------------------------------------------- # get data from bybit client = bybit.bybit(test=False, api_key="", api_secret="") info = client.Market.Market_symbolInfo(symbol="BTCUSD").result() info_dict = info[0]["result"][0] bybit_mark = round(float(info_dict["mark_price"]), 1) # [USD] bybit_oi = round(int(info_dict["open_interest"]) / 10 ** 6, 3) # [mil USD] bybit_funding = round(float(info_dict["funding_rate"]) * 100, 3) # [%] # ----------------------------------------------------------- # get data from binance request_client = RequestClient(api_key="None", secret_key="None", url="https://fapi.binance.com") binance_oi_api = request_client.get_open_interest(symbol="BTCUSDT") binance_mark_api = request_client.get_mark_price(symbol="BTCUSDT") binance_mark = round(binance_mark_api.markPrice , 1) # [USD] binance_funding = round(binance_mark_api.lastFundingRate * 100, 3) # [mil USD] binance_oi = round(binance_oi_api.openInterest * binance_mark / 10 ** 6, 3) # [%] # ----------------------------------------------------------- # get data from okex api_key = "" secret_key = "" passphrase = "" swap_contract = "BTC-USD-SWAP" swapAPI = swap.SwapAPI(api_key, secret_key, passphrase) mark_price_api = swapAPI.get_mark_price(swap_contract) okex_mark = round(float(mark_price_api["mark_price"]), 1) # [USD] funding_api = swapAPI.get_funding_time(swap_contract) okex_funding = round(float(funding_api["funding_rate"]) * 100, 3) # [%] oi = swapAPI.get_holds(swap_contract) okex_oi = round(int(oi["amount"]) * 100 / 10 ** 6, 3) # [mil USD] # ----------------------------------------------------------- # time time = datetime.datetime.now().strftime("%Y-%d-%m %H:%M") # year-day-month hours-minutes-seconds # ----------------------------------------------------------- # print outs print("-" * 200) print(f"{mex_mark}[USD] - {mex_funding}[%] - {mex_oi}[mil USD] => Bitmex") print(f"{bybit_mark}[USD] - {bybit_funding}[%] - {bybit_oi}[mil USD] => Bybit") print(f"{binance_mark}[USD] - {binance_funding}[%] - {binance_oi}[mil USD] => Binance") print(f"{okex_mark}[USD] - {okex_funding}[%] - {okex_oi}[mil USD] => Okex") print("-" * 200) # data storage # all data all_swap_data = [mex_mark, mex_funding, mex_oi, bybit_mark, bybit_funding, bybit_oi, binance_mark, binance_funding, binance_oi, okex_mark, okex_funding, okex_oi, time] all_swap_data_txt = f"{mex_mark};{mex_funding};{mex_oi};{bybit_mark};{bybit_funding};{bybit_oi};{binance_mark};{binance_funding};{binance_oi};{okex_mark};{okex_funding};{okex_oi};{time}\n" with open("YOUR FILE PATH/oi-funding-mark-data/data storage/all_swap_data_storage.txt", "a") as store_swap_data: store_swap_data.write(all_swap_data_txt) store_swap_data.close() # print(all_swap_data_txt) # print(all_swap_data) # ----------------------------------------------------------- # avg mark, cum OI, oi weighted funding avg_mark = round(np.average([mex_mark, bybit_mark, binance_mark, okex_mark]), 3) # [USD] cum_OI = round(np.sum([mex_oi, bybit_oi, binance_oi, okex_oi]), 3) # [mil USD 1000mil => 1bil] oi_w_funding = round((mex_oi*mex_funding + bybit_oi*bybit_funding + binance_oi*binance_funding + okex_oi*okex_funding)/(mex_oi + bybit_oi + binance_oi + okex_oi), 3) # [%] => (-) bears are paying, (+) bulls are paying avgMark_cumOI_oiWfunding = [avg_mark, cum_OI, oi_w_funding, time] avgMark_cumOI_oiWfunding_txt = f"{avg_mark};{cum_OI};{oi_w_funding};{time}\n" # [USD] - [mil USD] - [%] with open("YOUR FILE PATH/oi-funding-mark-data/data storage/avgMark_cumOI_oiWfunding_storage.txt", "a") as store_avgM_cumOi_oiWfund: store_avgM_cumOi_oiWfund.write(avgMark_cumOI_oiWfunding_txt) store_avgM_cumOi_oiWfund.close() # print(avgMark_cumOI_oiWfunding_txt) # print(avgMark_cumOI_oiWfunding) # print(avg_mark) # print(cum_OI) # print(oi_w_funding) # ----------------------------------------------------------- # mark prices mark_prices = [mex_mark, bybit_mark, binance_mark, okex_mark, time] mark_prices_txt = f"{mex_mark};{bybit_mark};{binance_mark};{okex_mark};{time}\n" # [USD] with open("YOUR FILE PATH/oi-funding-mark-data/data storage/mark_prices_storage.txt", "a") as store_mark_prices: store_mark_prices.write(mark_prices_txt) store_mark_prices.close() # print(mark_prices_txt) # print(mark_prices) # ----------------------------------------------------------- # fundings fundings = [mex_funding, bybit_funding, binance_funding, okex_funding, time] fundings_txt = f"{mex_funding};{bybit_funding};{binance_funding};{okex_funding};{time}\n" # [%] with open("YOUR FILE PATH/oi-funding-mark-data/data storage/fundings_storage.txt", "a") as store_fundings: store_fundings.write(fundings_txt) store_fundings.close() # print(fundings_txt) # print(fundings) # ----------------------------------------------------------- # open interests open_interests = [mex_oi, bybit_oi, binance_oi, okex_oi, time] open_interests_txt = f"{mex_oi};{bybit_oi};{binance_oi};{okex_oi};{time}\n" # [mil USD] with open("YOUR FILE PATH/oi-funding-mark-data/data storage/open_interests_storage.txt", "a") as store_open_interests: store_open_interests.write(open_interests_txt) store_open_interests.close()
#amount = math.floor(ws.funds()['amount'] * 100000000 * currentPrice) #floor to round number amount = 100 randID1 = ''.join( random.choice(string.ascii_lowercase) for i in range(15)) #make random string for checking open orders randID2 = ''.join(random.choice(string.ascii_lowercase) for i in range(15)) offsetLong = 0 offsetShort = 0 deadManSwitch = client.Order.Order_cancelAllAfter( timeout=60000.0).result() #dead man switch start switchCounter = 0 if (ws.get_instrument()['volume'] < ws.get_instrument()['volume24h'] / 24): result1 = client.Order.Order_new( symbol=symbol, ordType='Limit', orderQty=amount, price=ws.recent_trades()[0]['price'] - offsetLong, execInst='ParticipateDoNotInitiate').result() while (True): #check if order succesful else try again if (result1[0]['ordStatus'] == 'New'): print('order LONG uspesen') break else: offsetLong += 0.00000001 result1 = client.Order.Order_new( symbol=symbol,
class BitmexTracker(): index_prefix = 'btcusd.bitmex' def __init__(self, apikey=None, apisecret=None, bitmex_address='wss://www.bitmex.com/realtime', es_address='elasticsearch:9200'): self.running_lock = Lock() self.data_lock = Lock() self.reload_lock = Lock() self.apikey = apikey self.apisecret = apisecret self.bitmex_address = bitmex_address self.es_address = es_address self.written_trades_ids = {} self.current_tick = datetime.now() self.previous_tick = datetime.now() self.orderbook_width = 100 self.setup_es() self.last_volume = 0 self.volume_pool = [] self.ticker = None self.asks = None self.bids = None self.trades = None self.instrument = None self.ws_logger = None self.es_logger = None self.es_thread = Thread(target=self.tick) self.es_thread.start() def tick(self): logger = self.setup_logger('ES') self.running_lock.acquire() while self.running_lock.locked(): try: self.current_tick = datetime.now( pytz.utc).replace(microsecond=0) if (self.current_tick.second != self.previous_tick.second): self.data_lock.acquire() try: if self.ticker: ticker = self.ticker.copy() else: ticker = None # if self.trades: # trades = self.trades.copy() # else: # trades = None if self.instrument: instrument = self.instrument.copy() else: instrument = None asks = self.asks bids = self.bids finally: self.data_lock.release( ) # release lock, no matter what if asks is None or bids is None or ticker is None or instrument is None: continue logger.info( 'Ticker at timestamp.second {}: \033[94m{}\033[0m'. format(self.current_tick.second, ticker)) ticker['timestamp'] = self.current_tick self.es.create(index='{}.tickers'.format( self.index_prefix), id=utils.generate_nonce(), doc_type='ticker', body=ticker) instrument['timestamp'] = self.current_tick self.es.create(index='{}.instrument'.format( self.index_prefix), id=utils.generate_nonce(), doc_type='instrument', body=instrument) # Calculate average volume if instrument['volume'] != self.last_volume: if instrument['volume'] < self.last_volume: volume = instrument['volume'] self.last_volume = instrument['volume'] else: volume = instrument['volume'] - self.last_volume self.volume_pool.append(self.current_tick) for timestamp in self.volume_pool: self.es.create(index='{}.volumes'.format( self.index_prefix), id=utils.generate_nonce(), doc_type='volume', body={ 'timestamp': timestamp, 'volume': volume / len(self.volume_pool) }) self.volume_pool = [] else: self.volume_pool.append(self.current_tick) self.last_volume = instrument['volume'] for i in range(-1, -4, -1): # последовательное уменьшение разрешения, L2->L1->L0 asks_frame = asks[-30 * (-i):] bids_frame = bids[:30 * (-i)] body = { 'timestamp': self.current_tick, 'bids': [tuple(x) for x in bids_frame.values], 'asks': [tuple(x) for x in asks_frame.values] } self.es.create(index='{}.orderbooks.l{}'.format( self.index_prefix, -i - 1), id=utils.generate_nonce(), doc_type='orderbook', body=body) logger.info( 'Orderbook L{} at timestamp.second {}: ask \033[92m{}\033[0m, bid \033[91m{}\033[0m' .format(-i - 1, self.current_tick.second, body['asks'][-1], body['bids'][0])) if self.current_tick.second % (10**(-i)) != 0: break bids['price'] = bids['price'].round(i) asks['price'] = asks['price'].round(i) asks = asks.groupby(['price']).agg({ 'size': np.sum }).reset_index() bids = bids.groupby(['price']).agg({ 'size': np.sum }).reset_index() self.previous_tick = self.current_tick except: logger.error('\033[91m{}\033[0m'.format( traceback.format_exc())) try: self.setup_es() except: logger.error('Reloading ES') def get_ticker(self, logger): ticker = self.ws.get_ticker() self.data_lock.acquire() try: self.ticker = ticker finally: self.data_lock.release() def get_instrument(self, logger): instrument = self.ws.get_instrument() self.data_lock.acquire() try: self.instrument = instrument finally: self.data_lock.release() def get_orderbook(self, logger): while True: try: orderbook = self.ws.market_depth().copy() ob = pd.DataFrame(orderbook)[['price', 'side', 'size']] break except Exception as err: logger.error(str(err)) ob = None if ob is not None: bids = ob[ob['side'] == 'Sell'][['price', 'size']].sort_values('price') asks = ob[ob['side'] == 'Buy'][['price', 'size']].sort_values('price') self.data_lock.acquire() try: self.bids = bids self.asks = asks finally: self.data_lock.release() # release lock, no matter what def get_trades(self, logger): trades = self.ws.recent_trades() self.data_lock.acquire() try: self.trades = trades finally: self.data_lock.release() # self.es.create(index='btcusd.bitmex.trades', id=utils.generate_nonce(), # doc_type='trades', body=trade) def get_funds(self, logger): funds = self.ws.funds() logger.info("Funds: %s" % funds) self.es.create(index='{}.funds'.format(self.index_prefix), id=utils.generate_nonce(), doc_type='funds', body=funds) def setup_es(self): self.es = Elasticsearch(self.es_address) utils.create_index(self.es, '{}.tickers'.format(self.index_prefix)) utils.create_index(self.es, '{}.orderbooks.l2'.format(self.index_prefix)) utils.create_index(self.es, '{}.orderbooks.l1'.format(self.index_prefix)) utils.create_index(self.es, '{}.orderbooks.l0'.format(self.index_prefix)) utils.create_index(self.es, '{}.volumes'.format(self.index_prefix)) utils.create_index(self.es, '{}.instrument'.format(self.index_prefix)) utils.create_index(self.es, '{}.funds'.format(self.index_prefix)) def run(self): logger = self.setup_logger('WS') try: # Instantiating the WS will make it connect. Be sure to add your api_key/api_secret. self.ws = BitMEXWebsocket(endpoint=self.bitmex_address, symbol="XBTUSD", api_key=None, api_secret=None) self.ws.get_instrument() logger.info('WS connector loaded') while self.ws.ws.sock.connected: self.get_ticker(logger) if self.ws.api_key: self.get_funds(logger) self.get_orderbook(logger) self.get_instrument(logger) # self.get_trades(logger) except: logger.error('\033[91m{}\033[0m'.format(traceback.format_exc())) finally: self.running_lock.release() self.es_thread.join() logger.error('\033[91mTHIS IS THE END\033[0m') def setup_logger(self, name): # Prints logger info to terminal logger = logging.getLogger(name) logger.setLevel( logging.INFO) # Change this to DEBUG if you want a lot more info ch = RotatingFileHandler('collector.log', maxBytes=5000000, backupCount=5) # create formatter formatter = logging.Formatter( "\033[93m%(asctime)s - %(name)s - %(levelname)s\033[0m - %(message)s" ) # add formatter to ch ch.setFormatter(formatter) logger.addHandler(ch) return logger
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=symbol, api_key='W3P6SJrm4T4n1ZunuvFqHTh7', api_secret='VdyjaXtF5Wx9NPlBS04VmDA9AcNIGfUCRuhN6OImxgo0ezo6') #logger.info("Instrument data: %s" % ws.get_instrument()) # Run forever #currentPrice = ws.get_ticker() instriment = ws.get_instrument() bid = 0 ask = 0 bidsize = 0 asksize = 0 while (ws.ws.sock.connected): instrument = ws.get_instrument() quote = ws.get_quote() #print (quote) logger.info("bid price/size: %s %s ask price/size: %s %s", instrument['bidPrice'], quote['bidSize'], instrument['askPrice'], quote['askSize']) newbid = instrument['bidPrice'] newask = instrument['askPrice'] newbidsize = quote['bidSize'] newasksize = quote['askSize'] data1 = { 'market': symbol, 'exchange': exchange, 'bid': newbid, 'bidSize': newbidsize, 'ask': newask, 'askSize': newasksize, 'time': datetime.datetime.utcnow() } mongohistory.Insert(data1) if (bid != newbid or ask != newask or bidsize != newbidsize or asksize != newasksize): data = { 'market': symbol, 'exchange': exchange, 'bid': newbid, 'bidSize': newbidsize, 'ask': newask, 'askSize': newasksize, 'time': datetime.datetime.utcnow() } mongo.UpdateFieldByExchange(exchange, data) ask = newask bid = newbid bidsize = newbidsize asksize = newasksize print("save!") #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(1)
symbol = "XBTUSD" movement_start_price_delta = 25 movement_end_price_delta = 5 movement_time_delta = 5 is_in_movement = False movement_id = 0 api_key = 'replace' api_secret = 'replace' ws = BitMEXWebsocket(endpoint='https://testnet.bitmex.com/api/v1', symbol=symbol, api_key=None, api_secret=None) 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()
# also ce program crasha to pumaga de se lepo zaprejo orderji offsetLong = 0 offsetShort = 0 deadManSwitch = client.Order.Order_cancelAllAfter(timeout=60000.0).result() # dead man switch start switchCounter = 0 kukCajta = datetime.now() - lastRenew if (kukCajta.seconds / 60 > 15): # renew ws connection cause live feed lagging, renew every hour ws.exit() ws = BitMEXWebsocket(endpoint="https://www.bitmex.com/api/v1", symbol=symbol, api_key=apiKljuci['websocket']['key'], api_secret=apiKljuci['websocket']['secret']) lastRenew = datetime.now() if (ws.get_instrument()['volume'] < ws.get_instrument()['volume24h'] / 24): # avoid pumps/dumps d = dateutil.parser.parse(ws.get_instrument()['fundingTimestamp']) d = d.replace(tzinfo=None) razlika = d - datetime.utcnow() print(razlika.seconds / 60) if (razlika.seconds / 60 > 10): # check funding closing result1 = client.Order.Order_new(symbol=symbol, ordType='Limit', orderQty=amount, price=ws.recent_trades()[0]['price'] - offsetLong, execInst='ParticipateDoNotInitiate').result() while (True): # check if order succesful else try again if (result1[0]['ordStatus'] == 'New'): print('order LONG uspesen') break else: time.sleep(2) offsetLong += 0.05
from bitmex_websocket import BitMEXWebsocket import config.account as account from order_creator import OrderCreator from bot import MainBot def create_long_client(): return OrderCreator(account.is_test_net(), account.get_api_key_long(), account.get_api_secret_long()) if __name__ == "__main__": ws = BitMEXWebsocket(endpoint=account.get_end_point(), symbol="XBTUSD", api_key=account.get_api_key_long(), api_secret=account.get_api_secret_long()) ws.get_instrument() bot = MainBot(api_client=create_long_client(), web_socket=ws) try: bot.run('long') except KeyboardInterrupt: bot.clear_cache() exit(0) raise finally: bot.clear_cache()