#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.
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.