Creación de un indicador compuesto para el trading algorítmico en Python
Supongamos que tenemos una estrategia de trading manual o algorítmica que queremos mejorar. Para esto, vamos a desarrollar un indicador técnico compuesto que combine 2 de los osciladores más populares, el RSI (Relative Strenght Index) y el ATR (Average True Range). El objetivo de este indicador es lograr un resultado más matizado para la estrategia actual; intentar captar los puntos más altos y bajos extremos del mercado.
Los indicadores RSI y ATR
Por otro lado, el ATR es un indicador de volatilidad que mide la volatilidad del mercado descomponiendo todo el rango de un activo para ese período. No indica la dirección del precio, pero da una idea del grado de variación del rango de precios.
La idea detrás de combinar RSI y ATR
Al combinar RSI y ATR, este indicador compuesto debería tener en cuenta el impulso (RSI) pero también incorporar la volatilidad del mercado (ATR). La idea es que un indicador compuesto podría ofrecer una visión más completa del mercado, ayudando en la toma de decisiones al resaltar posibles señales de compra o venta que consideren tanto el momentum de los precios como la volatilidad.
¿Cómo funciona el indicador compuesto entre el RSI y ATR?
El indicador compuesto RSI-ATR debería funcionar superponiendo las señales de volatilidad del ATR con el análisis de momentum proporcionado por el RSI. La combinación ofrece una perspectiva diferente: podría señalar una posible señal de compra no solo cuando el activo esté técnicamente ‘sobrevendido’ (según lo indicado por el RSI) sino también considerando si la volatilidad del mercado respalda este movimiento. Para mercados volátiles como el de criptomonedas, en donde usualmente se usan algoritmos de trading, esto podría resultar en mejores entradas y menos falsos positivos.
Implementación del indicador compuesto en un algoritmo de trading mediante Python
Crear e integrar el indicador compuesto RSI-ATR en un algoritmo de trading implica calcular tanto los valores del RSI como del ATR y luego combinar estos dos para generar señales de trading. A continuación, describimos un enfoque simple para integrar este indicador compuesto en una estrategia de trading algorítmico. Este ejemplo está basado en cómo programo mi estrategia y señales, pero puedes utilizar el cálculo para implementarlo en tu propio código.
import pandas as pd import yfinance as yf import matplotlib.pyplot as plt def calculate_rsi(data, window=14): delta = data['Close'].diff(1) gain = delta.where(delta > 0, 0) loss = -delta.where(delta < 0, 0) avg_gain = gain.rolling(window=window, min_periods=1).mean() avg_loss = loss.rolling(window=window, min_periods=1).mean() rs = avg_gain / avg_loss rsi = 100 - (100 / (1 + rs)) return rsi def calculate_atr(data, window=14): high_low = data['High'] - data['Low'] high_close = (data['High'] - data['Close'].shift()).abs() low_close = (data['Low'] - data['Close'].shift()).abs() ranges = pd.concat([high_low, high_close, low_close], axis=1) true_range = ranges.max(axis=1) atr = true_range.rolling(window=window, min_periods=1).mean() return atr def normalize_atr(data): min_atr = data['ATR'].min() max_atr = data['ATR'].max() data['Normalized_ATR'] = (data['ATR'] - min_atr) / (max_atr - min_atr) return data def adjust_rsi_with_normalized_atr(data): adjusted_rsi = data['RSI'] * (1 + data['Normalized_ATR']) # Limitar los valores del RSI compuesto entre 0 y 100 data['Adjusted_RSI'] = adjusted_rsi.clip(lower=0, upper=100) return data # Descargar datos históricos del precio de Tesla ticker = 'TSLA' data = yf.download(ticker, start='2023-01-01', end='2024-01-01') # Calcular el RSI data['RSI'] = calculate_rsi(data) # Calcular el ATR data['ATR'] = calculate_atr(data) # Normalizar el ATR data = normalize_atr(data) # Ajustar el RSI con el ATR normalizado data = adjust_rsi_with_normalized_atr(data) # Crear la figura y los subgráficos fig, axs = plt.subplots(3, 1, figsize=(14, 12), sharex=True, gridspec_kw={'height_ratios': [3, 1, 1]}) sobrecompra=70.0 sobreventa=30.0 # Gráfico del precio de cierre axs[0].plot(data.index, data['Close'], label='Precio de Cierre', color='black') axs[0].set_title('Precio de Cierre de Tesla') axs[0].set_ylabel('Precio de Cierre') axs[0].legend() # Gráfico del RSI estándar axs[1].plot(data.index, data['RSI'], label='RSI Estándar', color='blue') axs[1].axhline(sobrecompra, linestyle='--', alpha=0.5, color='blue') axs[1].axhline(sobreventa, linestyle='--', alpha=0.5, color='blue') axs[1].set_title('RSI Estándar') axs[1].set_ylabel('RSI') axs[1].legend() # Gráfico del RSI ajustado axs[2].plot(data.index, data['Adjusted_RSI'], label='RSI Ajustado', color='red') axs[2].axhline(sobrecompra, linestyle='--', alpha=0.5, color='red') axs[2].axhline(sobreventa, linestyle='--', alpha=0.5, color='red') axs[2].set_title('RSI Ajustado') axs[2].set_xlabel('Fecha') axs[2].set_ylabel('RSI') axs[2].legend() # Ajustar el espaciado entre subgráficos plt.tight_layout() # Mostrar el gráfico plt.show()
Abajo (debajo del precio de cierre), la línea azul representa el RSI normal, la línea de color rojo representa el RSI compuesto.
Pruebas adicionales
La efectividad y los resultados de este indicador aún deben ser probados utilizando diferentes configuraciones y marcos de tiempo. Sin embargo, esta idea proporciona un punto de vista interesante sobre cómo combinar indicadores para obtener una perspectiva más amplia y posiblemente mejorar la toma de decisiones del algoritmo de trading.