PINE LIBRARY
Aktualisiert

CyberCausalityLib

200
# CyberCausalityLib v17

CyberCausalityLib provides information-theoretic and econometric causality detection for identifying directional influence between price series, filtering spurious correlations, and detecting lead-lag relationships across assets.

## What it does

Delivers 15+ causality functions in three categories: Transfer Entropy (information-theoretic directional causality), Granger Causality (econometric lagged correlation), and PCMCI filtering (partial correlation mediation for spurious causality detection). Answers questions like "Does Bitcoin volume predict Ethereum price?" and "Is Asset A→B correlation direct or mediated by Asset C?"

Outputs causality scores, directional indicators, and optimal lag values for multi-basket aggregation, lead-lag pair trading, and filtering false correlations driven by common factors.

## How it works

Transfer Entropy measures directional information flow: `TE(X→Y) = H(Y_t | Y_{t-1}) - H(Y_t | Y_{t-1}, X_{t-lag})` using Shannon entropy. Discretizes price data into 4-8 bins, calculates joint/conditional entropies. Higher TE = X predicts future Y beyond Y's own history.

Granger Causality aggregates lagged correlations: `Granger = Σ(w_i × corr(Y_t, X_{t-i}))` with weights `w_i = |corr_i| / Σ|corr_j|`. Supports Pearson/Spearman/Kendall. Returns magnitude + directional coefficient.

PCMCI filtering detects spurious causality via partial correlation: `ρ(X,Y|Z)`. If partial << raw correlation, Z mediates X→Y (indirect causality). Reduces score proportionally.

## Why this is original

First TradingView library with information-theoretic causality. Pine has no native entropy, Granger tests, or partial correlation. Existing libraries offer only basic correlation without directionality or lag optimization.

Unique features:
- Transfer Entropy with Shannon entropy discretization
- Granger Causality with auto-lag search (1-10)
- PCMCI filtering (up to 4 mediators)
- Ensemble aggregation (5 baskets)
- Möbius transformation state tracking

No other Pine library combines information theory, econometrics, and graph-based causality with NA guards and graceful degradation.

## How to use it

```pine
//version=6
indicator("CyberCausalityLib Demo", overlay=false)
import cybermediaboy/CyberCausalityLib/17 as C
import cybermediaboy/NumLib/4 as N

// Transfer Entropy: Does volume predict price?
var price_buf = array.new<float>()
var vol_buf = array.new<float>()

if bar_index >= 99
array.clear(price_buf)
array.clear(vol_buf)
for i = 0 to 99
array.push(price_buf, close[99-i])
array.push(vol_buf, volume[99-i])

[te_score, te_dir] = C.f_calculate_te_score_v2(
price_buf, vol_buf, 100, 5, 2
)
// te_score > 0.15 → volume predicts price
plot(te_score, "TE Score", color.blue)

// Granger Causality: Lead-lag detection
var x_buf = array.new<float>()
var y_buf = array.new<float>()
// ...populate buffers...
[granger, beta, lag] = C.f_calculate_granger_score(
y_buf, x_buf, 100, 5, "Pearson"
)
// granger > 0.3 → X Granger-causes Y

// PCMCI Filtering: Remove spurious correlation
[raw, _, _] = C.f_calculate_granger_score(y_buf, x_buf, 100, 5, "Pearson")
filtered = C.f_pcmci_filter_score(
raw, y_buf, x_buf, mediator_buf,
array.new<float>(), array.new<float>(), array.new<float>(), 100
)
// filtered << raw → indirect causality
```

## Key functions

- `f_calculate_te_score_v2()` - Transfer Entropy (recommended)
- `f_calculate_granger_score()` - Granger Causality with lag search
- `f_pcmci_filter_score()` - Spurious correlation filtering
- `f_compute_te_ensemble()` - Multi-basket aggregation
- `f_shannon_entropy()` - Shannon entropy calculation
- `MobiusState` UDT - Non-linear state tracking

## Dependencies

Requires NumLib v4 for correlation functions (Pearson/Spearman/Kendall).

```pine
import cybermediaboy/CyberCausalityLib/17 as C
import cybermediaboy/NumLib/4 as N
```

## Version history

- **v17** (2026-04-17): Added HAR-RV forecast, Durbin-Watson autocorrelation test, PCA explained variance, improved entropy discretization (v2 algorithm)
- **v16** (2026-03-xx): Added PCMCI filtering, Möbius state tracking UDT
- **v15** (2026-02-xx): Added Granger causality, multi-lag search, correlation at lag
- **v14** (2026-01-xx): Initial release with Transfer Entropy, ensemble aggregation

## License

Mozilla Public License 2.0

## Author

© cybermediaboy

## Support

For questions, bug reports, or feature requests, comment on the library publication page or reference the source code documentation.
Versionshinweise
v2

Added:
f_lcg_next(state)
  Parameters:
    state (int)

f_block_shuffle(x, block_len, seed)
  Parameters:
    x (array<float>)
    block_len (int)
    seed (int)

f_calculate_ete(primary_arr, ticker_arr, window, bins, lag, n_shuf, block_len, seed_base)
  Parameters:
    primary_arr (array<float>)
    ticker_arr (array<float>)
    window (int)
    bins (int)
    lag (int)
    n_shuf (int)
    block_len (int)
    seed_base (int)

f_calculate_ete_multilag(primary_arr, ticker_arr, window, bins, max_lag, n_shuf, block_len, z_threshold, seed_base)
  Parameters:
    primary_arr (array<float>)
    ticker_arr (array<float>)
    window (int)
    bins (int)
    max_lag (int)
    n_shuf (int)
    block_len (int)
    z_threshold (float)
    seed_base (int)

f_calculate_ete_gated(primary_arr, ticker_arr, window, bins, max_lag, coupling_damping, coupling_floor, n_shuf, block_len, z_threshold, seed_base)
  Parameters:
    primary_arr (array<float>)
    ticker_arr (array<float>)
    window (int)
    bins (int)
    max_lag (int)
    coupling_damping (float)
    coupling_floor (float)
    n_shuf (int)
    block_len (int)
    z_threshold (float)
    seed_base (int)

f_calculate_net_ete(primary_arr, ticker_arr, window, bins, lag, n_shuf, block_len, seed_base)
  Parameters:
    primary_arr (array<float>)
    ticker_arr (array<float>)
    window (int)
    bins (int)
    lag (int)
    n_shuf (int)
    block_len (int)
    seed_base (int)

f_ete_state_new()

f_ete_state_decay(s, decay_per_bar)
  Parameters:
    s (EteState)
    decay_per_bar (float)

f_ete_state_update(ete_new, z_new, dir_new, lag_new)
  Parameters:
    ete_new (float)
    z_new (float)
    dir_new (float)
    lag_new (int)

f_ete_regime(z, z_marginal, z_strong)
  Parameters:
    z (float)
    z_marginal (float)
    z_strong (float)

EteResult
  Fields:
    ete (series float): Effective TE = TE_obs - <TE_surrogate> (bias-corrected)
    z (series float): Bootstrap z-score = (TE_obs - mean_surr) / std_surr
    dir (series float): Sign from Pearson at best lag (-1 / +1)
    lag (series int): Argmax-|ETE| lag selected
    te_raw (series float): Pre-correction plug-in TE (for diagnostics)
    surr_mu (series float): Surrogate mean (bias estimate)
    surr_sd (series float): Surrogate std (significance scale)
    signif (series bool): True if |z| >= z_threshold

EteState
  Fields:
    ete_held (series float)
    z_held (series float)
    dir_held (series float)
    lag_held (series int)
    bars_since_recomp (series int)
Versionshinweise
v3
Versionshinweise
v4
Versionshinweise
v5
Versionshinweise
v6
Versionshinweise
v7

Updated:
f_discretize(data, bins)
  Discretize continauous data into bins (for entropy calculations)
  Parameters:
    data (array<float>): Array of continuous values
    bins (int): Number of bins
  Returns: Array of bin indices
Versionshinweise
v8

Added:
f_rate_return(price, price_prev, invert)
  Convert SOFR/rate futures price to implied rate return
  Parameters:
    price (float): Current close price of rate futures (e.g., SR3M = 96.38)
    price_prev (float): Previous bar close
    invert (bool): If true, rate = 100 - price (SOFR convention). If false, pass through.
  Returns: Rate return in bps (first difference of implied rate)

f_bar_is_live(bar_range, abs_ret, range_ma, ret_ma, range_pct, ret_pct)
  Classify bar as live (active trading) or stale (flat/illiquid)
  Parameters:
    bar_range (float): Current bar high - low
    abs_ret (float): Absolute return |close - close[1]|
    range_ma (float): EMA of bar_range (caller provides; typically ema(range, 20))
    ret_ma (float): EMA of abs_ret (caller provides; typically ema(abs_ret, 20))
    range_pct (float): Minimum fraction of range_ma to qualify as live (default 0.05)
    ret_pct (float): Minimum fraction of ret_ma to qualify as live (default 0.10)
  Returns: true if bar is actively traded, false if stale

f_carry_forward(src, is_live)
  Carry-forward filter: returns src on live bars, last valid value on stale bars
  Parameters:
    src (float): Input series value
    is_live (bool): Activity flag from f_bar_is_live
  Returns: src if live, last valid src otherwise (preserves time index for TE lag alignment)

f_adaptive_wilder(src, alpha_fast, alpha_slow, is_live)
  Adaptive Wilder smoother: updates fast on live bars, slow on stale bars
  Parameters:
    src (float): Input value
    alpha_fast (float): Alpha for live bars (e.g., 2/(fast_win+1))
    alpha_slow (float): Alpha for stale bars (e.g., 2/(slow_win*4+1)); near-zero = freeze
    is_live (bool): Activity flag from f_bar_is_live
  Returns: Smoothed value that ignores dead-zone contamination

f_variance_ok(src_var, var_floor)
  Check if a series has enough variance for meaningful TE/Granger computation
  Parameters:
    src_var (float): Rolling variance of the input series (caller provides: ta.variance(src, win))
    var_floor (float): Minimum variance to allow TE update (default 1e-8)
  Returns: true if variance is sufficient for TE/Granger computation

f_gated_correlation(x, y, win, src_var, var_floor)
  Variance-gated correlation: computes ta.correlation only when source has enough variance.
On insufficient variance, returns last valid correlation (carry-forward).
  Parameters:
    x (float): Series X (e.g., F1[lag_vix])
    y (float): Series Y (e.g., btc_ret)
    win (int): Correlation window length
    src_var (float): Rolling variance of x (caller provides: ta.variance(x, win))
    var_floor (float): Minimum variance threshold (default 1e-8)
  Returns: Correlation coefficient with carry-forward on low-variance bars

f_live_push(buf, val, is_live, max_size)
  Push value to TE array only on live bars (stale bars skipped entirely).
Preserves distribution quality for TE joint histogram — stale bars don't
contribute zero-change entries that pull distribution toward diagonal.
  Parameters:
    buf (array<float>): Target array for TE computation
    val (float): Value to push (typically z-score or rate return)
    is_live (bool): Activity flag from f_bar_is_live
    max_size (int): Maximum buffer size (trim oldest when exceeded)
  Returns: Current buffer size after operation

f_calculate_te_score_robust(primary_arr, ticker_arr, live_mask, window, bins, lag, min_live_pct)
  TE score with dead-bar exclusion. Filters ticker_arr to include
only bars marked live (parallel boolean mask). Reduces effective n but
prevents zero-variance contamination of the 3D contingency table.
  Parameters:
    primary_arr (array<float>): Target series (e.g., BTC returns)
    ticker_arr (array<float>): Source series (e.g., factor z-scores)
    live_mask (array<float>): Parallel array: 1.0 if live, 0.0 if stale (same length as ticker_arr)
    window (int): TE window size
    bins (int): Number of discretization bins
    lag (int): Source series lag
    min_live_pct (float): Minimum fraction of live bars in window required (0.3 = 30%)
  Returns: [te_score, direction] — 0.0 if insufficient live bars

f_calculate_te_gated_robust(primary_arr, ticker_arr, live_mask, window, bins, max_lag, coupling_damping, coupling_floor, min_live_pct)
  Robust gated TE multilag with dead-bar filtering.
Drop-in replacement for f_calculate_te_gated that adds live_mask filtering.
  Parameters:
    primary_arr (array<float>): Target series (BTC returns)
    ticker_arr (array<float>): Source series (factor z-scores)
    live_mask (array<float>): Parallel activity mask (1.0=live, 0.0=stale)
    window (int): TE window size
    bins (int): Discretization bins
    max_lag (int): Maximum lag to scan
    coupling_damping (float): Coupling strength (volatility proxy)
    coupling_floor (float): Minimum coupling to allow TE through
    min_live_pct (float): Minimum live fraction required (default 0.3)
  Returns: [gated_te, direction, best_lag]

f_symbolize(ret, threshold)
  Symbolize a return value into 3 states: -1 (down), 0 (dead), +1 (up)
  Parameters:
    ret (float): Return or rate change value
    threshold (float): Minimum magnitude to register as non-zero (dead-zone width)
  Returns: -1, 0, or +1

f_effective_n(sym_arr)
  Count effective (non-zero) symbols in a symbolized array.
Used to determine if TE has enough live data after dead-zone exclusion.
  Parameters:
    sym_arr (array<int>): Array of symbolized values (-1, 0, +1)
  Returns: Count of non-zero entries (effective sample size for TE)

Versionshinweise
v9
Versionshinweise
v10

Haftungsausschluss

Die Informationen und Veröffentlichungen sind nicht als Finanz-, Anlage-, Handels- oder andere Arten von Ratschlägen oder Empfehlungen gedacht, die von TradingView bereitgestellt oder gebilligt werden, und stellen diese nicht dar. Lesen Sie mehr in den Nutzungsbedingungen.