corr_pair = np.array([[1.0, 0.7], [0.7, 1.0]])
common_params = {
"min_length": 2000,
"max_length": 2000,
"freq": "D",
"correlation_matrix": corr_pair,
"marginal_distributions": [
{"type": "normal", "loc": 0.0, "scale": 1.0},
{"type": "normal", "loc": 0.0, "scale": 1.0},
],
"seed": 123,
}
gen_gauss_pair = CopulaGenerator(
engine="polars", copula_type="gaussian", **common_params
)
gen_t = CopulaGenerator(engine="polars", copula_type="t", df=3.0, **common_params)
wide = {}
for name, gen in [("gaussian", gen_gauss_pair), ("t", gen_t)]:
df_pair = gen.generate(n_series=2)
w = df_pair.pivot(on="unique_id", index="ds", values="y")
cols = sorted(c for c in w.columns if c != "ds")
wide[name] = (w[cols[0]].to_numpy(), w[cols[1]].to_numpy())
q = 0.05
print(f"Same specified correlation (0.7), joint {q:.0%}-tail behavior:\n")
for name, (x, y) in wide.items():
pearson = np.corrcoef(x, y)[0, 1]
lo = np.mean((x <= np.quantile(x, q)) & (y <= np.quantile(y, q)))
hi = np.mean((x >= np.quantile(x, 1 - q)) & (y >= np.quantile(y, 1 - q)))
cond = (lo + hi) / (2 * q)
print(
f" {name:8s} copula: correlation {pearson:.2f}, "
f"P(other channel also in its {q:.0%} tail) = {cond:.0%}"
)
print(f"\n independent channels would give {q:.0%}")