# CLAUDE-factors.md — 因子引擎 + 情绪因子 ## FactorEngine (`finance/factors/engine.py`) ```python from factors.registry import get_factor, list_factors from factors.engine import FactorEngine fe = FactorEngine(dm, sentiment_engine=sent) factor_df = fe.compute("000001.SZ", [get_factor("momentum_20"), get_factor("rsi_14")]) # → DataFrame: index=trade_date, columns=[momentum_20, rsi_14] cross = fe.compute_universe(factors, date="20250630", ts_codes=[...]) ``` 因子路由:`factor.category == "sentiment"` → SentimentEngine;`isinstance(f, FUNDAMENTAL_FACTOR_TYPES)` → 注入财务数据。 ## 因子注册表 (`finance/factors/registry.py`) 34 因子 / 12 分类:动量、RSI、MACD、量价、布林、ATR、均线、波动率、换手率、振幅、基本面、情绪。 ```python list_factors("动量") # → ['momentum_5','momentum_10','momentum_20','momentum_60'] get_factor("rsi_14") # → RSIFactor(period=14) ``` ## 技术因子 (`finance/factors/technical/`) 10 类。每个继承 `BaseFactor`,实现 `calculate(df) → pd.Series`。停牌跳过,新股不足 N 日返回 NaN。 ## 基本面因子 (`finance/factors/fundamental/`) - `roe.py` — ROEFactor(同花顺 `stock_financial_abstract_ths`) - `pe_pb.py` — PEFactor/PBFactor/EPFactor(close + 财务 EPS/BVPS map to daily) ## 情绪因子 (`finance/factors/sentiment/`) ### SentimentEngine (`sentiment_engine.py`) ```python sent = SentimentEngine(dm, qwen_client=client, news_source=news_src) sent_df = sent.compute("000001.SZ", max_news=30) # → DataFrame: news_sent_5, news_conf_5, sent_delta_5 ``` ### 新闻源 (`news_source.py`) 三数据源聚合:AkShare `stock_news_em` + DB `xwlb_daily_ext` + MCP `trendradar-news`。 xwlb 日期处理:DB `news_date +1day`(晚间播出→次日影响)→ `align_news_to_trading_days`。 AkShare 限频 → 自动 fallback。LIMIT 按日期跨度动态计算。 ### Qwen 客户端 (`qwen_client.py`) 双后端:DashScope API + 本地 Ollama。金融情绪专家 prompt,返回 `{sentiment_score, confidence, impact_duration, key_topics}`。配置:`.env` 中的 `QWEN_API_KEY` 或 `QWEN_LOCAL_BASE_URL`。 ### 情绪因子 (`sentiment_factor.py`) - `NewsSentimentFactor(window, decay)` — 时间衰减加权情绪 - `SentimentConfidenceFactor(window)` — score × confidence 加权 - `SentimentMomentumFactor(period)` — 情绪变化方向