# ETF轮动策略系统架构分析与通用化设计报告 ## 一、现有系统架构分析 ### 1.1 整体架构概览 ``` etf/ ├── config/ # 配置中心 │ └── strategies/ │ └── rotation.yaml # 策略参数配置 ├── core/ # 核心基础设施 │ ├── common/ # 公共工具(utils、db、notify) │ ├── datasource/ # 数据源层(混合数据源、统一fetcher) │ └── factors/ # 因子计算层(动量、技术指标) ├── strategies/ # 策略层 │ ├── base.py # 策略抽象基类 │ └── rotation/ # 轮动策略实现 │ ├── engine.py # 策略引擎(核心逻辑) │ ├── portfolio.py # 持仓跟踪与交易记录 │ └── report.py # 绩效报告生成 ├── scripts/ # 运行入口 │ └── run_rotation.py # 回测脚本 ├── visualization/ # 可视化层 │ └── report_generator/ # HTML报告生成器 └── tests/ # 测试与实验 ``` ### 1.2 核心模块职责 | 模块 | 职责 | 关键文件 | |------|------|----------| | **数据源层** | 多源数据获取、SSH隧道、缓存管理 | `hybrid_source.py`, `universal_fetcher.py` | | **因子层** | 动量得分计算、崩盘过滤、ATR动态周期 | `momentum.py` | | **策略引擎** | 信号生成、选股逻辑、调仓控制 | `engine.py` | | **持仓跟踪** | 交易记录、持仓统计、汇总 | `portfolio.py` | | **报告层** | KPI计算、图表绘制、HTML生成 | `report.py`, `generate_report.py` | ### 1.3 策略核心流程 ```mermaid graph TB A[配置加载] --> B[数据获取] B --> C[因子计算] C --> D[信号生成] D --> E[回测执行] E --> F[持仓跟踪] F --> G[报告生成] B --> B1[Tushare A股] B --> B2[YFinance 港美股] B --> B3[SSH隧道代理] C --> C1[加权动量得分] C --> C2[崩盘过滤] C --> C3[溢价控制] D --> D1[类内竞争Top1] D --> D2[跨类排序Top3] D --> D3[T+1执行] ``` --- ## 二、现有实现特点分析 ### 2.1 数据层设计 **优点**: - 混合数据源架构:Tushare(A股) + YFinance(港美股) - SSH隧道统一治理:解决网络受限环境问题 - 双轨数据架构:指数价格(信号源)+ ETF价格(收益计算) - 智能路由:根据代码格式自动选择数据源 **问题**: - ETF列名与指数代码不匹配导致收益计算使用错误数据源 - 缓存策略过于简单,缺乏版本控制 ### 2.2 因子层设计 **优点**: - 三种因子类型:momentum、slope_r2、weighted_momentum - 崩盘过滤机制:防止追接下跌飞刀 - ATR动态周期:自适应市场波动 - 加权线性回归:近期权重更高,对趋势变化敏感 **问题**: - 因子类型固定,扩展需修改源码 - 缺乏因子组合/加权机制 ### 2.3 策略层设计 **优点**: - 分散化选股:每大类Top1→全局Top3,强制跨资产配置 - T+1执行机制:信号基于T日数据,T+1日执行 - 溢价控制:跨境ETF溢价过滤 - 持仓跟踪:完整的交易记录和净值贡献计算 **问题**: - 调仓逻辑与因子计算耦合 - 缺乏风控模块(止损、仓位管理) - 单一策略类型,无法扩展其他策略 ### 2.4 报告层设计 **优点**: - 完整的KPI指标体系 - 可视化报告:净值曲线、月度收益、盈亏分布、品种排行 - 数据一致性:严格基于回测结果文件 **问题**: - 报告与策略耦合 - 缺乏实盘监控接口 --- ## 三、通用交易系统抽象设计 ### 3.1 核心抽象原则 | 原则 | 说明 | |------|------| | **数据独立** | 数据获取与策略逻辑分离,支持多源扩展 | | **因子可插拔** | 因子计算模块化,支持自定义因子组合 | | **策略可配置** | 策略逻辑通过配置驱动,无需修改代码 | | **执行可扩展** | 支持回测、模拟盘、实盘多种执行模式 | | **风控独立** | 风控模块独立,支持止损、仓位、敞口控制 | ### 3.2 建议架构设计 ``` trading_system/ ├── core/ │ ├── data/ │ │ ├── sources/ # 数据源接口(可插拔) │ │ │ ├── base.py # 数据源抽象基类 │ │ │ ├── tushare.py │ │ │ ├── yfinance.py │ │ │ └── ccxt.py │ │ ├── router.py # 数据源路由 │ │ └── cache.py # 缓存管理(版本控制) │ │ │ ├── factors/ │ │ ├── base.py # 因子抽象基类 │ │ ├── registry.py # 因子注册器 │ │ ├── momentum.py │ │ ├── technical.py │ │ └── fundamental.py │ │ │ ├── execution/ │ │ ├── base.py # 执行器抽象基类 │ │ ├── backtest.py # 回测执行器 │ │ ├── simulator.py # 模拟盘执行器 │ │ └── live.py # 实盘执行器 │ │ │ └── risk/ │ │ ├── base.py # 风控抽象基类 │ │ ├── stop_loss.py # 止损控制 │ │ ├── position.py # 仓位控制 │ │ └── exposure.py # 敞口控制 │ ├── strategies/ │ ├── base.py # 策略抽象基类 │ ├── registry.py # 策略注册器 │ ├── rotation/ # 轮动策略 │ ├── momentum/ # 动量策略 │ └── screener/ # 篩选策略 │ ├── portfolio/ │ ├── manager.py # 持仓管理器 │ ├── tracker.py # 交易跟踪 │ ├── rebalancer.py # 调仓执行器 │ ├── report/ │ ├── generator.py # 报告生成器 │ ├── metrics.py # KPI计算 │ └── visualizer.py # 可视化 │ ├── config/ │ ├── system.yaml # 系统配置 │ ├── strategies/ # 策略配置 │ │ ├── rotation.yaml │ │ └── momentum.yaml │ └── factors/ # 因子配置 │ └── scheduler/ ├── engine.py # 调度引擎 ├── triggers.py # 触发器(定时、事件) └── notifier.py # 通知器 ``` ### 3.3 核心接口设计 ```python # ==================== 数据源接口 ==================== class DataSource(ABC): """数据源抽象基类""" @abstractmethod def fetch(self, code: str, start: str, end: str) -> pd.DataFrame: """获取OHLCV数据""" pass @abstractmethod def get_trading_calendar(self, market: str) -> List[datetime]: """获取交易日历""" pass @abstractmethod def get_supported_codes(self) -> List[str]: """获取支持的代码列表""" pass # ==================== 因子接口 ==================== class Factor(ABC): """因子抽象基类""" @abstractmethod def compute(self, data: pd.DataFrame) -> pd.Series: """计算因子值""" pass @abstractmethod def get_name(self) -> str: """获取因子名称""" pass @property def params(self) -> dict: """因子参数""" return {} class FactorRegistry: """因子注册器""" _factors = {} @classmethod def register(cls, name: str, factor_cls: Factor): cls._factors[name] = factor_cls @classmethod def get(cls, name: str) -> Factor: return cls._factors.get(name) @classmethod def list(cls) -> List[str]: return list(cls._factors.keys()) # ==================== 执行器接口 ==================== class Executor(ABC): """执行器抽象基类""" @abstractmethod def execute(self, signals: pd.DataFrame, portfolio: Portfolio) -> Portfolio: """执行信号""" pass @abstractmethod def get_mode(self) -> str: """获取执行模式""" pass class BacktestExecutor(Executor): """回测执行器""" def execute(self, signals, portfolio): # 处理调仓成本 # 计算收益率 # 更新净值 pass def get_mode(self) -> str: return "backtest" class LiveExecutor(Executor): """实盘执行器""" def execute(self, signals, portfolio): # 检查交易权限 # 发送交易指令 # 记录交易结果 pass def get_mode(self) -> str: return "live" # ==================== 风控接口 ==================== class RiskControl(ABC): """风控抽象基类""" @abstractmethod def check(self, portfolio: Portfolio, signal: Signal) -> bool: """风控检查""" pass @abstractmethod def apply(self, portfolio: Portfolio) -> Portfolio: """应用风控""" pass class StopLossControl(RiskControl): """止损控制""" def __init__(self, threshold: float = 0.05): self.threshold = threshold def check(self, portfolio, signal): # 检查是否触发止损 for position in portfolio.positions: if position.loss > self.threshold: return False return True def apply(self, portfolio): # 强制平仓止损 pass # ==================== 策略接口 ==================== class Strategy(ABC): """策略抽象基类""" @abstractmethod def generate_signals(self, data: pd.DataFrame) -> pd.DataFrame: """生成信号""" pass @abstractmethod def get_name(self) -> str: """获取策略名称""" pass @abstractmethod def validate_config(self, config: dict) -> bool: """验证配置""" pass # ==================== 持仓管理接口 ==================== class Portfolio: """持仓管理器""" def __init__(self): self.positions = {} # 当前持仓 self.cash = 0.0 # 现金 self.nav = 1.0 # 净值 self.trades = [] # 交易记录 def rebalance(self, target_positions: dict): """调仓""" pass def get_nav(self) -> float: """获取净值""" pass def get_positions(self) -> dict: """获取持仓""" return self.positions ``` ### 3.4 配置驱动设计 ```yaml # config/strategies/rotation.yaml(通用化后) # ==================== 基础配置 ==================== strategy: name: "rotation" version: "2.0" mode: "backtest" # backtest | simulator | live # ==================== 候选池配置 ==================== universe: type: "static" # static | dynamic codes: # ...(与现有配置相同) mapping: signal_to_trade: true # 信号源→交易标的映射 # ==================== 因子配置 ==================== factors: - name: "weighted_momentum" weight: 1.0 params: n_days: 25 crash_filter: true # 可扩展多个因子 # - name: "volatility" # weight: 0.3 # params: # period: 20 # ==================== 选股配置 ==================== selection: mode: "diversified" # top_n | diversified | custom select_num: 3 group_by: "market" # 按大类分组 top_per_group: 1 # ==================== 调仓配置 ==================== rebalance: frequency: "daily" min_holding_days: 1 threshold: 0.0 cost: 0.001 # ==================== 风控配置 ==================== risk: stop_loss: enabled: true threshold: 0.05 position_limit: max_position: 0.5 max_single: 0.33 premium_control: enabled: true threshold: 0.10 # ==================== 执行配置 ==================== execution: mode: "backtest" start_date: "2019-01-01" benchmark: "000300.SH" # ==================== 数据源配置 ==================== data: sources: - name: "tushare" markets: ["A"] - name: "yfinance" markets: ["US", "HK", "JP", "EU"] proxy: type: "ssh" host: "8.218.167.69" port: 22 ``` --- ## 四、迁移路径建议 ### 4.1 阶段一:数据层重构 **目标**:修复ETF列名问题,建立可扩展数据源架构 **任务**: 1. 修复`compute_factors()`中的ETF数据路由逻辑 2. 创建`DataSource`抽象基类 3. 统一数据缓存管理(添加版本控制) ### 4.2 阶段二:因子层抽象 **目标**:因子计算可插拔、可组合 **任务**: 1. 创建`Factor`抽象基类 2. 建立`FactorRegistry`注册机制 3. 支持因子组合和加权 ### 4.3 阶段三:风控模块独立 **目标**:止损、仓位、敞口控制 **任务**: 1. 创建`RiskControl`抽象基类 2. 实现止损控制 3. 实现仓位限制 ### 4.4 阶段四:执行器分离 **目标**:支持回测、模拟盘、实盘三种模式 **任务**: 1. 创建`Executor`抽象基类 2. 实现回测执行器(迁移现有逻辑) 3. 实现模拟盘执行器(模拟交易) 4. 实现实盘执行器(连接券商API) ### 4.5 阶段五:配置驱动 **目标**:策略逻辑通过配置驱动 **任务**: 1. 策略配置YAML重构 2. 配置验证机制 3. 热加载配置 --- ## 五、总结与建议 ### 5.1 现有系统评价 | 维度 | 评分 | 说明 | |------|------|------| | 数据层 | 3.5/5 | 多源架构优秀,但有列名匹配bug | | 因子层 | 4/5 | 加权动量设计合理,崩盘过滤有效 | | 策略层 | 3/5 | 分散化选股创新,但缺乏扩展性 | | 执行层 | 2/5 | 仅支持回测,缺乏模拟/实盘 | | 风控层 | 1/5 | 仅溢价控制,缺乏止损/仓位管理 | | 报告层 | 4.5/5 | KPI完整,可视化丰富 | ### 5.2 通用化优先级 | 优先级 | 模块 | 紧急程度 | 预估工作量 | |--------|------|----------|------------| | P0 | 修复ETF数据路由bug | 🔴紧急 | 0.5天 | | P1 | 风控模块独立 | 🟡重要 | 2天 | | P1 | 因子层抽象 | 🟡重要 | 1天 | | P2 | 数据源可插拔 | 🟢一般 | 2天 | | P2 | 执行器分离 | 🟢一般 | 3天 | | P3 | 配置驱动 | 🔵低 | 1天 | ### 5.3 关键改进建议 1. **立即修复**:ETF数据列名匹配问题(影响回测真实性) 2. **短期改进**:添加止损控制(保护实盘资金) 3. **中期重构**:数据源/因子/执行器抽象(提升扩展性) 4. **长期规划**:实盘执行器、调度系统(支持自动化运行) --- *文档版本:V1.0* *生成时间:2026-05-08* *适用范围:ETF轮动策略系统架构分析与通用化设计*