2025-06-02 13:42:00 +08:00
# Technical Indicators Module
2025-06-06 15:06:17 +08:00
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.
2025-06-02 13:42:00 +08:00
## Overview
2025-06-07 01:32:21 +08:00
The module has been refactored into a dedicated package structure under `data/common/indicators/` . 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.
### Package Structure
```
data/common/indicators/
├── __init__ .py # Package exports
├── technical.py # TechnicalIndicators class implementation
├── result.py # IndicatorResult dataclass
└── utils.py # Utility functions for configuration
```
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
The module implements five core technical indicators:
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
- **Simple Moving Average (SMA)**
- **Exponential Moving Average (EMA)**
- **Relative Strength Index (RSI)**
- **Moving Average Convergence Divergence (MACD)**
- **Bollinger Bands**
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
## Key Features
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
- **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.
2025-06-07 01:32:21 +08:00
- **Modular Architecture**: Clear separation between calculation logic, result types, and utilities.
2025-06-02 13:42:00 +08:00
## Usage Examples
2025-06-07 01:32:21 +08:00
### Importing the Required Components
```python
from data.common.indicators import (
TechnicalIndicators,
IndicatorResult,
create_default_indicators_config,
validate_indicator_config
)
from data.common.data_types import OHLCVCandle
```
2025-06-06 15:06:17 +08:00
### 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.
2025-06-02 13:42:00 +08:00
```python
2025-06-06 15:06:17 +08:00
from components.charts.utils import prepare_chart_data
2025-06-02 13:42:00 +08:00
from data.common.indicators import TechnicalIndicators
2025-06-06 15:06:17 +08:00
# Assume 'candles' is a list of OHLCV dictionaries from the database
# candles = fetch_market_data(...)
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
# Prepare the DataFrame
df = prepare_chart_data(candles)
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
# df is now ready for indicator calculations
# It has a DatetimeIndex and the necessary OHLCV columns.
```
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
### Basic Indicator Calculation
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
Once you have a prepared DataFrame, you can calculate indicators directly.
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
```python
# Initialize the calculator
indicators = TechnicalIndicators()
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
# Calculate a Simple Moving Average
sma_df = indicators.sma(df, period=20)
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
# Calculate an Exponential Moving Average
ema_df = indicators.ema(df, period=12)
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
# sma_df and ema_df are pandas DataFrames containing the results.
```
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
### Using the `calculate` Method
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
The most flexible way to compute an indicator is with the `calculate` method, which accepts the indicator type as a string.
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
```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']
2025-06-02 13:42:00 +08:00
```
2025-06-06 15:06:17 +08:00
### Using Different Price Columns
You can specify which price column (`open` , `high` , `low` , or `close` ) to use for the calculation.
2025-06-02 13:42:00 +08:00
```python
2025-06-06 15:06:17 +08:00
# Calculate SMA on the 'high' price
sma_high_df = indicators.sma(df, period=20, price_column='high')
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
# Calculate RSI on the 'open' price
rsi_open_pkg = indicators.calculate('rsi', df, period=14, price_column='open')
2025-06-02 13:42:00 +08:00
```
## Indicator Details
2025-06-06 15:06:17 +08:00
The following details the parameters and the columns returned in the result DataFrame for each indicator.
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
### Simple Moving Average (SMA)
2025-06-02 13:42:00 +08:00
2025-06-06 15:06:17 +08:00
- **Parameters** : `period` (int), `price_column` (str, default: 'close')
- **Returned Columns** : `sma`
2025-06-02 13:42:00 +08:00
### Exponential Moving Average (EMA)
2025-06-06 15:06:17 +08:00
- **Parameters** : `period` (int), `price_column` (str, default: 'close')
- **Returned Columns** : `ema`
2025-06-02 13:42:00 +08:00
### Relative Strength Index (RSI)
2025-06-06 15:06:17 +08:00
- **Parameters** : `period` (int), `price_column` (str, default: 'close')
- **Returned Columns** : `rsi`
2025-06-02 13:42:00 +08:00
### MACD (Moving Average Convergence Divergence)
2025-06-06 15:06:17 +08:00
- **Parameters** : `fast_period` (int), `slow_period` (int), `signal_period` (int), `price_column` (str, default: 'close')
- **Returned Columns** : `macd` , `signal` , `histogram`
2025-06-02 13:42:00 +08:00
### Bollinger Bands
2025-06-06 15:06:17 +08:00
- **Parameters** : `period` (int), `std_dev` (float), `price_column` (str, default: 'close')
- **Returned Columns** : `upper_band` , `middle_band` , `lower_band`
2025-06-02 13:42:00 +08:00
## Data Structures
### IndicatorResult
2025-06-07 01:32:21 +08:00
The `IndicatorResult` class (from `data.common.indicators.result` ) contains technical indicator calculation results:
2025-06-02 13:42:00 +08:00
```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
```
2025-06-07 01:32:21 +08:00
### Configuration Management
2025-06-02 13:42:00 +08:00
2025-06-07 01:32:21 +08:00
The module provides utilities for managing indicator configurations (from `data.common.indicators.utils` ):
2025-06-02 13:42:00 +08:00
2025-06-07 01:32:21 +08:00
```python
# Create default configurations
config = create_default_indicators_config()
# Validate a configuration
is_valid = validate_indicator_config({
'type': 'sma',
'period': 20,
'price_column': 'close'
})
2025-06-02 13:42:00 +08:00
```
2025-06-07 01:32:21 +08:00
### Integration with TCP Platform
2025-06-02 13:42:00 +08:00
2025-06-07 01:32:21 +08:00
The indicators module is designed to work seamlessly with the platform's components:
2025-06-02 13:42:00 +08:00
```python
from data.common.indicators import TechnicalIndicators
2025-06-07 01:32:21 +08:00
from data.common.data_types import OHLCVCandle
from components.charts.utils import prepare_chart_data
2025-06-02 13:42:00 +08:00
2025-06-07 01:32:21 +08:00
# Initialize calculator
2025-06-02 13:42:00 +08:00
indicators = TechnicalIndicators()
2025-06-07 01:32:21 +08:00
# Calculate indicators
results = indicators.calculate_multiple_indicators(df, {
'sma_20': {'type': 'sma', 'period': 20},
'rsi_14': {'type': 'rsi', 'period': 14}
})
2025-06-02 13:42:00 +08:00
2025-06-07 01:32:21 +08:00
# Access results
for indicator_name, indicator_results in results.items():
2025-06-02 13:42:00 +08:00
for result in indicator_results:
2025-06-07 01:32:21 +08:00
print(f"{indicator_name}: {result.values}")
2025-06-02 13:42:00 +08:00
```
2025-06-07 01:32:21 +08:00
## 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` .
2025-06-02 13:42:00 +08:00
## 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 )
2025-06-06 20:33:29 +08:00
- [API Reference ](api-reference.md )
## `TechnicalIndicators` Class
The main class for calculating technical indicators.
- **RSI**: `rsi(df, period=14, price_column='close')`
- **MACD**: `macd(df, fast_period=12, slow_period=26, signal_period=9, price_column='close')`
- **Bollinger Bands**: `bollinger_bands(df, period=20, std_dev=2.0, price_column='close')`
### `calculate_multiple_indicators`
Calculates multiple indicators in a single pass for efficiency.
```python
# Configuration for multiple indicators
indicators_config = {
'sma_20': {'type': 'sma', 'period': 20},
'ema_50': {'type': 'ema', 'period': 50},
'rsi_14': {'type': 'rsi', 'period': 14}
}
# Calculate all indicators
all_results = ti.calculate_multiple_indicators(candles, indicators_config)
print(f"SMA results: {len(all_results['sma_20'])}")
print(f"RSI results: {len(all_results['rsi_14'])}")
```
## Sparse Data Handling
The `TechnicalIndicators` class is designed to handle sparse OHLCV data, which is a common scenario in real-time data collection.