- 新增 finance/tests/ 6 个测试套件(agents/backtest/dao_upsert/factors/features/fundamental_lookahead) - 数据层: data_manager / dao 优化,新增 upsert 逻辑 - 因子层: 基本面因子抽象定位 _mapping、ROE/PE/PB 重构 - 回测层: vectorbt/engine 大改动(251 行),report 增强 - ML 层: features/backtest_integration 特征工程与回测优化 - CLI: agent_cli 重构 - config/settings 扩充配置项
132 lines
5.2 KiB
Python
132 lines
5.2 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 实例
|
||
|
||
说明: 返回实例的 .name 恒等于注册键 name,即使构造器默认生成的
|
||
.name 与注册键不同(如 boll 的构造器默认 .name='boll_20')——
|
||
注册键是列名的唯一事实源,避免 FactorEngine.compute 的列名漂移。
|
||
"""
|
||
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)
|
||
# 无论是否覆盖参数,都强制 .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)
|