diegobeyl/backtesting
2
1"""2Clase base abstracta para algoritmos de trading3NO MODIFICAR - Este archivo define la interfaz que todos los algoritmos deben implementar4"""5 6from abc import ABC, abstractmethod7from dataclasses import dataclass, field8from typing import List, Optional, Dict, Any9from datetime import datetime10import pandas as pd11from enum import Enum12 13 14class TrendState(Enum):15 """Estado de tendencia"""16 BULLISH = 117 BEARISH = 018 NEUTRAL = -119 20 21@dataclass22class TradeSignal:23 """Señal de trading generada por el algoritmo"""24 timestamp: datetime25 signal_type: str # 'LONG', 'SHORT', 'CLOSE_LONG', 'CLOSE_SHORT', 'NONE'26 price: float27 stop_loss: Optional[float] = None28 reason: str = ""29 30 31@dataclass32class AlgorithmState:33 """Estado interno del algoritmo en cada barra"""34 bar_index: int35 timestamp: datetime36 trend: TrendState37 support: Optional[float]38 resistance: Optional[float]39 signal: Optional[TradeSignal] = None40 extra_data: Dict[str, Any] = field(default_factory=dict)41 42 43@dataclass44class AlgorithmResult:45 """Resultado de la ejecución del algoritmo"""46 states: List[AlgorithmState]47 signals: List[TradeSignal]48 support_history: List[Optional[float]]49 resistance_history: List[Optional[float]]50 trend_history: List[TrendState]51 52 def get_trend_series(self, index: pd.DatetimeIndex) -> pd.Series:53 """Convierte el historial de tendencias a una Serie de pandas"""54 return pd.Series(self.trend_history, index=index[:len(self.trend_history)])55 56 57class BaseAlgorithm(ABC):58 """59 Clase base abstracta para todos los algoritmos de trading.60 61 NO MODIFICAR esta clase - Define la interfaz que deben implementar62 todos los algoritmos (FAST, SLOW, etc.)63 """64 65 def __init__(self, name: str, version: str):66 self._name = name67 self._version = version68 self._is_initialized = False69 70 @property71 def name(self) -> str:72 return self._name73 74 @property75 def version(self) -> str:76 return self._version77 78 @property79 def full_name(self) -> str:80 return f"{self._name} v{self._version}"81 82 @abstractmethod83 def get_default_params(self) -> Dict[str, Any]:84 """85 Retorna los parámetros por defecto del algoritmo.86 Cada algoritmo debe definir sus propios parámetros.87 """88 pass89 90 @abstractmethod91 def get_param_descriptions(self) -> Dict[str, str]:92 """93 Retorna descripciones de cada parámetro para la UI.94 """95 pass96 97 @abstractmethod98 def validate_params(self, params: Dict[str, Any]) -> bool:99 """100 Valida que los parámetros sean correctos.101 Retorna True si son válidos, False si no.102 """103 pass104 105 @abstractmethod106 def run(self, df: pd.DataFrame, params: Dict[str, Any]) -> AlgorithmResult:107 """108 Ejecuta el algoritmo sobre los datos proporcionados.109 110 Args:111 df: DataFrame con columnas OHLCV (open, high, low, close, volume)112 params: Diccionario con los parámetros del algoritmo113 114 Returns:115 AlgorithmResult con los estados, señales e historial116 """117 pass118 119 def _validate_dataframe(self, df: pd.DataFrame) -> bool:120 """Valida que el DataFrame tenga las columnas necesarias"""121 required_columns = ['open', 'high', 'low', 'close']122 return all(col in df.columns for col in required_columns)123 