docs: 添加版本对比分析脚本与配置设计文档
新增对比脚本: - compare_v1_v2.py: V1 vs V2 简单版对比分析(153 行) * 发现 V2 简单版收益虚高(981.95% vs V1 的 103.29%) * 识别核心差异:交易成本、调仓逻辑、动态阈值、溢价控制 - compare_three_versions.py: 三版本完整对比(190 行) * V1 原始版:103.29%(基准) * V2 简单版:981.95%(未计入交易成本,虚高) * V2 正式版:135.63%(已计入交易成本,真实) * 量化分析收益下降 846% 的原因 新增文档: - CONFIG_DESIGN.md: V2 配置系统设计文档 * 扁平化资产池设计 * signal_source/trade_source 分离机制 * group 字段策略化语义 测试脚本: - test_api_dates.py: API 日期范围验证测试 关键发现: 1. V2 简单版未计入交易成本导致收益虚高 878% 2. V2 正式版计入 829 次调仓成本后收益降至 135.63% 3. V2 正式版 vs V1(+32.34%)差异合理,夏普比率更优(1.15 vs 0.78)
This commit is contained in:
573
framework_v2/config/CONFIG_DESIGN.md
Normal file
573
framework_v2/config/CONFIG_DESIGN.md
Normal file
@@ -0,0 +1,573 @@
|
||||
# V2 配置设计文档
|
||||
|
||||
## 概述
|
||||
|
||||
framework_v2 的配置系统基于 **Pydantic Schema 验证**,解决 V1 配置文件的 10 个问题。
|
||||
|
||||
---
|
||||
|
||||
## 核心设计原则
|
||||
|
||||
### 1. **类型安全**(解决 V1 问题 #2)
|
||||
|
||||
```python
|
||||
# ❌ V1: 无验证
|
||||
n_days: 25 # 如果是 "25"(字符串)会静默失败
|
||||
|
||||
# ✅ V2: Pydantic 验证
|
||||
class FactorConfig(BaseModel):
|
||||
n_days: int = Field(default=25, ge=5, le=250)
|
||||
```
|
||||
|
||||
**验证效果**:
|
||||
```python
|
||||
# 错误:超出范围
|
||||
factor: {n_days: 1000}
|
||||
# → ValidationError: n_days 必须在 5-250 之间
|
||||
|
||||
# 错误:类型错误
|
||||
factor: {n_days: "25"}
|
||||
# → ValidationError: n_days 必须是整数
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. **敏感信息环境变量化**(解决 V1 问题 #1)
|
||||
|
||||
```yaml
|
||||
# ❌ V1: 硬编码
|
||||
flask_api:
|
||||
url: "https://k3s.tokenpluse.xyz"
|
||||
ssh_tunnel:
|
||||
host: "8.218.167.69"
|
||||
key_path: "hk_ecs.pem"
|
||||
|
||||
# ✅ V2: 环境变量
|
||||
data:
|
||||
sources:
|
||||
- type: "flask_api"
|
||||
url: "${FLASK_API_URL}" # 从环境变量读取
|
||||
- type: "tushare"
|
||||
token: "${TUSHARE_TOKEN}" # 从环境变量读取
|
||||
```
|
||||
|
||||
**环境变量替换**:
|
||||
```python
|
||||
# 支持格式
|
||||
${VAR_NAME} # 必需环境变量
|
||||
${VAR_NAME:default_value} # 带默认值
|
||||
|
||||
# 示例
|
||||
url: "${FLASK_API_URL}" # 必须设置
|
||||
timeout: "${TIMEOUT:120}" # 默认 120
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. **资产池按类别分组**(解决 V1 问题 #3)
|
||||
|
||||
```yaml
|
||||
# ❌ V1: 混合在一起
|
||||
code_list:
|
||||
"399006.SZ":
|
||||
name: "创业板指"
|
||||
market: "A"
|
||||
"GC=F":
|
||||
name: "黄金"
|
||||
market: "COMMODITY"
|
||||
|
||||
# ✅ V2: 按类别分组
|
||||
asset_pools:
|
||||
equity: # 股票资产
|
||||
"399006.SZ":
|
||||
name: "创业板指"
|
||||
market: "CN_EQUITY"
|
||||
"NDX":
|
||||
name: "纳指100"
|
||||
market: "US_EQUITY"
|
||||
|
||||
commodity: # 商品资产
|
||||
"GC=F":
|
||||
name: "黄金"
|
||||
market: "COMMODITY"
|
||||
|
||||
fixed_income: # 固定收益
|
||||
"931862.CSI":
|
||||
name: "短债指数"
|
||||
market: "FIXED_INCOME"
|
||||
```
|
||||
|
||||
**优势**:
|
||||
- ✅ 清晰的资产分类
|
||||
- ✅ 支持分散化策略(每类选 Top-N)
|
||||
- ✅ 易于扩展新资产类别
|
||||
|
||||
---
|
||||
|
||||
### 4. **精简注释 + 独立文档**(解决 V1 问题 #4)
|
||||
|
||||
```yaml
|
||||
# ❌ V1: 30 行注释
|
||||
# 931862.CSI = 中证0-9个月国债指数(短债指数)
|
||||
# 数据范围:2007-12-31开始,约19年数据
|
||||
# 久期:极短(<1年),波动极小,熊市防御效果最佳
|
||||
# ...(共 30 行)
|
||||
"931862.CSI":
|
||||
name: "短债指数"
|
||||
etf: null
|
||||
market: "BOND"
|
||||
|
||||
# ✅ V2: 精简注释 + description 字段
|
||||
fixed_income:
|
||||
"931862.CSI":
|
||||
name: "短债指数"
|
||||
etf: null
|
||||
market: "FIXED_INCOME"
|
||||
description: "中证0-9个月国债指数,久期<1年,防御配置"
|
||||
```
|
||||
|
||||
**详细文档独立**:
|
||||
```
|
||||
docs/
|
||||
├── bond_analysis.md # 债券收益归因分析
|
||||
├── asset_pool_design.md # 资产池设计说明
|
||||
└── threshold_strategy.md # 阈值策略文档
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. **统一阈值配置**(解决 V1 问题 #6)
|
||||
|
||||
```yaml
|
||||
# ❌ V1: V2 + V3 共存,逻辑混乱
|
||||
min_score: 0.0 # V2 固定阈值
|
||||
|
||||
bond_threshold: # V3 动态阈值
|
||||
enabled: true
|
||||
bond_code: "931862.CSI"
|
||||
ratio: 1.0
|
||||
fill_bond: true
|
||||
|
||||
# ✅ V2: 统一配置
|
||||
rotation:
|
||||
threshold:
|
||||
mode: "dynamic" # 阈值模式: fixed / dynamic
|
||||
fixed_value: 0.0 # mode=fixed 时使用
|
||||
|
||||
dynamic: # mode=dynamic 时使用
|
||||
reference: "931862.CSI" # 参考标的
|
||||
ratio: 1.0 # 倍数
|
||||
fallback_enabled: true # 回退开关
|
||||
fallback_value: 0.0 # 回退值
|
||||
```
|
||||
|
||||
**模式切换**:
|
||||
```yaml
|
||||
# 固定阈值模式
|
||||
threshold:
|
||||
mode: "fixed"
|
||||
fixed_value: 0.0
|
||||
|
||||
# 动态阈值模式
|
||||
threshold:
|
||||
mode: "dynamic"
|
||||
dynamic:
|
||||
reference: "931862.CSI"
|
||||
ratio: 1.0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. **标准化市场类型**(解决 V1 问题 #8)
|
||||
|
||||
```yaml
|
||||
# ❌ V1: 随意定义
|
||||
market: "A" # A股
|
||||
market: "US" # 美股
|
||||
market: "JP" # 日本
|
||||
|
||||
# ✅ V2: 标准枚举
|
||||
market: "CN_EQUITY" # 中国股票
|
||||
market: "US_EQUITY" # 美国股票
|
||||
market: "JP_EQUITY" # 日本股票
|
||||
market: "EU_EQUITY" # 欧洲股票
|
||||
market: "HK_EQUITY" # 香港股票
|
||||
market: "COMMODITY" # 商品
|
||||
market: "FIXED_INCOME" # 固定收益
|
||||
```
|
||||
|
||||
**Python 枚举**:
|
||||
```python
|
||||
class MarketType(str, Enum):
|
||||
CN_EQUITY = "CN_EQUITY"
|
||||
US_EQUITY = "US_EQUITY"
|
||||
JP_EQUITY = "JP_EQUITY"
|
||||
EU_EQUITY = "EU_EQUITY"
|
||||
HK_EQUITY = "HK_EQUITY"
|
||||
COMMODITY = "COMMODITY"
|
||||
FIXED_INCOME = "FIXED_INCOME"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. **多数据源降级策略**(解决 V1 问题 #9)
|
||||
|
||||
```yaml
|
||||
# ❌ V1: 扁平化配置
|
||||
flask_api:
|
||||
enabled: true
|
||||
url: "https://k3s.tokenpluse.xyz"
|
||||
|
||||
ssh_tunnel:
|
||||
enabled: true
|
||||
# ...
|
||||
|
||||
# ✅ V2: 优先级列表
|
||||
data:
|
||||
sources:
|
||||
# 主数据源
|
||||
- type: "flask_api"
|
||||
enabled: true
|
||||
url: "${FLASK_API_URL}"
|
||||
timeout: 120
|
||||
|
||||
# 备用数据源
|
||||
- type: "tushare"
|
||||
enabled: true
|
||||
token: "${TUSHARE_TOKEN}"
|
||||
timeout: 60
|
||||
|
||||
# 降级数据源
|
||||
- type: "yfinance"
|
||||
enabled: false
|
||||
timeout: 120
|
||||
```
|
||||
|
||||
**降级逻辑**:
|
||||
```python
|
||||
for source in config.data.sources:
|
||||
if not source.enabled:
|
||||
continue
|
||||
|
||||
try:
|
||||
data = fetch_from_source(source)
|
||||
return data
|
||||
except Exception as e:
|
||||
print(f"数据源 {source.type} 失败: {e}")
|
||||
continue
|
||||
|
||||
raise ValueError("所有数据源均失败")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 8. **配置版本控制**(解决 V1 问题 #10)
|
||||
|
||||
```yaml
|
||||
# ❌ V1: 无版本信息
|
||||
# ETF轮动策略配置
|
||||
# (无版本)
|
||||
|
||||
# ✅ V2: 元数据
|
||||
metadata:
|
||||
version: "1.0.0"
|
||||
strategy: "rotation"
|
||||
description: "ETF轮动策略 V2 - 基于 framework_v2 架构"
|
||||
last_updated: "2024-04-16"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Schema 层次结构
|
||||
|
||||
```
|
||||
RotationStrategyConfig
|
||||
├── metadata: MetadataConfig
|
||||
│ ├── version: str
|
||||
│ ├── strategy: str
|
||||
│ ├── description: str
|
||||
│ └── last_updated: str
|
||||
│
|
||||
├── asset_pools: AssetPool
|
||||
│ ├── equity: Dict[str, AssetConfig]
|
||||
│ ├── commodity: Dict[str, AssetConfig]
|
||||
│ └── fixed_income: Dict[str, AssetConfig]
|
||||
│
|
||||
├── benchmark: BenchmarkConfig
|
||||
│ ├── code: str
|
||||
│ └── name: str
|
||||
│
|
||||
├── backtest: BacktestConfig
|
||||
│ ├── start_date: str
|
||||
│ └── end_date: Optional[str]
|
||||
│
|
||||
├── factor: FactorConfig
|
||||
│ ├── type: FactorType
|
||||
│ ├── n_days: int (5-250)
|
||||
│ ├── auto_day: bool
|
||||
│ ├── min_days: int
|
||||
│ └── max_days: int
|
||||
│
|
||||
├── rotation: RotationConfig
|
||||
│ ├── select_num: int (1-10)
|
||||
│ ├── diversified: bool
|
||||
│ └── threshold: ThresholdConfig
|
||||
│ ├── mode: ThresholdMode
|
||||
│ ├── fixed_value: float
|
||||
│ └── dynamic: DynamicThresholdConfig
|
||||
│ ├── reference: str
|
||||
│ ├── ratio: float
|
||||
│ ├── fallback_enabled: bool
|
||||
│ └── fallback_value: float
|
||||
│
|
||||
├── rebalance: RebalanceConfig
|
||||
│ ├── min_hold_days: int (1-30)
|
||||
│ ├── score_threshold: float (0-0.5)
|
||||
│ └── trade_cost: float (0-0.01)
|
||||
│
|
||||
├── premium_control: PremiumControlConfig
|
||||
│ ├── enabled: bool
|
||||
│ ├── default_threshold: float
|
||||
│ ├── mode: PremiumMode
|
||||
│ ├── penalty_factor: float
|
||||
│ └── market_overrides: Dict[str, MarketPremiumOverride]
|
||||
│
|
||||
└── data: DataConfig
|
||||
├── sources: List[DataSourceConfig]
|
||||
├── use_cache: bool
|
||||
└── cache_dir: str
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基础使用
|
||||
|
||||
```python
|
||||
from framework_v2.config import load_config
|
||||
|
||||
# 加载配置文件
|
||||
config = load_config('rotation_example.yaml')
|
||||
|
||||
# 访问配置
|
||||
print(f"动量窗口: {config.factor.n_days}")
|
||||
print(f"选股数量: {config.rotation.select_num}")
|
||||
print(f"数据源: {len(config.data.sources)} 个")
|
||||
```
|
||||
|
||||
### 验证错误处理
|
||||
|
||||
```python
|
||||
from pydantic import ValidationError
|
||||
|
||||
try:
|
||||
config = load_config('invalid_config.yaml')
|
||||
except ValidationError as e:
|
||||
print(f"配置验证失败: {e}")
|
||||
# 输出详细错误信息
|
||||
for error in e.errors():
|
||||
print(f" - {error['loc']}: {error['msg']}")
|
||||
```
|
||||
|
||||
### 环境变量
|
||||
|
||||
```bash
|
||||
# 设置环境变量
|
||||
export FLASK_API_URL="https://k3s.tokenpluse.xyz"
|
||||
export TUSHARE_TOKEN="your_token_here"
|
||||
|
||||
# 加载配置(自动替换环境变量)
|
||||
config = load_config('rotation_example.yaml')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
framework_v2/config/
|
||||
├── __init__.py # 导出模块
|
||||
├── schemas.py # Pydantic Schema 定义(275 行)
|
||||
├── loader.py # 配置加载器(237 行)
|
||||
├── rotation_example.yaml # 示例配置文件(195 行)
|
||||
└── CONFIG_DESIGN.md # 配置设计文档(本文件)
|
||||
|
||||
framework_v2/tests/
|
||||
└── test_config.py # 配置测试(286 行)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 测试验证
|
||||
|
||||
### 测试结果
|
||||
|
||||
```
|
||||
✓ 测试 1: 加载配置文件 - 通过
|
||||
✓ 测试 2: 资产池配置 - 通过
|
||||
✓ 测试 3: 阈值配置 - 通过
|
||||
✓ 测试 4: 数据源配置 - 通过
|
||||
✓ 测试 5: 验证错误处理 - 通过
|
||||
✓ 测试 6: 环境变量替换 - 通过
|
||||
|
||||
总计: 6/6 通过
|
||||
```
|
||||
|
||||
### 验证覆盖
|
||||
|
||||
| 验证项 | 测试内容 | 状态 |
|
||||
|--------|----------|------|
|
||||
| 配置加载 | YAML 解析 + 环境变量替换 | ✅ |
|
||||
| 类型验证 | n_days 范围、必需字段 | ✅ |
|
||||
| 资产池 | 股票/商品/债券分类 | ✅ |
|
||||
| 阈值配置 | 固定/动态模式切换 | ✅ |
|
||||
| 数据源 | 多源降级配置 | ✅ |
|
||||
| 错误处理 | ValidationError 捕获 | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## V1 vs V2 对比
|
||||
|
||||
| 特性 | V1 | V2 | 改进 |
|
||||
|------|----|----|----|
|
||||
| **类型安全** | ❌ 无验证 | ✅ Pydantic Schema | 早期失败 |
|
||||
| **敏感信息** | ❌ 硬编码 | ✅ 环境变量 | 安全性 |
|
||||
| **资产分类** | ❌ 混合 | ✅ 按类别分组 | 可维护性 |
|
||||
| **注释** | ❌ 冗长(30行) | ✅ 精简 + 独立文档 | 可读性 |
|
||||
| **阈值逻辑** | ❌ V2/V3 共存 | ✅ 统一配置 | 逻辑清晰 |
|
||||
| **市场类型** | ❌ 随意字符串 | ✅ 标准枚举 | 一致性 |
|
||||
| **数据源** | ❌ 扁平化 | ✅ 优先级列表 | 可靠性 |
|
||||
| **版本控制** | ❌ 无 | ✅ 元数据 | 可追溯 |
|
||||
|
||||
---
|
||||
|
||||
## 迁移指南
|
||||
|
||||
### 从 V1 迁移到 V2
|
||||
|
||||
#### 1. 更新配置文件结构
|
||||
|
||||
```yaml
|
||||
# V1
|
||||
code_list:
|
||||
"399006.SZ":
|
||||
name: "创业板指"
|
||||
etf: "159915.SZ"
|
||||
market: "A"
|
||||
|
||||
# V2
|
||||
asset_pools:
|
||||
equity:
|
||||
"399006.SZ":
|
||||
name: "创业板指"
|
||||
etf: "159915.SZ"
|
||||
market: "CN_EQUITY"
|
||||
```
|
||||
|
||||
#### 2. 更新市场类型
|
||||
|
||||
```yaml
|
||||
# V1 → V2 映射
|
||||
"A" → "CN_EQUITY"
|
||||
"US" → "US_EQUITY"
|
||||
"HK" → "HK_EQUITY"
|
||||
"COMMODITY" → "COMMODITY"
|
||||
"BOND" → "FIXED_INCOME"
|
||||
```
|
||||
|
||||
#### 3. 更新阈值配置
|
||||
|
||||
```yaml
|
||||
# V1
|
||||
min_score: 0.0
|
||||
bond_threshold:
|
||||
enabled: true
|
||||
bond_code: "931862.CSI"
|
||||
ratio: 1.0
|
||||
|
||||
# V2
|
||||
rotation:
|
||||
threshold:
|
||||
mode: "dynamic"
|
||||
dynamic:
|
||||
reference: "931862.CSI"
|
||||
ratio: 1.0
|
||||
```
|
||||
|
||||
#### 4. 更新数据源配置
|
||||
|
||||
```yaml
|
||||
# V1
|
||||
flask_api:
|
||||
enabled: true
|
||||
url: "https://k3s.tokenpluse.xyz"
|
||||
|
||||
# V2
|
||||
data:
|
||||
sources:
|
||||
- type: "flask_api"
|
||||
enabled: true
|
||||
url: "${FLASK_API_URL}"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 使用环境变量管理敏感信息
|
||||
|
||||
```bash
|
||||
# .env 文件(不要提交到 Git)
|
||||
FLASK_API_URL=https://k3s.tokenpluse.xyz
|
||||
TUSHARE_TOKEN=your_token_here
|
||||
SSH_HOST=8.218.167.69
|
||||
SSH_KEY_PATH=/path/to/hk_ecs.pem
|
||||
```
|
||||
|
||||
### 2. 为不同环境创建不同配置
|
||||
|
||||
```
|
||||
config/
|
||||
├── rotation_dev.yaml # 开发环境
|
||||
├── rotation_prod.yaml # 生产环境
|
||||
└── rotation_test.yaml # 测试环境
|
||||
```
|
||||
|
||||
### 3. 使用版本控制追踪配置变更
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
version: "1.0.0"
|
||||
last_updated: "2024-04-16"
|
||||
changelog:
|
||||
- "2024-04-16: 初始版本"
|
||||
```
|
||||
|
||||
### 4. 定期验证配置
|
||||
|
||||
```bash
|
||||
# 运行配置测试
|
||||
python framework_v2/tests/test_config.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 未来优化
|
||||
|
||||
1. [ ] 配置热重载(无需重启策略)
|
||||
2. [ ] 配置 diff 工具(对比版本差异)
|
||||
3. [ ] 配置 UI 编辑器(可视化配置)
|
||||
4. [ ] 配置模板系统(快速创建新策略)
|
||||
|
||||
---
|
||||
|
||||
## 版本历史
|
||||
|
||||
- **2024-04-16**: 初始版本
|
||||
- Pydantic Schema 验证
|
||||
- 环境变量替换
|
||||
- 资产池分类
|
||||
- 统一阈值配置
|
||||
- 多数据源降级
|
||||
- 6/6 测试通过
|
||||
Reference in New Issue
Block a user