Bosques causales para efectos de tratamiento heterogéneos en trading
Cada modelo predictivo en este blog estima el mismo objeto: una media condicional . Ingeniería de características, gradient boosting, intervalos conformes, validación walk-forward — todo ello sirve a un solo estimando. Este artículo trata sobre un estimando diferente y sobre la maquinaria que cambia cuando lo sustituyes.
El objeto es el efecto promedio de tratamiento condicional:
la diferencia entre dos resultados potenciales para la misma unidad — uno de los cuales nunca observas. No puedes hacer regresión sobre él, porque no está en tus datos. Los bosques causales (Athey e Imbens 2016; Wager y Athey 2018) lo estiman de forma no paramétrica y, notablemente, te dan un intervalo de confianza válido a su alrededor.
Tres cosas hacen esto posible y ninguna de ellas existe en un bosque aleatorio estándar: un criterio de división que maximiza la varianza del efecto de tratamiento en lugar de minimizar el error de predicción, una restricción de honestidad que prohíbe usar las mismas observaciones para elegir una división y estimar el efecto dentro de ella, y una relectura del bosque como un núcleo adaptativo que convierte la co-ocurrencia en hojas en pesos de estimación. Esas tres cosas, más la prueba de calibración que te dice si la heterogeneidad que encontraste es señal, son el contenido de este artículo.
De efectos promedio a efectos heterogéneos

El efecto promedio de tratamiento
La configuración: un tratamiento binario (un evento se disparó o no), un resultado (un retorno), covariables . El Efecto Promedio de Tratamiento es
el impacto promedio a través de todas las unidades. Para trading esto es casi inútil — no haces trading del promedio. Si un evento empuja la mitad del universo hacia arriba y la mitad hacia abajo, el ATE es cero y la oportunidad es máxima.
El efecto promedio de tratamiento condicional
El CATE condiciona sobre características. Dada una moneda con una capitalización de mercado específica, volatilidad realizada, historial de funding y profundidad del libro, ¿cuál es el impacto de retorno esperado de este evento en este activo? El CATE es una función sobre el espacio de covariables, y estimar esa función sin imponer su forma es lo que hacen los bosques causales.
¿Por qué no usar solo modelos de interacción lineal?
La alternativa del libro de texto es una regresión saturada:
donde lleva la interacción. Esto asume que la interacción es lineal. Rara vez lo es: la sensibilidad a un cambio de funding es convexa en el apalancamiento, no lineal; la profundidad interactúa con la capitalización de mercado de manera multiplicativa; el régimen de volatilidad condiciona todo lo demás. Los bosques causales no imponen nada de esto — particionan el espacio de covariables de forma adaptativa y dejan que la estructura de heterogeneidad surja de los datos.
Bosques causales: El algoritmo

Un bosque causal es un bosque aleatorio reconstruido alrededor del estimando de efecto de tratamiento. Cada árbol es un árbol causal que particiona el espacio de covariables para maximizar la heterogeneidad del efecto de tratamiento.
Árboles causales
En cada nodo interno, el algoritmo elige una variable de división y un punto de división . La diferencia clave con un árbol de regresión: el criterio maximiza la varianza del efecto de tratamiento estimado a través de los hijos en lugar de minimizar el error de predicción al cuadrado.
Para un nodo con datos , la estimación del efecto a nivel de nodo es la diferencia en medias de grupo:
y la puntuación de división es
con los tamaños de muestra en el hijo izquierdo, hijo derecho y padre. Esto es exactamente la varianza entre grupos de los efectos de tratamiento: una división es buena cuando los dos hijos no están de acuerdo sobre el efecto, no cuando predicen bien el resultado. Una covariable que predice fuertemente pero es ortogonal a cómo actúa nunca será seleccionada.
Estimación honesta
La innovación crítica es la honestidad. Los datos utilizados para determinar la estructura del árbol deben ser disjuntos de los datos utilizados para estimar los efectos de las hojas:
- Divide los datos en y
- Construye el árbol usando solo para elegir variables y puntos de división
- Estima efectos de hoja usando solo , dejando caer esas observaciones en el árbol ya fijado
Sin esto, el árbol hace trampa: esculpe hojas cuyos efectos extremos son ruido en la misma muestra utilizada para encontrarlas, y luego reporta ese ruido como la estimación. Este es el mismo fallo de selección adaptativa que la probabilidad de sobreajuste de backtest mide a nivel de estrategia, excepto que aquí se defiende contra él dentro del estimador en lugar de diagnosticarse después del hecho. La honestidad compra insesgamiento asintótico:
El precio es la eficiencia de la muestra — la mitad de tus datos construyen una estructura que luego no se puede usar para rellenar.
De árboles a bosques
Un bosque causal agrega árboles causales, cada uno en una submuestra aleatoria de tamaño con un subconjunto de covariables aleatorio en cada división:
La forma más útil de escribir esto es como un promedio ponderado de resultados:
con pesos adaptivos establecidos por la frecuencia con la que la observación cae en la misma hoja que :
donde es la hoja que contiene en el árbol . Esta es la vista de bosque aleatorio generalizado (Athey, Tibshirani y Wager 2019): un bosque causal es un estimador de núcleo adaptativo local. Aprende su propia noción de "similar", definida por qué covariables realmente importan para la heterogeneidad del efecto, en lugar de por la distancia euclidiana en un espacio donde tenías que elegir la escala a mano.
Teoría asintótica
Bajo condiciones de regularidad (Wager y Athey 2018) el estimador es consistente, , y asintóticamente normal:
dando intervalos puntuales . La varianza proviene del jackknife infinitesimal (o bootstrap-de-bolsas-pequeñas), calculado a partir de la misma estructura de submuestra que el bosque ya construyó — no hay bucle de bootstrap externo.
Vale la pena ser preciso sobre qué es y qué no es esta garantía. Es asintótica y puntual, y se cumple para el CATE. Los intervalos de predicción conforme utilizados elsewhere en este blog son de muestra finita y libres de distribución, pero marginales, y cubren un resultado. Diferente estimando, diferente garantía; no son sustitutos.
La conexión de Double Machine Learning
Cuando el tratamiento no está asignado aleatoriamente, el bosque causal se ajusta a datos residualizados: un modelo de resultado y un modelo de propensión se estiman mediante validación cruzada, y el bosque se ejecuta sobre contra . La ortogonalidad de Neyman es lo que hace que esto sea seguro: el error de estimación de molestias entra solo como un producto, así que y pueden converger cada uno a y aún converge a .
Ese marco — residualización, validación cruzada, el argumento de ortogonalidad, implicaciones del tamaño de muestra — es el tema de su propio artículo, Double Machine Learning para señales de trading causales. Léelo primero; todo a continuación asume eso y solo cubre lo que cambia cuando el estimando es en lugar de .
Aplicación de trading: Heterogeneidad del impacto de eventos

Configuración
El dominio natural para este blog es el universo de monedas de perpetuos, donde los eventos son frecuentes, con marca de tiempo y observables sin un feed de proveedor.
- Unidades: observaciones moneda-evento a través del universo perp comerciable
- Tratamiento: si el evento se disparó para la moneda — un cambio de signo de tasa de funding, una lista spot, o una cascada de liquidación que cruza el umbral supercrítico descrito en cascadas de liquidación como señal de trading — y para ventanas de no evento emparejadas
- Resultado: = el retorno anormal sobre la ventana del evento, no el retorno bruto. Ajusta un modelo de mercado en una ventana de estimación precedente al evento, luego toma el retorno anormal acumulativo. La especificación exacta — ventana de estimación, regresión de modelo de mercado, construcción de CAR y su estadístico t — se desarrolla en la sección de estudio de eventos de minería de alfa LLM desde llamadas de ganancias; reúsalo verbatim. Este paso no es opcional: un resultado close-to-close bruto permite que el movimiento de todo el mercado entre en , y dado que el movimiento del mercado es común a todas las unidades tratadas se ve exactamente como un efecto de tratamiento
- Covariables : capitalización de mercado, volatilidad realizada, historial de funding, profundidad del libro de órdenes, relación de interés abierto a capitalización
- Confusores : variables de régimen que cambian tanto la probabilidad del evento como los retornos
La señal de trading
La superficie CATE se mapea a un dimensionador de posiciones exactamente como cualquier estimación de incertidumbre calibrada: dimensiona por relativo al ancho del intervalo, y no trades cuando el intervalo se extiende sobre cero. Esa regla de decisión — dimensionamiento de ancho inverso, la razón de borde , el filtro de no trade, la variante consciente de costos y el argumento de por qué no deberías multiplicarlo en una fracción de Kelly — se deriva en Predicción Conforme para Dimensionamiento de Posiciones Consciente del Riesgo. Reúsalo con en lugar de y el intervalo de bosque causal en lugar del conforme. Equilibra las piernas largas y cortas y el libro es neutral al mercado por construcción.
Implementación en Python con EconML
import numpy as np
import pandas as pd
from sklearn.ensemble import GradientBoostingRegressor, GradientBoostingClassifier
from econml.dml import CausalForestDML
def fit_causal_forest(Y, T, X, W, n_estimators=1000):
"""
CausalForestDML: residualize against (X, W), then fit a causal
forest on the residuals.
Y: abnormal returns over the event window (CAR, market-model adjusted)
T: event indicator
X: effect modifiers -- only these drive heterogeneity
W: confounders -- enter the nuisance models only
"""
cf = CausalForestDML(
model_y=GradientBoostingRegressor(
n_estimators=200, max_depth=5, learning_rate=0.05
),
model_t=GradientBoostingClassifier(
n_estimators=200, max_depth=5, learning_rate=0.05
),
n_estimators=n_estimators,
min_samples_leaf=20,
max_depth=None,
criterion="het", # heterogeneity-based splitting
honest=True, # honest estimation
inference=True, # infinitesimal-jackknife intervals
cv=5, # cross-fitting folds for DML
random_state=42,
)
cf.fit(Y=Y, T=T, X=X, W=W)
return cf
def summarize_cate(cf, X, feature_names):
"""Distribution of the CATE and what drives its heterogeneity."""
tau_hat = cf.effect(X)
tau_lo, tau_hi = cf.effect_interval(X, alpha=0.05)
print(f"Mean CATE: {tau_hat.mean():.4f}")
print(f"Std CATE: {tau_hat.std():.4f}")
print(f"Range: [{tau_hat.min():.4f}, {tau_hat.max():.4f}]")
print(f"% CI excl. 0: {((tau_lo > 0) | (tau_hi < 0)).mean():.1%}")
for idx in np.argsort(cf.feature_importances_)[::-1]:
print(f" {feature_names[idx]:>20s}: {cf.feature_importances_[idx]:.4f}")
return tau_hat, tau_lo, tau_hi
Interpretando la superficie CATE
Los gráficos de efecto marginal muestran cómo se mueve el efecto de tratamiento a lo largo de una covariable con el resto mantenido en su mediana:
def plot_cate_by_feature(cf, X, feature_idx, n_points=50):
x_grid = np.linspace(X[:, feature_idx].min(),
X[:, feature_idx].max(), n_points)
X_eval = np.tile(np.median(X, axis=0), (n_points, 1))
X_eval[:, feature_idx] = x_grid
tau = cf.effect(X_eval)
tau_lo, tau_hi = cf.effect_interval(X_eval, alpha=0.05)
return x_grid, tau, tau_lo, tau_hi
Lee estos como descripciones de la superficie ajustada, no como curvas de dosis-respuesta causales — mantener las otras covariables en su mediana puede colocarte en una región del espacio de covariables sin soporte.
Suposiciones clave y diagnósticos

Viola estas y obtienes efectos confiados, precisos, incorrectos.
1. Sin confusión (Selección en observables)
La asignación del tratamiento debe ser independiente de los resultados potenciales dadas las covariables observadas. Para un evento definido mecánicamente esto es defendible; para un evento que es en sí mismo una reacción del mercado — un anuncio de listado, el motor de liquidación de un intercambio disparándose — no lo es, porque el mismo flujo no observado que desencadenó el evento también mueve el retorno.
Pruébalo con análisis de sensibilidad de Rosenbaum: si un no observado puede cambiar las probabilidades de tratamiento hasta un factor ,
qué tan grande debe ser antes de que el efecto estimado cambie de signo? Un diseño que se rompe en no es un hallazgo.
2. Superposición (Positividad)
Cada unidad necesita probabilidad positiva de aparecer en ambos brazos. Verifica las puntuaciones de propensión y recorta:
propensity = cf.models_t[0][0].predict_proba(np.hstack([X, W]))[:, 1]
print(f"Propensity range: [{propensity.min():.3f}, {propensity.max():.3f}]")
valid = (propensity > 0.05) & (propensity < 0.95)
print(f"Retained after trimming: {valid.mean():.1%}")
Recortar no es gratuito — redefine la población que describe tu . Reporta qué fracción sobrevivió.
3. SUTVA (Suposición de Valor de Tratamiento de Unidad Estable)
El tratamiento de una unidad no debe afectar el resultado de otra. En crypto esta es la más débil de las tres: una cascada de liquidación en un perp se propaga a través de colateral compartido e inventario de market makers en cada par correlacionado, que es interferencia por definición. Agrupar errores estándar por grupo de correlación lo aborda parcialmente; nada lo hace completamente.
Más allá de tratamientos binarios
Los bosques causales se extienden a tratamientos continuos a través de la misma maquinaria DML — estimar cuánto el magnitud de un choque, no solo su ocurrencia, mueve activos de manera diferencial:
donde es, digamos, el tamaño del cambio de tasa de funding en puntos base. Ahora es un efecto por punto base.
cf_continuous = CausalForestDML(
model_y=GradientBoostingRegressor(n_estimators=200),
model_t=GradientBoostingRegressor(n_estimators=200), # regression, not classifier
discrete_treatment=False,
n_estimators=1000,
honest=True,
inference=True,
)
cf_continuous.fit(Y=car, T=funding_change_bps, X=asset_features, W=controls)
effects_25bp = cf_continuous.effect(X_test, T0=0, T1=25)
Consideraciones prácticas
¿Es real la heterogeneidad?
Esta es la pregunta que los bosques causales responden y nada más en este blog hace, y merece una prueba real en lugar de una regla general. La honestidad protege contra divisiones espurias dentro del estimador; la evaluación fuera de muestra sobre eventos retenidos (no activos retenidos) es estándar y se cubre en optimización walk-forward y Sharpe desinflado y pruebas múltiples. Ninguno te dice si varía con en absoluto.
La prueba de Mejor Predictor Lineal sí lo hace. Regresa el resultado residualizado sobre el tratamiento residualizado y su interacción con la estimación CATE centrada:
Los dos coeficientes responden dos preguntas diferentes. es el efecto promedio: ¿hay algo aquí en absoluto? es la pendiente de calibración en tus propias predicciones: cuando tu bosque dice que el efecto es mayor, ¿realmente es mayor? Bajo la nulidad de sin heterogeneidad . Bajo calibración perfecta . Un significativamente sobre cero pero lejos de uno significa que el bosque encontró un ordenamiento real pero exageró su dispersión — puedes tradear el ranking, no las magnitudes.
El RScorer de EconML da una puntuación de selección de modelo acompañante:
from econml.score import RScorer
scorer = RScorer(
model_y=GradientBoostingRegressor(n_estimators=100),
model_t=GradientBoostingClassifier(n_estimators=100),
discrete_treatment=True,
cv=5,
)
scorer.fit(Y_val, T_val, X=X_val, W=W_val)
print(f"R-score: {scorer.score(cf):.4f}")
Ajusta el scorer en una división de validación que el bosque nunca vio, luego úsalo para comparar modelos CATE candidatos entre sí y contra una línea de base de efecto constante. Un bosque que no puede superar el modelo de efecto constante en R-score no ha encontrado heterogeneidad que valga la pena tradear, digan lo que digan sus importancias dentro de la muestra.
Tamaño de muestra
Los bosques causales necesitan más datos que un modelo de resultado, porque el estimando es una diferencia y ambos brazos deben estar poblados dentro de cada hoja. La disciplina general de datos-vs-parámetros — cuántos puntos fuera de muestra por parámetro libre, y la corrección de Bonferroni una vez que estás comparando configuraciones — está en la sección de requisitos de datos de optimización walk-forward. La respuesta específica de bosque causal es empírica, no una regla general: ajusta el bosque en submuestras anidadas y grafica el ancho de intervalo mediano contra ; el tamaño de muestra utilizable es donde el ancho cae por debajo de los tamaños de efecto que pretendes tradear.
Walk-Forward, con dos matices
El protocolo de evaluación es walk-forward anclado estándar — reajusta en todos los eventos hasta , tradea evento — y el tratamiento completo, incluyendo purging, embargo, la razón de eficiencia walk-forward y la tasa de degradación, está en optimización walk-forward. Dos cosas son específicas de este estimador.
Primero, las ventanas de eventos se superponen. Si la ventana de covariables precedente al evento contiene la ventana de resultado del evento , los folds comparten observaciones y el resultado fuera de muestra está contaminado. Purga ventanas superpuestas antes de contar un solo número PnL; con un tratamiento frecuentemente mecánico como un flip de funding esto puede eliminar una porción sustancial de eventos.
Segundo, la división honesta debe redibujarse en cada reajuste. Llevar la misma partición / a través de folds reintroduce exactamente la fuga de selección de estructura que la honestidad existe para prevenir, porque los eventos recién añadidos aterrizan en una partición que fue elegida con conocimiento de los antiguos.
Luego ejecuta PnL fuera de muestra a nivel de evento a través de los filtros usuales — PBO y la razón de Sharpe desinflada — antes de creer cualquier cosa.
Costos
Una señal CATE se cotiza como cualquier otra señal impulsada por eventos: resta el half-spread esperado de antes del filtro de no trade, y dimensiona hacia abajo en libros delgados. Las versiones cuantitativas — la ley de impacto de raíz cuadrada y curvas de costo ajustadas en modelos de costo de slippage, el filtro de no trade consciente de costos en predicción conforme, y la contabilidad de ejecución en implementation shortfall y TCA — todos se transfieren sin cambios.
Lo único que no se transfiere: la vida útil de una señal CATE está limitada por la ventana del evento, así que el costo se amortiza sobre un período de retención fijo corto en lugar de uno abierto. Una señal mantenida continuamente paga el spread una vez y gana mientras el borde persiste; esta lo paga en cada evento. Si el borde sobrevive eso es una pregunta empírica sobre tu evento específico y tu universo específico, y es lo primero que debes verificar, porque puede matar la estrategia antes de que importe cualquier maquinaria causal.
Conclusión
Los bosques causales estiman un objeto diferente al resto del toolkit de este blog. No "qué retornará este activo", sino "cuánto movió este evento este activo, relativo al contrafactual donde no se disparó". La maquinaria que hace eso estimable — divisiones que maximizan heterogeneidad, estimación honesta, la representación de pesos de núcleo adaptativo e intervalos de jackknife infinitesimal — no tiene análogo en aprendizaje supervisado ordinario, y las suposiciones que necesita (sin confusión, superposición, SUTVA) son lo suficientemente fuertes como para que deben probarse en lugar de afirmarse.
Lo que este artículo no tiene es un resultado. Cada número arriba es un marcador de posición. Contra el estándar establecido por el negativo honesto y Sharpe desinflado, un método sin una distribución CATE medida, un BLP con un valor p, un diagnóstico de superposición y PnL fuera de_sample protegido por DSR/PBO es un tutorial, no un hallazgo. Esos números son el siguiente trabajo; un resultado negativo vale la pena publicarse.
Referencias
- Athey, S., Imbens, G.W. "Recursive Partitioning for Heterogeneous Causal Effects." PNAS, 113(27), 7353-7360 (2016).
- Wager, S., Athey, S. "Estimation and Inference of Heterogeneous Treatment Effects using Random Forests." JASA, 113(523), 1228-1242 (2018). arXiv:1510.04342
- Athey, S., Tibshirani, J., Wager, S. "Generalized Random Forests." Annals of Statistics, 47(2), 1148-1178 (2019).
- Chernozhukov, V., et al. "Double/Debiased Machine Learning for Treatment and Structural Parameters." The Econometrics Journal, 21(1), C1-C68 (2018).
- Chernozhukov, V., Demirer, M., Duflo, E., Fernandez-Val, I. "Generic Machine Learning Inference on Heterogeneous Treatment Effects in Randomized Experiments." (2018). arXiv:1712.04802
- Battocchi, K., et al. "EconML: A Python Package for ML-Based Heterogeneous Treatment Effects Estimation." Microsoft Research (2019). GitHub
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.