Skip to content

metrics: typed report_result_invalid for overflow; annualised metrics under one day are null with a reason (rev 3.1, CR-202) - #453

Closed
luisleo526 wants to merge 1 commit into
mainfrom
cx/metrics-overflow-v5
Closed

luisleo526 wants to merge 1 commit into
mainfrom
cx/metrics-overflow-v5

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

Metrics overflow: revision 3.1 (CR-202, for the 1.6.2 final)

Supersedes #451. It carries the gating read's fixes, as ONE squash commit 3a359828d on main da9403fce.

Under revision 3 there is no catch-all null for an overflowing report metric. The owner-approved clarification REVISION 3.1 (L6 ruling 10-20) adds one defined exception:

  • Annualised metrics cagr, calmar, sharpe_bar, sortino_bar (exactly these four; docker/report_annualization.def): when the measured span is under one day they are null, at path metrics.equity.<field> only. The reason is at diagnostics.annualization.<field>. The run completes. The exact table is in docs/design/selected-window-wire-v1.3-revision-3.1.md and docs/pages/report-schema.md.
  • Any other overflowing report metric, including annualised ones on a span of one day or more, fails with the typed report_result_invalid fault.
  • The native runner report format (pineforge-native-report/v1) is unchanged; it writes "NaN" as documented. Revision 3 governs the public report only.
  • C-host failure paths fill a zeroed local ReportC, so *out is never half-written. A new test covers this.

Neutral digest re-pin (tests/test_native_anchored_legs.cpp, kNeutralReportDigest → 8139101939074791901). The value is harvested from lab job rj-20261020t003449-511ce1 (release log line "neutral report digest 8139101939074791901, pinned 17583267501122239024"), under CORE-TOP's fixture authority. The cause is cagr on a 14-minute span (15 one-minute bars) becoming null by the rule.

The commit message names every deleted doc sentence (doc-reverts).

🤖 Generated with Claude Code

…s; short-span annualised metrics are a defined absence with a named reason (CR-202)

Squash of cx/metrics-overflow-v3 on engine main da9403f. Its single parent is engine main, as the GitHub squash writes it.

What changes
- A report metric whose computed value overflows (buy_hold_return, every other report metric) fails the run with the typed failure report_result_invalid, reason nonfinite, instead of writing null.
- Revision 3.1 (docs/design/selected-window-wire-v1.3-revision-3.1.md, docs/pages/report-schema.md): cagr, calmar, sharpe_bar and sortino_bar are annualised from the measured span. Under one day (0 < span_ms < 86 400 000, span from the equity-curve point times, UTC epoch milliseconds, script-bar open clock) each is a defined absence: null on the public report with the reason span_too_short_to_annualize at diagnostics.annualization.<field>, outside the 135 digest leaves. At or above one day an overflow stays the typed failure. The policy list is docker/report_annualization.def, read by the kernel, and a copy in docker/run_json.py held equal by a test.
- C host (src/native_c_host.cpp): a report failure after a completed run is recorded and returns E_STATE, a report failure after an earlier latched failure returns E_RUN_FAILED with that failure; in both the caller's report struct is defined (zeroed local report freed on a throw) instead of half written.
- The native runner keeps its own report format: undefined metrics stay the string "NaN" (runner/README.md); only an infinite value is the typed failure there.
- Disclosed behaviour: an infinite first-open or last-close price and a non-finite selected anchor are now report_result_invalid (feed admission makes the first unreachable).
- kNeutralReportDigest in tests/test_native_anchored_legs.cpp is 8139101939074791901 (was 17583267501122239024): the lab harvest of the neutral 15 one-minute bar run, whose cagr, sharpe_bar and sortino_bar become absent on its 14-minute span. Source: lab job rj-20261020t003449-511ce1 (label cr202-v4b-harvest-22b20449), release step log line 2527 "neutral report digest 8139101939074791901, pinned 17583267501122239024"; fixture authority for exactly that printed value was given by CORE-TOP on 2026-10-20 08:20. That test was the only failure of that release run (99% tests passed, 1 tests failed out of 962).

Documentation sentences reworded or replaced by this change, each named for scripts/check_doc_reverts.py (the sentence's introducing commit, then its first words):
- 1bd075c (Trading metrics + equity curve in backtest report, #31): "See the per-field doxygen in `<pineforge/pineforge.h>` for the exact rule on every field." in docs/pages/report-schema.md, now "in `<pineforge/pineforge.h>` for the existing field domains; the rule below is authoritative for the sub-day case".
- 1b08c61 (EN-133, #384): "net_pnl, avg_trade, best_trade, worst_trade and max_drawdown, must be finite or the run fails with report_result_invalid, field naming the corresponding trades.<leaf> or summary.<leaf> and reason equal to nonfinite." in docs/pages/report-schema.md, extended with win_rate_pct and the equity-curve equity and open_profit leaves.
- 5691220 (ADR-0001 rewritten against HEAD): "compute_equity_stats answers its all-NaN value with no error" in docs/adr/0001-kernel-adapter-boundary.md, now "answers its defined empty-curve metrics with no error".
- 375795a (shard the ownership manifest-controls test, CR-196): "(9, 9, 9 and 8 for shards 1 to 4 of 4: 8, 8, 8 and 7 cases plus the guard)" and "The separate cheap test_shards_partition_every_case_exactly_once guard runs in every shard" in tests/ownership/README.md, now "(10, 10, 10 and 10 for shards 1 to 4 of 4: 9 cases plus the guard in each)" and "Each shard also runs the cheap test_shards_partition_every_case_exactly_once guard".
- file:line citation digits only, wording kept: ADR-0001 (the "inclusive bar metrics" bullet, the "Reporting." bullet, the strategy_configure_native_v1 row, the magnifier_sub_bars_total row), native-feature-parity rows RP2, RP4, S1b and "A zoned chart-day memo", native-refactor-progress (the quiet-bar cost check and the every_gate_is_taken_both_ways citation), native-engine ("MUST mirror" citation of compute_equity_stats).

Documentation sentences the history of this branch introduced and later reworded or removed (none of them is deleted by this squash against main):
- c9ba507 introduced "Report arithmetic that produces a nonfinite value, including overflow, fails with `report_result_invalid` and reason `nonfinite`." in docs/pages/report-schema.md.
- c9ba507 introduced "The engine checks computed values before they can become a metric absence." in docs/pages/report-schema.md.
- eba8561 (revision 3.1) introduced "The constant policy list is in `docker/report_annualization.def`, shared by the native metric walk and public report writer." in docs/design/selected-window-wire-v1.3-revision-3.1.md.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@luisleo526

Copy link
Copy Markdown
Collaborator Author

Superseded by #456 (CR-202 v6: owner ruling W-73, sub-day annualised metrics are proportional, never null).

@luisleo526 luisleo526 closed this Oct 20, 2026
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