TCPDashboard/docs/guides/adding-new-indicators.md

353 lines
10 KiB
Markdown
Raw Permalink Normal View History

2025-06-07 14:12:37 +08:00
# Adding New Indicators Guide
## Overview
This guide provides comprehensive instructions for adding new technical indicators to the Crypto Trading Bot Dashboard. The system uses a modular approach where each indicator is implemented as a separate class inheriting from `BaseIndicator`.
## Table of Contents
1. [Prerequisites](#prerequisites)
2. [Implementation Steps](#implementation-steps)
3. [Integration with Charts](#integration-with-charts)
4. [Best Practices](#best-practices)
5. [Testing Guidelines](#testing-guidelines)
6. [Common Pitfalls](#common-pitfalls)
7. [Example Implementation](#example-implementation)
## Prerequisites
- Python knowledge with pandas/numpy
- Understanding of technical analysis concepts
- Familiarity with the project structure
- Knowledge of the indicator's mathematical formula
- Understanding of the dashboard's chart system
## Implementation Steps
### 1. Create Indicator Class
Create a new file in `data/common/indicators/implementations/` named after your indicator (e.g., `stochastic.py`):
```python
from typing import Dict, Any, List
import pandas as pd
from ..base import BaseIndicator
from ..result import IndicatorResult
class StochasticIndicator(BaseIndicator):
"""
Stochastic Oscillator implementation.
The Stochastic Oscillator is a momentum indicator comparing a particular closing price
of a security to a range of its prices over a certain period of time.
"""
def __init__(self, logger=None):
super().__init__(logger)
self.name = "stochastic"
def calculate(self, df: pd.DataFrame, k_period: int = 14,
d_period: int = 3, price_column: str = 'close') -> List[IndicatorResult]:
"""
Calculate Stochastic Oscillator.
Args:
df: DataFrame with OHLCV data
k_period: The K period (default: 14)
d_period: The D period (default: 3)
price_column: Column to use for calculations (default: 'close')
Returns:
List of IndicatorResult objects containing %K and %D values
"""
try:
# Validate inputs
self._validate_dataframe(df)
self._validate_period(k_period, min_value=2)
self._validate_period(d_period, min_value=2)
# Calculate %K
lowest_low = df['low'].rolling(window=k_period).min()
highest_high = df['high'].rolling(window=k_period).max()
k_percent = 100 * ((df[price_column] - lowest_low) /
(highest_high - lowest_low))
# Calculate %D (signal line)
d_percent = k_percent.rolling(window=d_period).mean()
# Create results
results = []
for idx, row in df.iterrows():
if pd.notna(k_percent[idx]) and pd.notna(d_percent[idx]):
results.append(IndicatorResult(
timestamp=idx,
symbol=self._get_symbol(df),
timeframe=self._get_timeframe(df),
values={
'k_percent': float(k_percent[idx]),
'd_percent': float(d_percent[idx])
},
metadata={
'k_period': k_period,
'd_period': d_period
}
))
return results
except Exception as e:
self._handle_error(f"Error calculating Stochastic: {str(e)}")
return []
```
### 2. Register the Indicator
Add your indicator to `data/common/indicators/implementations/__init__.py`:
```python
from .stochastic import StochasticIndicator
__all__ = [
'SMAIndicator',
'EMAIndicator',
'RSIIndicator',
'MACDIndicator',
'BollingerBandsIndicator',
'StochasticIndicator'
]
```
### 3. Add to TechnicalIndicators Class
Update `data/common/indicators/technical.py`:
```python
class TechnicalIndicators:
def __init__(self, logger=None):
self.logger = logger
# ... existing indicators ...
self._stochastic = StochasticIndicator(logger)
def stochastic(self, df: pd.DataFrame, k_period: int = 14,
d_period: int = 3, price_column: str = 'close') -> List[IndicatorResult]:
"""
Calculate Stochastic Oscillator.
Args:
df: DataFrame with OHLCV data
k_period: The K period (default: 14)
d_period: The D period (default: 3)
price_column: Column to use (default: 'close')
Returns:
List of indicator results with %K and %D values
"""
return self._stochastic.calculate(
df,
k_period=k_period,
d_period=d_period,
price_column=price_column
)
```
## Integration with Charts
### 1. Create Chart Layer
Create a new layer class in `components/charts/layers/indicators.py` (overlay) or `components/charts/layers/subplots.py` (subplot):
```python
class StochasticLayer(IndicatorLayer):
def __init__(self, config: Dict[str, Any]):
super().__init__(config)
self.name = "stochastic"
self.display_type = "subplot"
def create_traces(self, df: pd.DataFrame, values: Dict[str, pd.Series]) -> List[go.Scatter]:
traces = []
traces.append(go.Scatter(
x=df.index,
y=values['k_percent'],
mode='lines',
name=f"%K ({self.config.get('k_period', 14)})",
line=dict(
color=self.config.get('color', '#007bff'),
width=self.config.get('line_width', 2)
)
))
traces.append(go.Scatter(
x=df.index,
y=values['d_percent'],
mode='lines',
name=f"%D ({self.config.get('d_period', 3)})",
line=dict(
color=self.config.get('secondary_color', '#ff6b35'),
width=self.config.get('line_width', 2)
)
))
return traces
```
### 2. Register in Layer Registry
Update `components/charts/layers/__init__.py`:
```python
SUBPLOT_REGISTRY = {
'rsi': RSILayer,
'macd': MACDLayer,
'stochastic': StochasticLayer,
}
```
### 3. Add UI Components
***(No longer needed - UI is dynamically generated from JSON templates)***
2025-06-07 14:12:37 +08:00
## Best Practices
### Code Quality
- Follow the project's coding style
- Add comprehensive docstrings
- Include type hints
- Handle edge cases gracefully
- Use vectorized operations where possible
### Error Handling
- Validate all input parameters
- Check for sufficient data
- Handle NaN values appropriately
- Log errors with meaningful messages
- Return empty results for invalid inputs
### Performance
- Use vectorized operations
- Avoid unnecessary loops
- Clean up temporary calculations
- Consider memory usage
- Cache results when appropriate
### Documentation
- Document all public methods
- Include usage examples
- Explain parameter ranges
- Document any assumptions
- Keep documentation up-to-date
## Testing Guidelines
### Test File Structure
Create `tests/indicators/test_stochastic.py`:
```python
import pytest
import pandas as pd
import numpy as np
from data.common.indicators import TechnicalIndicators
@pytest.fixture
def sample_data():
return pd.DataFrame({
'open': [10, 11, 12, 13, 14],
'high': [12, 13, 14, 15, 16],
'low': [8, 9, 10, 11, 12],
'close': [11, 12, 13, 14, 15],
'volume': [100, 110, 120, 130, 140]
}, index=pd.date_range('2023-01-01', periods=5))
def test_stochastic_calculation(sample_data):
indicators = TechnicalIndicators()
results = indicators.stochastic(sample_data, k_period=3, d_period=2)
assert len(results) > 0
for result in results:
assert 0 <= result.values['k_percent'] <= 100
assert 0 <= result.values['d_percent'] <= 100
```
### Testing Checklist
- [ ] Basic functionality with ideal data
- [ ] Edge cases (insufficient data, NaN values)
- [ ] Performance with large datasets
- [ ] Error handling
- [ ] Parameter validation
- [ ] Integration with TechnicalIndicators class
- [ ] Chart layer rendering
- [ ] UI interaction
### Running Tests
```bash
# Run all indicator tests
uv run pytest tests/indicators/
# Run specific indicator tests
uv run pytest tests/indicators/test_stochastic.py
# Run with coverage
uv run pytest tests/indicators/ --cov=data.common.indicators
```
## Common Pitfalls
1. **Insufficient Data Handling**
- Always check if enough data points are available
- Return empty results rather than partial calculations
- Consider the impact of NaN values
2. **NaN Handling**
- Use appropriate pandas NaN handling methods
- Don't propagate NaN values unnecessarily
- Document NaN handling behavior
3. **Memory Leaks**
- Clean up temporary DataFrames
- Avoid storing large datasets
- Use efficient data structures
4. **Performance Issues**
- Use vectorized operations instead of loops
- Profile code with large datasets
- Consider caching strategies
5. **UI Integration**
- Handle all parameter combinations
- Provide meaningful validation
- Give clear user feedback
## Example Implementation
See the complete Stochastic Oscillator implementation above as a reference. Key points:
1. **Modular Structure**
- Separate indicator class
- Clear inheritance hierarchy
- Focused responsibility
2. **Error Handling**
- Input validation
- Exception handling
- Meaningful error messages
3. **Performance**
- Vectorized calculations
- Efficient data structures
- Memory management
4. **Testing**
- Comprehensive test cases
- Edge case handling
- Performance verification
## Support
For questions or issues:
1. Check existing documentation
2. Review test cases
3. Consult with team members
4. Create detailed bug reports if needed
## Related Documentation
- [Technical Indicators Overview](../modules/technical-indicators.md)
- [Chart System Documentation](../modules/charts/README.md)
- [Data Types Documentation](../modules/data-types.md)