Add support for reporting a new spot price¶
Prerequisites¶
- Python >= 3.9, < 3.10
- Setup environment (see here)
Steps¶
- Add spot price to catalog. See
src/telliot_feeds/queries/query_catalog.py
. For example addingETH/USD
:query_catalog.add_entry( tag="eth-usd-spot", title="ETH/USD spot price", q=SpotPrice(asset="eth", currency="usd"), )
-
Add data feed in
src/telliot_feeds/feeds/
. For example, for addingETH/USD
, create filesrc/telliot_feeds/feeds/eth_usd_feed.py
:Above, we use thefrom telliot_feeds.datafeed import DataFeed from telliot_feeds.queries.price.spot_price import SpotPrice from telliot_feeds.sources.price.spot.binance import BinanceSpotPriceSource from telliot_feeds.sources.price.spot.coinbase import CoinbaseSpotPriceSource from telliot_feeds.sources.price.spot.coingecko import CoinGeckoSpotPriceSource from telliot_feeds.sources.price.spot.gemini import GeminiSpotPriceSource from telliot_feeds.sources.price.spot.kraken import KrakenSpotPriceSource from telliot_feeds.sources.price_aggregator import PriceAggregator eth_usd_median_feed = DataFeed( query=SpotPrice(asset="ETH", currency="USD"), source=PriceAggregator( asset="eth", currency="usd", algorithm="median", sources=[ CoinGeckoSpotPriceSource(asset="eth", currency="usd"), BinanceSpotPriceSource(asset="eth", currency="usdt"), CoinbaseSpotPriceSource(asset="eth", currency="usd"), GeminiSpotPriceSource(asset="eth", currency="usd"), KrakenSpotPriceSource(asset="eth", currency="usd"), ], ), )
PriceAggregator
to aggregate the price from multiple sources (automatic API fetches, not sources that require manual entry). Thealgorithm
can bemedian
ormean
. Thesources
can be any combination of those found insrc/telliot_feeds/sources/price/spot/
, or you can add your own.You're limited by what asset and currency pairs are supported by the underlying APIs (data providers). For example, if you want to add
ETH/JPY
, you might use theCoinGeckoSpotPriceSource
andBinanceSpotPriceSource
(which supportETH/JPY
), but not theCoinbaseSpotPriceSource
(which does not supportETH/JPY
). You'll have to check the documentation of the underlying APIs for which pairs they support. -
Add feed to
CATALOG_FEEDS
constant insrc/telliot_feeds/feeds/__init__.py
:from telliot_feeds.feeds.eth_usd_feed import eth_usd_median_feed CATALOG_FEEDS = { ... "eth-usd-spot": eth_usd_median_feed, }
- Add currency/asset to supported lists in
src/telliot_feeds/queries/price/spot_price.py
. For example, for addingETH/USD
:CURRENCIES = ["usd", "jpy", "eth"] SPOT_PRICE_PAIRS = [ ... "ETH/USD", ]
- Test your new feed in
tests/feeds/
. For example, once you've created a datafeed for anETH/USD
spot price using an aggregate of a few price sourcees, create filetests/feeds/test_eth_usd_feed.py
:import statistics import pytest from telliot_feeds.feeds.eth_usd_feed import eth_usd_median_feed @pytest.mark.asyncio async def test_eth_usd_median_feed(caplog): """Retrieve median ETH/USD price.""" v, _ = await eth_usd_median_feed.source.fetch_new_datapoint() assert v is not None assert v > 0 assert ( "sources used in aggregate: 4" in caplog.text.lower() or "sources used in aggregate: 5" in caplog.text.lower() ) print(f"ETH/USD Price: {v}") # Get list of data sources from sources dict source_prices = [source.latest[0] for source in eth_usd_median_feed.source.sources if source.latest[0]] # Make sure error is less than decimal tolerance assert (v - statistics.median(source_prices)) < 10**-6
- Create a pull request to merge your changes into the
main
branch here.