Esempio n. 1
0
    async def _funding(self, msg: dict, pair: str, timestamp: float):
        if 'funding_rate' in msg:
            f = Funding(
                self.id,
                pair,
                None,
                msg['funding_rate'],
                self.timestamp_normalize(msg['next_funding_rate_time']),
                self.timestamp_normalize(msg['time']),
                predicted_rate=msg['funding_rate_prediction'],
                raw=msg
            )
            await self.callback(FUNDING, f, timestamp)

        oi = msg['openInterest']
        if pair in self._open_interest_cache and oi == self._open_interest_cache[pair]:
            return
        self._open_interest_cache[pair] = oi
        o = OpenInterest(
            self.id,
            pair,
            oi,
            self.timestamp_normalize(msg['time']),
            raw=msg
        )
        await self.callback(OPEN_INTEREST, o, timestamp)
Esempio n. 2
0
 async def _open_interest(self, msg: dict, timestamp: float):
     """
     {
         'arg': {
             'channel': 'open-interest',
             'instId': 'BTC-USDT-SWAP
         },
         'data': [
             {
                 'instId': 'BTC-USDT-SWAP',
                 'instType': 'SWAP',
                 'oi':'565474',
                 'oiCcy': '5654.74',
                 'ts': '1630338003010'
             }
         ]
     }
     """
     symbol = self.exchange_symbol_to_std_symbol(msg['arg']['instId'])
     for update in msg['data']:
         oi = OpenInterest(self.id,
                           symbol,
                           Decimal(update['oi']),
                           self.timestamp_normalize(int(update['ts'])),
                           raw=update)
         await self.callback(OPEN_INTEREST, oi, timestamp)
Esempio n. 3
0
 async def _open_interest(self, msg: dict, timestamp: float):
     """
     {
         "openInterest": "10659.509",
         "symbol": "BTCUSDT",
         "time": 1589437530011   // Transaction time
     }
     """
     pair = msg['symbol']
     oi = msg['openInterest']
     if oi != self._open_interest_cache.get(pair, None):
         o = OpenInterest(self.id,
                          self.exchange_symbol_to_std_symbol(pair),
                          Decimal(oi),
                          self.timestamp_normalize(msg['time']),
                          raw=msg)
         await self.callback(OPEN_INTEREST, o, timestamp)
         self._open_interest_cache[pair] = oi
Esempio n. 4
0
 async def _open_interest(self, pairs: Iterable):
     """
         {
           "success": true,
           "result": {
             "volume": 1000.23,
             "nextFundingRate": 0.00025,
             "nextFundingTime": "2019-03-29T03:00:00+00:00",
             "expirationPrice": 3992.1,
             "predictedExpirationPrice": 3993.6,
             "strikePrice": 8182.35,
             "openInterest": 21124.583
           }
         }
     """
     while True:
         for pair in pairs:
             # OI only for perp and futures, so check for / in pair name indicating spot
             if '/' in pair:
                 continue
             end_point = f"https://ftx.com/api/futures/{pair}/stats"
             data = await self.http_conn.read(end_point)
             received = time()
             data = json.loads(data, parse_float=Decimal)
             if 'result' in data:
                 oi = data['result']['openInterest']
                 if oi != self._open_interest_cache.get(pair, None):
                     o = OpenInterest(
                         self.id,
                         self.exchange_symbol_to_std_symbol(pair),
                         oi,
                         None,
                         raw=data)
                     await self.callback(OPEN_INTEREST, o, received)
                     self._open_interest_cache[pair] = oi
                     await asyncio.sleep(1)
         await asyncio.sleep(60)
Esempio n. 5
0
    async def _instrument_info(self, msg: dict, timestamp: float):
        """
        ### Snapshot type update
        {
        "topic": "instrument_info.100ms.BTCUSD",
        "type": "snapshot",
        "data": {
            "id": 1,
            "symbol": "BTCUSD",                           //instrument name
            "last_price_e4": 81165000,                    //the latest price
            "last_tick_direction": "ZeroPlusTick",        //the direction of last tick:PlusTick,ZeroPlusTick,MinusTick,
                                                          //ZeroMinusTick
            "prev_price_24h_e4": 81585000,                //the price of prev 24h
            "price_24h_pcnt_e6": -5148,                   //the current last price percentage change from prev 24h price
            "high_price_24h_e4": 82900000,                //the highest price of prev 24h
            "low_price_24h_e4": 79655000,                 //the lowest price of prev 24h
            "prev_price_1h_e4": 81395000,                 //the price of prev 1h
            "price_1h_pcnt_e6": -2825,                    //the current last price percentage change from prev 1h price
            "mark_price_e4": 81178500,                    //mark price
            "index_price_e4": 81172800,                   //index price
            "open_interest": 154418471,                   //open interest quantity - Attention, the update is not
                                                          //immediate - slowest update is 1 minute
            "open_value_e8": 1997561103030,               //open value quantity - Attention, the update is not
                                                          //immediate - the slowest update is 1 minute
            "total_turnover_e8": 2029370141961401,        //total turnover
            "turnover_24h_e8": 9072939873591,             //24h turnover
            "total_volume": 175654418740,                 //total volume
            "volume_24h": 735865248,                      //24h volume
            "funding_rate_e6": 100,                       //funding rate
            "predicted_funding_rate_e6": 100,             //predicted funding rate
            "cross_seq": 1053192577,                      //sequence
            "created_at": "2018-11-14T16:33:26Z",
            "updated_at": "2020-01-12T18:25:16Z",
            "next_funding_time": "2020-01-13T00:00:00Z",  //next funding time
                                                          //the rest time to settle funding fee
            "countdown_hour": 6                           //the remaining time to settle the funding fee
        },
        "cross_seq": 1053192634,
        "timestamp_e6": 1578853524091081                  //the timestamp when this information was produced
        }

        ### Delta type update
        {
        "topic": "instrument_info.100ms.BTCUSD",
        "type": "delta",
        "data": {
            "delete": [],
            "update": [
                {
                    "id": 1,
                    "symbol": "BTCUSD",
                    "prev_price_24h_e4": 81565000,
                    "price_24h_pcnt_e6": -4904,
                    "open_value_e8": 2000479681106,
                    "total_turnover_e8": 2029370495672976,
                    "turnover_24h_e8": 9066215468687,
                    "volume_24h": 735316391,
                    "cross_seq": 1053192657,
                    "created_at": "2018-11-14T16:33:26Z",
                    "updated_at": "2020-01-12T18:25:25Z"
                }
            ],
            "insert": []
        },
        "cross_seq": 1053192657,
        "timestamp_e6": 1578853525691123
        }
        """
        update_type = msg['type']

        if update_type == 'snapshot':
            updates = [msg['data']]
        else:
            updates = msg['data']['update']

        for info in updates:
            if msg['topic'] in self._instrument_info_cache and self._instrument_info_cache[msg['topic']] == updates:
                continue
            else:
                self._instrument_info_cache[msg['topic']] = updates

            ts = int(msg['timestamp_e6']) / 1_000_000

            if 'open_interest' in info:
                oi = OpenInterest(
                    self.id,
                    self.exchange_symbol_to_std_symbol(info['symbol']),
                    Decimal(info['open_interest']),
                    ts,
                    raw=info
                )
                await self.callback(OPEN_INTEREST, oi, timestamp)

            if 'index_price_e4' in info:
                i = Index(
                    self.id,
                    self.exchange_symbol_to_std_symbol(info['symbol']),
                    Decimal(info['index_price_e4']) * Decimal('1e-4'),
                    ts,
                    raw=info
                )
                await self.callback(INDEX, i, timestamp)

            if 'funding_rate_e6' in info:
                f = Funding(
                    self.id,
                    self.exchange_symbol_to_std_symbol(info['symbol']),
                    None,
                    Decimal(info['funding_rate_e6']) * Decimal('1e-6'),
                    info['next_funding_time'].timestamp(),
                    ts,
                    predicted_rate=Decimal(info['predicted_funding_rate_e6']) * Decimal('1e-6'),
                    raw=info
                )
                await self.callback(FUNDING, f, timestamp)
Esempio n. 6
0
    async def _instrument(self, msg: dict, timestamp: float):
        """
        Example instrument data

        {
        'table':'instrument',
        'action':'partial',
        'keys':[
            'symbol'
        ],
        'types':{
            'symbol':'symbol',
            'rootSymbol':'symbol',
            'state':'symbol',
            'typ':'symbol',
            'listing':'timestamp',
            'front':'timestamp',
            'expiry':'timestamp',
            'settle':'timestamp',
            'relistInterval':'timespan',
            'inverseLeg':'symbol',
            'sellLeg':'symbol',
            'buyLeg':'symbol',
            'optionStrikePcnt':'float',
            'optionStrikeRound':'float',
            'optionStrikePrice':'float',
            'optionMultiplier':'float',
            'positionCurrency':'symbol',
            'underlying':'symbol',
            'quoteCurrency':'symbol',
            'underlyingSymbol':'symbol',
            'reference':'symbol',
            'referenceSymbol':'symbol',
            'calcInterval':'timespan',
            'publishInterval':'timespan',
            'publishTime':'timespan',
            'maxOrderQty':'long',
            'maxPrice':'float',
            'lotSize':'long',
            'tickSize':'float',
            'multiplier':'long',
            'settlCurrency':'symbol',
            'underlyingToPositionMultiplier':'long',
            'underlyingToSettleMultiplier':'long',
            'quoteToSettleMultiplier':'long',
            'isQuanto':'boolean',
            'isInverse':'boolean',
            'initMargin':'float',
            'maintMargin':'float',
            'riskLimit':'long',
            'riskStep':'long',
            'limit':'float',
            'capped':'boolean',
            'taxed':'boolean',
            'deleverage':'boolean',
            'makerFee':'float',
            'takerFee':'float',
            'settlementFee':'float',
            'insuranceFee':'float',
            'fundingBaseSymbol':'symbol',
            'fundingQuoteSymbol':'symbol',
            'fundingPremiumSymbol':'symbol',
            'fundingTimestamp':'timestamp',
            'fundingInterval':'timespan',
            'fundingRate':'float',
            'indicativeFundingRate':'float',
            'rebalanceTimestamp':'timestamp',
            'rebalanceInterval':'timespan',
            'openingTimestamp':'timestamp',
            'closingTimestamp':'timestamp',
            'sessionInterval':'timespan',
            'prevClosePrice':'float',
            'limitDownPrice':'float',
            'limitUpPrice':'float',
            'bankruptLimitDownPrice':'float',
            'bankruptLimitUpPrice':'float',
            'prevTotalVolume':'long',
            'totalVolume':'long',
            'volume':'long',
            'volume24h':'long',
            'prevTotalTurnover':'long',
            'totalTurnover':'long',
            'turnover':'long',
            'turnover24h':'long',
            'homeNotional24h':'float',
            'foreignNotional24h':'float',
            'prevPrice24h':'float',
            'vwap':'float',
            'highPrice':'float',
            'lowPrice':'float',
            'lastPrice':'float',
            'lastPriceProtected':'float',
            'lastTickDirection':'symbol',
            'lastChangePcnt':'float',
            'bidPrice':'float',
            'midPrice':'float',
            'askPrice':'float',
            'impactBidPrice':'float',
            'impactMidPrice':'float',
            'impactAskPrice':'float',
            'hasLiquidity':'boolean',
            'openInterest':'long',
            'openValue':'long',
            'fairMethod':'symbol',
            'fairBasisRate':'float',
            'fairBasis':'float',
            'fairPrice':'float',
            'markMethod':'symbol',
            'markPrice':'float',
            'indicativeTaxRate':'float',
            'indicativeSettlePrice':'float',
            'optionUnderlyingPrice':'float',
            'settledPrice':'float',
            'timestamp':'timestamp'
        },
        'foreignKeys':{
            'inverseLeg':'instrument',
            'sellLeg':'instrument',
            'buyLeg':'instrument'
        },
        'attributes':{
            'symbol':'unique'
        },
        'filter':{
            'symbol':'XBTUSD'
        },
        'data':[
            {
                'symbol':'XBTUSD',
                'rootSymbol':'XBT',
                'state':'Open',
                'typ':'FFWCSX',
                'listing':'2016-05-13T12:00:00.000Z',
                'front':'2016-05-13T12:00:00.000Z',
                'expiry':None,
                'settle':None,
                'relistInterval':None,
                'inverseLeg':'',
                'sellLeg':'',
                'buyLeg':'',
                'optionStrikePcnt':None,
                'optionStrikeRound':None,
                'optionStrikePrice':None,
                'optionMultiplier':None,
                'positionCurrency':'USD',
                'underlying':'XBT',
                'quoteCurrency':'USD',
                'underlyingSymbol':'XBT=',
                'reference':'BMEX',
                'referenceSymbol':'.BXBT',
                'calcInterval':None,
                'publishInterval':None,
                'publishTime':None,
                'maxOrderQty':10000000,
                'maxPrice':1000000,
                'lotSize':1,
                'tickSize':Decimal(         '0.5'         ),
                'multiplier':-100000000,
                'settlCurrency':'XBt',
                'underlyingToPositionMultiplier':None,
                'underlyingToSettleMultiplier':-100000000,
                'quoteToSettleMultiplier':None,
                'isQuanto':False,
                'isInverse':True,
                'initMargin':Decimal(         '0.01'         ),
                'maintMargin':Decimal(         '0.005'         ),
                'riskLimit':20000000000,
                'riskStep':10000000000,
                'limit':None,
                'capped':False,
                'taxed':True,
                'deleverage':True,
                'makerFee':Decimal(         '-0.00025'         ),
                'takerFee':Decimal(         '0.00075'         ),
                'settlementFee':0,
                'insuranceFee':0,
                'fundingBaseSymbol':'.XBTBON8H',
                'fundingQuoteSymbol':'.USDBON8H',
                'fundingPremiumSymbol':'.XBTUSDPI8H',
                'fundingTimestamp':'2020-02-02T04:00:00.000Z',
                'fundingInterval':'2000-01-01T08:00:00.000Z',
                'fundingRate':Decimal(         '0.000106'         ),
                'indicativeFundingRate':Decimal(         '0.0001'         ),
                'rebalanceTimestamp':None,
                'rebalanceInterval':None,
                'openingTimestamp':'2020-02-02T00:00:00.000Z',
                'closingTimestamp':'2020-02-02T01:00:00.000Z',
                'sessionInterval':'2000-01-01T01:00:00.000Z',
                'prevClosePrice':Decimal(         '9340.63'         ),
                'limitDownPrice':None,
                'limitUpPrice':None,
                'bankruptLimitDownPrice':None,
                'bankruptLimitUpPrice':None,
                'prevTotalVolume':1999389257669,
                'totalVolume':1999420432348,
                'volume':31174679,
                'volume24h':1605909209,
                'prevTotalTurnover':27967114248663460,
                'totalTurnover':27967447182062520,
                'turnover':332933399058,
                'turnover24h':17126993087717,
                'homeNotional24h':Decimal(         '171269.9308771703'         ),
                'foreignNotional24h':1605909209,
                'prevPrice24h':9348,
                'vwap':Decimal(         '9377.3443'         ),
                'highPrice':9464,
                'lowPrice':Decimal(         '9287.5'         ),
                'lastPrice':9352,
                'lastPriceProtected':9352,
                'lastTickDirection':'ZeroMinusTick',
                'lastChangePcnt':Decimal(         '0.0004'         ),
                'bidPrice':9352,
                'midPrice':Decimal(         '9352.25'         ),
                'askPrice':Decimal(         '9352.5'         ),
                'impactBidPrice':Decimal(         '9351.9125'         ),
                'impactMidPrice':Decimal(         '9352.25'         ),
                'impactAskPrice':Decimal(         '9352.7871'         ),
                'hasLiquidity':True,
                'openInterest':983043322,
                'openValue':10518563545400,
                'fairMethod':'FundingRate',
                'fairBasisRate':Decimal(         '0.11607'         ),
                'fairBasis':Decimal(         '0.43'         ),
                'fairPrice':Decimal(         '9345.36'         ),
                'markMethod':'FairPrice',
                'markPrice':Decimal(         '9345.36'         ),
                'indicativeTaxRate':0,
                'indicativeSettlePrice':Decimal(         '9344.93'         ),
                'optionUnderlyingPrice':None,
                'settledPrice':None,
                'timestamp':'2020-02-02T00:30:43.772Z'
            }
        ]
        }
        """
        for data in msg['data']:
            if 'openInterest' in data:
                ts = self.timestamp_normalize(data['timestamp'])
                oi = OpenInterest(self.id, self.exchange_symbol_to_std_symbol(data['symbol']), Decimal(data['openInterest']), ts, raw=data)
                await self.callback(OPEN_INTEREST, oi, timestamp)
Esempio n. 7
0
    async def _ticker(self, msg: dict, timestamp: float):
        '''
        {
            "params" : {
                "data" : {
                    "timestamp" : 1550652954406,
                    "stats" : {
                        "volume" : null,
                        "low" : null,
                        "high" : null
                    },
                    "state" : "open",
                    "settlement_price" : 3960.14,
                    "open_interest" : 0.12759952124659626,
                    "min_price" : 3943.21,
                    "max_price" : 3982.84,
                    "mark_price" : 3940.06,
                    "last_price" : 3906,
                    "instrument_name" : "BTC-PERPETUAL",
                    "index_price" : 3918.51,
                    "funding_8h" : 0.01520525,
                    "current_funding" : 0.00499954,
                    "best_bid_price" : 3914.97,
                    "best_bid_amount" : 40,
                    "best_ask_price" : 3996.61,
                    "best_ask_amount" : 50
                    },
                "channel" : "ticker.BTC-PERPETUAL.raw"
            },
            "method" : "subscription",
            "jsonrpc" : "2.0"}
        '''
        pair = self.exchange_symbol_to_std_symbol(
            msg['params']['data']['instrument_name'])
        ts = self.timestamp_normalize(msg['params']['data']['timestamp'])
        t = Ticker(self.id,
                   pair,
                   Decimal(msg["params"]["data"]['best_bid_price']),
                   Decimal(msg["params"]["data"]['best_ask_price']),
                   ts,
                   raw=msg)
        await self.callback(TICKER, t, timestamp)

        if "current_funding" in msg["params"]["data"] and "funding_8h" in msg[
                "params"]["data"]:
            f = Funding(self.id,
                        pair,
                        Decimal(msg['params']['data']['mark_price']),
                        Decimal(msg["params"]["data"]["current_funding"]),
                        None,
                        ts,
                        raw=msg)
            await self.callback(FUNDING, f, timestamp)

        oi = msg['params']['data']['open_interest']
        if pair in self._open_interest_cache and oi == self._open_interest_cache[
                pair]:
            return
        self._open_interest_cache[pair] = oi
        o = OpenInterest(self.id, pair, Decimal(oi), ts, raw=msg)
        await self.callback(OPEN_INTEREST, o, timestamp)