Acceder

DETECTAR PULLBACKS (actuales) con python. - Algorithmic Trading

1 respuesta
DETECTAR PULLBACKS (actuales) con python. - Algorithmic Trading
DETECTAR PULLBACKS (actuales) con python. - Algorithmic Trading

CÓDIGO AMIGO

Gestión inteligente del capital con Trade Republic: IBAN español y 2% de remuneración sin límite de saldo

#1

DETECTAR PULLBACKS (actuales) con python. - Algorithmic Trading

Buenas tardes!!!

He conocido el mundo de la programación hace poco y me fascina, tengo gente que sabe sobre programación y junto a la ia han sido mis apoyos constantes en este ambito de la informatica.
Mi idea es mezclar la informatica con la inversion o trading y con mi persona guiando el proceso.

Tengo un codigo que busca detectar pullbacks, estoy creando una aplicacion capaz de localizar los pullbacks reales del mercado en base a patrones historicos y un sistema de puntuacion sobre la accion en particular en base a una serie de caracteristicas de los patrones localizados y de los sectores de las acciones potenciales. Tengo creado todo el proceso de localizacion de esos patrones en base a unos datos especificos sobre la evolucion del volumen actual y desde el inicio del pullback, RSI durante el proceso por igual, estado del MACD y la EMA de diferentes niveles y poco más.
El proceso es analisis del mercado de acciones europeas y americanas, deteccion de pullbacks (caidas por ventanas temporales que ganan peso durante la evolucion del patron de caida --> Pullback hasta llegar a un minimo que puede ser rebotado o seguir en caida aún).
La idea es activar el detector de pullbacks para extraer los datos de esa accion en especifico y posteriormente en otro script analizarlo y fundir los patrones con los pullbacks a ver que sale. He conseguido ver el mercado con sus pullbacks en dos ocasiones, es decir he mirado a traves de la ventana dos veces y me ha detectado buenas señales sin embargo no es estable el codigo en el tiempo.
Me gustaria saber que tengo que hacer (que lineas de codigo python utf-8 tengo que describir en el conjunto del codigo, mando la mas avanzada y paralela a los scripts que funcionaron en el siguiente mensaje:
═══════════════════════════════════════════════════════════════════════════════
# DETECTOR PULLBACK (LÓGICA COMPROBADA DEL CONSTRUCTOR HISTÓRICO)
# ═══════════════════════════════════════════════════════════════════════════════

def detectar_pullbacks_ventana_sliding(data, ticker):
    """
    Detecta pullbacks usando LÓGICA COMPROBADA del constructor_historico_yf_sp500.py
    
    Algoritmo:
    1. Iterar cada vela desde día 120 en adelante
    2. Para cada vela: buscar máximo en últimos 120 días
    3. Si precio actual está 5%+ por debajo del máximo = PULLBACK
    4. Buscar mínimo más bajo en últimos 20 días (confirmación)
    5. Retornar: fecha, máx, mín, caída%, recuperación
    """
    
    pullbacks = []
    
    if data is None or len(data) < MIN_DATA_POINTS:
        return pullbacks
    
    try:
        # Reset índice para trabajar con arrays
        df = data.reset_index()
        
        if 'Date' not in df.columns and len(df.index) > 0:
            df['Date'] = data.index
        
        close_prices = df['Close'].values if 'Close' in df.columns else df['close'].values
        high_prices = df['High'].values if 'High' in df.columns else close_prices
        low_prices = df['Low'].values if 'Low' in df.columns else close_prices
        dates = df['Date'].values if 'Date' in df.columns else list(range(len(close_prices)))
        
        # Iterar por cada punto desde día 120 en adelante
        for i in range(LOOKBACK_DAYS, len(close_prices) - 20):
            try:
                # 1. Buscar máximo en últimos 120 días (ventana histórica)
                ventana_historica = high_prices[i-LOOKBACK_DAYS:i]
                max_historico = ventana_historica.max()
                idx_max = (i - LOOKBACK_DAYS) + ventana_historica.argmax()
                
                # 2. Precio actual
                precio_actual = close_prices[i]
                
                # 3. Calcular caída %
                caida_pct = (max_historico - precio_actual) / max_historico * 100
                
                # 4. ¿Es pullback válido? (mínimo 5% de caída)
                if caida_pct < MIN_PULLBACK_PCT:
                    continue
                
                # 5. Confirmación: buscar mínimo más bajo en últimos 20 días
                ventana_pullback = low_prices[i-20:i+1]
                min_pullback = ventana_pullback.min()
                idx_min = i - 20 + ventana_pullback.argmin()
                
                # 6. Magnitud REAL del pullback (máx a mín)
                magnitud_pullback = (max_historico - min_pullback) / max_historico * 100
                
                # Solo registrar si es significativo (>5%)
                if magnitud_pullback < MIN_PULLBACK_PCT:
                    continue
                
                # 7. Recuperación post-pullback (desde mín a hoy)
                recuperacion_pct = ((precio_actual - min_pullback) / min_pullback) * 100
                
                # 8. Días desde fondo
                dias_desde_fondo = i - idx_min
                
                # 9. Formato de fechas
                try:
                    fecha_max = pd.Timestamp(dates[idx_max]).strftime('%Y-%m-%d')
                    fecha_min = pd.Timestamp(dates[idx_min]).strftime('%Y-%m-%d')
                    fecha_hoy = pd.Timestamp(dates[i]).strftime('%Y-%m-%d')
                except:
                    fecha_max = f"D{idx_max}"
                    fecha_min = f"D{idx_min}"
                    fecha_hoy = f"D{i}"
                
                # Registrar pullback
                pullbacks.append({
                    'ticker': ticker,
                    'max_precio': float(max_historico),
                    'min_precio': float(min_pullback),
                    'precio_hoy': float(precio_actual),
                    'pullback_pct': float(caida_pct),
                    'magnitud_pullback_pct': float(magnitud_pullback),  # REAL (máx a mín)
                    'recuperacion_pct': float(recuperacion_pct),
                    'dias_desde_fondo': int(dias_desde_fondo),
                    'fecha_max': fecha_max,
                    'fecha_min': fecha_min,
                    'fecha_hoy': fecha_hoy
                })
                
            except Exception as e:
                continue
        
        return pullbacks
    
    except Exception as e:
        logger.error(f"Error detectando pullbacks para {ticker}: {e}")
        logger.exception("Stack trace:")
        return []

Por favor al que le interese comparto con privado con el los resultados y lo mantengo al tanto del uso gratuito del programa que sea capaz de crear tranquilamente de por vida. No tendria problema en regalarlo, de momento antes de regalarlo o armarme con esto me gustaría encontrar ayuda.
Un saludo.
#2

Re: DETECTAR PULLBACKS (actuales) con python. - Algorithmic Trading


🔒 CONCLUSIÓN


El problema:
No era la lógica del detector de pullbacks, sino cómo accedemos a los datos de yfinance.

La solución: Manejo explícito del MultiIndex DataFrame usando data[('columna', ticker)].

El impacto: De 0 pullbacks detectados a detección correcta en todos los mercados.

Tiempo a solución: 4+ horas de debugging metodológico llevó a 15 minutos de fix.

Lección clave: Cuando el código "funciona" pero no produce resultados, revisa los tipos de datos y estructuras internas antes de cambiar la lógica.



Documento generado:
2026-01-23 00:50 CET
Scanner estable: scanner_pullback_v4.py
Estado: ✅ PRODUCCIÓN LISTA