- 新增获取3033.HK复权与不复权价格对比脚本,支持代理配置 - 新增使用Tushare获取AU9999黄金现货数据脚本,支持日期范围查询和CSV保存 - 新增从OKX通过CCXT库获取BTC/USDT日线数据脚本,支持HTTP代理和时间范围过滤 - 所有脚本均包含打印数据显示的格式化输出 - 各脚本提供主函数入口,易于独立运行和调试
110 lines
3.4 KiB
Python
110 lines
3.4 KiB
Python
"""
|
||
从 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()
|