Métodos conjuntos: combinación de alumnos débiles para una alfa sólida
La mayoría de los escritos sobre conjuntos comerciales sostienen que cuantos más modelos haya, mejor. Ese es el eje equivocado. El error de un conjunto se descompone en tres términos y, en el comercio, sólo uno de ellos es la restricción vinculante.
Este artículo trata sobre ese término y sobre dos consecuencias que el resto de este blog no cubre: el apilamiento como una capa de combinación de señales explícita y si la combinación de muchas señales realmente reduce la facturación antes de que las operaciones lleguen al mercado.
El término que realmente vincula: sesgo-varianza-covarianza
Para un conjunto de regresión de modelos, el error cuadrático esperado de la predicción promedio se descompone como:
Tres términos, tres palancas:
- Bagging ataca el término de varianza promediando muestras de arranque.
- Impulso ataca el término de sesgo corrigiendo iterativamente los residuos.
- Apilamiento ataca el término de covarianza aprendiendo pesos combinados en lugar de asumir pesos iguales.
- Creciente reduce solo la contribución a la varianza. No afecta en absoluto a la covarianza: la el coeficiente ya es 0,99 en .
Ese último punto es todo el argumento. En el comercio, los modelos se entrenan con los mismos instrumentos, durante el mismo historial, contra objetivos que son en sí mismos transformaciones casi idénticas de la misma serie de precios. Sus errores no son ni de lejos independientes. Entonces, el término de covarianza es grande y el término de varianza ya está agotado, lo que significa que el recuento de modelos no permite comprar casi nada y la diferencia estructural lo compra todo.
La forma concreta y falsificable de la afirmación: agregar el árbol 101 impulsado por gradiente debería mover la métrica del conjunto menos que agregar un modelo estructuralmente diferente: un LSTM, un modelo lineal en un dominio de características disjunto, cualquier cosa con un sesgo inductivo diferente. El árbol marginal es casi colineal con los árboles que ya aparecen en el libro; el modelo estructuralmente diferente no lo es.
La correlación, no el recuento del modelo, establece la amplitud efectiva de un conjunto: la derivación, los factores de correlación medidos criptográficamente por clase de activo y la simulación con datos de pares reales se encuentran en Correlación de señales: cuántos pares monitorear.
No reduzca la diversidad del conjunto a un solo número. El índice de Sharpe deflactado calcula cinco pruebas efectivas estimadores (correlación promedio, índice de participación, PCA-95%, Kaiser, Cheverud-Nyholt) en una cuadrícula real de 640 celdas, muestra que abarcan de 1,6 a 370, y sostiene que la banda (no una estimación puntual única) es lo que se puede entregar. Denuncia la banda.
Apilamiento como capa de combinación de señales
El embolsado y el impulso están bien tratados en otros lugares. Modelado extendido con aprendizaje automático incluye la configuración de aumento de gradiente, la selección de pérdidas para objetivos sesgados, los hallazgos de importancia de SHAP, la taxonomía de características y una división de avance purgada con la superposición de ventana delantera que motiva la brecha. Empiece por ahí; esta sección lo asume.
Lo que no se cubre es el nivel superior: un metaaprendiz que toma las predicciones del modelo base como características de entrada y aprende a combinarlas.
- Nivel 0 (estudiantes básicos): diversos modelos que producen predicciones a partir de características sin procesar.
- Nivel 1 (metaaprendiz): un modelo que aprende en qué base confiar los alumnos y cuándo.
El mecanismo que hace que esto sea seguro son las metacaracterísticas desplegadas. El metaaprendiz nunca debe ver una predicción del modelo base que se realizó a partir de datos con los que se entrenó el modelo base; esas predicciones están sesgadas de manera optimista de una manera que no sobrevive al comercio real, y el metaaprendiz las ponderará en consecuencia.
import numpy as np
import pandas as pd
from sklearn.base import clone
from sklearn.model_selection import TimeSeriesSplit
class TradingStackingEnsemble:
"""
Two-level stacking ensemble for return prediction.
Level 0: base learners, each on its own feature domain
Level 1: meta-learner trained on out-of-fold base predictions
"""
def __init__(self, base_models: list, meta_model, n_splits: int = 5):
self.base_models = base_models # list of (name, model, feature_cols)
self.meta_model = meta_model
self.n_splits = n_splits
self.fitted_base_models_ = {}
def _generate_meta_features(
self,
X: pd.DataFrame,
y: pd.Series
) -> pd.DataFrame:
"""Out-of-fold predictions from each base model."""
tscv = TimeSeriesSplit(n_splits=self.n_splits)
meta_features = pd.DataFrame(index=X.index)
for name, model, feature_cols in self.base_models:
oof_preds = pd.Series(np.nan, index=X.index)
for train_idx, val_idx in tscv.split(X):
X_train = X.iloc[train_idx][feature_cols]
y_train = y.iloc[train_idx]
X_val = X.iloc[val_idx][feature_cols]
fold_model = clone(model)
fold_model.fit(X_train, y_train)
if hasattr(fold_model, 'predict_proba'):
oof_preds.iloc[val_idx] = fold_model.predict_proba(X_val)[:, 1]
else:
oof_preds.iloc[val_idx] = fold_model.predict(X_val)
meta_features[name] = oof_preds
return meta_features.dropna()
def fit(self, X: pd.DataFrame, y: pd.Series):
meta_features = self._generate_meta_features(X, y)
y_meta = y.loc[meta_features.index]
self.meta_model.fit(meta_features, y_meta)
for name, model, feature_cols in self.base_models:
model.fit(X[feature_cols], y)
self.fitted_base_models_[name] = model
return self
def predict(self, X: pd.DataFrame) -> np.ndarray:
meta_features = pd.DataFrame()
for name, model, feature_cols in self.base_models:
fitted = self.fitted_base_models_[name]
if hasattr(fitted, 'predict_proba'):
meta_features[name] = fitted.predict_proba(X[feature_cols])[:, 1]
else:
meta_features[name] = fitted.predict(X[feature_cols])
return self.meta_model.predict(meta_features)
La disciplina de división aquí no es opcional ni novedosa: utilice un procedimiento purgado y embargado y comprenda lo que vale cada clase de filtración en el inflado Sharpe antes de confiar en cualquiera de estos números. Ambos ya están medidos: la taxonomía de sesgo de anticipación cuantifica la fuga de ejecución, indicador y normalización en un simulador controlado, y optimización de avance cubre ventanas ancladas versus ventanas rodantes, CPCV, purga y diagnóstico de degradación de WFER.
Tres decisiones de diseño son específicas del apilamiento y vale la pena mencionarlas.
Simplicidad del metaaprendiz. Utilice un modelo lineal: cresta, lazo, regresión logística. Los alumnos básicos manejan la no linealidad; el metaaprendiz solo maneja la combinación. Un metaaprendiz complejo además de alumnos base complejos es un sobreajuste de segundo orden, y la regularización L1 en la capa de combinación tiene el útil efecto secundario de poner a cero los modelos base que solo contribuyen con ruido.
Resultados de probabilidad sobre etiquetas impresas. predict_proba lleva información de confianza que una etiqueta de clase descarta y permite al metaaprendiz ponderar más las predicciones base seguras.
Partición del dominio de características. Esta es la palanca de diversidad de mayor apalancamiento y se deriva directamente del argumento de la covarianza: los modelos que ven las mismas características producen errores correlacionados independientemente del algoritmo.
FEATURE_GROUPS = {
'momentum': ['ret_5d', 'ret_10d', 'ret_21d', 'ret_63d'],
'volatility': ['vol_21d', 'vol_ratio', 'vol_skew', 'garch_vol'],
'volume': ['volume_ratio', 'obv_slope', 'vwap_dist', 'adv_ratio'],
'mean_reversion': ['dist_from_ma21', 'dist_from_ma63', 'rsi_14', 'bb_pct'],
'microstructure': ['bid_ask_spread', 'kyle_lambda', 'amihud_illiq'],
'fundamental': ['ep_ratio', 'bp_ratio', 'roe', 'accruals'],
}
base_models = []
for domain, features in FEATURE_GROUPS.items():
model = GradientBoostingClassifier(
n_estimators=200, max_depth=3,
learning_rate=0.05, subsample=0.7
)
base_models.append((domain, model, features))
Cada modelo base se convierte en un experto en el dominio: el modelo de impulso aprende patrones de impulso sin interferencia del ruido del volumen, y el metaaprendiz aprende en qué experto confiar y en qué condiciones.
Dos advertencias sobre esa última cláusula. En primer lugar, la ponderación condicional del régimen es un problema resuelto y publicado: la detección de regímenes con HMM deriva los regímenes correctamente a través de Forward/Viterbi/Baum-Welch y los alimenta como características a un conjunto posterior, y combinación dinámica de estrategias cubre las estrategias ponderadas por el régimen reversión a la media frente a impulso con resultados informados. No sustituya ninguno de los dos por un proxy de señal de impulso ad hoc. En segundo lugar, la selección basada en el desempeño dentro de la muestra produce ganadores que no sobreviven; el mecanismo genérico y la defensa CSCV se miden en la probabilidad de sobreajuste del backtest. El apilamiento es un ejemplo más limitado de exactamente ese problema.
Para ponderar flujos de retorno en lugar de predicciones del modelo, no vuelva a derivar la media-varianza. 12 algoritmos de optimización de cartera, comparados compite con HRP, HERC, GHRP, MHRP, Black-Litterman, NCO, MVO, paridad de riesgo e igual peso con resultados medidos y código fuente abierto; La teoría de la cartera de Markowitz para las criptomonedas tiene la implementación de varianza media SLSQP; y el resultado 1/N es difícil de superar ya se ha probado frente a HRP y CVaR en el proceso de cartera de HRP/CVaR.
Red de facturación: la afirmación que vale la pena probar
Aquí está la parte del argumento de la biblioteca alfa que el grupo de costos de ejecución de este blog no cubre actualmente.
Cuando Alpha #4,721 dice "comprar MSFT" y Alpha #8,392 dice "vender MSFT" en el mismo reequilibrio, esas operaciones se cruzan internamente. Sólo la posición neta llega al mercado. La afirmación es que, con suficientes señales, una gran fracción del volumen de negocios bruto previsto se cancela antes de incurrir en diferenciales, tarifas o impacto en el mercado, lo que significaría que es más barato ejecutar un conjunto que la suma de sus componentes, y no simplemente más estable.
Este es un mecanismo distinto del que ya maneja la orquestación de estrategias en cascada. Cascade resuelve conflictos en el nivel de ranura: el mismo par, la dirección opuesta está prohibida y se resuelve mediante puntuación, el desalojo de pares cruzados pasa por una cola de prioridad, y el artículo demuestra empíricamente que el PnL por estrategia no se puede simplemente sumar debido a la superposición de tiempo y las limitaciones de capital. La compensación consiste en aritmética de posiciones brutas a netas reduciendo la cantidad negociada en sí.
También es barato falsificar: calcule la facturación bruta versus neta en rellenos reales cuando se combinan las señales de los componentes, luego fije el precio de ambos a través de la maquinaria de costos existente: tarifas y reembolsos de maker-taker, déficit de implementación y TCA, y costo de deslizamiento modelos.
Una nota a escala, ya que el marco de la biblioteca alfa lo invita. WorldQuant informa haber producido una biblioteca alfa muy grande, y [101 fórmulas alfa] de Kakushadze (https://arxiv.org/pdf/1601.00991) documenta la forma de las señales individuales. Pero la minería alfa a escala industrial es también la máquina de pruebas múltiples más grande que se pueda imaginar, y la postura de este blog al respecto es clara: una búsqueda de tamaño debe desinflarse frente a la suerte esperada de una búsqueda de ese tamaño. The Deflated Sharpe Ratio muestra una cuadrícula de 640 celdas que ya supera las pruebas de significancia ingenuas, y The Honest Negative muestra una búsqueda de ~37.000 pruebas que produce un +16,35 % de ganador fuera de la muestra que se desinfla a DSR 0,00. El tamaño de la biblioteca no es evidencia de ventaja. Es el denominador que tienes que pagar.
Juntándolo
Raw Data
|
v
Feature Engineering
|
v
Feature Subsets (partitioned by domain -> decorrelated errors)
|
+---> Base Model 1: RF on momentum features
+---> Base Model 2: GBM on volatility features
+---> Base Model 3: LSTM on price sequences
+---> Base Model 4: Lasso on fundamental features
+---> Base Model 5: XGBoost on microstructure features
|
v
Out-of-Fold Predictions (purged walk-forward)
|
v
Meta-Learner (Ridge)
|
v
Combined Signal -> Net Position -> Execution
|
v
DSR >= 0.95 and PBO <= 0.2 gate, or it does not ship
La última caja no es decoración. apilando modelos base es un procedimiento de selección de tamaño , y un artículo conjunto que no se desinfla es indefendible.
Comidas para llevar
- La diferencia estructural supera el recuento del modelo. El término de covarianza no se reduce con . Agregar un sexto árbol correlacionado no es diversificación; agregar una clase de modelo diferente o un dominio de características disjunto sí lo es.
- Reportar la efectividad- banda, no un punto. Cinco estimadores, cinco respuestas, a veces con dos órdenes de magnitud de diferencia.
- Mantenga lineal al metaaprendiz. La complejidad en la capa de combinación casi siempre se sobreajusta, y L1 allí realiza una útil selección automática de modelos.
- Fuera de pliegue o nada. Un metaaprendiz capacitado en predicciones base en muestra aprende las ponderaciones incorrectas con alta confianza.
- Desinfla el conjunto en sí. Apilar es una búsqueda. Póngalo como uno.
Lectura adicional:
- Kakushadze, Z. (2016). 101 alfas de fórmula
- Aprendizaje conjunto en inversión — Fundación de Investigación del Instituto CFA, 2025
- Predicción de rentabilidad de las acciones: apilamiento de una variedad de modelos — Journal of Financial Economics
- Jansen, S. [Aprendizaje automático para el comercio algorítmico] (https://github.com/stefan-jansen/machine-learning-for-trading), 2.ª edición
Authors
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.