""" 从 OKX 获取 BTC 日线数据 使用 CCXT 库,支持本地 Clash HTTP 代理 """ import ccxt import pandas as pd from datetime import datetime, timedelta from typing import Optional import os def fetch_btc_okx(days: int = 10, http_proxy: str = "http://127.0.0.1:7890") -> Optional[pd.DataFrame]: """ 从 OKX 获取 BTC/USDT 日线数据 Args: days: 获取最近多少天的数据,默认10天 http_proxy: HTTP 代理地址,默认使用本地 Clash 代理 http://127.0.0.1:7890 Returns: DataFrame with columns: date, open, high, low, close, volume """ try: # 配置 CCXT config = {'enableRateLimit': True} # 设置 HTTP 代理 if http_proxy: config['proxies'] = {'http': http_proxy, 'https': http_proxy} print(f"使用 HTTP 代理: {http_proxy}") # 创建 OKX 交易所实例 exchange = ccxt.okx(config) # 计算时间范围 end_date = datetime.now() start_date = end_date - timedelta(days=days + 5) # 多取几天确保有足够数据 since = int(start_date.timestamp() * 1000) print(f"从 OKX 获取 BTC/USDT 最近{days}天数据...") print(f"时间范围: {start_date.strftime('%Y-%m-%d')} ~ {end_date.strftime('%Y-%m-%d')}") # 获取日线数据 ohlcv = exchange.fetch_ohlcv('ETH/USDT', '1d', since, limit=100) if not ohlcv: print("未获取到数据") return None # 转换为 DataFrame df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume']) # 转换时间戳为日期索引(UTC -> 北京时间) df['date'] = pd.to_datetime(df['timestamp'], unit='ms', utc=True).dt.tz_convert('Asia/Shanghai') df = df.set_index('date') df = df[['open', 'high', 'low', 'close', 'volume']] # 过滤最近N天 df = df.tail(days) print(f"✓ 获取成功: {len(df)} 条数据") print(f"时间范围: {df.index[0].strftime('%Y-%m-%d %H:%M')} ~ {df.index[-1].strftime('%Y-%m-%d %H:%M')}") return df except Exception as e: print(f"获取数据失败: {e}") return None def print_btc_data(df: pd.DataFrame): """打印 BTC 数据""" print("\n" + "="*80) print("BTC/USDT 日线数据 (OKX)") print("="*80) print(f"{'日期':<20} {'开盘价':>12} {'最高价':>12} {'最低价':>12} {'收盘价':>12} {'成交量':>12}") print("-"*80) for date, row in df.iterrows(): date_str = date.strftime('%Y-%m-%d %H:%M') print(f"{date_str:<20} {row['open']:>12.2f} {row['high']:>12.2f} {row['low']:>12.2f} {row['close']:>12.2f} {row['volume']:>12.4f}") print("="*80) def main(): """主函数""" # 使用本地 Clash HTTP 代理(默认端口 7890) # 如果 Clash 使用其他端口,请修改此处 http_proxy = "http://127.0.0.1:7890" # 获取数据 df = fetch_btc_okx(days=10, http_proxy=http_proxy) if df is not None: print_btc_data(df) # 保存到CSV output_file = "btc_okx_1d.csv" df.to_csv(output_file) print(f"\n数据已保存: {output_file}") else: print("获取数据失败") if __name__ == "__main__": main()