Files
myquant/finance/factors/technical/rsi.py
T
Simon 73d191b43a feat: 量化引擎加固 — 新增测试 + 数据/因子/回测层优化
- 新增 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 扩充配置项
2026-08-31 14:01:06 +08:00

36 lines
1.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
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"]