def place_orders(self): if self.monitor: return None con_sz = self.con_size for fut in self.futures.keys(): account = self.client.fetchBalance() spot = self.get_spot() bal_btc = float(account['info']['totalMarginBalance']) / spot pos = float(self.positions[fut]['positionAmt']) pos_lim_long = bal_btc * PCT_LIM_LONG * 125 #/ len(self.futures) pos_lim_short = bal_btc * PCT_LIM_SHORT * 125 #/ len(self.futures) #print(pos_lim_long) #expi = self.futures[ fut ][ 'expi_dt' ] #tte = max( 0, ( expi - datetime.utcnow()).total_seconds() / SECONDS_IN_DAY ) pos_decay = 1.0 - math.exp(-DECAY_POS_LIM * 8035200) pos_lim_long *= pos_decay pos_lim_short *= pos_decay pos_lim_long -= pos pos_lim_short += pos pos_lim_long = max(0, pos_lim_long) pos_lim_short = max(0, pos_lim_short) min_order_size_btc = (MIN_ORDER_SIZE * CONTRACT_SIZE) / spot print( min_order_size_btc) #0.0006833471711135484 0.08546200188472201 qtybtc = bal_btc * 125 / 25 nbids = min(math.trunc(pos_lim_long / qtybtc), MAX_LAYERS) nasks = min(math.trunc(pos_lim_short / qtybtc), MAX_LAYERS) place_bids = nbids > 0 place_asks = nasks > 0 if not place_bids and not place_asks: print('No bid no offer for %s' % fut, min_order_size_btc) continue tsz = float(self.get_ticksize(fut)) # Perform pricing vol = max(self.vols[BTC_SYMBOL], self.vols[fut]) eps = BP * vol * RISK_CHARGE_VOL riskfac = math.exp(eps) bbo = self.get_bbo(fut) bid_mkt = bbo['bid'] ask_mkt = bbo['ask'] if bid_mkt is None and ask_mkt is None: bid_mkt = ask_mkt = spot elif bid_mkt is None: bid_mkt = min(spot, ask_mkt) elif ask_mkt is None: ask_mkt = max(spot, bid_mkt) mid_mkt = 0.5 * (bid_mkt + ask_mkt) ords = self.client.fetchOpenOrders(fut) cancel_oids = [] bid_ords = ask_ords = [] if place_bids: bid_ords = [o for o in ords if o['info']['side'] == 'buy'] len_bid_ords = min(len(bid_ords), nbids) bid0 = mid_mkt * math.exp(-MKT_IMPACT) bids = [bid0 * riskfac**-i for i in range(1, nbids + 1)] bids[0] = ticksize_floor(bids[0], tsz) if place_asks: ask_ords = [o for o in ords if o['info']['side'] == 'sell'] len_ask_ords = min(len(ask_ords), nasks) ask0 = mid_mkt * math.exp(MKT_IMPACT) asks = [ask0 * riskfac**i for i in range(1, nasks + 1)] asks[0] = ticksize_ceil(asks[0], tsz) for i in range(max(nbids, nasks)): # BIDS if place_bids and i < nbids: if i > 0: prc = ticksize_floor(min(bids[i], bids[i - 1] - tsz), tsz) else: prc = bids[0] qty = round(prc * qtybtc / con_sz) / spot if i < len_bid_ords: oid = bid_ords[i]['info']['side']['orderId'] print(oid) try: self.client.editOrder(oid, qty, prc) except (SystemExit, KeyboardInterrupt): raise except Excetion as e: print(e) else: try: self.client.createOrder(fut, "Limit", 'buy', qty, prc) except (SystemExit, KeyboardInterrupt): raise except Exception as e: print(e) self.logger.warn( 'Bid order failed: %s bid for %s' % (prc, qty)) # OFFERS if place_asks and i < nasks: if i > 0: prc = ticksize_ceil(max(asks[i], asks[i - 1] + tsz), tsz) else: prc = asks[0] qty = round(prc * qtybtc / con_sz) / spot if i < len_ask_ords: oid = ask_ords[i]['info']['side']['orderId'] print(oid) try: self.client.editOrder(oid, qty, prc) except (SystemExit, KeyboardInterrupt): raise except Exeption as e: print(e) else: try: self.client.createOrder(fut, "Limit", 'sell', qty, prc) except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warn('Offer order failed: %s at %s' % (qty, prc)) if nbids < len(bid_ords): cancel_oids += [ o['info']['side']['orderId'] for o in bid_ords[nbids:] ] if nasks < len(ask_ords): cancel_oids += [ o['info']['side']['orderId'] for o in ask_ords[nasks:] ] for oid in cancel_oids: try: self.client.cancelOrder(oid, 'BTC/USDT') except: self.logger.warn('Order cancellations failed: %s' % oid)
def place_orders( self ): if self.monitor: return None con_sz = self.con_size print(['BTC-PERPETUAL', 'BTC-25DEC20', 'BTC-25SEP20', 'BTC-26MAR21']) for fut in ['BTC-PERPETUAL', 'BTC-25DEC20', 'BTC-25SEP20', 'BTC-26MAR21']: print(fut) account = self.client.account() spot = self.get_spot() bal_btc = account[ 'equity' ] pos = self.positions[ fut ][ 'sizeBtc' ] expi = self.futures[ fut ][ 'expi_dt' ] tte = max( 0, ( expi - datetime.utcnow()).total_seconds() / SECONDS_IN_DAY ) pos_decay = 1.0 - math.exp( -DECAY_POS_LIM * tte ) min_order_size_btc = MIN_ORDER_SIZE / spot * CONTRACT_SIZE qtybtc = max( PCT_QTY_BASE * bal_btc, min_order_size_btc) nbids = MAX_LAYERS nasks = MAX_LAYERS #place_bids = nbids > 0 #place_asks = nasks > 0 self.MAX_SKEW = MIN_ORDER_SIZE * MAX_LAYERS * 10 #print(fut) spot = self.get_spot() ##print(res) t = 0 for pos in self.positions: t = t + math.fabs(self.positions[pos]['size']) self.equity_usd = self.equity_btc * spot self.LEV = t / self.equity_usd self.IM = self.LEV / 2 ##print(' ') ##print(fut) ##print(' ') for k in self.positions: self.skew_size[k[0:3]] = 0 ####print('skew_size: ' + str(self.skew_size)) ####print(self.positions) for k in self.positions: self.skew_size[k[0:3]] = self.skew_size[k[0:3]] + self.positions[k]['size'] ####print('skew_size: ' + str(self.skew_size)) #print(self.skew_size) psize = self.positions[fut]['size'] self.place_bids[fut] = True self.place_asks[fut] = True ###print(self.PCT_LIM_LONG) a = {} for pos in self.positions: a[pos] = 0 for pos in self.positions: a[pos] = a[pos] + math.fabs(self.positions[pos]['size']) ##print((((a[pos[0:3]] / self.equity_usd) / self.LEV_LIM[pos[0:3]] * 1000 ) / 10 )) ##print((((a[pos[0:3]] / self.equity_usd) / self.LEV_LIM[pos[0:3]] * 1000 ) / 10 )) ##print((((a[pos[0:3]] / self.equity_usd) / self.LEV_LIM[pos[0:3]] * 1000 ) / 10 )) #print(self.LEV_LIM) #print(a) if self.LEV_LIM[fut] == 0: ##print('lev lim 0!') if self.positions[fut]['size'] < 0: self.place_asks[fut] = False if self.positions[fut]['size'] > 0: self.place_bids[fut] = False elif (((a[fut] / self.equity_usd) / self.LEV_LIM[fut] * 1000 ) / 10 ) > 100: if self.positions[fut]['size'] < 0: self.place_asks[fut] = False if self.positions[pos]['size'] > 0: self.place_bids[pos] = False #print((((a[fut] / self.equity_usd) / self.LEV_LIM[fut] * 1000 ) / 10 )) if self.place_asks[fut] == False and self.place_bids[fut] == False: try: prc = self.get_bbo(fut)['bid'] qty = self.equity_usd / 48 / 10 / 2 qty = float(min( qty, MIN_ORDER_SIZE)) # ###print('qty: ' + str(qty)) ###print(max_bad_arb) qty = round(qty) for k in self.positions: self.skew_size[k[0:3]] = 0 for k in self.positions: self.skew_size[k[0:3]] = self.skew_size[k[0:3]] + self.positions[k]['size'] token = fut[0:3] if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) if qty <= 1: qty = 1 if self.positions[fut]['size'] >= 0: ##print(' ') ##print(' ') ##print(qty) ##print(self.skew_size[token]) ##print(self.MAX_SKEW) if qty + self.skew_size[token] * -1 <= self.MAX_SKEW: mexAsks = [] for i in range(0, round(MAX_LAYERS)): r = random.randint(0, 100) #print(r) if qty + self.skew_size[fut[0:3]] * -1 < self.MAX_SKEW: if i >= len_ask_ords: self.client.sell( fut, qty, asks[i], 'true' ) if self.positions[fut]['size'] <= 0: if qty + self.skew_size[token] < self.MAX_SKEW: mexBids = [] for i in range(0, round(MAX_LAYERS)): r = random.randint(0, 100) #print(r) if qty + self.skew_size[fut[0:3]] < self.MAX_SKEW: if i >= len_bid_ords: self.client.buy( fut, qty, bids[i], 'true' ) except: PrintException() tsz = self.get_ticksize( fut ) # Perform pricing bbo = self.get_bbo( fut ) bid_mkt = bbo[ 'bid' ] ask_mkt = bbo[ 'ask' ] if bid_mkt is None and ask_mkt is None: bid_mkt = ask_mkt = spot elif bid_mkt is None: bid_mkt = min( spot, ask_mkt ) elif ask_mkt is None: ask_mkt = max( spot, bid_mkt ) mid_mkt = 0.5 * ( bid_mkt + ask_mkt ) ords = self.client.getopenorders( fut ) cancel_oids = [] bid_ords = ask_ords = [] riskfac = 1 asks = [] bids = [] if self.place_bids[fut]: bid_ords = [ o for o in ords if o[ 'direction' ] == 'buy' ] len_bid_ords = min( len( bid_ords ), nbids ) bid0 = mid_mkt * math.exp( -MKT_IMPACT ) bids = [ bid0 * riskfac ** -i for i in range( 1, nbids + 1 ) ] bids[ 0 ] = ticksize_floor( bids[ 0 ], tsz ) if self.place_asks[fut]: ask_ords = [ o for o in ords if o[ 'direction' ] == 'sell' ] len_ask_ords = min( len( ask_ords ), nasks ) ask0 = mid_mkt * math.exp( MKT_IMPACT ) asks = [ ask0 * riskfac ** i for i in range( 1, nasks + 1 ) ] asks[ 0 ] = ticksize_ceil( asks[ 0 ], tsz ) nbids = len(bids) nasks = len(asks) # BIDS for i in range( 0, MAX_LAYERS ): if i < nbids: ###print(i) if i > 0: prc = ticksize_floor( min( bids[ i ], bids[ i - 1 ] - tsz ), tsz ) else: prc = bids[ 0 ] #qty = ( prc * qtybtc / con_sz ) qty = self.equity_usd / 48 / 10 / 2 qty = float(min( qty, MIN_ORDER_SIZE)) max_bad_arb = int(self.MAX_SKEW ) # ###print('qty: ' + str(qty)) ###print(max_bad_arb) qty = qty qty = round(qty) * (i+1) if qty <= 1: qty = 1 ###print('qty: ' + str(qty)) if self.MAX_SKEW < qty * 10 : self.MAX_SKEW = qty * 10 if self.place_asks[fut] == False: self.MAX_SKEW = self.MAX_SKEW * 3 qty = qty * 10 ob = self.client.getorderbook( fut ) bids1 = ob[ 'bids' ] asks1 = ob[ 'asks' ] prc = ticksize_floor(( bids1[0]['price']), tsz ) if qty + self.skew_size[fut[0:3]] > self.MAX_SKEW: print(fut+ ' bid self.MAX_SKEW return ...') for xyz in bid_ords: cancel_oids.append( xyz['orderId'] ) #self.execute_cancels(fut, nbids, nasks, bid_ords, ask_ords, qtybtc, con_sz, tsz, cancel_oids, len_bid_ords, len_ask_ords) continue ##print(len_bid_ords) ###print('i less') try: if i < len_bid_ords: sleep(RATE_LIMIT) ###print('i less') try: oid = bid_ords[ i ][ 'orderId' ] self.restartflag = False self.client.edit( oid, qty, prc ) except (SystemExit, KeyboardInterrupt): raise except Exception as e: PrintException() elif len_bid_ords <= MAX_LAYERS: if 'PERPETUAL' not in fut: if self.longperp == False: if self.arbmult[fut]['arb'] > 0 and (self.positions[fut]['size'] - qty <= max_bad_arb ): if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) if qty <= 1: qty = 1 self.restartflag = False self.client.buy( fut, qty, prc, 'true' ) if self.arbmult[fut]['arb'] < 0 : if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) qty = int(qty * 3) ###print('buy qty * 1.1, 1' + fut) if qty <= 1: qty = 1 self.restartflag = False self.client.buy( fut, qty, prc, 'true' ) else: print(self.longperp) if self.longperp == True: qty = qty * 2 print(qty) print(self.arbmult[fut]['arb']) print(self.positions[fut]['size']) print(max_bad_arb) if self.arbmult[fut]['arb'] < 0 and (self.positions[fut]['size'] - qty <= max_bad_arb ): if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) if qty <= 1: qty = 1 self.restartflag = False self.client.buy( fut, qty, prc, 'true' ) if self.arbmult[fut]['arb'] > 0: if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) qty = int(qty * 3) ###print('buy qty * 1.1, 2' + fut) if qty <= 1: qty = 1 self.restartflag = False self.client.buy( fut, qty, prc, 'true' ) elif len_bid_ords <= MAX_LAYERS: sleep(RATE_LIMIT) if 'PERPETUAL' not in fut: if self.longperp == False: if self.arbmult[fut]['arb'] > 0 and (self.positions[fut]['size'] - qty <= max_bad_arb ): if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) if qty <= 1: qty = 1 self.restartflag = False self.client.buy( fut, qty, prc, 'true' ) if self.arbmult[fut]['arb'] < 0 : if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) qty = int(qty * 3) ###print('buy qty * 1.1, 1' + fut) if qty <= 1: qty = 1 self.restartflag = False self.client.buy( fut, qty, prc, 'true' ) else: if self.longperp == True: qty = qty * 2 if self.arbmult[fut]['arb'] < 0 and (self.positions[fut]['size'] - qty <= max_bad_arb ): if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) if qty <= 1: qty = 1 self.restartflag = False self.client.buy( fut, qty, prc, 'true' ) if self.arbmult[fut]['arb'] > 0: if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) qty = int(qty * 3) ###print('buy qty * 1.1, 2' + fut) if qty <= 1: qty = 1 self.restartflag = False self.client.buy( fut, qty, prc, 'true' ) except (SystemExit, KeyboardInterrupt): raise except Exception as e: PrintException() self.logger.warn( 'Bid order failed: %s bid for %s' % ( prc, qty )) # OFFERS # ASKS ###print('# OFFERS') if i < nasks: if i > 0: prc = ticksize_ceil( max( asks[ i ], asks[ i - 1 ] + tsz ), tsz ) else: prc = asks[ 0 ] qty = self.equity_usd / 48 / 10 / 2 qty = float(min( qty, MIN_ORDER_SIZE)) #10 max_bad_arb = int(self.MAX_SKEW ) ###print('qty: ' + str(qty)) ###print(max_bad_arb) qty = qty qty = round(qty) * (i+1) if qty <= 1: qty = 1 if self.MAX_SKEW < qty * 10 : self.MAX_SKEW = qty * 10 if self.place_bids[fut] == False: self.MAX_SKEW = self.MAX_SKEW * 3 qty = qty * 10 ob = self.client.getorderbook( fut ) bids1 = ob[ 'bids' ] asks1 = ob[ 'asks' ] prc = ticksize_ceil(( asks1[0]['price']), tsz ) ###print('qty: ' + str(qty)) ####print('skew_size: ' + str(self.skew_size)) ####print('max_soew: ' + str(self.MAX_SKEW)) if qty + self.skew_size[fut[0:3]] * -1 > self.MAX_SKEW: print(fut + ' offer self.MAX_SKEW return ...') for xyz in ask_ords: cancel_oids.append( xyz['orderId'] ) #self.execute_cancels(fut, nbids, nasks, bid_ords, ask_ords, qtybtc, con_sz, tsz, cancel_oids, len_bid_ords, len_ask_ords) continue ##print(len_ask_ords) try: if i < len_ask_ords: sleep(RATE_LIMIT) ###print('i less') try: oid = ask_ords[ i ][ 'orderId' ] self.restartflag = False self.client.edit( oid, qty, prc ) except (SystemExit, KeyboardInterrupt): raise except Exception as e: PrintException() elif len_ask_ords <= MAX_LAYERS: if 'PERPETUAL' not in fut: if self.longperp == True: if self.arbmult[fut]['arb'] >= 0: if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) qty = int(qty * 3) ###print('sell qty * 1.1, 1' + fut) if qty <= 1: qty = 1 self.restartflag = False self.client.sell( fut, qty, prc, 'true' )#self.client.sell( fut, qty, prc, 'true' ) if self.arbmult[fut]['arb'] <= 0 and self.positions[fut]['size'] + qty * -1 >=-1 * max_bad_arb : if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) if qty <= 1: qty = 1 self.restartflag = False self.client.sell( fut, qty, prc, 'true' )#self.client.sell( fut, qty, prc, 'true' ) else: if self.longperp == False: #print(self.arbmult) qty = qty * 2 if self.arbmult[fut]['arb'] <= 0: if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) qty = int(qty * 3) ###print('sell qty * 1.1, 2' + fut) if qty <= 1: qty = 1 self.restartflag = False self.client.sell( fut, qty, prc, 'true' )#self.client.sell( fut, qty, prc, 'true' ) if self.arbmult[fut]['arb'] >= 0 and self.positions[fut]['size'] + qty * -1 >=-1 * max_bad_arb : if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) if qty <= 1: qty = 1 self.restartflag = False self.client.sell( fut, qty, prc, 'true' )#self.client.sell( fut, qty, prc, 'true' ) elif len_ask_ords <= MAX_LAYERS: sleep(RATE_LIMIT) if 'PERPETUAL' not in fut: if self.longperp == True: if self.arbmult[fut]['arb'] >= 0: if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) qty = int(qty * 3) ###print('sell qty * 1.1, 1' + fut) if qty <= 1: qty = 1 self.restartflag = False self.client.sell( fut, qty, prc, 'true' )#self.client.sell( fut, qty, prc, 'true' ) if self.arbmult[fut]['arb'] <= 0 and self.positions[fut]['size'] + qty * -1 >=-1 * max_bad_arb : if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) if qty <= 1: qty = 1 self.restartflag = False self.client.sell( fut, qty, prc, 'true' )#self.client.sell( fut, qty, prc, 'true' ) else: if self.longperp == False: qty = qty * 2 if self.arbmult[fut]['arb'] <= 0: if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) qty = int(qty * 3) ###print('sell qty * 1.1, 2' + fut) if qty <= 1: qty = 1 self.restartflag = False self.client.sell( fut, qty, prc, 'true' )#self.client.sell( fut, qty, prc, 'true' ) if self.arbmult[fut]['arb'] >= 0 and self.positions[fut]['size'] + qty * -1 >=-1 * max_bad_arb : if 'ETH' in fut or 'XRP' in fut: qty = qty / self.get_bbo(fut[0:3] + 'USD')['bid'] if 'USD' in fut: qty = qty / self.get_multiplier(fut) if qty <= 1: qty = 1 self.restartflag = False self.client.sell( fut, qty, prc, 'true' )#self.client.sell( fut, qty, prc, 'true' ) except (SystemExit, KeyboardInterrupt): raise except Exception as e: PrintException() self.logger.warn( 'Offer order failed: %s at %s' % ( qty, prc )) if nbids < len( bid_ords ): cancel_oids += [ o[ 'orderId' ] for o in bid_ords[ nbids : ]] if nasks < len( ask_ords ): cancel_oids += [ o[ 'orderId' ] for o in ask_ords[ nasks : ]] for oid in cancel_oids: try: self.client.cancel( oid ) except: self.logger.warn( 'Order cancellations failed: %s' % oid )
def place_orders(self): if self.monitor: return None con_sz = self.con_size for fut in self.futures.keys(): account = self.client.account() spot = self.get_spot() bal_btc = account['equity'] * 100 pos_lim_long = bal_btc * PCT_LIM_LONG / len(self.futures) pos_lim_short = bal_btc * PCT_LIM_SHORT / len(self.futures) expi = self.futures[fut]['expi_dt'] ##print(self.futures[ fut ][ 'expi_dt' ]) if self.eth is 0: self.eth = 200 if 'ETH' in fut: if 'sizeEth' in self.positions[fut]: pos = self.positions[fut][ 'sizeEth'] * self.eth / self.get_spot() else: pos = 0 else: pos = self.positions[fut]['sizeBtc'] tte = max(0, (expi - datetime.utcnow()).total_seconds() / SECONDS_IN_DAY) pos_decay = 1.0 - math.exp(-DECAY_POS_LIM * tte) pos_lim_long *= pos_decay pos_lim_short *= pos_decay pos_lim_long -= pos pos_lim_short += pos pos_lim_long = max(0, pos_lim_long) pos_lim_short = max(0, pos_lim_short) min_order_size_btc = MIN_ORDER_SIZE / spot * CONTRACT_SIZE #qtybtc = max( PCT_QTY_BASE * bal_btc, min_order_size_btc) qtybtc = PCT_QTY_BASE * bal_btc nbids = min(math.trunc(pos_lim_long / qtybtc), MAX_LAYERS) nasks = min(math.trunc(pos_lim_short / qtybtc), MAX_LAYERS) place_bids = nbids > 0 place_asks = nasks > 0 #buy bid sell ask if self.dsrsi > 80: #over place_bids = 0 if self.dsrsi < 20: #under place_asks = 0 if not place_bids and not place_asks: #print( 'No bid no offer for %s' % fut, min_order_size_btc ) continue tsz = self.get_ticksize(fut) # Perform pricing vol = max(self.vols[BTC_SYMBOL], self.vols[fut]) if 1 in self.volatility: eps = BP * vol * RISK_CHARGE_VOL if 0 in self.volatility: eps = BP * 0.5 * RISK_CHARGE_VOL if 2 in self.price: eps = eps * self.diff if 3 in self.price: if self.diffdeltab[fut] > 0 or self.diffdeltab[fut] < 0: eps = eps * self.diffdeltab[fut] if 2 in self.volatility: eps = eps * (1 + self.bbw[fut]) if 3 in self.volatility: eps = eps * (self.atr[fut] / 100) riskfac = math.exp(eps) bbo = self.get_bbo(fut) bid_mkt = bbo['bid'] ask_mkt = bbo['ask'] mid = 0.5 * (bbo['bid'] + bbo['ask']) mid_mkt = 0.5 * (bid_mkt + ask_mkt) ords = self.client.getopenorders(fut) cancel_oids = [] bid_ords = ask_ords = [] if place_bids: bid_ords = [o for o in ords if o['direction'] == 'buy'] len_bid_ords = min(len(bid_ords), nbids) bid0 = mid_mkt * math.exp(-MKT_IMPACT) bids = [bid0 * riskfac**-i for i in range(1, nbids + 1)] bids[0] = ticksize_floor(bids[0], tsz) if place_asks: ask_ords = [o for o in ords if o['direction'] == 'sell'] len_ask_ords = min(len(ask_ords), nasks) ask0 = mid_mkt * math.exp(MKT_IMPACT) asks = [ask0 * riskfac**i for i in range(1, nasks + 1)] asks[0] = ticksize_ceil(asks[0], tsz) for i in range(max(nbids, nasks)): # BIDS #print('nbids') #print(nbids) #print('nasks') #print(nasks) if place_bids and i < nbids: if i > 0: prc = ticksize_floor(min(bids[i], bids[i - 1] - tsz), tsz) else: prc = bids[0] qty = round(prc * qtybtc / (con_sz / 1)) if 'ETH' in fut: qty = round(prc * 450 * qtybtc / (con_sz / 1)) if 4 in self.quantity_switch: if self.diffdeltab[fut] > 0 or self.diffdeltab[fut] < 0: qty = round(qty / (self.diffdeltab[fut])) if 2 in self.quantity_switch: qty = round(qty * self.buysellsignal[fut]) if 3 in self.quantity_switch: qty = round(qty * self.multsLong[fut]) if 1 in self.quantity_switch: qty = round(qty / self.diff) if qty < 0: qty = qty * -1 if i < len_bid_ords: oid = bid_ords[i]['orderId'] try: self.client.edit(oid, qty, prc) except (SystemExit, KeyboardInterrupt): raise except: try: self.client.buy(fut, qty, prc, 'true') cancel_oids.append(oid) self.logger.warn('Edit failed for %s' % oid) except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warn( 'Bid order failed: %s bid for %s' % (prc, qty)) else: try: self.client.buy(fut, qty, prc, 'true') except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warn( 'Bid order failed: %s bid for %s' % (prc, qty)) # OFFERS if place_asks and i < nasks: if i > 0: prc = ticksize_ceil(max(asks[i], asks[i - 1] + tsz), tsz) else: prc = asks[0] qty = round(prc * qtybtc / (con_sz / 1)) if 'ETH' in fut: qty = round(prc * 450 * qtybtc / (con_sz / 1)) #print(qty) #print(qty) #print(qty) #print(qty) if 4 in self.quantity_switch: if self.diffdeltab[fut] > 0 or self.diffdeltab[fut] < 0: qty = round(qty / (self.diffdeltab[fut])) if 2 in self.quantity_switch: qty = round(qty / self.buysellsignal[fut]) if 3 in self.quantity_switch: qty = round(qty * self.multsShort[fut]) #print(qty) #print(qty) #print(qty) #print(qty) if 1 in self.quantity_switch: qty = round(qty / self.diff) if qty < 0: qty = qty * -1 if i < len_ask_ords: oid = ask_ords[i]['orderId'] try: self.client.edit(oid, qty, prc) except (SystemExit, KeyboardInterrupt): raise except: try: self.client.sell(fut, qty, prc, 'true') cancel_oids.append(oid) self.logger.warn('Sell Edit failed for %s' % oid) except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warn( 'Offer order failed: %s at %s' % (qty, prc)) else: try: self.client.sell(fut, qty, prc, 'true') except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warn('Offer order failed: %s at %s' % (qty, prc)) if nbids < len(bid_ords): cancel_oids += [o['orderId'] for o in bid_ords[nbids:]] if nasks < len(ask_ords): cancel_oids += [o['orderId'] for o in ask_ords[nasks:]] for oid in cancel_oids: try: self.client.cancel(oid) except: self.logger.warn('Order cancellations failed: %s' % oid)
def place_orders(self): if self.monitor: return None for fut in self.futures.keys(): try: avg_price = self.positions[fut]['averagePrice'] * ( self.positions[fut]['size'] / abs(self.positions[fut]['size'])) except: avg_price = 0 spot = self.get_spot() # Me imb = self.get_bbo(fut)['imbalance'] posOpn = sum( OrderedDict({ k: self.positions[k]['size'] for k in self.futures.keys() }).values()) posOB = sum([ o['quantity'] for o in [ o for o in self.client.getopenorders() if o['direction'] == 'buy' ] ]) - sum([ o['quantity'] for o in [ o for o in self.client.getopenorders() if o['direction'] == 'sell' ] ]) posOBBid = sum([ o['quantity'] for o in [ o for o in self.client.getopenorders() if o['direction'] == 'buy' ] ]) posOBAsk = sum([ o['quantity'] for o in [ o for o in self.client.getopenorders() if o['direction'] == 'sell' ] ]) posNet = posOB + posOpn posNet2 = posNet + (10 / 100 * posNet) Margin = avg_price * PCT / 8 #8 = arbitrase aja avg_priceAdj = avg_price * PCT / 2 #up/down, 2= arbitrase aja # Me nbids = 1 nasks = 1 place_bids = 'true' place_asks = 'true' print('posOpn', posOpn, 'posOB', posOB, 'posNet', posNet, 'posNet2', posNet2, 'avg_price', avg_price) if not place_bids and not place_asks: print('No bid no offer for %s' % fut) continue tsz = self.get_ticksize(fut) # Perform pricing vol = max(self.vols[BTC_SYMBOL], self.vols[fut]) eps = BP * vol * RISK_CHARGE_VOL riskfac = math.exp(eps) bbo = self.get_bbo(fut) bid_mkt = bbo['bid'] ask_mkt = bbo['ask'] if bid_mkt is None and ask_mkt is None: bid_mkt = ask_mkt = spot elif bid_mkt is None: bid_mkt = min(spot, ask_mkt) elif ask_mkt is None: ask_mkt = max(spot, bid_mkt) mid_mkt = 0.25 * (bid_mkt + ask_mkt) ords = self.client.getopenorders(fut) cancel_oids = [] bid_ords = ask_ords = [] if place_bids: bid_ords = [o for o in ords if o['direction'] == 'buy'] len_bid_ords = min(len(bid_ords), nbids) bid0 = mid_mkt * math.exp(-MKT_IMPACT) bids = [bid0 * riskfac**-i for i in range(1, nbids + 1)] bids[0] = ticksize_floor(bids[0], tsz) if place_asks: ask_ords = [o for o in ords if o['direction'] == 'sell'] len_ask_ords = min(len(ask_ords), nasks) ask0 = mid_mkt * math.exp(MKT_IMPACT) asks = [ask0 * riskfac**i for i in range(1, nasks + 1)] asks[0] = ticksize_ceil(asks[0], tsz) for i in range(max(nbids, nasks)): time.sleep(1) # BIDS if place_bids: offerOB = bid_mkt print('BIDS', offerOB, 'posOpn', posOpn, 'posOB', posOB, 'posNet', posNet, 'avg_price', avg_price, 'avg_priceAdj', avg_price - avg_priceAdj, 'imb', imb) # cek posisi awal if posOpn == 0: # posisi baru mulai, order bila bid>ask (memperkecil resiko salah) if avg_price == 0 and imb > 0: prc = bid_mkt # sudah ada posisi short, buat posisi beli elif avg_price < 0: prc = min(bid_mkt, (abs(avg_price) - abs(Margin))) # average down elif avg_price > 0: prc = abs(avg_price) - abs(avg_priceAdj) else: prc = 0 # net sudah ada posisi, individual masih kosong elif avg_price == 0: # mencegah bid makin menambah posisi long #if posOpn > posNet2: # prc = 0 # menyeimbangkan posisi if posNet < 0: prc = bid_mkt else: prc = 0 # sudah ada posisi long elif avg_price > 0: # posisi rugi, average down if bid_mkt < avg_price: prc = min(bid_mkt, abs(avg_price) + abs(avg_priceAdj)) # sudah ada short, ambil laba elif avg_price < 0: prc = min(bid_mkt, (abs(avg_price) - abs(Margin))) else: prc = 0 qty = 1 if i < len_bid_ords: oid = bid_ords[i]['orderId'] try: self.client.edit(oid, qty, prc) except (SystemExit, KeyboardInterrupt): raise except: try: self.client.buy(fut, qty, prc, 'true') cancel_oids.append(oid) self.logger.warning('Edit failed for %s' % oid) except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warning( 'Bid order failed: %s bid for %s' % (prc, qty)) else: try: self.client.buy(fut, qty, prc, 'true') except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warning( 'Bid order failed: %s bid for %s' % (prc, qty)) # OFFERS if place_asks: offerOB = ask_mkt print('OFFERS', offerOB, 'posOpn', posOpn, 'posOB', posOB, 'posNet', posNet, 'avg_price', avg_price, 'avg_priceAdj', avg_priceAdj + avg_price, 'imb', imb) # cek posisi awal if posOpn == 0: # posisi baru mulai, order bila bid>ask (memperkecil resiko salah) if avg_price == 0 and imb < 0: prc = bid_mkt # sudah ada posisi short, buat posisi beli elif avg_price > 0: prc = max(bid_mkt, (abs(avg_price) + abs(Margin))) # average up elif avg_price < 0: prc = abs(avg_price) + abs(avg_priceAdj) else: prc = 0 # net sudah ada posisi, individual masih kosong elif avg_price == 0: # mencegah bid makin menambah posisi short #if posOpn > posNet2: # prc = 0 # menyeimbangkan posisi if posNet > 0: prc = bid_mkt # order bila bid>ask (memperkecil resiko salah) elif imb < 0: prc = bid_mkt else: prc = 0 # sudah ada posisi short elif avg_price < 0: # posisi rugi, average up if bid_mkt > avg_price: prc = max(bid_mkt, abs(avg_priceAdj) + abs(avg_price)) else: prc = 0 # sudah ada long, ambil laba elif avg_price > 0: prc = max(bid_mkt, (abs(avg_price) + abs(Margin))) else: prc = 0 qty = 1 if i < len_ask_ords: oid = ask_ords[i]['orderId'] try: self.client.edit(oid, qty, prc) except (SystemExit, KeyboardInterrupt): raise except: try: self.client.sell(fut, qty, prc, 'true') cancel_oids.append(oid) self.logger.warning('Sell Edit failed for %s' % oid) except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warning( 'Offer order failed: %s at %s' % (qty, prc)) else: try: self.client.sell(fut, qty, prc, 'true') except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warning( 'Offer order failed: %s at %s' % (qty, prc)) if nbids > len(bid_ords): cancel_oids += [o['orderId'] for o in bid_ords[nbids:]] if nasks > len(ask_ords): cancel_oids += [o['orderId'] for o in ask_ords[nasks:]] for oid in cancel_oids: try: self.client.cancel(oid) except: self.logger.warning('Order cancellations failed: %s' % oid)
def get_bbo(self, contract): # Get best b/o excluding own orders j = self.ohlcv[contract].json() fut2 = contract #print(contract) best_bids = [] best_asks = [] o = [] h = [] l = [] c = [] v = [] for b in j['result']['open']: o.append(b) for b in j['result']['high']: h.append(b) for b in j['result']['low']: l.append(b) for b in j['result']['close']: c.append(b) for b in j['result']['volume']: v.append(b) abc = 0 ohlcv2 = [] for b in j['result']['open']: ohlcv2.append([o[abc], h[abc], l[abc], c[abc], v[abc]]) abc = abc + 1 ddf = pd.DataFrame(ohlcv2, columns=['open', 'high', 'low', 'close', 'volume']) if 1 in self.directional: sleep(0) try: self.dsrsi = TA.STOCHRSI(ddf).iloc[-1] * 100 except: self.dsrsi = 50 ##print(self.dsrsi) # Get orderbook if 2 in self.volatility or 3 in self.price or 4 in self.quantity_switch: self.bands[fut2] = TA.BBANDS(ddf).iloc[-1] self.bbw[fut2] = (TA.BBWIDTH(ddf).iloc[-1]) #print(float(self.bands[fut2]['BB_UPPER'] - self.bands[fut2]['BB_LOWER'])) if (float(self.bands[fut2]['BB_UPPER'] - self.bands[fut2]['BB_LOWER'])) > 0: deltab = (self.get_spot() - self.bands[fut2]['BB_LOWER']) / ( self.bands[fut2]['BB_UPPER'] - self.bands[fut2]['BB_LOWER']) if deltab > 50: self.diffdeltab[fut2] = (deltab - 50) / 100 + 1 if deltab < 50: self.diffdeltab[fut2] = (50 - deltab) / 100 + 1 else: self.diffdeltab[fut2] = 25 / 100 + 1 if 3 in self.volatility: self.atr[fut2] = TA.ATR(ddf).iloc[-1] if 0 in self.price: ob = self.client.getorderbook(contract) bids = ob['bids'] asks = ob['asks'] ords = self.client.getopenorders(contract) bid_ords = [o for o in ords if o['direction'] == 'buy'] ask_ords = [o for o in ords if o['direction'] == 'sell'] best_bid = None best_ask = None err = 10**-(self.get_precision(contract) + 1) for b in bids: match_qty = sum([ o['quantity'] for o in bid_ords if math.fabs(b['price'] - o['price']) < err ]) if match_qty < b['quantity']: best_bid = b['price'] break for a in asks: match_qty = sum([ o['quantity'] for o in ask_ords if math.fabs(a['price'] - o['price']) < err ]) if match_qty < a['quantity']: best_ask = a['price'] break best_asks.append(best_ask) best_bids.append(best_bid) if 1 in self.price: dvwap = TA.VWAP(ddf) ##print(dvwap) tsz = self.get_ticksize(contract) try: bid = ticksize_floor(dvwap.iloc[-1], tsz) ask = ticksize_ceil(dvwap.iloc[-1], tsz) except: bid = ticksize_floor(self.get_spot(), tsz) ask = ticksize_ceil(self.get_spot(), tsz) #print( { 'bid': bid, 'ask': ask }) best_asks.append(best_ask) best_bids.append(best_bid) if 2 in self.quantity_switch: dppo = TA.PPO(ddf) self.buysellsignal[fut2] = 1 try: if (dppo.iloc[-1].PPO > 0): self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 + PRICE_MOD) else: self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 - PRICE_MOD) if (dppo.iloc[-1].HISTO > 0): self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 + PRICE_MOD) else: self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 - PRICE_MOD) if (dppo.iloc[-1].SIGNAL > 0): self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 + PRICE_MOD) else: self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 - PRICE_MOD) except: self.buysellsignal[fut2] = 1 ##print({ 'bid': best_bid, 'ask': best_ask }) return { 'bid': self.cal_average(best_bids), 'ask': self.cal_average(best_asks) }
def place_orders(self): if self.monitor: return None con_sz = self.con_size for fut in self.futures.keys(): account = self.client.account() spot = self.get_spot() bal_btc = account['equity'] pos = self.positions[fut]['sizeBtc'] pos_lim_long = bal_btc * PCT_LIM_LONG / len(self.futures) pos_lim_short = bal_btc * PCT_LIM_SHORT / len(self.futures) expi = self.futures[fut]['expi_dt'] tte = max(0, (expi - datetime.utcnow()).total_seconds() / SECONDS_IN_DAY) pos_decay = 1.0 - math.exp(-DECAY_POS_LIM * tte) pos_lim_long *= pos_decay pos_lim_short *= pos_decay pos_lim_long -= pos pos_lim_short += pos pos_lim_long = max(0, pos_lim_long) pos_lim_short = max(0, pos_lim_short) min_order_size_btc = MIN_ORDER_SIZE / spot * CONTRACT_SIZE qtybtc = max(PCT_QTY_BASE * bal_btc, min_order_size_btc) nbids = min(math.trunc(pos_lim_long / qtybtc), MAX_LAYERS) nasks = min(math.trunc(pos_lim_short / qtybtc), MAX_LAYERS) place_bids = nbids > 0 place_asks = nasks > 0 if not place_bids and not place_asks: print('No bid no offer for %s' % fut, pos_lim_long) continue tsz = self.get_ticksize(fut) # Perform pricing vol = max(self.vols[BTC_SYMBOL], self.vols[fut]) eps = BP * vol * RISK_CHARGE_VOL riskfac = math.exp(eps) bbo = self.get_bbo(fut) bid_mkt = bbo['bid'] ask_mkt = bbo['ask'] if bid_mkt is None and ask_mkt is None: bid_mkt = ask_mkt = spot elif bid_mkt is None: bid_mkt = min(spot, ask_mkt) elif ask_mkt is None: ask_mkt = max(spot, bid_mkt) mid_mkt = 0.5 * (bid_mkt + ask_mkt) ords = self.client.getopenorders(fut) cancel_oids = [] bid_ords = ask_ords = [] if place_bids: bid_ords = [o for o in ords if o['direction'] == 'buy'] len_bid_ords = min(len(bid_ords), nbids) bid0 = mid_mkt * math.exp(-MKT_IMPACT) bids = [bid0 * riskfac**-i for i in range(1, nbids + 1)] bids[0] = ticksize_floor(bids[0], tsz) if place_asks: ask_ords = [o for o in ords if o['direction'] == 'sell'] len_ask_ords = min(len(ask_ords), nasks) ask0 = mid_mkt * math.exp(MKT_IMPACT) asks = [ask0 * riskfac**i for i in range(1, nasks + 1)] asks[0] = ticksize_ceil(asks[0], tsz) for i in range(max(nbids, nasks)): # BIDS if place_bids and i < nbids: if i > 0: prc = ticksize_floor(min(bids[i], bids[i - 1] - tsz), tsz) else: prc = bids[0] qty = round(prc * qtybtc / con_sz) if i < len_bid_ords: oid = bid_ords[i]['orderId'] try: self.client.edit(oid, qty, prc) except (SystemExit, KeyboardInterrupt): raise except: try: self.client.buy(fut, qty, prc, 'true') cancel_oids.append(oid) self.logger.warn('Edit failed for %s' % oid) except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warn( 'Bid order failed: %s bid for %s' % (prc, qty)) else: try: self.client.buy(fut, qty, prc, 'true') except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warn( 'Bid order failed: %s bid for %s' % (prc, qty)) # OFFERS if place_asks and i < nasks: if i > 0: prc = ticksize_ceil(max(asks[i], asks[i - 1] + tsz), tsz) else: prc = asks[0] qty = round(prc * qtybtc / con_sz) if i < len_ask_ords: oid = ask_ords[i]['orderId'] try: self.client.edit(oid, qty, prc) except (SystemExit, KeyboardInterrupt): raise except: try: self.client.sell(fut, qty, prc, 'true') cancel_oids.append(oid) self.logger.warn('Sell Edit failed for %s' % oid) except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warn( 'Offer order failed: %s at %s' % (qty, prc)) else: try: self.client.sell(fut, qty, prc, 'true') except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warn('Offer order failed: %s at %s' % (qty, prc)) if nbids < len(bid_ords): cancel_oids += [o['orderId'] for o in bid_ords[nbids:]] if nasks < len(ask_ords): cancel_oids += [o['orderId'] for o in ask_ords[nasks:]] for oid in cancel_oids: try: self.client.cancel(oid) except: self.logger.warn('Order cancellations failed: %s' % oid)
def place_orders(self): if self.monitor: return None for fut in self.futures.keys(): instName = self.get_perpetual (fut) # hold = ITEMS ON HAND # ord = ITEMS ON ORDER BOOK # net = LONG + SHORT # fut = INDIVIDUAL ITEM PER INSTRUMENT # all = TOTAL INDIVIDUAL ITEM PER INSTRUMENT PER DIRECTION imb = self.get_bbo(fut)['imbalance'] spot = self.get_spot() ##determine various Qty variable #hold_fut = abs(self.positions[fut]['size'])#individual hold_longItem = len([o['averagePrice'] for o in [o for o in self.client.positions ( ) if o['direction'] == 'buy' and o['currency'] == fut[:3].lower()]]) hold_shortItem = len([o['averagePrice'] for o in [o for o in self.client.positions ( ) if o['direction'] == 'sell' and o['currency'] == fut[:3].lower()]]) hold_longQtyAll = sum([o['size'] for o in [o for o in self.client.positions () if o[ 'direction'] == 'buy' and o['currency'] == fut[:3].lower()]]) hold_shortQtyAll = sum([o['size'] for o in [o for o in self.client.positions () if o[ 'direction'] == 'sell' and o['currency'] == fut[:3].lower()]]) #hold_netFut = (hold_longQtyAll+hold_shortQtyAll) ord_longQtyFut = sum([o['quantity'] for o in [o for o in self.client.getopenorders( ) if o['direction'] == 'buy' and o['api'] == True and o[ 'instrument'] == fut[:3].lower()]]) ord_shortQtyFut = sum([o['quantity'] for o in [o for o in self.client.getopenorders( ) if o['direction'] == 'sell' and o['api'] == True and o[ 'instrument'] == fut[:3].lower()]]) bal_btc = self.client.account()[ 'equity' ] qty_lvg = max(1,round( (bal_btc * spot * 80)/10 * PCT,0)) # 100%-20% #determine various price variable hold_avgPrcFut = self.positions[fut]['averagePrice']*(self.positions[fut]['size'])/abs( self.positions[fut]['size']) if self.positions[fut] ['size'] != 0 else 0 hold_avgPrcShort = sum([o['averagePrice'] for o in [o for o in self.client.positions ( ) if o['direction'] == 'sell' and o['currency'] == fut[:3].lower()]] ) hold_avgQtyShort = len([o['averagePrice'] for o in [o for o in self.client.positions ( ) if o['direction'] == 'sell' and o['currency'] == fut[:3].lower()]]) hold_avgPrcLong = sum([o['averagePrice'] for o in [o for o in self.client.positions ( ) if o['direction'] == 'buy' and o['currency'] == fut[:3].lower()]] ) hold_avgQtyLong = len([o['averagePrice'] for o in [o for o in self.client.positions ( ) if o['direction'] == 'buy' and o['currency'] == fut[:3].lower()]]) hold_avgPrcShortAll = 0 if hold_avgQtyShort == 0 else hold_avgPrcShort/hold_avgQtyShort hold_avgPrcLongAll = 0 if hold_avgQtyLong == 0 else hold_avgPrcLong/hold_avgQtyLong try: hold_lastPrcBuy = min([o['price'] for o in [o for o in self.get_bbo(fut) [ 'last_price_buy'] if o['instrument'] == instName]]) hold_lastPrcSell= max([o['price'] for o in [o for o in self.get_bbo(fut) [ 'last_price_sell'] if o['instrument'] == instName]]) except: hold_lastPrcBuy = hold_avgPrcFut hold_lastPrcSell= hold_avgPrcFut diffperpfut = self.client.getsummary(fut)['markPrice' ]-self.client.getsummary ('BTC-PERPETUAL')['markPrice'] hold_avgPrcLongPerp = hold_avgPrcLongAll - (hold_avgPrcLongAll*PCT*10 + diffperpfut) hold_avgPrcShortPerp= hold_avgPrcShortAll + (hold_avgPrcShortAll*PCT*10 + diffperpfut) #Menghitung kuantitas beli/jual # maks kuantitas by maks leverage nbids = 1 nasks = 1 place_bids = 'true' place_asks = 'true' if not place_bids and not place_asks: print('No bid no offer for %s' % fut) continue tsz = self.get_ticksize(fut) # Perform pricing vol = max(self.vols[BTC_SYMBOL], self.vols[fut]) eps = BP * vol * RISK_CHARGE_VOL riskfac = math.exp(eps) bbo = self.get_bbo(fut) bid_mkt = bbo['bid'] ask_mkt = bbo['ask'] if bid_mkt is None and ask_mkt is None: bid_mkt = ask_mkt elif bid_mkt is None: bid_mkt = ask_mkt elif ask_mkt is None: ask_mkt = bid_mkt mid_mkt = self.get_ticksize(fut) * (bid_mkt + ask_mkt) ords = self.client.getopenorders(fut) cancel_oids = [] bid_ords = ask_ords = [] if place_bids: bid_ords = [o for o in ords if o['direction'] == 'buy'] len_bid_ords = min(len(bid_ords), nbids) bid0 = mid_mkt * math.exp(-MKT_IMPACT) bids = [bid0 * riskfac ** -i for i in range(1, nbids + 1)] bids[0] = ticksize_floor(bids[0], tsz) if place_asks: ask_ords = [o for o in ords if o['direction'] == 'sell'] len_ask_ords = min(len(ask_ords), nasks) ask0 = mid_mkt * math.exp(MKT_IMPACT) asks = [ask0 * riskfac ** i for i in range(1, nasks + 1)] asks[0] = ticksize_ceil(asks[0], tsz) #market condition df = self.DF(fut) RSI = ((pd.DataFrame(df,self.RSI(df)).tail (1)['RSI'].values))[0] ATR = (pd.DataFrame(df ,self.ATR(df,14)).tail (1)['ATR'].values)[0] SMA10 = (pd.DataFrame(df,self.SMA10(df)).tail (1)['SMA10'].values)[0] bullish = RSI > 60 and SMA10 > bid_mkt bear = RSI < 30 and SMA10 < bid_mkt sideways= RSI > 30 and RSI < 60 hold_diffTime = (self.client.gettime()/1000)-(self.get_bbo(fut)['last_price'][0] ['timeStamp']/1000) try: ord_diffTime = (self.client.gettime()/1000) - (ords [0] ['created']/1000) except: ord_diffTime = 29 actual_prcBuy = abs(hold_lastPrcBuy) if hold_diffTime < 100 else abs(hold_avgPrcFut) actual_prcSell = abs(hold_lastPrcSell) if hold_diffTime < 100 else abs(hold_avgPrcFut) avg_down0 = min(abs(actual_prcBuy),abs(hold_avgPrcFut)) - abs(ATR/2) if sideways == True else min( abs(actual_prcBuy),abs(hold_avgPrcFut)) - min(abs(actual_prcBuy),abs(hold_avgPrcFut)) * PCT/2 avg_down2 = abs(min(abs(actual_prcBuy),abs(hold_avgPrcFut))) - abs(min(abs(actual_prcBuy),abs(hold_avgPrcFut)) * PCT * 2) avg_down20 = abs(min(abs(actual_prcBuy),abs(hold_avgPrcFut))) - abs(min(abs(actual_prcBuy),abs(hold_avgPrcFut)) * PCT * 20) avg_up0 = max (abs(actual_prcSell),hold_avgPrcFut) + abs(ATR/2) if sideways == True else max ( actual_prcSell,hold_avgPrcFut) + max(abs(actual_prcSell),hold_avgPrcFut) * PCT/2 print (instName,actual_prcBuy,actual_prcSell,hold_diffTime) print ('true', max (abs(actual_prcSell),hold_avgPrcFut) ) print ('ATR',abs(ATR/2)) print ('true', max (abs(actual_prcSell),hold_avgPrcFut) + abs(ATR/2)) print ('false',max (actual_prcSell,hold_avgPrcFut) + max(abs(actual_prcSell),hold_avgPrcFut) * PCT/2) print (instName, avg_up0 , bid_mkt, hold_avgPrcFut, ATR/2,sideways ) avg_up2 = abs(max(abs(actual_prcSell),hold_avgPrcFut)) + abs(max(abs(actual_prcSell),hold_avgPrcFut) * PCT * 2) avg_up20 = abs(max(abs(actual_prcSell),hold_avgPrcFut)) + abs(max(abs(actual_prcSell),hold_avgPrcFut) * PCT * 20) #export_excel = SMAATR.to_excel (r'C:\Users\agung\Documents\!project\data1.xlsx', index = None, header=True) for i in range(max(nbids, nasks)): # BIDS if place_bids: if hold_avgPrcFut == 0 and imb > 0 and abs(ord_longQtyFut ) < qty_lvg and hold_longItem <2 : # posisi baru mulai, order bila bid>ask if instName [-10:] != '-PERPETUAL' and hold_longQtyAll <= 0 and ord_longQtyFut ==0 and ( bullish == True or sideways == True): prc = bid_mkt elif instName [-10:] == '-PERPETUAL' and hold_avgPrcLongAll !=0 : prc = min(bid_mkt,hold_avgPrcLongPerp) else: prc = 0 # sudah ada short, ambil laba elif hold_avgPrcFut < 0 and hold_avgPrcFut != 0: prc = min(bid_mkt, abs(avg_down0)) # average down pada harga < 5%, 10% & 20% elif bid_mkt < hold_avgPrcFut and hold_avgPrcFut != 0 and abs( ord_longQtyFut) < 1 and hold_shortQtyAll !=0 : if hold_longQtyAll <= qty_lvg : prc = min(bid_mkt, abs(avg_down2)) elif hold_longQtyAll < qty_lvg * 3 and instName [-10:] != '-PERPETUAL': prc = min(bid_mkt, abs(avg_down20)) elif hold_longQtyAll < qty_lvg * 4 and instName [-10:] == '-PERPETUAL': prc = min(bid_mkt, abs(avg_down20)) else: prc = 0 else: prc = 0 else: prc = 0 qty = 1 if i < len_bid_ords: oid = bid_ords[i]['orderId'] try: self.client.edit(oid, qty, prc) except (SystemExit, KeyboardInterrupt): raise except: try: self.client.buy(fut, qty, prc, 'true') cancel_oids.append(oid) self.logger.warning('Edit failed for %s' % oid) except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warning('Bid order failed: %s'% instName ) else: try: self.client.buy(fut, qty, prc, 'true') except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warning('Bid order failed %s'% instName) # OFFERS if place_asks: # cek posisi awal if hold_avgPrcFut == 0 and imb < 0 and abs(ord_shortQtyFut ) < qty_lvg and hold_shortItem <2 : # posisi baru mulai, order bila bid<ask (memperkecil resiko salah) if instName [-10:] != '-PERPETUAL' and abs(hold_shortQtyAll) <= 0 and ord_shortQtyFut ==0 and ( bear == True or sideways == True): prc = bid_mkt elif instName [-10:] == '-PERPETUAL' and hold_avgPrcShortAll !=0: prc = max(bid_mkt,hold_avgPrcShortPerp) else: prc = 0 # sudah ada long, ambil laba elif hold_avgPrcFut > 0 and hold_avgPrcFut != 0 : prc = max(bid_mkt, abs(avg_up0)) # average up pada harga < 5%, 10% & 20% elif bid_mkt > hold_avgPrcFut and hold_avgPrcFut != 0 and abs( ord_shortQtyFut) < 1 and hold_longQtyAll !=0 : if abs(hold_shortQtyAll) <= qty_lvg: prc = max(bid_mkt, abs(avg_up2)) elif abs(hold_shortQtyAll) < qty_lvg * 3 and instName [-10:] != '-PERPETUAL': prc = max(bid_mkt, abs(avg_up20)) elif abs(hold_shortQtyAll) < qty_lvg * 4 and instName [-10:] == '-PERPETUAL': prc = max(bid_mkt, abs(avg_up20)) else: prc = 0 else: prc = 0 else: prc = 0 qty = 1 if i < len_ask_ords: oid = ask_ords[i]['orderId'] try: self.client.edit(oid, qty, prc) except (SystemExit, KeyboardInterrupt): raise except: try: self.client.sell(fut, qty, prc, 'true') cancel_oids.append(oid) self.logger.warning('Sell Edit failed for %s' % oid) except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warning('Offer order failed: %s'% instName ) else: try: self.client.sell(fut, qty, prc, 'true') except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warning('Offer order failed: %s'% instName ) if nbids > len(bid_ords): cancel_oids += [o['orderId'] for o in bid_ords[nbids:]] if nasks > len(ask_ords): cancel_oids += [o['orderId'] for o in ask_ords[nasks:]] for oid in cancel_oids: try: self.client.cancel(oid) except: self.logger.warning('Order cancellations failed: %s' % oid) #cancell all orders when: any executions on order book, # item quantity outstanding on orderbook> 1, or > 10 seconds if hold_diffTime < 1 or ord_shortQtyFut >3 or ord_longQtyFut>3 or ord_diffTime > 30: while True: self.client.cancelall() sleep (10) break
def place_orders(self): if self.monitor: return None con_sz = self.con_size for fut in self.futures.keys(): account = self.ws['XBTUSD'].funds() spot = self.get_spot() bal_btc = float(account['marginBalance'] / 100000000) bal_usd = bal_btc * spot for k in self.positions.keys(): if 'currentQty' not in self.positions[k]: self.positions[k]['currentQty'] = 0 pos = float(self.positions[fut]['currentQty']) pos_lim_long = bal_usd * PCT_LIM_LONG / len(self.futures) pos_lim_short = bal_usd * PCT_LIM_SHORT / len(self.futures) expi = self.futures['XBTUSD']['expi_dt'] tte = max(0, (expi - datetime.utcnow()).total_seconds() / SECONDS_IN_DAY) pos_decay = 1.0 - math.exp(-DECAY_POS_LIM * tte) pos_lim_long *= pos_decay pos_lim_short *= pos_decay pos_lim_long -= pos pos_lim_short += pos pos_lim_long = max(0, pos_lim_long) pos_lim_short = max(0, pos_lim_short) min_order_size_btc = MIN_ORDER_SIZE / spot * CONTRACT_SIZE if 'ETH' in fut: min_order_size_btc = min_order_size_btc * spot / self.get_spot_eth( ) * (spot / self.get_spot_eth()) / 2 qtybtc = max(PCT_QTY_BASE * bal_btc, min_order_size_btc) nbids = min(math.trunc(pos_lim_long / qtybtc), MAX_LAYERS) nasks = min(math.trunc(pos_lim_short / qtybtc), MAX_LAYERS) place_bids = nbids > 0 place_asks = nasks > 0 #buy bid sell ask if self.dsrsi > 80: #over place_bids = 0 if self.dsrsi < 20: #under place_asks = 0 if not place_bids and not place_asks: print('No bid no offer for %s' % fut, min_order_size_btc) continue tsz = self.get_ticksize(fut) # Perform pricing vol = max(self.vols[BTC_SYMBOL], self.vols[fut]) if 1 in self.volatility: eps = BP * vol * RISK_CHARGE_VOL if 0 in self.volatility: eps = BP * 0.5 * RISK_CHARGE_VOL if 2 in self.price: eps = eps * self.diff if 3 in self.price: if self.diffdeltab[fut] > 0 or self.diffdeltab[fut] < 0: eps = eps * self.diffdeltab[fut] if 2 in self.volatility: eps = eps * (1 + self.bbw[fut]) if 3 in self.volatility: eps = eps * (self.atr[fut] / 100) riskfac = math.exp(eps) bbo = self.get_bbo(fut) bid_mkt = bbo['bid'] ask_mkt = bbo['ask'] mid = 0.5 * (bbo['bid'] + bbo['ask']) mid_mkt = 0.5 * (bid_mkt + ask_mkt) contract = fut if contract == 'BTC/USD': ords = self.ws['XBTUSD'].open_orders('') else: ords = self.ws[contract].open_orders('') cancel_oids = [] bid_ords = ask_ords = [] if place_bids: #print(ords) bid_ords = [o for o in ords if o['side'] == 'Buy'] len_bid_ords = min(len(bid_ords), nbids) bid0 = mid_mkt * math.exp(-MKT_IMPACT) bids = [bid0 * riskfac**-i for i in range(1, nbids + 1)] if math.isnan(bids[0]): bbo = self.get_bbo(fut) for i in range(0, MAX_LAYERS): bids[i] = ticksize_floor(bbo['bid'], tsz) bids[0] = ticksize_floor(bids[0], tsz) if place_asks: ask_ords = [o for o in ords if o['side'] == 'Sell'] len_ask_ords = min(len(ask_ords), nasks) ask0 = mid_mkt * math.exp(MKT_IMPACT) asks = [ask0 * riskfac**i for i in range(1, nasks + 1)] if math.isnan(asks[0]): bbo = self.get_bbo(fut) for i in range(0, MAX_LAYERS): asks[i] = ticksize_floor(bbo['ask'], tsz) asks[0] = ticksize_ceil(asks[0], tsz) for i in range(max(nbids, nasks)): # BIDS if place_bids and i < nbids: if i > 0: prc = ticksize_floor(min(bids[i], bids[i - 1] - tsz), tsz) else: prc = bids[0] qty = round(prc * qtybtc / con_sz) if 'ETH' in fut: qty = round(qty / 28.3 * 6) if 4 in self.quantity_switch: if self.diffdeltab[fut] > 0 or self.diffdeltab[fut] < 0: qty = round(qty / (self.diffdeltab[fut])) if 2 in self.quantity_switch: qty = round(qty * self.buysellsignal[fut]) if 3 in self.quantity_switch: qty = round(qty * (1 + self.multsShort[fut] / 100)) if 1 in self.quantity_switch: qty = round(qty / self.diff) if qty < 0: qty = qty * -1 if i < len_bid_ords: oid = bid_ords[i]['orderID'] #print(oid) try: fut2 = fut if fut is 'XBTUSD': fut2 = 'BTC/USD' if fut is 'ETHUSD': fut2 = 'ETH/USD' self.client.editOrder( oid, fut2, "Limit", bid_ords[i]['side'], qty, prc, {'execInst': 'ParticipateDoNotInitiate'}) except (SystemExit, KeyboardInterrupt): raise except Exception as e: print(e) else: try: fut2 = fut if fut is 'XBTUSD': fut2 = 'BTC/USD' if fut is 'ETHUSD': fut2 = 'ETH/USD' self.client.createOrder( fut2, "Limit", 'buy', qty, prc, {'execInst': 'ParticipateDoNotInitiate'}) except (SystemExit, KeyboardInterrupt): raise except Exception as e: print(e) self.logger.warn( 'Bid order failed: %s bid for %s' % (prc, qty)) # OFFERS if place_asks and i < nasks: if i > 0: prc = ticksize_ceil(max(asks[i], asks[i - 1] + tsz), tsz) else: prc = asks[0] qty = round(prc * qtybtc / con_sz) if 'ETH' in fut: qty = round(qty / 28.3 * 6) if 4 in self.quantity_switch: if self.diffdeltab[fut] > 0 or self.diffdeltab[fut] < 0: qty = round(qty / (self.diffdeltab[fut])) if 2 in self.quantity_switch: qty = round(qty / self.buysellsignal[fut]) if 3 in self.quantity_switch: qty = round(qty * (1 + self.multsLong[fut] / 100)) if 1 in self.quantity_switch: qty = round(qty / self.diff) if qty < 0: qty = qty * -1 if i < len_ask_ords: oid = ask_ords[i]['orderID'] #print(oid) try: fut2 = fut if fut is 'XBTUSD': fut2 = 'BTC/USD' if fut is 'ETHUSD': fut2 = 'ETH/USD' self.client.editOrder( oid, fut2, "Limit", ask_ords[i]['side'], qty, prc, {'execInst': 'ParticipateDoNotInitiate'}) except (SystemExit, KeyboardInterrupt): raise except Exception as e: print(e) else: try: fut2 = fut if fut is 'XBTUSD': fut2 = 'BTC/USD' if fut is 'ETHUSD': fut2 = 'ETH/USD' self.client.createOrder( fut2, "Limit", 'sell', qty, prc, {'execInst': 'ParticipateDoNotInitiate'}) except (SystemExit, KeyboardInterrupt): raise except Exception as e: self.logger.warn('Offer order failed: %s at %s' % (qty, prc))
def get_bbo(self, contract): # Get best b/o excluding own orders vwap = {} ohlcv2 = {} fut2 = contract if contract is 'XBTUSD': fut2 = 'BTC/USD' if contract is 'ETHUSD': fut2 = 'ETH/USD' now = datetime.now() format_iso_now = now.isoformat() then = now - timedelta(minutes=100) format_later_iso = then.isoformat() thetime = then.strftime('%Y-%m-%dT%H:%M:%S') ohlcv = self.client.fetchOHLCV(fut2, '1m', self.client.parse8601(thetime)) ohlcv2 = [] for o in ohlcv: ohlcv2.append([o[1], o[2], o[3], o[4], o[5]]) df = pd.DataFrame(ohlcv2, columns=['open', 'high', 'low', 'close', 'volume']) best_bids = [] best_asks = [] if 1 in self.directional: #print(df) try: self.dsrsi = TA.STOCHRSI(df).iloc[-1] * 100 except: self.dsrsi = 50 #print(self.dsrsi) # Get orderbook if 2 in self.volatility or 3 in self.price or 4 in self.quantity_switch: self.bands[fut2] = TA.BBANDS(df).iloc[-1] self.bbw[fut2] = (TA.BBWIDTH(df).iloc[-1]) print( float(self.bands[fut2]['BB_UPPER'] - self.bands[fut2]['BB_LOWER'])) if (float(self.bands[fut2]['BB_UPPER'] - self.bands[fut2]['BB_LOWER'])) > 0: deltab = (self.get_spot() - self.bands[fut2]['BB_LOWER']) / ( self.bands[fut2]['BB_UPPER'] - self.bands[fut2]['BB_LOWER']) if deltab > 50: self.diffdeltab[fut2] = (deltab - 50) / 100 + 1 if deltab < 50: self.diffdeltab[fut2] = (50 - deltab) / 100 + 1 else: self.diffdeltab[fut2] = 25 / 100 + 1 if 3 in self.volatility: self.atr[fut2] = TA.ATR(df).iloc[-1] if 0 in self.price: # Get orderbook if contract == 'BTC/USD': ob = self.ws['XBTUSD'].market_depth() else: ob = self.ws[contract].market_depth() #ob = self.client.fetchOrderBook( contract ) #print(ob) bids = [] asks = [] for o in ob: if o['side'] == 'Sell': bids.append([o['price'], o['size']]) else: asks.append([o['price'], o['size']]) if contract == 'BTC/USD': ords = self.ws['XBTUSD'].open_orders('') else: ords = self.ws[contract].open_orders('') #print(ords) bid_ords = [o for o in ords if o['side'] == 'Buy'] ask_ords = [o for o in ords if o['side'] == 'Sell'] best_bid = None best_ask = None err = 10**-(self.get_precision(contract) + 1) best_bid = 9999999999999999999 for a in bids: if a[0] < best_bid: best_bid = a[0] best_ask = 0 for a in asks: if a[0] > best_ask: best_ask = a[0] print({'bid': best_bid, 'ask': best_ask}) best_asks.append(best_ask) best_bids.append(best_bid) if 1 in self.price: dvwap = TA.VWAP(df) #print(dvwap) tsz = self.get_ticksize(contract) try: bid = ticksize_floor(dvwap.iloc[-1], tsz) ask = ticksize_ceil(dvwap.iloc[-1], tsz) except: bid = ticksize_floor(self.get_spot(), tsz) ask = ticksize_ceil(self.get_spot(), tsz) print({'bid': bid, 'ask': ask}) best_asks.append(best_ask) best_bids.append(best_bid) if 2 in self.quantity_switch: dppo = TA.PPO(df) self.buysellsignal[fut2] = 1 try: if (dppo.iloc[-1].PPO > 0): self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 + PRICE_MOD) else: self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 - PRICE_MOD) if (dppo.iloc[-1].HISTO > 0): self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 + PRICE_MOD) else: self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 - PRICE_MOD) if (dppo.iloc[-1].SIGNAL > 0): self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 + PRICE_MOD) else: self.buysellsignal[fut2] = self.buysellsignal[fut2] * ( 1 - PRICE_MOD) except: self.buysellsignal[fut2] = 1 #print({ 'bid': best_bid, 'ask': best_ask }) return { 'bid': self.cal_average(best_bids), 'ask': self.cal_average(best_asks) }