Skip to content

fix(runtime): make the live runtime agree with the official backtest - #150

Merged
kcrmin merged 1 commit into
developfrom
feature/parity-live-backtest
Aug 8, 2026
Merged

fix(runtime): make the live runtime agree with the official backtest#150
kcrmin merged 1 commit into
developfrom
feature/parity-live-backtest

Conversation

@kcrmin

@kcrmin kcrmin commented Aug 8, 2026

Copy link
Copy Markdown
Member

Two places where a released bot did not do what its own backtest showed. Paired with backtest-engine #68.

session.close came from the clock, not the calendar

It was true only when the market hour read 16:00. The market closes at 13:00 ET the day after Thanksgiving, on Christmas Eve, and on July 3. On those days live never published the flag at all, so a SESSION_CLOSE exit silently did not run, while the backtest reads the session's real closesAt and exited as written.

The flag now follows the daily candle, which the gateway finalizes at the session close (FinalizedCandleBoundaryPlanner caps the last boundary at session.closesAt()). One calendar governs both runtimes and early closes need no special case — no protocol change, since closed1d is already on the wire.

RSI_14 had a second implementation

BasicPlanInterpreter recomputed it from the closes series at 18 significant digits with HALF_UP, never quantized. rsi:1.0.0 is 34 digits with HALF_EVEN quantized to 8, and the backtest reads the series that definition published.

Two implementations that merely agree are not one feature: a window whose value sat a rounding step from the threshold crossed it on one side and not the other. RSI_14 now delegates to OfficialFeatureCatalog, so the definition has exactly one implementation. Periods the catalog does not define — it defines only 14 — use the same procedure at the same precision rather than a looser one. OfficialFeatureCatalog.quantize is public for that reason: one quantizer, not a copy of it.

Verification

  • rsi14IsTheOfficialCatalogValueRatherThanASecondImplementation asserts the value live publishes equals the catalog's exactly, for both the current and previous window. It fails against develop.
  • Three session.close cases added, covering the 2025-11-28 early close, the usual 16:00 hour when the day has not ended, and a regular close.
  • ./gradlew build — BUILD SUCCESSFUL, whole repo.

🤖 Generated with Claude Code

Two places where a released bot did not do what its own backtest showed.

`session.close` came from the clock, not the calendar. It was true only when
the market hour read 16:00, but the market closes at 13:00 ET the day after
Thanksgiving, on Christmas Eve, and on July 3. On those days live never
published the flag at all, so a SESSION_CLOSE exit silently did not run while
the backtest, which reads the session's real closesAt, exited as written. The
flag now follows the daily candle, which is finalized at the session close, so
one calendar governs both runtimes and early closes need no special case.

RSI_14 had a second implementation. The interpreter recomputed it from the
closes series at 18 significant digits with HALF_UP and never quantized, while
`rsi:1.0.0` is 34 digits with HALF_EVEN quantized to 8 and the backtest reads
the series that definition published. Two implementations that merely agree are
not one feature: a window whose value sat a rounding step from the threshold
crossed it on one side and not the other. RSI_14 now delegates to
OfficialFeatureCatalog, so the definition has exactly one implementation, and
periods the catalog does not define use the same procedure at the same
precision rather than a looser one. OfficialFeatureCatalog.quantize is public
for that reason -- one quantizer, not a copy of it.

Both are pinned by tests that fail without the change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@kcrmin
kcrmin merged commit 47b7c85 into develop Aug 8, 2026
2 checks passed
@kcrmin
kcrmin deleted the feature/parity-live-backtest branch August 8, 2026 03:20
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