106 lines
3.1 KiB
Python
106 lines
3.1 KiB
Python
"""
|
|
Base classes and interfaces for technical indicators.
|
|
|
|
This module provides the foundation for all technical indicators
|
|
with common functionality and type definitions.
|
|
"""
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import List, Dict, Any
|
|
import pandas as pd
|
|
from utils.logger import get_logger
|
|
|
|
from .result import IndicatorResult
|
|
from ..data_types import OHLCVCandle
|
|
|
|
|
|
|
|
class BaseIndicator(ABC):
|
|
"""
|
|
Abstract base class for all technical indicators.
|
|
|
|
Provides common functionality and enforces consistent interface
|
|
across all indicator implementations.
|
|
"""
|
|
|
|
def __init__(self, logger=None):
|
|
"""
|
|
Initialize base indicator.
|
|
|
|
Args:
|
|
logger: Optional logger instance
|
|
"""
|
|
if logger is None:
|
|
self.logger = get_logger(__name__)
|
|
self.logger = logger
|
|
|
|
def prepare_dataframe(self, candles: List[OHLCVCandle]) -> pd.DataFrame:
|
|
"""
|
|
Convert OHLCV candles to pandas DataFrame for calculations.
|
|
|
|
Args:
|
|
candles: List of OHLCV candles (can be sparse)
|
|
|
|
Returns:
|
|
DataFrame with OHLCV data, sorted by timestamp
|
|
"""
|
|
if not candles:
|
|
return pd.DataFrame()
|
|
|
|
# Convert to DataFrame
|
|
data = []
|
|
for candle in candles:
|
|
data.append({
|
|
'timestamp': candle.end_time, # Right-aligned timestamp
|
|
'symbol': candle.symbol,
|
|
'timeframe': candle.timeframe,
|
|
'open': float(candle.open),
|
|
'high': float(candle.high),
|
|
'low': float(candle.low),
|
|
'close': float(candle.close),
|
|
'volume': float(candle.volume),
|
|
'trade_count': candle.trade_count
|
|
})
|
|
|
|
df = pd.DataFrame(data)
|
|
|
|
# Sort by timestamp to ensure proper order
|
|
df = df.sort_values('timestamp').reset_index(drop=True)
|
|
|
|
# Set timestamp as index for time-series operations
|
|
df.set_index('timestamp', inplace=True)
|
|
|
|
return df
|
|
|
|
@abstractmethod
|
|
def calculate(self, df: pd.DataFrame, **kwargs) -> List[IndicatorResult]:
|
|
"""
|
|
Calculate the indicator values.
|
|
|
|
Args:
|
|
df: DataFrame with OHLCV data
|
|
**kwargs: Additional parameters specific to each indicator
|
|
|
|
Returns:
|
|
List of indicator results
|
|
"""
|
|
pass
|
|
|
|
def validate_dataframe(self, df: pd.DataFrame, min_periods: int) -> bool:
|
|
"""
|
|
Validate that DataFrame has sufficient data for calculation.
|
|
|
|
Args:
|
|
df: DataFrame to validate
|
|
min_periods: Minimum number of periods required
|
|
|
|
Returns:
|
|
True if DataFrame is valid, False otherwise
|
|
"""
|
|
if df.empty or len(df) < min_periods:
|
|
if self.logger:
|
|
self.logger.warning(
|
|
f"Insufficient data: got {len(df)} periods, need {min_periods}"
|
|
)
|
|
return False
|
|
return True |