Quant500 Academy

4. Aprendizaje supervisado: aprender con profesor

Nivel 10: Machine Learning Aplicado al Trading

Los problemas de machine learning se agrupan en unos pocos tipos según qué información tenemos disponible. El primero y más común es el aprendizaje supervisado.

Este tipo de algoritmos funciona con el modelo del profesor. Significa que tenemos un conjunto de datos con valores de entrada y de salida, es decir, datos etiquetados. Definimos un método para obtener las salidas conocidas a partir de las entradas de que disponemos. A medida que mejoramos ese método usando todos los pares entrada-salida (a eso se le llama entrenar), podemos predecir valores de salida para datos de entrada nuevos. Eso es el aprendizaje supervisado. Aprendemos el modelo usando los datos de entrenamiento y lo probamos con datos de test que no ha visto. Es decir, trabajamos tanto con datos de entrada como de salida.

Un ejemplo típico de aprendizaje supervisado es predecir precios de viviendas. Otro es decir qué dígito, qué animal o qué objeto aparece en una imagen.

Dentro del aprendizaje supervisado hay dos grandes familias, y la diferencia está en la naturaleza de y:

En finanzas hay un detalle que no aparece en los tutoriales genéricos y que arruina más backtests que ningún otro error: la partición entre entrenamiento y test no puede ser aleatoria. Si barajas las filas, el modelo se entrena con días futuros y se evalúa con días pasados, y aprende relaciones que en el momento de operar no estaban disponibles. La partición tiene que respetar el orden temporal.

import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

# df tiene columnas Open, High, Low, Close de un activo (por ejemplo, SPY)
df = df.dropna().copy()

# Variables de entrada (X): información disponible AL CIERRE de hoy
df["Open-Close"] = df["Open"] - df["Close"]
df["High-Low"] = df["High"] - df["Low"]
df["Ret_1d"] = np.log(df["Close"] / df["Close"].shift(1))

# Variable de salida (y): etiqueta binaria, 1 si manana cierra por encima
df["y"] = np.where(df["Close"].shift(-1) > df["Close"], 1, 0)
df = df.dropna()

X = df[["Open-Close", "High-Low", "Ret_1d"]]
y = df["y"]

# Partición TEMPORAL, nunca aleatoria: 70% pasado para entrenar, 30% futuro para test
split = int(0.7 * len(df))
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]

modelo = LogisticRegression(max_iter=1000).fit(X_train, y_train)
print("Acierto en train:", accuracy_score(y_train, modelo.predict(X_train)))
print("Acierto en test :", accuracy_score(y_test, modelo.predict(X_test)))

Si el acierto en train es mucho mayor que en test, tienes sobreajuste. Y si el acierto en test ronda el 50% en una tarea binaria equilibrada, tu modelo no sabe nada: está lanzando una moneda cara.

El resto de Quant500

Lo que estás aprendiendo, aplicado al índice todos los días:

La cartera del modelo, cada semana en tu correo

Cada sábado, su semana en un minuto: cómo fue, lo mejor y lo peor, y qué directivos compraron con su dinero. Y el día que el modelo se rehace, qué entra y qué sale. Es una simulación, no un consejo. Como mucho un correo a la semana, sin publicidad y sin cuenta; te das de baja con un clic. Lo hace una persona: Pol Gracia.

Cartera modelo con resultados simulados, no una recomendación personalizada. Tu correo se usa solo para esto: privacidad.

Detrás de la Academia y del resto de Quant500 hay una sola persona: Pol Gracia Serrahima.