TCPDashboard/docs/modules/technical-indicators.md
2025-06-07 14:12:37 +08:00

9.1 KiB

Technical Indicators Module

Overview

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.

Architecture

Package Structure

data/common/indicators/
├── __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)

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)

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)

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)

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

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

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

# 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

# Calculate any indicator by name
result = indicators.calculate(
    'macd',
    df,
    fast_period=12,
    slow_period=26,
    signal_period=9
)

Data Structures

IndicatorResult

@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:

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:

uv run pytest tests/test_indicators.py

Contributing

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 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

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.

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, `