Team Ai
Apppublic

diegobeyl/backtesting

sourceHugging Faceupdated 9mo agoView on Hugging Face
2likes
debug_position_size.py188 linesDownload Raw Back to debug
1"""
2Debug del cálculo de tamaño de posición
3Verifica por qué el P&L está 10x menor
4"""
5
6import sys
7import os
8import pandas as pd
9from datetime import datetime, timedelta
10
11# Agregar path correcto
12sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'backtesting_app', 'backtesting_app'))
13
14from core.data_loader import DataLoader
15from core.backtester import Backtester
16from algorithms.fast_ariascampos import FastAriasCampos
17
18
19def debug_backtest():
20    """Ejecuta backtest con debug detallado"""
21    
22    print("=" * 80)
23    print("DEBUG: ANÁLISIS DE TAMAÑO DE POSICIÓN")
24    print("=" * 80)
25    print()
26    
27    # Parámetros
28    symbol = 'AAPL'
29    timeframe = '1mo'
30    initial_capital = 10000
31    risk_percent = 1.0
32    
33    # Descargar datos
34    end_date = datetime.now()
35    start_date = end_date - timedelta(days=365*10)
36    
37    print(f"📊 Descargando datos de {symbol}...")
38    print(f"   Timeframe: {timeframe}")
39    print(f"   Período: {start_date.date()} a {end_date.date()}")
40    
41    df = DataLoader.download(
42        symbol=symbol,
43        interval=timeframe,
44        start_date=start_date.strftime('%Y-%m-%d'),
45        end_date=end_date.strftime('%Y-%m-%d'),
46        source='yfinance'
47    )
48    
49    if df is None or df.empty:
50        print("❌ Error: No se pudieron descargar datos")
51        return
52    
53    print(f"✅ {len(df)} velas descargadas\n")
54    
55    # Ejecutar backtest
56    print("=" * 80)
57    print("CONFIGURACIÓN DEL BACKTEST")
58    print("=" * 80)
59    print(f"Capital Inicial: ${initial_capital:,.2f}")
60    print(f"Riesgo por Trade: {risk_percent}%")
61    print(f"Riesgo en dólares: ${initial_capital * risk_percent / 100:,.2f}")
62    print()
63    
64    algorithm = FastAriasCampos()
65    algo_params = {
66        'lookbehind': 0,
67        'stop_resets_support': True,
68        'break_margin': 0.0,
69        'timeframe': timeframe
70    }
71    
72    backtester = Backtester(
73        algorithm=algorithm,
74        initial_capital=initial_capital,
75        risk_percent=risk_percent,
76        commission_pct=0.1
77    )
78    
79    result = backtester.run(df, algo_params, symbol, timeframe)
80    
81    # Análisis detallado de trades
82    print("=" * 80)
83    print("ANÁLISIS DETALLADO DE CADA TRADE")
84    print("=" * 80)
85    print()
86    
87    for i, trade in enumerate(result.trades[:10], 1):  # Primeros 10 trades
88        print(f"{'='*80}")
89        print(f"TRADE #{i} - {trade.direction}")
90        print(f"{'='*80}")
91        print(f"Fecha Entrada:     {trade.entry_date}")
92        print(f"Precio Entrada:    ${trade.entry_price:,.2f}")
93        print(f"Stop Loss Inicial: ${trade.initial_sl:,.2f}")
94        
95        # Cálculos
96        sl_distance = abs(trade.entry_price - trade.initial_sl)
97        sl_distance_pct = (sl_distance / trade.entry_price) * 100
98        
99        print(f"\n📏 DISTANCIA AL STOP:")
100        print(f"   Absoluta: ${sl_distance:,.2f}")
101        print(f"   Porcentual: {sl_distance_pct:.2f}%")
102        
103        # Cálculo esperado de posición
104        risk_amount = trade.capital_at_entry * (risk_percent / 100)
105        expected_position_size = risk_amount / sl_distance
106        
107        print(f"\n💰 CÁLCULO DE POSICIÓN:")
108        print(f"   Capital disponible: ${trade.capital_at_entry:,.2f}")
109        print(f"   Riesgo {risk_percent}%: ${risk_amount:,.2f}")
110        print(f"   Tamaño esperado: {expected_position_size:,.2f} acciones")
111        print(f"   Tamaño REAL: {trade.position_size:,.2f} acciones")
112        
113        # Verificar discrepancia
114        if abs(expected_position_size - trade.position_size) > 0.1:
115            print(f"   ⚠️  DISCREPANCIA: {abs(expected_position_size - trade.position_size):,.2f} acciones")
116        
117        # Valor de posición
118        position_value = trade.position_size * trade.entry_price
119        leverage = position_value / trade.capital_at_entry
120        
121        print(f"\n📊 VALOR DE POSICIÓN:")
122        print(f"   Valor total: ${position_value:,.2f}")
123        print(f"   Apalancamiento: {leverage:.2f}x")
124        print(f"   % del capital: {leverage * 100:.1f}%")
125        
126        # Resultado
127        if trade.exit_price:
128            print(f"\n💵 RESULTADO:")
129            print(f"   Precio Salida: ${trade.exit_price:,.2f}")
130            print(f"   Razón: {trade.exit_reason}")
131            
132            # Cálculo manual del P&L
133            if trade.direction == 'LONG':
134                price_diff = trade.exit_price - trade.entry_price
135            else:
136                price_diff = trade.entry_price - trade.exit_price
137            
138            expected_pnl = price_diff * trade.position_size
139            
140            print(f"\n   Diferencia de precio: ${price_diff:,.2f}")
141            print(f"   P&L esperado: ${expected_pnl:,.2f}")
142            print(f"   P&L REAL: ${trade.pnl:,.2f}")
143            
144            if abs(expected_pnl - trade.pnl) > 10:
145                print(f"   ⚠️  DISCREPANCIA EN P&L: ${abs(expected_pnl - trade.pnl):,.2f}")
146            
147            print(f"   P&L %: {trade.pnl_percent:+.2f}%")
148            print(f"   Barras mantenidas: {trade.bars_held}")
149        
150        print()
151    
152    # Resumen
153    print("=" * 80)
154    print("RESUMEN GENERAL")
155    print("=" * 80)
156    print(f"Total Trades: {result.total_trades}")
157    print(f"Capital Final: ${result.total_return:,.2f}")
158    print(f"Retorno: ${result.total_return - initial_capital:,.2f}")
159    print(f"Retorno %: {result.total_return_percent:+.2f}%")
160    print(f"Win Rate: {result.win_rate:.1f}%")
161    print()
162    
163    # Verificar problema específico
164    print("=" * 80)
165    print("🔍 DIAGNÓSTICO")
166    print("=" * 80)
167    print()
168    
169    if result.total_trades > 0:
170        avg_position_value = sum(t.position_size * t.entry_price for t in result.trades) / len(result.trades)
171        avg_leverage = avg_position_value / initial_capital
172        
173        print(f"Valor promedio de posición: ${avg_position_value:,.2f}")
174        print(f"Apalancamiento promedio: {avg_leverage:.2f}x")
175        
176        if avg_leverage < 0.1:
177            print("⚠️  PROBLEMA: Posiciones muy pequeñas (< 10% del capital)")
178            print("   Esto explicaría por qué el P&L es 10x menor")
179            print()
180            print("   POSIBLES CAUSAS:")
181            print("   1. Los stops están muy lejos del precio de entrada")
182            print("   2. El riesgo por trade es muy bajo")
183            print("   3. Hay un error en el cálculo de position_size")
184
185
186if __name__ == "__main__":
187    debug_backtest()
188