34 lines
1.4 KiB
Python
34 lines
1.4 KiB
Python
"""Full-sample and LEFT-TAIL correlation. Left-tail = correlation on the book's worst days (crisis-relevant)."""
|
|
from __future__ import annotations
|
|
|
|
import numpy as np
|
|
|
|
from fxhnt.domain.diversification.correlation import full_correlation, left_tail_correlation
|
|
|
|
|
|
def test_full_correlation_aligned() -> None:
|
|
a = np.array([1.0, -1.0, 2.0, -2.0, 0.5])
|
|
assert abs(full_correlation(a, a) - 1.0) < 1e-9
|
|
assert abs(full_correlation(a, -a) + 1.0) < 1e-9
|
|
|
|
|
|
def test_left_tail_picks_book_worst_days() -> None:
|
|
# book: last two days are the worst; sleeve co-moves ONLY on those days -> high left-tail corr,
|
|
# near-zero full-sample corr.
|
|
rng = np.random.default_rng(0)
|
|
n = 200
|
|
book = rng.normal(0, 0.01, n)
|
|
book[-2:] = [-0.05, -0.06] # crisis days
|
|
sleeve = rng.normal(0, 0.01, n)
|
|
sleeve[-2:] = [-0.05, -0.07] # sleeve crashes WITH the book
|
|
lt = left_tail_correlation(sleeve, book, tail_frac=0.02) # worst ~4 days
|
|
fs = full_correlation(sleeve, book)
|
|
assert lt > 0.5 # co-moves in the tail
|
|
assert lt > fs # tail corr exceeds full-sample (the crisis-hiding case)
|
|
|
|
|
|
def test_left_tail_unestimable_returns_nan() -> None:
|
|
book = np.array([0.01, 0.02]) # too few days for a tail
|
|
sleeve = np.array([0.0, 0.0])
|
|
assert np.isnan(left_tail_correlation(sleeve, book, tail_frac=0.1))
|