Files
2026-07-14 07:31:13 +08:00

350 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Universe Selection Engine (USE)
一个基于币安实时数据的加密货币标的池筛选引擎,支持 **多报价币扫描** 与三种主流量化策略:**趋势跟踪**、**均值回归**、**统计套利**。
> 所有阈值、报价币、代理地址、K 线周期等参数均通过 `config/config.yaml` 管理,**零硬编码**。
---
## 一、项目特点
-**多报价币混扫**USDT / USDC / BUSD / BTC 任选组合,一次扫描多个计价市场
-**按报价币独立阈值**:BTC 交叉盘流动性差,可单独放宽成交额门槛
-**自适应稳定币黑名单**:扫 USDC 时不会误杀 USDC 标的
-**上市天数过滤**:剔除刚上线的新币
-**K 线拉取带重试**:网络抖动不会丢失标的
-**异步并发 + 限频**:使用 `asyncio.Semaphore` 防 429 封禁
-**三种策略并行**:趋势 / 均值回归 / 统计套利
---
## 二、快速开始
### 2.1 环境要求
- Python >= 3.10
- Windows / Linux / macOS 全平台
- **代理工具**(国内访问币安 API 必需)
### 2.2 安装
```bash
cd crypto_use
pip install -r requirements.txt
```
依赖:`ccxt`, `pandas`, `numpy`, `statsmodels`, `pyyaml`, `scipy`
### 2.3 代理配置
> ⚠️ **国内直连币安 API 会被阻断,必须配置代理**。
编辑 `config/config.yaml`,修改 `exchange.proxy`
```yaml
exchange:
proxy: "http://127.0.0.1:7890" # 改成你的代理地址
```
如不需要代理,填 `null`。系统会判断:有代理则注入自定义 aiohttp session`ThreadedResolver` 绕过 aiodns DNS 失败问题),无代理则走 ccxt 默认行为。
### 2.4 运行
```bash
python main.py
```
输出结果保存到 `output/universe_results.json`。**任何目录下运行均可**,项目根路径自动锁定 `main.py` 所在位置。
---
## 三、输出说明
```json
{
"timestamp": "2026-07-14 07:24:52",
"timeframe": "1h",
"quote_currencies": ["USDT", "USDC"],
"trend_universe": ["BTC/USDT", "ETH/USDT", "BNB/USDT", ...],
"mr_universe": [],
"starb_pairs": []
}
```
| 字段 | 类型 | 含义 |
|------|------|------|
| `timestamp` | string | 运行时间 |
| `timeframe` | string | 使用的 K 线周期 |
| `quote_currencies` | list | 本次扫描的报价币列表 |
| `trend_universe` | list | 趋势跟踪策略标的池 |
| `mr_universe` | list | 均值回归策略标的池 |
| `starb_pairs` | list | 统计套利配对池,格式 `[["ETH/USDT", "SOL/USDT"], ...]` |
---
## 四、配置参数详解
所有参数集中在 `config/config.yaml`,共 8 个顶级字段。
### 4.1 `exchange` 交易所设置
```yaml
exchange:
name: binance # 交易所名称(ccxt 支持列表)
market: spot # spot=现货, future=U本位合约
proxy: "http://127.0.0.1:7890" # 代理地址,留空或 null 直连
```
### 4.2 `data` 数据设置
```yaml
data:
timeframe: 1h # K线周期:1m, 5m, 15m, 1h, 4h, 1d
lookback_candles: 500 # 拉取历史K线根数
max_concurrency: 15 # K 线并发拉取上限(防 429
```
| 参数 | 调小 | 调大 |
|------|------|------|
| `timeframe` | 1m/5m → 捕捉短期波动,适合日内 | 1d → 过滤噪声,适合长线 |
| `lookback_candles` | 100 → 计算快但统计不显著 | 1000+ → 更稳健但增加 API 压力 |
| `max_concurrency` | 5~8 → 更安全 | 20 → 更快但易触发 429 |
### 4.3 `base_filter` 基础流动性过滤
```yaml
base_filter:
# 报价币列表 —— 引擎会扫描所有这些计价市场,写几个就扫几个
# 支持混配:['USDT', 'USDC'] 会同时扫 USDT 对和 USDC 对
quote_currencies:
- USDT
- USDC
# 单一计价模式(兼容老配置),如果 quote_currencies 未设置则使用此值
quote_currency: USDT
min_quote_volume_24h: 20000000 # 默认成交额门槛(按对应报价币计算)
# 按报价币覆盖成交额门槛 —— 低流动性报价币可单独放宽
# 未列出的报价币沿用 min_quote_volume_24h
volume_thresholds:
BTC: 50 # BTC 交叉盘流动性远低于 USDT 对
BUSD: 5000000 # BUSD 对同样冷门
USDC: 5000000 # USDC 对略低于 USDT
max_spread_pct: 0.05 # 最大买卖价差 (%)
min_listing_days: 90 # 最小上市天数(0 = 不限制)
# 报价币对应的稳定币黑名单(不同计价场景需要不同定义)
stablecoin_bases:
USDT: [USDC, FDUSD, DAI, TUSD, BUSD, EUR, TRY]
USDC: [USDT, FDUSD, DAI, TUSD, BUSD, EUR, TRY]
BUSD: [USDT, USDC, FDUSD, DAI, TUSD, EUR, TRY]
BTC: [USDT, USDC, FDUSD, DAI, TUSD, BUSD, EUR, TRY, WBTC]
USD: [USDT, USDC, FDUSD, DAI, TUSD, BUSD, EUR, TRY]
exclude_stablecoins: true # 是否启用稳定币过滤
```
**核心设计**:扫 USDT 时,`USDC/FDUSD/DAI...` 这些 base 会被当作稳定币排除;扫 USDC 时不会误杀 USDC 标的;扫 BTC 时还会排除 `WBTC`(防止 WBTC/BTC 这种没意义的循环对)。
### 4.4 `trend_filter` 趋势跟踪过滤
```yaml
trend_filter:
min_annualized_vol: 0.40 # 最小年化波动率(40%
min_hurst: 0.55 # 最小 Hurst 指数(>0.5 表示趋势持续)
```
### 4.5 `mean_reversion_filter` 均值回归过滤
```yaml
mean_reversion_filter:
max_adf_pvalue: 0.05 # ADF 检验最大 p-value<0.05 表示平稳)
max_hurst: 0.45 # 最大 Hurst 指数(<0.5 表示反持续)
max_kurtosis: 10.0 # 最大峰度(剔除极端肥尾/黑天鹅币)
```
### 4.6 `starb_filter` 统计套利过滤
```yaml
starb_filter:
max_coint_pvalue: 0.05 # 协整检验最大 p-value
# 板块分类 —— 键为板块名,值为标的列表
# 标的格式必须为 BASE/QUOTE,必须在 quote_currencies 里有对应 quote
sectors:
L1: ["ETH/USDT", "SOL/USDT", "AVAX/USDT", "ADA/USDT", "DOT/USDT", "NEAR/USDT"]
DeFi: ["UNI/USDT", "AAVE/USDT", "MKR/USDT", "SNX/USDT", "COMP/USDT", "LDO/USDT"]
Meme: ["DOGE/USDT", "SHIB/USDT", "PEPE/USDT", "WIF/USDT", "FLOKI/USDT", "BONK/USDT"]
AI: ["RNDR/USDT", "FET/USDT", "AGIX/USDT", "TAO/USDT", "ARKM/USDT"]
# 交叉盘示例:
# BTC_Pairs: ["ETH/BTC", "SOL/BTC", "AVAX/BTC"]
```
> ⚠️ 板块分类需要**根据市场叙事动态更新**,不是一成不变的。
### 4.7 `fetcher` K 线拉取设置
```yaml
fetcher:
max_retries: 3 # 单个标的最大重试次数
retry_delay: 1.0 # 重试基础间隔(秒),实际为 retry_delay × 第几次
```
### 4.8 `output` 输出设置
```yaml
output:
save_path: "./output/universe_results.json" # 相对路径相对项目根,也可写绝对路径
```
---
## 五、参数调优指南
### 5.1 标的池太少?→ 放宽阈值
| 场景 | 操作 |
|------|------|
| 没有任何标的过基础过滤 | 降低 `min_quote_volume_24h` 或在 `volume_thresholds` 给冷门 quote 设小门槛 |
| 趋势池为空 | 降低 `min_hurst`(如 0.55 → 0.52)或降低 `min_annualized_vol`0.40 → 0.25 |
| 均值回归池为空 | 降低 `max_kurtosis`10.0 → 15.0)或提高 `max_hurst`0.45 → 0.50 |
| 套利配对为空 | 提高 `max_coint_pvalue`(0.05 → 0.10)或扩大板块覆盖 |
### 5.2 标的池太多?→ 收紧阈值
| 场景 | 操作 |
|------|------|
| 趋势池全是"死币" | 提高 `min_hurst` 到 0.60+ |
| 均值回归池出现单边下跌币 | 降低 `max_kurtosis` 到 5.0 以下 |
| 套利配对太多 | 降低 `max_coint_pvalue` 到 0.01 |
### 5.3 多报价币策略
| 需求 | 配置示例 |
|------|----------|
| 同时扫 USDT + USDC 主流市场 | `quote_currencies: [USDT, USDC]` |
| 只扫 BTC 交叉盘(量化做 BTC 对统计套利) | `quote_currencies: [BTC]` + `volume_thresholds.BTC: 50` |
| 全量扫描(不推荐,慢) | `quote_currencies: [USDT, USDC, BUSD, BTC, USD]` + 对应 `volume_thresholds` |
---
## 六、与实盘对接
### 6.1 读取结果
```python
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parent
with open(ROOT / "output" / "universe_results.json", "r", encoding="utf-8") as f:
universe = json.load(f)
trend_symbols = universe["trend_universe"] # 趋势策略使用
mr_symbols = universe["mr_universe"] # 均值回归策略使用
starb_pairs = universe["starb_pairs"] # 统计套利策略使用
quote_currencies = universe["quote_currencies"] # 本次扫描的报价币
```
### 6.2 定时调度
**建议执行频率**:每天凌晨 00:00 UTC 运行一次(流动性/统计量在日内变化不大)。
**Linux cron 示例**
```bash
0 0 * * * cd /path/to/crypto_use && /usr/bin/python main.py >> /var/log/use_cron.log 2>&1
```
**Windows 任务计划程序**:新建基本任务 → 触发器"每天 00:00" → 操作"启动程序" `python main.py`,起始于 `crypto_use` 目录。
---
## 七、项目结构
```
crypto_use/
├── config/
│ └── config.yaml # 全局配置(零硬编码的唯一来源)
├── universe_selector/
│ ├── __init__.py
│ ├── fetcher.py # 异步数据拉取(ccxt + 限频 + 重试)
│ ├── filters.py # 三种策略过滤器(Hurst/ADF/Coint
│ ├── engine.py # 流水线控制器
│ └── utils.py # 统计算法辅助函数
├── output/
│ └── universe_results.json # 筛选结果(每次运行覆盖)
├── main.py # 入口脚本
├── use_engine.log # 运行日志(每次追加)
├── requirements.txt # 依赖包
└── README.md # 本文件
```
---
## 八、常见问题
**Q: 运行报 DNS 错误?**
A: 确认代理 7890 端口已启动,且 `config.yaml``exchange.proxy` 已正确填写。本项目在有代理时会自动注入 `ThreadedResolver`,绕过 aiodns 在代理环境下的 DNS 失败问题。
**Q: 报 429 限频?**
A: 降低 `data.max_concurrency` 到 8~10;或降低 `fetcher.max_retries` 减少重试风暴。
**Q: 某些标的 K 线拉不到?**
A: 项目对每个标的自动重试 3 次(指数退避),最终失败会在日志中输出 ERROR 但不中断流程。如大量失败,检查网络或降低并发。
**Q: 均值回归池一直是空的?**
A: 这是正常现象。`max_hurst < 0.45 + ADF p < 0.05 + kurtosis < 10` 三条件同时满足的标的在币安全市场现货里极少。降低 `max_kurtosis` 到 15+ 或提高 `max_hurst` 到 0.50 试试。
**Q: 统计套利配对一直是 0**
A: 在 `starb_filter.sectors` 里扩大板块覆盖,或提高 `max_coint_pvalue` 到 0.10。
**Q: 想扫描 BTC 交叉盘但出不了标的?**
A: 在 `base_filter.volume_thresholds.BTC` 设置小门槛(如 50 BTC)。BTC 交叉盘流动性远低于 USDT 对,必须单独配置门槛。
**Q: 想看某币是因什么原因被过滤掉的?**
A: 当前版本未提供 verbose 调试模式。如需要可临时将 `fetcher.py``get_liquid_symbols` 的循环里加 `print(f"[skip] {symbol}: 原因")`
**Q: 支持合约市场吗?**
A: 支持。把 `exchange.market` 改成 `future` 即可。但注意币安合约 API 的 ticker 字段与现货略有差异,可能需要根据实际情况微调。
**Q: 在哪个目录运行 main.py**
A: 任意目录均可。项目根路径通过 `Path(__file__).resolve().parent` 自动锁定,配置/输出/日志路径与 cwd 无关。
---
## 九、扩展开发
### 9.1 新增一种策略过滤器
`universe_selector/filters.py``StrategyFilters` 类里添加新方法,例如:
```python
def filter_breakout(self, data_dict: dict[str, pd.DataFrame]) -> list[str]:
"""突破策略:检测近期价格是否突破 N 日高点"""
universe = []
for sym, df in data_dict.items():
close = df['close'].values
high_20d = close[:-1][-20*24:].max() # 前 20 天最高
if close[-1] > high_20d:
universe.append(sym)
return universe
```
然后在 `engine.py``run_pipeline` 中调用:
```python
results['breakout_universe'] = self.filters.filter_breakout(data_dict)
```
### 9.2 接入实盘自动下单
引擎输出 `output/universe_results.json` 后,下游策略可订阅文件变化(`watchdog` 库)或定时轮询,将新标的池与持仓比对,自动调整下单白名单。
---
## 十、版本
| 版本 | 日期 | 变更 |
|------|------|------|
| 1.0 | 2026-07 | 初始版本(USDT only |
| 1.1 | 2026-07 | 多报价币 / 按 quote 独立门槛 / 上市天数 / K 线重试 / 路径稳健化 |
---
## 十一、许可
仅供学习和研究使用。加密货币交易有风险,请自行评估。