Session flags match TradingView on multi-window and extended-hours charts (K-SESSION-WINDOWS) - #293
Merged
Merged
Conversation
…ight session has neither TradingView flags no bar of TSE:7203 (0900-1130,1230-1530 Asia/Tokyo), HKEX:700 (0930-1200,1300-1600 Asia/Hong_Kong) or CBOT:ZC1! (1900-0745, 0830-1320 America/Chicago) pre- or post-market, at 15, 60 and 240 minutes: 1,570 bars across nine `lab tv` every-flag tapes, the 60-minute bars that open inside a break (TSE 12:00, ZC 08:00) included. Nor any bar of the overnight and 24-hour charts CME_MINI:ES1! (1700-1600), OANDA:XAUUSD (1800-1700), OANDA:EURUSD (1700-1700) and BINANCE:ETHUSDT.P (24x7). On NASDAQ:AAPL, the one-window control, the extended-hours tapes flag the bars opening 04:00 to before 09:30 ET pre-market and 16:00 to before 20:00 post-market, and the regular-hours tapes none. pineforge::session_in_premarket / session_in_postmarket (session_time.cpp), which generated code reaches through PineStrategyHost's class-scope wrappers -- gated by the calendar's in-market answer on the chart, and alone inside a request.security payload -- took the pre-market end and the post-market start from the FIRST "HHMM-HHMM" window, with fixed 04:00 / 20:00 bounds (lane CG-SESSION-2 finding F6). So HKEX:700's and TSE:7203's afternoons read post-market, the same windows written the other way round made the morning pre-market, and an overnight first window made one instant both (ZC 60: 60 bars both). The rule is now: pre-market runs from 04:00 to the session day's first open and post-market from its last close to 20:00, over every window in any order (extended_hours_bounds); a break between windows is neither; a session with a window that wraps midnight -- its day opens on the previous date -- or one that spans 24 hours has neither. A single same-day window reads exactly as before, the 24-hour spellings too. tests/test_session_prepost_windows_tape.cpp (kernel-only, new) replays the seventeen tapes of tests/fixtures/session_windows (README.md there: every tape's provenance; the CG-SESSION-2 and CG-ISMARKET tapes are copied unchanged from pineforge-codegen) through the chart-bar forms, and pins a synthetic day's off-market bars: the HKEX lunch is neither in either order, corn has neither. At 1e360bd it fails 31 of 114 checks (log in the lane scratch, tdd-f6-red.log): pre / post misses HKEX 15 0/120, reversed 100/0, TSE 15 0/130, ZC 15 350/240 (both-order 150/40), HKEX 60 0/30, TSE 60 0/40, ZC 60 100/70 with 60 both, ES1! 108/30, XAUUSD 117/20; the AAPL, EURUSD and ETH tapes 0 before and after. The replay reads TSE:7203 at 1545, where TradingView holds the 15:30 closing bar (CG-SESSION-2's open finding). Session policy, in the language calendar functions ADR-0001 rules for generated code (session_time.cpp); the kernel is untouched. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…l, not at an earlier instant of its interval TradingView flags NASDAQ:AAPL 60 with extended hours (bars on the hour, 04:00-19:00 ET, `cgim-flags-aapl-60-ext`) out of market on the 16:00 bar, and ends the regular day on the 15:00 bar (islastbar_regular); its first regular bar is 10:00. TSE:7203's 60-minute bar that opens at 12:00, inside the 11:30-12:30 break, and CBOT:ZC1!'s that opens at 08:00, inside 07:45-08:30, are in market (`ksw-flags-tse7203-60`, `ksw-flags-zc1-60`, and the 240-minute tapes; `lab tv --no-note`). present_session_day (native_execution_consumer.cpp) read every bar -- and every held neighbour, through eligible_session_point -- at the first eligible instant of the script interval holding its label. On the extended chart the regular session's 09:30-anchored grid files the 16:00 bar under the 15:30 interval, so it read in session and closed the day in place of 15:00 (lane CG-ISMARKET finding F1): in_session missed 10 bars of the tape and closes_session_day 20. A bar is now read at its label, or at its interval's first eligible instant when that is LATER: the break-open bars keep reading in session at their reopen, and an instant before a bar's own open is never the bar's. The certified-cycle fast path already answered that way (an in-span label is at or after its interval's first eligible instant), so it is unchanged. ADR-0001 ruling (row `present_session_day`, amended here): generic kernel. Reading a bar at its own label is a property of the facts, not a platform rule -- an instant before a bar opened is not in that bar, whatever grid the calendar keys the bar's interval to -- and nothing branches on a venue: the session, the zone and the labels are the run's data. The facts stay presentation and fold into no digest, so no hash, epoch or layout moves. Pine's pre/post-market and the extended-hours day stay in the adapter and session_time.cpp. tests/test_native_session_day_bar_open.cpp (kernel-only, new): a bare FeedTolerant host replays AAPL 60 / 15 with and without extended hours, and TSE:7203 / CBOT:ZC1! 60 and 240 aggregated from TradingView's own 15-minute bars; every script label, in_session, opens_session_day and closes_session_day is TradingView's session.ismarket / isfirstbar_regular / islastbar_regular on every bar. At 1e360bd the extended AAPL 60 tape fails 2 of 64 checks (in_session 10 bars, closes_session_day 20; lane scratch tdd-f1-red.log); every other case passes before and after, the break-open bars included. The 102 session, calendar, stream and C-API ctest rows pass unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… and the _regular pair the regular one TradingView's extended-hours tapes of NASDAQ:AAPL (`cgim-flags-aapl-60-ext`, `cgs2-hist-aapl-15-ext`) part the two pairs: at 60 minutes isfirstbar is the 04:00 ET bar and islastbar the 19:00 one, isfirstbar_regular 10:00 and islastbar_regular 15:00; at 15 minutes 04:00, 19:45, 09:30 and 15:45. On every chart without extended hours (AAPL regular, TSE:7203, HKEX:700, CBOT:ZC1!, CME_MINI:ES1!, OANDA:XAUUSD / EURUSD, BINANCE:ETHUSDT.P) each pair is one flag. The Pine host held one pair, the kernel's regular session-day facts, which generated code read for both spellings (lane CG-ISMARKET finding F2): with F1 in place the extended tapes still missed isfirstbar and islastbar on 20 bars each (lane scratch tdd-f2-red-behaviour.log). PineStrategyHost now holds session_isfirstbar_regular_ / session_islastbar_regular_, the kernel's facts as they are, and widens the plain pair to the chart's session day (update_extended_session_day): the regular day plus the pre- and post-market bars of its date the chart holds, pre- and post-market being session_time's windows (F6), which exist only on a session day that opens and closes on one date. The bar before is the script bar published last; the bar after is the first retained input past the script bar's interval (PineScheduler::retained_input_from), so the chart, magnified and aggregated paths read one answer for the same bars, as lane E25 requires; a batch's final bar closes its day by the kernel's convention. A stream's realtime bar has nothing held after it: a pre- or post-market bar then reads the chart timeframe's next slot and a regular bar keeps the kernel's close. A chart holding no pre- or post-market bar reads exactly the kernel's facts, as before. Pine policy, in the adapter; the kernel is untouched and the new members fold into no hash (waivers beside the other session flags). tests/test_session_extended_day_tape.cpp (release, new) replays eleven tapes of tests/fixtures/session_windows through the host: every flag of all four is TradingView's, and a stream of the extended AAPL 60 tape keeps the plain pair exact. It pins one kernel residual there: on a realtime day the kernel's scheduled close steps the regular session's 09:30-anchored grid and expects a 15:30 bar after the off-grid 15:00 one, so islastbar_regular never fires (8 days). Fail-before at its parent 3d218d7 (F1): the unit does not compile (`session_isfirstbar_regular_` undeclared, tdd-f2-red-compile.log). Two existing rows fed synthetic post- and pre-market bars and pinned the regular day on the plain flags. Their strings move to the _regular members unchanged, and the plain flags now read the chart's day as TradingView's extended tapes do: test_session_islastbar_aggregation (one session close: islastbar 16:10, the last post-market bar; two sessions: islastbar Tuesday 16:10, isfirstbar Wednesday 09:15, the first pre-market bar; every path still agrees bar for bar) and test_aggregated_path_regressions (the calc_on_order_fills post-market case: 15:45 keeps islastbar_regular, and one answer per bar still holds). None of the 312 corpus probes reads a session flag. Three documentation sentences are rewritten because the host now widens the plain pair: the design record's OT7 row (lane F5, f064b1c: the adapter selecting the kernel's facts into the three flags) and the Pine v6 coverage detail's session.isfirstbar_regular / islastbar_regular rows (e244d65: 'Aliased to session.isfirstbar'), and ADR-0001's line that the host computes no session-day rule of its own. Generated code still lowers session.isfirstbar_regular / islastbar_regular to the plain members (codegen visit_expr.py): routing them to the new members is the transpiler's follow-up, until which a generated _regular read on an extended-hours chart follows the chart's day. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…n market, as the kernel reads them Lane CG-ISMARKET's finding F7 (an aggregated split-session bar whose nominal open falls in a break reads out of market) had no tape. This lane's `lab tv --no-note` exports give one (tests/fixtures/session_windows): TSE:7203 60 opens a bar at 12:00, inside the 11:30-12:30 lunch break, and CBOT:ZC1! 60 one at 08:00, inside 07:45-08:30; TradingView flags both in market, neither pre- nor post-market nor a day's first or last bar. Its 60- and 240-minute bars open at the same instants as the engine's aggregation of TradingView's own 15-minute bars of the window. TradingView agrees with the engine where it answers per bar, so nothing changes: the kernel reads such a bar at its interval's first eligible instant, the reopen (kept by F1), and session_ismarket_, the session-day flags and the gated pre- / post-market predicates are TradingView's on every bar. What disagrees is a reading at the bar's open instant -- the time-of-day predicate pine_session_ismarket, and the session calendar asked at the open, which is how the transpiler lowers a chart's session.ismarket (codegen session_market.py) -- 10 bars on each 60-minute tape, none at 240. tests/test_session_break_open_bar_tape.cpp (release, new) replays TSE:7203 and CBOT:ZC1! 60 and 240, aggregated from their 15-minute tapes, through the Pine host: labels and every flag are TradingView's, and the at-open readings' misses are pinned (RESIDUAL) for the transpiler, whose change is to lower session.ismarket to session_ismarket_. The rows it checks agree at 1e360bd as well (the kernel fact already read the bucket's first eligible instant); the unit compiles from df4510e (F2) on, which adds the _regular members it reads. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…lendar at the bar's open, the predicate only inside request.security Lane CG-ISMARKET's finding F5: the comment above PineStrategyHost's session flags said a generated session.ismarket calls pine_session_ismarket. Since pineforge-codegen a425965 a chart's session.ismarket asks the session calendar at the bar's open through the transpiler's own helper (_pf_session_market_, native_calendar::session_day_at; e.g. the corpus's validation/symbol-specified/AAPL/session-ismarket-nyse-rth-01/generated.cpp), and only a read inside a request.security payload still calls the class-scope pine_session_ismarket. The comment now says so, and says which member each flag spelling reads today (the transpiler lowers the _regular spellings to the plain pair). The same stale sentence stood in ADR-0001 (the adapter's Pine language state), docs/pages/pine-to-native.md (the session.ismarket row, whose in_session sentence now also states F1's reading), the Pine v6 coverage detail and the design record's row 36, and in the H-MEASURE tape row's header; each now names the calendar reading on the chart, the predicate in a request.security payload, and the break-open bar only the kernel's fact holds in market (tests/test_session_break_open_bar_tape.cpp). The design record's row 36 sentence (INT26, d093560: the generated predicate is codegen's to route) is rewritten to what the transpiler does now. Two ADR and design citations of the host header re-anchored. Comments and pages only. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…1 -> 293, release 720 -> 724, PR registration 705/705/714 Lane K-SESSION-WINDOWS adds four CTest rows. Two are source-free and register in the kernel profile and in release (F6 test_session_prepost_windows_tape, F1 test_native_session_day_bar_open); two reach the source layer and register in release only (F2 test_session_extended_day_tape, F7 test_session_break_open_bar_tape). All four register in the Debug, sanitizers and native profiles as well. Counted with ctest -N after configuring each profile exactly as ci_verify does (configure only), on main 7f807b9 and on this rebased tree: profile main 7f807b9 rebased delta release 720 724 +4 debug 701 705 +4 sanitizers 701 705 +4 native 710 714 +4 kernel 292 registered 294 +2 (F6, F1) The row diff between the two trees is exactly the lane's four rows (two in the kernel profile), none of them XSYM-D's. So KERNEL_MIN_TESTS 291 -> 293 (294 registered, the WebSocket row still skips on a system libcurl), RELEASE_MIN_TESTS 720 -> 724 and EXCLUDED_REGISTERED_MIN 701/701/710 -> 705/705/714, each keeping XSYM-D's accounting above the lane's, with the self-test's literal and docs/ci.md's sentence naming both lanes. The two constants moved lines, so their citations in CONTRIBUTING.md and docs/pages/contributing-llm.md are carried by hand (ci_verify.py:284 -> :293, :447 -> :463); check_doc_anchors resolves every anchor. 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.
Session flags match TradingView on multi-window and extended-hours charts
Each rule is pinned by TradingView tapes and has a test that fails before the fix.
session_time.cpp). Pre-market runs from 04:00 to the session day's first open; post-market runs from its last close to 20:00. A break between windows is neither, and an overnight or 24-hour session has neither. Before, only the first window was read, with fixed bounds, so HKEX lunch bars read as post-market and an overnight window read as both. Pinned on TSE:7203, HKEX:700 and CBOT:ZC1! (15/60/240 minutes), ES1!, XAUUSD, EURUSD and ETHUSDT.P, with NASDAQ:AAPL as the single-window control.present_session_dayrow amended), atmax(label, slot eligible_open). On an extended-hours chart the regular day now ends on the 15:00 bar, and bars that open inside a break are in market.session.isfirstbar/islastbarmark the chart's session day, including extended hours; new_regularhost members carry the regular session. On AAPL 60 extended:isfirstbar04:00,islastbar19:00,isfirstbar_regular10:00,islastbar_regular15:00.session.ismarketgeneration comment now matches the tree.Verification (this exact tree)
ctest -Non top of the previous engine PR's rows.The population parity sweep of this exact tree is posted as
pineforge/parity.🤖 Generated with Claude Code
https://claude.ai/code/session_01LifAW9e5J6gFx7gatuxETE