Skip to content

feat(backtest): enforce promotion-grade Purged WFA - #286

Merged
Pigbibi merged 1 commit into
mainfrom
codex/qsl-p0-qpk-purged-wfa-fresh-reslice-20260805
Aug 4, 2026
Merged

feat(backtest): enforce promotion-grade Purged WFA#286
Pigbibi merged 1 commit into
mainfrom
codex/qsl-p0-qpk-purged-wfa-fresh-reslice-20260805

Conversation

@Pigbibi

@Pigbibi Pigbibi commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add an explicit typed promotion-grade runner capability and run_promotion() path
  • enforce ordered non-overlapping Purged Walk-Forward folds, positive purge/embargo, and a locked final OOS of at least 12 calendar months
  • reject untyped windows, undated/non-finite results, non-finite cost inputs, and caller-labeled promotion state
  • preserve source revision, cost model, fold/timing/purge/embargo identity through enrichment and persistence without changing legacy positional field order

Boundary

  • synthetic/offline tests only
  • exactly three authorized paths; no dependency, provider, evidence-v2, store redesign, monitoring, runtime, deploy, or live changes
  • ordinary run() / walk_forward() remain non-promotion
  • replaces stale closed-unmerged feat: add R1 timing semantics to BacktestOrchestrator #248; does not revive its review loop

Tests-first evidence

  • RED on exact base 444f2a9da0117046b792374dffd99b37181ed97c: 14 failed, 11 passed
  • focused: 25 passed, 4 subtests passed
  • full locked suite: 809 passed, 1 skipped, 26 subtests passed
  • Ruff check: pass
  • scoped Ruff format check: pass
  • compile: pass
  • sdist/wheel build and wheel-content readback: pass
  • exact scope, diff, untracked, and added-line secret gates: pass

Compatibility inventory

Read-only inventory of current local origin/main refs found keyword-only BacktestResult construction in CN/HK/US/Crypto strategy and snapshot/pipeline consumers; no positional constructor call was found. Existing ordinary orchestrator signatures are unchanged. This is static inventory only and does not claim downstream suites pass.

Co-Authored-By: Codex <noreply@openai.com>
@Pigbibi
Pigbibi merged commit de9f193 into main Aug 4, 2026
1 check passed
@Pigbibi
Pigbibi deleted the codex/qsl-p0-qpk-purged-wfa-fresh-reslice-20260805 branch August 4, 2026 18:44

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0a0f69cdc6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +341 to +343
# Appended to preserve the positional order of every legacy field above.
validation_identity: BacktestValidationIdentity | None = None
cost_inputs: Mapping[str, float] = field(default_factory=dict)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve promotion identity when loading persisted results

When promotion runs are saved and later retrieved through PerformanceStore.load_latest_backtest()/run_latest(), the new validation_identity and cost_inputs fields are silently dropped because performance_store._backtest_from_dict() still constructs BacktestResult without deserializing them. This means persisted promotion-grade fold/OOS records cannot be audited after reload even though the JSON contains the identity and cost inputs; for example, a saved promotion result reloads with validation_identity is None and empty cost_inputs. Please add the corresponding deserialization when introducing these persisted fields.

Useful? React with 👍 / 👎.

embargo_days=embargo_days,
)
fold_results.append(
self._persist_result(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid overwriting promotion fold artifacts

If a promotion runner stamps all fold and locked-OOS results with the same computed_at value, this loop preserves that timestamp for every _persist_result() call. PerformanceStore._backtest_key() is derived from domain/strategy/param_version/computed_at and does not include the fold id, so those writes collide and only the final artifact remains persisted even though run_promotion() returned multiple results. This can happen with runners that use a single run timestamp or second-granularity timestamps; make the persisted key/timestamp unique per fold before saving.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant