Ejemplo n.º 1
0
 def __init__(self):
     self.Access_key = os.environ.get('Access_key', 'no')
     self.Access_secret = os.environ.get('Access_secret', 'no')
     self.contractCount = os.environ.get('count', 'no')
     self.client = RestClient(self.Access_key, self.Access_secret)
     self.frontMfuture = self.getFronFutureName()
     timestampim = self.getLastTradetimeToDate()
Ejemplo n.º 2
0
    def get(self, request):

        # Generate Deribit client
        client = RestClient(settings.DERIBIT_KEY, settings.DERIBIT_SECRET)

        print("Getting this thing")
        print(Instrument.objects.first().instrumentName)

        # Get instruments
        instruments = client.getinstruments()
        trade_list = client.getlasttrades(instruments[1]['instrumentName'])

        instruments_model = Instrument(**instruments[1])
        instruments_model.save()

        #trade_list = client.getlasttrades(Instrument.objects.get(id=827).instrumentName)

        print(trade_list)

        # Create instruments
        # TODO: Make use of bulk_create here
        for trade in trade_list:
            try:
                trade_model = Trade(**trade)
                trade_model.instrument = instrument_model
                trade_model.save()
            except Exception as e:
                # TODO: Integrate logger here
                print("Error while saving model")
                print(e)

        context = {'trade_list': Trade.objects.all()}
        return render(request, 'table_trade.html', context)
Ejemplo n.º 3
0
	def options():
		client = RestClient()
		call = "BTC-29DEC17-11000-C"
		put = "BTC-29DEC17-3000-P"
		myc = client.getsummary(call)
		myp = client.getsummary(put)
		result = str(myc['instrumentName']) + ": " + str(myc['bidPrice']) + "\n" + str(myp['instrumentName']) + ": " + str(myp['bidPrice'])
		return result
Ejemplo n.º 4
0
 def __init__(self, interest_rate=0, K_range=(0, math.inf)):
     # this is my account. Don't share it to others. But I don't have money in it :P
     self.client = RestClient('2SQfDzW1Kaf3F', 'HOG2A2HCYERM2YONRBTYEBMYRZ2ESN3K')
     data = self.client.getsummary('future')
     # convert this list of dictionaries into data frame
     data = pd.DataFrame.from_dict(data=data)
     # split strings to get date and type
     data_tmp = data['instrumentName'].str.split('-')
     data['ExpirationDate'] = [data_tmp[i][1] for i in range(len(data))]
     data['ExpirationDate'] = pd.to_datetime(data['ExpirationDate'], format='%d%b%y')
     self.data = data
 def __init__(self,client_id = Tokens['Deribit']['Read_and_Write']['id'],client_secret = Tokens['Deribit']['Read_and_Write']['secret']):
     # Login read only account
     self.MyAccount = RestClient(client_id,client_secret)
     self.Fee = {
         'Future':{
                     'Market':0.00075,'Limit':-0.0025
                 },
         'Option':0.0004
     }
     self.Max_Order_Num = 3
     self.Trading_Frequency = 1
Ejemplo n.º 6
0
class current_index:
    """This class is used only for the main page to download the current index automatically"""
    def __init__(self, interest_rate=0, K_range=(0, math.inf)):
        # this is my account. Don't share it to others. But I don't have money in it :P
        self.client = RestClient('2SQfDzW1Kaf3F', 'HOG2A2HCYERM2YONRBTYEBMYRZ2ESN3K')

    def get_index(self):
        return self.client.index()['btc']
Ejemplo n.º 7
0
    def __init__(self):
        self.client = RestClient('', '')
        self.table = {}
        #self.logger = logging.getLogger('root')
        self.__reset()

        setup_logger(__name__, 'DeribitWebsocket.log')
        self.logger = logging.getLogger(__name__)

        # disable all loggers from different files
        logging.getLogger('asyncio').setLevel(logging.ERROR)
        logging.getLogger('asyncio.coroutines').setLevel(logging.ERROR)
        logging.getLogger('websockets.server').setLevel(logging.ERROR)
        logging.getLogger('websockets.protocol').setLevel(logging.ERROR)
        logging.getLogger('websocket-client').setLevel(logging.ERROR)

        requests_log = logging.getLogger("requests.packages.urllib3")
        requests_log.setLevel(logging.WARNING)
Ejemplo n.º 8
0
    def get(self, request):

        # Generate Deribit client
        client = RestClient(settings.DERIBIT_KEY, settings.DERIBIT_SECRET)
        # Get instruments
        instrument_list = client.getinstruments()

        # Create instruments
        # TODO: Make use of bulk_create here
        for instrument in instrument_list:
            try:
                instruments_model = Instrument(**instrument)
                instruments_model.save()

            except Exception as e:
                # TODO: Integrate logger here
                print("Error while saving model")

        context = {'instrument_list': Instrument.objects.all()}
        return render(request, 'table_instrument.html', context)
Ejemplo n.º 9
0
 def __init__(self, interest_rate=0, K_range=(0, math.inf)):
     # this is my account. Don't share it to others. But I don't have money in it :P
     self.client = RestClient('2SQfDzW1Kaf3F', 'HOG2A2HCYERM2YONRBTYEBMYRZ2ESN3K')
     self.rate = interest_rate
     self.index = self.client.index()['btc']
     # download option prices
     min_K, max_K = K_range
     data_tmp = self._download_option_price(min_K, max_K)
     data_on_index = data_tmp.loc[data_tmp['uIx'] == 'index_price', :]
     data = data_tmp.loc[data_tmp['uIx'] != 'index_price', :]
     # reindex
     data = data.dropna(axis=0)
     data_on_index = data_on_index.dropna(axis=0)
     data = data.reset_index()
     data_on_index = data_on_index.reset_index()
     # save data
     self.data = data
     self.data_on_index = data_on_index
     # calculate implied vol
     self.data['Implied_Vol'] = self.generate_implied_vol()
     self.future_data = self._download_future_price()
Ejemplo n.º 10
0
def main():
    start = datetime.now()
    mtype_count = {}
    client = RestClient(k, s)

    def on_message(ws, message):
        cur = datetime.now()
        since = cur - start
        #print (since)
        m = message
        j = json.loads(m)
        if "notifications" in j.keys():
            n = j["notifications"][0]
            mtype = n["message"]
            r = n["result"]
            instr = (r["instrument"])
            if instr not in mtype_count.keys():
                mtype_count[instr] = 0
            mtype_count[instr] += 1

            print (instr," ",mtype_count[instr]," ",since)
            print (n)

    def on_error(ws, error):
        print(error)

    def on_close(ws):
        print("### closed ###")

    def on_open(ws):
        data = {
            "id": 5533, 
            "action": "/api/v1/private/subscribe",  
            "arguments": {
                #"instrument": ["all"],
                #"instrument": ["BTC-PERPETUAL","BTC-28JUN19-13000-C"],
                "instrument": ["BTC-29MAR19-3000-C"],
                "event": ["order_book"] 
            }
        }
        data['sig'] = client.generate_signature(data['action'], data['arguments'])

        ws.send(json.dumps(data))

    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("wss://www.deribit.com/ws/api/v1/",
                              on_message = on_message,
                              on_error = on_error,
                              on_close = on_close)
    ws.on_open = on_open
    ws.run_forever()
Ejemplo n.º 11
0
class date_selection:
    """This class only output the future maturity dates.
    It is used as a light weight and fast data output"""
    def __init__(self, interest_rate=0, K_range=(0, math.inf)):
        # this is my account. Don't share it to others. But I don't have money in it :P
        self.client = RestClient('2SQfDzW1Kaf3F', 'HOG2A2HCYERM2YONRBTYEBMYRZ2ESN3K')
        data = self.client.getsummary('future')
        # convert this list of dictionaries into data frame
        data = pd.DataFrame.from_dict(data=data)
        # split strings to get date and type
        data_tmp = data['instrumentName'].str.split('-')
        data['ExpirationDate'] = [data_tmp[i][1] for i in range(len(data))]
        data['ExpirationDate'] = pd.to_datetime(data['ExpirationDate'], format='%d%b%y')
        self.data = data

    def get_date(self):
        dates = pd.Series.sort_values(self.data['ExpirationDate'])
        dates = dates.reset_index(drop=True)
        return dates
Ejemplo n.º 12
0
def main():
    client = RestClient(k, s)

    def on_message(ws, message):
        m = message
        n = m["notifications"]
        print(n[0]["message"])
        #print(message)

    def on_error(ws, error):
        print(error)

    def on_close(ws):
        print("### closed ###")

    def on_open(ws):
        data = {
            "id": 5533,
            "action": "/api/v1/private/subscribe",
            "arguments": {
                "instrument": ["all"],
                "event": ["order_book"]
            }
        }
        data['sig'] = client.generate_signature(data['action'],
                                                data['arguments'])

        ws.send(json.dumps(data))

    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("wss://www.deribit.com/ws/api/v1/",
                                on_message=on_message,
                                on_error=on_error,
                                on_close=on_close)
    ws.on_open = on_open
    ws.run_forever()
Ejemplo n.º 13
0
class MarketMaker( object ):
    
    def __init__( self, monitor = True, output = True ):
        self.longperp = None
        self.equity_usd         = None
        self.LEV_LIM = {}
        self.place_asks = {}
        self.place_bids = {}
        self.skew_size = {}
        self.LEV = 0
        self.IM = 0
        self.MAX_SKEW = 0
        self.equity_btc         = None
        self.equity_usd_init    = None
        self.equity_btc_init    = None
        self.con_size           = float( CONTRACT_SIZE )
        self.client             = None
        self.deltas             = OrderedDict()
        self.futures            = OrderedDict()
        self.futures_prv        = OrderedDict()
        self.logger             = None
        self.mean_looptime      = 1
        self.monitor            = monitor
        self.output             = output or monitor
        self.positions          = OrderedDict()
        self.spread_data        = None
        self.this_mtime         = None
        self.ts                 = None
        self.vols               = OrderedDict()
    
    
    def create_client( self ):
        self.client = RestClient( KEY, SECRET, URL )
    
    
    def get_bbo( self, contract ): # Get best b/o excluding own orders
        
        # Get orderbook
        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
        
        return { 'bid': best_bid, 'ask': best_ask }
    
        
    def get_futures( self ): # Get all current futures instruments
        
        self.futures_prv    = cp.deepcopy( self.futures )
        insts               = self.client.getinstruments()
        self.futures        = sort_by_key( { 
            i[ 'instrumentName' ]: i for i in insts  if i[ 'kind' ] == 'future'  and 'BTC' in i['instrumentName'] 
        } )
        
        for k, v in self.futures.items():
            self.futures[ k ][ 'expi_dt' ] = datetime.strptime( 
                                                v[ 'expiration' ][ : -4 ], 
                                                '%Y-%m-%d %H:%M:%S' )
                        
        
    def get_pct_delta( self ):         
        self.update_status()
        return sum( self.deltas.values()) / self.equity_btc

    
    def get_spot( self ):
        return self.client.index()[ 'btc' ]

    
    def get_precision( self, contract ):
        return self.futures[ contract ][ 'pricePrecision' ]

    
    def get_ticksize( self, contract ):
        return self.futures[ contract ][ 'tickSize' ]
    
    
    def output_status( self ):
        
        if not self.output:
            return None
        
        self.update_status()
        
        now     = datetime.utcnow()
        days    = ( now - self.start_time ).total_seconds() / SECONDS_IN_DAY
        #print( '********************************************************************' )
        #print( 'Start Time:        %s' % self.start_time.strftime( '%Y-%m-%d %H:%M:%S' ))
        #print( 'Current Time:      %s' % now.strftime( '%Y-%m-%d %H:%M:%S' ))
        #print( 'Days:              %s' % round( days, 1 ))
        #print( 'Hours:             %s' % round( days * 24, 1 ))
        #print( 'Spot Price:        %s' % self.get_spot())
        
        
        pnl_usd = self.equity_usd - self.equity_usd_init
        pnl_btc = self.equity_btc - self.equity_btc_init
        
        #print( 'Equity ($):        %7.2f'   % self.equity_usd)
        #print( 'P&L ($)            %7.2f'   % pnl_usd)
        #print( 'Equity (BTC):      %7.4f'   % self.equity_btc)
        #print( 'P&L (BTC)          %7.4f'   % pnl_btc)
        #print( '%% Delta:           %s%%'% round( self.get_pct_delta() / PCT, 1 ))
        #print( 'Total Delta (BTC): %s'   % round( sum( self.deltas.values()), 2 ))        
        print_dict_of_dicts( {
            k: {
                'BTC': self.deltas[ k ]
            } for k in self.deltas.keys()
            }, 
            roundto = 2, title = 'Deltas' )
        
        print_dict_of_dicts( {
            k: {
                'Contracts': self.positions[ k ][ 'size' ]
            } for k in self.positions.keys()
            }, 
            title = 'Positions' )
        
        if not self.monitor:
            print_dict_of_dicts( {
                k: {
                    '%': self.vols[ k ]
                } for k in self.vols.keys()
                }, 
                multiple = 100, title = 'Vols' )
            #print( '\nMean Loop Time: %s' % round( self.mean_looptime, 2 ))
            
        #print( '' )

        
    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 restart( self ):        
        try:
            strMsg = 'RESTARTING'
            #print( strMsg )
            self.client.cancelall()
            strMsg += ' '
            for i in range( 0, 5 ):
                strMsg += '.'
                #print( strMsg )
                sleep( 1 )
        except:
            pass
        finally:
            os.execv( sys.executable, [ sys.executable ] + sys.argv )        
            

    def run( self ):
        
        self.run_first()
        self.output_status()

        t_ts = t_out = t_loop = t_mtime = datetime.utcnow()

        while True:
            bbos = []
            arbs = {}
            #self.client.buy(  'BTC-PERPETUAL', size, mid * 1.02)
            expdays = {}
            for k in self.futures.keys():
                bbo  = self.get_bbo( k[0:3] + '-PERPETUAL' )
                bid_mkt = bbo[ 'bid' ]
                ask_mkt = bbo[ 'ask' ]
                mid = 0.5 * ( bbo[ 'bid' ] + bbo[ 'ask' ] )

                m = self.get_bbo(k)
                
                bid = m['bid']
                ask=m['ask']
                mid1 = 0.5 * (bid + ask)
                if k == 'ETHM20' or k == 'XRPM20':
                    mid1 = mid1 * self.get_spot()
                arb = mid1 / mid
                arbs[k] = float(arb)
                #if 'PERPETUAL' not in k:
                    ###print('perp is ' + str(mid) + ' ' + k + ' is ' + str(mid1) + ' and arb is ' + str(arb)  + ' positive is sell negative is bbuy')
                
                expsecs = (self.futures[k]['expi_dt'] - datetime.now()).total_seconds()
                
                expday = expsecs / 60 / 24
                expdays[k]=float(expday)
                bbos.append({k: mid1 - self.get_spot()})
            fundvsprem = {}
            newarbs = {}
            self.arbmult = {}
            for k in arbs:
                if 'PERPETUAL' not in k:
                    doin = ((-1*(1-arbs[k]) / expdays[k])* 100) 
                    ###print(k[0:3])
                    #print(k + '! Premium arb is ' + str(math.fabs(doin)) + ' %!')
                    fundvsprem[k] = 'premium'
                    newarbs[k] = doin
                    self.arbmult[k] = {}
            arbs = newarbs

                
            for token in arbs:
                
                if arbs[token] < 0:
                    self.arbmult[token] = ({'coin': token, 'long': 'futs', 'short': 'perp', 'arb': (arbs[token])})
                else:
                    self.arbmult[token] = ({'coin': token, 'long': 'perp', 'short': 'futs', 'arb': (arbs[token])})
            #funding: {'ETH': {'coin': 'ETH', 'long': 'futs', 'short': 'perp', 'arb': -0.00030000000000000003}, 'XBT': {'coin': 'XBT', 'long': 'perp', 'short': 'futs', 'arb': 0.000153}, 'XRP': {'coin': 'XRP', 'long': 'futs', 'short': 'perp', 'arb': -0.0007440000000000001}}
            #premium: {'ETH': {'coin': 'ETH', 'long': 'futs', 'short': 'perp', 'arb': -0.00013291636050582245}, 'XBT': {'coin': 'XBT', 'long': 'perp', 'short': 'futs', 'arb': 3.722894995661838e-05}, 'XRP': {'coin': 'XRP', 'long': 'futs', 'short': 'perp', 'arb': -6.462857850516617e-05}}
            perplongs = 0
            perpshorts = 0
            for arb in self.arbmult:
                if self.arbmult[arb]['long'] == 'perp':
                    perplongs = perplongs + 1
                else:
                    perpshorts = perpshorts + 1
            if perplongs >= perpshorts:
                self.longperp = True
                self.arbmult['BTC-PERPETUAL'] = ({'coin': 'BTC-PERPETUAL', 'long': 'perp', 'short': 'futs', 'arb': 0.5})
            else:
                self.longperp = False
                self.arbmult['BTC-PERPETUAL'] = ({'coin': 'BTC-PERPETUAL', 'long': 'futs', 'short': 'perp', 'arb': -0.5})
            #print('self.longpperp? ' + str(self.longperp))
            #print(self.arbmult)
            t = 0
            c = 0
            for arb in self.arbmult:
                t = t + math.fabs(self.arbmult[arb]['arb'])

                c = c + 1
            #print('t: ' + str(t))
            
            for arb in self.arbmult:
                self.arbmult[arb]['perc'] = math.fabs(round((self.arbmult[arb]['arb']) / t * 1000) / 1000) #* 1.41425
                
            #print(self.arbmult)
            ##print(self.arbmult)
            for coin in arbs:
                self.LEV_LIM[coin] = LEVERAGE_MAX / 2
            for coin in arbs:
                self.LEV_LIM[coin] = self.LEV_LIM[coin] * self.arbmult[coin]['perc'] 
                
            self.LEV_LIM['BTC-PERPETUAL'] = LEVERAGE_MAX / 2
            #print(self.LEV_LIM)
            skewingpos = 0
            skewingneg = 0
            positionSize = 0
            for p in self.positions:
                positionSize = positionSize + self.positions[p]['size']
                if self.positions[p]['size'] > 0:
                    skewingpos = skewingpos + 1
                elif self.positions[p]['size'] < 0:
                    skewingneg = skewingneg + 1
            self.get_futures()
            
            # Restart if a new contract is listed
            if len( self.futures ) != len( self.futures_prv ):
                self.restart()
            
            self.update_positions()
            
            t_now   = datetime.utcnow()
            
            # Update time series and vols
            if ( t_now - t_ts ).total_seconds() >= WAVELEN_TS:
                t_ts = t_now
                self.update_timeseries()
                self.update_vols()
    
            self.place_orders()
            
            # Display status to terminal
            if self.output:    
                t_now   = datetime.utcnow()
                if ( t_now - t_out ).total_seconds() >= WAVELEN_OUT:
                    self.output_status(); t_out = t_now
            
            # Restart if file change detected
            t_now   = datetime.utcnow()
            if ( t_now - t_mtime ).total_seconds() > WAVELEN_MTIME_CHK:
                t_mtime = t_now
                if getmtime( __file__ ) > self.this_mtime:
                    self.restart()
            
            t_now       = datetime.utcnow()
            looptime    = ( t_now - t_loop ).total_seconds()
            
            # Estimate mean looptime
            w1  = EWMA_WGT_LOOPTIME
            w2  = 1.0 - w1
            t1  = looptime
            t2  = self.mean_looptime
            
            self.mean_looptime = w1 * t1 + w2 * t2
            
            t_loop      = t_now
            sleep_time  = MIN_LOOP_TIME - looptime
            if sleep_time > 0:
                time.sleep( sleep_time )
            if self.monitor:
                time.sleep( WAVELEN_OUT )

            
    def run_first( self ):
        
        self.create_client()
        self.client.cancelall()
        self.logger = get_logger( 'root', LOG_LEVEL )
        # Get all futures contracts
        self.get_futures()
        self.this_mtime = getmtime( __file__ )
        self.symbols    = [ BTC_SYMBOL ] + list( self.futures.keys()); self.symbols.sort()
        self.deltas     = OrderedDict( { s: None for s in self.symbols } )
        
        # Create historical time series data for estimating vol
        ts_keys = self.symbols + [ 'timestamp' ]; ts_keys.sort()
        
        self.ts = [
            OrderedDict( { f: None for f in ts_keys } ) for i in range( NLAGS + 1 )
        ]
        
        self.vols   = OrderedDict( { s: VOL_PRIOR for s in self.symbols } )
        
        self.start_time         = datetime.utcnow()
        self.update_status()
        self.equity_usd_init    = self.equity_usd
        self.equity_btc_init    = self.equity_btc
    
    
    def update_status( self ):
        
        account = self.client.account()
        spot    = self.get_spot()

        self.equity_btc = account[ 'equity' ]
        self.equity_usd = self.equity_btc * spot
                
        self.update_positions()
                
        self.deltas = OrderedDict( 
            { k: self.positions[ k ][ 'sizeBtc' ] for k in self.futures.keys()}
        )
        self.deltas[ BTC_SYMBOL ] = account[ 'equity' ]        
        
        
    def update_positions( self ):

        self.positions  = OrderedDict( { f: {
            'size':         0,
            'sizeBtc':      0,
            'indexPrice':   None,
            'markPrice':    None
        } for f in self.futures.keys() } )
        positions       = self.client.positions()
        
        for pos in positions:
            if pos[ 'instrument' ] in self.futures:
                self.positions[ pos[ 'instrument' ]] = pos
        
    
    def update_timeseries( self ):
        
        if self.monitor:
            return None
        
        for t in range( NLAGS, 0, -1 ):
            self.ts[ t ]    = cp.deepcopy( self.ts[ t - 1 ] )
        
        spot                    = self.get_spot()
        self.ts[ 0 ][ BTC_SYMBOL ]    = spot
       
        for c in self.futures.keys():
            
            bbo = self.get_bbo( c )
            bid = bbo[ 'bid' ]
            ask = bbo[ 'ask' ]

            if not bid is None and not ask is None:
                mid = 0.5 * ( bbo[ 'bid' ] + bbo[ 'ask' ] )
            else:
                continue
            self.ts[ 0 ][ c ]               = mid
                
        self.ts[ 0 ][ 'timestamp' ]  = datetime.utcnow()

        
    def update_vols( self ):
        
        if self.monitor:
            return None
        
        w   = EWMA_WGT_COV
        ts  = self.ts
        
        t   = [ ts[ i ][ 'timestamp' ] for i in range( NLAGS + 1 ) ]
        p   = { c: None for c in self.vols.keys() }
        for c in ts[ 0 ].keys():
            p[ c ] = [ ts[ i ][ c ] for i in range( NLAGS + 1 ) ]
        
        if any( x is None for x in t ):
            return None
        for c in self.vols.keys():
            if any( x is None for x in p[ c ] ):
                return None
        
        NSECS   = SECONDS_IN_YEAR
        cov_cap = COV_RETURN_CAP / NSECS
        
        for s in self.vols.keys():
            
            x   = p[ s ]            
            dx  = x[ 0 ] / x[ 1 ] - 1
            dt  = ( t[ 0 ] - t[ 1 ] ).total_seconds()
            v   = min( dx ** 2 / dt, cov_cap ) * NSECS
            v   = w * v + ( 1 - w ) * self.vols[ s ] ** 2
            
            self.vols[ s ] = math.sqrt( v )
Ejemplo n.º 14
0
 def create_client( self ):
     self.client = RestClient( KEY, SECRET, URL )
Ejemplo n.º 15
0
def checkPrice(apikey, from_email, price_window, period_modifier, period_label, pricefreq, cooldown): 
    try:
        #read csv file with recent prices
        pricedf = pd.read_csv('btcprices.csv', index_col=0)
       
        #get current price from api
        client = RestClient()
        index = client.index()
        price = index['btc']       

        #add new price to dataframe
        newprice = {'price' : price}
        newpricedf = pd.DataFrame(newprice, index=[datetime.utcnow()])
        pricedf = pricedf.append(newpricedf)
        

        #keep only last 60 prices
        if len(pricedf) > price_window:
            pricedf.drop(pricedf.index[0], inplace=True)
        length = len(pricedf)
        
        #write out to csv
        pricedf.to_csv('btcprices.csv')
        
        #initialize variables
        maxchng = 0
        periods = 0
        direction = ""
        
        #collect at least 3 datapoints before calculating 
        if len(pricedf) < 4:
            print("----------More data needed for accurate results")
        else:
            #calculate max price change
            for i in range(-2, -length, -1):
                chng = (pricedf["price"].iloc[-1] - pricedf["price"].iloc[i]) / pricedf["price"].iloc[i]
                if abs(chng) > abs(maxchng):
                    maxchng = chng
                    periods = -i -1
            
            #make percentage
            maxchng = maxchng * 100
            
            #assign direction of price change
            if maxchng > 0:
                direction = "up"
            elif maxchng < 0:
                direction = "down"
            
            #round percentage
            maxchng = round( abs(maxchng), 2)
            
            #modify label when appropriate
            if periods == 1 and period_label == "minutes":
                period_label = period_label[:-1]
            if period_label == "seconds" and periods * period_modifier > 119:
                period_label = "minutes"
                period_modifier = pricefreq/60
                
            #print results    
            print("----------The price has gone ", direction, " ", maxchng, "% in the past ", '%.0f' % (periods * period_modifier), " ", period_label, ".", sep="")
        
            #check and send mail if price changes sufficiently
            if maxchng > 30:
                priceMailer(apikey, from_email, 30, periods, maxchng, direction, period_modifier, period_label, cooldown)
            elif maxchng > 25:
                priceMailer(apikey, from_email, 25, periods, maxchng, direction, period_modifier, period_label, cooldown)
            elif maxchng > 20:
                priceMailer(apikey, from_email, 20, periods, maxchng, direction, period_modifier, period_label, cooldown)
            elif maxchng > 15:
                priceMailer(apikey, from_email, 15, periods, maxchng, direction, period_modifier, period_label, cooldown)
            elif maxchng > 10:
                priceMailer(apikey, from_email, 10, periods, maxchng, direction, period_modifier, period_label, cooldown)
            elif maxchng > 5:
                priceMailer(apikey, from_email, 5, periods, maxchng, direction, period_modifier, period_label, cooldown)
                
    except (IOError, OSError):
        print("----------Error: btcprices.csv could not be found or is corrupted.")
        print("----------Creating new file....")
        
        #get current price from api
        client = RestClient()
        index = client.index()
        price = index['btc']   
        
        #create new dataframe and csv
        newdf = {'price' : price}
        pricedf = pd.DataFrame(newdf, index=[datetime.utcnow()])
        pricedf.to_csv('btcprices.csv')
        print("----------New file created.")
    
    except Exception as e:
        print(e)
        
Ejemplo n.º 16
0
def main():

    client = RestClient("CSNAPH9dfTzg", "JGDPSFIQFZXNGROTOVTKW3RXBFWPNHA2")
    client.i = 0

    # get existing instruments
    instruments = {i.ticker: i.id for i in Instrument.select()}

    # create a loop in case we get disconnected
    def on_message(ws, message):
        if message == '{"id":-1,"result":"pong"}':
            return

        client.i = client.i + 1
        try:
            data = json.loads(message)
        except:
            return

        if 'notifications' not in data:
            return

        ms_out = data['msOut']
        for n in data['notifications']:
            if n['message'] != 'order_book_event':
                continue

            result = n['result']
            instrument_name = result['instrument']
            if instrument_name in instruments:
                instrument = instruments[instrument_name]
            else:
                instrument = Instrument.create(ticker=instrument_name)
                instruments[instrument_name] = instrument
            update = OrderBookUpdate.create(ms_out=ms_out,
                                            instrument=instrument)
            summary = Summary.create(high=float_or_m1(result['high']),
                                     low=float_or_m1(result['low']),
                                     last=float_or_m1(result['last']),
                                     update=update)
            for bid in result['bids']:
                ob_entry = OrderBook.create(is_bid=True,
                                            cm=bid['cm'],
                                            price=bid['price'],
                                            qty=bid['quantity'],
                                            update=update)
            for ask in result['bids']:
                ob_entry = OrderBook.create(is_bid=False,
                                            cm=ask['cm'],
                                            price=ask['price'],
                                            qty=ask['quantity'],
                                            update=update)

        if client.i % 100 == 0:
            data = {'id': -1, 'action': '/api/v1/public/ping', 'arguments': {}}
            data['sig'] = client.generate_signature(data['action'],
                                                    data['arguments'])
            ws.send(json.dumps(data))

    def on_error(ws, error):
        print(error)

    def on_close(ws):
        print('subscription closed!')

    def on_open(ws):
        data = {
            "id": 5533,
            "action": "/api/v1/private/subscribe",
            "arguments": {
                "instrument": ["options"],
                "event": ["order_book"]
            }
        }
        data['sig'] = client.generate_signature(data['action'],
                                                data['arguments'])

        ws.send(json.dumps(data))

    # websocket.enableTrace(True)
    ws = websocket.WebSocketApp("wss://www.deribit.com/ws/api/v1/",
                                on_message=on_message,
                                on_error=on_error,
                                on_close=on_close)
    ws.on_open = on_open  # not sure why this was on another line, it was like this in the example
    ws.run_forever()
Ejemplo n.º 17
0
class myDERIBIT:
    Access_key = "no"
    Access_secret = "no"
    client = 0
    frontMfuture = 0
    lastInfo = 'nothing yet'
    killDeribitThread = False
    contractCount = str(1)
    timeLeft = 500 * 60
    emailSentTime = 5

    def __init__(self):
        self.Access_key = os.environ.get('Access_key', 'no')
        self.Access_secret = os.environ.get('Access_secret', 'no')
        self.contractCount = os.environ.get('count', 'no')
        self.client = RestClient(self.Access_key, self.Access_secret)
        self.frontMfuture = self.getFronFutureName()
        timestampim = self.getLastTradetimeToDate()

    def ClosePosition(self, posParams, direction):
        closeDirection = 0
        if direction == 'buy':
            closeDirection = 'sell'
        elif direction == 'sell':
            closeDirection = 'buy'
        self.BuyOrSellMarket(posParams, closeDirection)

    def BuyOrSellMarket(self, posParams, direction):
        response = 0
        posParams['type'] = 'market'
        posParams['price'] = ''

        if direction == 'buy':
            try:
                response = self.client.buy(posParams['instrument'],
                                           posParams['quantity'],
                                           posParams['price'])
            except Exception:
                nonce = int(time.time() * 1000)
                signature = self.deribit_signature(nonce,
                                                   '/api/v1/private/buy',
                                                   posParams, self.Access_key,
                                                   self.Access_secret)
                response = self.client.session.post(
                    'https://www.deribit.com' + '/api/v1/private/buy',
                    data=posParams,
                    headers={'x-deribit-sig': signature},
                    verify=True)
        elif direction == 'sell':
            try:
                self.client.sell(posParams['instrument'],
                                 posParams['quantity'], posParams['price'])
            except Exception:
                nonce = int(time.time() * 1000)
                signature = self.deribit_signature(nonce,
                                                   '/api/v1/private/sell',
                                                   posParams, self.Access_key,
                                                   self.Access_secret)
                response = self.client.session.post(
                    'https://www.deribit.com' + '/api/v1/private/sell',
                    data=posParams,
                    headers={'x-deribit-sig': signature},
                    verify=True)

    def getPositionsWithSlippage(self):
        posParams = {}
        posJson = 0
        direction = 0
        try:
            posJson = self.value(self.client.positions())
        except Exception:
            nonce = int(time.time() * 1000)
            signature = self.deribit_signature(nonce,
                                               '/api/v1/private/positions',
                                               posParams, self.Access_key,
                                               self.Access_secret)
            response = self.client.session.post(
                'https://www.deribit.com' + '/api/v1/private/positions',
                data=posParams,
                headers={'x-deribit-sig': signature},
                verify=True)
            posJson = self.value(response.json())['result']

        if posJson.empty:
            direction = 0
        else:
            posParams['instrument'] = str(posJson['instrument'][0])
            direction = str(posJson['direction'][0])
            posParams['quantity'] = str(abs(posJson['size'][0]))
            if direction == 'buy':
                posParams['price'] = str(posJson['markPrice'][0] - 5)
            elif direction == 'sell':
                posParams['price'] = str(posJson['markPrice'][0] + 5)
        return posParams, direction

    def deribit_signature(self, nonce, uri, params, access_key, access_secret):
        sign = '_=%s&_ackey=%s&_acsec=%s&_action=%s' % (nonce, access_key,
                                                        access_secret, uri)
        for key in sorted(params.keys()):
            sign += '&' + key + '=' + "".join(params[key])
        return '%s.%s.%s' % (access_key, nonce,
                             base64.b64encode(hashlib.sha256(sign).digest()))

    def value(self, df):
        return json_normalize(df)

    def getFronFutureName(self):
        instruments = self.client.getinstruments()
        instruments0 = json_normalize(instruments)
        instruments0 = pd.DataFrame.from_dict(instruments)
        futures = instruments0[instruments0['kind'].str.contains("uture")]
        frontMfuture = futures.iloc[0]['instrumentName']
        now = datetime.datetime.now()
        for i in xrange(len(futures)):
            notPERPETUAL = 'PERPETUAL' not in futures.iloc[i]['instrumentName']
            yearDif = int(futures.iloc[i]['expiration'][0:4]) - int(now.year)
            monthDif = int(futures.iloc[i]['expiration'][5:7]) - int(now.month)
            dayDif = int(futures.iloc[i]['expiration'][8:10]) - int(now.day)
            if notPERPETUAL and yearDif == 1:
                frontMfuture = futures.iloc[i]['instrumentName']
                break
            if notPERPETUAL and yearDif == 0 and monthDif > 0:
                frontMfuture = futures.iloc[i]['instrumentName']
                break
            if notPERPETUAL and monthDif == 0 and dayDif > 4:
                frontMfuture = futures.iloc[i]['instrumentName']
                break
        return frontMfuture

    def getLastTradetimeToDate(self, instrument=None):
        if instrument == None:
            instrument = self.frontMfuture
        timestampim = (self.value(
            self.client.getlasttrades(instrument))['timeStamp'][0])
        timestampim = time.strftime("%a %d %b %Y %H:%M:%S GMT",
                                    time.gmtime(timestampim / 1000.0))
        return timestampim

    def getBestBidAsk(self, instrument=None):
        if instrument == None:
            instrument = self.frontMfuture
        ask = self.value(self.client.getorderbook(instrument)['asks'][0])[
            'price']  # satmaq isdiyenner
        bid = self.value(self.client.getorderbook(instrument)['bids'][0])[
            'price']  #almaq istiyenner
        return ask, bid
Ejemplo n.º 18
0
class MarketMaker(object):
    def __init__(self, monitor=True, output=True):
        self.equity_usd = None
        self.equity_btc = None
        self.equity_usd_init = None
        self.equity_btc_init = None
        self.con_size = float(CONTRACT_SIZE)
        self.client = None
        self.deltas = OrderedDict()
        self.futures = OrderedDict()
        self.futures_prv = OrderedDict()
        self.logger = None
        self.mean_looptime = 1
        self.monitor = monitor
        self.output = output or monitor
        self.positions = OrderedDict()
        self.spread_data = None
        self.this_mtime = None
        self.ts = None
        self.vols = OrderedDict()

    def create_client(self):
        self.client = RestClient(KEY, SECRET, URL)

    def get_bbo(self, contract):  # Get best b/o excluding own orders

        # Get orderbook
        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

        return {'bid': best_bid, 'ask': best_ask}

    def get_futures(self):  # Get all current futures instruments

        self.futures_prv = cp.deepcopy(self.futures)
        insts = self.client.getinstruments()
        self.futures = sort_by_key(
            {i['instrumentName']: i
             for i in insts if i['kind'] == 'future'})

        for k, v in self.futures.items():
            self.futures[k]['expi_dt'] = datetime.strptime(
                v['expiration'][:-4], '%Y-%m-%d %H:%M:%S')

    def get_pct_delta(self):
        self.update_status()
        return sum(self.deltas.values()) / self.equity_btc

    def get_spot(self):
        return self.client.index()['btc']

    def get_precision(self, contract):
        return self.futures[contract]['pricePrecision']

    def get_ticksize(self, contract):
        return self.futures[contract]['tickSize']

    def output_status(self):

        if not self.output:
            return None

        self.update_status()

        now = datetime.utcnow()
        days = (now - self.start_time).total_seconds() / SECONDS_IN_DAY
        print(
            '********************************************************************'
        )
        print('Start Time:        %s' %
              self.start_time.strftime('%Y-%m-%d %H:%M:%S'))
        print('Current Time:      %s' % now.strftime('%Y-%m-%d %H:%M:%S'))
        print('Days:              %s' % round(days, 1))
        print('Hours:             %s' % round(days * 24, 1))
        print('Spot Price:        %s' % self.get_spot())

        pnl_usd = self.equity_usd - self.equity_usd_init
        pnl_btc = self.equity_btc - self.equity_btc_init

        print('Equity ($):        %7.2f' % self.equity_usd)
        print('P&L ($)            %7.2f' % pnl_usd)
        print('Equity (BTC):      %7.4f' % self.equity_btc)
        print('P&L (BTC)          %7.4f' % pnl_btc)
        print('%% Delta:           %s%%' %
              round(self.get_pct_delta() / PCT, 1))
        print('Total Delta (BTC): %s' % round(sum(self.deltas.values()), 2))
        print_dict_of_dicts(
            {k: {
                'BTC': self.deltas[k]
            }
             for k in self.deltas.keys()},
            roundto=2,
            title='Deltas')

        print_dict_of_dicts(
            {
                k: {
                    'Contracts': self.positions[k]['size']
                }
                for k in self.positions.keys()
            },
            title='Positions')

        if not self.monitor:
            print_dict_of_dicts(
                {k: {
                    '%': self.vols[k]
                }
                 for k in self.vols.keys()},
                multiple=100,
                title='Vols')
            print('\nMean Loop Time: %s' % round(self.mean_looptime, 2))

        print('')

    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 restart(self):
        try:
            strMsg = 'RESTARTING'
            print(strMsg)
            self.client.cancelall()
            strMsg += ' '
            for i in range(0, 5):
                strMsg += '.'
                print(strMsg)
                sleep(1)
        except:
            pass
        finally:
            os.execv(sys.executable, [sys.executable] + sys.argv)

    def run(self):

        self.run_first()
        self.output_status()

        t_ts = t_out = t_loop = t_mtime = datetime.utcnow()

        while True:

            self.get_futures()

            # Restart if a new contract is listed
            if len(self.futures) != len(self.futures_prv):
                self.restart()

            self.update_positions()

            t_now = datetime.utcnow()

            # Update time series and vols
            if (t_now - t_ts).total_seconds() >= WAVELEN_TS:
                t_ts = t_now
                self.update_timeseries()
                self.update_vols()

            self.place_orders()

            # Display status to terminal
            if self.output:
                t_now = datetime.utcnow()
                if (t_now - t_out).total_seconds() >= WAVELEN_OUT:
                    self.output_status()
                    t_out = t_now

            # Restart if file change detected
            t_now = datetime.utcnow()
            if (t_now - t_mtime).total_seconds() > WAVELEN_MTIME_CHK:
                t_mtime = t_now
                if getmtime(__file__) > self.this_mtime:
                    self.restart()

            t_now = datetime.utcnow()
            looptime = (t_now - t_loop).total_seconds()

            # Estimate mean looptime
            w1 = EWMA_WGT_LOOPTIME
            w2 = 1.0 - w1
            t1 = looptime
            t2 = self.mean_looptime

            self.mean_looptime = w1 * t1 + w2 * t2

            t_loop = t_now
            sleep_time = MIN_LOOP_TIME - looptime
            if sleep_time > 0:
                time.sleep(sleep_time)
            if self.monitor:
                time.sleep(WAVELEN_OUT)

    def run_first(self):

        self.create_client()
        self.client.cancelall()
        self.logger = get_logger('root', LOG_LEVEL)
        # Get all futures contracts
        self.get_futures()
        self.this_mtime = getmtime(__file__)
        self.symbols = [BTC_SYMBOL] + list(self.futures.keys())
        self.symbols.sort()
        self.deltas = OrderedDict({s: None for s in self.symbols})

        # Create historical time series data for estimating vol
        ts_keys = self.symbols + ['timestamp']
        ts_keys.sort()

        self.ts = [
            OrderedDict({f: None
                         for f in ts_keys}) for i in range(NLAGS + 1)
        ]

        self.vols = OrderedDict({s: VOL_PRIOR for s in self.symbols})

        self.start_time = datetime.utcnow()
        self.update_status()
        self.equity_usd_init = self.equity_usd
        self.equity_btc_init = self.equity_btc

    def update_status(self):

        account = self.client.account()
        spot = self.get_spot()

        self.equity_btc = account['equity']
        self.equity_usd = self.equity_btc * spot

        self.update_positions()

        self.deltas = OrderedDict(
            {k: self.positions[k]['sizeBtc']
             for k in self.futures.keys()})
        self.deltas[BTC_SYMBOL] = account['equity']

    def update_positions(self):

        self.positions = OrderedDict({
            f: {
                'size': 0,
                'sizeBtc': 0,
                'indexPrice': None,
                'markPrice': None
            }
            for f in self.futures.keys()
        })
        positions = self.client.positions()

        for pos in positions:
            if pos['instrument'] in self.futures:
                self.positions[pos['instrument']] = pos

    def update_timeseries(self):

        if self.monitor:
            return None

        for t in range(NLAGS, 0, -1):
            self.ts[t] = cp.deepcopy(self.ts[t - 1])

        spot = self.get_spot()
        self.ts[0][BTC_SYMBOL] = spot

        for c in self.futures.keys():

            bbo = self.get_bbo(c)
            bid = bbo['bid']
            ask = bbo['ask']

            if not bid is None and not ask is None:
                mid = 0.5 * (bbo['bid'] + bbo['ask'])
            else:
                continue
            self.ts[0][c] = mid

        self.ts[0]['timestamp'] = datetime.utcnow()

    def update_vols(self):

        if self.monitor:
            return None

        w = EWMA_WGT_COV
        ts = self.ts

        t = [ts[i]['timestamp'] for i in range(NLAGS + 1)]
        p = {c: None for c in self.vols.keys()}
        for c in ts[0].keys():
            p[c] = [ts[i][c] for i in range(NLAGS + 1)]

        if any(x is None for x in t):
            return None
        for c in self.vols.keys():
            if any(x is None for x in p[c]):
                return None

        NSECS = SECONDS_IN_YEAR
        cov_cap = COV_RETURN_CAP / NSECS

        for s in self.vols.keys():

            x = p[s]
            dx = x[0] / x[1] - 1
            dt = (t[0] - t[1]).total_seconds()
            v = min(dx**2 / dt, cov_cap) * NSECS
            v = w * v + (1 - w) * self.vols[s]**2

            self.vols[s] = math.sqrt(v)
Ejemplo n.º 19
0
from deribit_api import RestClient

# TEST_URL = 'https://test.deribit.com'
KEY = '45Sxzh7sa1vN'
KEY_SECRET = 'CPQEV33KLU3KJ2OC3FGI4LKTBEJAHJB4'

deribit_api_client = RestClient(KEY, KEY_SECRET)
# deribit_api = RestClient(KEY, KEY_SECRET, TEST_URL)


class Account(object):
    """
    Base account class docstring
    """
    def __init__(self, name, currency):
        """
        Init object instance
        """
        self.name = name
        self.currency = currency
        self.enabletrade = False  # can't trade by default
        self.in_position = False
        self.open_orders = None  # will be set up by initialize function
        self.current_positions = None  # will be set up by initialize function


class DeribitAccount(Account):
    """
    DeribitAccount inhereted from Account object
    Deribit API added
    """
Ejemplo n.º 20
0
class MarketMaker(object):
    def __init__(self, monitor=True, output=True):
        self.equity_usd = None
        self.equity_btc = None
        self.eth = 0
        self.equity_usd_init = None
        self.equity_btc_init = None
        self.con_size = float(CONTRACT_SIZE)
        self.client = None
        self.deltas = OrderedDict()
        self.futures = OrderedDict()
        self.futures_prv = OrderedDict()
        self.logger = None
        self.volatility = 0

        self.bbw = {}
        self.atr = {}
        self.diffdeltab = {}
        self.diff2 = 0
        self.diff3 = 0
        self.bands = {}
        self.quantity_switch = []
        self.price = []
        self.buysellsignal = {}
        self.directional = []
        self.seriesData = {}
        self.seriesData[(datetime.strptime(
            (date.today() - timedelta(days=1)).strftime('%Y-%m-%d'),
            '%Y-%m-%d'))] = 0

        self.seriesPercent = {}
        self.startUsd = {}
        self.firstfirst = True
        self.dsrsi = 50
        self.minMaxDD = None
        self.maxMaxDD = None
        self.ws = {}
        self.ohlcv = {}
        self.mean_looptime = 1
        self.monitor = monitor
        self.output = output or monitor
        self.positions = OrderedDict()
        self.spread_data = None
        self.this_mtime = None
        self.ts = None
        self.vols = OrderedDict()
        self.multsShort = {}
        self.multsLong = {}
        self.diff = 1

    def create_client(self):
        self.client = RestClient(KEY, SECRET, URL)

    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 get_futures(self):  # Get all current futures instruments

        self.futures_prv = cp.deepcopy(self.futures)
        insts = self.client.getinstruments()
        self.futures = sort_by_key({
            i['instrumentName']: i
            for i in insts if ('BTC-PERPETUAL' in i['instrumentName'])
            and i['kind'] == 'future'  #  
        })

        for k, v in self.futures.items():
            self.futures[k]['expi_dt'] = datetime.strptime(
                v['expiration'][:-4], '%Y-%m-%d %H:%M:%S')

    def get_pct_delta(self):
        self.update_status()
        return sum(self.deltas.values()) / self.equity_btc

    def get_spot(self):
        return self.client.index()['btc']

    def get_precision(self, contract):
        return self.futures[contract]['pricePrecision']

    def get_ticksize(self, contract):
        return self.futures[contract]['tickSize']

    def output_status(self):
        startLen = (len(self.seriesData))
        if self.startUsd != {}:
            startUsd = self.startUsd
            nowUsd = self.equity_usd
            diff = 100 * ((nowUsd / startUsd) - 1)
            print('diff')
            print(diff)

            if diff < self.diff2:
                self.diff2 = diff
            if diff > self.diff3:
                self.diff3 = diff
            if self.diff3 > self.maxMaxDD:
                print('broke max max dd! sleep 24hr')
                time.sleep(60 * 60 * 24)
                self.diff3 = 0
                self.startUsd = self.equity_usd
            if self.diff2 < self.minMaxDD:
                print('broke min max dd! sleep 24hr')
                time.sleep(60 * 60 * 24)
                self.diff2 = 0
                self.startUsd = self.equity_usd
            self.seriesData[(datetime.strptime(
                datetime.today().strftime('%Y-%m-%d'),
                '%Y-%m-%d'))] = self.diff2

            endLen = (len(self.seriesData))
            if endLen != startLen:
                self.seriesPercent[(datetime.strptime(
                    datetime.today().strftime('%Y-%m-%d'), '%Y-%m-%d'))] = diff
                self.diff2 = 0
                self.diff3 = 0
                self.startUsd = self.equity_usd
            s = pd.Series(self.seriesData)

            print(s)
            print(qs.stats.max_drawdown(s))
        if not self.output:
            return None

        self.update_status()

        now = datetime.utcnow()
        days = (now - self.start_time).total_seconds() / SECONDS_IN_DAY
        print(
            '********************************************************************'
        )
        print('Start Time:        %s' %
              self.start_time.strftime('%Y-%m-%d %H:%M:%S'))
        print('Current Time:      %s' % now.strftime('%Y-%m-%d %H:%M:%S'))
        print('Days:              %s' % round(days, 1))
        print('Hours:             %s' % round(days * 24, 1))
        print('Spot Price:        %s' % self.get_spot())

        pnl_usd = self.equity_usd - self.equity_usd_init
        pnl_btc = self.equity_btc - self.equity_btc_init
        if self.firstfirst == True:
            self.startUsd = self.equity_usd
            self.firstfirst = False
        print('Equity ($):        %7.2f' % self.equity_usd)
        print('P&L ($)            %7.2f' % pnl_usd)
        print('Equity (BTC):      %7.4f' % self.equity_btc)
        print('P&L (BTC)          %7.4f' % pnl_btc)
        ##print( '%% Delta:           %s%%'% round( self.get_pct_delta() / PCT, 1 ))
        ##print( 'Total Delta (BTC): %s'   % round( sum( self.deltas.values()), 2 ))
        #print_dict_of_dicts( {
        #    k: {
        #        'BTC': self.deltas[ k ]
        #    } for k in self.deltas.keys()
        #    },
        #    roundto = 2, title = 'Deltas' )

        print_dict_of_dicts(
            {
                k: {
                    'Contracts': self.positions[k]['size']
                }
                for k in self.positions.keys()
            },
            title='Positions')

        if not self.monitor:
            print_dict_of_dicts(
                {k: {
                    '%': self.vols[k]
                }
                 for k in self.vols.keys()},
                multiple=100,
                title='Vols')
            #print( '\nMean Loop Time: %s' % round( self.mean_looptime, 2 ))
            #print( '' )
            for k in self.positions.keys():

                self.multsShort[k] = 1
                self.multsLong[k] = 1

                if 'sizeEth' in self.positions[k]:
                    key = 'sizeEth'
                else:
                    key = 'sizeBtc'
                if self.positions[k][key] > 10:
                    self.multsShort[k] = (self.positions[k][key] /
                                          10) * POS_MOD
                if self.positions[k][key] < -1 * 10:
                    self.multsLong[k] = (-1 * self.positions[k]['currentQty'] /
                                         10) * POS_MOD


#Vols
#print(self.multsLong)
#print(self.multsShort)

    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 restart(self):
        try:
            strMsg = 'RESTARTING'
            #print( strMsg )
            self.client.cancelall()
            strMsg += ' '
            for i in range(0, 5):
                strMsg += '.'
                #print( strMsg )
                sleep(1)
        except:
            pass
        finally:
            os.execv(sys.executable, [sys.executable] + sys.argv)

    def run(self):

        self.run_first()
        self.output_status()

        t_ts = t_out = t_loop = t_mtime = datetime.utcnow()

        while True:
            self.get_futures()
            # Directional
            # 0: none
            # 1: StochRSI
            #
            # Price
            # 0: none
            # 1: vwap
            # 2: ppo
            #

            # Volatility
            # 0: none
            # 1: ewma
            with open('deribit-settings.json', 'r') as read_file:
                data = json.load(read_file)

                self.maxMaxDD = data['maxMaxDD']
                self.minMaxDD = data['minMaxDD']
                self.directional = data['directional']
                self.price = data['price']
                self.volatility = data['volatility']
                self.quantity_switch = data['quantity']

            # Restart if a new contract is listed
            if len(self.futures) != len(self.futures_prv):
                self.restart()

            self.update_positions()

            t_now = datetime.utcnow()

            # Update time series and vols
            if (t_now - t_ts).total_seconds() >= WAVELEN_TS:
                t_ts = t_now
                for contract in self.futures.keys():
                    self.ohlcv[contract] = requests.get(
                        'https://test.deribit.com/api/v2/public/get_tradingview_chart_data?instrument_name='
                        + contract + '&start_timestamp=' +
                        str(int(time.time()) * 1000 - 1000 * 60 * 60) +
                        '&end_timestamp=' + str(int(time.time()) * 1000) +
                        '&resolution=1')

                self.update_timeseries()
                self.update_vols()

            self.place_orders()

            # Display status to terminal
            if self.output:
                t_now = datetime.utcnow()
                if (t_now - t_out).total_seconds() >= WAVELEN_OUT:
                    self.output_status()
                    t_out = t_now

            # Restart if file change detected
            t_now = datetime.utcnow()
            if (t_now - t_mtime).total_seconds() > WAVELEN_MTIME_CHK:
                t_mtime = t_now
                if getmtime(__file__) > self.this_mtime:
                    self.restart()

            t_now = datetime.utcnow()
            looptime = (t_now - t_loop).total_seconds()

            # Estimate mean looptime
            w1 = EWMA_WGT_LOOPTIME
            w2 = 1.0 - w1
            t1 = looptime
            t2 = self.mean_looptime

            self.mean_looptime = w1 * t1 + w2 * t2

            t_loop = t_now
            sleep_time = MIN_LOOP_TIME - looptime
            if sleep_time > 0:
                time.sleep(sleep_time)
            if self.monitor:
                time.sleep(WAVELEN_OUT)

    def cal_average(self, num):
        sum_num = 0
        for t in num:
            sum_num = sum_num + t

        avg = sum_num / len(num)
        return avg

    def run_first(self):

        self.create_client()
        self.client.cancelall()
        self.logger = get_logger('root', LOG_LEVEL)
        # Get all futures contracts
        self.get_futures()
        for k in self.futures.keys():
            self.ohlcv[k] = requests.get(
                'https://test.deribit.com/api/v2/public/get_tradingview_chart_data?instrument_name='
                + k + '&start_timestamp=' +
                str(int(time.time()) * 1000 - 1000 * 60 * 60) +
                '&end_timestamp=' + str(int(time.time()) * 1000) +
                '&resolution=1')

            self.bbw[k] = 0
            self.bands[k] = []
            self.atr[k] = 0
            self.diffdeltab[k] = 0
            self.buysellsignal[k] = 1

        self.this_mtime = getmtime(__file__)
        self.symbols = [BTC_SYMBOL] + list(self.futures.keys())
        self.symbols.sort()
        self.deltas = OrderedDict({s: None for s in self.symbols})

        # Create historical time series data for estimating vol
        ts_keys = self.symbols + ['timestamp']
        ts_keys.sort()

        self.ts = [
            OrderedDict({f: None
                         for f in ts_keys}) for i in range(NLAGS + 1)
        ]

        self.vols = OrderedDict({s: VOL_PRIOR for s in self.symbols})

        self.start_time = datetime.utcnow()
        self.update_status()
        self.equity_usd_init = self.equity_usd
        self.equity_btc_init = self.equity_btc

    def update_status(self):

        account = self.client.account()
        spot = self.get_spot()

        self.equity_btc = account['equity']
        self.equity_usd = self.equity_btc * spot

        self.update_positions()

    #  self.deltas = OrderedDict(
    #      { k: self.positions[ k ][ 'sizeBtc' ] for k in self.futures.keys()}
    #  )

    #  self.deltas[ BTC_SYMBOL ] = account[ 'equity' ]

    def update_positions(self):

        self.positions = OrderedDict({
            f: {
                'size': 0,
                'sizeBtc': 0,
                'indexPrice': None,
                'markPrice': None
            }
            for f in self.futures.keys()
        })
        positions = self.client.positions()

        for pos in positions:
            if 'ETH' in pos['instrument']:
                pos['size'] = pos['size'] / 10
            if pos['instrument'] in self.futures:
                self.positions[pos['instrument']] = pos

    def update_timeseries(self):

        if self.monitor:
            return None

        for t in range(NLAGS, 0, -1):
            self.ts[t] = cp.deepcopy(self.ts[t - 1])

        spot = self.get_spot()
        self.ts[0][BTC_SYMBOL] = spot

        for contract in self.futures.keys():
            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
            bid = best_bid
            ask = best_ask

            if not bid is None and not ask is None:
                mid = 0.5 * (bid + ask)

            else:
                continue
            self.ts[0][contract] = mid

        self.ts[0]['timestamp'] = datetime.utcnow()

    def update_vols(self):

        if self.monitor:
            return None

        w = EWMA_WGT_COV
        ts = self.ts

        t = [ts[i]['timestamp'] for i in range(NLAGS + 1)]
        p = {c: None for c in self.vols.keys()}
        for c in ts[0].keys():
            p[c] = [ts[i][c] for i in range(NLAGS + 1)]

        if any(x is None for x in t):
            return None
        for c in self.vols.keys():
            if any(x is None for x in p[c]):
                return None

        NSECS = SECONDS_IN_YEAR
        cov_cap = COV_RETURN_CAP / NSECS

        for s in self.vols.keys():

            x = p[s]
            #print(x)
            dx = x[0] / x[1] - 1
            #print(dx)
            dt = (t[0] - t[1]).total_seconds()
            v = min(dx**2 / dt, cov_cap) * NSECS
            v = w * v + (1 - w) * self.vols[s]**2
            self.vols[s] = math.sqrt(v)
Ejemplo n.º 21
0
# pip install requests deribit_api
# also pip install "websocket-client<0.49.0" ecdsa
# see instructions on https://github.com/coinflex-exchange/python-library

import threading
import datetime, time, random, math, sys
import requests, json
import websocket
import logging, os
from deribit_api import RestClient

from coinflex import Assets
from coinflex import WSClient

# test account on deribit
client = RestClient("reference", "token")

# COINFLEX SECRETS -- enter something here!
USERID = 'core_id'
COOKIE = 'cookie'
PASSWD = 'password'

# SETUP LOGGER
##############
# add logging.StreamHandler() to handlers list if needed
logger = logging.getLogger("Coinflex")
logger.setLevel(logging.INFO)
# create file handler which logs even debug messages
fh = logging.FileHandler('simplemm.log')
fh.setLevel(logging.INFO)
# create formatter and add it to the handlers
Ejemplo n.º 22
0
 def __init__(self, interest_rate=0, K_range=(0, math.inf)):
     # this is my account. Don't share it to others. But I don't have money in it :P
     self.client = RestClient('2SQfDzW1Kaf3F', 'HOG2A2HCYERM2YONRBTYEBMYRZ2ESN3K')
Ejemplo n.º 23
0
#Deribit API
from deribit_api import RestClient
client = RestClient("4M2iZZwmDDqfg", "IE37DBTQ2INOHL4GZFMOC4ZGAFKMY5BX")
#Pandaz
import pandas as pd
#Numpy
import numpy as np
#Extract strings
import string
#Timers
import datetime
from time import sleep
#File system
import os, errno
#CSV
import csv

print "************************"
print "Mama Bitcoin is: " + str(client.index()[u'btc'])
print "************************"

#Get API Data
exp_dat = client.getinstruments()


#Extract Options Title
def extract(dat, extract, tool):
    opt = []
    for each in dat:
        if (extract in each[tool]):
            opt.append(each)
Ejemplo n.º 24
0
from deribit_api import RestClient
from localsettings import *


client = RestClient(DERIBIT_KEY, DERIBIT_SECRET)
client.index()
client.account()

# Get instruments
instruments = client.getinstruments()

print(instruments[1])

# Get Last trades
lastrades = client.getlasttrades(instruments[1]['instrumentName'])

print(lastrades[0])
Ejemplo n.º 25
0
class DeribitWebsocket():
    def __init__(self):
        self.client = RestClient('', '')
        self.table = {}
        #self.logger = logging.getLogger('root')
        self.__reset()

        setup_logger(__name__, 'DeribitWebsocket.log')
        self.logger = logging.getLogger(__name__)

        # disable all loggers from different files
        logging.getLogger('asyncio').setLevel(logging.ERROR)
        logging.getLogger('asyncio.coroutines').setLevel(logging.ERROR)
        logging.getLogger('websockets.server').setLevel(logging.ERROR)
        logging.getLogger('websockets.protocol').setLevel(logging.ERROR)
        logging.getLogger('websocket-client').setLevel(logging.ERROR)

        requests_log = logging.getLogger("requests.packages.urllib3")
        requests_log.setLevel(logging.WARNING)

    def on_message(self, ws, message):
        print("message ", message)
        message = json.loads(message)
        if 'notifications' in message:
            self.table[message['notifications'][0]['result']
                       ['instrument']] = message['notifications'][0]['result']

    def on_error(self, ws, error):
        self.logger.error("error %s" % str(error))
        print(str(error))

    def on_close(self, ws):
        self.logger.info("### closed ###")

    def market_depth(self, symbol):
        return self.table[symbol]

    def on_open(self, ws):
        self.logger.info("ws on_open")
        self.logger.info("connected %s" % str(ws.sock.connected))

        data = {
            "id": 5533,
            "action": "/api/v1/private/subscribe",
            "arguments": {
                #"instrument": ["all"],
                #"instrument": ["BTC-29DEC17"],
                "instrument": ["BTC-PERPETUAL"],
                "event": ["order_book"]
            }
        }

        data['sig'] = self.client.generate_signature(data['action'],
                                                     data['arguments'])
        self.logger.info("subscribe")
        print(data)

        ws.send(json.dumps(data))
        #print (dir(ws))
        #print (ws.sock.connected)

    def connect(self):
        self.logger.info("connect ws")
        websocket.enableTrace(True)
        self.ws = websocket.WebSocketApp(
            "wss://www.deribit.com/ws/api/v1/",
            on_message=lambda ws, msg: self.on_message(ws, msg),
            on_error=lambda ws, msg: self.on_error(ws, msg),
            on_open=lambda ws: self.on_open(ws),
            #on_open = self.on_open,
            on_close=self.on_close)
        ssl_defaults = ssl.get_default_verify_paths()
        sslopt_ca_certs = {'ca_certs': ssl_defaults.cafile}
        self.wst = threading.Thread(
            target=lambda: self.ws.run_forever(sslopt=sslopt_ca_certs))
        self.wst.daemon = True
        self.wst.start()
        self.logger.info("Started thread")
        #TOOD subscribe later
        #self.ws.run_forever()

    def __reset(self):
        self.data = {}
        self.keys = {}
        self.exited = False
        self._error = None
class trading:
# Real Trading
    def __init__(self,client_id = Tokens['Deribit']['Read_and_Write']['id'],client_secret = Tokens['Deribit']['Read_and_Write']['secret']):
        # Login read only account
        self.MyAccount = RestClient(client_id,client_secret)
        self.Fee = {
            'Future':{
                        'Market':0.00075,'Limit':-0.0025
                    },
            'Option':0.0004
        }
        self.Max_Order_Num = 3
        self.Trading_Frequency = 1
    def post_order(self,Instrument,Short_or_Long,Post_Size):
        def get_Post_Dist(Orderbook,Bid_or_Ask,Order_Num,Post_Size):
            Top_Order = [Orderbook[Bid_or_Ask][i]['quantity'] for i in range(Order_Num)]
            Order_Weight = [Top_Order[i]*Post_Size/sum(Top_Order) for i in range(Order_Num)]
            # If the order weight is smaller than 0.1 then add it to 0.1
            Order_Weight = [round(w,1) for w in Order_Weight]
            Order_Weight[0] = Order_Weight[0] + (Post_Size - sum(Order_Weight))
            # Transfer it as order dictionary
            Post_Dist = [{'price':Orderbook[Bid_or_Ask][i]['price'],'size':Order_Weight[i]} for i in range(Order_Num)]
            return Post_Dist
        Orderbook = self.MyAccount.getorderbook(Instrument)
        # Post orders by weighted-size
        if Short_or_Long == 'Short':
            Bid_or_Ask = 'asks'
        elif Short_or_Long == 'Long':
            Bid_or_Ask = 'bids'
        Order_Num = min(int(Post_Size/0.1),min(self.Max_Order_Num,len(Orderbook[Bid_or_Ask]))) # Total number of orders will be posted
        Post_Dist = [] # Store price and amount of each orders will be posted
        if Orderbook['bids'][min(2,len(Orderbook['bids']))]['cm']>Orderbook['asks'][min(2,len(Orderbook['bids']))]['cm']:
            # Bid pressure is larger than Ask pressure, then post order at the top orders of asks book
            Post_Dist = get_Post_Dist(Orderbook,Bid_or_Ask,Order_Num,Post_Size)
        else:
            # Bid pressure is smaller than Ask pressure, then post order above and at the orders of ask book
            if Orderbook['asks'][0]['price'] - Orderbook['bids'][0]['price']<0.001:
                Post_Dist = [{'price':Orderbook['bids'][0]['price'],'size':Post_Size}]

            else:
                First_Order = max(0.1,round(Post_Size/3,1))
                Post_Dist = [{'price':Orderbook['asks'][0]['price']-0.0005,'size':First_Order}]
                Post_Dist = Post_Dist + get_Post_Dist(Orderbook,Bid_or_Ask,Order_Num - 1,Post_Size - First_Order)

        Post_Dist = [{'price':Post_Dist[i]['price'],'size':round(Post_Dist[i]['size'],1)} for i in range(len(Post_Dist))]
        # Print the result
        print("There will be %d %s orders posted:"%(Order_Num,Short_or_Long.lower()))
        pprint(Post_Dist)
        Execute_or_Not = input('Post those orders? [y/n]')
        if Execute_or_Not == 'y':
            ###---Post Orders---###
            if Short_or_Long == 'Short':
                [self.MyAccount.sell(Instrument, p['size'], p['price'], False) for p in Post_Dist]
                for p in Post_Dist:
                    if p['size']!=0:
                        self.MyAccount.sell(Instrument, p['size'], p['price'], False)
                time.sleep(self.Trading_Frequency)
            elif Short_or_Long == 'Long':
                for p in Post_Dist:
                    if p['size']!=0:
                        self.MyAccount.buy(Instrument, p['size'], p['price'], False)
                time.sleep(self.Trading_Frequency)
            else:
                print('Error occurs')
                return False
            ###------###
            return True
        else:
            return False
    def get_current_btc_postition(self,Instrument):
        if len(self.MyAccount.positions())!=0:
            if sum([p['instrument'] == 'BTC-PERPETUAL' for p in self.MyAccount.positions()])!= 0: # list is not empty
                Perpetual_Position = self.MyAccount.positions()\
                    [\
                        [p['instrument'] == 'BTC-PERPETUAL' for p in self.MyAccount.positions()].index(True)\
                    ]['sizeBtc']
            else:
                Perpetual_Position = 0
            if sum([p['instrument'] == Instrument for p in self.MyAccount.positions()]) != 0: # list is not empty
                Option_Position = self.MyAccount.positions()\
                    [\
                        [p['instrument'] == Instrument for p in self.MyAccount.positions()].index(True)\
                    ]['size']
            else:
                Option_Position = 0
        else:
            Perpetual_Position = 0
            Option_Position = 0
        return Perpetual_Position,Option_Position
    def hedge(self,Instrument,Strike_Price):
        BTC_Price = float(self.MyAccount.index()['btc'])
        Perpetual_Position,Option_Position = self.get_current_btc_postition(Instrument)
        # Hedge current risk exposure
        while (BTC_Price < Strike_Price) and (Perpetual_Position> Option_Position): # Hedging
            sms_notification('Hedging Start.')
            Execute_or_Not = input('Cancel all orders?[y/n]')
            if Execute_or_Not == 'y':
                self.MyAccount.cancelall()
            else:
                return False
            Orderbook = self.MyAccount.getorderbook('BTC-PERPETUAL')
            Post_Size = abs(float(Perpetual_Position - Option_Position))
            Top_Order_Size = Orderbook['bids'][0]['quantity']/Orderbook['bids'][0]['price'] # Top_Order_Size is counted as BTC
            print("There will be %lf perpetual shorted at %lf"%(min(Post_Size,Top_Order_Size),\
                                                                    Orderbook['bids'][0]['price']))
            sms_notification("There will be %lf perpetual shorted at %lf [y/n]"%(min(Post_Size,Top_Order_Size),\
                                                                    Orderbook['bids'][0]['price']))
            Execute_or_Not = input('Post those orders? [y/n]')
            if Execute_or_Not == 'y':
                ###------ Post Order ------###
                Sell_Size = int(min(\
                                    Post_Size,\
                                    Top_Order_Size\
                                   )*Orderbook['bids'][0]['price']/10\
                               )
                if Sell_Size >=1:
                    self.MyAccount.sell('BTC-PERPETUAL',Sell_Size , Orderbook['bids'][0]['price'], False)
                    time.sleep(self.Trading_Frequency)
                else:
                    print("Sell Size is smaller than the minimal requirement.")
                ###------ Post Order Completed ------###
            else:
                print("Trading Stop")
                return False
            BTC_Price = self.MyAccount.index()['btc']
            Perpetual_Position,Option_Position = self.get_current_btc_postition(Instrument)
        # Clear the previous perpetual position
        Orderbook = self.MyAccount.getorderbook('BTC-PERPETUAL')
        while (int(Orderbook['bids'][0]['price']*Perpetual_Position/10-1e-3)<=-1) and (BTC_Price>=Strike_Price): # Closing position
            Execute_or_Not = input('Cancel all orders?[y/n]')
            if Execute_or_Not == 'y':
                self.MyAccount.cancelall()
            else:
                return False
            Perpetual_Position,Option_Position = self.get_current_btc_postition(Instrument)
            BTC_Price = self.MyAccount.index()['btc']
            if Perpetual_Position>0:
                # Short Perpetual
                Orderbook = self.MyAccount.getorderbook('BTC-PERPETUAL')
                Post_Size = min(abs(float(Perpetual_Position)),Orderbook['bids'][0]['quantity']/Orderbook['bids'][0]['price'])
                print("There will be %lf perpetual shorted at %lf[y/n]"%(Post_Size,Orderbook['bids'][0]['price']))
                sms_notification("There will be %lf perpetual shorted at %lf"%(Post_Size,Orderbook['bids'][0]['price']))
                Execute_or_Not = input('Post those orders? [y/n]')
                if Execute_or_Not == 'y':
                    ###------ Post Order ------###
                    Sell_Size = int(Post_Size*Orderbook['bids'][0]['price']/10)
                    if Sell_Size >= 1:
                        self.MyAccount.sell('BTC-PERPETUAL', Sell_Size, Orderbook['bids'][0]['price'], False)
                        # Post_Size is counted as BTC, but sell perpetual is counted as 10 USD, so we do a bit transfer.
                        time.sleep(self.Trading_Frequency)
                    else:
                        print("Sell Size is smaller than the minimal requirement.")
                    ###------ Post Order Completed ------###
                else:
                    return False
            if Perpetual_Position<0:
                # Long Perpetual
                Orderbook = self.MyAccount.getorderbook('BTC-PERPETUAL')
                Post_Size = min(abs(float(Perpetual_Position)),Orderbook['asks'][0]['quantity']/Orderbook['asks'][0]['price'])
                print("There will be %lf perpetual longed at %lf"%(Post_Size,Orderbook['asks'][0]['price']))
                sms_notification("There will be %lf perpetual longed at %lf[y/n]"%(Post_Size,Orderbook['asks'][0]['price']))
                Execute_or_Not = input('Post those orders? [y/n]')
                if Execute_or_Not == 'y':
                    ###------ Post Order ------###
                    Buy_Size = int(Post_Size*Orderbook['asks'][0]['price']/10)
                    if Buy_Size >= 1:
                        self.MyAccount.buy('BTC-PERPETUAL', Buy_Size, Orderbook['asks'][0]['price'], False)
                        # Post_Size is counted as BTC, but sell perpetual is counted as 10 USD, so we do a bit transfer.
                        time.sleep(self.Trading_Frequency)
                    else:
                        print("Buy Size is smaller than the minimal requirement.")
                    ###------ Post Order Completed ------###
                else:
                    return False

        return True

    def short_option(self,Date,Year,Strike_Price,Contract_Type):
        Instrument = "BTC-%s%s-%s-%s"%(Date.upper(),Year,Strike_Price,Contract_Type.upper())
        Strike_Price = float(Strike_Price)
        # Compute margin and fee cost
        markPrice = self.MyAccount.getsummary(Instrument)['markPrice']
        btcPrice = self.MyAccount.index()['btc']
        MM_Option = max(0.075,0.075*markPrice)+markPrice # Maintianence margin
        IM_Option = max(max(0.15 - (btcPrice - float(Strike_Price))/btcPrice,0.1)+markPrice,MM_Option)# Initial margin
        size = 0.25
        IM_Future = 0.01+(0.005/100)*size
        Required_Balance = (IM_Option+self.Fee['Option'])*size + size*(IM_Future+self.Fee['Future']['Market'])
        Account = self.MyAccount.account()
        while Required_Balance<=Account['availableFunds']:
            print('Required Balance = %lf if size = %lf'%(Required_Balance,size))
            size += 0.05
            IM_Future = 0.01+(0.005/100)*size
            Required_Balance = (IM_Option+self.Fee['Option'])*size + size*(IM_Future+self.Fee['Future']['Market'])

        # Short Option
        Short_Size = float(input("Short Size:")) # Total position will be shorted
        pprint({\
                'availableFunds':self.MyAccount.account()['availableFunds']\
                ,'balance':self.MyAccount.account()['balance']\
                ,'equity':self.MyAccount.account()['equity']\
              ,'initialMargin':self.MyAccount.account()['initialMargin']\
              ,'maintenanceMargin':self.MyAccount.account()['maintenanceMargin']\
               })
        while Short_Size !=0:
            if len(self.MyAccount.positions()) !=0:
                Current_Size = self.MyAccount.positions()\
                [\
                    [p['instrument'] == Instrument for p in self.MyAccount.positions()].index(True)\
                ]['size']
            else:
                Current_Size = 0
            Short_Size = Short_Size - abs(float(Current_Size))
            print("Short Option: %lf"%Short_Size) # Print Short Size
            # Clear all open orders
            Execute_or_Not = input('Cancel all orders?[y/n]')
            if Execute_or_Not == 'y':
                self.MyAccount.cancelall()
            else:
                return False
            # Post new orders
            if not self.post_order(Instrument,'Short',Short_Size):
                print("Trading stop")
                pprint(self.MyAccount.account())
                return 0
            Continue_or_Not = input('Continue Short Options or Not [y/n]')
        # Hedge
        Mon = list(calendar.month_abbr).index(Date[(len(Date)-3):len(Date)][0].upper()+Date[(len(Date)-3):len(Date)][1:3].lower())
        Day = int(Date[0:(len(Date)-3)])
        settle_time = datetime.datetime(int("20%s"%Year),Mon,Day,16,0)
        while datetime.datetime.now() <=settle_time:
             if not self.hedge(Instrument,Strike_Price):
                print("Trading stop")
                pprint(self.MyAccount.account())
                return 0
        return 0
    def alert(self):
        BTC_Price = self.MyAccount.index()['btc']
        if BTC_Price<9125:
            sms_notification("Wake up! Price is out of bound")
import time
from blackscholes import black_scholes
import time
from datetime import datetime
#   >>> black_scholes(7598.45, 7000, 0.09587902546296297, 0.679, 0.03, 0.0, -1)
#   >>> black_scholes(7598.45, 9000, 0.09587902546296297, 0.675, 0.03, 0.0, 1)
from deribit_api import RestClient

KEY = ''  #
SECRET = ''
client = RestClient(KEY, SECRET, 'https://test.deribit.com')
import math
from utils import (get_logger, lag, print_dict, print_dict_of_dicts,
                   sort_by_key, ticksize_ceil, ticksize_floor, ticksize_round)

count1 = -1
while True:
    count1 = count1 + 1
    if count1 >= 10:
        count1 = -1
        client.cancelall()
    puts = []
    calls = [
    ]  #order size * (higher of pct lim long/short * num fut) * 10 / lev
    therisk = ((250) * ((50 * 3) / 100) * 10) * 1

    if therisk < 0:
        therisk = therisk * -1
    tty = datetime(2019, 12, 27).strftime('%s')

    theyield = 0.1541
Ejemplo n.º 28
0
            if len(lTrades) > 30:
                for i in reversed(range(0, len(lTrades) - 10)):
                    trades.pop(i)

    except:
        print('')


if __name__ == "__main__":
    import asyncio
    from deribit_api import RestClient
    import json
    with open("creds.json") as data_file:
        creds = json.load(data_file)
    url = 'wss://test.deribit.com/ws/api/v1/'

    instrument = "BTC-PERPETUAL"
    client = RestClient(creds['Key'], creds['Secret'],
                        'https://test.deribit.com')
    d = {
        "id": 5634,
        "action": "/api/v1/private/subscribe",
        "arguments": {
            "event": ["user_order", "order_book", "trade"],
            "instrument": [instrument]
        }
    }
    # orders = client.getopenorders()
    asyncio.run(connct(url, client, d))
Ejemplo n.º 29
0
# In[5]:

arb_algo_path = os.getcwd().replace("\\python_scripts", "")
arb_algo_path

# In[6]:

from deribit_api import RestClient

## spread account
url = "https://www.deribit.com"
key = "5WmL4PVQDkYsr"
secret = "SCUMOH5HNLQ6DBVD7LYJJQDIGHRSHWQO"

client = RestClient(key, secret, url)

# In[7]:

import json, hmac, hashlib, time, requests, base64
from collections import OrderedDict


def generate_signature(key, secret, action, data):
    tstamp = int(time.time() * 1000)
    signature_data = {
        '_': tstamp,
        '_ackey': key,
        '_acsec': secret,
        '_action': action
    }
Ejemplo n.º 30
0
from deribit_api import RestClient

TEST_URL = 'https://test.deribit.com'
KEY = '45Sxzh7sa1vN'
KEY_SECRET = 'CPQEV33KLU3KJ2OC3FGI4LKTBEJAHJB4'
deribit_api = RestClient(KEY, KEY_SECRET, TEST_URL)