El objetivo de Quantinsti es formar a su alumnos en el trading algorítmico. Pertenece a iRageCapital Advisory, empresa conocida por sus servicios relacionados con la creación de mesas de trading algorítmico.
Predicción del Precio del Oro: Guía Paso a Paso Usando Python y Machine Learning
¿Es posible predecir hacia dónde se dirige el precio del oro?
Sí, usaremos técnicas de regresión de machine learning para predecir el precio de uno de los metales preciosos más importantes: el oro.
Crearemos un modelo de regresión lineal de machine learning que toma información de precios pasados del ETF de oro (GLD) y devuelve una predicción del precio del oro para el día siguiente.
GLD es el mayor ETF para invertir directamente en oro físico. (Fuente)
Cubriremos los siguientes temas en nuestro camino para predecir los precios del oro usando machine learning en Python:
- Importar las librerías y leer los datos del ETF de oro
- Definir las variables explicativas
- Definir la variable dependiente
- Dividir los datos en conjuntos de entrenamiento y prueba
- Crear un modelo de regresión lineal
- Predecir los precios del ETF de oro
- Graficar los rendimientos acumulados
- ¿Cómo usar este modelo para predecir los movimientos diarios?
Importar las librerías y leer los datos del ETF de oro
Primero lo primero: importar todas las librerías necesarias para implementar esta estrategia.
# LinearRegression is a machine learning library for linear regression
from sklearn.linear_model import LinearRegression
# pandas and numpy are used for data manipulation
import pandas as pd
import numpy as np
# matplotlib and seaborn are used for plotting graphs
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('seaborn-darkgrid')
# yahoo finance is used to fetch data
import yfinance as yf
Luego, leemos los datos diarios de precios del ETF de oro de los últimos 12 años y los almacenamos en `Df`. Eliminamos las columnas que no son relevantes y descartamos los valores NaN usando la función `dropna()`. Luego, graficamos el precio de cierre del ETF de oro.
# Read data Df = yf.download('GLD', '2008-01-01', '2020-6-22', auto_adjust=True) # Only keep close columns Df = Df[['Close']] # Drop rows with missing values Df = Df.dropna() # Plot the closing price of GLD Df.Close.plot(figsize=(10, 7),color='r') plt.ylabel("Gold ETF Prices") plt.title("Gold ETF Price Series") plt.show()
Definir las variables explicativas
Una variable explicativa es aquella que se manipula para determinar el valor del precio del ETF de oro al día siguiente. En este caso, usaremos el promedio móvil de los últimos 3 días y de los últimos 9 días como variables explicativas y las almacenaremos en `X`.
Sin embargo, puedes agregar más variables a `X` que consideres útiles para predecir los precios del ETF de oro. Estas variables pueden ser indicadores técnicos, el precio de otro ETF como el ETF de mineros de oro (GDX) o el ETF de petróleo (USO), o datos económicos de EE.UU.
Definir la variable dependiente
La variable dependiente depende de los valores de las variables explicativas. En este caso, es el precio del ETF de oro que intentamos predecir y lo almacenamos en `y`.
# Define explanatory variables Df['S_3'] = Df['Close'].rolling(window=3).mean() Df['S_9'] = Df['Close'].rolling(window=9).mean() Df['next_day_price'] = Df['Close'].shift(-1) Df = Df.dropna() X = Df[['S_3', 'S_9']] # Define dependent variable y = Df['next_day_price']
Dividir los datos en conjuntos de entrenamiento y prueba
En este paso, dividimos los datos en conjuntos de entrenamiento y de prueba. Los datos de entrenamiento se usan para crear el modelo de regresión lineal, asociando la entrada con la salida esperada. Los datos de prueba se usan para evaluar qué tan bien se ha entrenado el modelo.
- El primer 80% de los datos se utiliza para entrenamiento y el resto para pruebas.
- X_train e y_train son conjuntos de datos de entrenamiento
- X_test e y_test son conjuntos de datos de prueba
# Split the data into train and test dataset t = .8 t = int(t*len(Df)) # Train dataset X_train = X[:t] y_train = y[:t] # Test dataset X_test = X[t:] y_test = y[t:]
Crear un modelo de regresión lineal
Ahora crearemos un modelo de regresión lineal, pero qué es una regresión lineal?
Si intentamos capturar una relación matemática entre las variables ‘x’ y ‘y’ que “mejor” explique los valores observados de ‘y’ en función de los valores observados de ‘x’ ajustando una línea a través de un gráfico de dispersión, entonces dicha ecuación entre x e y se llama análisis de regresión lineal.
Para desglosarlo más, la regresión explica la variación en una variable dependiente en términos de variables independientes. La variable dependiente – ‘y’ es la variable que deseas predecir. Las variables independientes – ‘x’ son las variables explicativas que usas para predecir la variable dependiente. La siguiente ecuación de regresión describe esa relación:
Y = m1 * X1 + m2 * X2 + C
Precio del ETF de Oro = m1 * promedio móvil de 3 días + m2 * promedio móvil de 15 días + c
Luego usamos el método *fit* para ajustar las variables independientes y dependientes (x e y) y así generar el coeficiente y la constante para la regresión.
# Create a linear regression model linear = LinearRegression().fit(X_train, y_train) print("Linear Regression model") print("Gold ETF Price (y) = %.2f * 3 Days Moving Average (x1) \ + %.2f * 9 Days Moving Average (x2) \ + %.2f (constant)" % (linear.coef_[0], linear.coef_[1], linear.intercept_))
Salida:
Modelo de Regresión Lineal
Precio del ETF de Oro (y) = 1.20 * Promedio Móvil de 3 Días (x1) + -0.21 * Promedio Móvil de 9 Días (x2) + 0.43 (constante)
Predecir los precios del ETF de oro
Es hora de verificar si el modelo funciona en el conjunto de prueba. Predecimos los precios del ETF de oro usando el modelo lineal creado con el conjunto de entrenamiento. El método `predict` encuentra el precio del ETF de oro (`y`) para la variable explicativa dada `X`.
# Predicting the Gold ETF prices predicted_price = linear.predict(X_test) predicted_price = pd.DataFrame( predicted_price, index=y_test.index, columns=['price']) predicted_price.plot(figsize=(10, 7)) y_test.plot() plt.legend(['predicted_price', 'actual_price']) plt.ylabel("Gold ETF Price") plt.show()
El gráfico muestra el precio predicho y el precio real del ETF de Oro.
Ahora, calculemos el ajuste del modelo usando la función *score()*.
# R square r2_score = linear.score(X[t:], y[t:])*100 float("{0:.2f}".format(r2_score))
Salida:
99.21
Como se puede ver, el R-cuadrado del modelo es de 99.21%. El R-cuadrado siempre está entre 0 y 100%. Un puntaje cercano al 100% indica que el modelo explica bien los precios del ETF de Oro.
Graficar los rendimientos acumulados
Calculemos los rendimientos acumulados de esta estrategia para analizar su rendimiento.
Los pasos para calcular los rendimientos acumulados son los siguientes:
1. Generar el cambio porcentual diario del precio del oro.
2. Crear una señal de compra representada por “1” cuando el precio pronosticado del día siguiente es mayor al precio predicho del día actual. De lo contrario, no se toma posición.
3. Calcular los rendimientos de la estrategia multiplicando el cambio porcentual diario con la señal de trading.
4. Finalmente, graficamos el rendimiento acumulado.
gold = pd.DataFrame() gold['price'] = Df[t:]['Close'] gold['predicted_price_next_day'] = predicted_price gold['actual_price_next_day'] = y_test gold['gold_returns'] = gold['price'].pct_change().shift(-1) gold['signal'] = np.where(gold.predicted_price_next_day.shift(1) < gold.predicted_price_next_day,1,0) gold['strategy_returns'] = gold.signal * gold['gold_returns'] ((gold['strategy_returns']+1).cumprod()).plot(figsize=(10,7),color='g') plt.ylabel('Cumulative Returns') plt.show()
También calcularemos el ratio de Sharpe, que mide el rendimiento ajustado por riesgo de la estrategia.
# Calculate sharpe ratio sharpe = gold['strategy_returns'].mean()/gold['strategy_returns'].std()*(252**0.5) 'Sharpe Ratio %.2f' % (sharpe)
El resultado se proporciona a continuación:
‘Sharpe ratio 1,06’
¿Cómo usar este modelo para predecir los movimientos diarios?
Puedes usar el siguiente código para predecir los precios del oro y generar una señal de trading indicando si deberíamos comprar GLD o no tomar ninguna posición.
# import datetime and get today's date import datetime as dt current_date = dt.datetime.now() # Get the data data = yf.download('GLD', '2008-06-01', current_date, auto_adjust=True) data['S_3'] = data['Close'].rolling(window=3).mean() data['S_9'] = data['Close'].rolling(window=9).mean() data = data.dropna() # Forecast the price data['predicted_gold_price'] = linear.predict(data[['S_3', 'S_9']]) data['signal'] = np.where(data.predicted_gold_price.shift(1) < data.predicted_gold_price,"Buy","No Position") # Print the forecast data.tail(1)[['signal','predicted_gold_price']].T
La salida se muestra a continuación
¡Felicidades! Acabas de aprender una poderosa técnica de aprendizaje automático fundamental, con un ejemplo de predicción del precio del oro.
¡Gracias por leer!