Bandas de Bollinger con Python aplicadas al S&P500

Utilizando las Bandas de Bollinger, podemos crear una estrategia de trading para comprar y vender acciones en función de la volatilidad móvil del mercado.

Utilizando las Bandas de Bollinger, podemos crear una estrategia de trading para comprar y vender acciones en función de la volatilidad móvil del mercado.

Estrategia de trading utilizando Bandas de Bollinger con señales de compra y venta destacadas
F1. Trading con Bandas de Bollinger aplicada al S&P500

Te explicamos el proceso mientras aplicamos la estrategia a los datos del S&P500.

Data

El S&P500 es un índice que representa el rendimiento de las 500 empresas más grandes de Estados Unidos.

Para simplificar la comprensión, seleccionamos un año de datos.

import yfinance as yf
df = yf.download('SPY', start='2023-01-01', end='2024-01-01')
Gráfico de líneas mostrando un año de datos del S&P500
F2. Datos bursátiles del S&P500 durante 2023

Questions

Preguntas

  1. ¿Qué son las Bandas de Bollinger y cómo se calculan?
  2. ¿Cómo determinar las señales de compra y venta con las Bandas de Bollinger?
  3. ¿Cómo evitar señales de compra o venta consecutivas en la estrategia de trading?
  4. ¿Cómo calcular el resultado de la estrategia?

Metodología

Medias y desviaciones móviles

Las Bandas de Bollinger se calculan a partir de la media \(\) y desviación estándar \(\) móviles en base a un periodo \(r\).

\(\) bands = _r k _r \(\)

En nuestro caso, utilizaremos un periodo de 30 días.

df['Adj Close'].rolling(30).agg(['mean', 'std'])

Calcular bandas

Además de elegir el periodo, debemos seleccionar la amplitud de las bandas con el parámetro \(k\), que multiplicará la desviación estándar.

(df
 .assign(
     b_lower = lambda x: x['mean'] - 2 * x['std'],
     b_upper = lambda x: x['mean'] + 2 * x['std']
 )
)
Cálculo de Bandas de Bollinger para el S&P500, mostrando bandas superior e inferior
F3. Bandas de Bollinger calculadas

Señales de compra y venta

Ahora viene la parte más jugosa (y complicada): calcular los puntos de compra y venta.

Si el precio (de cierre) cruza la banda inferior, significa que el activo está subvaluado (vale más de lo que cuesta) y es probable que suba. Por tanto, es una señal de compra.

Para vender, utilizaremos el cruce de la banda superior.

¿Conoces a alguien que podría interesarle este artículo? Compártelo con ellos.

mask_sell = df.close > df.b_upper
mask_buy = df.close < df.b_lower

df.loc[mask_buy, 'signal'] = 1
df.loc[mask_sell, 'signal'] = -1

He aquí los días en los que deberíamos comprar y vender.

Detalle de señales de compra y venta en el tiempo, indicadas sobre el precio de cierre del S&P500
F4. Señales de compra y venta sin restricciones

Peeeeero, si invertimos todo el capital en cada operación, no podremos comprar si ya estamos comprados, ni vender si ya estamos vendidos.

Es decir, no debería haber dos señales de compra (1) o venta (-1) seguidas.

Control de señales

Para evitar el problema anterior, tendremos en cuenta el estado actual de las operaciones con una flag. Por defecto, estará en False porque no tenemos ninguna operación abierta (no hemos comprado).

flag_buy = False

Iteramos sobre cada día para calcular las señales según las condiciones anteriores.

l = []

for idx, day in df.iterrows():
    if (day.signal == 1) & (flag_buy == False):
        signal = 1
        flag_buy = True
    elif (day.signal == -1) & (flag_buy == True):
        signal = -1
        flag_buy = False
    else:
        signal = 0
        
    l.append(signal)
    
df['signal'] = l

Y obtenemos las señales corregidas, con una sola señal de compra o venta seguida.

Estrategia de trading utilizando Bandas de Bollinger con señales de compra y venta destacadas
F1. Trading con Bandas de Bollinger aplicada al S&P500

Resultado de la estrategia

Finalmente, calculamos el resultado de la estrategia.

Si compramos siempre con la misma cantidad, el resultado será la suma de las diferencias entre los momentos de compra y venta.

(df.close * df.signal).mul(-1).sum()

Por tanto, si hubiésemos comprado una acción completa en cada señal, habríamos obtenido un beneficio total de $38.46 al final del periodo.

¿Preguntas? Hablamos abajo en comentarios.

Conclusions

  1. Bandas de Bollinger: rolling(n).agg(['mean', 'std']) calcula la media y desviación estándar móviles, base para las Bandas de Bollinger, una medida de volatilidad.
  2. Señales de compra/venta: Utilizando la condición df.close < df.b_lower para compra y df.close > df.b_upper para venta, se identifican los momentos óptimos basados en las Bandas de Bollinger.
  3. Control de señales: Mediante la implementación de una flag y un bucle, se evitan señales consecutivas del mismo tipo.
  4. Resultado de la estrategia: (df.close * df.signal).mul(-1).sum() para sumar las diferencias entre los puntos de compra y venta.

Si pudieras programar lo que quisieras, ¿qué sería? Podría crear un tutorial sobre ello ;)

Hablamos abajo en los comentarios.

Great! You’ve successfully signed up.

Welcome back! You've successfully signed in.

You've successfully subscribed to datons.

Success! Check your email for magic link to sign-in.

Success! Your billing info has been updated.

Your billing was not updated.