Files
Trading-Bot/BACKTESTING.md
DaM 9b34de3127 feat: Backtesting engine completo + documentación (Semanas 3-4)
 Motor de backtesting:
- BacktestEngine con simulación de trades
- Sistema de Trade y Position
- Gestión de capital y comisiones
- Slippage simulado

 Estrategias implementadas:
- MovingAverageCrossover (SMA/EMA configurable)
- RSIStrategy (umbrales personalizables)
- BuyAndHold (baseline)

 Métricas de performance:
- Sharpe Ratio, Sortino Ratio, Calmar Ratio
- Max Drawdown, Win Rate, Profit Factor
- Expectancy, Risk/Reward Ratio

 Scripts:
- backtest.py: Ejecutar backtests individuales
- backtest.py compare: Comparar múltiples estrategias

 Documentación:
- README actualizado con sección de backtesting
- Ejemplos de uso programático
- Estructura de proyecto actualizada
2026-01-27 21:37:39 +01:00

7.0 KiB

🧪 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

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

python backtest.py compare

Compara 4 estrategias diferentes sobre los mismos datos.

📊 Estrategias Disponibles

1. Moving Average Crossover

Cruces de medias móviles:

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:

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:

from src.strategies import BuyAndHold

strategy = BuyAndHold()

Compra al inicio y mantiene hasta el final.

🛠️ Uso Programático

Backtest Básico

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

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

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

🔄 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.