- 新增 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 扩充配置项
36 lines
1.2 KiB
Python
36 lines
1.2 KiB
Python
"""
|
||
RSI 相对强弱因子。
|
||
"""
|
||
|
||
import numpy as np
|
||
import pandas as pd
|
||
|
||
from factors.base import BaseFactor
|
||
|
||
|
||
class RSIFactor(BaseFactor):
|
||
"""Wilder's RSI = 100 - 100 / (1 + RS), RS = avg_gain / avg_loss"""
|
||
|
||
category = "technical"
|
||
|
||
def __init__(self, period: int = 14):
|
||
self.period = period
|
||
self.name = f"rsi_{period}"
|
||
|
||
def calculate(self, df: pd.DataFrame) -> pd.Series:
|
||
delta = df["close"].diff()
|
||
gain = delta.clip(lower=0)
|
||
loss = (-delta).clip(lower=0)
|
||
avg_gain = gain.ewm(span=self.period, min_periods=self.period).mean()
|
||
avg_loss = loss.ewm(span=self.period, min_periods=self.period).mean()
|
||
# 标准 Wilder RSI:avg_loss==0 时 RSI 应 = 100,而非 NaN。
|
||
# 用 where 显式处理除零,避免 replace(0, nan) 把上涨趋势判为缺失。
|
||
rs = avg_gain / avg_loss.where(avg_loss != 0, np.nan)
|
||
rsi = 100 - 100 / (1 + rs)
|
||
# 上涨且无下跌的高位情形补 100(无 prior-loss 的窗口仍留 NaN 由上游填充)
|
||
rsi = rsi.where(avg_loss != 0, 100.0)
|
||
return rsi
|
||
|
||
def get_required_columns(self) -> list[str]:
|
||
return ["close"]
|