Team Ai
Apppublic

diegobeyl/backtesting

sourceHugging Faceupdated 9mo agoView on Hugging Face
2likes
test_new_features.py259 linesDownload Raw Back to tests
1#!/usr/bin/env python32"""3Test script to verify:41. Direction filtering (LONG/SHORT/BOTH) in Backtester52. Configurable lookbehind in SLOW algorithm63. Integration in UI (single_asset, multi_asset)7"""8 9import sys10import os11sys.path.insert(0, '/Users/javier/Projects/backtesting_app_v2')12 13from datetime import datetime, timedelta14import pandas as pd15import numpy as np16 17# Import necessary components18from backtesting_app.core import DataLoader, Backtester19from backtesting_app.algorithms import FastAriasCampos, SlowAriasCampos20 21 22def test_direction_filtering():23    """Test trade direction filtering in Backtester"""24    print("\n" + "="*60)25    print("TEST 1: Direction Filtering in Backtester")26    print("="*60)27    28    # Load sample data29    end_date = datetime.now()30    start_date = end_date - timedelta(days=90)31    32    df = DataLoader.download(33        symbol='AAPL',34        interval='1h',35        start_date=start_date.strftime('%Y-%m-%d'),36        end_date=end_date.strftime('%Y-%m-%d'),37        source='yahoo'38    )39    40    if df is None or df.empty:41        print("❌ Could not load data")42        return False43    44    print(f"✅ Loaded {len(df)} candles")45    46    # Test FAST algorithm with different directions47    algorithm = FastAriasCampos()48    algo_params = {49        'lookbehind': 5,50        'stop_resets_support': True,51        'break_margin': 0.0,52        'timeframe': '1h'53    }54    55    results_both = []56    results_long = []57    results_short = []58    59    try:60        # Test with BOTH directions (None)61        backtester_both = Backtester(62            algorithm=algorithm,63            initial_capital=10000,64            risk_percent=1.0,65            trade_direction=None66        )67        result_both = backtester_both.run(df, algo_params, 'AAPL', '1h')68        results_both = result_both.trades if hasattr(result_both, 'trades') else []69        70        # Test with LONG only71        backtester_long = Backtester(72            algorithm=FastAriasCampos(),73            initial_capital=10000,74            risk_percent=1.0,75            trade_direction='LONG'76        )77        result_long = backtester_long.run(df, algo_params, 'AAPL', '1h')78        results_long = result_long.trades if hasattr(result_long, 'trades') else []79        80        # Test with SHORT only81        backtester_short = Backtester(82            algorithm=FastAriasCampos(),83            initial_capital=10000,84            risk_percent=1.0,85            trade_direction='SHORT'86        )87        result_short = backtester_short.run(df, algo_params, 'AAPL', '1h')88        results_short = result_short.trades if hasattr(result_short, 'trades') else []89        90        print(f"✅ BOTH directions: {len(results_both)} trades")91        print(f"✅ LONG only: {len(results_long)} trades")92        print(f"✅ SHORT only: {len(results_short)} trades")93        94        # Verify filtering is working95        if hasattr(results_long[0], 'trade_type') if results_long else False:96            long_types = set(t.trade_type for t in results_long)97            print(f"   Trade types in LONG filter: {long_types}")98            assert long_types == {'LONG'}, "LONG filter not working"99        100        if hasattr(results_short[0], 'trade_type') if results_short else False:101            short_types = set(t.trade_type for t in results_short)102            print(f"   Trade types in SHORT filter: {short_types}")103            assert short_types == {'SHORT'}, "SHORT filter not working"104        105        print("✅ Direction filtering works correctly")106        return True107        108    except Exception as e:109        print(f"❌ Error: {str(e)}")110        import traceback111        traceback.print_exc()112        return False113 114 115def test_slow_lookbehind():116    """Test configurable lookbehind in SLOW algorithm"""117    print("\n" + "="*60)118    print("TEST 2: Configurable Lookbehind in SLOW Algorithm")119    print("="*60)120    121    # Load sample data122    end_date = datetime.now()123    start_date = end_date - timedelta(days=90)124    125    df = DataLoader.download(126        symbol='BTC/USDT',127        interval='4h',128        start_date=start_date.strftime('%Y-%m-%d'),129        end_date=end_date.strftime('%Y-%m-%d'),130        source='binance'131    )132    133    if df is None or df.empty:134        print("⚠️  Could not load BTC/USDT from Binance, trying Yahoo")135        df = DataLoader.download(136            symbol='BTC-USD',137            interval='4h',138            start_date=start_date.strftime('%Y-%m-%d'),139            end_date=end_date.strftime('%Y-%m-%d'),140            source='yahoo'141        )142    143    if df is None or df.empty:144        print("❌ Could not load data")145        return False146    147    print(f"✅ Loaded {len(df)} candles")148    149    algorithm = SlowAriasCampos()150    151    # Test with different lookbehind values152    lookbehind_values = [0, 5, 10]153    results = {}154    155    try:156        for lookbehind in lookbehind_values:157            algo_params = {158                'lookbehind': lookbehind,159                'sensibilidad': 2,160                'offset': 1,161                'timeframe': '4h'162            }163            164            backtester = Backtester(165                algorithm=SlowAriasCampos(),166                initial_capital=10000,167                risk_percent=1.0168            )169            170            result = backtester.run(df, algo_params, 'BTC/USDT', '4h')171            num_trades = len(result.trades) if hasattr(result, 'trades') else 0172            results[lookbehind] = num_trades173            174            print(f"✅ Lookbehind={lookbehind}: {num_trades} trades, PnL=${result.total_return:.2f}")175        176        print("✅ Lookbehind parameter works correctly")177        return True178        179    except Exception as e:180        print(f"❌ Error: {str(e)}")181        import traceback182        traceback.print_exc()183        return False184 185 186def test_ui_parameters():187    """Test that UI parameters are properly passed"""188    print("\n" + "="*60)189    print("TEST 3: UI Parameters Integration")190    print("="*60)191    192    try:193        # Import UI components194        from backtesting_app.ui.components import convert_direction_filter195        196        # Test direction filter conversion197        test_cases = [198            ('LONG y SHORT', None),199            ('Solo LONG', 'LONG'),200            ('Solo SHORT', 'SHORT'),201        ]202        203        for input_val, expected in test_cases:204            result = convert_direction_filter(input_val)205            assert result == expected, f"Expected {expected}, got {result}"206            print(f"✅ {input_val} -> {result}")207        208        print("✅ Direction filter conversion works correctly")209        210        return True211        212    except Exception as e:213        print(f"❌ Error: {str(e)}")214        import traceback215        traceback.print_exc()216        return False217 218 219def main():220    """Run all tests"""221    print("\n" + "="*60)222    print("TESTING NEW FEATURES")223    print("Trade Direction Filtering + Configurable Lookbehind")224    print("="*60)225    226    results = []227    228    # Test 1: Direction filtering229    results.append(('Direction Filtering', test_direction_filtering()))230    231    # Test 2: Lookbehind in SLOW232    results.append(('Lookbehind in SLOW', test_slow_lookbehind()))233    234    # Test 3: UI parameters235    results.append(('UI Parameters', test_ui_parameters()))236    237    # Print summary238    print("\n" + "="*60)239    print("SUMMARY")240    print("="*60)241    242    for name, passed in results:243        status = "✅ PASSED" if passed else "❌ FAILED"244        print(f"{name}: {status}")245    246    all_passed = all(result[1] for result in results)247    print("\n" + ("="*60))248    if all_passed:249        print("✅ ALL TESTS PASSED")250    else:251        print("❌ SOME TESTS FAILED")252    print("="*60 + "\n")253    254    return 0 if all_passed else 1255 256 257if __name__ == '__main__':258    exit(main())259