feat(strategy): require real crypto performance evidence#125
Conversation
Co-Authored-By: Codex <noreply@openai.com>
🤖 Codex PR Review🚫 Merge blocked: contract arbitration failed closed; automatic remediation is disabled 🚫 Blocking IssuesThese issues must be fixed before this PR can be merged: 1. 🟠 [HIGH] Logic in
|
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cb6c6e334e
ℹ️ 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".
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6fdfb8fbba
ℹ️ 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".
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e9c9020311
ℹ️ 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".
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 12a085da0f
ℹ️ 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".
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 97fbba3c64
ℹ️ 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".
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4983135454
ℹ️ 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".
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ec24b82309
ℹ️ 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".
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f2da506019
ℹ️ 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".
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 838cc0db03
ℹ️ 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".
| strategy_index = header.index("strategy") | ||
| if not any(len(row) > strategy_index and row[strategy_index].strip().lower() == "final_score" for row in rows): | ||
| return False | ||
| return bool(set(header).intersection(metrics)) and _has_numeric_value(header, rows, metrics) |
There was a problem hiding this comment.
Require metrics on the final_score row
When performance_summary.csv has a strategy column and includes a final_score row whose metric cells are blank/NaN, this still scans every row for a finite metric value. A numeric rule_score row therefore makes build_review() report BASELINE_REVIEW_NOT_YET_FROZEN even though the required final_score performance evidence is missing; the fresh evidence beyond the prior row-existence issue is that a placeholder final_score row is enough to pass. Restrict the numeric metric check to the final_score row when that column is present.
Useful? React with 👍 / 👎.
| datetime.fromisoformat(row[positions["test_end"]].replace("Z", "+00:00")) | ||
| except (IndexError, TypeError, ValueError): |
There was a problem hiding this comment.
Reject reversed walk-forward windows
When a hand-built or corrupted walkforward_validation_summary.csv has test_start after test_end, both timestamps still parse successfully and a finite metric makes _usable_walkforward_csv() return true. That moves the fail-closed review to BASELINE_REVIEW_NOT_YET_FROZEN even though the OOS window is chronologically invalid; require test_start <= test_end before accepting the row as evidence.
Useful? React with 👍 / 👎.
| if any(key in manifest for key in ("market_start_date", "market_end_date")): | ||
| if manifest.get("market_start_date") != market_start or manifest.get("market_end_date") != market_end: | ||
| raise InsufficientEvidenceError("v1 market date range does not match manifest") | ||
| return panel.set_index(["date", "symbol"]).sort_index() |
There was a problem hiding this comment.
Reject duplicate panel keys before backtesting
If an env-supplied preflight bundle contains duplicate (date, symbol) rows and its manifest counts match that CSV, this validation returns the duplicated index as-is. The delegated backtest later pivots with unstack("symbol"), so the production lifecycle path raises a raw duplicate-index error instead of a controlled InsufficientEvidenceError; check for duplicate date/symbol keys before returning the panel.
Useful? React with 👍 / 👎.
| required = {"date", "symbol", "in_universe", "open", "final_score"} | ||
| if not required.issubset(panel.columns): | ||
| raise InsufficientEvidenceError("research_panel.csv.gz missing required columns") |
There was a problem hiding this comment.
Reject rows without a panel symbol
When an env-supplied bundle has a blank symbol on a scored in-universe row and the manifest row count is adjusted to match, this only checks that the column exists, then later compares manifest symbols after dropna(). The malformed row can therefore reach run_single_backtest(), where selecting it introduces a NaN symbol into the weight vector and can crash with a raw sort/indexing error instead of failing closed; validate that every panel symbol is present and non-empty before accepting the bundle.
Useful? React with 👍 / 👎.
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 119a83d590
ℹ️ 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".
| expected_end_date = date.fromisoformat(os.environ["CRYPTO_LIFECYCLE_EXPECTED_END_DATE"]) | ||
| result = runner.run( | ||
| "crypto_live_pool_rotation", | ||
| {}, |
There was a problem hiding this comment.
Verify the real strategy configuration
When the publish job reaches this verification step, it calls the lifecycle runner with an empty param set, so CryptoLivePoolBacktestRunner falls back to its hard-coded DEFAULT_BACKTEST_CONFIG (top_n=2, weighting='equal'). I checked the production research path: src/pipeline.py backtests using config/default.yaml, whose strategy is top_n: 3 and weighting: inverse_vol. This means the uploaded preflight can pass while validating a different portfolio than the crypto live-pool rotation operators actually run; pass the loaded strategy config or make the runner defaults match the live config.
Useful? React with 👍 / 👎.
| raise InsufficientEvidenceError("market history preflight artifact is stale") | ||
| if expected_start_date is not None and panel_start_date > expected_start_date: | ||
| raise InsufficientEvidenceError("research panel starts after requested evaluation window") | ||
| if expected_end_date is not None and panel_end_date < expected_end_date: |
There was a problem hiding this comment.
Require the requested end date to exist
When an env-supplied bundle skips the requested expected_end_date but has a later scored date, this coverage check still passes. The runner then slices to <= end_date, silently evaluates only the earlier available rows, and _metrics_to_qpk_result() reports the supplied end date, so a verification run for yesterday can publish evidence as if that completed date was present; require the requested end date to be in the scored panel dates before delegating.
Useful? React with 👍 / 👎.
| if any(key in manifest for key in ("market_start_date", "market_end_date")): | ||
| if manifest.get("market_start_date") != market_start or manifest.get("market_end_date") != market_end: | ||
| raise InsufficientEvidenceError("v1 market date range does not match manifest") | ||
| return panel.set_index(["date", "symbol"]).sort_index() |
There was a problem hiding this comment.
Trim unscored warm-up rows before backtesting
When the exported bundle includes unscored warm-up rows before the manifest start, this returns the entire CSV to the runner. For no-start lifecycle runs such as the new publish verification, run_single_backtest() builds returns over all trading dates, so pre-score days are counted as zero-return observations and the result start date precedes the first scored evidence; trim to the scored date range or pass the scored start date into the runner.
Useful? React with 👍 / 👎.
| """Factory for the Crypto backtest runner.""" | ||
| return CryptoBacktestRunner() | ||
| if self._panel is None: | ||
| self._runner = CryptoLivePoolBacktestRunner(panel=load_preflight_panel(start_date, end_date)) |
There was a problem hiding this comment.
Export inverse-vol inputs for preflight runs
When the lifecycle runner is used with the production weighting: inverse_vol setting, this delegated preflight panel still only contains the exported lifecycle columns (in_universe, open, final_score). select_portfolio() applies inverse-vol weighting only when vol20 is present, otherwise it silently uses equal weights, so even after passing the real strategy params this adapter cannot reproduce the production backtest evidence unless the preflight bundle includes the weighting input.
Useful? React with 👍 / 👎.
Summary
InsufficientEvidenceErrorCRYPTO_LIFECYCLE_PREFLIGHT_ROOTthroughGITHUB_ENV, and invoke the public no-arg factory against the real artifact before uploadcrypto.lifecycle_preflight.v2; strictly validate v2 identity, counts, symbols, date ranges, and finite numeric content; retain strictly validated legacy v1 compatibilityRuntime rollout order
Publish Lifecycle Inputsdownloads real Binance history and exports the v2 bundle.CRYPTO_LIFECYCLE_PREFLIGHT_ROOTtoGITHUB_ENVbefore callingbuild_backtest_runner()with no arguments.InsufficientEvidenceError.Validation