PCMCI: Causal Discovery in Multivariate Crypto Time Series
PCMCI, desarrollado por Jakob Runge (2018, 2020), es un algoritmo de descubrimiento causal para series temporales multivariadas. Combina el algoritmo de PC para el aprendizaje de modelos gráficos con una prueba de independencia condicional momentánea (MCI) cuyo conjunto de condicionamiento está diseñado para neutralizar tres cosas a la vez: impulsores comunes, rutas indirectas y la autocorrelación de la variable fuente. Esta última parte es la que vale la pena leer atentamente: es la razón por la que PCMCI no hereda la tasa de falsos positivos que hunde las ingenuas pruebas de avance-retraso en series con mucho impulso.
Este artículo analiza la construcción en dos etapas desde los primeros principios, la implementa con la biblioteca tigramite y presenta el estudio de datos reales que el método necesita antes de que cualquiera de ellos se convierta en un insumo comercial.
Lo que esto añade a lo que ya está aquí

El blog ya ha hecho el trabajo de correlación. El co-movimiento criptográfico es en gran medida un artefacto de factor común: correlación de señales entre pares muestra que PC1 por sí solo absorbe el 65% de la varianza en un libro de diez pares. Una correlación de pares alta no es una relación negociable, razón por la cual arbitraje estadístico y comercio de pares apuesta por la cointegración. Y la dependencia en sí ni siquiera es estable: correlación dinámica DCC-GARCH enumera por qué una correlación muestral estática supone estacionariedad de la dependencia, volatilidad marginal constante y simetría en todas las direcciones, ninguna de las cuales se cumple.
Ninguno de ellos produce un gráfico dirigido. Te dicen que BTC, ETH y SOL se mueven juntos y que un factor común explica la mayor parte; no le dicen si BTC impulsa SOL directamente o si la asociación está mediada completamente a través de ETH. La causalidad de Granger es la forma habitual de buscar una dirección, pero el Granger estándar es bivariado: no puede separar un factor común no observado de una causalidad genuina.
Hay un tercer modo de fallo que aquí importa más de lo que parece. Cada serie de retorno criptográfico conlleva una autocorrelación positiva, y la autocorrelación infla la estadística de prueba de cualquier prueba de dependencia ejecutada entre dos de esas series: dos procesos autocorrelacionados independientes parecerán significativamente relacionados en muestras finitas. El trabajo de correlación trata esto como una corrección del tamaño de la muestra (la discusión sobre el N efectivo en el artículo sobre correlación de señales). Para el descubrimiento causal no es una corrección, es el problema central de diseño, y es exactamente para lo que está diseñado el conjunto de condicionamientos de la Etapa 2.
El algoritmo PCMCI

PCMCI opera en dos etapas. La primera etapa identifica un conjunto candidato de padres causales para cada variable. La segunda etapa prueba cada vínculo candidato con una prueba de independencia condicional cuidadosamente construida.
Etapa 1: Selección de condición estable de PC (PC1)
El objetivo de la Etapa 1 es encontrar, para cada variable , un superconjunto de sus verdaderos padres causales. Este conjunto se utilizará más tarde como conjunto de acondicionamiento en la Etapa 2.
El algoritmo comienza con el conjunto completo de todas las variables rezagadas como padres potenciales:
Luego elimina iterativamente las variables que son condicionalmente independientes de . en iteración , el algoritmo prueba a cada padre candidato por la independencia con , condicionando el padres restantes más fuertes (excluyendo sí mismo):
dónde es el conjunto de variables en con la asociación más fuerte con .
El aspecto "estable" significa que las decisiones de eliminación dentro de una sola iteración se basan en los conjuntos principales de la iteración anterior, lo que evita la dependencia del orden en los resultados. Esto es fundamental para la reproducibilidad.
El nivel de significancia en esta etapa se establece deliberadamente liberalmente (a menudo 0,2 o más, o se determina automáticamente a través del pc_alpha=None opción en tigramita). El objetivo no es controlar los falsos positivos aquí, sino retener a todos los padres verdaderos mientras se eliminan tantas variables irrelevantes como sea posible. Algunos falsos positivos en son aceptables; los falsos negativos no lo son.
Etapa 2: Prueba de independencia condicional momentánea (MCI)
Una vez que tengamos los conjuntos de padres estimados para todas las variables, la Etapa 2 prueba cada vínculo causal potencial utilizando la estadística MCI:
La innovación clave es el conjunto de acondicionamiento. Condicionamos a:
- Padres del objetivo : Esto elimina el efecto de los impulsores comunes y otras rutas indirectas hacia .
- Padres de la fuente : Esto elimina la autocorrelación de la variable fuente, evitando estadísticas de prueba infladas.
Al condicionar ambos conjuntos simultáneamente, MCI aísla efectivamente el efecto causal directo y momentáneo de en en el retraso específico , neto de todos los factores de confusión, mediadores y efectos de autocorrelación.
El estadístico de prueba puede ser cualquier prueba de independencia condicional válida. Para relaciones lineales, la correlación parcial es la opción estándar. Para dependencias no lineales, información mutua condicional (CMI) estimada mediante -Se pueden utilizar los métodos del vecino más cercano o la prueba GPDC (correlación de distancia del proceso gaussiano).
Correlación parcial como prueba predeterminada
Para la mayoría de las aplicaciones financieras, la prueba de correlación parcial (ParCorr en tigramita) es el caballo de batalla. Variables dadas , y un set de acondicionamiento , la correlación parcial es:
dónde y son los residuos de la regresión y en , respectivamente:
En otras palabras, la correlación parcial mide la asociación lineal entre y después de eliminar la influencia lineal de las variables condicionantes . Bajo la hipótesis nula de independencia condicional con datos gaussianos, el estadístico de prueba sigue una distribución conocida, lo que permite obtener resultados exactos. -cálculo del valor.
Los valores de correlación parcial se encuentran en y proporcionar una clasificación natural de las fortalezas de los vínculos causales. Una correlación parcial de 0,3 entre BTC en el retraso 1 y ETH en el retraso 0, condicionada a ambos conjuntos principales, significa: "Después de eliminar los efectos de todos los factores de confusión y la autocorrelación identificados, un impacto de una desviación estándar en los rendimientos de BTC predice un movimiento de 0,3 de desviación estándar en los rendimientos de ETH un período después".
De los resultados de la prueba a un gráfico causal (DAG)
La salida de PCMCI es un par de matrices:
- val_matrix: Forma , que contiene la estadística de prueba MCI (por ejemplo, correlación parcial) para cada enlace dirigido .
- p_matrix: Misma forma, conteniendo el correspondiente -valores.
Para construir un gráfico causal, ponemos un umbral -matriz a un nivel de significancia corregido:
Cuál corrección no es un detalle al que puedas saludar. pruebas PCMCI enlaces que son dependientes por construcción - cada enlace en comparte un conjunto de condicionamiento entre sí y, para empezar, las series fuente están mutuamente correlacionadas. Ése es precisamente el régimen donde falla la simple Benjamini-Hochberg y la armónica pena de Benjamini-Yekutieli. es el que sobrevive a la dependencia arbitraria entre pruebas; Sharpe desinflado y pruebas múltiples mide las tasas nulas de descubrimiento falso que hacen que esto sea concreto. Informe la cantidad de enlaces probados y el umbral corregido junto con cualquier gráfico que publique.
La estructura resultante es un gráfico de series de tiempo (TSG), que es un gráfico dirigido donde:
- Los nodos representan variables en desfases de tiempo específicos.
- Los bordes dirigidos representan vínculos causales con retrasos asociados.
- Los bucles automáticos representan efectos autorregresivos.
Este GTA se puede resumir en un gráfico resumido que muestra solo la existencia y dirección de vínculos causales entre variables (agregando entre rezagos), lo que a menudo es más práctico para la interpretación.
Implementación con Tigramite

Tigramita es la implementación de referencia de PCMCI, desarrollada y mantenida por el grupo de Jakob Runge en el Centro Aeroespacial Alemán (DLR). Proporciona una API limpia para el manejo de datos, múltiples pruebas de independencia condicional, varias variantes de PCMCI y visualización integrada.
Instalación
pip install tigramite
Verificación de cordura de recuperación (no es un resultado)
Antes de analizar los datos del mercado, vale la pena confirmar que el oleoducto encuentra una estructura que usted plantó. Esta es una prueba unitaria para la implementación y nada más: la verdad fundamental a continuación está escrita a mano en el ciclo de generación de datos, por lo que su recuperación demuestra que el código funciona y no dice nada en absoluto sobre las criptomonedas. Léelo de esa manera.
import numpy as np
import tigramite
from tigramite import data_processing as pp
from tigramite.pcmci import PCMCI
from tigramite.independence_tests.parcorr import ParCorr
from tigramite import plotting as tp
np.random.seed(42)
T, N = 2000, 5
var_names = ["BTC", "ETH", "SOL", "BNB", "AVAX"]
data = np.zeros((T, N))
noise = np.random.randn(T, N) * 0.5
for t in range(2, T):
data[t, 0] = 0.5 * data[t-1, 0] + noise[t, 0]
data[t, 1] = 0.5 * data[t-1, 1] + 0.4 * data[t-1, 0] + noise[t, 1]
data[t, 2] = 0.5 * data[t-1, 2] + 0.3 * data[t-1, 1] + noise[t, 2]
data[t, 3] = 0.5 * data[t-1, 3] + 0.25 * data[t-1, 0] + noise[t, 3]
data[t, 4] = 0.5 * data[t-1, 4] + 0.2 * data[t-2, 3] + noise[t, 4]
dataframe = pp.DataFrame(
data,
datatime=np.arange(T),
var_names=var_names,
)
parcorr = ParCorr(significance="analytic")
pcmci = PCMCI(
dataframe=dataframe,
cond_ind_test=parcorr,
verbosity=1,
)
results = pcmci.run_pcmci(
tau_max=4, # test lags up to 4 hours
tau_min=1, # only lagged (not contemporaneous) links
pc_alpha=None, # auto-select alpha for condition selection
alpha_level=0.01, # significance threshold for final MCI test
)
print("\n--- Significant causal links ---")
pcmci.print_significant_links(
p_matrix=results["p_matrix"],
val_matrix=results["val_matrix"],
alpha_level=0.01,
)
tp.plot_graph(
val_matrix=results["val_matrix"],
p_matrix=results["p_matrix"],
var_names=var_names,
link_colorbar_label="MCI (partial corr.)",
node_colorbar_label="Auto-MCI",
alpha_level=0.01,
figsize=(10, 6),
)
tp.plot_time_series_graph(
val_matrix=results["val_matrix"],
p_matrix=results["p_matrix"],
var_names=var_names,
link_colorbar_label="MCI (partial corr.)",
alpha_level=0.01,
figsize=(14, 6),
)
Leyendo el resultado
Sobre el VAR plantado, print_significant_links devuelve:
Variable BTC has 0 causal parent(s):
Variable ETH has 1 causal parent(s):
BTC (lag -1): val = 0.38, p = 0.000
Variable SOL has 1 causal parent(s):
ETH (lag -1): val = 0.28, p = 0.000
Variable BNB has 1 causal parent(s):
BTC (lag -1): val = 0.24, p = 0.000
Variable AVAX has 1 causal parent(s):
BNB (lag -2): val = 0.19, p = 0.000
La estructura plantada regresa, incluido el resultado negativo que importa: no hay una ventaja directa BTC -> SOL, a pesar de que BTC y SOL están fuertemente correlacionados en esta muestra. MCI atribuye la asociación íntegramente al mediador de ETH. Ése es el comportamiento que se supone que produce el conjunto de doble condicionamiento, y confirmarlo es el objetivo de este bloque. Es una prueba unitaria aprobada, no un hallazgo sobre las criptomonedas.
Trabajar con datos reales del mercado
PCMCI necesita insumos débilmente estacionarios, por lo que debe alimentarlo con rendimientos logarítmicos estandarizados en lugar de precios: la maquinaria ADF y las razones por las que los precios brutos fallan se tratan en arbitraje estadístico y comercio de pares. Una vez que tenga una matriz de rendimientos estandarizada, la parte específica de tigramite consta de dos líneas:
data = log_returns.values # (T, N) standardized log-returns
var_names = list(log_returns.columns)
dataframe = pp.DataFrame(data, var_names=var_names)
Dos detalles de tigramite no se trasladan del canal de retorno habitual:
- Datos faltantes: Tigramite admite matrices enmascaradas para manejar observaciones faltantes. Usar
dataframe.maskpara señalar lagunas, no las llene hacia adelante, ya que una observación fabricada se propaga a cada conjunto de condicionamiento que la contiene. - Alineación de frecuencia: todas las series deben ubicarse en la misma cuadrícula de tiempo. Para las criptomonedas, esto suele ser sencillo, ya que los intercambios proporcionan datos OHLCV sincronizados.
El estudio que necesita este método
Todo lo de arriba es maquinaria. El artículo no se puede publicar en este blog hasta que la maquinaria apunte a datos reales e informe lo que encontró, incluso si la respuesta es "nada estable". La carrera a hacer:
- Configuración: PCMCI+ en rendimientos por hora para una canasta real durante un rango de fechas establecido,
tau_maxarreglado por razonamiento de dominio,alpha_level = 0.01con corrección de Benjamini-Yekutieli en todos campo de golf. Informe el recuento de enlaces probados y el umbral corregido, según el Sharpe desinflado estándar. - Resultado a informar: qué aristas sobreviven a la corrección, sus magnitudes de correlación parcial y cuántas sobreviven fuera de la muestra.
- Al menos una medida de estabilidad, sin la cual la pieza es un README de tigramita con tickers criptográficos: qué fracción de bordes persisten de ventana a ventana a través de ventanas móviles; o sensibilidad del gráfico recuperado a
tau_maxypc_alpha; o desacuerdo entre ParCorr y CMIknn sobre los mismos datos.
Un gráfico inestable es un resultado publicable, no fallido. "PCMCI en cinco especialidades: el gráfico causal no sobrevive a las ventanas cambiantes" encaja con la línea en la que ya se encuentra este blog un resultado negativo honesto, y es un artículo más útil que un tutorial que funciona.
Elegir los parámetros correctos

Retraso máximo
Este parámetro limita el horizonte temporal del descubrimiento causal. Si lo ajustas a un nivel demasiado bajo, es posible que se pierdan efectos de propagación lenta; demasiado alto aumenta el costo computacional y la carga de pruebas múltiples.
Para datos criptográficos por horas, a es un rango razonable. Para datos diarios, a captura la mayoría de las relaciones de avance-retraso. El conocimiento del dominio es importante aquí: si sabe que los efectos de la tasa de financiación tardan 8 horas en propagarse, establezca .
Importancia de la selección de condiciones
Configuración pc_alpha=None permite que tigramite seleccione automáticamente este parámetro utilizando el criterio de información de Akaike, que es el valor predeterminado recomendado. Si desea configurarlo manualmente, los valores entre 0,1 y 0,4 funcionan bien. Los valores más bajos hacen que la Etapa 1 sea más agresiva (se retienen menos padres), lo que reduce el costo computacional pero corre el riesgo de eliminar a los verdaderos padres.
Nivel de significancia final
Este es el umbral estándar de prueba de hipótesis. Para el análisis exploratorio, está bien. Para cualquier cosa que alimente una decisión comercial, utilice o más estricto, y aplíquelo después de la corrección consciente de la dependencia descrita anteriormente: el nivel nominal no es el nivel en el que realmente está realizando la prueba.
PCMCI+: Agregar enlaces contemporáneos

PCMCI estándar sólo descubre vínculos causales retrasados (). Pero en los mercados de criptomonedas, donde la información se propaga a través de los activos en segundos, la frecuencia de muestreo cada hora significa que muchos efectos causales parecen contemporáneos ().
PCMCI+ (Runge, 2020) amplía PCMCI para descubrir vínculos causales tanto rezagados como contemporáneos. Los enlaces contemporáneos no están dirigidos por defecto (dado que el orden temporal no puede distinguir la causa del efecto dentro del mismo lapso de tiempo), pero algunos pueden orientarse usando las reglas de orientación del algoritmo estándar de PC (detección de colisionador, restricciones de aciclicidad).
results_plus = pcmci.run_pcmciplus(
tau_max=4,
tau_min=0, # include contemporaneous links
pc_alpha=None,
)
Para aplicaciones criptográficas con una frecuencia horaria o menor, PCMCI+ suele ser más apropiado que PCMCI estándar, ya que muchos efectos cruzados de activos ocurren más rápido que el intervalo de muestreo.
Extensiones no lineales

Las series de tiempo financieras a menudo exhiben dependencias no lineales (por ejemplo, agrupaciones de volatilidad, efectos de adelanto y retraso dependientes del régimen). Tigramite proporciona varias pruebas de independencia condicional no lineales:
Correlación de distancia del proceso gaussiano (GPDC)
from tigramite.independence_tests.gpdc import GPDC
gpdc = GPDC(significance="analytic", gp_params=None)
pcmci = PCMCI(dataframe=dataframe, cond_ind_test=gpdc)
GPDC utiliza el proceso de regresión gaussiano para eliminar la influencia del conjunto de condicionamiento y luego aplica la correlación de distancia en los residuos. Es más poderoso que ParCorr para detectar efectos no lineales pero significativamente más lento.
Información mutua condicional (CMIknn)
from tigramite.independence_tests.cmiknn import CMIknn
cmiknn = CMIknn(significance="shuffle_test", knn=0.1, shuffle_neighbors=5)
pcmci = PCMCI(dataframe=dataframe, cond_ind_test=cmiknn)
CMIknn estima información mutua condicional utilizando -Métodos del vecino más cercano. Es completamente no paramétrico y puede detectar dependencias funcionales arbitrarias. La compensación es el costo computacional y la necesidad de más datos para lograr poder estadístico.
Para la mayoría de las aplicaciones de comercio de criptomonedas, comience con ParCorr. Cambie a pruebas no lineales sólo cuando tenga evidencia específica de mecanismos causales no lineales y datos suficientes (normalmente ).
Dónde se conectaría un gráfico causal

Una cosa que le brinda un gráfico causal que una matriz de correlación no puede: fuera de grado. Ejecute PCMCI en entre 20 y 50 activos y los nodos con muchas ventajas salientes serán líderes en información: sus movimientos conllevan contenido predictivo para el resto del libro, y esa es una afirmación direccional que una matriz de correlación simétrica es estructuralmente incapaz de hacer. Una descomposición de factores le indica que BTC domina la varianza; una clasificación de grado superior le indica si BTC domina porque lidera o porque todo, incluido BTC, se carga en el mismo shock macro.
Suponiendo que alguna vez se recupere un gráfico estable, los lugares donde se adjuntaría para trabajar ya en este blog son bastante claros. Los cambios de ventana móvil en la topología del gráfico son una señal de ruptura estructural, que es objeto de detección de régimen con HMM — la pregunta abierta es si un gráfico causal detecta la transición antes que un modelo de estado. La aplicación de PCMCI a un activo en todos los lugares aborda el liderazgo en precios entre lugares, que ya se mide con una resolución de milisegundos en enrutamiento inteligente de pedidos; un gráfico de barras horarias tendría que superar eso, no reformularlo. Y el vínculo periódico entre el delincuente y el lugar creado por el mecanismo de financiación de 8 horas, cubierto en arbitraje de tasa de financiación, es un caso de prueba de respuesta conocida: PCMCI debería recuperar una estructura causal que podamos verificar de forma independiente, lo que la convierte en un objetivo de validación en lugar de un descubrimiento.
Ninguno de estos son hallazgos. Son hipótesis a la espera del estudio descrito anteriormente.
Limitaciones y advertencias

PCMCI es una herramienta poderosa, pero tiene limitaciones importantes que los profesionales deben comprender:
-
Supuesto de suficiencia causal: PCMCI supone que se observan todas las variables relevantes. Si un factor común oculto (por ejemplo, la actividad comercial de una ballena, noticias no publicadas) afecta a dos activos observados, PCMCI puede informar incorrectamente un vínculo causal directo entre ellos. La variante LPCMCI soluciona esto parcialmente al permitir factores de confusión latentes, a costa de devolver menos bordes orientados.
-
Supuesto de estacionariedad: la estructura causal se supone constante a lo largo de la ventana de análisis. En la práctica, la dinámica del mercado criptográfico cambia rápidamente. Utilice el análisis de ventana móvil para detectar roturas estructurales.
-
Lineal versus no lineal: Con
ParCorr, sólo se detectan efectos causales lineales. Un mecanismo causal no lineal (por ejemplo, "BTC hace que ETH caiga sólo cuando BTC cae más del 5%") sería invisible para la prueba lineal. -
La frecuencia de muestreo importa: los efectos causales que ocurren más rápido que la frecuencia de muestreo aparecen como contemporáneos () enlaces en PCMCI estándar, y su dirección puede ser ambigua. Utilice PCMCI+ y considere datos de mayor frecuencia.
-
Pruebas múltiples: pruebas dependientes, corregidas como se describe anteriormente; consulte Sharpe desinflado y pruebas múltiples explica por qué la estructura de dependencia descarta la elección obvia.
-
Requisitos de tamaño de muestra: el descubrimiento causal confiable requiere datos suficientes. Como pauta aproximada, apunte a para
ParCorrcon variables, y para pruebas no lineales o conjuntos de variables más grandes.
PCMCI frente a otros métodos

| Método | Maneja la autocorrelación | Maneja controladores comunes | Enlaces contemporáneos | No lineal | Factores de confusión latentes |
|---|---|---|---|---|---|
| Causalidad de Granger | En parte | No (bivariado) | No | Con extensiones | No |
| Transferir entropía | En parte | No (bivariado) | No | Sí | No |
| PCMCI | Sí (MCI) | Sí | No | Con CMIknn/GPDC | No |
| PCMCI+ | Sí | Sí | Sí | Con CMIknn/GPDC | No |
| LPCMCI | Sí | Sí | Sí | Con CMIknn/GPDC | Sí |
| VAR-LiNGAM | No | Sí | Sí | No | No |
La principal ventaja del PCMCI sobre la causalidad de Granger y la entropía de transferencia es la prueba MCI, que tiene en cuenta correctamente la autocorrelación y los factores comunes en un entorno multivariado. Este es precisamente el escenario que se encuentra en los mercados de criptomonedas, donde docenas de activos correlacionados y autocorrelacionados interactúan simultáneamente.
Conclusión

La construcción en dos etapas es la contribución que vale la pena sacar: selección de condiciones dispersas para limitar el conjunto principal, luego una prueba de MCI cuyo conjunto condicionante incluye los padres de la fuente así como el objetivo. Esa segunda mitad es lo que separa a PCMCI de Granger y la entropía de transferencia, y es lo que hace que el método sea viable en series tan autocorrelacionadas como los retornos criptográficos.
Lo que el método no trae es evidencia. Un gráfico recuperado es una hipótesis sobre el flujo de información, no una señal, y en este blog no cuenta para nada hasta que se haya ejecutado con datos reales con una cesta establecida, un rango de fechas establecido, una corrección consciente de la dependencia y al menos una medición de si el gráfico se mantiene quieto cuando se mueve la ventana. Hasta que exista esa ejecución, trate todo lo que aparece aquí como herramientas.
Si el gráfico resulta no ser estable, ese es el artículo. No sería el primer resultado negativo que valga más que un tutorial práctico.
Referencias
- Runge, J., Nowack, P., Kretschmer, M., Flaxman, S. y Sejdinovic, D. (2019). Detectar y cuantificar asociaciones causales en grandes conjuntos de datos de series temporales no lineales. Avances científicos, 5(11), eau4996.
- Runge, J. (2020). Descubrir relaciones causales contemporáneas y rezagadas en conjuntos de datos de series temporales no lineales autocorrelacionadas. Actas de la 36ª Conferencia sobre Incertidumbre en Inteligencia Artificial (UAI), PMLR 124:1388-1397.
- Documentación de Tigramite: https://jakobrunge.github.io/tigramite/
- Repositorio de Tigramite GitHub: https://github.com/jakobrunge/tigramite
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.