# Technical Indicators Module The Technical Indicators module provides a suite of common technical analysis tools. It is designed to work efficiently with pandas DataFrames, which is the standard data structure for time-series analysis in the TCP Trading Platform. ## Overview The module has been refactored to be **DataFrame-centric**. All calculation methods now expect a pandas DataFrame with a `DatetimeIndex` and the required OHLCV columns (`open`, `high`, `low`, `close`, `volume`). This change simplifies the data pipeline, improves performance through vectorization, and ensures consistency across the platform. The module implements five core technical indicators: - **Simple Moving Average (SMA)** - **Exponential Moving Average (EMA)** - **Relative Strength Index (RSI)** - **Moving Average Convergence Divergence (MACD)** - **Bollinger Bands** ## Key Features - **DataFrame-Centric Design**: Operates directly on pandas DataFrames for performance and simplicity. - **Vectorized Calculations**: Leverages pandas and numpy for high-speed computation. - **Flexible `calculate` Method**: A single entry point for calculating any supported indicator by name. - **Standardized Output**: All methods return a DataFrame containing the calculated indicator values, indexed by timestamp. ## Usage Examples ### Preparing the DataFrame Before you can calculate indicators, you need a properly formatted pandas DataFrame. The `prepare_chart_data` utility is the recommended way to create one from a list of candle dictionaries. ```python from components.charts.utils import prepare_chart_data from data.common.indicators import TechnicalIndicators # Assume 'candles' is a list of OHLCV dictionaries from the database # candles = fetch_market_data(...) # Prepare the DataFrame df = prepare_chart_data(candles) # df is now ready for indicator calculations # It has a DatetimeIndex and the necessary OHLCV columns. ``` ### Basic Indicator Calculation Once you have a prepared DataFrame, you can calculate indicators directly. ```python # Initialize the calculator indicators = TechnicalIndicators() # Calculate a Simple Moving Average sma_df = indicators.sma(df, period=20) # Calculate an Exponential Moving Average ema_df = indicators.ema(df, period=12) # sma_df and ema_df are pandas DataFrames containing the results. ``` ### Using the `calculate` Method The most flexible way to compute an indicator is with the `calculate` method, which accepts the indicator type as a string. ```python # Calculate RSI using the generic method rsi_pkg = indicators.calculate('rsi', df, period=14) if rsi_pkg: rsi_df = rsi_pkg['data'] # Calculate MACD with custom parameters macd_pkg = indicators.calculate('macd', df, fast_period=10, slow_period=30, signal_period=8) if macd_pkg: macd_df = macd_pkg['data'] ``` ### Using Different Price Columns You can specify which price column (`open`, `high`, `low`, or `close`) to use for the calculation. ```python # Calculate SMA on the 'high' price sma_high_df = indicators.sma(df, period=20, price_column='high') # Calculate RSI on the 'open' price rsi_open_pkg = indicators.calculate('rsi', df, period=14, price_column='open') ``` ## Indicator Details The following details the parameters and the columns returned in the result DataFrame for each indicator. ### Simple Moving Average (SMA) - **Parameters**: `period` (int), `price_column` (str, default: 'close') - **Returned Columns**: `sma` ### Exponential Moving Average (EMA) - **Parameters**: `period` (int), `price_column` (str, default: 'close') - **Returned Columns**: `ema` ### Relative Strength Index (RSI) - **Parameters**: `period` (int), `price_column` (str, default: 'close') - **Returned Columns**: `rsi` ### MACD (Moving Average Convergence Divergence) - **Parameters**: `fast_period` (int), `slow_period` (int), `signal_period` (int), `price_column` (str, default: 'close') - **Returned Columns**: `macd`, `signal`, `histogram` ### Bollinger Bands - **Parameters**: `period` (int), `std_dev` (float), `price_column` (str, default: 'close') - **Returned Columns**: `upper_band`, `middle_band`, `lower_band` ## Integration with the TCP Platform The refactored `TechnicalIndicators` module is now tightly integrated with the `ChartBuilder`, which handles all data preparation and calculation automatically when indicators are added to a chart. For custom analysis or strategy development, you can use the class directly as shown in the examples above. The key is to always start with a properly prepared DataFrame using `prepare_chart_data`. ## Data Structures ### IndicatorResult Container for technical indicator calculation results. ```python @dataclass class IndicatorResult: timestamp: datetime # Right-aligned candle timestamp symbol: str # Trading symbol (e.g., 'BTC-USDT') timeframe: str # Candle timeframe (e.g., '1m', '5m') values: Dict[str, float] # Indicator values metadata: Optional[Dict[str, Any]] = None # Calculation metadata ``` ### Configuration Format Indicator configurations use a standardized JSON format: ```json { "indicator_name": { "type": "sma|ema|rsi|macd|bollinger_bands", "period": 20, "price_column": "close", // Additional parameters specific to indicator type } } ``` ## Integration with TCP Platform ### Aggregation Strategy Compatibility The indicators module is designed to work seamlessly with the TCP platform's aggregation strategy: - **Right-Aligned Timestamps**: Uses `end_time` from OHLCV candles - **Sparse Data Support**: Handles missing candles without interpolation - **No Future Leakage**: Only processes completed candles - **Time Boundary Respect**: Maintains proper temporal ordering ### Real-Time Processing ```python from data.common.aggregation import RealTimeCandleProcessor from data.common.indicators import TechnicalIndicators # Set up real-time processing candle_processor = RealTimeCandleProcessor(symbol='BTC-USDT', exchange='okx') indicators = TechnicalIndicators() # Process incoming trades and calculate indicators def on_new_candle(candle): # Get recent candles for indicator calculation recent_candles = get_recent_candles(symbol='BTC-USDT', count=50) # Calculate indicators sma_results = indicators.sma(recent_candles, period=20) rsi_results = indicators.rsi(recent_candles, period=14) # Use indicator values for trading decisions if sma_results and rsi_results: latest_sma = sma_results[-1].values['sma'] latest_rsi = rsi_results[-1].values['rsi'] # Trading logic here... ``` ### Database Integration ```python from database.models import IndicatorData # Store indicator results in database def store_indicators(indicator_results, indicator_type): for result in indicator_results: indicator_data = IndicatorData( symbol=result.symbol, timeframe=result.timeframe, timestamp=result.timestamp, indicator_type=indicator_type, values=result.values, metadata=result.metadata ) session.add(indicator_data) session.commit() ``` ## Performance Considerations ### Memory Usage - Process indicators in batches for large datasets - Use appropriate period lengths to balance accuracy and performance - Consider data retention policies for historical indicator values ### Calculation Frequency - Calculate indicators only when new complete candles are available - Cache recent indicator values to avoid recalculation - Use incremental updates for real-time scenarios ### Optimization Tips - Use `calculate_multiple_indicators()` for efficiency when computing multiple indicators - Limit the number of historical candles to what's actually needed - Consider using different timeframes for different indicators ## Error Handling The module includes comprehensive error handling: - **Insufficient Data**: Returns empty results when not enough data is available - **Invalid Configuration**: Validates configuration parameters before calculation - **Data Quality Issues**: Handles NaN values and missing data gracefully - **Type Errors**: Converts data types safely with fallback values ## Testing The module includes comprehensive unit tests covering: - All indicator calculations with known expected values - Sparse data handling scenarios - Edge cases (insufficient data, invalid parameters) - Configuration validation - Multiple indicator batch processing Run tests with: ```bash uv run pytest tests/test_indicators.py -v ``` ## Future Enhancements Potential future additions to the indicators module: - **Additional Indicators**: Stochastic, Williams %R, Commodity Channel Index - **Custom Indicators**: Framework for user-defined indicators - **Performance Metrics**: Calculation timing and memory usage statistics - **Streaming Updates**: Incremental indicator updates for real-time scenarios - **Parallel Processing**: Multi-threaded calculation for large datasets ## See Also - [Aggregation Strategy Documentation](aggregation-strategy.md) - [Data Types Documentation](data-types.md) - [Database Schema Documentation](database-schema.md) - [API Reference](api-reference.md)