def query_historical_price( self, from_asset: Asset, to_asset: Asset, timestamp: Timestamp, ) -> Price: vs_currency = Coingecko.check_vs_currencies( from_asset=from_asset, to_asset=to_asset, location='historical price', ) if not vs_currency: return Price(ZERO) try: from_coingecko_id = from_asset.to_coingecko() except UnsupportedAsset: log.warning( f'Tried to query coingecko historical price from {from_asset.identifier} ' f'to {to_asset.identifier}. But from_asset is not supported in coingecko', ) return Price(ZERO) date = timestamp_to_date(timestamp, formatstr='%d-%m-%Y') cached_price = self._get_cached_price(from_asset=from_asset, to_asset=to_asset, date=date) if cached_price is not None: return cached_price result = self._query( module='coins', subpath=f'{from_coingecko_id}/history', options={ 'date': date, 'localization': False, }, ) try: price = Price( FVal(result['market_data']['current_price'][vs_currency])) except KeyError as e: log.warning( f'Queried coingecko historical price from {from_asset.identifier} ' f'to {to_asset.identifier}. But got key error for {str(e)} when ' f'processing the result.', ) return Price(ZERO) self._save_cached_price(from_asset, to_asset, date, price) return price
def asset_data(self, asset: Asset) -> CoingeckoAssetData: """ May raise: - UnsupportedAsset() if the asset is not supported by coingecko - RemoteError if there is a problem querying coingecko """ options = { # Include all localized languages in response (true/false) [default: true] 'localization': False, # Include tickers data (true/false) [default: true] 'tickers': False, # Include market_data (true/false) [default: true] 'market_data': False, # Include communitydata (true/false) [default: true] 'community_data': False, # Include developer data (true/false) [default: true] 'developer_data': False, # Include sparkline 7 days data (eg. true, false) [default: false] 'sparkline': False, } gecko_id = asset.to_coingecko() data = self._query( module='coins', subpath=f'{gecko_id}', options=options, ) try: parsed_data = CoingeckoAssetData( identifier=gecko_id, symbol=data['symbol'], name=data['name'], description=data['description']['en'], images=CoingeckoImageURLs( thumb=data['image']['thumb'], small=data['image']['small'], large=data['image']['large'], ), ) except KeyError as e: raise RemoteError( f'Missing expected key entry {e} in coingecko coin data response', ) from e return parsed_data
def query_current_price(self, from_asset: Asset, to_asset: Asset) -> Price: """Returns a simple price for from_asset to to_asset in coingecko Uses the simple/price endpoint of coingecko. If to_asset is not part of the coingecko simple vs currencies or if from_asset is not supported in coingecko price zero is returned. May raise: - RemoteError if there is a problem querying coingecko """ vs_currency = Coingecko.check_vs_currencies( from_asset=from_asset, to_asset=to_asset, location='simple price', ) if not vs_currency: return Price(ZERO) try: from_coingecko_id = from_asset.to_coingecko() except UnsupportedAsset: log.warning( f'Tried to query coingecko simple price from {from_asset.identifier} ' f'to {to_asset.identifier}. But from_asset is not supported in coingecko', ) return Price(ZERO) result = self._query( module='simple/price', options={ 'ids': from_coingecko_id, 'vs_currencies': vs_currency, }) # https://github.com/PyCQA/pylint/issues/4739 try: return Price(FVal(result[from_coingecko_id][vs_currency])) # pylint: disable=unsubscriptable-object # noqa: E501 except KeyError as e: log.warning( f'Queried coingecko simple price from {from_asset.identifier} ' f'to {to_asset.identifier}. But got key error for {str(e)} when ' f'processing the result.', ) return Price(ZERO)
def query_historical_price( self, from_asset: Asset, to_asset: Asset, timestamp: Timestamp, ) -> Price: vs_currency = Coingecko.check_vs_currencies( from_asset=from_asset, to_asset=to_asset, location='historical price', ) if not vs_currency: return Price(ZERO) try: from_coingecko_id = from_asset.to_coingecko() except UnsupportedAsset: log.warning( f'Tried to query coingecko historical price from {from_asset.identifier} ' f'to {to_asset.identifier}. But from_asset is not supported in coingecko', ) return Price(ZERO) # check DB cache price_cache_entry = GlobalDBHandler().get_historical_price( from_asset=from_asset, to_asset=to_asset, timestamp=timestamp, max_seconds_distance=DAY_IN_SECONDS, source=HistoricalPriceOracle.COINGECKO, ) if price_cache_entry: return price_cache_entry.price # no cache, query coingecko for daily price date = timestamp_to_date(timestamp, formatstr='%d-%m-%Y') result = self._query( module='coins', subpath=f'{from_coingecko_id}/history', options={ 'date': date, 'localization': False, }, ) try: price = Price( FVal(result['market_data']['current_price'][vs_currency])) except KeyError as e: log.warning( f'Queried coingecko historical price from {from_asset.identifier} ' f'to {to_asset.identifier}. But got key error for {str(e)} when ' f'processing the result.', ) return Price(ZERO) # save result in the DB and return date_timestamp = create_timestamp(date, formatstr='%d-%m-%Y') GlobalDBHandler().add_historical_prices(entries=[ HistoricalPrice( from_asset=from_asset, to_asset=to_asset, source=HistoricalPriceOracle.COINGECKO, timestamp=date_timestamp, price=price, ) ]) return price