Bollinger bands ®
Published: 2021-09-12 18:08:03

Si lo que buscas es una explicación de la mano de un experto en la materia, te aconsejo que continues con tu búsqueda, mis conocimientos financieros se podría calificar como prácticamente nulos. No obstante, últimamaente he estado leyendo publicaciones relacionada con el mundo financiero y éste, me ha parecido un concepto interesante.

Si estás leyendo esto, imagino que ya sabes en que consisten, por lo que no te voy a aburrir con los detalles (de no ser así encontrarás infinidad de entradas si haces una búsqueda del término). Pero creo que si que te puede resultar de insterés el código de una función que construya una representación gráfica de las mismas para un valor determinado.

Para ello, vamos a utilizar el API de **Yahoo finance**, para recuperar la información de una acción determinada, **python** como lenguaje de programación, **pandas** para realizar los cálculos necesarios y **matplotlib** para crear el gráfico deseado y que tendrá el siguiente aspecto.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4kx6tykak1fwh5sny7c2.png)

Bueno, ha llegado la hora de poner manos a la obra, así que vamos a crear un entorno virtual e instalar las librerías necesarias.

```bash
mkdir bollinger_bands
cd bollinger_bands
python3 -m venv venv
source venv/bin/activate
pip3 install yfinance pandas matplotlib
```

Ahora, abrimos nuetro editor favorito y tecleamos el siguiente código:

```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
from datetime import datetime, timedelta

def bollinger_band(stock_name, desde=datetime.today() - timedelta(days=365) , window=20):
    # La función espera recibir los siguientes parámetros:
    #   stock_name: ID que identifica a la acción p.ej "GOOGL" en el caso de Google
    #   desde: Fecha desde la cual se desea iniciar la representación. Si no se especifica
    #          nada, por defecto, se tomará un periodo de 1 año contando a partir de hoy
    #   windows: Número de días a considerar para los cálculos de la media móvil simple y
    #            de las desviaciones standar. Si no se especifica, se tomarán 20 días.
    #
    # Documentación Yahoo finance en https://pypi.org/project/yfinance/ 
    
    # Utilizamos la API de Yahoo finance para recuperar la 
    # información histórica de las cotizaciones en bolsa para
    # las acciones de la empresa seleccionada.
    stock_data = yf.Ticker(stock_name)

    # Guardamos todos los datos recuperados en un DataFrame de pandas.
    # Aunque podríamos limitar el periodo deseado en la descarga, dado que el 
    # volumen de información es reducido, descargamos toda la información disponible
    # y realizaremos el filtrado posteriormente. 
    stock_hist = stock_data.history(period="max", auto_adjust=True)

    # Añadimos la columna "mean" al DataFrame con el valor de la SMA (media móvil simple)
    # tomado en consideración la cantidad de días deseados (20 por defecto)
    stock_hist['mean'] = stock_hist["Close"].rolling(window=window).mean()

    # Guardamos desviación standar para el mismo periodo considerado para la media.
    stock_hist['std'] = stock_hist["Close"].rolling(window=window).std()

    # Creamos columna con el valor de la banda superior 
    # (considerando 2 desviaciones standar)
    stock_hist['BU'] = stock_hist["mean"] + 2 * stock_hist["std"]

    # Creamos columna con el valor de la banda inferior 
    # (considerando 2 desviaciones standar)
    stock_hist['BD'] = stock_hist["mean"] - 2 * stock_hist["std"]

    # Añadimos columna que contendrá los valores que superan la banda superior.
    # Se supone que deberíamos considerar la venta de acciones por estár sobrevaloradas.
    stock_hist['BU point'] = stock_hist['Close']
    condicion = (stock_hist['BU point'] <= stock_hist['BU'])
    stock_hist.loc[condicion,'BU point'] = np.nan

    # Añadimos columna que contendrá los valores que sean menores a la banda inferior.
    # Se supone que deberíamos considerar la compra de acciones por estár infravaloradas.
    stock_hist['BD point'] = stock_hist['Close']
    condicion = (stock_hist['BD point'] >= stock_hist['BD'])
    stock_hist.loc[condicion,'BD point'] = np.nan
    
    # Creamos el lienzo para dibujar la imagen
    plt.figure(figsize=(15, 6))

    # Calculamos la fecha desde la cual queremos iniciar la representación.
    inicio = pd.to_datetime(desde)

    # Dibujoas los valores de cierre de la acción.
    stock_hist.loc[inicio:,"Close"].plot(alpha=0.5)
    
    # Para no sobrecargar el gráfico, no mostraremos las líneas que representan las bandas.
    # Pero si deseas añadirlas, descomenta las líneas siguientes.
    # stock_hist.loc[inicio:,"BU"].plot()
    # stock_hist.loc[inicio:,"BD"].plot()

    # Mostramos en rojo las supuestas oportunidades de venta. Donde el valor de cierre
    # supera la banda superior.
    stock_hist.loc[inicio:,"BU point"].plot(lw=3, color={"BU point": "red"})

    # Mostramos en verde las supuestas oportunidades de compra. Donde el valor de cierre
    # es inferiro la banda inferior.
    stock_hist.loc[inicio:,"BD point"].plot(lw=3, color={"BD point": "green"})
    
    # Como no hemos representado las bandas, sombreamos la zona entre ambas pra que el
    # rango sea visible.
    plt.fill_between(stock_hist[inicio:].index, stock_hist.loc[inicio:,'BD'], stock_hist.loc[inicio:,'BU'], facecolor='orange', alpha=0.25)
    
    # Para que sea más fácil ver su valor, dibujamos un línea horizontal con el
    # último valor de cierre conocido para la acción deseada.
    plt.axhline(stock_hist.loc[stock_hist.index[-1], 'Close'], color='k', linestyle='--')
    
    # Colocamos título y etiquetas.
    plt.title(f"Bollinger bands® {stock_name} ventana={window}")
    plt.xlabel("Fecha")
    plt.ylabel("Precio de cierre")
    plt.ylim(0)
    plt.show()


# Seleccionamos el identificador de la empresa que nos interese y llamamos a la función
# que creará el gráfico. En este caso, he usaso el Banco Santander que muestra toda 
# la casuística.
STOCK = "SAN"
bollinger_band(STOCK)
```
Y ya tenemos lo que, al parecer, es una de las herramientas principales para el **análisis tècnico** de los mercados de valores.

He añadido comentarios a casi todas las líneas, por lo que no creo que sea necesario hacer explicaciones adicionales al còdigo.

Ya para finalizar, he de decir que, aunque el concepto me pareció interesante, por lo que he podido ver al analizar diferetnes ejemplos, no creo que su aplicación estricta sea la panacea para aumentar espectacularmente nuestros beneficios. No obstante, como comenté al principio, no soy ningún especialista en la materia, por lo que si tiene tanta popularidad, digo yo que **por algo será...**