Spaces:
Running
Running
File size: 4,624 Bytes
97873ec 76f2683 97873ec fd31489 476cee0 2ac36a0 fd31489 19f368e fd31489 c95cace 76f2683 c95cace 76f2683 c95cace 76f2683 fd31489 76f2683 431e338 19f368e fd31489 76f2683 19f368e 476cee0 76f2683 476cee0 c95cace 19f368e 76f2683 19f368e 431e338 76f2683 431e338 76f2683 431e338 c95cace 431e338 76f2683 431e338 76f2683 19f368e 431e338 76f2683 431e338 76f2683 c95cace 431e338 76f2683 431e338 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
"""
A professional-grade, multi-asset, multi-oracle price engine.
This engine dynamically fetches prices for a configured list of assets
from decentralized oracles to detect market dislocations.
"""
import asyncio
import logging
from typing import Dict, Optional
import httpx
logger = logging.getLogger(__name__)
# ====================================================================
# THE "MONEY-SPINNING" UPGRADE IS HERE
# ====================================================================
# This is our master watchlist. The engine will hunt for opportunities
# across all 10 of these high-volume assets simultaneously.
ASSET_CONFIG = {
"BTC": {
"pyth_id": "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415B43",
"coingecko_id": "bitcoin",
},
"ETH": {
"pyth_id": "ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace",
"coingecko_id": "ethereum",
},
"SOL": {
"pyth_id": "ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d",
"coingecko_id": "solana",
},
"XRP": {
"pyth_id": "02a01e69981d314fd8a723be08253181e53b4945b4bf376d15a51980a37330c3",
"coingecko_id": "ripple",
},
"DOGE": {
"pyth_id": "042f02faf4229babc62635593855b6a383d6a4a2a1b9b9a7c385a4a50b86a345",
"coingecko_id": "dogecoin",
},
"ADA": {
"pyth_id": "34f544985c7943c093b5934963505a767f4749445244a852654c6017b28091ea",
"coingecko_id": "cardano",
},
"AVAX": {
"pyth_id": "0x141f2a3c34c8035443a01d64380b52207991b16c14c5145f617eb578a994753c",
"coingecko_id": "avalanche-2",
},
"LINK": {
"pyth_id": "0x63f4f4755a5a67c64c781d45763b33a72666a15e6b91c0fbdf3b2f205d5a6b01",
"coingecko_id": "chainlink",
},
"DOT": {
"pyth_id": "0x00a896677493a74421b33362a7447785b13612f0e340d418641a33716a5067a3",
"coingecko_id": "polkadot",
},
"MATIC": {
"pyth_id": "0x737ac3c13709b45da8128ff9e1058a984f86a048035656111b8a365e4921648a",
"coingecko_id": "matic-network",
},
}
# ====================================================================
class PriceFetcher:
PYTH_URL = "https://hermes.pyth.network/v2/updates/price/latest"
AGGREGATOR_URL = "https://api.coingecko.com/api/v3/simple/price"
def __init__(self, client: httpx.AsyncClient):
self.client = client
self._prices: Dict[str, Dict[str, Optional[float]]] = {}
self._lock = asyncio.Lock()
async def _fetch_pyth_prices(self) -> Dict[str, float]:
pyth_ids = [v['pyth_id'] for v in ASSET_CONFIG.values()]
params = [("ids[]", pid) for pid in pyth_ids]
try:
resp = await self.client.get(self.PYTH_URL, params=params, timeout=10)
resp.raise_for_status()
parsed_data = resp.json().get('parsed', [])
id_to_symbol = {v['pyth_id']: k for k, v in ASSET_CONFIG.items()}
return {
id_to_symbol[item['id']]: int(item['price']['price']) / (10 ** abs(int(item['price']['expo'])))
for item in parsed_data if item['id'] in id_to_symbol
}
except Exception as e:
logger.error(f"β Oracle Error (Pyth): {e}")
return {}
async def _fetch_aggregator_prices(self) -> Dict[str, float]:
coingecko_ids = ",".join([v['coingecko_id'] for v in ASSET_CONFIG.values()])
params = {"ids": coingecko_ids, "vs_currencies": "usd"}
try:
resp = await self.client.get(self.AGGREGATOR_URL, params=params, timeout=10)
resp.raise_for_status()
data = resp.json()
id_to_symbol = {v['coingecko_id']: k for k, v in ASSET_CONFIG.items()}
return {id_to_symbol[cg_id]: prices['usd'] for cg_id, prices in data.items()}
except Exception as e:
logger.error(f"β Oracle Error (Aggregator): {e}")
return {}
async def update_prices_async(self):
pyth_task = self._fetch_pyth_prices()
agg_task = self._fetch_aggregator_prices()
pyth_prices, agg_prices = await asyncio.gather(pyth_task, agg_task)
async with self._lock:
for symbol in ASSET_CONFIG.keys():
self._prices[symbol] = {
"pyth": pyth_prices.get(symbol),
"chainlink_agg": agg_prices.get(symbol)
}
logger.info(f"β
Multi-Asset Prices Updated")
def get_all_prices(self) -> Dict[str, Dict[str, Optional[float]]]:
return self._prices.copy() |