Files
Trading-Bot/BACKTESTING.md

402 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🧪 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.**