Skip to content

Strategies

This is the canonical strategy catalog for StackSats built-ins. The published page is generated from the in-repo strategy catalog.

Built-in support tier is defined by catalog metadata, not by the implementation module path. For the maintainer workflow that adds new cataloged strategies, use Add a Built-in Strategy.

Use this page for:

  • built-in behavior and intent mode
  • model card links, owners, and promotion stage
  • required feature sets/columns
  • exposed tuning parameters and defaults
  • canonical validate/backtest/audit commands
  • reasonableness expectations when interpreting model results
  • support tier for stable versus experimental reference strategies

Model cards for all cataloged built-ins:

Purpose and Scope

Framework boundary (canonical):

  • User strategy code owns feature transforms, signal formulas, and allocation intent.
  • Framework runtime owns feature sourcing/materialization, window iteration, clipping, lock semantics, and final invariants.

See Framework Boundary for the full contract.

Global Strategy Contract

All strategy hooks are Polars-only:

  • transform_features(...) -> pl.DataFrame
  • build_signals(...) -> dict[str, pl.Series]
  • propose_weight(state) -> float or build_target_profile(...) -> TargetProfile | pl.DataFrame

Data shape contract:

  • strategy-facing frames use canonical date columns (no index semantics)
  • TargetProfile.values payload must be date + value
  • runtime rejects ambiguous dual-hook strategies unless intent_preference is set explicitly

Canonical Dataset and Scoring Window

Dataset flow:

  • Canonical source dataset is long-format merged_metrics*.parquet (day_utc, metric, value)
  • Runtime commands consume a derived BRK-wide parquet via STACKSATS_ANALYTICS_PARQUET, managed default ~/.stacksats/data/bitcoin_analytics.parquet, or legacy local fallback ./bitcoin_analytics.parquet
  • Canonical schema: Merged Metrics Parquet Schema
  • Projection workflow: BRK Data Source

Scoring defaults used by runtime and strategy audits:

  • default backtest start: 2018-01-01
  • default backtest end: 2025-12-31 (or earlier if data coverage ends sooner)
  • feature warmup history is included by default; scored windows still begin at the requested start_date

Stable Supported Built-ins

These strategies are part of the stable 1.x contract because their catalog entries are marked tier=stable. Stable built-in strategy IDs: uniform, run-daily-paper, simple-zscore, momentum, mvrv.

Strategy strategy_id Model card Tier Promotion Family Owner Benchmarks Import spec Intent mode Required feature sets Required columns Configurable params (defaults) Validation defaults Backtest defaults Description / use case
UniformStrategy uniform card stable promoted baseline StackSats Maintainers none stacksats.strategies.stable.baselines.uniform:UniformStrategy propose core_model_features_v1 none none min_win_rate=50.0, strict=True start_date='2018-01-01', end_date='2025-12-31' Uniform baseline allocation across each window. Tags: baseline, sanity-check.
RunDailyPaperStrategy run-daily-paper card stable promoted baseline StackSats Maintainers uniform stacksats.strategies.stable.baselines.run_daily_paper:RunDailyPaperStrategy propose core_model_features_v1 none none min_win_rate=0.0, strict=False start_date='2018-01-01', end_date='2025-12-31' Canonical agent-facing daily decision example with relaxed daily validation defaults. Tags: agent, daily, paper.
SimpleZScoreStrategy simple-zscore card stable promoted signal StackSats Maintainers uniform, mvrv stacksats.strategies.stable.signals.simple_zscore:SimpleZScoreStrategy profile core_model_features_v1 none none min_win_rate=50.0, strict=True start_date='2018-01-01', end_date='2025-12-31' Preference tilts toward lower mvrv_zscore values. Tags: toy, profile, value.
MomentumStrategy momentum card stable promoted signal StackSats Maintainers uniform, mvrv stacksats.strategies.stable.signals.momentum:MomentumStrategy profile core_model_features_v1 price_usd none min_win_rate=50.0, strict=True start_date='2018-01-01', end_date='2025-12-31' Contrarian 30-day momentum preference model. Tags: toy, profile, momentum.
MVRVStrategy mvrv card stable promoted mvrv StackSats Maintainers uniform stacksats.strategies.stable.mvrv.core:MVRVStrategy profile core_model_features_v1 price_vs_ma, mvrv_zscore, mvrv_gradient, mvrv_percentile, mvrv_acceleration, mvrv_zone, mvrv_volatility, signal_confidence none min_win_rate=50.0, strict=True start_date='2018-01-01', end_date='2025-12-31' Core package MVRV and MA preference model. Tags: baseline, mvrv, production.

Experimental Reference Strategies

These strategies are cataloged as tier=experimental and are not part of the stable 1.x contract. Their current implementation modules may live under stacksats.strategies.experimental.*, but support status comes from the catalog entry. Experimental built-in strategy IDs: example-mvrv, mvrv-plus.

Strategy strategy_id Model card Tier Promotion Family Owner Benchmarks Import spec Intent mode Required feature sets Required columns Configurable params (defaults) Validation defaults Backtest defaults Description / use case
ExampleMVRVStrategy example-mvrv card experimental research overlay StackSats Maintainers uniform, mvrv stacksats.strategies.experimental.overlays.example_mvrv:ExampleMVRVStrategy profile core_model_features_v1, brk_overlay_v1 price_vs_ma, mvrv_zscore, mvrv_gradient, mvrv_percentile, mvrv_acceleration, mvrv_zone, mvrv_volatility, signal_confidence, brk_netflow_fast, brk_netflow_slow, brk_netflow_slope, brk_activity_level, brk_activity_div_fast, brk_activity_div_slow, brk_liquidity_level, brk_liquidity_impulse, brk_exchange_share_level, brk_exchange_share_delta, brk_miner_pressure, brk_hash_momentum, brk_roi30, brk_roi1y activity_weight=0.3, base_temperature=0.58, exchange_share_weight=0.08, interaction_weight=0.12, liquidity_weight=0.1, miner_pressure_weight=0.12, momentum_follow_weight=0.18, netflow_weight=0.22, overlay_features=['brk_netflow_fast', 'brk_netflow_slow', 'brk_netflow_slope', 'brk_activity_level', 'brk_activity_div_fast', 'brk_activity_div_slow', 'brk_liquidity_level', 'brk_liquidity_impulse', 'brk_exchange_share_level', 'brk_exchange_share_delta', 'brk_miner_pressure', 'brk_hash_momentum', 'brk_roi30', 'brk_roi1y'], overlay_scale=0.75, roi_weight=0.12, temperature_confidence_boost=0.55, temperature_volatility_penalty=0.35, temperature_zone_boost=0.14 min_win_rate=50.0, strict=True start_date='2018-01-01', end_date='2025-12-31' Experimental MVRV model with multi-horizon BRK overlays. Tags: experimental, overlay, brk.
MVRVPlusStrategy mvrv-plus card experimental candidate overlay StackSats Maintainers uniform, mvrv stacksats.strategies.experimental.overlays.mvrv_plus:MVRVPlusStrategy profile core_model_features_v1, brk_overlay_v1 price_usd, price_vs_ma, mvrv_zscore, mvrv_gradient, mvrv_percentile, mvrv_acceleration, mvrv_zone, mvrv_volatility, signal_confidence, brk_netflow, brk_exchange_share, brk_exchange_share_delta, brk_activity_div, brk_roi_context, brk_liquidity_impulse, brk_miner_pressure, brk_hash_momentum confidence_boost=0.16, deep_value_boost=1.18, derived_features=['plus_vol21', 'plus_drawdown90'], disagreement_penalty=0.2, drawdown_penalty=0.24, hash_momentum_weight=0.12, high_vol_penalty=0.34, miner_pressure_weight=0.2, neutral_scale=1.0, overheat_dampen=0.62, overlay_features=['brk_netflow', 'brk_exchange_share', 'brk_exchange_share_delta', 'brk_activity_div', 'brk_roi_context', 'brk_liquidity_impulse', 'brk_miner_pressure', 'brk_hash_momentum'], overlay_scale=0.2, risk_budget_base=1.02, risk_budget_max=1.22, risk_budget_min=0.72, smooth_alpha=0.1 min_win_rate=50.0, strict=True start_date='2018-01-01', end_date='2025-12-31' Experimental MVRV baseline with BRK-aware regime gating. Tags: experimental, overlay, risk.

Built-in intent is explicit by implementation shape:

  • UniformStrategy uses propose mode.
  • RunDailyPaperStrategy uses propose mode.
  • SimpleZScoreStrategy uses profile mode.
  • MomentumStrategy uses profile mode.
  • MVRVStrategy uses profile mode.

How to Run (Parquet-First)

Fetch and prepare the managed runtime parquet:

stacksats data fetch
stacksats data prepare

Validate a built-in strategy on fixed comparison bounds:

stacksats strategy validate \
  --strategy mvrv \
  --start-date 2018-01-01 \
  --end-date 2025-12-31

Run a backtest on the same canonical window:

stacksats strategy backtest \
  --strategy mvrv \
  --start-date 2018-01-01 \
  --end-date 2025-12-31 \
  --output-dir output

Run the built-in strategy audit matrix (uses local workspace code and emits output/strategy_audit.json):

python scripts/run_all_strategies.py

Compare a candidate against baselines on a shared window (uses strategy_id for built-ins and module_or_path:ClassName for customs):

python scripts/compare_strategies.py \
  --strategy my_strategy.py:MyStrategy \
  --strategy simple-zscore \
  --strategy mvrv \
  --baseline uniform \
  --start-date 2024-01-01 \
  --end-date 2024-12-31 \
  --strict

Profile hot paths for strategy runtime:

python scripts/profile_strategy_hotpaths.py

Generate an execution-ready daily decision payload for an external agent:

stacksats strategy decide-daily \
  --strategy run-daily-paper \
  --total-window-budget-usd 1000

Metric Interpretation Guide

Primary metrics:

  • win_rate: percent of windows where strategy percentile beats uniform percentile
  • exp_decay_percentile: recency-weighted strategy percentile
  • uniform_exp_decay_percentile: recency-weighted baseline percentile
  • exp_decay_multiple_vs_uniform: ratio of dynamic vs uniform recency-weighted percentile
  • score: blended headline metric (0.5 * win_rate + 0.5 * exp_decay_percentile)

Reasonableness expectations by strategy family:

  • uniform: baseline multiple should stay near 1.0; material drift indicates a bug.
  • run-daily-paper: treat as a daily-execution harness, not a benchmark; expect near-uniform behavior and use it to verify paper-flow correctness.
  • simple-zscore, momentum: acceptable if finite/stable and non-pathological, even when close to baseline.
  • mvrv: stable baseline model; should produce distinct, non-baseline behavior on representative windows.
  • experimental overlay models: treat outputs as reference or research signals, not as stable benchmark promises.

Comparability discipline:

  • compare strategies on the same start/end window
  • keep allocation span and strictness settings fixed
  • avoid comparing fixed-end runs with extended-to-latest runs without calling out recency effects
  • treat all example interpretations as illustrative unless explicitly dated; regenerate current metrics from local parquet before decisions

Troubleshooting

Missing columns or provider data errors

  • Confirm strategy required_feature_sets() and required_feature_columns() are satisfied.
  • Verify runtime parquet was derived from canonical merged metrics with required BRK columns.
  • For overlay models, ensure required overlay metrics exist in the runtime parquet.

No backtest windows generated

  • Ensure end_date >= start_date.
  • Ensure date span is long enough for 365-day window generation.
  • Confirm runtime parquet covers the full requested range.

Forward leakage failures

  • Ensure strategy logic uses observed-only inputs.
  • Remove any dependence on future rows, centered/forward-looking transforms, or direct external I/O inside strategy hooks.
  • Remember that causal lint is best-effort static analysis, not a runtime sandbox.
  • Re-run strict validation to inspect leakage diagnostics.

Warmup and horizon drift

  • Keep explicit bounds (2018-01-01 to 2025-12-31) for stable model comparisons.
  • Understand that extending end date changes recency-weighted metrics materially.
  • Warmup history can shift early-window features; this is expected and should be held constant across comparisons.

Extending with New Strategies

When adding a custom strategy, keep this contract:

  1. Subclass BaseStrategy and provide stable metadata (strategy_id, version, description).
  2. Declare provider-backed required_feature_sets() and hard-required transformed columns.
  3. Keep hooks Polars-native and return canonical shapes.
  4. If implementing both intent hooks, set intent_preference explicitly.
  5. Keep external data access out of strategy methods; use framework providers.
  6. Validate and backtest on explicit date bounds before claiming model deltas.

Selector rules:

  • built-in strategies use strategy_id
  • custom strategies use module_or_path:ClassName
  • service registry built-ins use catalog_strategy_id

Related references: