TCPDashboard/docs/modules/technical-indicators.md

339 lines
9.1 KiB
Markdown
Raw Normal View History

# Technical Indicators Module
## Overview
2025-06-07 14:12:37 +08:00
The Technical Indicators module provides a modular, extensible system for calculating technical analysis indicators. It is designed to handle sparse OHLCV data efficiently, making it ideal for real-time trading applications.
2025-06-07 14:12:37 +08:00
## Architecture
2025-06-07 14:12:37 +08:00
### Package Structure
```
data/common/indicators/
2025-06-07 14:12:37 +08:00
├── __init__.py # Package exports
├── technical.py # Main facade class
├── base.py # Base indicator class
├── result.py # Result container class
├── utils.py # Utility functions
└── implementations/ # Individual indicator implementations
├── __init__.py
├── sma.py # Simple Moving Average
├── ema.py # Exponential Moving Average
├── rsi.py # Relative Strength Index
├── macd.py # MACD
└── bollinger.py # Bollinger Bands
```
### Key Components
#### 1. Base Classes
- **BaseIndicator**: Abstract base class providing common functionality
- Data preparation
- Validation
- Error handling
- Logging
#### 2. Individual Indicators
Each indicator is implemented as a separate class inheriting from `BaseIndicator`:
- Focused responsibility
- Independent testing
- Easy maintenance
- Clear documentation
#### 3. TechnicalIndicators Facade
Main entry point providing:
- Unified interface
- Batch calculations
- Consistent error handling
- Data preparation
## Supported Indicators
### Simple Moving Average (SMA)
```python
from data.common.indicators import TechnicalIndicators
indicators = TechnicalIndicators()
results = indicators.sma(df, period=20, price_column='close')
```
- **Parameters**:
- `period`: Number of periods (default: 20)
- `price_column`: Column to average (default: 'close')
### Exponential Moving Average (EMA)
```python
results = indicators.ema(df, period=12, price_column='close')
```
- **Parameters**:
- `period`: Number of periods (default: 20)
- `price_column`: Column to average (default: 'close')
### Relative Strength Index (RSI)
```python
results = indicators.rsi(df, period=14, price_column='close')
```
- **Parameters**:
- `period`: Number of periods (default: 14)
- `price_column`: Column to analyze (default: 'close')
### Moving Average Convergence Divergence (MACD)
```python
results = indicators.macd(
df,
fast_period=12,
slow_period=26,
signal_period=9,
price_column='close'
)
```
- **Parameters**:
- `fast_period`: Fast EMA period (default: 12)
- `slow_period`: Slow EMA period (default: 26)
- `signal_period`: Signal line period (default: 9)
- `price_column`: Column to analyze (default: 'close')
### Bollinger Bands
```python
results = indicators.bollinger_bands(
df,
period=20,
std_dev=2.0,
price_column='close'
)
```
- **Parameters**:
- `period`: SMA period (default: 20)
- `std_dev`: Standard deviation multiplier (default: 2.0)
- `price_column`: Column to analyze (default: 'close')
## Usage Examples
### Basic Usage
```python
from data.common.indicators import TechnicalIndicators
# Initialize calculator
indicators = TechnicalIndicators(logger=my_logger)
# Calculate single indicator
sma_results = indicators.sma(df, period=20)
# Access results
for result in sma_results:
print(f"Time: {result.timestamp}, SMA: {result.values['sma']}")
```
### Batch Calculations
```python
# Configure multiple indicators
config = {
'sma_20': {'type': 'sma', 'period': 20},
'ema_12': {'type': 'ema', 'period': 12},
'rsi_14': {'type': 'rsi', 'period': 14},
'macd': {
'type': 'macd',
'fast_period': 12,
'slow_period': 26,
'signal_period': 9
}
}
# Calculate all at once
results = indicators.calculate_multiple_indicators(df, config)
```
### Dynamic Indicator Selection
```python
# Calculate any indicator by name
result = indicators.calculate(
'macd',
df,
fast_period=12,
slow_period=26,
signal_period=9
)
```
## Data Structures
### IndicatorResult
```python
@dataclass
class IndicatorResult:
timestamp: datetime # Right-aligned timestamp
symbol: str # Trading symbol
timeframe: str # Candle timeframe
values: Dict[str, float] # Indicator values
metadata: Optional[Dict[str, Any]] = None # Calculation metadata
```
## Error Handling
The module provides comprehensive error handling:
- Input validation
- Data sufficiency checks
- Calculation error handling
- Detailed error logging
Example:
```python
try:
results = indicators.rsi(df, period=14)
except Exception as e:
logger.error(f"RSI calculation failed: {e}")
results = []
```
## Performance Considerations
1. **Data Preparation**
- Uses pandas for vectorized calculations
- Handles sparse data efficiently
- Maintains timestamp alignment
2. **Memory Usage**
- Avoids unnecessary data copies
- Cleans up temporary calculations
- Uses efficient data structures
3. **Calculation Optimization**
- Vectorized operations where possible
- Minimal data transformations
- Efficient algorithm implementations
## Testing
The module includes comprehensive tests:
- Unit tests for each indicator
- Integration tests for the facade
- Edge case handling
- Performance benchmarks
Run tests with:
```bash
uv run pytest tests/test_indicators.py
```
2025-06-07 14:12:37 +08:00
## Contributing
2025-06-07 14:12:37 +08:00
When adding new indicators:
1. Create a new class in `implementations/`
2. Inherit from `BaseIndicator`
3. Implement the `calculate` method
4. Add tests
5. Update documentation
See [Adding New Indicators](./adding-new-indicators.md) for detailed instructions.
## 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')
2025-06-07 14:12:37 +08:00
- **Returned Columns**: `upper_band`, `