docs: 添加策略框架调研与设计方案
包含4份核心文档: - 轮动策略系统架构分析报告 - 量化策略通用框架抽象设计 - Freqtrade架构调研与对比分析 - ETF轮动策略通用化重构方案 调研结论:三种策略可抽象通用框架 设计决策:因子注册器风格 + 5个核心回调钩子 + TopN/Trend/Reversal信号生成器
This commit is contained in:
387
docs/ETF轮动策略通用化重构方案.md
Normal file
387
docs/ETF轮动策略通用化重构方案.md
Normal file
@@ -0,0 +1,387 @@
|
||||
# ETF轮动策略通用化重构方案
|
||||
|
||||
## 一、重构目标与范围
|
||||
|
||||
### 1.1 核心目标
|
||||
|
||||
**将现有轮动策略重构为通用量化框架**,支持:
|
||||
- ✅ 轮动策略(动量选股 + Top N)
|
||||
- ✅ 趋势跟踪策略(趋势因子 + 信号跟随)
|
||||
- ✅ 反转策略(反转因子 + 超买超卖)
|
||||
- ✅ 自定义策略扩展
|
||||
|
||||
### 1.2 重构范围
|
||||
|
||||
| 模块 | 是否重构 | 重构内容 | 保持不变 |
|
||||
|------|----------|----------|----------|
|
||||
| **数据层** | ✅ 部分重构 | 添加DataSource抽象接口 | 混合数据源逻辑保留 |
|
||||
| **因子层** | ✅ 重构 | FactorBase抽象 + 注册器 + 组合器 | 因子计算逻辑保留 |
|
||||
| **信号层** | ✅ 重构 | SignalGenerator抽象(TopN/Trend/Reversal) | 选股逻辑迁移 |
|
||||
| **风控层** | ✅ 新增 | 回调钩子 + 风控组件库 | 无(原为分散化) |
|
||||
| **执行层** | ⚠️ 保持 | 回测引擎不变 | 回测逻辑完整保留 |
|
||||
| **报告层** | ⚠️ 保持 | KPI计算不变 | 可视化保留 |
|
||||
| **配置层** | ✅ 重构 | YAML配置驱动 | 参数结构保留 |
|
||||
|
||||
---
|
||||
|
||||
## 二、核心设计决策(需确认)
|
||||
|
||||
### 决策点1:因子抽象方式
|
||||
|
||||
**选项A:Freqtrade风格(方法内定义)**
|
||||
```python
|
||||
def populate_indicators(self, dataframe):
|
||||
dataframe['momentum'] = calculate_momentum(dataframe, 25)
|
||||
dataframe['rsi'] = ta.RSI(dataframe, 14)
|
||||
return dataframe
|
||||
```
|
||||
- 优点:简单直观,与Freqtrade一致
|
||||
- 缺点:因子不可复用,难以组合
|
||||
|
||||
**选项B:注册器风格(模块化)**
|
||||
```python
|
||||
class MomentumFactor(FactorBase):
|
||||
def compute(self, data):
|
||||
return calculate_momentum(data, self.n_days)
|
||||
|
||||
FactorRegistry.register(MomentumFactor)
|
||||
|
||||
# 在策略中使用
|
||||
factors = FactorCombiner([
|
||||
FactorRegistry.get('momentum', n_days=25),
|
||||
FactorRegistry.get('volatility', period=20)
|
||||
])
|
||||
```
|
||||
- 优点:因子可复用、可组合、可插拔
|
||||
- 缺点:复杂度略高
|
||||
|
||||
**建议**:**选择B(注册器风格)**,保持我们的模块化优势。
|
||||
|
||||
---
|
||||
|
||||
### 决策点2:回调钩子范围
|
||||
|
||||
**参考Freqtrade的回调设计**:
|
||||
|
||||
| 回调钩子 | 用途 | 是否需要 |
|
||||
|----------|------|----------|
|
||||
| `before_entry` | 入场前检查(溢价、崩盘) | ✅ 需要 |
|
||||
| `after_entry` | 入场后记录 | ⚠️ 可选 |
|
||||
| `before_exit` | 出场前检查 | ⚠️ 可选 |
|
||||
| `after_exit` | 出场后记录 | ⚠️ 可选 |
|
||||
| `dynamic_stoploss` | 动态止损 | ✅ 需要 |
|
||||
| `custom_exit` | 自定义出场条件 | ✅ 需要 |
|
||||
| `position_adjust` | DCA/部分止盈 | ❌ 不需要(轮动不适用) |
|
||||
|
||||
**建议**:**实现5个核心回调**(before_entry, dynamic_stoploss, custom_exit, after_entry, after_exit)。
|
||||
|
||||
---
|
||||
|
||||
### 册策点3:参数装饰器设计
|
||||
|
||||
**Freqtrade风格**:
|
||||
```python
|
||||
class RotationStrategy:
|
||||
n_days = IntParameter(10, 60, default=25, space='factor')
|
||||
select_num = IntParameter(1, 5, default=3, space='signal')
|
||||
```
|
||||
|
||||
**简化风格(无Hyperopt)**:
|
||||
```python
|
||||
class RotationStrategy:
|
||||
n_days = 25 # 类属性,可被配置覆盖
|
||||
select_num = 3
|
||||
```
|
||||
|
||||
**建议**:**先实现简化版(类属性 + 配置覆盖)**,后续再添加参数装饰器 + Hyperopt。
|
||||
|
||||
---
|
||||
|
||||
### 决策点4:信号生成抽象
|
||||
|
||||
**选项A:统一SignalGenerator接口**
|
||||
```python
|
||||
class SignalGenerator(ABC):
|
||||
def generate(self, factor_data: DataFrame) -> DataFrame
|
||||
|
||||
class TopNSelector(SignalGenerator):
|
||||
def generate(self, factor_data):
|
||||
# Top N选股逻辑
|
||||
|
||||
class TrendFollower(SignalGenerator):
|
||||
def generate(self, factor_data):
|
||||
# 趋势跟随逻辑
|
||||
```
|
||||
|
||||
**选项B:策略直接生成信号**
|
||||
```python
|
||||
class RotationStrategy:
|
||||
def generate_signals(self, data):
|
||||
# 直接在策略内生成
|
||||
```
|
||||
|
||||
**建议**:**选择A(统一SignalGenerator)**,信号逻辑可复用、可插拔。
|
||||
|
||||
---
|
||||
|
||||
### 决策点5:执行模式支持
|
||||
|
||||
**Freqtrade支持**:backtest / hyperopt / dry / live
|
||||
|
||||
**当前系统支持**:backtest only
|
||||
|
||||
**需要添加**:
|
||||
- ✅ dry-run(模拟盘):验证策略逻辑
|
||||
- ⚠️ live(实盘):需券商API对接
|
||||
- ❌ hyperopt:后期添加
|
||||
|
||||
**建议**:**仅添加dry-run模式**,实盘执行器延后。
|
||||
|
||||
---
|
||||
|
||||
## 三、分阶段实施路径
|
||||
|
||||
### 阶段一:因子层抽象(P1,预估2天)
|
||||
|
||||
**目标**:因子可插拔、可组合
|
||||
|
||||
**实施内容**:
|
||||
1. 创建`FactorBase`抽象基类
|
||||
2. 创建`FactorRegistry`注册器
|
||||
3. 创建`FactorCombiner`组合器
|
||||
4. 重构现有动量因子为`MomentumFactor`
|
||||
5. 添加技术因子(`TrendFactor`, `ReversalFactor`)
|
||||
|
||||
**验收标准**:
|
||||
- 因子可注册、可获取、可组合
|
||||
- 现有轮动策略功能不变(回归测试)
|
||||
|
||||
---
|
||||
|
||||
### 阶段二:信号层抽象(P1,预估1天)
|
||||
|
||||
**目标**:信号生成可插拔
|
||||
|
||||
**实施内容**:
|
||||
1. 创建`SignalGenerator`抽象基类
|
||||
2. 创建`TopNSelector`实现(迁移现有选股逻辑)
|
||||
3. 创建`TrendFollower`实现
|
||||
4. 创建`ReversalTrader`实现
|
||||
|
||||
**验收标准**:
|
||||
- 三种信号生成器可独立运行
|
||||
- TopNSelector与原逻辑一致
|
||||
|
||||
---
|
||||
|
||||
### 阶段三:回调钩子机制(P1,预估1天)
|
||||
|
||||
**目标**:生命周期可控
|
||||
|
||||
**实施内容**:
|
||||
1. 在`StrategyBase`中添加回调钩子定义
|
||||
2. 实现`before_entry`回调(溢价过滤)
|
||||
3. 实现`dynamic_stoploss`回调
|
||||
4. 实现`custom_exit`回调
|
||||
|
||||
**验收标准**:
|
||||
- 回调可正常触发
|
||||
- 溢价过滤生效
|
||||
- 动态止损生效
|
||||
|
||||
---
|
||||
|
||||
### 阶段四:配置驱动重构(P2,预估1天)
|
||||
|
||||
**目标**:策略参数可配置
|
||||
|
||||
**实施内容**:
|
||||
1. YAML配置结构设计
|
||||
2. 配置加载与验证
|
||||
3. 配置覆盖类属性
|
||||
4. 策略工厂(根据配置创建策略)
|
||||
|
||||
**验收标准**:
|
||||
- 可通过YAML配置运行策略
|
||||
- 配置可覆盖策略默认参数
|
||||
|
||||
---
|
||||
|
||||
### 阶段五:趋势/反转策略实现(P3,预估2-3天)
|
||||
|
||||
**目标**:验证框架扩展性
|
||||
|
||||
**实施内容**:
|
||||
1. 实现`TrendFollowStrategy`
|
||||
2. 实现`ReversalStrategy`
|
||||
3. 回测验证
|
||||
|
||||
**验收标准**:
|
||||
- 新策略可正常运行
|
||||
- 回测报告正常生成
|
||||
|
||||
---
|
||||
|
||||
## 四、预期收益与风险
|
||||
|
||||
### 4.1 预期收益
|
||||
|
||||
| 维度 | 当前状态 | 重构后 | 提升 |
|
||||
|------|----------|--------|------|
|
||||
| **代码复用** | 因子/信号耦合 | 模块化复用 | 50%+ |
|
||||
| **策略扩展** | 仅轮动策略 | 支持3+策略类型 | - |
|
||||
| **参数调优** | 手动修改代码 | 配置驱动 | 效率提升 |
|
||||
| **风控灵活性** | 固定分散化 | 回调动态控制 | - |
|
||||
| **维护成本** | 多处修改 | 单点修改 | 降低50% |
|
||||
|
||||
### 4.2 风险评估
|
||||
|
||||
| 风险 | 等级 | 应对措施 |
|
||||
|------|------|----------|
|
||||
| **回归风险**:重构导致原有逻辑变化 | 🔴高 | 每阶段完成后运行回测验证 |
|
||||
| **性能风险**:抽象层增加性能损耗 | 🟡中 | 保持向量化计算,避免循环 |
|
||||
| **复杂度风险**:抽象层增加理解成本 | 🟡中 | 完善文档 + 示例代码 |
|
||||
| **时间风险**:预估时间不准 | 🟢低 | 分阶段验收,及时调整 |
|
||||
|
||||
---
|
||||
|
||||
## 五、关键架构图
|
||||
|
||||
### 5.1 最终架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ QuantStrategyFramework │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ DataSource │ │ FactorLayer │ │ SignalLayer │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ - HybridSrc │ │ - FactorBase │ │ - SignalGen │ │
|
||||
│ │ - Tushare │ │ - Registry │ │ - TopN │ │
|
||||
│ │ - YFinance │ │ - Combiner │ │ - Trend │ │
|
||||
│ │ │ │ │ │ - Reversal │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ StrategyBase │ │ RiskLayer │ │ ExecLayer │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ - populate_* │ │ - Callbacks │ │ - Backtest │ │
|
||||
│ │ - 回调钩子 │ │ - StopLoss │ │ - DryRun │ │
|
||||
│ │ │ │ - Position │ │ │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Config (YAML驱动) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │RotationStrat │ │ TrendStrat │ │ ReversalStrat│ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ 动量因子 │ │ 趋势因子 │ │ 反转因子 │ │
|
||||
│ │ TopN选股 │ │ 趋势跟随 │ │ 反转交易 │ │
|
||||
│ │ 回调过滤 │ │ 动态止损 │ │ 快速止损 │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 5.2 因子层设计
|
||||
|
||||
```python
|
||||
# 因子基类
|
||||
class FactorBase(ABC):
|
||||
@abstractmethod
|
||||
def compute(self, data: DataFrame) -> Series
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def name(self) -> str
|
||||
|
||||
# 因子注册
|
||||
FactorRegistry.register(MomentumFactor)
|
||||
FactorRegistry.register(TrendFactor)
|
||||
|
||||
# 因子组合
|
||||
factors = FactorCombiner([
|
||||
FactorRegistry.get('momentum', n_days=25, weight=0.7),
|
||||
FactorRegistry.get('volatility', period=20, weight=0.3)
|
||||
])
|
||||
```
|
||||
|
||||
### 5.3 信号层设计
|
||||
|
||||
```python
|
||||
# 信号生成器
|
||||
class TopNSelector(SignalGenerator):
|
||||
def generate(self, factor_data):
|
||||
# 按因子值排序,选Top N
|
||||
|
||||
class TrendFollower(SignalGenerator):
|
||||
def generate(self, factor_data):
|
||||
# 趋势强度 > 阈值 → 入场
|
||||
|
||||
class ReversalTrader(SignalGenerator):
|
||||
def generate(self, factor_data):
|
||||
# 超买超卖 → 反转信号
|
||||
```
|
||||
|
||||
### 5.4 回调钩子设计
|
||||
|
||||
```python
|
||||
class StrategyBase:
|
||||
# 入场前回调
|
||||
def before_entry(self, code: str, price: float, **kwargs) -> bool:
|
||||
"""可拒绝交易"""
|
||||
if kwargs.get('premium', 0) > 0.10:
|
||||
return False
|
||||
return True
|
||||
|
||||
# 动态止损回调
|
||||
def dynamic_stoploss(self, position: Position) -> float:
|
||||
"""根据持仓时间调整止损"""
|
||||
if position.holding_days > 10:
|
||||
return -0.03
|
||||
return -0.10
|
||||
|
||||
# 自定义出场回调
|
||||
def custom_exit(self, position: Position) -> bool:
|
||||
"""反转信号强制出场"""
|
||||
return False
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、需确认事项清单
|
||||
|
||||
| 序号 | 决策点 | 选项 | 建议 | 你的选择 |
|
||||
|------|--------|------|------|----------|
|
||||
| 1 | 因子抽象方式 | A:方法内 / B:注册器 | **B** | ? |
|
||||
| 2 | 回调钩子范围 | 5个 / 7个 / 全部 | **5个核心** | ? |
|
||||
| 3 | 参数装饰器 | 简化版 / Freqtrade风格 | **先简化版** | ? |
|
||||
| 4 | 信号生成抽象 | 统一接口 / 策略内生成 | **统一接口** | ? |
|
||||
| 5 | 执行模式支持 | 仅backtest / +dry-run / +live | **+dry-run** | ? |
|
||||
| 6 | 实施优先级 | 全部实施 / 分阶段 | **分阶段** | ? |
|
||||
| 7 | 时间安排 | 立即开始 / 等待确认 | **等待确认** | ? |
|
||||
|
||||
---
|
||||
|
||||
## 七、下一步行动
|
||||
|
||||
**确认方案后,我将开始**:
|
||||
1. 创建`FactorBase`抽象基类
|
||||
2. 创建`FactorRegistry`注册器
|
||||
3. 重构现有动量因子
|
||||
4. 运行回测验证功能不变
|
||||
|
||||
**请确认以下内容**:
|
||||
- ✅ 重构范围是否合理
|
||||
- ✅ 设计决策是否认可
|
||||
- ✅ 实施路径是否可行
|
||||
- ✅ 时间安排是否同意
|
||||
|
||||
---
|
||||
|
||||
*方案版本:V1.0*
|
||||
*生成时间:2026-05-08*
|
||||
*等待用户确认*
|
||||
Reference in New Issue
Block a user