Files
bitcoin-model/btcmodel/models/__init__.py
T
sam b0243adf61 Composable models and A/B tests of the 2024 ideas; add powerlaw.
Models are now a Composite of drift, volatility and (optional) shape
components, so an experiment can swap one part against a fixed control.

btcmodel/experiments.py holds seven experiments built from the ideas in the
old branches (catalogued in docs/2024-ideas.md), each with its hypothesis
and source, and a verdict rule fixed before anything ran. `just ab` runs
them on development data. Results:

- Shrinking the cycle drift, and a power-law trend (plain or reverting),
  beat their controls. The power law beats the random walk by 53-63% at
  3-4 years with unbiased outcomes, so it is promoted to MODELS.
- Every alternative volatility estimate (EWMA blends, other windows,
  reversion to a level or trend) is worse than the trailing 365-day window.
  Cycle-dependent volatility, heavy tails and stretched cycle phase show no
  reliable effect.
2026-09-24 03:01:46 -07:00

31 lines
1.1 KiB
Python

"""
Candidate models.
A model is any object with a `name` and a
`forecast(history: pd.DataFrame, horizons: np.ndarray) -> Forecast` method.
`history` holds every row up to and including the forecast origin and nothing
after it; the harness guarantees that, so models can use all of it freely.
Most models are a Composite of a drift and a volatility component.
"""
from .base import Composite
from .drift import CycleDrift, PowerLawDrift, TrailingMeanDrift, ZeroDrift
from .volatility import TrailingVol
BASELINE = "random_walk"
# Order is fixed: it sets each model's colour in every chart.
MODELS = {
m.name: m
for m in (
# "It stays about here, give or take."
Composite(BASELINE, ZeroDrift(), TrailingVol()),
# "It keeps doing what it did last cycle."
Composite("drift_rw", TrailingMeanDrift(), TrailingVol()),
# The 2024 model, distilled.
Composite("cycle", CycleDrift(), TrailingVol()),
# "Growth keeps slowing, like it always has." Passed the diminishing-returns A/B.
Composite("powerlaw", PowerLawDrift(), TrailingVol()),
)
}