import logging import requests logger = logging.getLogger(__name__) def fetch_fear_greed() -> dict: """Fetch Fear & Greed index from alternative.me (no API key needed).""" try: resp = requests.get("https://api.alternative.me/fng/?limit=1", timeout=10) resp.raise_for_status() data = resp.json() item = data["data"][0] return { "value": int(item["value"]), "label": item["value_classification"], "timestamp": item["timestamp"], } except Exception as e: logger.warning(f"Fear & Greed fetch failed: {e}") return {"value": 50, "label": "Neutral", "timestamp": ""} def fetch_funding_rate(asset: str) -> float | None: """Fetch current funding rate from Binance public API.""" symbol_map = {"BTC/USDT": "BTCUSDT", "ETH/USDT": "ETHUSDT"} symbol = symbol_map.get(asset, asset.replace("/", "")) try: url = "https://fapi.binance.com/fapi/v1/fundingRate" params = {"symbol": symbol, "limit": 1} resp = requests.get(url, params=params, timeout=10) resp.raise_for_status() data = resp.json() if data: return float(data[-1]["fundingRate"]) * 100 # as percentage except Exception as e: logger.warning(f"Funding rate fetch failed for {asset}: {e}") return None def fetch_onchain_data(asset: str) -> dict: """Aggregate all on-chain data for one asset.""" return { "fear_greed": fetch_fear_greed(), "funding_rate": fetch_funding_rate(asset), }