- Enhanced the `UserIndicator` class to include an optional `timeframe` attribute for custom indicator timeframes. - Updated the `get_indicator_data` method in `MarketDataIntegrator` to fetch and calculate indicators based on the specified timeframe, ensuring proper data alignment and handling. - Modified the `ChartBuilder` to pass the correct DataFrame for plotting indicators with different timeframes. - Added UI elements in the indicator modal for selecting timeframes, improving user experience. - Updated relevant JSON templates to include the new `timeframe` field for all indicators. - Refactored the `prepare_chart_data` function to ensure it returns a DataFrame with a `DatetimeIndex` for consistent calculations. This commit enhances the flexibility and usability of the indicator system, allowing users to analyze data across various timeframes.
9.1 KiB
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
calculateMethod: 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.
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.
# 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.
# 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.
# 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.
@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