stacksats.strategy_types¶
stacksats.strategy_types
¶
Strategy-first domain types for StackSats.
BaseStrategy
¶
Bases: ABC
Base class for strategy-first runtime behavior.
backtest_and_save(config: BacktestConfig | None = None, *, output_dir: str | None = None, write_plots: bool = True, write_json: bool = True, **kwargs) -> tuple['BacktestResult', str]
¶
Run backtest and persist standard artifacts to disk.
build_signal_exprs(ctx: StrategyLazyContext, schema: pl.Schema) -> dict[str, pl.Expr]
¶
Optional lazy signal expressions for profile-mode strategies.
build_signals(ctx: StrategyContext, features_df: pl.DataFrame) -> dict[str, pl.Series]
¶
Hook for user-defined signal formulas.
build_target_profile(ctx: StrategyContext, features_df: pl.DataFrame, signals: dict[str, pl.Series]) -> TargetProfile | pl.DataFrame
¶
Return daily preference scores or absolute target profile.
Default behavior vectorizes propose_weight over the active window.
Return TargetProfile with values as pl.DataFrame (date, value) or pl.DataFrame directly.
build_target_profile_lazy(ctx: StrategyLazyContext, features_lf: pl.LazyFrame) -> TargetProfile | pl.LazyFrame
¶
Optional lazy target-profile hook for profile-mode strategies.
compute_weights(ctx: StrategyContext) -> pl.DataFrame
¶
Framework-owned orchestration from hooks -> final weights.
Returns pl.DataFrame with columns 'date' and 'weight'.
hook_status() -> tuple[bool, bool]
¶
Return which intent hooks this strategy overrides.
intent_mode() -> Literal['propose', 'profile']
¶
Return the active intent execution mode for this strategy.
metadata() -> StrategyMetadata
¶
Return canonical strategy metadata.
params() -> dict[str, object]
¶
Return stable strategy configuration for provenance and idempotency.
propose_weight(state: DayState) -> float
¶
Optional per-day weight proposal hook.
required_feature_columns() -> tuple[str, ...]
¶
Return transformed feature columns required for this strategy.
required_feature_sets() -> tuple[str, ...]
¶
Return framework-owned feature provider IDs required by this strategy.
run(*, validation_config: ValidationConfig | None = None, backtest_config: BacktestConfig | None = None, export_config: ExportConfig | None = None, include_export: bool = False, save_backtest_artifacts: bool = False, output_dir: str | None = None, btc_df: pl.DataFrame | None = None, current_date: dt.datetime | None = None) -> StrategyRunResult
¶
Run validate + backtest, with optional export and artifact persistence.
spec() -> StrategySpec
¶
Return canonical public strategy contract surface.
transform_features(ctx: StrategyContext) -> pl.DataFrame
¶
Hook for user-defined feature transforms on the active window.
transform_features_lazy(ctx: StrategyLazyContext, features_lf: pl.LazyFrame) -> pl.LazyFrame
¶
Optional lazy transform hook for profile-mode strategies.
validate_contract() -> tuple[bool, bool]
¶
Validate framework contract compliance for this strategy instance.
validate_weights(weights: pl.DataFrame, ctx: StrategyContext) -> None
¶
Optional strategy-specific weight checks.
weights: pl.DataFrame with 'weight' column.
DayState(current_date: dt.datetime, features: pl.DataFrame, remaining_budget: float, day_index: int, total_days: int, uniform_weight: float)
dataclass
¶
Per-day user hook input for proposing today's weight.
features: pl.DataFrame with one row (that day's feature values).
StrategyArtifactSet(strategy_id: str, version: str, config_hash: str, run_id: str, output_dir: str, files: dict[str, str] = dict(), schema_version: str = PUBLIC_ARTIFACT_SCHEMA_VERSION)
dataclass
¶
Artifact bundle with strategy provenance metadata.
StrategyContext(features: FeatureTimeSeries, start_date: dt.datetime, end_date: dt.datetime, current_date: dt.datetime, locked_weights: np.ndarray | None = None, btc_price_col: str = 'price_usd', mvrv_col: str = 'mvrv')
dataclass
¶
Normalized context passed into strategy computation.
features_df: pl.DataFrame
property
¶
Polars DataFrame of features. Alias for ctx.features.data.
from_features_df(features_df: pl.DataFrame, start_date: dt.datetime | str, end_date: dt.datetime | str, current_date: dt.datetime | str, *, required_columns: tuple[str, ...] = (), as_of_date: dt.datetime | str | None = None, locked_weights: np.ndarray | None = None, btc_price_col: str = 'price_usd', mvrv_col: str = 'mvrv') -> StrategyContext
classmethod
¶
Build a StrategyContext from a Polars feature DataFrame.
When as_of_date is provided, validates no forward-looking data (max date in features <= as_of_date).
StrategyLazyContext(start_date: dt.datetime, end_date: dt.datetime, current_date: dt.datetime, locked_weights: np.ndarray | None = None, btc_price_col: str = 'price_usd', mvrv_col: str = 'mvrv')
dataclass
¶
Lightweight context for opt-in lazy profile execution.
StrategyMetadata(strategy_id: str, version: str, description: str = '')
dataclass
¶
Canonical strategy identity and descriptive metadata.
StrategyRunResult(validation: 'ValidationResult', backtest: 'BacktestResult', export_batch: 'WeightTimeSeriesBatch | None' = None, output_dir: str | None = None)
dataclass
¶
Composite result for a full strategy lifecycle run.
StrategySpec(metadata: StrategyMetadata, intent_mode: Literal['propose', 'profile'], params: dict[str, object], required_feature_sets: tuple[str, ...] = (), required_feature_columns: tuple[str, ...] = ())
dataclass
¶
Stable public strategy contract for identity, intent, and params.
TargetProfile(values: pl.DataFrame, mode: Literal['preference', 'absolute'] = 'preference')
dataclass
¶
User-provided target profile or daily preference score.
values: pl.DataFrame with columns 'date' and 'value'.
strategy_context_from_features_df(features_df: pl.DataFrame, start_date: dt.datetime | str, end_date: dt.datetime | str, current_date: dt.datetime | str, *, required_columns: tuple[str, ...] = (), as_of_date: dt.datetime | str | None = None, locked_weights: np.ndarray | None = None, btc_price_col: str = 'price_usd', mvrv_col: str = 'mvrv') -> StrategyContext
¶
Build a StrategyContext from a Polars feature DataFrame.
strategy_hook_status(strategy_cls: type[BaseStrategy]) -> tuple[bool, bool]
¶
Return whether strategy overrides propose/profile intent hooks.
validate_strategy_contract(strategy: BaseStrategy) -> tuple[bool, bool]
¶
Enforce framework-owned compute kernel boundaries for strategies.