コード例 #1
0
 def bbtInit(self):
   self.api = cl.bbCCXTInit(n=self.n)
   riskDf = cl.bbtGetRiskDf(self.api, self.spotDict)
   for ccy in self.validCcys:
     if ccy in riskDf.index:
       self.futures.loc[ccy, 'FutDelta']=cl.bbtGetFutPos(self.api,ccy)
       self.liqDict[ccy] = riskDf.loc[ccy,'liq']
     else:
       self.liqDict[ccy] = 0
   self.calcFuturesDeltaUSD()
   #####
   if self.n>=2: # trim list for auxiliary BBTs
     self.validCcys=list(self.futures.index[self.futures['FutDelta'] != 0])
   #####
   self.oneDayIncome = 0
   self.prevIncome = 0
   if CR_CONFIGS_DICT['IS_CALC_PAYMENTS']:
     pmts=pd.DataFrame()
     for ccy in self.validCcys:
       data = cl.bbtGetTradeExecutionList(self.api,ccy)
       if not data is None:
         pmts = pmts.append(pd.DataFrame(data).set_index('symbol', drop=False))
     if len(pmts)>0:
       cl.dfSetFloat(pmts, ['fee_rate', 'exec_fee'])
       pmts.loc[['Sell' in z for z in pmts['order_id']],'fee_rate']*=-1 # Correction for fee_rate signs
       pmts['incomeUSD'] = -pmts['exec_fee'] * self.spotDict['USDT']
       pmts['date'] = [datetime.datetime.fromtimestamp(int(ts) / 1000) for ts in pmts['trade_time_ms']]
       pmts = pmts.set_index('date').sort_index()
       #####
       self.oneDayIncome = pmts['incomeUSD'].sum()
       self.prevIncome = pmts.loc[pmts.index[-1]]['incomeUSD'].sum()
   self.setAnnRets()
   #####
   usdtDict=self.api.v2_private_get_wallet_balance({'coin': 'USDT'})['result']['USDT']
   equity = float(usdtDict['equity'])
   self.nav = equity * self.spotDict['USDT']
   self.spots.loc['USDT', 'SpotDelta'] = equity
   self.calcSpotDeltaUSD()
   #####
   for ccy in self.validCcys:
     oneDayFunding = 0
     prevFunding = 0
     estFunding=0
     estFunding2=0
     if CR_CONFIGS_DICT['IS_CALC_PAYMENTS']:
       if len(pmts)>0:
         df=pmts.loc[pmts['symbol']==ccy+'USDT','fee_rate']
         if len(df) > 0:
           oneDayFunding = df.mean() * 3 * 365
           prevFunding = df[df.index[-1]].mean() * 3 * 365
     #####
     if CR_CONFIGS_DICT['IS_CALC_ESTS']:
       estFunding, estFunding2 = self.bbtGetEstFundings_fast(ccy)
     self.makeFundingStr(ccy, oneDayFunding, prevFunding, estFunding, estFunding2)
   #####
   self.makeIncomesStr()
   self.makeLiqStr(riskDf=riskDf,availableBalance=float(usdtDict['available_balance']))
   self.isDone = True
コード例 #2
0
                if max_size > position_value:
                    select_id = int(risk['id'])
                    select_lev = float(risk['max_leverage'])
                    if int(pos['risk_id']) != select_id:
                        api.v2_private_post_position_risk_limit({
                            'symbol':
                            sym,
                            'risk_id':
                            select_id
                        })
                    if lev < select_lev:
                        api.v2_private_post_position_leverage_save({
                            'symbol':
                            sym,
                            'leverage':
                            select_lev,
                            'leverage_only':
                            True
                        })
                    print(
                        f'{sym} {position_value:,.0f} -> Risk limit ({max_size:,.0f})  Leverage ({select_lev})'
                    )
                    break


######
# Main
######
cl.printHeader('BBAutoRiskLimit - ' + cl.getCurrentTime())
bb = cl.bbCCXTInit()
BB_AutoRiskLimit(bb, sym_list)
コード例 #3
0
ファイル: BBTWhatIf.py プロジェクト: eonsmile/CryptoTools
  for i in range(-100, 100):
    additional = i * 5000
    df['unrealised_pnl_sim'] = df['unrealised_pnl'] + df['delta_value'] * (tgtLiqH - 1)
    df['ab_delta'] = df['unrealised_pnl_sim'].clip(None, 0) - df['unrealised_pnl'].clip(None, 0)
    ab = availableBalance + additional + df['ab_delta'].sum()
    df['cushion'] = ab + df['im_value'] - df['mm_value'] + df['unrealised_pnl_sim'].clip(0, None)
    if df['cushion'].min() > 0:
      return additional # -ve = money can leave account
  return 0

######
# Init
######
apiDict=cl.getApiDict()
spotDict=dict()
spotDict['USDT']=cl.ftxGetMid(apiDict['ftx'],'USDT/USD')
#####
riskDfs = []
for i in range(SHARED_EXCH_DICT['bbt']):
  riskDfs.append(cl.bbtGetRiskDfs(i + 1, spotDict))
cl.parallelRun(riskDfs)

######
# Main
######
for i in range(SHARED_EXCH_DICT['bbt']):
  cl.printHeader('BBT' + str(i + 1))
  usdtDict=cl.bbCCXTInit(i+1).v2_private_get_wallet_balance({'coin': 'USDT'})['result']['USDT']
  print('Adjustment = ',str(bbtGetAdj(riskDfs[0].riskDf, float(usdtDict['available_balance']), tgtLiqH)))

コード例 #4
0
                            if lev[side] < select_lev:
                                api.private_linear_post_position_set_leverage({
                                    'symbol':
                                    sym,
                                    side.lower() + '_leverage':
                                    select_lev,
                                    opp_side.lower() + '_leverage':
                                    lev[opp_side]
                                })
                                isMod = True
                            if isMod:
                                print(
                                    f'{sym} {position_value:,.0f} -> Risk limit ({max_size:,.0f})  Leverage ({select_lev})'
                                )
                            break


######
# Init
######
cl.printHeader('BBTAutoRiskLimit - ' + cl.getCurrentTime())
apiDict = cl.getApiDict()
spotDict = dict()
spotDict['USDT'] = cl.ftxGetMid(apiDict['ftx'], 'USDT/USD')

# Traditional
for i in range(SHARED_EXCH_DICT['bbt']):
    cl.printHeader('BBT' + str(i + 1))
    bb = cl.bbCCXTInit(i + 1)
    df = cl.bbtGetRiskDf(bb, spotDict)
    autoRiskLimit(bb, df.index)
コード例 #5
0
def bbtCrossOrder(bbNB, bbNS, ccy, trade_qty, distance=0):
  @retry(wait_fixed=1000, stop_max_attempt_number=SHARED_ETC_DICT['RETRY_MAX_ATTEMPTS'])
  def getSymbols(bb):
    return pd.DataFrame(bb.v2PublicGetSymbols()['result']).set_index('name')
  ######
  @retry(wait_fixed=1000, stop_max_attempt_number=SHARED_ETC_DICT['RETRY_MAX_ATTEMPTS'])
  def getData(bb, ticker):
    return bb.v2PublicGetTickers({'symbol': ticker})['result'][0]
  ######
  # Do not use @retry
  def getIsReduceOnly(bb, ticker, side, qty):
    df = pd.DataFrame(bb.private_linear_get_position_list({'symbol': ticker})['result']).set_index('side')
    oppSide = 'Sell' if side == 'BUY' else 'Buy'
    return qty <= float(df.loc[oppSide, 'size'])
  #####
  # Do not use @retry
  def placeOrder(bb, ticker, side, qty, limitPrice):
    return bb.private_linear_post_order_create({'side': side.capitalize(), 'symbol': ticker, 'order_type': 'Limit', 'qty': qty, 'price': limitPrice, 'time_in_force': 'GoodTillCancel',
                                                'reduce_only': bool(getIsReduceOnly(bb, ticker, side, qty)), 'close_on_trigger': False})['result']['order_id']
  #####
  # Do not use @retry
  def cancelOrder(bb, ticker, orderId):
    try:
      bb.private_linear_post_order_cancel({'symbol': ticker, 'order_id': orderId})
    except:
      pass
  #####
  @retry(wait_fixed=1000, stop_max_attempt_number=SHARED_ETC_DICT['RETRY_MAX_ATTEMPTS'])
  def getOrder(bb, ticker, orderId):
    return bb.private_linear_get_order_search({'symbol': ticker, 'order_id': orderId})['result']
  #####
  # Do not use @retry
  def calcFill(orderStatus):
    filledSize = float(orderStatus['cum_exec_qty'])
    filledValue = float(orderStatus['cum_exec_value'])
    if filledSize == 0:
      return 0
    else:
      return filledValue / filledSize
  #####
  if bbNB==bbNS:
    print('Cannot cross against oneself!')
    sys.exit(1)
  bbB=cl.bbCCXTInit(bbNB)
  bbS=cl.bbCCXTInit(bbNS)
  ticker = ccy+'USDT'
  symbols = getSymbols(bbB)
  maxTradingQty=float(symbols.loc[ticker, 'lot_size_filter']['max_trading_qty'])
  qty = round(min(trade_qty,maxTradingQty), 3)
  data = getData(bbB, ticker)
  bid = float(data['bid_price'])
  ask = float(data['ask_price'])
  isUpTick = 'Plus' in data['last_tick_direction']
  limitPrice = ask if isUpTick else bid
  suffix1 = ' (qty=' + str(qty) + ') ....'
  suffix2 = '; price=' + str(limitPrice) + '] '
  if not isUpTick:
    print(cl.timeTag('Sending buy order in BBT' + str(bbNB) + suffix1))
    print(cl.timeTag('Sending sell order in BBT' + str(bbNS) + suffix1))
    buyOrderId = placeOrder(bbB, ticker, 'BUY', qty, limitPrice)
    sellOrderId = placeOrder(bbS, ticker, 'SELL', qty, limitPrice)
    print(cl.timeTag('[DEBUG: buyOrderId=' + buyOrderId + suffix2))
    print(cl.timeTag('[DEBUG: sellOrderId=' + sellOrderId + suffix2))
  else:
    print(cl.timeTag('Sending sell order in BBT' + str(bbNS) + suffix1))
    print(cl.timeTag('Sending buy order in BBT' + str(bbNB) + suffix1))
    sellOrderId = placeOrder(bbS, ticker, 'SELL', qty, limitPrice)
    buyOrderId = placeOrder(bbB, ticker, 'BUY', qty, limitPrice)
    print(cl.timeTag('[DEBUG: sellOrderId=' + sellOrderId + suffix2))
    print(cl.timeTag('[DEBUG: buyOrderId=' + buyOrderId + suffix2))
  time.sleep(3)
  cancelOrder(bbB, ticker, buyOrderId)
  cancelOrder(bbS, ticker, sellOrderId)
  buyOrderStatus = getOrder(bbB, ticker, buyOrderId)
  sellOrderStatus = getOrder(bbS, ticker, sellOrderId)
  leavesQtyB=qty-float(buyOrderStatus['cum_exec_qty'])
  leavesQtyS=qty-float(sellOrderStatus['cum_exec_qty'])

  # Fix rounding issues
  threshold=500
  if (leavesQtyB*limitPrice)<threshold: leavesQtyB=0
  if (leavesQtyS*limitPrice)<threshold: leavesQtyS=0

  fillB1 = calcFill(buyOrderStatus)
  fillS1 = calcFill(sellOrderStatus)
  if leavesQtyB==0 and leavesQtyS==0:
    print(cl.timeTag('[DEBUG: clean cross!]'))
    return 0 # zero slippage
  elif leavesQtyB>0 and leavesQtyS==0:
    fillB2=cl.bbtRelOrder('BUY',bbB,ccy,leavesQtyB,maxChases=888,distance=distance)
    fillBAvg=(fillB1*(qty-leavesQtyB) + fillB2*leavesQtyB)/qty
    fillSAvg=fillS1
  elif leavesQtyB==0 and leavesQtyS>0:
    fillS2 = cl.bbtRelOrder('SELL', bbS, ccy, leavesQtyS, maxChases=888, distance=distance)
    fillSAvg = (fillS1 * (qty - leavesQtyS) + fillS2 * leavesQtyS) / qty
    fillBAvg=fillB1
  else: # partial fills for both
    print('bbtCrossOrder abnormal termination!')
    sys.exit(1)
  return fillBAvg / fillSAvg - 1 # slippage
コード例 #6
0
ファイル: BBTr.py プロジェクト: eonsmile/CryptoTools
    self.label = self.ccy + ': ' + str(round(self.fDict['ftxEstFunding1'] * 100)) + '//' + \
                 str(round(self.fDict['bbtEstFunding1'] * 100)) + '/' + str(round(self.fDict['bbtEstFunding2'] * 100)) + \
                 '; sb=' + str(round(sbBps)) + \
                 '; yield=' + cl.fmtPct(self.yld, None)
    self.label += '; turn=$' + str(round(self.tickersDf.loc[self.ccy, 'turnover_24h'] / 1e6)) + 'M'
    if len(self.df) > 0:
      self.label += '; fut=$' + str(round(self.futDeltaUSD / 1000)) + 'K'
      if self.futDeltaUSD>0: color = 'red'
    self.label = termcolor.colored(self.label, color)

######
# Init
######
cl.printHeader('BBTr - '+cl.getCurrentTime())
apiDict=cl.getApiDict()
apiDict['bb']=cl.bbCCXTInit(2)
spotDict=dict()
spotDict['USDT']=cl.ftxGetMid(apiDict['ftx'],'USDT/USD')
#####
riskDfs = []
for i in range(SHARED_EXCH_DICT['bbt']):
  riskDfs.append(cl.bbtGetRiskDfs(i + 1, spotDict))
cl.parallelRun(riskDfs)
#####
ccys=[]
for i in range(SHARED_EXCH_DICT['bbt']):
  ccys.extend(list(riskDfs[i].riskDf.index))
#####
tickersDf = pd.DataFrame(apiDict['bb'].v2PublicGetTickers()['result']).set_index('symbol')
tickersDf = tickersDf[['USDT' in symbol for symbol in tickersDf.index]]
myList=[ticker[:len(ticker)-4] for ticker in tickersDf.index]
コード例 #7
0
 def bbInit(self):
   def getPayments(ccy):
     n = 0
     df = pd.DataFrame()
     while True:
       n += 1
       tl = self.api.v2_private_get_execution_list({'symbol': ccy + 'USD', 'start_time': cl.getYest() * 1000, 'limit': 1000, 'page': n})['result']['trade_list']
       if tl is None:
         break
       else:
         df = df.append(pd.DataFrame(tl))
     if len(df)==0:
       return None
     else:
       return df.set_index('symbol', drop=False)
   #####
   self.api = cl.bbCCXTInit()
   self.wallet=pd.DataFrame(self.api.v2_private_get_wallet_balance()['result']).transpose()
   cl.dfSetFloat(self.wallet,'equity')
   for ccy in self.validCcys:
     self.spots.loc[ccy,'SpotDelta']=self.wallet.loc[ccy,'equity']
   self.calcSpotDeltaUSD()
   #####
   futs = self.api.v2_private_get_position_list()['result']
   futs = pd.DataFrame([pos['data'] for pos in futs]).set_index('symbol')
   cl.dfSetFloat(futs, ['size','liq_price','position_value','unrealised_pnl'])
   for ccy in self.validCcys:
     ccy2=ccy+'USD'
     mult = -1 if futs.loc[ccy2,'side']=='Sell' else 1
     self.futures.loc[ccy, 'FutDelta'] = futs.loc[ccy2, 'size'] * mult / self.spotDict[ccy]
     self.liqDict[ccy] = futs.loc[ccy2,'liq_price'] / cl.bbGetMid(self.api,ccy)
   self.calcFuturesDeltaUSD()
   #####
   self.oneDayIncome=0
   self.prevIncome=0
   if CR_CONFIGS_DICT['IS_CALC_PAYMENTS']:
     pmts = pd.DataFrame()
     for ccy in self.validCcys:
       pmts = pmts.append(getPayments(ccy))
     if len(pmts)>0:
       pmts = pmts[pmts['exec_type'] == 'Funding'].copy()
       cl.dfSetFloat(pmts, ['fee_rate', 'exec_fee'])
       pmts.loc[['Sell' in z for z in pmts['order_id']],'fee_rate']*=-1 # Correction for fee_rate signs
       for ccy in self.validCcys:
         ccy2=ccy+'USD'
         if ccy2 in pmts.index: pmts.loc[ccy2, 'incomeUSD'] = -pmts.loc[ccy2, 'exec_fee'] * self.spotDict[ccy]
       pmts['date'] = [datetime.datetime.fromtimestamp(int(ts) / 1000) for ts in pmts['trade_time_ms']]
       pmts = pmts.set_index('date')
       #####
       if len(pmts)>0:
         self.oneDayIncome = pmts['incomeUSD'].sum()
         self.prevIncome = pmts.loc[pmts.index[-1]]['incomeUSD'].sum()
   self.setAnnRets()
   #####
   self.nav=self.spots['SpotDeltaUSD'].sum()
   #####
   for ccy in self.validCcys:
     oneDayFunding = 0
     prevFunding = 0
     estFunding = 0
     estFunding2 = 0
     if CR_CONFIGS_DICT['IS_CALC_PAYMENTS']:
       if len(pmts) > 0:
         df = pmts.loc[pmts['symbol'] == ccy + 'USD', 'fee_rate']
         if len(df) > 0:
           oneDayFunding = df.mean() * 3 * 365
           prevFunding = df[df.index[-1]].mean() * 3 * 365
     #####
     if CR_CONFIGS_DICT['IS_CALC_ESTS']:
       estFunding,estFunding2 = cl.bbGetEstFundings(self.api, ccy)
     self.makeFundingStr(ccy, oneDayFunding, prevFunding, estFunding, estFunding2)
   #####
   self.makeIncomesStr()
   self.isDone = True