Team Ai
Apppublic

diegobeyl/backtesting

sourceHugging Faceupdated 9mo agoView on Hugging Face
2likes
test_slow_support.py199 linesDownload Raw Back to tests
1#!/usr/bin/env python32"""3Test del algoritmo SLOW AriasCampos - Verificar cálculo correcto de soportes4Valida que:51. Las resistencias se calculen correctamente62. Cuando se rompe una resistencia en tendencia alcista, el soporte = mínimo absoluto 7   desde la creación de la resistencia hasta la vela que la rompe8"""9 10import sys11from pathlib import Path12sys.path.insert(0, str(Path(__file__).parent))13 14import pandas as pd15import numpy as np16from datetime import datetime, timedelta17from backtesting_app.algorithms.slow_ariascampos import SlowAriasCampos18 19 20def create_test_dataframe():21    """22    Crea un DataFrame de prueba que simula:23    1. Tendencia alcista inicial con soporte24    2. Se forma una resistencia cuando el precio cae25    3. Se rompe la resistencia hacia arriba26    4. El nuevo soporte debe ser el mínimo desde que se creó la resistencia27    """28    dates = pd.date_range('2024-01-01', periods=30, freq='D')29    30    # Crear datos con patrón específico para probar la lógica31    data = {32        'open':  [100, 101, 102, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103],33        'high':  [101, 102, 103, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104],34        'low':   [99, 100, 101, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102],35        'close': [100, 101, 102, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103],36        'volume': [1000] * 3037    }38    39    df = pd.DataFrame(data, index=dates)40    return df41 42 43def test_support_calculation():44    """Test que verifica el cálculo correcto de soportes"""45    print("\n" + "="*60)46    print("TEST: Cálculo de Soporte al Romper Resistencia")47    print("="*60)48    49    algo = SlowAriasCampos()50    df = create_test_dataframe()51    52    params = algo.get_default_params()53    params['sensibilidad'] = 1  # Sin sensibilidad para prueba54    params['offset'] = 0.0  # Sin offset para números limpios55    params['support_margin_long'] = 0  # Sin margen56    params['resistance_margin_short'] = 0  # Sin margen57    58    result = algo.run(df, params)59    60    print("\nResultados por barra:")61    print(f"{'Bar':>3} {'Date':<12} {'High':>6} {'Low':>6} {'Trend':>7} {'Soporte':>8} {'Resistencia':>12}")62    print("-" * 70)63    64    for i, state in enumerate(result.states):65        trend_str = "ALCISTA" if state.trend.value == 1 else "BAJISTA" if state.trend.value == 0 else "NEUTRAL"66        support_str = f"{state.support:.2f}" if state.support else "None"67        resistance_str = f"{state.resistance:.2f}" if state.resistance else "None"68        69        high = df.iloc[i]['high']70        low = df.iloc[i]['low']71        72        print(f"{i:3d} {state.timestamp.strftime('%Y-%m-%d')} {high:6.1f} {low:6.1f} {trend_str:>7} {support_str:>8} {resistance_str:>12}")73    74    print("\n" + "="*60)75    print("Señales Generadas:")76    print("="*60)77    for signal in result.signals:78        print(f"{signal.timestamp}: {signal.signal_type} @ {signal.price:.2f} - {signal.reason}")79    80    # Validación81    print("\n" + "="*60)82    print("VALIDACIONES:")83    print("="*60)84    85    # Buscar cambios de tendencia86    changes = []87    for i in range(1, len(result.trend_history)):88        if result.trend_history[i] != result.trend_history[i-1]:89            changes.append((i, result.trend_history[i-1], result.trend_history[i]))90    91    print(f"✓ Cambios de tendencia detectados: {len(changes)}")92    for bar, from_trend, to_trend in changes:93        from_str = "ALCISTA" if from_trend.value == 1 else "BAJISTA"94        to_str = "ALCISTA" if to_trend.value == 1 else "BAJISTA"95        print(f"  Barra {bar}: {from_str} → {to_str}")96    97    return result98 99 100def test_specific_scenario():101    """102    Test específico del scenario reportado:103    - Tendencia alcista con soporte104    - Se forma resistencia cuando precio cae105    - Se rompe resistencia hacia arriba106    - El nuevo soporte debe ser el mínimo desde la creación de la resistencia107    """108    print("\n" + "="*60)109    print("TEST ESPECÍFICO: Soporte en Ruptura de Resistencia")110    print("="*60)111    112    # Datos controlados para prueba específica113    dates = pd.date_range('2024-01-01', periods=20, freq='D')114    115    data = {116        'open':  [100, 101, 102, 103, 104, 103, 102, 101, 100, 99, 98, 97, 96, 97, 98, 99, 100, 101, 102, 103],117        'high':  [101, 102, 103, 104, 105, 104, 103, 102, 101, 100, 99, 98, 97, 98, 99, 100, 101, 102, 103, 104],118        'low':   [99, 100, 101, 102, 103, 102, 101, 100, 99, 98, 97, 96, 95, 96, 97, 98, 99, 100, 101, 102],119        'close': [100, 101, 102, 103, 104, 103, 102, 101, 100, 99, 98, 97, 96, 97, 98, 99, 100, 101, 102, 103],120        'volume': [1000] * 20121    }122    123    df = pd.DataFrame(data, index=dates)124    125    algo = SlowAriasCampos()126    params = algo.get_default_params()127    params['sensibilidad'] = 1128    params['offset'] = 0.0129    params['support_margin_long'] = 0130    params['resistance_margin_short'] = 0131    132    result = algo.run(df, params)133    134    print("\nSecuencia de eventos:")135    print(f"{'Bar':>3} {'Fecha':<12} {'H':>5} {'L':>5} {'Tendencia':>8} {'Soporte':>8} {'Resistencia':>12} {'Evento':<30}")136    print("-" * 90)137    138    for i, state in enumerate(result.states):139        trend_str = "ALCISTA" if state.trend.value == 1 else "BAJISTA" if state.trend.value == 0 else "NEUTRAL"140        support_str = f"{state.support:.1f}" if state.support else "----"141        resistance_str = f"{state.resistance:.1f}" if state.resistance else "----"142        143        high = df.iloc[i]['high']144        low = df.iloc[i]['low']145        146        evento = ""147        if state.signal:148            evento = f"→ {state.signal.signal_type}"149        150        print(f"{i:3d} {state.timestamp.strftime('%Y-%m-%d')} {high:5.0f} {low:5.0f} {trend_str:>8} {support_str:>8} {resistance_str:>12} {evento:<30}")151    152    # Análisis153    print("\n" + "="*60)154    print("ANÁLISIS DEL COMPORTAMIENTO:")155    print("="*60)156    157    # Encontrar cuándo se forma la resistencia158    resistance_bar = None159    for i, val in enumerate(result.resistance_history):160        if val is not None and (resistance_bar is None or result.resistance_history[resistance_bar] is None):161            resistance_bar = i162            print(f"✓ Resistencia formada en barra {i} (valor: {val:.2f})")163    164    # Encontrar cuándo se rompe165    breakout_bar = None166    if resistance_bar is not None:167        for i in range(resistance_bar + 1, len(result.resistance_history)):168            if result.resistance_history[i] is None and result.trend_history[i].value == 1:169                breakout_bar = i170                print(f"✓ Resistencia rota en barra {i}")171                break172    173    # Verificar soporte calculado174    if breakout_bar is not None and breakout_bar + 1 < len(result.support_history):175        new_support = result.support_history[breakout_bar + 1]176        print(f"✓ Nuevo soporte establecido: {new_support:.2f}")177        178        # Calcular el mínimo esperado usando iloc en lugar de loc179        min_expected = df.iloc[resistance_bar:breakout_bar+1]['low'].min()180        print(f"✓ Mínimo en el rango [{resistance_bar}, {breakout_bar}]: {min_expected:.2f}")181        182        if abs(new_support - min_expected) < 0.1:183            print("✓✓✓ CORRECTO: El soporte coincide con el mínimo esperado")184        else:185            print(f"✗✗✗ ERROR: El soporte ({new_support:.2f}) no coincide con el mínimo ({min_expected:.2f})")186 187 188if __name__ == "__main__":189    print("\n" + "="*60)190    print("TESTS DEL ALGORITMO SLOW - ARIASCAMPOS")191    print("="*60)192    193    test_support_calculation()194    test_specific_scenario()195    196    print("\n" + "="*60)197    print("TESTS COMPLETADOS")198    print("="*60 + "\n")199