""" Relative Strength Index (RSI) indicator implementation. """ from typing import List import pandas as pd import numpy as np from ..base import BaseIndicator from ..result import IndicatorResult class RSIIndicator(BaseIndicator): """ Relative Strength Index (RSI) technical indicator. Measures momentum by comparing the magnitude of recent gains to recent losses. Handles sparse data appropriately without interpolation. """ def calculate(self, df: pd.DataFrame, period: int = 14, price_column: str = 'close') -> pd.DataFrame: """ Calculate Relative Strength Index (RSI). Args: df: DataFrame with OHLCV data period: Number of periods for RSI calculation (default: 14) price_column: Price column to use ('open', 'high', 'low', 'close') Returns: DataFrame with RSI values and metadata, indexed by timestamp """ # Validate input data if not self.validate_dataframe(df, period): return pd.DataFrame() try: df = df.copy() delta = df[price_column].diff() gain = (delta.where(delta > 0, 0)).rolling(window=period).mean() loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean() rs = gain / loss rs = rs.replace([np.inf, -np.inf], np.nan) df['rsi'] = 100 - (100 / (1 + rs)) # Only keep rows with valid RSI, and only 'timestamp' and 'rsi' columns result_df = df.loc[df['rsi'].notna(), ['timestamp', 'rsi']].copy() result_df = result_df.iloc[period-1:] result_df.set_index('timestamp', inplace=True) return result_df except Exception: return pd.DataFrame()