""" Exponential Moving Average (EMA) indicator implementation. """ import pandas as pd from ..base import BaseIndicator class EMAIndicator(BaseIndicator): """ Exponential Moving Average (EMA) technical indicator. Calculates weighted moving average giving more weight to recent prices. Handles sparse data appropriately without interpolation. """ def calculate(self, df: pd.DataFrame, period: int = 20, price_column: str = 'close') -> pd.DataFrame: """ Calculate Exponential Moving Average (EMA). Args: df: DataFrame with OHLCV data period: Number of periods for moving average (default: 20) price_column: Price column to use ('open', 'high', 'low', 'close') Returns: DataFrame with EMA values and metadata, indexed by timestamp """ # Validate input data if not self.validate_dataframe(df, period): return pd.DataFrame() try: df = df.copy() df['ema'] = df[price_column].ewm(span=period, adjust=False).mean() # Only keep rows with valid EMA, and only 'timestamp' and 'ema' columns result_df = df.loc[df['ema'].notna(), ['timestamp', 'ema']].copy() # Only keep rows after enough data for EMA result_df = result_df.iloc[period-1:] result_df.set_index('timestamp', inplace=True) return result_df except Exception: return pd.DataFrame()