# 🧪 Backtesting Engine - Guía de Uso ## 📋 Descripción El motor de backtesting permite simular estrategias de trading sobre datos históricos para evaluar su performance antes de arriesgar capital real. ## 🚀 Uso Rápido ### Demo Simple ```bash python backtest.py ``` Esto ejecuta un backtest con: - Estrategia: Moving Average Crossover (10/30) - Símbolo: BTC/USDT - Periodo: 60 días - Capital inicial: $10,000 ### Comparar Estrategias ```bash python backtest.py compare ``` Compara 4 estrategias diferentes sobre los mismos datos. ## 📊 Estrategias Disponibles ### 1. Moving Average Crossover Cruces de medias móviles: ```python from src.strategies import MovingAverageCrossover strategy = MovingAverageCrossover( fast_period=10, # Periodo media rápida slow_period=30, # Periodo media lenta ma_type='sma' # 'sma' o 'ema' ) ``` **Señales:** - BUY: Media rápida cruza por encima de media lenta - SELL: Media rápida cruza por debajo de media lenta ### 2. RSI Strategy Basada en niveles de RSI: ```python from src.strategies import RSIStrategy strategy = RSIStrategy( rsi_period=14, # Periodo del RSI oversold_threshold=30, # Umbral de sobreventa overbought_threshold=70 # Umbral de sobrecompra ) ``` **Señales:** - BUY: RSI < 30 (sobrevendido) - SELL: RSI > 70 (sobrecomprado) ### 3. Buy and Hold Estrategia base para comparación: ```python from src.strategies import BuyAndHold strategy = BuyAndHold() ``` Compra al inicio y mantiene hasta el final. ## 🛠️ Uso Programático ### Backtest Básico ```python from src.data.storage import StorageManager from src.backtest import BacktestEngine from src.strategies import MovingAverageCrossover # Cargar datos storage = StorageManager(...) data = storage.load_ohlcv('BTC/USDT', '1h') # Crear estrategia strategy = MovingAverageCrossover(fast_period=10, slow_period=30) # Crear motor de backtesting engine = BacktestEngine( strategy=strategy, initial_capital=10000, commission=0.001, # 0.1% por trade slippage=0.0005, # 0.05% de slippage position_size=0.95 # Usar 95% del capital ) # Ejecutar results = engine.run(data) # Ver resultados from src.backtest.metrics import print_backtest_report print_backtest_report(results) ``` ### Crear Tu Propia Estrategia ```python from src.backtest.strategy import Strategy, Signal import pandas as pd class MiEstrategia(Strategy): def __init__(self): super().__init__(name="Mi Estrategia", params={}) def init_indicators(self, data: pd.DataFrame) -> pd.DataFrame: """ Calcula tus indicadores aquí """ # Ejemplo: añadir SMA data['sma_20'] = data['close'].rolling(20).mean() return data def generate_signal(self, idx: int) -> Signal: """ Lógica de tu estrategia """ current_price = self.data.iloc[idx]['close'] sma = self.data.iloc[idx]['sma_20'] # Ejemplo: comprar si precio > SMA if current_price > sma and self.current_position == 0: return Signal.BUY # Vender si precio < SMA y tenemos posición elif current_price < sma and self.current_position > 0: return Signal.SELL return Signal.HOLD # Usar tu estrategia strategy = MiEstrategia() engine = BacktestEngine(strategy, initial_capital=10000) results = engine.run(data) ``` ## 📈 Métricas Disponibles ### Básicas - **Total Return**: Retorno total del periodo - **Total Trades**: Número de trades ejecutados - **Win Rate**: Porcentaje de trades ganadores - **Profit Factor**: Ganancia bruta / Pérdida bruta ### Avanzadas - **Sharpe Ratio**: Retorno ajustado por riesgo - **Sortino Ratio**: Como Sharpe pero solo penaliza volatilidad a la baja - **Max Drawdown**: Máxima caída desde un pico - **Calmar Ratio**: Retorno anualizado / Max Drawdown - **Expectancy**: Ganancia esperada por trade - **Recovery Factor**: Net Profit / Max Drawdown ## 🎯 Estructura de Resultados ```python results = { # Capital 'initial_capital': 10000, 'final_equity': 12500, 'total_return': 0.25, 'total_return_pct': 25.0, 'total_pnl': 2500, # Trades 'total_trades': 15, 'winning_trades': 9, 'losing_trades': 6, 'win_rate': 0.6, 'win_rate_pct': 60.0, # Performance 'gross_profit': 3000, 'gross_loss': 500, 'profit_factor': 6.0, 'avg_trade': 166.67, 'avg_win': 333.33, 'avg_loss': -83.33, # Riesgo 'max_drawdown': -0.15, 'max_drawdown_pct': -15.0, 'sharpe_ratio': 1.8, # Para análisis 'equity_curve': [...], 'timestamps': [...], 'trades': [Trade(...), Trade(...), ...] } ``` ## 💡 Mejores Prácticas ### 1. Periodo de Backtest - **Mínimo**: 1 año de datos - **Recomendado**: 3-5 años - **Ideal**: Múltiples ciclos de mercado ### 2. Comisiones y Slippage - Siempre incluir comisiones realistas - Incluir slippage (0.05% - 0.1%) - No optimizar en exceso (overfitting) ### 3. Position Sizing - No usar 100% del capital por trade - Recomendado: 50-95% del capital disponible - Considerar gestión de riesgo ### 4. Validación - **In-sample**: Periodo de entrenamiento/optimización - **Out-of-sample**: Periodo de validación (datos no vistos) - **Walk-forward**: Validación continua ### 5. Métricas Importantes - No solo mirar retorno total - Sharpe Ratio > 1.0 es bueno, > 2.0 es excelente - Max Drawdown < 20% es aceptable - Win Rate: >50% es bueno, pero no es lo único importante - Profit Factor > 1.5 es bueno, > 2.0 es excelente ## ⚠️ Advertencias ### Limitaciones del Backtesting 1. **Look-ahead bias**: No usar información futura 2. **Survivorship bias**: Incluir activos que ya no existen 3. **Overfitting**: Optimizar demasiado para datos históricos 4. **Market conditions**: Pasado no garantiza futuro 5. **Ejecución perfecta**: Backtesting asume ejecución instantánea ### Realismo El backtest asume: - ✅ Comisiones y slippage incluidos - ✅ No hay look-ahead bias - ❌ Liquidez infinita (órdenes siempre se ejecutan) - ❌ No considera impacto de mercado - ❌ No simula rechazo de órdenes ## 📊 Ejemplos de Resultados ### Estrategia Exitosa ``` Retorno Total: 45.2% Sharpe Ratio: 2.1 Max Drawdown: -12.3% Win Rate: 58% Profit Factor: 2.4 ``` ### Estrategia Problemática ``` Retorno Total: 15.2% Sharpe Ratio: 0.4 Max Drawdown: -35.8% Win Rate: 45% Profit Factor: 1.1 ``` ## 🔁 Walk-Forward Validation (Out-of-Sample) ### 📌 ¿Qué es Walk-Forward Validation? El *walk-forward validation* es una técnica avanzada de validación que simula cómo se comportaría una estrategia en condiciones reales: - Los parámetros se **optimizan solo en datos pasados (TRAIN)** - La estrategia se **ejecuta en datos futuros no vistos (TEST)** - El proceso se repite de forma deslizante a lo largo del tiempo Esto evita: - Look-ahead bias - Overfitting clásico - Optimismo artificial en backtests Es el estándar en *quant research* profesional. --- ### 🧠 Metodología aplicada en este proyecto Para cada ventana temporal: 1. **TRAIN** - Periodo fijo de entrenamiento - Optimización por grid search - Selección de parámetros según métrica objetivo (Sharpe Ratio) 2. **TEST (Out-of-Sample)** - Backtest con los mejores parámetros del TRAIN - Sin reoptimización - Métricas registradas de forma independiente 3. **Desplazamiento** - La ventana avanza en el tiempo - Se repite el proceso hasta agotar los datos --- ### ⏱️ Configuración utilizada - **Activo:** BTC/USDT - **Timeframe:** 1h - **Ventana TRAIN:** 365 días - **Ventana TEST:** 90 días - **Step:** 90 días - **Capital inicial:** $10,000 - **Comisión:** 0.1% - **Slippage:** 0.05% **Estrategia base:** - Moving Average Crossover - Filtro de tendencia con ADX --- ### 📊 Resultados por ventana (TEST – Out-of-Sample) | Window | Return % | Sharpe | Max DD % | Trades | Parámetros | |------|----------|--------|----------|--------|------------| | 1 | +38.00 | 0.75 | -11.93 | 3 | MA(15/50) + ADX 25 | | 2 | +3.62 | 0.10 | -23.67 | 2 | MA(15/50) + ADX 30 | | 3 | +8.54 | 0.22 | -10.28 | 2 | MA(15/50) + ADX 30 | | 4 | 0.00 | 0.00 | 0.00 | 0 | Sin trades | | 5 | +9.71 | 0.26 | -10.57 | 2 | MA(15/50) + ADX 30 | | 6 | 0.00 | 0.00 | 0.00 | 0 | Sin trades | | 7 | -2.25 | -0.06 | -12.42 | 2 | MA(15/50) + ADX 30 | | 8 | -2.27 | -0.13 | -5.46 | 2 | MA(15/30) + ADX 30 | --- ### 📈 Métricas agregadas (Out-of-Sample) - **Ventanas evaluadas:** 8 - **Retorno medio:** +6.92% - **Sharpe medio:** 0.14 - **Max Drawdown medio:** -9.29% --- ### 🧩 Interpretación de resultados - La estrategia **no es sobreoptimizada** - Existen ventanas sin operaciones → el sistema sabe **no operar** - Las pérdidas están **controladas** - No hay colapsos en mercados adversos - El rendimiento depende claramente del régimen de mercado Este comportamiento es consistente con una estrategia: - Tendencial - Conservadora - Apta para mejoras vía *position sizing* y *portfolio diversification* --- ### ✅ Decisiones tomadas tras Walk-Forward 1. **NO modificar la lógica de entrada** 2. **NO optimizar más los parámetros base** 3. Mantener el filtro ADX como componente estructural 4. Avanzar hacia mejoras de: - Position sizing - Stops dinámicos - Portfolio multi-asset El walk-forward valida que la señal base es **estable y explotable**, aunque no espectacular por sí sola. ## 🔄 Próximos Pasos Después del backtesting: 1. ✅ Si resultados son buenos → Paper trading 2. ✅ Validar en out-of-sample 3. ✅ Optimizar parámetros (con cuidado) 4. ✅ Añadir gestión de riesgo 5. ✅ Testear en diferentes condiciones de mercado ## 📝 Notas - Siempre testea en datos out-of-sample - Un buen backtest no garantiza éxito futuro - Considera paper trading antes de dinero real - Mantén expectativas realistas - El mercado puede cambiar --- **Para dudas o problemas, consulta el README principal del proyecto.**