"""BTC Ensemble — Enhanced + PriceMomentum + GaussianCycle (75/15/10).

Three complementary models:

  Enhanced (75%):     regime-based signals, best in orderly markets
  PriceMom (15%):     pure price momentum, correction insurance (corr=-0.60)
  GaussianCycle (10%): Ehlers cycle filter, zero time decay (corr=-0.20)

The GaussianCycle component adds a new uncorrelated signal source.
Its key property is zero IC time decay (+0.01) — unique among all models.
While its standalone IC (+0.035) is modest, it fills the gap where
Enhanced decays (F3-F4) without the negative IC risk of PriceMomentum.

Walk-forward validation (4 rolling 60d folds, 1d horizon, BTC):
  Enhanced:           IC=+0.102  IR=1.23  Decay=-0.98
  AdaptiveEnsemble:   IC=+0.077  IR=1.16  Decay=-0.56
  GaussianCycle:      IC=+0.035  IR=0.74  Decay=+0.01

Correlation with Enhanced:
  PriceMomentum:  -0.60  (strong anti-correlation)
  GaussianCycle:  -0.20  (mild anti-correlation)
"""

from __future__ import annotations

from vanta.tracker import TrackerBase
from vanta.examples.enhanced_tracker import EnhancedTracker
from vanta.examples.price_momentum_tracker import PriceMomentumTracker
from vanta.examples.gaussian_cycle_tracker import GaussianCycleTracker


class BTCEnsembleTracker(TrackerBase):
    """75/15/10 blend of Enhanced + PriceMomentum + GaussianCycle.

    Args:
        enhanced_weight: Weight for Enhanced signal (default 0.75).
        momentum_weight: Weight for PriceMomentum signal (default 0.15).
        gaussian_weight: Weight for GaussianCycle signal (default 0.10).
    """

    def __init__(
        self,
        enhanced_weight: float = 0.75,
        momentum_weight: float = 0.15,
        gaussian_weight: float = 0.10,
    ):
        super().__init__()
        self._enhanced = EnhancedTracker()
        self._pricemom = PriceMomentumTracker()
        self._gaussian = GaussianCycleTracker()
        self._w_e = enhanced_weight
        self._w_p = momentum_weight
        self._w_g = gaussian_weight

    def tick(self, data: dict) -> None:
        super().tick(data)
        self._enhanced.tick(data)
        self._pricemom.tick(data)
        self._gaussian.tick(data)

    def predict(self, symbol: str, horizon_seconds: int, step_seconds: int) -> dict:
        er_e = self._enhanced.predict(symbol, horizon_seconds, step_seconds).get("expected_return", 0.0)
        er_p = self._pricemom.predict(symbol, horizon_seconds, step_seconds).get("expected_return", 0.0)
        er_g = self._gaussian.predict(symbol, horizon_seconds, step_seconds).get("expected_return", 0.0)

        blended = self._w_e * er_e + self._w_p * er_p + self._w_g * er_g
        return {"expected_return": blended}
