Strategy Validation Properties (Exhaustive)¶
This is the canonical running list of properties that validation enforces for strategies.
Framework contract reference: docs/framework.md
Validation Execution Flow¶
flowchart LR
A["Input strategy + date range"] --> B["Contract checks"]
B --> C["Backtest metrics"]
C --> D["Leakage + strict diagnostics"]
D --> E["Threshold checks"]
E --> F["Validation pass/fail summary"]
Validation Property Checklist¶
- [ ] Allocation span config is valid
-
STACKSATS_ALLOCATION_SPAN_DAYSmust be an integer in[90, 1460](default365). -
[ ] Strategy cannot bypass framework orchestration
-
Custom
compute_weightsoverrides are rejected. -
[ ] Strategy must implement an allowed hook path
-
At least one is required:
propose_weight(state)orbuild_target_profile(ctx, features_df, signals). -
[ ]
transform_featuresoutput type is valid -
Must return a pandas
DataFrame. -
[ ]
build_signalsoutput type is valid -
Must return
dict[str, pandas.Series]. -
[ ] Signal and profile series shape/index contract holds
-
Each series must be a pandas
Series, with no duplicate index, ascending index, exact match to window index. -
[ ] Signal and profile series numeric validity holds
-
Series values must be finite numeric (no
NaN,inf, or non-numeric coercion failures). -
[ ]
propose_weightoutputs are finite -
Every proposal must be finite numeric.
-
[ ] Target profile mode is valid
-
Only
preferenceandabsolutemodes are allowed. -
[ ] Allocation index monotonicity holds for temporal counting
-
Allocation index used for
n_pastmust be monotonic increasing. -
[ ] Locked-prefix structural validity holds
-
locked_weightsmust be 1D, finite, values in[0, 1], and length<= n_past. -
[ ] Locked-prefix budget feasibility holds
-
Running sum of locked weights must never exceed total budget
1.0. -
[ ] Locked-prefix daily bounds hold on contract-length windows
-
When window length equals configured span, locked values must be within
[1e-5, 0.1]. -
[ ] Per-day clipping obeys future feasibility constraints
- For contract-length windows, daily clipping enforces both day bounds and future-budget feasibility.
-
Infeasible bounds must hard-fail.
-
[ ] Output weight vector structure is valid
-
Final weights must be 1D and finite.
-
[ ] Output weight values are valid
-
No negative weights; no values above
1.0(within tolerance). -
[ ] Output weights sum exactly to budget (within tolerance)
-
Final weight sum must be
1.0. -
[ ] Contract-length day bounds hold on final weights
-
For span-length windows, each day weight must be within
[1e-5, 0.1]. -
[ ] Daily bounds are globally feasible for span length
-
Span must satisfy feasibility:
n_days * min_daily_weight <= 1.0 <= n_days * max_daily_weight. -
[ ] Historical lock immutability is enforced in strict checks
-
Injected locked prefix must be preserved exactly when recomputing under perturbed future features.
-
[ ] Forward-leakage resistance: masked-future invariance
-
Prefix weights at probe date must match when all future features are masked to
NaN. -
[ ] Forward-leakage resistance: perturbed-future invariance
-
Prefix weights at probe date must match when future features are strongly perturbed.
-
[ ] Profile-only leakage resistance is enforced
-
For profile-hook strategies (without propose hook), prefix profile values must be invariant under masked/perturbed future inputs.
-
[ ] Strict mode forbids in-place feature mutation
-
Strategy must not mutate
ctx.features_dfduring weight computation. -
[ ] Strict mode forbids profile-build feature mutation
-
Strategy must not mutate
ctx.features_dfduring transform/signal/profile build path. -
[ ] Strict mode determinism holds
-
Repeated runs with identical inputs must produce exactly matching weights (within
atol=1e-12). -
[ ] Weight constraints hold across validation windows
-
Validation windows must not violate sum, negativity, or (when applicable) min/max day bounds.
-
[ ] Boundary saturation stays below strict threshold
-
In strict mode, boundary-hit rate (days at
MINorMAX) must be<= max_boundary_hit_rate(default0.85). -
[ ] Cross-fold robustness minimum is met in strict mode (when fold checks run)
- Minimum fold win rate must be
>= min_fold_win_rate(default20.0). -
Fold checks are skipped when there is insufficient date range for at least two valid folds.
-
[ ] Cross-fold instability is bounded in strict mode (when fold checks run)
- Fold win-rate standard deviation must be
<= max_fold_win_rate_std(default35.0). -
Fold checks are skipped when there is insufficient date range for at least two valid folds.
-
[ ] Shuffled-null robustness threshold is met in strict mode (when shuffled checks run)
- Mean win rate on shuffled-price trials must be
<= max_shuffled_win_rate(default80.0) acrossshuffled_trials(default3). -
Shuffled checks are skipped when
PriceUSD_coinmetricsis missing, the shuffled window is empty, orshuffled_trials <= 0. -
[ ] Global win-rate threshold is met
-
Validation backtest win rate must be
>= min_win_rate(default50.0). -
[ ] Validation date range must contain data
-
Empty requested validation range is an automatic validation failure.
-
[ ] Backtest path must generate windows
- Validation relies on backtest windows; if none are generated, validation cannot pass.