feat(datasource): 实现加密货币数据获取功能

- 新增 ccxt_source.py: CCXT + OKX 加密货币数据源
- 新增 socks2http.py: SOCKS5 转 HTTP 代理转换器
- 修改 universal_fetcher.py: 添加 _fetch_crypto 方法,支持 timeframe 参数
- 修改 flask_server.py: API 支持 timeframe 参数,加密货币不缓存

支持的 timeframe: 1d, 1h, 4h, 15m, 1m
测试验证: BTC 数据获取成功
This commit is contained in:
2026-05-13 23:30:32 +08:00
parent 105af19690
commit 416f708d53
4 changed files with 513 additions and 13 deletions

View File

@@ -29,6 +29,7 @@ from .tushare_source import TushareSource
from .yfinance_source import YFinanceSource
from .ssh_tunnel import SSHTunnelManager
from .asset_type_detector import AssetTypeDetector, AssetType
from .ccxt_source import CCXTSource, get_crypto_source
class UniversalDataFetcher:
@@ -65,6 +66,9 @@ class UniversalDataFetcher:
# SSH隧道延迟初始化
self._tunnel: Optional[SSHTunnelManager] = None
self._tunnel_started = False
# 加密货币数据源(延迟初始化)
self._crypto: Optional[CCXTSource] = None
def __enter__(self):
"""上下文管理器入口"""
@@ -108,7 +112,8 @@ class UniversalDataFetcher:
code: str,
start_date: str,
end_date: str,
retry: int = 3
retry: int = 3,
timeframe: str = '1d'
) -> Optional[pd.DataFrame]:
"""
统一数据获取入口
@@ -120,6 +125,7 @@ class UniversalDataFetcher:
start_date: 开始日期 'YYYY-MM-DD'
end_date: 结束日期 'YYYY-MM-DD'
retry: 重试次数
timeframe: K线周期仅加密货币需要默认1d
Returns:
DataFrame with columns: date, open, high, low, close, volume
@@ -144,7 +150,7 @@ class UniversalDataFetcher:
elif asset_type == AssetType.FUTURES:
return self._fetch_futures(code, start_date, end_date)
elif asset_type == AssetType.CRYPTO:
return self._fetch_crypto(code, start_date, end_date)
return self._fetch_crypto(code, start_date, end_date, timeframe)
else:
print(f"⚠️ 未知资产类型: {code} -> {asset_type}")
return None
@@ -333,17 +339,31 @@ class UniversalDataFetcher:
self,
code: str,
start_date: str,
end_date: str
end_date: str,
timeframe: str = '1d'
) -> Optional[pd.DataFrame]:
"""
获取加密货币
特点:CCXT不支持SOCKS5代理
特点:
- 使用 CCXT + OKX
- 需要通过 socks2http 将 SOCKS5 转 HTTP 代理
- 必须指定 timeframe
- 不缓存(每次实时下载)
TODO: 实现加密货币获取
Args:
code: 加密货币代码BTC, ETH
start_date: 开始日期
end_date: 结束日期
timeframe: K线周期1d, 1h, 4h, 15m, 1m
"""
print(f"⚠️ 加密货币数据获取尚未实现: {code}")
return None
# 延迟初始化加密货币数据源
if self._crypto is None:
# 使用 SSH 隧道的 SOCKS5 端口
socks_port = self.ssh_config.get('local_port', 1080)
self._crypto = get_crypto_source(socks_port=socks_port)
return self._crypto.fetch(code, start_date, end_date, timeframe)
# ============================================================
# 批量获取