7 Sprints 全部完成: Sprint 0: 基础设施 (DataManager + MariaDB) Sprint 1: 因子引擎 (34因子/12分类) Sprint 2: VectorBT 回测 (5策略+截面) Sprint 3: Optuna 优化 (+Walk-Forward) Sprint 4: ML 模型 (LightGBM+CatBoost) Sprint 5: Qwen 情绪因子 (三源新闻+日期对齐) Sprint 6: Agent 系统 (4Agent+日报.md/.html) 生产加固 (15项): Tushare双源fallback, SSH自动恢复, pool_pre_ping, save_daily先删后插, load_dotenv绝对路径, 日报5d/20d修复, RiskAgent改上证指数, 昨日对比+数据截止, mac_report utf8mb4, CLAUDE-*.md 9条已知Bug, demo全参数化, djapi数据源归一化, indexDatas API修正 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
128 lines
4.9 KiB
Python
128 lines
4.9 KiB
Python
"""
|
||
因子注册表。
|
||
|
||
通过名称获取因子实例,方便回测和策略配置时引用。
|
||
"""
|
||
|
||
from factors.base import BaseFactor
|
||
from factors.technical.momentum import MomentumFactor
|
||
from factors.technical.rsi import RSIFactor
|
||
from factors.technical.macd import MACDFactor
|
||
from factors.technical.volume import VolumeFactor, VolumeChangeFactor
|
||
from factors.technical.bollinger import BollingerFactor, BollingerWidthFactor
|
||
from factors.technical.atr import ATRFactor, ATRRatioFactor
|
||
from factors.technical.ma_cross import MACrossFactor, MADeviationFactor
|
||
from factors.technical.volatility import VolatilityFactor, DownsideVolatilityFactor
|
||
from factors.technical.turnover import TurnoverFactor, TurnoverChangeFactor
|
||
from factors.technical.amplitude import AmplitudeFactor
|
||
from factors.fundamental.roe import ROEFactor
|
||
from factors.fundamental.pe_pb import PEFactor, PBFactor, EPFactor
|
||
from factors.sentiment.sentiment_factor import (
|
||
NewsSentimentFactor,
|
||
SentimentMomentumFactor,
|
||
SentimentConfidenceFactor,
|
||
)
|
||
|
||
# ── 内置因子工厂函数 ──────────────────────────────────────
|
||
|
||
_BUILTIN_FACTORIES: dict[str, callable] = { # type: ignore
|
||
# 动量
|
||
"momentum_5": lambda: MomentumFactor(period=5),
|
||
"momentum_10": lambda: MomentumFactor(period=10),
|
||
"momentum_20": lambda: MomentumFactor(period=20),
|
||
"momentum_60": lambda: MomentumFactor(period=60),
|
||
# RSI
|
||
"rsi_7": lambda: RSIFactor(period=7),
|
||
"rsi_14": lambda: RSIFactor(period=14),
|
||
# MACD
|
||
"macd": lambda: MACDFactor(),
|
||
"macd_5_35_5": lambda: MACDFactor(fast=5, slow=35, signal=5),
|
||
# 量价
|
||
"vol_ratio_5": lambda: VolumeFactor(period=5),
|
||
"vol_ratio_20": lambda: VolumeFactor(period=20),
|
||
"vol_chg_5": lambda: VolumeChangeFactor(period=5),
|
||
# 布林
|
||
"boll": lambda: BollingerFactor(),
|
||
"boll_width": lambda: BollingerWidthFactor(),
|
||
# ATR
|
||
"atr_14": lambda: ATRFactor(period=14),
|
||
"atr_ratio_14": lambda: ATRRatioFactor(period=14),
|
||
# 均线
|
||
"ma_cross_5_20": lambda: MACrossFactor(fast=5, slow=20),
|
||
"ma_cross_10_60": lambda: MACrossFactor(fast=10, slow=60),
|
||
"ma_dev_20": lambda: MADeviationFactor(period=20),
|
||
"ma_dev_60": lambda: MADeviationFactor(period=60),
|
||
# 波动率
|
||
"volatility_20": lambda: VolatilityFactor(period=20),
|
||
"volatility_60": lambda: VolatilityFactor(period=60),
|
||
"down_vol_20": lambda: DownsideVolatilityFactor(period=20),
|
||
# 换手率
|
||
"turnover_5": lambda: TurnoverFactor(period=5),
|
||
"turnover_chg_5": lambda: TurnoverChangeFactor(period=5),
|
||
# 振幅
|
||
"amplitude_5": lambda: AmplitudeFactor(period=5),
|
||
"amplitude_20": lambda: AmplitudeFactor(period=20),
|
||
# 基本面
|
||
"roe": lambda: ROEFactor(),
|
||
"pe": lambda: PEFactor(),
|
||
"pb": lambda: PBFactor(),
|
||
"ep": lambda: EPFactor(),
|
||
# 情绪
|
||
"news_sent_5": lambda: NewsSentimentFactor(window=5),
|
||
"news_sent_20": lambda: NewsSentimentFactor(window=20),
|
||
"news_conf_5": lambda: SentimentConfidenceFactor(window=5),
|
||
"sent_delta_5": lambda: SentimentMomentumFactor(period=5),
|
||
}
|
||
|
||
# ── 分类映射 ──────────────────────────────────────────────
|
||
|
||
FACTOR_CATEGORIES: dict[str, list[str]] = {
|
||
"动量": ["momentum_5", "momentum_10", "momentum_20", "momentum_60"],
|
||
"RSI": ["rsi_7", "rsi_14"],
|
||
"MACD": ["macd", "macd_5_35_5"],
|
||
"量价": ["vol_ratio_5", "vol_ratio_20", "vol_chg_5"],
|
||
"布林": ["boll", "boll_width"],
|
||
"ATR": ["atr_14", "atr_ratio_14"],
|
||
"均线": ["ma_cross_5_20", "ma_cross_10_60", "ma_dev_20", "ma_dev_60"],
|
||
"波动率": ["volatility_20", "volatility_60", "down_vol_20"],
|
||
"换手率": ["turnover_5", "turnover_chg_5"],
|
||
"振幅": ["amplitude_5", "amplitude_20"],
|
||
"基本面": ["roe", "pe", "pb", "ep"],
|
||
"情绪": ["news_sent_5", "news_sent_20", "news_conf_5", "sent_delta_5"],
|
||
}
|
||
|
||
|
||
def get_factor(name: str, **overrides) -> BaseFactor:
|
||
"""按名称获取因子实例。
|
||
|
||
参数:
|
||
name: 因子名称(如 'momentum_20')
|
||
**overrides: 覆盖默认参数
|
||
|
||
返回:
|
||
BaseFactor 实例
|
||
"""
|
||
if name not in _BUILTIN_FACTORIES:
|
||
raise KeyError(f"未知因子: '{name}'。可用: {list(_BUILTIN_FACTORIES)}")
|
||
factor = _BUILTIN_FACTORIES[name]()
|
||
if overrides:
|
||
for k, v in overrides.items():
|
||
if hasattr(factor, k):
|
||
setattr(factor, k, v)
|
||
# 更新 factor.name
|
||
if hasattr(factor, "name"):
|
||
factor.name = name
|
||
return factor
|
||
|
||
|
||
def list_factors(category: str | None = None) -> list[str]:
|
||
"""列出所有可用因子名称。"""
|
||
if category and category in FACTOR_CATEGORIES:
|
||
return FACTOR_CATEGORIES[category]
|
||
return list(_BUILTIN_FACTORIES)
|
||
|
||
|
||
def list_categories() -> list[str]:
|
||
"""列出所有因子分类。"""
|
||
return list(FACTOR_CATEGORIES)
|