TCPDashboard/docs/modules/technical-indicators.md
Vasily.onl c8d8d980aa Refactor technical indicators module and enhance structure
- Introduced a dedicated sub-package for technical indicators under `data/common/indicators/`, improving modularity and maintainability.
- Moved `TechnicalIndicators` and `IndicatorResult` classes to their respective files, along with utility functions for configuration management.
- Updated import paths throughout the codebase to reflect the new structure, ensuring compatibility.
- Added comprehensive safety net tests for the indicators module to verify core functionality and prevent regressions during refactoring.
- Enhanced documentation to provide clear usage examples and details on the new package structure.

These changes improve the overall architecture of the technical indicators module, making it more scalable and easier to manage.
2025-06-07 01:32:21 +08:00

288 lines
9.7 KiB
Markdown

# 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 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
```
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.
- **Modular Architecture**: Clear separation between calculation logic, result types, and utilities.
## Usage Examples
### 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
```
### 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`
## Data Structures
### IndicatorResult
The `IndicatorResult` class (from `data.common.indicators.result`) contains 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 Management
The module provides utilities for managing indicator configurations (from `data.common.indicators.utils`):
```python
# Create default configurations
config = create_default_indicators_config()
# Validate a configuration
is_valid = validate_indicator_config({
'type': 'sma',
'period': 20,
'price_column': 'close'
})
```
### Integration with TCP Platform
The indicators module is designed to work seamlessly with the platform's components:
```python
from data.common.indicators import TechnicalIndicators
from data.common.data_types import OHLCVCandle
from components.charts.utils import prepare_chart_data
# Initialize calculator
indicators = TechnicalIndicators()
# Calculate indicators
results = indicators.calculate_multiple_indicators(df, {
'sma_20': {'type': 'sma', 'period': 20},
'rsi_14': {'type': 'rsi', 'period': 14}
})
# Access results
for indicator_name, indicator_results in results.items():
for result in indicator_results:
print(f"{indicator_name}: {result.values}")
```
## 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`.
## 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)
## `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.