Skip to content

Add selected-window backtests with retained pre-roll - #363

Merged
luisleo526 merged 1 commit into
mainfrom
win-rc1-landing
Oct 10, 2026
Merged

luisleo526 merged 1 commit into
mainfrom
win-rc1-landing

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

Add an opt-in selected-window mode. A run evaluates retained bars from before the requested window to initialize strategy state, then reports only the activity inside the window. The last pre-roll evaluation may produce an order that fills at the first bar of the window, never earlier. The selected report starts flat at initial capital, carries a separate anchor, and reports the retained, pre-roll and window bar counts separately. With the mode off, every existing output is unchanged.

The development candidate supports the admitted intraday chart timeframes and compatible clock identities. Trusted admission refuses unsupported chart or request-feed timeframes, and incomplete or mismatched request inventories, before any feed is opened or any strategy is loaded. Execution completion is reported before result assembly, so a report failure after that point stays distinct from a strategy failure.

Report-only terminal-quote writers after the seal: once a selected run is sealed, these writers leave the stored quote and the captured report unchanged. The C++ setters raise the named exception selected_window_query_after_seal before storing anything. The C metadata setter keeps its existing void ABI, so its refusal is observable only through the status reader: hosts call strategy_state_query_status_v1, and PF_STATE_QUERY_SELECTED_WINDOW_AFTER_SEAL_V1 now means that these report-only quote writes are refused as well as the state reads it already covered. This extends the documented scope of that status value, and hosts may rely on it. A refusal does not replace the run's first error or status, and no new run failure is latched after a completed execution. Setter behaviour in ordinary mode is unchanged. Because that refusal never reaches a run, its three throws in the source layer are admitted by a row of the run-failure throw allowlist rather than given a run-failure code; the run-failure catalog's release diff is regenerated from the unchanged catalog.

A selected Pine run on an aggregating chart counts the script bars it executes without re-checking the window end: the scheduler asks a new count_selected_executed_primary (the same request checks, clock admission, start alignment and row walk, with the end unbounded), because the end bounds none of the groups the consumer executes. count_selected_retained_primary keeps every end check. The new function is one additive declaration in the installed C++ header selected_window_plan.hpp; no C ABI symbol changes.

The native-counts test fixture now asks the kernel to record its curve. The product route runs KernelRecordedAtHostMarks; the native-counts fixture exercised a HostRecorded host that no product path in this release uses. The release image's backtest entry point is docker/run_json.py. Its selected run loads the transpiled strategy library, sets the window through strategy_set_selected_window_v1 and calls the generated run_backtest_full, whose strategy class derives from source::PineStrategyHost. PineStrategyHost::prepare_native_begin (src/source/pine_strategy_host.cpp:335) projects the run spec through PineExecutionAdapter::project, which sets spec.report_policy = NativeReportPolicy::KernelRecordedAtHostMarks (src/source/pine_adapter.cpp:2796), and nothing rewrites it before configure. That route passes on an aggregated chart: ROUTES-BATCH-TF (tests/test_selected_window_routes.cpp, check_pine_route) runs a PineStrategyHost 1 -> 15 with a selected window under its own projected policy and asserts a clean run that matches the ordinary run. The engine refuses a HostRecorded host that records nothing on purpose (test_selected_window_report_integration, wsr-mismatch). The fixture now asks the kernel to record (KernelRecorded); no CHECK, count or expected value changes. The release image's generated strategies take that route: the transpiler at 2e9aa21f emits "class GeneratedStrategy : public pineforge::source::PineStrategyHost {" (pineforge_codegen/codegen/base.py:4769), attaches the Pine execution adapter (emit_top.py:1157), and no non-test transpiler file names report_policy.

The pinned window of the two-entry same-open gate in tests/pine_input_domain_gates.json follows the split of apply_terminal_explicit_market_policy into a forwarding overload and a two-argument body: only the body's signature line gained ", bool execute_now"; the gate text, its old and new forms, line and evidence are unchanged.

New tests run a retained pre-roll on the product route (a Pine host under its own projected report policy on a 1 -> 15 chart with two pre-roll groups and an aligned window end), the planner-admitted window shape for the Pine timeframe route, the real planner and a real native run on the same rows, and count_selected_executed_primary directly. The verifier's test-count floors follow the fifteen new rows, set to the counts registered at this tree with a configure-only ctest -N on each profile's own definitions: RELEASE_MIN_TESTS 895, KERNEL_MIN_TESTS 325, EXCLUDED_REGISTERED_MIN debug 876, sanitizers 867, native 963, so a silent loss of any new row fails the check.

The documentation's source citations and stated ABI counts are brought up to date with the new code, and the verifier test's two ABI count constants follow the counts the ABI check derives. run-failure-codes.md said only window_mode_unsupported of the 24 selected-window and report-contract codes had a raise site. Twelve do, all in the Python wrappers under docker/ (the selected-window request refusals, the report-option refusals and report_post_execution_failed); the page now names them and the twelve with none. index.md and README.md counted 137 PF_API declarations across two headers. Every include/pineforge/*.h is installed, and five of them declare 145: pineforge.h 94, native_c_api.h 43, execution_observer.h 3, selected_window.h 3 and selected_window_plan.h 2. check_c_abi_runtime.py pins 80 runtime and 43 native symbols, not 81 and 43. abi-stability.md said enum values never change. This release renumbers RunFailureCode in the installed C++ header run_failure_codes.hpp: 36 of the 38 codes released in 1.4.0 get new numbers (none, chart_bars_rejected and chart_bars_unreadable keep their numbers). Codes cross the C boundary by name, so the page says who is affected. Two sentences of docs/pages/run-failure-codes.md are rewritten, not lost. From 65c69b0, "UTF-8, keys sorted, no whitespace; an integer argument is a JSON integer" is extended because the catalog gains the nullable_string and scalar argument kinds; it now lives in the same paragraph, which names both kinds. From 70ddaa3, "rows below are unreleased, targeted for 1.5.0, and not part of 1.4.0" is extended because the 24 selected-window and report-contract rows are unreleased as well; it now lives in the same sentence, which says so.

This is a development-only parity candidate. It advertises the selected-window contract revision 1.3-parity only, makes no claim of complete value-ownership coverage, declares no value sinks, reports lookback as explicitly unknown, and cannot be promoted to stable. Ordinary mode keeps its existing contract.

This change merges together with the paired transpiler change for 1.5.0-rc.1 (pineforge-codegen-oss #195).

🤖 Generated with Claude Code

Add an opt-in selected-window mode. A run evaluates retained bars from before the requested window to initialize strategy state, then reports only the activity inside the window. The last pre-roll evaluation may produce an order that fills at the first bar of the window, never earlier. The selected report starts flat at initial capital, carries a separate anchor, and reports the retained, pre-roll and window bar counts separately. With the mode off, every existing output is unchanged.

The development candidate supports the admitted intraday chart timeframes and compatible clock identities. Trusted admission refuses unsupported chart or request-feed timeframes, and incomplete or mismatched request inventories, before any feed is opened or any strategy is loaded. Execution completion is reported before result assembly, so a report failure after that point stays distinct from a strategy failure.

Report-only terminal-quote writers after the seal: once a selected run is sealed, these writers leave the stored quote and the captured report unchanged. The C++ setters raise the named exception `selected_window_query_after_seal` before storing anything. The C metadata setter keeps its existing void ABI, so its refusal is observable only through the status reader: hosts call `strategy_state_query_status_v1`, and `PF_STATE_QUERY_SELECTED_WINDOW_AFTER_SEAL_V1` now means that these report-only quote writes are refused as well as the state reads it already covered. This extends the documented scope of that status value, and hosts may rely on it. A refusal does not replace the run's first error or status, and no new run failure is latched after a completed execution. Setter behaviour in ordinary mode is unchanged. Because that refusal never reaches a run, its three throws in the source layer are admitted by a row of the run-failure throw allowlist rather than given a run-failure code; the run-failure catalog's release diff is regenerated from the unchanged catalog.

A selected Pine run on an aggregating chart counts the script bars it executes without re-checking the window end: the scheduler asks a new count_selected_executed_primary (the same request checks, clock admission, start alignment and row walk, with the end unbounded), because the end bounds none of the groups the consumer executes. count_selected_retained_primary keeps every end check. The new function is one additive declaration in the installed C++ header selected_window_plan.hpp; no C ABI symbol changes.

The native-counts test fixture now asks the kernel to record its curve. The product route runs KernelRecordedAtHostMarks; the native-counts fixture exercised a HostRecorded host that no product path in this release uses. The release image's backtest entry point is docker/run_json.py. Its selected run loads the transpiled strategy library, sets the window through strategy_set_selected_window_v1 and calls the generated run_backtest_full, whose strategy class derives from source::PineStrategyHost. PineStrategyHost::prepare_native_begin (src/source/pine_strategy_host.cpp:335) projects the run spec through PineExecutionAdapter::project, which sets spec.report_policy = NativeReportPolicy::KernelRecordedAtHostMarks (src/source/pine_adapter.cpp:2796), and nothing rewrites it before configure. That route passes on an aggregated chart: ROUTES-BATCH-TF (tests/test_selected_window_routes.cpp, check_pine_route) runs a PineStrategyHost 1 -> 15 with a selected window under its own projected policy and asserts a clean run that matches the ordinary run. The engine refuses a HostRecorded host that records nothing on purpose (test_selected_window_report_integration, wsr-mismatch). The fixture now asks the kernel to record (KernelRecorded); no CHECK, count or expected value changes. The release image's generated strategies take that route: the transpiler at 2e9aa21f emits "class GeneratedStrategy : public pineforge::source::PineStrategyHost {" (pineforge_codegen/codegen/base.py:4769), attaches the Pine execution adapter (emit_top.py:1157), and no non-test transpiler file names report_policy.

The pinned window of the two-entry same-open gate in tests/pine_input_domain_gates.json follows the split of apply_terminal_explicit_market_policy into a forwarding overload and a two-argument body: only the body's signature line gained ", bool execute_now"; the gate text, its old and new forms, line and evidence are unchanged.

New tests run a retained pre-roll on the product route (a Pine host under its own projected report policy on a 1 -> 15 chart with two pre-roll groups and an aligned window end), the planner-admitted window shape for the Pine timeframe route, the real planner and a real native run on the same rows, and count_selected_executed_primary directly. The verifier's test-count floors follow the fifteen new rows, set to the counts registered at this tree with a configure-only ctest -N on each profile's own definitions: RELEASE_MIN_TESTS 895, KERNEL_MIN_TESTS 325, EXCLUDED_REGISTERED_MIN debug 876, sanitizers 867, native 963, so a silent loss of any new row fails the check.

The documentation's source citations and stated ABI counts are brought up to date with the new code, and the verifier test's two ABI count constants follow the counts the ABI check derives. run-failure-codes.md said only window_mode_unsupported of the 24 selected-window and report-contract codes had a raise site. Twelve do, all in the Python wrappers under docker/ (the selected-window request refusals, the report-option refusals and report_post_execution_failed); the page now names them and the twelve with none. index.md and README.md counted 137 PF_API declarations across two headers. Every include/pineforge/*.h is installed, and five of them declare 145: pineforge.h 94, native_c_api.h 43, execution_observer.h 3, selected_window.h 3 and selected_window_plan.h 2. check_c_abi_runtime.py pins 80 runtime and 43 native symbols, not 81 and 43. abi-stability.md said enum values never change. This release renumbers RunFailureCode in the installed C++ header run_failure_codes.hpp: 36 of the 38 codes released in 1.4.0 get new numbers (`none`, `chart_bars_rejected` and `chart_bars_unreadable` keep their numbers). Codes cross the C boundary by name, so the page says who is affected. Two sentences of docs/pages/run-failure-codes.md are rewritten, not lost. From 65c69b0, "UTF-8, keys sorted, no whitespace; an `integer` argument is a JSON integer" is extended because the catalog gains the `nullable_string` and `scalar` argument kinds; it now lives in the same paragraph, which names both kinds. From 70ddaa3, "rows below are unreleased, targeted for 1.5.0, and not part of 1.4.0" is extended because the 24 selected-window and report-contract rows are unreleased as well; it now lives in the same sentence, which says so.

This is a development-only parity candidate. It advertises the selected-window contract revision `1.3-parity` only, makes no claim of complete value-ownership coverage, declares no value sinks, reports lookback as explicitly unknown, and cannot be promoted to stable. Ordinary mode keeps its existing contract.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Comment thread docker/run_json.py
try:
self.writer.advance(phase)
except self._error_type as error:
raise _typed_failure(error) from None

def test_non_sockets_are_rejected_and_left_open_and_untouched(self):
read_end, write_end = os.pipe()
null = os.open(os.devnull, os.O_RDWR)
]


_ABI_EXPORTS = ("pf_selected_window_version", "strategy_set_selected_window_v1",
import os
import subprocess
import tempfile
import unittest
import os
import socket
import sys
import unittest
import os
import socket
import time
import unittest
@luisleo526
luisleo526 marked this pull request as ready for review October 10, 2026 18:53
@luisleo526
luisleo526 merged commit 47184e5 into main Oct 10, 2026
11 of 20 checks passed
luisleo526 added a commit that referenced this pull request Oct 12, 2026
….0 notes

Two things that are in the v1.5.0 tag were missing from its notes: the opt-in
selected-window mode with retained pre-roll bars (#363, already in
v1.5.0-rc.1) and the typed failures that docker/run_json.py raises for
exceptions from the selected-window helper modules (_typed_failure).

The new subsection "Additions to the 1.5.0 notes" only states what the code
and the #363 text say, with the same "development-only parity candidate"
limits (contract revision 1.3-parity, no claim of complete value-ownership
coverage, cannot be promoted to stable). It adds lines and changes none.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
luisleo526 added a commit that referenced this pull request Oct 14, 2026
….0 notes

Two things that are in the v1.5.0 tag were missing from its notes: the opt-in
selected-window mode with retained pre-roll bars (#363, already in
v1.5.0-rc.1) and the typed failures that docker/run_json.py raises for
exceptions from the selected-window helper modules (_typed_failure).

The new subsection "Additions to the 1.5.0 notes" only states what the code
and the #363 text say, with the same "development-only parity candidate"
limits (contract revision 1.3-parity, no claim of complete value-ownership
coverage, cannot be promoted to stable). It adds lines and changes none.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
luisleo526 added a commit that referenced this pull request Oct 14, 2026
* docs: the 1.6.0-rc.1 changelog entry

The changelog section for the first candidate of 1.6.0, tag v1.6.0-rc.1 on
commit 04607c1: the selected-window contract
revision 1.3 and the typed failures behind it (#388), finite trade and summary
doubles in every report writer (#384, #388), the favicon of the API
documentation (#355), the removed CI time limits and command-line options (#378),
and the tests, CI and benchmarks changes since 1.5.0 (#375, #376, #377, #382,
#383, #385, #386, #387).

The entry is inserted above the 1.5.0 section; no existing line changes. The
date is the UTC date of the tag.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

* README: link the apex pineforge.dev, not the www host

The README header link pointed at https://www.pineforge.dev. The product site
lives at the apex, https://pineforge.dev; the www host is being redirected to
it, and search indexes both forms today. One link changed, nothing else.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

* CHANGELOG: add the selected-window mode and typed failures to the 1.5.0 notes

Two things that are in the v1.5.0 tag were missing from its notes: the opt-in
selected-window mode with retained pre-roll bars (#363, already in
v1.5.0-rc.1) and the typed failures that docker/run_json.py raises for
exceptions from the selected-window helper modules (_typed_failure).

The new subsection "Additions to the 1.5.0 notes" only states what the code
and the #363 text say, with the same "development-only parity candidate"
limits (contract revision 1.3-parity, no claim of complete value-ownership
coverage, cannot be promoted to stable). It adds lines and changes none.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

---------

Co-authored-by: Claude Sonnet 5.5 <[email protected]>
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