diegobeyl/backtesting
2
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 