#!/usr/bin/env python3 """ 数据源验证脚本 - 第二批 社交媒体 + 新闻情绪 + 衍生品 + 新增数据源(目标 40+) 验证时间:2026-03-06 """ import requests import json import time TIMEOUT = 15 results = {} def test(name, fn): try: start = time.time() data = fn() elapsed = round((time.time() - start) * 1000) results[name] = {"status": "✅ 通过", "latency_ms": elapsed, "sample": data} print(f"✅ {name} ({elapsed}ms): {json.dumps(data, ensure_ascii=False, default=str)[:150]}") except Exception as e: results[name] = {"status": "❌ 失败", "error": str(e)} print(f"❌ {name}: {e}") # ─── 社交媒体 ────────────────────────────────────────────────────────────── # 1. Alternative.me 恐惧贪婪(已验证,重复确认) def test_fear_greed(): url = "https://api.alternative.me/fng/?limit=7&format=json" r = requests.get(url, timeout=TIMEOUT) r.raise_for_status() d = r.json()["data"] return {"latest_value": d[0]["value"], "latest_class": d[0]["value_classification"], "7day_avg": round(sum(int(x["value"]) for x in d)/7, 1)} test("Alternative.me恐惧贪婪(7日均值)", test_fear_greed) # 2. Reddit r/Bitcoin 热门帖子(无需 API Key) def test_reddit_bitcoin(): url = "https://www.reddit.com/r/Bitcoin/hot.json?limit=5" r = requests.get(url, headers={"User-Agent": "QuantKnowledge/1.0 (research bot)"}, timeout=TIMEOUT) r.raise_for_status() posts = r.json()["data"]["children"] return { "post_count": len(posts), "top_post": {"title": posts[0]["data"]["title"][:60], "score": posts[0]["data"]["score"], "comments": posts[0]["data"]["num_comments"]}, "subreddit_subscribers": posts[0]["data"]["subreddit_subscribers"] } test("Reddit r/Bitcoin热门帖子", test_reddit_bitcoin) # 3. Reddit r/CryptoCurrency def test_reddit_crypto(): url = "https://www.reddit.com/r/CryptoCurrency/hot.json?limit=5" r = requests.get(url, headers={"User-Agent": "QuantKnowledge/1.0 (research bot)"}, timeout=TIMEOUT) r.raise_for_status() posts = r.json()["data"]["children"] return { "post_count": len(posts), "top_post": {"title": posts[0]["data"]["title"][:60], "score": posts[0]["data"]["score"]}, "subreddit_subscribers": posts[0]["data"]["subreddit_subscribers"] } test("Reddit r/CryptoCurrency热门帖子", test_reddit_crypto) # 4. Reddit r/algotrading def test_reddit_algo(): url = "https://www.reddit.com/r/algotrading/hot.json?limit=3" r = requests.get(url, headers={"User-Agent": "QuantKnowledge/1.0 (research bot)"}, timeout=TIMEOUT) r.raise_for_status() posts = r.json()["data"]["children"] return {"top_post": posts[0]["data"]["title"][:80], "score": posts[0]["data"]["score"]} test("Reddit r/algotrading热门帖子", test_reddit_algo) # 5. Nitter RSS(X/Twitter 免费方案) def test_nitter_rss(): # 尝试多个 Nitter 实例 instances = [ "https://nitter.privacydev.net", "https://nitter.poast.org", "https://nitter.net", ] for instance in instances: try: url = f"{instance}/glassnode/rss" r = requests.get(url, timeout=8, headers={"User-Agent": "Mozilla/5.0"}) if r.status_code == 200 and " 0: return {"symbol": d[0].get("symbol"), "open_interest": d[0].get("open_interest"), "open_interest_usd": d[0].get("open_interest_usd")} return {"raw": str(d)[:100]} test("Coinalyze未平仓量", test_coinalyze) # 11. Binance 多空比 def test_binance_longshort(): url = "https://fapi.binance.com/futures/data/globalLongShortAccountRatio" r = requests.get(url, params={"symbol": "BTCUSDT", "period": "1h", "limit": "3"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() latest = d[-1] return {"symbol": latest["symbol"], "longShortRatio": latest["longShortRatio"], "longAccount": latest["longAccount"], "shortAccount": latest["shortAccount"], "timestamp": latest["timestamp"]} test("Binance全球多空比", test_binance_longshort) # 12. Binance 大户持仓多空比 def test_binance_toptrader(): url = "https://fapi.binance.com/futures/data/topLongShortPositionRatio" r = requests.get(url, params={"symbol": "BTCUSDT", "period": "1h", "limit": "3"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() latest = d[-1] return {"longShortRatio": latest["longShortRatio"], "longAccount": latest["longAccount"], "shortAccount": latest["shortAccount"]} test("Binance大户持仓多空比", test_binance_toptrader) # 13. Binance 合约清算数据 def test_binance_liquidation(): url = "https://fapi.binance.com/futures/data/allForceOrders" r = requests.get(url, params={"symbol": "BTCUSDT", "limit": "5"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() if not d: return {"message": "暂无清算数据(市场平稳)"} latest = d[0] return {"symbol": latest["symbol"], "side": latest["side"], "price": latest["price"], "origQty": latest["origQty"], "time": latest["time"]} test("Binance合约清算记录", test_binance_liquidation) # 14. OKX 期权行情摘要 def test_okx_options(): url = "https://www.okx.com/api/v5/market/opt-summary" r = requests.get(url, params={"uly": "BTC-USD"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() if d["code"] != "0": raise Exception(f"OKX error: {d['msg']}") items = d["data"][:3] return {"total_options": len(d["data"]), "sample": [{"instId": x["instId"], "delta": x.get("delta"), "gamma": x.get("gamma"), "vega": x.get("vega")} for x in items]} test("OKX期权Greeks摘要", test_okx_options) # ─── 链上数据扩展 ────────────────────────────────────────────────────────── # 15. Etherscan ETH 价格(免费 API) def test_etherscan(): url = "https://api.etherscan.io/api" r = requests.get(url, params={"module": "stats", "action": "ethprice", "apikey": "YourApiKeyToken"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() if d["status"] == "1": result = d["result"] return {"ethusd": result["ethusd"], "ethbtc": result["ethbtc"], "ethusd_timestamp": result["ethusd_timestamp"]} raise Exception(f"Etherscan error: {d['message']}") test("Etherscan ETH价格(免费)", test_etherscan) # 16. Blockchain.info BTC 链上数据(完全免费) def test_blockchain_info(): url = "https://blockchain.info/stats?format=json" r = requests.get(url, timeout=TIMEOUT) r.raise_for_status() d = r.json() return { "market_price_usd": d.get("market_price_usd"), "hash_rate": f"{d.get('hash_rate', 0)/1e6:.0f} EH/s", "minutes_between_blocks": d.get("minutes_between_blocks"), "n_blocks_mined": d.get("n_blocks_mined"), "total_fees_btc": d.get("total_fees_btc") } test("Blockchain.info BTC链上统计", test_blockchain_info) # 17. Mempool.space BTC 链上数据(完全免费) def test_mempool(): url = "https://mempool.space/api/v1/fees/recommended" r = requests.get(url, timeout=TIMEOUT) r.raise_for_status() d = r.json() return { "fastestFee": f"{d['fastestFee']} sat/vB", "halfHourFee": f"{d['halfHourFee']} sat/vB", "hourFee": f"{d['hourFee']} sat/vB", "economyFee": f"{d['economyFee']} sat/vB" } test("Mempool.space BTC手续费(完全免费)", test_mempool) # 18. Mempool.space 哈希率 def test_mempool_hashrate(): url = "https://mempool.space/api/v1/mining/hashrate/3d" r = requests.get(url, timeout=TIMEOUT) r.raise_for_status() d = r.json() latest = d["hashrates"][-1] if d["hashrates"] else {} return {"timestamp": latest.get("timestamp"), "avgHashrate": f"{latest.get('avgHashrate', 0)/1e18:.2f} EH/s", "data_points": len(d["hashrates"])} test("Mempool.space BTC哈希率", test_mempool_hashrate) # 19. CoinGlass 资金费率聚合(公开端点) def test_coinglass_funding(): url = "https://open-api.coinglass.com/public/v2/funding" r = requests.get(url, params={"symbol": "BTC"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() if d.get("code") == "0" or d.get("success"): data = d.get("data", []) if data: return {"exchange_count": len(data), "sample": data[:2]} return {"raw_status": d.get("code"), "msg": d.get("msg", "")[:100]} test("CoinGlass资金费率聚合", test_coinglass_funding) # ─── 宏观经济扩展 ────────────────────────────────────────────────────────── # 20. Yahoo Finance VIX 恐慌指数 def test_yahoo_vix(): url = "https://query1.finance.yahoo.com/v8/finance/chart/%5EVIX" r = requests.get(url, params={"interval": "1d", "range": "5d"}, headers={"User-Agent": "Mozilla/5.0"}, timeout=TIMEOUT) r.raise_for_status() d = r.json()["chart"]["result"][0] meta = d["meta"] return {"symbol": meta["symbol"], "regularMarketPrice": meta["regularMarketPrice"], "description": "CBOE Volatility Index"} test("Yahoo Finance VIX恐慌指数", test_yahoo_vix) # 21. Yahoo Finance 10年期美债收益率 def test_yahoo_tnx(): url = "https://query1.finance.yahoo.com/v8/finance/chart/%5ETNX" r = requests.get(url, params={"interval": "1d", "range": "5d"}, headers={"User-Agent": "Mozilla/5.0"}, timeout=TIMEOUT) r.raise_for_status() d = r.json()["chart"]["result"][0] meta = d["meta"] return {"symbol": meta["symbol"], "regularMarketPrice": f"{meta['regularMarketPrice']:.3f}%", "description": "10-Year Treasury Yield"} test("Yahoo Finance 10年期美债收益率", test_yahoo_tnx) # 22. Yahoo Finance 纳斯达克 def test_yahoo_nasdaq(): url = "https://query1.finance.yahoo.com/v8/finance/chart/%5EIXIC" r = requests.get(url, params={"interval": "1d", "range": "5d"}, headers={"User-Agent": "Mozilla/5.0"}, timeout=TIMEOUT) r.raise_for_status() d = r.json()["chart"]["result"][0] meta = d["meta"] return {"symbol": meta["symbol"], "regularMarketPrice": meta["regularMarketPrice"]} test("Yahoo Finance纳斯达克(IXIC)", test_yahoo_nasdaq) # 23. 世界银行 CPI 通胀率 def test_worldbank_cpi(): url = "https://api.worldbank.org/v2/country/US/indicator/FP.CPI.TOTL.ZG" r = requests.get(url, params={"format": "json", "per_page": "3", "mrv": "3"}, timeout=TIMEOUT) r.raise_for_status() d = r.json()[1] return [{"year": x["date"], "cpi_inflation": f"{x['value']:.2f}%" if x["value"] else "N/A"} for x in d] test("世界银行美国CPI通胀率", test_worldbank_cpi) # ─── 新增数据源(目标 40+)────────────────────────────────────────────────── # 24. Kraken K 线(CEX 补充) def test_kraken(): url = "https://api.kraken.com/0/public/OHLC" r = requests.get(url, params={"pair": "XBTUSD", "interval": "60", "count": "3"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() if d["error"]: raise Exception(str(d["error"])) result = d["result"] pair_key = [k for k in result.keys() if k != "last"][0] candles = result[pair_key] latest = candles[-1] return {"pair": pair_key, "time": latest[0], "open": latest[1], "high": latest[2], "low": latest[3], "close": latest[4], "volume": latest[6]} test("Kraken BTC/USD K线", test_kraken) # 25. Gate.io K 线(CEX 补充) def test_gateio(): url = "https://api.gateio.ws/api/v4/futures/usdt/candlesticks" r = requests.get(url, params={"contract": "BTC_USDT", "interval": "1h", "limit": "3"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() latest = d[-1] return {"t": latest["t"], "o": latest["o"], "h": latest["h"], "l": latest["l"], "c": latest["c"], "v": latest["v"]} test("Gate.io BTC合约K线", test_gateio) # 26. Bitget K 线(CEX 补充) def test_bitget(): url = "https://api.bitget.com/api/v2/mix/market/candles" r = requests.get(url, params={"symbol": "BTCUSDT", "productType": "USDT-FUTURES", "granularity": "1h", "limit": "3"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() if d["code"] != "00000": raise Exception(f"Bitget error: {d['msg']}") latest = d["data"][0] return {"ts": latest[0], "open": latest[1], "high": latest[2], "low": latest[3], "close": latest[4], "volume": latest[5]} test("Bitget BTC合约K线", test_bitget) # 27. Hyperliquid 去中心化永续合约 def test_hyperliquid(): url = "https://api.hyperliquid.xyz/info" payload = {"type": "metaAndAssetCtxs"} r = requests.post(url, json=payload, timeout=TIMEOUT) r.raise_for_status() d = r.json() meta = d[0]["universe"] btc = next((x for x in d[1] if True), None) btc_meta = meta[0] return { "name": btc_meta["name"], "szDecimals": btc_meta["szDecimals"], "asset_count": len(meta) } test("Hyperliquid去中心化永续合约", test_hyperliquid) # 28. CoinGecko 交易所数据 def test_coingecko_exchanges(): url = "https://api.coingecko.com/api/v3/exchanges" r = requests.get(url, params={"per_page": "5", "page": "1"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() return {"total_exchanges": len(d), "top3": [{"id": x["id"], "name": x["name"], "trust_score": x["trust_score"], "trade_volume_24h_btc": f"{x['trade_volume_24h_btc']:.0f} BTC"} for x in d[:3]]} test("CoinGecko交易所排名", test_coingecko_exchanges) # 29. CoinGecko 趋势搜索 def test_coingecko_trending(): url = "https://api.coingecko.com/api/v3/search/trending" r = requests.get(url, timeout=TIMEOUT) r.raise_for_status() d = r.json()["coins"] return {"trending_coins": [{"name": x["item"]["name"], "symbol": x["item"]["symbol"], "market_cap_rank": x["item"]["market_cap_rank"]} for x in d[:5]]} test("CoinGecko热搜趋势", test_coingecko_trending) # 30. CoinGecko NFT 数据 def test_coingecko_nft(): url = "https://api.coingecko.com/api/v3/nfts/list" r = requests.get(url, params={"per_page": "3", "page": "1"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() return {"total_nfts": len(d), "sample": [{"id": x["id"], "name": x["name"], "symbol": x["symbol"]} for x in d[:3]]} test("CoinGecko NFT列表", test_coingecko_nft) # 31. DeFiLlama 协议收益率 def test_defillama_yields(): url = "https://yields.llama.fi/pools" r = requests.get(url, timeout=TIMEOUT) r.raise_for_status() d = r.json()["data"] # 筛选 BTC 相关的高收益池 btc_pools = [x for x in d if "BTC" in x.get("symbol", "")][:3] return {"total_pools": len(d), "btc_pools_sample": [{"pool": x["pool"][:30], "project": x["project"], "apy": f"{x.get('apy', 0):.2f}%", "tvlUsd": f"${x.get('tvlUsd', 0)/1e6:.1f}M"} for x in btc_pools]} test("DeFiLlama协议收益率(Yields)", test_defillama_yields) # 32. DeFiLlama DEX 交易量 def test_defillama_dex(): url = "https://api.llama.fi/overview/dexs" r = requests.get(url, params={"excludeTotalDataChart": "true", "excludeTotalDataChartBreakdown": "true", "dataType": "dailyVolume"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() protocols = d.get("protocols", [])[:3] return {"total_volume_24h": f"${d.get('total24h', 0)/1e9:.2f}B", "top3": [{"name": x["name"], "volume_24h": f"${x.get('total24h', 0)/1e6:.0f}M"} for x in protocols]} test("DeFiLlama DEX交易量", test_defillama_dex) # 33. Binance 资金费率历史 def test_binance_funding_history(): url = "https://fapi.binance.com/fapi/v1/fundingRate" r = requests.get(url, params={"symbol": "BTCUSDT", "limit": "5"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() return {"count": len(d), "latest": {"fundingRate": d[-1]["fundingRate"], "fundingTime": d[-1]["fundingTime"]}, "avg_rate": f"{sum(float(x['fundingRate']) for x in d)/len(d)*100:.6f}%"} test("Binance资金费率历史", test_binance_funding_history) # 34. Binance 合约持仓量历史 def test_binance_oi_history(): url = "https://fapi.binance.com/futures/data/openInterestHist" r = requests.get(url, params={"symbol": "BTCUSDT", "period": "1h", "limit": "5"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() latest = d[-1] return {"sumOpenInterest": latest["sumOpenInterest"], "sumOpenInterestValue": f"${float(latest['sumOpenInterestValue'])/1e9:.2f}B", "timestamp": latest["timestamp"]} test("Binance合约持仓量历史", test_binance_oi_history) # 35. Binance ETH 合约数据 def test_binance_eth(): url = "https://fapi.binance.com/fapi/v1/premiumIndex" r = requests.get(url, params={"symbol": "ETHUSDT"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() return {"symbol": d["symbol"], "markPrice": d["markPrice"], "lastFundingRate": d["lastFundingRate"]} test("Binance ETH合约资金费率", test_binance_eth) # 36. OKX 期权到期结构 def test_okx_option_expiry(): url = "https://www.okx.com/api/v5/public/instruments" r = requests.get(url, params={"instType": "OPTION", "uly": "BTC-USD", "instFamily": "BTC-USD"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() if d["code"] != "0": raise Exception(f"OKX error: {d['msg']}") items = d["data"] # 统计到期日分布 expiries = {} for item in items: exp = item.get("expTime", "")[:8] expiries[exp] = expiries.get(exp, 0) + 1 top3_expiries = sorted(expiries.items(), key=lambda x: x[0])[:3] return {"total_options": len(items), "expiry_distribution": [{"date": k, "count": v} for k, v in top3_expiries]} test("OKX BTC期权到期结构", test_okx_option_expiry) # 37. Bybit 未平仓量 def test_bybit_oi(): url = "https://api.bybit.com/v5/market/open-interest" r = requests.get(url, params={"category": "linear", "symbol": "BTCUSDT", "intervalTime": "1h", "limit": "3"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() if d["retCode"] != 0: raise Exception(f"Bybit error: {d['retMsg']}") latest = d["result"]["list"][0] return {"openInterest": latest["openInterest"], "openInterestValue": f"${float(latest['openInterestValue'])/1e9:.2f}B", "timestamp": latest["timestamp"]} test("Bybit BTC未平仓量历史", test_bybit_oi) # 38. Bybit 多空比 def test_bybit_longshort(): url = "https://api.bybit.com/v5/market/account-ratio" r = requests.get(url, params={"category": "linear", "symbol": "BTCUSDT", "period": "1h", "limit": "3"}, timeout=TIMEOUT) r.raise_for_status() d = r.json() if d["retCode"] != 0: raise Exception(f"Bybit error: {d['retMsg']}") latest = d["result"]["list"][0] return {"buyRatio": latest["buyRatio"], "sellRatio": latest["sellRatio"], "timestamp": latest["timestamp"]} test("Bybit BTC多空比", test_bybit_longshort) # 39. Deribit 期权 24h 成交量 def test_deribit_option_volume(): url = "https://www.deribit.com/api/v2/public/get_book_summary_by_currency" r = requests.get(url, params={"currency": "BTC", "kind": "option"}, timeout=TIMEOUT) r.raise_for_status() d = r.json()["result"] total_volume = sum(x.get("volume_usd", 0) for x in d) total_oi = sum(x.get("open_interest", 0) for x in d) return { "total_options": len(d), "total_volume_usd_24h": f"${total_volume/1e6:.0f}M", "total_open_interest": f"{total_oi:.0f} BTC" } test("Deribit期权24h成交量汇总", test_deribit_option_volume) # 40. Deribit 期货数据 def test_deribit_futures(): url = "https://www.deribit.com/api/v2/public/get_book_summary_by_currency" r = requests.get(url, params={"currency": "BTC", "kind": "future"}, timeout=TIMEOUT) r.raise_for_status() d = r.json()["result"] perpetual = next((x for x in d if "PERPETUAL" in x.get("instrument_name", "")), None) if perpetual: return {"instrument": perpetual["instrument_name"], "mark_price": perpetual["mark_price"], "open_interest": perpetual["open_interest"], "volume_usd": f"${perpetual.get('volume_usd', 0)/1e6:.0f}M"} return {"futures_count": len(d)} test("Deribit BTC期货数据", test_deribit_futures) # ─── 保存结果 ────────────────────────────────────────────────────────────── print("\n=== 验证结果汇总 ===") passed = sum(1 for v in results.values() if "✅" in v["status"]) failed = sum(1 for v in results.values() if "❌" in v["status"]) print(f"通过: {passed}/{len(results)}, 失败: {failed}/{len(results)}") with open("/home/ubuntu/quantKnowledge/20_Go迭代系统/scripts/verify_batch2_results.json", "w") as f: json.dump(results, f, ensure_ascii=False, indent=2, default=str) print("结果已保存到 verify_batch2_results.json")