Beispiel #1
0
    def query_endpoint_price(
        self,
        from_asset: Asset,
        to_asset: Asset,
        handling_special_case: bool = False,
    ) -> Dict[str, Any]:
        """Returns the current price of an asset compared to another asset

        - May raise RemoteError if there is a problem reaching the cryptocompare server
        or with reading the response returned by the server
        - May raise PriceQueryUnsupportedAsset if from/to assets are not known to cryptocompare
        """
        special_asset = (from_asset in CRYPTOCOMPARE_SPECIAL_CASES
                         or to_asset in CRYPTOCOMPARE_SPECIAL_CASES)
        if special_asset and not handling_special_case:
            return self._special_case_handling(
                method_name='query_endpoint_price',
                from_asset=from_asset,
                to_asset=to_asset,
            )
        try:
            cc_from_asset_symbol = from_asset.to_cryptocompare()
            cc_to_asset_symbol = to_asset.to_cryptocompare()
        except UnsupportedAsset as e:
            raise PriceQueryUnsupportedAsset(e.asset_name)

        query_path = f'price?fsym={cc_from_asset_symbol}&tsyms={cc_to_asset_symbol}'
        result = self._api_query(path=query_path)
        return result
Beispiel #2
0
    def query_endpoint_price(
            self,
            from_asset: Asset,
            to_asset: Asset,
            handling_special_case: bool = False,
    ) -> Dict[str, Any]:
        """Returns the current price of an asset compared to another asset

        - May raise RemoteError if there is a problem reaching the cryptocompare server
        or with reading the response returned by the server
        """
        special_asset = (
            from_asset in CRYPTOCOMPARE_SPECIAL_CASES or to_asset in CRYPTOCOMPARE_SPECIAL_CASES
        )
        if special_asset and not handling_special_case:
            return self._special_case_handling(
                method_name='query_endpoint_price',
                from_asset=from_asset,
                to_asset=to_asset,
            )
        # These two can raise but them raising here is a bug
        cc_from_asset_symbol = from_asset.to_cryptocompare()
        cc_to_asset_symbol = to_asset.to_cryptocompare()
        query_path = f'price?fsym={cc_from_asset_symbol}&tsyms={cc_to_asset_symbol}'
        result = self._api_query(path=query_path)
        return result
Beispiel #3
0
    def query_endpoint_pricehistorical(
            self,
            from_asset: Asset,
            to_asset: Asset,
            timestamp: Timestamp,
    ) -> Price:
        """Queries the historical daily price of from_asset to to_asset for timestamp

        - May raise RemoteError if there is a problem reaching the cryptocompare server
        or with reading the response returned by the server
        """
        log.debug(
            'Querying cryptocompare for daily historical price',
            from_asset=from_asset,
            to_asset=to_asset,
            timestamp=timestamp,
        )
        # These two can raise but them raising here is a bug
        cc_from_asset_symbol = from_asset.to_cryptocompare()
        cc_to_asset_symbol = to_asset.to_cryptocompare()
        query_path = (
            f'pricehistorical?fsym={cc_from_asset_symbol}&tsyms={cc_to_asset_symbol}'
            f'&ts={timestamp}'
        )
        if to_asset == 'BTC':
            query_path += '&tryConversion=false'
        result = self._api_query(query_path)
        return Price(FVal(result[cc_from_asset_symbol][cc_to_asset_symbol]))
Beispiel #4
0
    def query_current_price(
        self,
        from_asset: Asset,
        to_asset: Asset,
        handling_special_case: bool = False,
    ) -> Price:
        """Returns the current price of an asset compared to another asset

        - May raise RemoteError if there is a problem reaching the cryptocompare server
        or with reading the response returned by the server
        - May raise PriceQueryUnsupportedAsset if from/to assets are not known to cryptocompare
        """
        special_asset = (from_asset.identifier in CRYPTOCOMPARE_SPECIAL_CASES
                         or to_asset.identifier in CRYPTOCOMPARE_SPECIAL_CASES)
        if special_asset and not handling_special_case:
            return self._special_case_handling(
                method_name='query_current_price',
                from_asset=from_asset,
                to_asset=to_asset,
            )
        try:
            cc_from_asset_symbol = from_asset.to_cryptocompare()
            cc_to_asset_symbol = to_asset.to_cryptocompare()
        except UnsupportedAsset as e:
            raise PriceQueryUnsupportedAsset(e.asset_name) from e

        query_path = f'price?fsym={cc_from_asset_symbol}&tsyms={cc_to_asset_symbol}'
        result = self._api_query(path=query_path)
        # Up until 23/09/2020 cryptocompare may return {} due to bug.
        # Handle that case by assuming 0 if that happens
        if cc_to_asset_symbol not in result:
            return Price(ZERO)

        return Price(FVal(result[cc_to_asset_symbol]))
Beispiel #5
0
    def query_endpoint_histohour(
            self,
            from_asset: Asset,
            to_asset: Asset,
            limit: int,
            to_timestamp: Timestamp,
            handling_special_case: bool = False,
    ) -> Dict[str, Any]:
        """Returns the full histohour response including TimeFrom and TimeTo

        - May raise RemoteError if there is a problem reaching the cryptocompare server
        or with reading the response returned by the server
        """
        special_asset = (
            from_asset in CRYPTOCOMPARE_SPECIAL_CASES or to_asset in CRYPTOCOMPARE_SPECIAL_CASES
        )
        if special_asset and not handling_special_case:
            return self._special_case_handling(
                method_name='query_endpoint_histohour',
                from_asset=from_asset,
                to_asset=to_asset,
                limit=limit,
                to_timestamp=to_timestamp,
            )

        # These two can raise but them raising here is a bug
        cc_from_asset_symbol = from_asset.to_cryptocompare()
        cc_to_asset_symbol = to_asset.to_cryptocompare()
        query_path = (
            f'v2/histohour?fsym={cc_from_asset_symbol}&tsym={cc_to_asset_symbol}'
            f'&limit={limit}&toTs={to_timestamp}'
        )
        result = self._api_query(path=query_path)
        return result
Beispiel #6
0
def _get_cache_key(from_asset: Asset, to_asset: Asset) -> Optional[PairCacheKey]:
    try:
        from_cc_asset = from_asset.to_cryptocompare()
        to_cc_asset = to_asset.to_cryptocompare()
    except UnsupportedAsset:
        return None

    return PairCacheKey(from_cc_asset + '_' + to_cc_asset)
Beispiel #7
0
def _get_cache_key(from_asset: Asset, to_asset: Asset) -> Optional[PairCacheKey]:
    try:  # first see if they both support cryptocompare
        from_asset.to_cryptocompare()
        to_asset.to_cryptocompare()
    except UnsupportedAsset:
        return None

    return PairCacheKey(from_asset.identifier + '_' + to_asset.identifier)
Beispiel #8
0
    def query_endpoint_pricehistorical(
            self,
            from_asset: Asset,
            to_asset: Asset,
            timestamp: Timestamp,
            handling_special_case: bool = False,
    ) -> Price:
        """Queries the historical daily price of from_asset to to_asset for timestamp

        - May raise RemoteError if there is a problem reaching the cryptocompare server
        or with reading the response returned by the server
        - May raise PriceQueryUnsupportedAsset if from/to assets are not known to cryptocompare
        """
        log.debug(
            'Querying cryptocompare for daily historical price',
            from_asset=from_asset,
            to_asset=to_asset,
            timestamp=timestamp,
        )
        special_asset = (
            from_asset.identifier in CRYPTOCOMPARE_SPECIAL_CASES or
            to_asset.identifier in CRYPTOCOMPARE_SPECIAL_CASES
        )
        if special_asset and not handling_special_case:
            return self._special_case_handling(
                method_name='query_endpoint_pricehistorical',
                from_asset=from_asset,
                to_asset=to_asset,
                timestamp=timestamp,
            )

        try:
            cc_from_asset_symbol = from_asset.to_cryptocompare()
            cc_to_asset_symbol = to_asset.to_cryptocompare()
        except UnsupportedAsset as e:
            raise PriceQueryUnsupportedAsset(e.asset_name) from e

        query_path = (
            f'pricehistorical?fsym={cc_from_asset_symbol}&tsyms={cc_to_asset_symbol}'
            f'&ts={timestamp}'
        )
        if to_asset == 'BTC':
            query_path += '&tryConversion=false'
        result = self._api_query(query_path)
        # Up until 23/09/2020 cryptocompare may return {} due to bug.
        # Handle that case by assuming 0 if that happens
        if (
            cc_from_asset_symbol not in result or
            cc_to_asset_symbol not in result[cc_from_asset_symbol]
        ):
            return Price(ZERO)

        return Price(FVal(result[cc_from_asset_symbol][cc_to_asset_symbol]))
Beispiel #9
0
 def query_endpoint_histohour(
     self,
     from_asset: Asset,
     to_asset: Asset,
     limit: int,
     to_timestamp: Timestamp,
 ) -> Dict[str, Any]:
     """Returns the full histohour response including TimeFrom and TimeTo"""
     # These two can raise but them raising here is a bug
     cc_from_asset_symbol = from_asset.to_cryptocompare()
     cc_to_asset_symbol = to_asset.to_cryptocompare()
     query_path = (
         f'histohour?fsym={cc_from_asset_symbol}&tsym={cc_to_asset_symbol}'
         f'&limit={limit}&toTs={to_timestamp}')
     result = self._api_query(path=query_path)
     return result
Beispiel #10
0
    def query_endpoint_price(
            self,
            from_asset: Asset,
            to_asset: Asset,
    ) -> Dict[str, Any]:
        """Returns the current price of an asset compared to another asset

        - May raise RemoteError if there is a problem reaching the cryptocompare server
        or with reading the response returned by the server
        """
        # These two can raise but them raising here is a bug
        cc_from_asset_symbol = from_asset.to_cryptocompare()
        cc_to_asset_symbol = to_asset.to_cryptocompare()
        query_path = f'price?fsym={cc_from_asset_symbol}&tsyms={cc_to_asset_symbol}'
        result = self._api_query(path=query_path)
        return result
Beispiel #11
0
def query_cryptocompare_for_fiat_price(asset: Asset) -> Price:
    log.debug('Get usd price from cryptocompare', asset=asset)
    cc_asset_str = asset.to_cryptocompare()
    resp = retry_calls(
        5,
        'find_usd_price',
        'requests.get',
        requests.get,
        u'https://min-api.cryptocompare.com/data/price?'
        'fsym={}&tsyms=USD'.format(cc_asset_str),
    )

    if resp.status_code != 200:
        raise RemoteError(
            'Cant reach cryptocompare to get USD value of {}'.format(asset))

    resp = rlk_jsonloads_dict(resp.text)

    # If there is an error in the response skip this token
    if 'USD' not in resp:
        error_message = ''
        if resp['Response'] == 'Error':
            error_message = resp['Message']

        log.error(
            'Cryptocompare usd price query failed',
            asset=asset,
            error=error_message,
        )
        return Price(ZERO)

    price = Price(FVal(resp['USD']))
    log.debug('Got usd price from cryptocompare', asset=asset, price=price)
    return price
Beispiel #12
0
 def query_endpoint_histohour(
         self,
         from_asset: Asset,
         to_asset: Asset,
         limit: int,
         to_timestamp: Timestamp,
 ) -> Dict[str, Any]:
     # These two can raise but them raising here is a bug
     cc_from_asset_symbol = from_asset.to_cryptocompare()
     cc_to_asset_symbol = to_asset.to_cryptocompare()
     query_path = (
         f'histohour?fsym={cc_from_asset_symbol}&tsym={cc_to_asset_symbol}'
         f'&limit={limit}&toTs={to_timestamp}'
     )
     result = self._api_query(path=query_path, only_data=False)
     return result
Beispiel #13
0
    def query_endpoint_pricehistorical(
            self,
            from_asset: Asset,
            to_asset: Asset,
            timestamp: Timestamp,
            handling_special_case: bool = False,
    ) -> Price:
        """Queries the historical daily price of from_asset to to_asset for timestamp

        - May raise RemoteError if there is a problem reaching the cryptocompare server
        or with reading the response returned by the server
        """
        log.debug(
            'Querying cryptocompare for daily historical price',
            from_asset=from_asset,
            to_asset=to_asset,
            timestamp=timestamp,
        )
        special_asset = (
            from_asset in CRYPTOCOMPARE_SPECIAL_CASES or to_asset in CRYPTOCOMPARE_SPECIAL_CASES
        )
        if special_asset and not handling_special_case:
            return self._special_case_handling(
                method_name='query_endpoint_pricehistorical',
                from_asset=from_asset,
                to_asset=to_asset,
                timestamp=timestamp,
            )

        # These two can raise but them raising here is a bug
        cc_from_asset_symbol = from_asset.to_cryptocompare()
        cc_to_asset_symbol = to_asset.to_cryptocompare()
        query_path = (
            f'pricehistorical?fsym={cc_from_asset_symbol}&tsyms={cc_to_asset_symbol}'
            f'&ts={timestamp}'
        )
        if to_asset == 'BTC':
            query_path += '&tryConversion=false'
        result = self._api_query(query_path)
        return Price(FVal(result[cc_from_asset_symbol][cc_to_asset_symbol]))
Beispiel #14
0
 def query_endpoint_pricehistorical(
     self,
     from_asset: Asset,
     to_asset: Asset,
     timestamp: Timestamp,
 ) -> Price:
     log.debug(
         'Querying cryptocompare for daily historical price',
         from_asset=from_asset,
         to_asset=to_asset,
         timestamp=timestamp,
     )
     # These two can raise but them raising here is a bug
     cc_from_asset_symbol = from_asset.to_cryptocompare()
     cc_to_asset_symbol = to_asset.to_cryptocompare()
     query_path = (
         f'pricehistorical?fsym={cc_from_asset_symbol}&tsyms={cc_to_asset_symbol}'
         f'&ts={timestamp}')
     if to_asset == 'BTC':
         query_path += '&tryConversion=false'
     result = self._api_query(query_path)
     return Price(FVal(result[cc_from_asset_symbol][cc_to_asset_symbol]))
Beispiel #15
0
    def query_endpoint_histohour(
            self,
            from_asset: Asset,
            to_asset: Asset,
            limit: int,
            to_timestamp: Timestamp,
            handling_special_case: bool = False,
    ) -> Dict[str, Any]:
        """Returns the full histohour response including TimeFrom and TimeTo

        - May raise RemoteError if there is a problem reaching the cryptocompare server
        or with reading the response returned by the server
        - May raise PriceQueryUnsupportedAsset if from/to assets are not known to cryptocompare
        """
        special_asset = (
            from_asset.identifier in CRYPTOCOMPARE_SPECIAL_CASES or
            to_asset.identifier in CRYPTOCOMPARE_SPECIAL_CASES
        )
        if special_asset and not handling_special_case:
            return self._special_case_handling(
                method_name='query_endpoint_histohour',
                from_asset=from_asset,
                to_asset=to_asset,
                limit=limit,
                to_timestamp=to_timestamp,
            )

        try:
            cc_from_asset_symbol = from_asset.to_cryptocompare()
            cc_to_asset_symbol = to_asset.to_cryptocompare()
        except UnsupportedAsset as e:
            raise PriceQueryUnsupportedAsset(e.asset_name) from e

        query_path = (
            f'v2/histohour?fsym={cc_from_asset_symbol}&tsym={cc_to_asset_symbol}'
            f'&limit={limit}&toTs={to_timestamp}'
        )
        result = self._api_query(path=query_path)
        return result
Beispiel #16
0
def query_cryptocompare_for_fiat_price(asset: Asset) -> Price:
    log.debug('Get usd price from cryptocompare', asset=asset)
    cc_asset_str = asset.to_cryptocompare()
    resp = retry_calls(
        times=5,
        location='find_usd_price',
        handle_429=False,
        backoff_in_seconds=0,
        method_name='requests.get',
        function=requests.get,
        # function's arguments
        url=(
            u'https://min-api.cryptocompare.com/data/price?'
            'fsym={}&tsyms=USD'.format(cc_asset_str)
        ),
    )

    if resp.status_code != 200:
        raise RemoteError('Cant reach cryptocompare to get USD value of {}'.format(asset))

    resp = rlk_jsonloads_dict(resp.text)

    # If there is an error in the response skip this token
    if 'USD' not in resp:
        error_message = ''
        if resp.get('Response', None) == 'Error':
            error_message = resp.get('Message', '')

        log.error(
            'Cryptocompare usd price query failed',
            asset=asset,
            error=error_message,
        )
        return Price(ZERO)

    price = Price(FVal(resp['USD']))
    log.debug('Got usd price from cryptocompare', asset=asset, price=price)
    return price