def find_usd_price(asset: Asset) -> Price: """Returns the current USD price of the asset Returns Price(ZERO) if all options have been exhausted and errors are logged in the logs """ if asset.identifier in SPECIAL_SYMBOLS: ethereum = Inquirer()._ethereum assert ethereum, 'Inquirer should never be called before the injection of ethereum' underlying_asset_price = get_underlying_asset_price( asset.identifier) usd_price = handle_defi_price_query( ethereum=ethereum, token_symbol=asset.identifier, underlying_asset_price=underlying_asset_price, ) if usd_price is None: return Price(ZERO) return Price(usd_price) try: price = Inquirer()._cryptocompare_find_usd_price(asset) except RemoteError: price = Price(ZERO) if price == Price(ZERO): try: price = Inquirer()._coingecko.simple_price(from_asset=asset, to_asset=A_USD) except RemoteError as e: log.error( f'Coingecko usd price query for {asset.identifier} failed due to {str(e)}', ) price = Price(ZERO) return price
def handle_protocols( self, protocol_name: str, token_symbol: str, normalized_balance: FVal, token_address: str, token_name: str, ) -> Optional[DefiBalance]: """Special handling for price for token/protocols which are easier to do onchain or need some kind of special treatment. """ if protocol_name == 'PoolTogether': result = _handle_pooltogether(normalized_balance, token_name) if result is not None: return result underlying_asset_price = get_underlying_asset_price(token_symbol) usd_price = handle_defi_price_query(self.ethereum, token_symbol, underlying_asset_price) if usd_price is None: return None return DefiBalance( token_address=to_checksum_address(token_address), token_name=token_name, token_symbol=token_symbol, balance=Balance(amount=normalized_balance, usd_value=normalized_balance * usd_price), )
def find_usd_price( asset: Asset, ignore_cache: bool = False, ) -> Price: """Returns the current USD price of the asset Returns Price(ZERO) if all options have been exhausted and errors are logged in the logs """ if asset == A_USD: return Price(FVal(1)) instance = Inquirer() cache_key = (asset, A_USD) if ignore_cache is False: cache = instance.get_cached_current_price_entry( cache_key=cache_key) if cache is not None: return cache.price if asset.is_fiat(): try: return instance._query_fiat_pair(base=asset, quote=A_USD) except RemoteError: pass # continue, a price can be found by one of the oracles (CC for example) if asset in instance.special_tokens: ethereum = instance._ethereum assert ethereum, 'Inquirer should never be called before the injection of ethereum' token = EthereumToken.from_asset(asset) assert token, 'all assets in special tokens are already ethereum tokens' underlying_asset_price = get_underlying_asset_price(token) usd_price = handle_defi_price_query( ethereum=ethereum, token=token, underlying_asset_price=underlying_asset_price, ) if usd_price is None: price = Price(ZERO) else: price = Price(usd_price) Inquirer._cached_current_price[cache_key] = CachedPriceEntry( price=price, time=ts_now()) # noqa: E501 return price return instance._query_oracle_instances(from_asset=asset, to_asset=A_USD)
def handle_protocols( self, protocol_name: str, token_symbol: str, normalized_balance: FVal, token_address: str, token_name: str, ) -> Optional[DefiBalance]: """Special handling for price for token/protocols which are easier to do onchain or need some kind of special treatment. This method can raise DeserializationError """ if protocol_name == 'PoolTogether': result = _handle_pooltogether(normalized_balance, token_name) if result is not None: return result asset = get_asset_by_symbol(token_symbol) if asset is None: return None token = EthereumToken.from_asset(asset) if token is None: return None underlying_asset_price = get_underlying_asset_price(token) usd_price = handle_defi_price_query(self.ethereum, token, underlying_asset_price) if usd_price is None: return None return DefiBalance( token_address=deserialize_ethereum_address(token_address), token_name=token_name, token_symbol=token_symbol, balance=Balance(amount=normalized_balance, usd_value=normalized_balance * usd_price), )
def find_usd_price( asset: Asset, ignore_cache: bool = False, ) -> Price: """Returns the current USD price of the asset Returns Price(ZERO) if all options have been exhausted and errors are logged in the logs """ instance = Inquirer() cache_key = (asset, A_USD) if ignore_cache is False: cache = instance.get_cached_price_entry(cache_key=cache_key) if cache is not None: return cache.price if asset.identifier in SPECIAL_SYMBOLS: ethereum = instance._ethereum assert ethereum, 'Inquirer should never be called before the injection of ethereum' underlying_asset_price = get_underlying_asset_price( asset.identifier) usd_price = handle_defi_price_query( ethereum=ethereum, token_symbol=asset.identifier, underlying_asset_price=underlying_asset_price, ) if usd_price is None: price = Price(ZERO) else: price = Price(usd_price) Inquirer._cached_current_price[cache_key] = CachedPriceEntry( price=price, time=ts_now()) # noqa: E501 return price return instance._query_oracle_instances(from_asset=asset, to_asset=A_USD)
def find_usd_price( asset: Asset, ignore_cache: bool = False, ) -> Price: """Returns the current USD price of the asset Returns Price(ZERO) if all options have been exhausted and errors are logged in the logs """ if asset == A_USD: return Price(FVal(1)) instance = Inquirer() cache_key = (asset, A_USD) if ignore_cache is False: cache = instance.get_cached_current_price_entry( cache_key=cache_key) if cache is not None: return cache.price if asset.is_fiat(): try: return instance._query_fiat_pair(base=asset, quote=A_USD) except RemoteError: pass # continue, a price can be found by one of the oracles (CC for example) # Try and check if it is an ethereum token with specified protocol or underlying tokens is_known_protocol = False underlying_tokens = None try: token = EthereumToken.from_asset(asset) if token is not None: if token.protocol is not None: is_known_protocol = token.protocol in KnownProtocolsAssets underlying_tokens = GlobalDBHandler( ).get_ethereum_token( # type: ignore token.ethereum_address, ).underlying_tokens except UnknownAsset: pass # Check if it is a special token if asset in instance.special_tokens: ethereum = instance._ethereum assert ethereum, 'Inquirer should never be called before the injection of ethereum' assert token, 'all assets in special tokens are already ethereum tokens' underlying_asset_price = get_underlying_asset_price(token) usd_price = handle_defi_price_query( ethereum=ethereum, token=token, underlying_asset_price=underlying_asset_price, ) if usd_price is None: price = Price(ZERO) else: price = Price(usd_price) Inquirer._cached_current_price[cache_key] = CachedPriceEntry( price=price, time=ts_now()) # noqa: E501 return price if is_known_protocol is True or underlying_tokens is not None: assert token is not None result = get_underlying_asset_price(token) if result is None: usd_price = Price(ZERO) if instance._ethereum is not None: instance._ethereum.msg_aggregator.add_warning( f'Could not find price for {token}', ) else: usd_price = Price(result) Inquirer._cached_current_price[cache_key] = CachedPriceEntry( price=usd_price, time=ts_now(), ) return usd_price # BSQ is a special asset that doesnt have oracle information but its custom API if asset == A_BSQ: try: price_in_btc = get_bisq_market_price(asset) btc_price = Inquirer().find_usd_price(A_BTC) usd_price = Price(price_in_btc * btc_price) Inquirer._cached_current_price[cache_key] = CachedPriceEntry( price=usd_price, time=ts_now(), ) return usd_price except (RemoteError, DeserializationError) as e: msg = f'Could not find price for BSQ. {str(e)}' if instance._ethereum is not None: instance._ethereum.msg_aggregator.add_warning(msg) return Price(BTC_PER_BSQ * price_in_btc) if asset == A_KFEE: # KFEE is a kraken special asset where 1000 KFEE = 10 USD return Price(FVal(0.01)) return instance._query_oracle_instances(from_asset=asset, to_asset=A_USD)
def find_usd_price( asset: Asset, ignore_cache: bool = False, ) -> Price: """Returns the current USD price of the asset Returns Price(ZERO) if all options have been exhausted and errors are logged in the logs """ if asset == A_USD: return Price(FVal(1)) instance = Inquirer() cache_key = (asset, A_USD) if ignore_cache is False: cache = instance.get_cached_current_price_entry( cache_key=cache_key) if cache is not None: return cache.price if asset.is_fiat(): try: return instance._query_fiat_pair(base=asset, quote=A_USD) except RemoteError: pass # continue, a price can be found by one of the oracles (CC for example) # Try and check if it is an ethereum token with specified protocol or underlying tokens is_known_protocol = False underlying_tokens = None try: token = EthereumToken.from_asset(asset) if token is not None: if token.protocol is not None: is_known_protocol = token.protocol in KnownProtocolsAssets underlying_tokens = GlobalDBHandler( ).get_ethereum_token( # type: ignore token.ethereum_address, ).underlying_tokens except UnknownAsset: pass # Check if it is a special token if asset in instance.special_tokens: ethereum = instance._ethereum assert ethereum, 'Inquirer should never be called before the injection of ethereum' assert token, 'all assets in special tokens are already ethereum tokens' underlying_asset_price = get_underlying_asset_price(token) usd_price = handle_defi_price_query( ethereum=ethereum, token=token, underlying_asset_price=underlying_asset_price, ) if usd_price is None: price = Price(ZERO) else: price = Price(usd_price) Inquirer._cached_current_price[cache_key] = CachedPriceEntry( price=price, time=ts_now()) # noqa: E501 return price if is_known_protocol is True or underlying_tokens is not None: assert token is not None result = get_underlying_asset_price(token) usd_price = Price(ZERO) if result is None else Price(result) Inquirer._cached_current_price[cache_key] = CachedPriceEntry( price=usd_price, time=ts_now(), ) return usd_price return instance._query_oracle_instances(from_asset=asset, to_asset=A_USD)