Recipe: Create a Strategy¶
Goal¶
Create a custom strategy file and run it end-to-end.
If you are extending the built-in StackSats library rather than creating a one-off local model, use Add a Built-in Strategy instead. Built-ins are cataloged and selected by strategy_id; custom strategies keep using module_or_path:ClassName.
Steps¶
- Create
my_strategy.pywith aBaseStrategysubclass. - Declare
required_feature_sets()so the framework materializes the feature providers your strategy needs. - Implement
transform_features,build_signals, and one intent hook. - Use copyable templates: Minimal Strategy Examples.
- Use reusable helpers: Model Development Helpers.
- Use built-in reference models: Strategies.
- Declare any hard-required transformed columns with
required_feature_columns(). - Keep durable config in public attrs or
params(), and keep runtime caches private. - For starter configs, mirror the pattern in
examples/strategy_configs/first_strategy_run.example.json. - Run the fast local loop with
python scripts/research_strategy.py .... - Add a smoke test early using
examples/tests/custom_strategy_smoke.example.py. - Validate and backtest with CLI from the canonical command guide:
- Validate
- Backtest
Contract reminders¶
ctx.features_dfis already an observed-only, as-of-materialized frame. Do not assume rows aftercurrent_dateexist.- Strategy classes should avoid direct file, database, or network access. StackSats applies best-effort static lint checks for these patterns, but the lint is heuristic rather than a runtime sandbox. Use provider-backed feature sets instead.
- For fast research inside the repo, start from
stacksats/strategies/templates/before deciding whether the model belongs in the built-in catalog. - For custom comparison runs, keep
start_date,end_date, and strictness explicit so baselines stay comparable. - Strict validation is the default CLI path and the same strict checks gate
run_dailypaper/live execution.
Expected output¶
- Validation summary line with pass/fail status.
- Backtest artifacts in the standard run output directory (see Export Command).
Common failure patterns¶
- Non-finite signal values (
NaN/inf). - Incorrect date alignment across feature and signal series.
- Strategy bypass attempts of framework-owned kernel behavior.
- Missing or unregistered
required_feature_sets(). - AST lint blockers such as negative
shift, centered rolling windows, or direct file/network I/O. - Ambiguous dual-hook strategies: define
intent_preferenceif bothpropose_weightandbuild_target_profileexist, or validation will fail. - Missing required transformed feature columns.