Files
etf/docs/ETF轮动策略通用化重构方案.md
aszerW c54ba442ad docs: 添加策略框架调研与设计方案
包含4份核心文档:
- 轮动策略系统架构分析报告
- 量化策略通用框架抽象设计
- Freqtrade架构调研与对比分析
- ETF轮动策略通用化重构方案

调研结论:三种策略可抽象通用框架
设计决策:因子注册器风格 + 5个核心回调钩子 + TopN/Trend/Reversal信号生成器
2026-05-11 22:17:41 +08:00

387 lines
13 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.

# ETF轮动策略通用化重构方案
## 一、重构目标与范围
### 1.1 核心目标
**将现有轮动策略重构为通用量化框架**,支持:
- ✅ 轮动策略(动量选股 + Top N
- ✅ 趋势跟踪策略(趋势因子 + 信号跟随)
- ✅ 反转策略(反转因子 + 超买超卖)
- ✅ 自定义策略扩展
### 1.2 重构范围
| 模块 | 是否重构 | 重构内容 | 保持不变 |
|------|----------|----------|----------|
| **数据层** | ✅ 部分重构 | 添加DataSource抽象接口 | 混合数据源逻辑保留 |
| **因子层** | ✅ 重构 | FactorBase抽象 + 注册器 + 组合器 | 因子计算逻辑保留 |
| **信号层** | ✅ 重构 | SignalGenerator抽象TopN/Trend/Reversal | 选股逻辑迁移 |
| **风控层** | ✅ 新增 | 回调钩子 + 风控组件库 | 无(原为分散化) |
| **执行层** | ⚠️ 保持 | 回测引擎不变 | 回测逻辑完整保留 |
| **报告层** | ⚠️ 保持 | KPI计算不变 | 可视化保留 |
| **配置层** | ✅ 重构 | YAML配置驱动 | 参数结构保留 |
---
## 二、核心设计决策(需确认)
### 决策点1因子抽象方式
**选项AFreqtrade风格方法内定义**
```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*
*等待用户确认*