session.ismarket asks the engine's session calendar at each bar's open time - #142
Merged
Merged
Conversation
The engine lane H-MEASURE (row G2-36, branch r5/hmeasure at 2b494497) recorded six `lab tv` tapes of TradingView's own session.ismarket on every bar of CME_MINI:ES1!, OANDA:EURUSD, OANDA:XAUUSD and BINANCE:ETHUSDT.P 60, across both 2025 US DST switches and the Thanksgiving week: all 1,138 bars in market. The files are copied byte for byte; the README records their provenance, sha256 and campaign notes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Generated session.ismarket called the time-of-day predicate pine_session_ismarket(syminfo_.session, syminfo_.timezone, time), which tests each instant's own weekday against a session's day mask and does not parse "2400". On H-MEASURE's six TradingView tapes (all 1,138 bars in market) it missed every Sunday-evening open under a ":23456" mask (14/14/14/14/12 bars on ES1! x3, EURUSD, XAUUSD) and every "0000-2400" bar (97/97 on ETH). The engine's source host stores the kernel's in-session fact of the script bar (NativeDecisionContext::in_session) as session_ismarket_ before every source callback; codegen now reads it. A request.security payload runs on its own bars, which carry no host fact, so it keeps the predicate at the security bar's time (a depth flag set around the payload visitor). A batch of fewer than two bars given no timeframe gets no session facts from the engine (script_tf_ stays empty) and keeps the predicate too. session_ismarket_ and script_tf_ join the reserved emitter names, so a script variable of either name no longer shadows the host member. tests/test_e2e_session_ismarket.py replays every tape end to end under the lane sessions, the ":23456" masks and "0000-2400" / "0000-0000": every bar is now TradingView's flag, and the pre-lane build (b0ed496) misses exactly the pinned bars. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A public probe carries every session flag in each entry's Signal (session.ismarket, ispremarket, ispostmarket, isfirstbar, islastbar and the _regular twins). Exported with `lab tv` (ws-report-v1, rangeProof covered, --no-note) on H-MEASURE's six charts and windows: CME_MINI:ES1! 60 across both 2025 US DST switches and the Thanksgiving week, OANDA:EURUSD 60, OANDA:XAUUSD 60 and BINANCE:ETHUSDT.P 60. TradingView flags all 1,138 bars in market and none pre- or post-market; every session day opens on an F1 bar and closes on an L1 bar, the _regular flags equal to the plain ones. The README records each tape's sha256 and export time. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
session.ispremarket / ispostmarket were time-of-day windows only: 04:00 to
the session's first open, and its close to 20:00. For an overnight session
the "open" is the evening restart, so the windows covered in-market hours:
on this lane's TradingView tapes of every session flag the predicates read
108/108/98 bars of ES1! ("1700-1600", America/Chicago) and 117 of XAUUSD
("1800-1700", America/New_York) as pre-market and 30/29/29 and 20 as
post-market, where TradingView flags every bar in market and none in an
extended session.
A bar in market is in neither extended session: both flags now require
the kernel's in-session fact to be false, as session.ismarket reads it, and
bars out of market keep the windows. A request.security payload keeps the
plain predicates at the security bar's time, as it does for ismarket.
tests/test_e2e_session_ismarket.py now replays both tape sets and compares
all seven flags (ismarket, ispremarket, ispostmarket, isfirstbar,
islastbar and the _regular twins) on every bar; the pre-lane build misses
exactly the pinned ismarket, ispremarket and ispostmarket bars, and the
session-day flags were already TradingView's.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The every-flag probe on NASDAQ:AAPL 60, 2025-03-03 .. 03-15, exported through the pinescript-scrapper WebSocket exporter (ws-report-v1, rangeProof covered). The exporter always asks for the regular session; the extended-hours tape ran a scratch copy that differs in one line, the symbol descriptor's session, with CGIM_TV_SESSION=extended. The README records both files' sha256 and the exporter's commit. The extended chart's bars open on the hour and TradingView flags each by its open time: the 09:00 bar, which holds the 09:30 open, is pre-market (M0P1) and the 16:00 bar post-market (M0Q1). isfirstbar / islastbar are the extended day's 04:00 and 19:00 bars, the _regular twins the regular day's 10:00 and 15:00 bars. The regular chart's 09:30..15:30 bars are all in market, first and last at 09:30 and 15:30. The README's header now covers exporters other than lab tv: every metrics.json carries the sha256 of strategy.pine as sourceArtifactHash. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The previous step read the kernel's per-bar fact session_ismarket_. An independent review found, and this lane's extended-hours NASDAQ:AAPL tape proves, that the fact asks the bar's grid interval rather than the bar: after a 09:30-16:00 session the 16:00 bar shares the 15:30 interval, so the fact put it in market (and out of post-market) on all 10 days, where TradingView flags it post-market (M0Q1). TradingView flags a bar by its own open time: the extended chart's 09:00 bar, which holds the 09:30 open, is pre-market. A chart bar's session.ismarket now calls the emitted helper _pf_session_ismarket (codegen/session_market.py): a D/W/M bar is in market; otherwise the engine's native_calendar answers for the bar's open time, on the calendar the kernel builds for the run from the same session and timezone, resolved once per session day as the kernel does. That keeps the Sunday-evening opens under ":23456" and the "0000-2400" day in market, as on the six-chart tapes, and puts the 16:00 bar out of market, as on the AAPL tape; the time-of-day predicate was already right there. It needs no timeframe, so a one-bar run, which the engine gives no session facts, is answered too. ispremarket / ispostmarket keep "in market is in neither". A request.security payload still reads the time-of-day predicates at the security bar's open time, and now warns that they can differ from TradingView. The helper and script_tf_ are reserved emitter names. The public-corpus TUs that change are still the five that read session.*; each books byte-identical trades before and after on the corpus 15m feed (default and declared 0930-1600 America/New_York syminfo) and a 60m resample with the declared session. The per-session-day memo keeps their run time at the pre-lane build's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The every-flag probe on OANDA:XAUUSD 1D, 2025-01-01 .. 04-01, exported with `lab tv` (ws-report-v1, rangeProof covered, --no-note). TradingView stamps each of the 64 daily bars at 17:00 America/New_York, the break of the 1800-1700 session, and flags every one M1P0Q0F1L1f1l1: in market, and the first and last bar of its session day. A daily bar holds whole session days. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A second review of the calendar lowering found no blocker and asked for: - A per-strategy cache instead of a per-thread one. Strategies with different sessions taking turns on one thread re-parsed the calendar on every read, every read paid a thread-local lookup in the loaded strategy module, and a throwing parse left the old calendar under the new key. The emitted _PFSessionMarket type now precedes the class and each strategy holds one mutable _pf_session_market_, declared after the checkpointed script state; the key is written only after a successful parse. A day the calendar cannot resolve, or an exception while resolving it, is out of session, as the kernel reads it. - An accurate payload warning: on a D/W/M chart the kept predicate is a constant, not the security bar's time of day. The docs now say that a user function the security evaluator calls reads the chart bar, that the pre/post windows are the first window's, and that the calendar also puts a masked overnight session's bars after the weekly close out of market. A new TradingView tape covers the helper's D/W/M branch: every XAUUSD daily bar, stamped at the 17:00 ET break, is in market (without the branch the calendar reads all 64 out). Two engine-free tests pin the emission (one type before the class, one cache outside the checkpoint, nothing when no chart flag is read) and one warning per payload read site. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
session.ismarketon a chart bar now asks the engine's own session calendar whether the session holds the bar's open time, which is how TradingView flags bars. Daily, weekly and monthly bars are always in market.native_calendar::session_day_at, built from the same session and timezone the kernel uses) is queried once per session day and cached per strategy, outside the checkpointed script state.session.ispremarket/session.ispostmarket: a bar is in one of them only when it is not in market and falls inside that window. The old time-of-day predicates marked in-market bars of overnight sessions as pre-market.request.security: the three flags keep the time-of-day predicate and emit one warning per source location. No per-bar session fact exists for the security bar._PFSessionMarket,_pf_session_market_andscript_tf_are reserved, so a script variable can no longer shadow the generated code.Evidence
:23456/0000-2400sessions, AAPL regular and extended hours, XAUUSD daily) are replayed intests/test_e2e_session_ismarket.py.:23456masks, and 97 of 97 on0000-2400.isfirstbar/islastbardivergence on the extended-hours tape.tests/test_compile_corpus.py314 passed; gate selftest OK;PARITY OK over 277 fixtures.The branch is rebased onto main, which adds only release-channel files; no transpiler file overlaps.
🤖 Generated with Claude Code
https://claude.ai/code/session_01LifAW9e5J6gFx7gatuxETE