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.
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')
Questions
Preguntas
- ¿Qué son las Bandas de Bollinger y cómo se calculan?
- ¿Cómo determinar las señales de compra y venta con las Bandas de Bollinger?
- ¿Cómo evitar señales de compra o venta consecutivas en la estrategia de trading?
- ¿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']
)
)
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.
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.
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
- 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. - Señales de compra/venta: Utilizando la condición
df.close < df.b_lower
para compra ydf.close > df.b_upper
para venta, se identifican los momentos óptimos basados en las Bandas de Bollinger. - Control de señales: Mediante la implementación de
una
flag
y un bucle, se evitan señales consecutivas del mismo tipo. - 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.
Take a step forward and learn to develop algorithms and applications with our digital courses in Udemy.