- Introduced `indicators.py` containing implementations for SMA, EMA, RSI, MACD, and Bollinger Bands, optimized for handling sparse OHLCV data. - Added `IndicatorResult` dataclass to encapsulate results of indicator calculations. - Implemented methods for calculating multiple indicators efficiently with JSON configuration support and validation. - Updated `__init__.py` to include new indicators in the module's exports. - Enhanced documentation to cover the new technical indicators module, including usage examples and integration details. - Added comprehensive unit tests to ensure accuracy and robustness of the indicators module.
10 KiB
Technical Indicators Module
The Technical Indicators module provides comprehensive technical analysis capabilities for the TCP Trading Platform. It's designed to handle sparse OHLCV data efficiently and integrates seamlessly with the platform's aggregation strategy.
Overview
The module implements five core technical indicators commonly used in trading:
- Simple Moving Average (SMA) - Average price over a specified period
- Exponential Moving Average (EMA) - Weighted average giving more importance to recent prices
- Relative Strength Index (RSI) - Momentum oscillator measuring speed and change of price movements
- Moving Average Convergence Divergence (MACD) - Trend-following momentum indicator
- Bollinger Bands - Volatility indicator with upper and lower bands around a moving average
Key Features
Sparse Data Handling
- No Interpolation: Preserves gaps in timestamp data without artificial interpolation
- Efficient Processing: Uses pandas for vectorized calculations
- Right-Aligned Timestamps: Follows the platform's aggregation strategy convention
- Robust Error Handling: Gracefully handles insufficient data and edge cases
Performance Optimized
- Vectorized Calculations: Leverages pandas and numpy for fast computation
- Batch Processing: Calculate multiple indicators simultaneously
- Memory Efficient: Processes data in chunks without excessive memory usage
Flexible Configuration
- JSON Configuration: Define indicator parameters via configuration files
- Multiple Price Columns: Calculate indicators on open, high, low, or close prices
- Custom Parameters: Adjust periods, standard deviations, and other parameters
- Validation: Built-in configuration validation
Usage Examples
Basic Usage
from data.common.indicators import TechnicalIndicators
from data.common.data_types import OHLCVCandle
# Initialize indicators calculator
indicators = TechnicalIndicators()
# Calculate Simple Moving Average
sma_results = indicators.sma(candles, period=20)
# Calculate Exponential Moving Average
ema_results = indicators.ema(candles, period=12)
# Calculate RSI
rsi_results = indicators.rsi(candles, period=14)
# Calculate MACD
macd_results = indicators.macd(candles, fast_period=12, slow_period=26, signal_period=9)
# Calculate Bollinger Bands
bb_results = indicators.bollinger_bands(candles, period=20, std_dev=2.0)
Multiple Indicators
# Define configuration for multiple indicators
config = {
'sma_20': {'type': 'sma', 'period': 20},
'sma_50': {'type': 'sma', 'period': 50},
'ema_12': {'type': 'ema', 'period': 12},
'rsi_14': {'type': 'rsi', 'period': 14},
'macd': {'type': 'macd'},
'bb_20': {'type': 'bollinger_bands', 'period': 20}
}
# Calculate all indicators at once
results = indicators.calculate_multiple_indicators(candles, config)
# Access individual indicator results
sma_20_values = results['sma_20']
rsi_values = results['rsi_14']
macd_values = results['macd']
Using Different Price Columns
# Calculate SMA on high prices instead of close
sma_high = indicators.sma(candles, period=20, price_column='high')
# Calculate EMA on low prices
ema_low = indicators.ema(candles, period=12, price_column='low')
# Calculate RSI on open prices
rsi_open = indicators.rsi(candles, period=14, price_column='open')
Default Configuration
from data.common.indicators import create_default_indicators_config
# Get default configuration
default_config = create_default_indicators_config()
# Calculate using defaults
results = indicators.calculate_multiple_indicators(candles, default_config)
Indicator Details
Simple Moving Average (SMA)
Calculates the arithmetic mean of prices over a specified period.
Parameters:
period: Number of periods (default: 20)price_column: Price column to use (default: 'close')
Returns:
sma: Simple moving average value
Exponential Moving Average (EMA)
Calculates exponentially weighted moving average, giving more weight to recent prices.
Parameters:
period: Number of periods (default: 20)price_column: Price column to use (default: 'close')
Returns:
ema: Exponential moving average value
Relative Strength Index (RSI)
Momentum oscillator that measures the speed and change of price movements.
Parameters:
period: Number of periods (default: 14)price_column: Price column to use (default: 'close')
Returns:
rsi: RSI value (0-100 range)
MACD (Moving Average Convergence Divergence)
Trend-following momentum indicator showing the relationship between two moving averages.
Parameters:
fast_period: Fast EMA period (default: 12)slow_period: Slow EMA period (default: 26)signal_period: Signal line EMA period (default: 9)price_column: Price column to use (default: 'close')
Returns:
macd: MACD line (fast EMA - slow EMA)signal: Signal line (EMA of MACD)histogram: MACD histogram (MACD - Signal)
Bollinger Bands
Volatility indicator consisting of a moving average and two standard deviation bands.
Parameters:
period: Number of periods for moving average (default: 20)std_dev: Number of standard deviations (default: 2.0)price_column: Price column to use (default: 'close')
Returns:
upper_band: Upper Bollinger Bandmiddle_band: Middle band (SMA)lower_band: Lower Bollinger Bandbandwidth: Band width relative to middle bandpercent_b: %B indicator (position within bands)
Data Structures
IndicatorResult
Container for technical indicator calculation results.
@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:
{
"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_timefrom 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
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
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:
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