Repository navigation
INT29: engine integration (W10 margin/cap, W11 session/color/time_close, W12 session-argument calendar, W13 margin calls) - #295
Merged
Merged
Conversation
…ed against their placement's position TradingView judges a MARKET entry it fills at the open after the bar that placed it against the position held at its placement. A sibling entry that filled at the same open a moment earlier does not count against it: two entries that each fit the equity alone both fill, and the excess margin is called at the fill, first in first out. The fill-time admission in validate_precommit counted the sibling's lot as held and refused the second entry, so pf-probe-thula-live-explicit-add-free-funds (six lanes, weak on all) kept one lot of each co-queued pair where TradingView keeps both and a margin-call slice. An entry the open trades already hold at the pyramiding cap keeps the whole-book requirement: TradingView refuses it at that check (H-MEASURE's first-eligible-point count). Pinned by two synthetic lab tv --no-note tapes (tests/fixtures/ coqueued_open_margin, BINANCE:ETHUSDT.P 15): flat long and short pairs over the equity, a pair inside it (control), two adds to a held long, and a single over-equity add (control); a fixed-default variant exports the same file. test_coqueued_open_margin_tapes fails before on 8633d944 (155 passed, 2 failed) and passes after (193 passed, 0 failed). test_adapter_live_state_equivalence: 2 of 108 digests move, re-harvested with PINEFORGE_V19E_HARVEST (the base reproduces every old value); an instrumented copy of the adapter shows the rule acting once in each and in no other configuration (reversals seeds 2827683 and 3141870, pyramiding 2). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit c0eaf49646a5e257d8430a30f4d6aed521e3fc40) INT29: tests/test_adapter_live_state_equivalence_data.hpp keeps main's digest rows here (INT28-FIX re-harvested them on 74491fa); the pins are re-harvested once on the integrated tree. tests/CMakeLists.txt: git's clean merge put this lane's fixture if() inside INT28-FIX RC's block; each block is closed on its own. validate_precommit composes this rule with W5B-ENG-MARGIN-RESIDUAL SB (on main): SB's flat_sibling_book branch runs first and judges a flat-placed entry that meets a book only its own bar's flat market entries opened; this rule's placement-held requirement applies to every other co-queued MARKET entry of the placement's side. INT29 pick note: W10-DIAG-UNKNOWN 1 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…site entry placed before it TradingView's strategy.risk.max_intraday_filled_orders counts the orders that fill. A strategy.close that fills is one of them, and an opposite entry the script placed AFTER that close on the same bar opens from flat and is another: from a long, close then short then a third fill trips the cap at the short. Only an opposite entry placed BEFORE the close has already closed the position by its reversal, so the close is void and the bar is one fill. The Pine cap's declared count-full-closes candidate let the co-queued opposite entry inherit the close's slot whatever order the script placed them in, so a close-then-entry bar counted once and the cap tripped a bar late. Pinned by two synthetic lab tv --no-note tapes (tests/fixtures/ intraday_cap_tv, BINANCE:ETHUSDT.P 15, process_orders_on_close, cap 3): days C and F (close, then short) and D (short, then close), with A, B and E as controls. test_intraday_cap_tv_tapes replays them with the three cap switches declared: fail-before on c0eaf496 110 passed, 2 failed (days C and F); after 106 passed, 0 failed. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 23840a41e4d5e547c94f7bb177501227875cb32e) INT29 pick note: W10-DIAG-UNKNOWN 2 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…nts as TradingView does The Pine cap component models TradingView's strategy.risk.max_intraday_filled_orders count with three candidate switches a host declares through metadata: a held-direction MARKET entry that pyramiding makes a no-op is not a fill (A), the cap's close for a same-bar process_orders_on_close fill is taken at the next open (B), and a strategy.close that fills the position is a fill (C). All three were off unless declared, and no generated strategy's host declares them, so the engine charged no-op entries, closed each cap trip at its fill and never charged a close. TradingView's tapes of synthetic probes show all three: officialjackofalltrades-regime-execution-strategy-joat (process_orders_on_ close, cap 6) books 505 of TradingView's 540 XAUUSD trades and 564 of 588 EURUSD, and both become byte-identical with the switches on. A Pine script's own cap statement (PineStrategyHost::set_pine_risk_max_intraday_filled_orders, which generated code calls) now turns on every switch its host did not declare; a declared switch keeps its value, and a component selected any other way (the protected legacy assignment the twins use, enable_pine_intraday_cap) keeps the component's defaults. IntradayCap records which keys were declared; the state hash folds that record only while the cap is active, so no run without a positive limit moves. Pinned by tests/fixtures/intraday_cap_tv (the two tapes of CAP-ORDER): test_intraday_cap_tv_tapes replays them with nothing declared, fail-before on 23840a41 153 passed, 2 failed; after 152 passed, 0 failed. test_adapter_quiet_bar: 4 of 272 runs move, the one scenario with a positive cap (IntradayCapDeferred), in their source-fold and hash columns only, re-harvested with PINEFORGE_QUIET_BAR_HARVEST (the base reproduces every old row). docs/pine-intraday-cap-boundary.md records the rule, and drops f864be5's sentence that all independent A/B/C combinations retain their existing defaults and scope: a script's own cap statement now turns on every switch it did not declare. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 5b5f7f35c3a6999a34ab5d2ba3592386f283ed9d) INT29: the digest pins (tests/test_adapter_quiet_bar_pinned.inc) keep main's rows here; they are re-harvested once on the integrated tree. INT29 pick note: W10-DIAG-UNKNOWN 3 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…w cannot pay for is refused Under process_orders_on_close a default percent_of_equity (at most 100) stop entry placed from flat, not yet marketable, is sized at its level. When a later bar opens through that level TradingView fills it at the open only if the equity it was sized from pays for its units there; otherwise it refuses the order, which is gone (a later cross of its level does not fill it). The adapter admitted the gapped fill and let a one-unit margin call take the excess. validate_precommit now refuses it. Pinned by three lab tv --no-note tapes of a synthetic probe on NASDAQ:AAPL 15 (tests/fixtures/pooc_gap_stop): with the default size G1, K1 and K2 fill at their gapped opens, G2 (486 sized at 211.17 from 102,630.93; 486 x 211.18 = 102,633.48) never fills; the fixed-1 tape fills G2, the tape without process_orders_on_close fills G2 485. tests/test_pooc_gap_stop_tapes.cpp fail-before on 5b5f7f35: 107 passed, 1 failed; after: 102 passed, 0 failed. Population probe vasudevshenoy-manoj-betrayed-me NASDAQ:AAPL 15: moderate -> excellent (361/361) on the lane replica. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 4091273d7217f3527cad1df7ff6f8c6e918e70fd) INT29 pick note: W10-DIAG-UNKNOWN 4 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
… position it closes still margined A default-size MARKET entry placed while flat can reach its fill after an earlier entry of its bar opened a position at the same open, and then reverses it. TradingView judges it against the equity it was sized from with that position still margined: its own side plus the held side must fit, or it refuses it and the held position stays. The adapter admitted it whenever its own side fitted, so at 100 % the reversal went through and a margin call trimmed it. Scoped to what the tapes pin: ordinary fills (no process_orders_on_close, calc_on_order_fills or stream), the fill at the open after the placing bar, the position opened this bar. Pinned by three lab tv --no-note tapes on NASDAQ:AAPL 1D (tests/fixtures/same_open_reversal, agent gjv): at 100 % no S1 or L3 ever fills; at 10 % every S1 and S2 reverses; at 50 % L1-CL1-S1 reverses (9,966,231.92 against 10,000,000) and L2-S2 does not (10,266,882.00 against 10,113,055.02). tests/test_same_open_reversal_tapes.cpp fail-before on 4091273d: 1754 passed, 2 failed; after: 1567 passed, 0 failed. Population probe htanrisevdir-trail-stop-al-sat-stratejisi on AAPL, NIFTY, F and XAUUSD 1D: strong -> excellent on the lane replica (AAPL and XAUUSD byte-identical). test_publication_witness: Config03 and Config03M re-pinned (digest only; the rule refuses three times in each, the only runs where it does, by an instrumented copy; 4091273d reproduces every old row). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit f9028183cfa2e8cd0e8583c8bd56c203a52015e1) INT29: the publication-witness pins (tests/test_publication_witness.cpp's harvest ledger and tests/test_publication_witness_pinned.inc) keep main's rows here; they are re-harvested once on the integrated tree. INT29 pick note: W10-DIAG-UNKNOWN 5 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…ntraday-risk-01 The corpus probe declares strategy.risk.max_intraday_filled_orders under process_orders_on_close and no intraday_cap_* switch, so rule CAP-ON (70ea8a37, tests/fixtures/intraday_cap_tv) turns on all three of its switches. Its engine_trades.csv moves 356f4d7b -> de41c699 (the sha256 scripts/corpus_trades_identity.py takes: LF-normalised text), re-derived with scripts/run_strategy.py on this tree's build of the probe's generated.cpp at the corpus gitlink b40aa8e. Against the probe's own TradingView tape the move is towards TradingView: of its 302 trades, the base engine's exits differ on 6 (147, 177, 206, 214, ...: the cap's close taken at the fill instead of the next open), this tree's on 1 (264, a Gatekeeper Guard exit one bar late, unchanged). Tier excellent before and after. The same procedure on the base 8633d944 reproduces the old pin, and the control probe analyzer-anvil-percent-costs-01 reproduces its pin on both trees. No other corpus probe moves in the lane's population replays (exp-w10-diag-pop3/pop4-20260928). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 6bd9c1068c84dd6ccb6f7d9740c18e9e709e9c9c) INT29: main (INT28) had already moved this probe's pin (356f4d7b -> 46e06bbf); on the integrated tree CAP-ON moves it on to 34fddd5f, the value this commit pins, re-derived with the lane's procedure (the probe's generated.cpp at the corpus gitlink b40aa8e, built against this tree's library, scripts/run_strategy.py, LF-normalised sha256). The same procedure on main 74491fa reproduces 46e06bbf, and the control analyzer-anvil-percent-costs-01 reproduces its pin. Five trades move (147, 177, 206, 214, 258: the cap's close now at the next open), and against the probe's TradingView tape the integrated tree books all 302 trades exactly (scripts/verify_corpus.py: exit p100 0 %, main 1.0869 %). INT29 pick note: W10-DIAG-UNKNOWN 6 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…ses a same-open position only if both sides fit A position is held; on one bar the script places the reversing entry and then an entry on the held side (at the pyramiding cap when placed). At the next open the first reverses the position; the second is then a reversal of a position its own bar's market entry opened at that open. TradingView judges it as it judges a same-open reversal placed while flat: its own side plus the held side must fit the equity it was sized from, or it is refused and the position stays. The rule now covers an entry placed flat or on its own side, and requires the position to have been opened by a market entry (position_open_priced_ false). Pinned by two more lab tv --no-note tapes on NASDAQ:AAPL 1D (tests/fixtures/same_open_reversal/w10-sameopen-held-a100, -b10): at 100 % no S1 or L2 ever fills; at 10 % every S1 reverses L1 back and every L2 reverses S2 back. A cap checked when the order is placed would refuse the 10 % ones too, so it is the margin, not the pyramiding count. tests/test_same_open_reversal_tapes.cpp now replays five tapes; fail-before on e8170ffa: 3024 passed, 1 failed (held-a100); after: 2983 passed, 0 failed. The held-b10 S2-L2 cells (TradingView reverses back at 10 %, the engine keeps S2 as the base engine does) are left out: the rule only refuses. Population probe job-2614-andrewwieiw-frosty-alerts, whose first divergence on BTCUSDT, EURUSD and ETHUSDT.P 15 is that pattern (lane replica, base -> this tree): BTCUSDT weak -> strong (count delta 34 -> 1), EURUSD moderate -> strong (126 -> 9, pnl p90 118.88 -> 5.66), ETHUSDT.P (hard) weak, every metric better (120 -> 13, coverage 82.4 -> 84.1 %), XAUUSD moderate (110 -> 14, coverage 93.5 -> 92.9 %: that lane is a bar early on every trade from TradingView's first, on every engine). htanrisevdir's four lanes are unchanged. test_adapter_quiet_bar: Random35's four runs re-pinned (one refusal in each, the only runs where the rule refuses, by an instrumented copy; one trade fewer); test_publication_witness unchanged. Doc anchors into pine_adapter.cpp moved through the line map (56) and one snippet cite by hand. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 26deaa687b670ae50146763d0235254744d8ff54) INT29: the four doc pages keep main's text (this commit's doc hunks re-number anchors only, and are redone once on the integrated tree), the quiet-bar digest pins keep main's rows (re-harvested once on the integrated tree), and tests/fixtures/same_open_reversal/README.md takes the lane's text (its fail-before note had been reworded by the skipped floors commit e8170ffa). INT29 pick note: W10-DIAG-UNKNOWN 7 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…open close Two rows pinned the base engine's cap close for a same-bar MARKET fill under process_orders_on_close: at the fill bar's high or close. Rule CAP-ON (5b5f7f35) makes a script's own cap statement count as TradingView does, and TradingView takes that close at the next open (tests/fixtures/intraday_cap_tv, days A-C). The release run of e8170ffa (lab remote rj-20260928t053433-168323) failed exactly these two rows. - test_adapter_risk_relower MG13 and MG14: the adapter literals are re-harvested with the test's PF_DUMP switch (the cap rows now close at bar 2's and bar 25's open), their CHECK literals and comments follow; the kernel literals and every other row are unchanged. - test_l10l_corpus_parity scenario 2 pins the CloseNow slippage path of the cap: its host now declares intraday_cap_defer_pooc_close = 0, the switch that selects it, and keeps its owner literals. (TradingView's own cap-gatekeeper-intraday-risk-01 #258 exits at 09:00 on the Gatekeeper Guard, not on a cap close; the engine books it so.) Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit b260956b3e4fcbf72e96d3d46af823b40bbfcbfc) INT29 pick note: W10-DIAG-UNKNOWN 8 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…ssion and the magnifier keep the rule Four more lab tv --no-note tapes on NASDAQ:AAPL 1D (tests/fixtures/same_open_reversal): - w10-sameopen-shapes-base: a Long and a Short from flat plus a third call (a Long under another id, the Short again, a priced stop that never fills, a raw strategy.order, a third entry cancelled on the bar): no Short ever fills in any cell; - w10-sameopen-shapes-mag: the same with the bar magnifier, the same trades; - w10-sameopen-pair-comm: the bare pair under a 0.1 % commission: no Short ever fills; - w10-sameopen-shapes-slip: the same shapes with slippage 1: TradingView runs the Short close-only (the Long closes on it, no short opens), except the replaced Short, which it refuses. The rule is therefore scoped to zero slippage, a behaviour it does not model; tests/test_same_open_reversal_tapes.cpp replays shapes-base (but the raw order, which the adapter fills an open later, as before) and pair-comm, and reads -mag's and -slip's rows. 3881 passed, 0 failed. test_default_flat_market_gross_admission_l4d (the A29 twin of the base engine's exact-pair rule) pinned the controls as ordinary reversals: its exact-book controls with a third call, and its commission and magnifier configuration controls now keep the Long alone, as the tapes do (expectation corrected in its tables; CHECK texts, and so twin parity, unchanged); its slippage control keeps the reversal. The release run of e8170ffa failed that row. With slippage out of scope the rule no longer fires in test_publication_witness (Config03, Config03M) or test_adapter_quiet_bar (Random35): both carry slippage, and their pins go back to the rows before SAMEOPEN-REV, which this tree's harvest reproduces byte for byte. Doc anchors into pine_adapter.cpp moved through the line map. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 3c5ed053af26dfe30936adb8dc187aa613efb90d) INT29: the four doc pages keep main's text (this commit's doc hunks re-number anchors only, and are redone once on the integrated tree); the quiet-bar and publication-witness digest pins keep main's rows (the lane's SAMEOPEN-REV ledger paragraph this commit deletes was never picked); both are redone once on the integrated tree. INT29 pick note: W10-DIAG-UNKNOWN 9 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…to the book its tapes pin The held-side form (26deaa68) is pinned by tapes whose book at the open is the bar's market entries alone (tests/fixtures/same_open_reversal, w10-sameopen-held-*). The base engine's live-position rule pins the same decline for that book and an ordinary reversal once a priced or raw order, or one carried in from an earlier bar, is in it (test_live_position_market_gross_admission_l4d, an A29 twin whose checks are frozen); the release and debug runs of 3c5ed053 (rj-20260928t061833-85258f, rj-20260928t061834-a8bb41) failed exactly its three controls. The held-side form now requires that book: no RAW order, live or parked behind the pair (delayed_market_orders_), and no priced entry or entry of an earlier bar. The flat-placed form is unchanged; its tapes cover third orders (w10-sameopen-shapes-base). test_live_position_market_gross_admission_l4d: 25 passed, 4 failed before, 29 passed, 0 failed after. test_same_open_reversal_tapes 3881/0, the l4d flat twin 163/0 and every digest battery unchanged. On the lane replica job-2614-andrewwieiw-frosty-alerts' BTCUSDT, EURUSD, ETHUSDT.P and XAUUSD 15 trades are byte-identical to the unscoped form's. Doc anchors into pine_adapter.cpp moved through the line map. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 479fb899cd010c5beecc28c71a018ef17061e1e7) INT29: the four doc pages keep main's text (this commit's doc hunks re-number anchors only, and are redone once on the integrated tree). INT29 pick note: W10-DIAG-UNKNOWN 10 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…, "2400" the day's end time(), time_close() and the session predicates read each window of a session argument through hhmm_to_minutes, which refuses an hour of 24, so a "0000-2400" window was skipped: time(timeframe.period, "0000-2400") answered na on every bar, and the session gate of the ten ai-distribution-express-ttv-strategy-v0-2 probes never opened (XSYM-C). TradingView reads each HHMM of a window as HH * 60 + MM minutes after a day's midnight and checks neither part: "2400" is the day's end, "2430" 00:30 on the next day, "0060" 01:00. An end at or before the start is on the next day, and a time of day is in the window when it, or it on the next day, falls in [start, end). local_time_in_session_windows now reads its windows that way (session_clock_minutes). A window whose clocks lie in 0000..2359 reads exactly as before; only the 24xx and xx60+ spellings, skipped until now, change. Tapes: tests/fixtures/session_clock (lab tv --no-note): BINANCE:BTCUSDT 15 across the 2025-03-09 US DST switch, BINANCE:BTCUSDT 1D, OANDA:XAUUSD 15, and eleven edge forms on BINANCE:BTCUSDT 15 (2400-0100, 2430-0100, 0000-0060, 2330-2430, 1700-2500, 0000-2401 / 2430 / 2500 / 2360 / 9959, 2400-2400), each accepted by TradingView. Pinned by tests/test_session_predicates.cpp (test_session_2400_tapes: 13,140 readings; test_session_clock_edge_tapes: 2,101 bars): 80 passed, 14 failed on 4efcb8c; 94 passed, 0 failed here. Moved pin, attributed to the tapes: the "0000-2400" row of tests/test_session_ismarket_tape.cpp (H-MEASURE G2-36) pinned the predicate's 97 misses on hm-g236-eth-60-24x7; it now reads all 97 bars in market, as TradingView's tape does. Two readings of where a D period opens under a session argument differ from TradingView on these tapes and are another rule's, reported by the lane: time("D", session) keys its day on UTC where TradingView keys it on syminfo.timezone (w11-sess2400-xau15 field d), and on a D chart time(timeframe.period, session, tz) floors to the tz's day where TradingView answers the bar's own time (w11-sess2400-btc1d field k). The test compares only whether those bars are in the window. ADR-0001 rule 1: session_time is the language calendar runtime. The window test is a function of the session string, the zone and the instant, the same for every venue; no kernel order, fill, settlement, margin or hash code calls it; its calibration is recorded at the site (the tapes above). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit e57029e638e4c09f29b96d1092955c3dc8a2cbaf) INT29 pick note: W11-ENG-TIME-COLOR 1 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…dmits Monday to Friday
With no day list after its windows, a session argument of time(),
time_close() and the session predicates admitted every day. TradingView
admits one window on every day, but several windows on Monday to Friday only;
a day list is taken as written.
passes_session_filter now gives a session of several windows and no day list
the days 23456, when each window ends after it starts
(several_same_day_windows). A window across midnight makes the session's
days session days -- CBOT:ZC1!'s 1900-0745,0830-1320 opens Monday's session
on Sunday evening, in market on TradingView's tapes -- which this reading of
one instant's weekday cannot give, so such a session keeps its every-day
reading (tests/test_session_break_open_bar_tape.cpp's ZC1 rows are
unchanged). One window, a day list, "24x7" and the empty session read as
before.
Population: doriannnq-tjr-v4-strategy (9 probes) reads time() through
"0825-0835,0955-1005"; on its crypto lanes TradingView's window is closed on
weekends.
Tape: tests/fixtures/session_clock/w11-sessmask-btc15 (lab tv --no-note,
BINANCE:BTCUSDT 15, 2025-03-06 .. 2025-03-12): seven sessions, one window
and several, with and without a day list. Field g of the w11-sess2400 tapes
("2300-2400,0000-0100": Sunday 23:00 and Saturday 00:00 out) is now replayed
too. Pinned by tests/test_session_predicates.cpp
(test_session_day_list_tapes: 4,025 readings; test_session_2400_tapes with
g): 93 passed, 4 failed on the previous commit; 97 passed, 0 failed here.
ADR-0001 rule 1: session_time is the language calendar runtime. The day list
a session argument implies is a function of the session string alone, the
same for every venue; no kernel order, fill, settlement, margin or hash code
calls it; its calibration is recorded at the site (the tape above).
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(cherry picked from commit ef973bf3d75e6713db6e21f3ca01a9907a8f404d)
INT29 pick note: W11-ENG-TIME-COLOR 2
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…w does, and the named colors are Pine v6's color.hpp stored a transparency t as the alpha byte (int)((100 - t) * 2.55), truncated, and read a byte a back as 100 - a * 100 / 255 in integer division. color.new(c, 90) therefore read back 91, color.new(c, 0) read back 1, and 96 of the 101 whole transparencies read back wrong (XSYM-C: color.t in the jdehorty/MLExtensions tape). Six named constants were neither Pine v5's nor v6's: red was #FF0000, and black, blue and silver were wrong in both versions. TradingView stores t as the alpha byte nearest 255 * (100 - t) / 100 and reads a byte back as 100 - a * 100 / 255 rounded to the nearest whole number, so a whole t reads back as itself. new_color now rounds, clamps to the byte and takes the transparency as a double: every int caller converts exactly, and a fractional transparency goes through the byte as on TradingView (10.5 reads 11, 20.5 reads 20) once the transpiler passes it unrounded -- color_alpha_cast truncates it to an int today, the transpiler's change to make. An na transparency reads as 100, as the transpiler already passes a missing one. t() rounds half up on the byte, and no byte sits on a half. The named constants are Pine v6's: red #F23645, blue #2962FF, black #363A45, yellow #FDD835, silver #B2B5BE, teal #089981; the other eleven were right. Pine v5 spells red #FF5252, teal #00897B and yellow #FFEB3B, which the transpiler lowers for a v5 library (XSYM-C's library_v5 _V5_COLORS) and has yet to lower for a v5 script. Population: no scraped probe compares, prints or reads a color's components, so no trade moves. Tapes: tests/fixtures/color_tv (lab tv --no-note, BINANCE:ETHUSDT.P 15): w11-color-v6-eth15 and its v5 twin w11-color-v5-eth15 (r,g,b,t of the seventeen constants; color.t of color.new / color.rgb / a nested color.new for t = 0 .. 100 and t + 0.5), w11-color-alpha-eth15 (color.t of #FF0000xx for all 256 bytes). Pinned by tests/test_color_tapes.cpp (new source-free row, kernel profile too): 12 passed, 9 failed against 4efcb8c's color.hpp; 21 passed, 0 failed here. ADR-0001 rule 1: color.hpp is the header-only runtime of generated strategies (ruled retained, no kernel translation unit includes it). The encoding is a function of its inputs, the same for every venue; no kernel order, fill, settlement, margin or hash code reads a color; its calibration is recorded at the site (the tapes above). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit a451e3c5e2727ab4aa9bd66663d7b01d6341c129) INT29 pick note: W11-ENG-TIME-COLOR 3 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…, direction 1 from bar 0 ta::Supertrend, which generated code builds for a literal or input factor and period, answered na for the line and the direction until its ATR was valid, then seeded its bands unratcheted and its direction from the first valid bar. TradingView runs Pine v6's reference implementation from the run's first bar. Each band is ratcheted against nz(band[1]) and close[1], and a comparison with na is false, so with no close[1] on bar 0 both bands keep nz's 0 and bar 0's line is 0; bars 1 .. atrPeriod - 1 answer na; the direction is 1 while atr[1] is na. On the ta/7 tape the ta.supertrend readings of the first two hours (bars 1, 3, 5 and 7) were na in the engine and 1 on TradingView: 664 of 672 Signals matched (XSYM-C). Supertrend::compute now runs that reference from the first bar, in the class's existing members (initialized_ holds whether atr[1] was valid): no layout or hash change. After the warm-up it is the same arithmetic as before but at the first valid ATR bar, whose direction is now 1, and on a lower band the reference pins at 0 (a factor so large that hl2 - factor * atr turns negative). It is the rule PineSupertrend (the series-factor class) already follows; na OHLC input still answers na without advancing the state. Moved pin: tests/test_ta_voltrend_edge.cpp test_supertrend_flip's first bar, pinned (na, na), is now (0, 1), TradingView's; its later bars are unchanged. Tapes: tests/fixtures/supertrend_warmup/w11-st-warmup-eth15 (lab tv --no-note, BINANCE:ETHUSDT.P 15, 2025-04-01 .. 04-03; ta.supertrend(3, 10), (2, 1), (1000, 5), (0.5, 3) and an input pair from bar 0, the chart's bars embedded from the corpus 1m feed), and in the lane's scratch w11-st-warmup-btc1d (BINANCE:BTCUSDT 1D, the same rule on a daily chart). Pinned by tests/test_ta_voltrend_edge.cpp (test_supertrend_warmup_tape, 191 bars and bar 0): 53 passed, 4 failed on 4efcb8c's ta::Supertrend; 57 passed, 0 failed here. Doc anchor: docs/design/native-feature-parity.md row b's plus_dm citation ta_volatility_trend.cpp:356-359 -> :329-332 (the function above it is shorter; digits only). ADR-0001 rule 1: ta_volatility_trend is the indicator library of the language runtime. ta.supertrend is a function of its bars, the same for every venue; no kernel order, fill, settlement, margin or hash code calls it; its calibration is recorded at the site (the tape above). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 972acb702d67e45c120b35e96c35c612ceff7c9d) INT29 pick note: W11-ENG-TIME-COLOR 4 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…last traded close
PineStrategyHost::time_close() answered the chart bar's close through the
time-of-day session filter of time_close(timeframe.period, syminfo.session,
syminfo.timezone). OANDA stamps its XAUUSD daily bars at 17:00 ET, inside the
17:00-18:00 break of the 1800-1700 session, so every bar of the xauusd-1d
lanes read as out of session and time_close was na (XSYM-E). Where the
filter passed, the close was the chart timezone's calendar-day end: 23:59:59.999
ET for a NASDAQ:AAPL daily bar and the wrong day for OANDA:EURUSD.
TradingView closes a D, W or M chart bar at its period's last traded close,
to the millisecond, whatever time of day its stamp reads: XAUUSD 1D at the
next 17:00 ET, XAUUSD W on Friday 17:00 ET, XAUUSD 1M at the month's last
traded 17:00 ET, EURUSD 1D at the next 17:00 ET, AAPL 1D at 16:00 ET,
BTCUSDT 1D at the next 00:00 UTC. On a calendar chart time_close() now
answers session_period_last_traded_close_ms of the bar's period on the
symbol clock (chart_time_close, out of line so the installed header keeps
its lines). The intraday path and a foreign payload's close are unchanged.
Exchange holidays and early closes are not modelled. TradingView closes
AAPL's 2025-07-03 at 13:00 ET, and XAUUSD's week and month that ended on
2024-11-29 at 14:45 ET (the daily bars keep 17:00), and so did the XSYM-E
early-close days of AAPL 1D (3) and ES1! 1D (8). A daily bar's actual close
is feed or calendar data the run does not hold, not a rule the engine can
derive, and the three tape readings are pinned as such.
Population: no probe on a D lane reads the chart's time_close (inside a
request.security payload the transpiler renders its own); BTCUSDT and
ETHUSDT.P daily bars close 1 ms later than before, exactly at TradingView's
boundary.
Tapes: tests/fixtures/daily_break_close/w11-tclose3-{xau1d,btc1d,eur1d,
aapl1d,xauw,xaum} (lab tv --no-note): time_close - time in milliseconds.
Pinned by tests/test_engine_trade_accessors.cpp
(test_chart_time_close_tapes, 445 bars): 65 passed, 8 failed on 4efcb8c;
73 passed, 0 failed here.
Pine policy, source layer only: no kernel change, no ADR-0001 ruling.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(cherry picked from commit 6bc0e4dcfd633f82d7fc9fa72a4884610f5a49b8)
INT29 pick note: W11-ENG-TIME-COLOR 5
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…session day
The day list of a session argument -- as written, or Monday to Friday for
several windows with none (1b) -- was tested against the instant's own
weekday, and 1b applied its default only to sessions whose windows all end
after they start. TradingView tests the list against each window's session
day: the day the window starts, but the day it ends for a window that ends
at or before its start, past midnight. "1700-1700:23456" runs from Sunday
17:00 to Friday 16:45; "1800-0200:23456" and "2330-0030:23456" admit
Sunday evening and not Friday evening; "2330-2430:23456" keeps Friday's
00:00-00:30 tail on Saturday and drops Sunday's on Monday; "0000-0000:23456"
is the calendar's weekdays. The default holds for several windows whether
or not one opens at 00:00 ("0930-1130,1300-1500" admits no weekend bar, in
UTC or New York). The independent review of the lane asked for exactly
those shapes; they read otherwise before this commit.
passes_session_filter now applies the list through
local_time_in_session_days, which finds the window a time of day lies in
and the day that window opened, and tests that window's session day. With
no list and one window the reading is unchanged (every day), and a list on
windows that start and end within one day reads as before.
several_same_day_windows is gone: a window across midnight is handled by
its session day, so CBOT:ZC1!'s 1900-0745,0830-1320 still opens Monday's
session on Sunday evening (tests/test_session_break_open_bar_tape.cpp
unchanged).
Moved pins, attributed to their own tapes: the five ":23456" rows of
tests/test_session_ismarket_tape.cpp (H-MEASURE G2-36), where the
predicate put each Sunday-evening open out of market (14, 14, 14, 14 and 12
bars) while TradingView flags every bar M1, now agree on every bar.
Population: no scraped probe spells a day list on a session that crosses
midnight; doriannnq-tjr-v4-strategy's "0825-0835,0955-1005" reads as in 1b.
Tapes: tests/fixtures/session_clock/w11-sessmask2-btc15 and
w11-sessmask3-btc15 (lab tv --no-note, BINANCE:BTCUSDT 15, 2025-03-06 ..
2025-03-12). Pinned by tests/test_session_predicates.cpp
(test_session_day_list_tapes, 10,925 readings): 101 passed, 2 failed on
the previous commit; 103 passed, 0 failed here.
ADR-0001 rule 1: session_time is the language calendar runtime. The session
day of a window is a function of the session string and the instant, the
same for every venue; no kernel order, fill, settlement, margin or hash code
calls it; its calibration is recorded at the site (the tapes above).
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(cherry picked from commit 58aab09e17f858c5adfb5b51ad8a04aa7e95d91b)
INT29 pick note: W11-ENG-TIME-COLOR 6
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
… once per bar ta::Supertrend::recompute restored the bands' saved state and then called compute, which computed the ATR inside again: the ATR's RMA advanced a second time on every recalculated bar, and every later bar of the run read a wrong line. Generated code recalculates a bar through recompute when the bar is not a new history slot (a calc_on_order_fills recalculation, a realtime tick), so the ATR drifted there. Found by the lane's independent review of 4; it predates the lane. compute and recompute now share one step: the first computation of a bar computes the ATR, a recalculation recomputes it from its own saved state, as the bands do from theirs -- the way PineSupertrend (the series-factor class) already does. An na recalculation restores the ATR too, so it leaves no advance of its own behind. compute is unchanged; ta.hpp gains a private step declaration after the lines any document cites. Doc anchor: docs/design/native-feature-parity.md row b's plus_dm citation moves with its lines (digits only, through an exact line map). Population: no scraped ta.supertrend probe recalculates a bar in a batch run (none declares calc_on_order_fills), so the replay moves nothing. Pinned by tests/test_ta_voltrend_edge.cpp (test_supertrend_recompute_is_one_computation: a first tick then the bar's recalculation equals one computation, bar after bar; an na recalculation leaves the next one exact): 77 passed, 10 failed on the previous commit; 87 passed, 0 failed here. ADR-0001 rule 1: ta_volatility_trend is the indicator library of the language runtime. A recalculation equal to one computation is a function of the bars alone, the same for every venue; no kernel order, fill, settlement, margin or hash code calls it. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 215533c40b77c1fa18da86f2e1ad262202fb7fd5) INT29: docs/design/native-feature-parity.md takes this commit's plus_dm anchor (ta_volatility_trend.cpp:337-340) and keeps main's native-consumer anchor in the neighbouring row (`:9075`; the lane's `:9092` counts the unpicked kernel commit c6170f57). INT29 pick note: W11-ENG-TIME-COLOR 7 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…on closes with the session it opens 3 closed a D/W/M chart bar at the last traded close of the period its stamp falls in. A stamp outside the session -- a daily bar a feed dates at midnight, before the open, or after the close -- falls in the previous session day on the symbol clock, so its time_close came before the bar itself: a 0930-1600 daily bar stamped 00:00 ET closed at 16:00 ET the day before, a weekly bar stamped Monday 00:00 ET on the previous Friday (the lane's independent review). 4efcb8c answered na for these stamps. chart_time_close now maps the stamp to the session it covers first (session_covered_instant_ms: a stamp before the open or at or after the close covers the session about to open, as OANDA's 17:00 ET break stamp does), then closes that session's period. A stamp inside its session, and the 17:00 ET XAUUSD stamp, read as in 3; TradingView stamps its own daily bars at the session open, so every tape of 3 is unchanged. Pinned by tests/test_engine_trade_accessors.cpp (test_chart_time_close_gap_stamps: three daily stamps outside 0930-1600 and a weekly Monday-midnight stamp close at the covered session's 16:00 ET, after the bar; the in-session stamp unchanged): 75 passed, 8 failed on the previous commit; 83 passed, 0 failed here. Pine policy, source layer only: no kernel change, no ADR-0001 ruling. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit b2ad28622e783a8cf41412468f6113b397a65c76) INT29 pick note: W11-ENG-TIME-COLOR 8 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The comment of new_color said an na transparency reads as 100. That holds for a NaN double, the value an na float carries. An int na is INT_MIN, which the double parameter reads as far below 0, so it clamps to opaque (under the int parameter before 2 it overflowed). The transpiler never passes one: color_alpha_cast maps an na transparency to 100 before the call. The comment now says so (the lane's independent review). Comment only. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 9586a63d1c532706b2591b1426629d164bbec503) INT29 pick note: W11-ENG-TIME-COLOR 9 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…endar days; the default counts windows that read
1c read a day list through each window's session day, but a 24-hour body
with a list ("24x7:23456", ":23456") has no window to read: time() and
session.ismarket's predicate answered na / false on every bar, where
4efcb8c admitted the listed calendar days (the kernel calendar builds an
all-day session with the mask). And any comma implied several windows, so
"0930-1600," took the Monday-to-Friday default. Both found by the lane's
independent review of 1c; TradingView's reading of neither spelling is
taped, so each reads as it did before 1b.
passes_session_filter now reads a 24-hour body under a list as
"0000-0000", whose session day is the calendar day, and gives the
Monday-to-Friday default only to a session with two or more windows whose
clocks read (session_window_count).
Pinned by tests/test_session_predicates.cpp
(test_session_day_list_edges): 106 passed, 4 failed on the previous commit;
110 passed, 0 failed here. Every tape of 1, 1b and 1c reads as before.
ADR-0001 rule 1: session_time is the language calendar runtime; a function
of the session string and the instant, the same for every venue, called by
no kernel order, fill, settlement, margin or hash code.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(cherry picked from commit ca7f91c9ef1985745276639054cb162879938fb7)
INT29 pick note: W11-ENG-TIME-COLOR 10
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…loses with the period it opens 3c closed a calendar chart bar with the session its stamp covers. A W or M bar dated on a weekend its session does not trade -- a Sunday-dated week or month of a 0930-1600 equity -- covers that weekend day's session, which the symbol clock counts in the period that has already closed, so its time_close still came before the bar: the week of Sunday 2025-03-02 closed on Friday 02-28, the month of Sunday 2025-08-31 on Friday 08-29 (the lane's independent review of 3c). TradingView dates its own weekly and monthly bars at the first session day's stamp, so no tape reaches this. chart_time_close now reads a close at or before the bar's own time as the next period's: the last traded close of the period that opens where this one closes (session_period_close_ms). A chart bar's time_close is after its time on every stamp. Pinned by tests/test_engine_trade_accessors.cpp (test_chart_time_close_gap_stamps, the Sunday-dated week and month): 83 passed, 4 failed on the previous commit; 87 passed, 0 failed here. Every tape of 3 reads as before. Pine policy, source layer only: no kernel change, no ADR-0001 ruling. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 4d43785dace5e0ebb1bbb47d8deeb80fffbc88a0) INT29 pick note: W11-ENG-TIME-COLOR 11 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…ng (case 12, adapter-only) Lane W11-ENG-TIME-COLOR's commit c6170f57 changed the kernel (pump_instrument_subscription in src/native_execution_consumer.cpp and the NativeInstrumentFeed delivery rule in include/pineforge/native_run_spec.hpp) so that a D/W/M label stamped in its session's break opens the next period for an instrument series. It is not picked: the Pine adapter never changes the kernel's generic mechanics (owner rule), and lane W12-ENG-TIME carries TradingView's reading into the adapter. Its test half came with it: case 12 of tests/test_native_instrument_feed.cpp asserted the new kernel reading (17,788 checks, 903 failures without it) and its two TradingView tapes (w11-tclose-xau1d, w11-tclose-la-xau1d) documented the DXY requests. This commit keeps that case to what the adapter-only tree does. The tapes come over unchanged (tv_trades.csv and strategy.pine shas as W11 recorded them), and case 12 rebuilds the same synthetic shape -- an XAUUSD-like daily chart stamped at 17:00 ET under 1800-1700, a DXY-like daily feed and an hourly one, lookahead off and on -- through a bare kernel host, but checks the kernel's generic reading: each raw label reads its calendar interval (the session that closes at a Monday-to-Thursday label, opened at 18:00 ET the day before; the Sunday label's weekend slot as measured), the delivery rule written out independently of the kernel (check_against_rule), and every per-label read pinned in hours from the label. TradingView's readings, from the tapes, are written beside them and counted: 38 of the 40 reads differ, all but the Sunday labels' lookahead-off daily reads. The fixture README says the same. What changed against W11's version: case 12 pins the kernel's reads (daily off -70/-22 h, hourly off 0 h, hourly on -23 h, daily on -24/-48/-46 h on Monday to Thursday; -46/-48/-49/-70 h on Sunday) where W11 asserted TradingView's (+2, +24, 0, and the by-label daily-on read); the native_run_spec.hpp comment and the five doc anchors W11 moved stay main's. test_native_instrument_feed: 17,800 checks, 0 failures (main: 12,375). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…View's tape of the composition Lane W10-DIAG-UNKNOWN was built without lane W5B-ENG-MARGIN-RESIDUAL, which main now carries (INT28-FIX). Their fill-time margin rules meet in PineExecutionAdapter::validate_precommit: W5B's SB (a flat bar's same-side MARKET entries each fill on their own cost) and PA (an add is judged on its combined margin with no lot of slack), W10's COQ (a MARKET entry filled at the open after its bar is judged against the position held at its placement, not a same-open sibling) and SAMEOPEN-REV (a default-size reversal of a same-open position must fit with that position still margined). SB's branch runs first and decides a flat-placed sibling; COQ's placement-held requirement then covers the co-queued entries placed on the held side; SAMEOPEN-REV and PA share the frozen-sizing arm, one on a reversal and one on an add. TradingView, on a synthetic probe written for INT29 (lab tv --no-note, BINANCE:ETHUSDT.P 15, 2025-04-01 .. 05-01; tests/fixtures/int29_compositions int29-c1-open-pairs, 432 trades): 120 cells, five kinds in turn, every cell of a kind booking the same shape -- - A (SB): two flat longs of 60 % both fill at one open; the call there takes the first whole and the second in part; - B (COQ): a seed of 30 %, then two explicit adds of 40 %: both fill; - C (SB + SAMEOPEN-REV): from flat a long of 80 %, a default short and a long of 30 % on one bar: both longs fill, the short is refused, the long book is called at that open; - D (COQ + PA): a seed of 50 %, then an explicit add of 30 % and a default add (30 %): BOTH fill, and the call takes part of the seed; - E (PA pair): a seed of 50 %, then two default adds: both fill, the seed is called in part. A, B and C already held on the integrated tree. D and E did not: a default add goes through the frozen-sizing arm, which judged it on the whole book, same-open sibling included, and refused the second add of every cell (24 + 24). TradingView judges it as COQ judges an explicit add: on the position held when it was placed plus itself, with PA's no-slack guard. The frozen arm now does so for a MARKET add filled at the open after its bar while more than its placement's held quantity is open (COQ's own scope: placed flat or on its side, the pyramiding cap not yet reached), reading the held quantity from the placement's projection_tv_carry_qty. A single add has no sibling, so PA's own tapes do not move. test_int29_rule_compositions (new) replays the tape trade for trade and reads each kind off TradingView's rows. Fail-before on 2e31430 (the picks without this rule): "2432 passed, 1 failed" -- the engine books 336 of the tape's 432 trades, first difference in cell D. After: "2721 passed, 0 failed". The lanes' own tapes pass unchanged on this tree, and in them the rules already act together (an instrumented copy of the adapter, scratch only): w10-coq-flat-pair runs SB three times and COQ once, w10-sameopen-shapes-base SAMEOPEN-REV 33 times and SB 4 times. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…ors commit did Lane W10-DIAG-UNKNOWN's floors-and-docs commit e8170ffa is not picked (INT29 redoes floors and anchors once on the integrated tree), but it also carried one source fix: include/pineforge/compat/pine/intraday_cap.hpp's CAP-ON comment named the Pine statement max_intraday_filled_orders, which the source guard check_dangling_comment_names flags (no such identifier in the compile closure). The comment now names the host setter it reaches through, PineStrategyHost::set_pine_risk_max_intraday_filled_orders, word for word as e8170ffa did; check_dangling_comment_names: 1 finding -> 0. Comment only. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…wn, in its timezone
time(tf, session, tz) and time_close(tf, session, tz) under a D, W or M tf
filtered the bar through the session's windows and then floored it to a
calendar day, week or month of the explicit tz, else UTC
(resolve_session_tz / compute_tf_open_ms, src/session_time.cpp). Lane
W11-ENG-TIME-COLOR's report read two symptoms of that: time("D", session)
keyed its day on UTC where TradingView keys it on syminfo.timezone
(w11-sess2400-xau15 field d), and on a D chart time(timeframe.period,
session, tz) floored to the tz's day where W11 read TradingView's answer
as the bar's own time (w11-sess2400-btc1d field k).
TradingView reads neither: it builds the tf bar on the session argument
itself, in the session's timezone (the explicit tz, else
syminfo.timezone). Every session day -- a window's day is the day it
starts, the day it ends for one past midnight, and a list, given or the
Monday-to-Friday default of several windows, leaves days out, as
local_time_in_session_days reads them -- is one D bar from its first
window's open to its last window's close; a W or M bar opens at the first
session day of its Monday-start week or calendar month and holds every
instant until the next one opens. On OANDA:XAUUSD 15 time("D",
"0000-2400") opens at New York's midnight, time("D", "1700-2400",
"America/New_York") at 17:00 New York, time("D", "1800-1700") at 18:00 the
day before, and a bar in the break of "0930-1130,1300-1500" reads the day
that opened at 09:30; a bar no day bar holds reads na, a W or M bar never
does. time_close("D") is the day bar's close (16:00 for "0930-1600");
time_close("W"/"M") is the next period's open on an intraday chart and the
close of the period's last session day on a daily chart. On
BINANCE:BTCUSDT 1D, time(timeframe.period, "1700-2400",
"America/New_York") reads 17:00 New York, not the bar's 00:00 UTC time
(W11's field k read the bar's own time only because "2000-2400" opens at
the bar's instant in summer), and time(timeframe.period, "0000-2400",
"America/New_York") reads New York's midnight. On a daily chart a window
spelled past midnight without wrapping ("2330-2430") ends at the week's
end when it opens on a Saturday: TradingView reads Sunday's 00:00 bar as
na there, where its 60-minute chart and a wrapping "2330-0030" read
Saturday's 23:30 open.
session_argument_bar (src/session_time.cpp) is that bar, with exact wall
clock (native_calendar::resolve_civil: New York's midnight on the
2025-03-09 switch is 05:00Z, where the tz-only calendar floor's mktime
read 04:00Z) and a per-thread memo of each session day. The four time /
time_close forms take it for a valid session argument under a D/W/M tf;
an intraday tf, and every call without a session argument, read as
before. session_time.hpp states the rule.
Tapes: tests/fixtures/session_period (lab tv --no-note), w12-tfd-{btc15,
xau15,btc1d,xau1d}, w12-tfd2-{btc15,xau15,btc1d,xau1d} and w12-tfd3-btc1d:
eighteen, sixteen and fourteen session spellings against their charts.
Pinned by tests/test_session_predicates.cpp test_session_period_tapes,
49,708 readings: on 0cfaa78 plus the W11 picks, session_predicates 127
passed, 10 failed (25,852 readings differ, and W11's w11-sess2400-xau15
field d 463, whose "compare only the window" relaxation is removed);
137 passed, 0 failed here.
Moved pins, attributed to the tapes: tests/test_session_day_anchors.cpp
(time("D", "0930-1600", "America/New_York") opens at 09:30 New York, not
New York's midnight; 23852/1 -> 23853/0) and tests/test_session_time.cpp
(a tz-less "0000-2359" rolls at syminfo.timezone's midnight, as the
explicit tz does; 37/1 -> 38/0).
ADR-0001 rule 1: session_time is the language calendar runtime. The bar is
a function of the session string, the zone, the chart's timeframe and the
instant, the same for every venue; no kernel order, fill, settlement,
margin or hash code calls it; its calibration is recorded at the site (the
tapes above).
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(cherry picked from commit 78c2a56aacfdf22de23c498021e9a6e12cce1954)
INT29 pick note: W12-ENG-TIME 1
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…week or month closes by the chart
The function forms time_close("D"), ("W") and ("M") without a session
argument returned their close minus one millisecond: the symbol-clock branch
of timeframe_time_close subtracted 1 from session_period_close_ms, and the
tz-only forms' compute_tf_close_ms from the next period's midnight
(src/session_time.cpp). On every chart the week and month closed where the
next one opens, and a month opened and closed at the session of the 1st even
when that is a Saturday.
TradingView returns the exact boundary (lab tv w12-tclose-*,
tests/fixtures/time_close_function): time_close("D") - time("D") is
86400000 on BINANCE:BTCUSDT and 23400000 on NASDAQ:AAPL, not one less. A D
closes at the session day's close on every chart. On an intraday chart a W or
M closes where the next one opens -- OANDA:XAUUSD's week at the next Sunday
17:00 ET, 167 hours on across the 2025-03-09 switch -- and a month opens and
closes at the first traded session of a month, a Saturday or Sunday trading
date being none: XAUUSD's February 2025 runs from Sunday 02-02 17:00 ET to
Sunday 03-02 17:00 ET, AAPL's March from Monday 03-03 09:30 ET to Tuesday
04-01 09:30 ET. On a daily chart a W or M closes at the period's last traded
close, the chart bar's own time_close (lane W11-ENG-TIME-COLOR 3): XAUUSD's
week on Friday 17:00 ET, AAPL's on Friday 16:00 ET.
timeframe_time_close's symbol-clock branch now returns session_period_close_ms
itself on an intraday chart and chart_period_close_ms on a daily-or-higher
one; chart_period_close_ms is W11's chart-bar reading moved from
PineStrategyHost::chart_time_close into the runtime, and the chart accessor
now asks it through pine_time_close, so the two read one rule
(time_close == time_close("D") on a 1D chart, as on TradingView). A month's
open and its intraday close step over weekend trading dates
(first_traded_day_stamp_ms, the weekday rule of
session_period_last_traded_close_ms). The tz-only forms' D / W / M close is
the next period's midnight exactly.
Exchange holidays are not modelled: 39 W / M readings of w12-tclose-aapl1d
(the MLK, Presidents Day, Good Friday and Memorial Day weeks, and January,
whose first traded day is the 2nd) close earlier or open later on TradingView,
counted as such by the test.
Test: tests/test_session_predicates.cpp test_time_close_function_tapes, 13,602
readings over seven tapes: on the item-1 head, session_predicates 153 passed,
12 failed (12,273 readings differ); 165 passed, 0 failed here.
Moved pins, attributed to the tapes (the last millisecond was the engine's
own derivation, no tape pinned it): tests/test_session_day_anchors.cpp
(23851/2 -> 23853/0), tests/test_pine_time_day_stamp_grid.cpp (93/7 ->
100/0), tests/test_session_calendar_extra.cpp (37/6 -> 43/0),
tests/test_o_close_pct_day_anchor.cpp (3 failures -> 0) and its oracle
copy tests/oracle/test_oracle_day_key.cpp (compiled as
test_native_oracle_day_key_l2; 3 failures -> 0, the oracle census count of
84 CHECKs unchanged; tests/oracle.sha256 re-pins that file's digest and the
tree digest, as lane R1-CONSOLIDATE did), and tests/test_local_time_fields.cpp,
whose libc reference of the tz-only close now ends at the boundary.
ADR-0001 rule 1: session_time is the language calendar runtime; the close is
a function of the tf, the chart's timeframe, the symbol's session and zone
and the instant, the same for every venue, and no kernel order, fill,
settlement, margin or hash code calls it. The adapter's chart accessor reads
it; no kernel file changes.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(cherry picked from commit 3d959a91bc3dce2b38a26dc8f8ceb13f6c88512c)
INT29 pick note: W12-ENG-TIME 2
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…he session's windows
time(tf, session, tz) and time_close(tf, session, tz) under an intraday tf
filtered the bar through the session's windows and then answered the
symbol's own grid bucket -- the day-stamp-anchored grid in the seven-argument
forms, the epoch grid in the tz-only ones (compute_tf_open_ms,
src/session_time.cpp); the header called the session argument "only a
filter". TradingView builds the tf bars on the session argument itself, the
rule item 1 states for D / W / M (lab tv w12-tfd4-*, w12-tfd3-btc60 and
w12-tfd5-xau15, tests/fixtures/session_period): its bars open at each window's
open and every tf after it, the last one cut at the window's close, and a bar
in no window reads na. On BINANCE:BTCUSDT 60 time(timeframe.period,
"0930-1600") reads 09:30 for the 10:00 bar, "0945-1600" 09:45, "0907-1600"
09:07; time("240", "0930-1600") reads 09:30 and then 13:30 and closes at
16:00; a second window opens its own grid ("0930-1130,1245-1500": 12:45,
13:45); time("30", "0945-1600") reads 09:45 for the 10:00 bar; and
time(timeframe.period, "2330-2430") reads Saturday's 23:30 for Sunday's
00:00 bar. On OANDA:XAUUSD 15 time("240", "1800-1700") opens at 18:00 ET and
time("45", "1800-1700") at 18:00, 18:45, .., where time("240") and time("45")
keep the symbol's 17:00 ET grid. A window that opens on the chart's grid
reads each chart bar's own time, as before.
session_argument_intraday_bar (src/session_time.cpp): the latest window
instance holding the bar -- the day rule and lists of item 1, the wall clock
of native_calendar::resolve_civil, memoised per session day -- cut into tf
bars from its open. The four time / time_close forms read it for a valid
session argument under an intraday tf; without a session argument the
symbol's grid stands.
Test: tests/test_session_predicates.cpp test_session_period_tapes, five more
tapes (12,350 readings): on the item-3 head, session_predicates 175 passed,
5 failed (2,091 readings differ); 180 passed, 0 failed here.
Moved pin, attributed to w12-tfd5-xau15: tests/test_pine_time_day_stamp_grid.cpp
A's "a session argument only filters; the grid is the symbol's" -- time("240",
"1800-1700") on the Monday 20:45 ET bar opens at 18:00 ET, not the 17:00 stamp
(99/1 -> 100/0).
ADR-0001 rule 1: session_time is the language calendar runtime; the bar is a
function of the session string, the zone, the tf and the instant, the same
for every venue, and no kernel order, fill, settlement, margin or hash code
calls it.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(cherry picked from commit ceec570f825f6d1157faea7070479fd74119f3dd)
INT29 pick note: W12-ENG-TIME 3
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
… across a DST switch
A session whose day lasts 24 hours on the wall clock -- 24x7, or one window
whose end is its start, as 1700-1700 -- in a zone with daylight saving closed
its D bar at its open plus 24 hours (session_day_close_real_ms, reached through
session_period_last_traded_close_ms and session_period_close_ms), so across a
switch the chart's time_close and time_close("D") were an hour late or early;
and the runtime's per-UTC-day zone offset read New York's midnight an hour off
on the switch Sundays (time("D") of a 24x7 New York symbol at 04:00Z on
2025-03-09). Lane W11-ENG-TIME-COLOR's reviewer found the first.
TradingView closes such a day at the next day's same wall-clock time (lab tv
w12-tclose-cap1d and w12-tzscan-*, tests/fixtures/dst_day_close):
CAPITALCOM:BTCUSD, 1700-1700 New York every day, closes its Saturday
2025-03-08 17:00 EST bar at Sunday 17:00 EDT, 82,800,000 ms on;
ACTIVTRADES:BTCUSD, Europe/Amsterdam, its Sunday 2025-03-30 00:00 CET bar at
Monday 00:00 CEST. (BINANCE, COINBASE, GEMINI, BITSTAMP, KRAKEN, CRYPTO,
INDEX, BNC and CRYPTOCAP report Etc/UTC; no TradingView symbol found trades
24x7 at New York's midnight, so that case is pinned from the rule.)
wall_clock_day_bar (src/session_time.cpp): for such a session in a zone other
than UTC, the symbol clock's D bar is the session's own day bar of item 1 --
exact wall clock through native_calendar::resolve_civil -- for time("D"),
time_close("D") and, through chart_period_close_ms, the D chart's time_close.
Every other session, and every UTC zone, reads as before; no population lane
trades through a switch (Binance is UTC, OANDA and the US listings are shut
on the switch Sundays, CME opens after them, NSE keeps no daylight saving).
Tests: tests/test_engine_trade_accessors.cpp test_chart_time_close_dst_tapes
(three tapes, 237 bars, one across a switch each; ACTIVTRADES' Friday 23:00
close and Saturday 09:00 open are its venue's schedule, not read) and
tests/test_session_predicates.cpp (w12-tclose-cap1d's D readings in
test_time_close_function_tapes; test_wall_clock_day_24x7_new_york). On the
item-2 head: engine_trade_accessors 98 passed, 3 failed; session_predicates
187 passed, 3 failed. Here: 101 passed, 0 failed; 190 passed, 0 failed.
ADR-0001 rule 1: session_time is the language calendar runtime; the day is a
function of the session string, the zone and the instant, the same for every
venue, and no kernel order, fill, settlement, margin or hash code calls it.
src/timeframe.cpp, which the kernel archive shares, is not changed: its
session days keep the open-plus-length arithmetic its callers pin.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(cherry picked from commit 6dd8af9a81facee5bec19383fb15071e2ea7c743)
INT29 pick note: W12-ENG-TIME 4
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…et predicate's day list session_in_premarket and session_in_postmarket (src/session_time.cpp) read only a day list a session spells, and tested it against the bar's weekday, while session_in_market and time() read the list lane W11-ENG-TIME-COLOR's tapes establish: the one spelled, else Monday to Friday for a session of several windows (lab tv w11-sessmask-btc15 and w11-sessmask2-btc15, tests/fixtures/session_clock). So a Saturday bar of "0900-1130,1230-1530" read pre-market at 05:00 and post-market at 16:30 while it was not a day of the session in market (W11's reviewer). session_day_list resolves the list once, for the in-market predicate, both extended-hours predicates and the session-argument bars of items 1 and 2. A bar before the open or after the close is on its session day's own date (an overnight or 24-hour session has no pre- or post-market, extended_hours_bounds), so the weekday test is the session-day rule there. No TradingView chart of such a session holds a Saturday bar; the weekday readings are TSE:7203's and HKEX:700's (tests/test_session_prepost_windows_tape.cpp, unchanged, 114 passed). Test: tests/test_session_predicates.cpp test_prepost_market_day_list, the Saturday of a Tokyo two-window session, with weekday, listed-Saturday and one-window controls: on the item-5 head session_predicates 197 passed, 2 failed; 199 passed, 0 failed here. ADR-0001 rule 1: session_time is the language calendar runtime; the predicates are functions of the session string, the zone and the instant, the same for every venue, and no kernel order, fill, settlement, margin or hash code calls them. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit fb69c93b103aa60cf6e98714e280390af8309195) INT29 pick note: W12-ENG-TIME 5 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…there The chart's time_close (chart_period_close_ms, src/session_time.cpp, W11's chart-bar reading) maps a D / W / M stamp outside its session to the session it opens (session_covered_instant_ms), which read a stamp exactly at a session's close as the NEXT session's: a daily bar a feed stamps at its close -- Monday 16:00 ET on an equity, 16:00 CT on CME's 1700-1600 -- closed at Tuesday's 16:00, and a weekly bar stamped Friday 16:00 ET at the next Friday's (W11's reviewer: close-stamped calendar feeds read as the next session under raw labels). The kernel reads such a raw label as the calendar interval that holds it, the session that closes there; W11's kernel commit c6170f57, which advanced such labels to the next session, is withdrawn by owner ruling and not picked here, so the chart accessor now reads it as the kernel does. A stamp exactly at its session day's close that no session day opens at is the bar of the session that closes there: its time_close is its own stamp. A stamp that is also where a session day opens -- OANDA's 17:00 ET under 1800-1700 and 1700-1700, CME's 17:00 CT, a 24x7 day's midnight -- still opens that session, and a stamp past the close, in the break, is still the next session's (test_chart_time_close_gap_stamps, unchanged). The weekend guard of W11's 3d moves a period only when its last traded close is BEFORE the stamp, so a close stamp keeps its own period. TradingView stamps its own bars at the session's open (09:30 ET, 17:00 CT, OANDA's 17:00 ET), so no tape reaches a close stamp; W11's tests/fixtures/daily_break_close tapes, which read every TradingView stamp, are unchanged (test_chart_time_close_tapes). Test: tests/test_engine_trade_accessors.cpp test_chart_time_close_close_stamps, three close stamps and four controls: on the item-6 head 112 passed, 3 failed; 115 passed, 0 failed here. ADR-0001 rule 1: session_time is the language calendar runtime, read by the adapter's chart accessor; the close is a function of the stamp, the session and the zone, the same for every venue. No kernel file changes. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 9be7551ff17039a9c667c1ac87c3ccd19696c440) INT29 pick note: W12-ENG-TIME 6 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…and zone The Cloud Run replay of items 1-7 (exp-w12-after-20260928) timed 44 probes out -- scripts with several session sites in several zones, the ORB and session-sweep shapes -- because the calendar of items 1, 2 and 5 kept each session day in a direct-mapped per-thread slot keyed by the day alone: two sites of one bar evicted each other's days, and every miss resolved its wall clock through native_calendar::resolve_civil, whose zone acceptance reads the zone file and whose mktime switches the process zone. Four interleaved sites (two zones) cost 1,748 us a bar on this Mac. Each session argument, in each zone, now keeps its own entry (ArgCache: the parsed windows and day list, and 64 session days' D bars and window instances), eight entries per thread evicting the least recently used; the wall clock of a minute is read through the offsets decompose_ms_local holds (the offsets in force a day before and after it, the candidate whose own wall clock reads the minute, the earlier of two in a repeated hour), with resolve_civil left for a minute a switch skips; and the month step of item 3 keeps its last four answers. The four interleaved sites cost 0.4 us a bar; the symbol clock's D / W / M read what they did before the lane (0.1-0.4 us, M 1.3 us against 1.4 us). Every value is unchanged: the micro-benchmark's checksums, session_predicates 199/0, engine_trade_accessors 115/0 and every other time test as before. ADR-0001 rule 1: session_time is the language calendar runtime; a per-thread cache of a pure function, no kernel state. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit af422718bbab3e44ba290f5997c92ae9837a1012) INT29 pick note: W12-ENG-TIME 7 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…ist trades Item 3 stepped a symbol-clock month's open and its intraday close over Saturday and Sunday trading dates for every session with hours, the weekday rule of session_period_last_traded_close_ms. A market that trades every day -- CAPITALCOM:BTCUSD, 1700-1700 New York -- opens February 2025 at Friday 01-31 17:00 ET on TradingView (w12-tclose-cap1d, tests/fixtures/dst_day_close); the step moved it to Sunday 02-02 17:00, after the bars of 01-31 and 02-01 themselves, and on its daily chart the week and month closed on Friday, where TradingView closes them on the last day the market trades (the lane's reviewer). first_traded_day_stamp_ms now reads the session's own list (session_day_list): a spelled list decides which trading dates trade, and only a session with hours and no list keeps the weekday rule; a month's open is never after the bar (a bar on a day the rule steps over proves that day trades). On a daily chart a week or month of a list that trades a Saturday or Sunday closes at its period's last session day of the list (session_argument_bar on the covered instant, the session's own calendar of item 1), where the runtime's weekday rule stops on Friday. A session with hours and no list reads as before: TV's own symbols spell their days, and a host that describes a seven-day market by hours alone is read as trading Monday to Friday, as the runtime reads it. Test: tests/test_session_predicates.cpp -- test_time_close_function_tapes reads w12-tclose-cap1d spelled "1700-1700:1234567" for D, W and M (1,074 readings; item 5 read its D only), and test_month_open_never_after_the_bar; the test now checks na before it subtracts. On the item-7 head, session_predicates 198 passed, 5 failed (457 cap1d readings differ); 203 passed, 0 failed here. ADR-0001 rule 1: session_time is the language calendar runtime; the readings are functions of the session string, the zone, the chart's timeframe and the instant. No kernel file changes; timeframe.cpp's weekday rule is unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 5395fd9ce634afa087c7ec304d6b5f0f5a6d6b22) INT29 pick note: W12-ENG-TIME 8 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…n's grid The host's chart accessor reads time_close(timeframe.period, syminfo.session, syminfo.timezone) on an intraday chart, so since item 2 it closes a bar on the session's own grid: one timeframe after the bar's open, the session's last bar at the session's close. TradingView does the same (lab tv --no-note tapes w12-ctclose-aapl60 / -aapl45 / -nifty60, probe spelling (time_close - time) / 60000 and the exchange HHMM of time): NASDAQ:AAPL 60 reads 60 for its 09:30 .. 14:30 bars and 30 for 15:30, AAPL 45 reads 45 from 09:30 in 45-minute steps and 30 for 15:30, NSE:NIFTY 60 reads 60 for 09:15 .. 14:15 and 15 for 15:15. test_chart_time_close_intraday_session_grid replays every reading through the chart accessor on each chart's symbol facts. Fail-before on item 3's session_time.cpp (the epoch grid): aapl60 29 of 33 bars, aapl45 39 of 43, nifty60 29 of 33 differ (engine_trade_accessors 115 passed, 9 failed); after: 124 passed, 0 failed. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit da0cff1ba760e0e20f6437cabdd04bbd01cdd4a6) INT29 pick note: W12-ENG-TIME 9 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…ver the wall-clock day
Item 5 answers the symbol-clock time("D") / time_close("D") of a 24-hour
session in a DST zone with the wall-clock day before session_period_open_ms
/ close_ms are asked, so on an intraday chart with a native daily feed the
wall-clock day overrode the feed's partition (its stamps and merged days).
wall_clock_day_bar now returns false where an active native partition on
the same zone and session holds the bar; before its first stamp and from
its last bound the wall-clock day answers, as the nominal rules do there.
The reviewer also asked to defer on days of exactly 24 hours. That is not
the same bar: a scan of 16,571,520 readings (six zones, seven sessions,
15 / 60 / 1D charts, D / W / M, 2024-2026) differs on 120, all the hour
before a spring switch, where the runtime's midnight floor reads New York's
Saturday 2024-03-09 23:00 EST as Sunday's day. The wall-clock day answers
every day, and the comment says so (the old one called UTC "a zone without
daylight saving's switches"). The same scan without a partition hashes
identically before and after this commit (a161a34f5a385083).
test_wall_clock_day_defers_to_native_partition builds a partition that
merges CAPITALCOM-style 1700-1700 New York's Saturday 2025-03-08 into
Friday's bar and checks both readings under NativeDayPartitionScope and
after it. Fail-before on 2b's head: session_predicates 211 passed, 2 failed
(the D open read Saturday 17:00 EST, not the Friday stamp); after: 213
passed, 0 failed.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(cherry picked from commit b0c01c0730d228b16f2d0a1cb462fda3c453332a)
INT29 pick note: W12-ENG-TIME 10
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…riod that closed at it Item 7 turned the weekend guard of W11's 3d from close <= stamp to close < stamp for every stamp, so a stamp where a period's last session closes AND the next session opens -- OANDA's week stamped Friday 17:00 ET under 1800-1700 or 1700-1700 -- kept the period that had just closed: its time_close was its own stamp, a zero-length bar. The strict guard now applies only when item 7's close-stamp reading fired (the stamp was read one millisecond earlier, as the session closing there); every other stamp keeps W11's <= and moves to the next period. test_chart_time_close_close_stamps gains the two OANDA controls (1W, Fri 2025-03-07 17:00 EST -> Fri 03-14 17:00 EDT). Fail-before on 5b's head: engine_trade_accessors 126 passed, 2 failed (time_close 1741384800000, the stamp itself); after: 128 passed, 0 failed. A scan of 16,571,520 readings (six zones, seven sessions, 15 / 60 / 1D charts, D / W / M, 2024-2026) moves 4008, all on 1D charts and all of them readings whose time_close equalled their own stamp before; none else changes. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 1cec8ab29603e602245c619bd834295129f29267) INT29 pick note: W12-ENG-TIME 11 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
W11's tape replay (test_session_2400_tapes and its siblings) compared only
na-ness for time(timeframe.period, session, tz) on a D chart, since W11
read that reading as the bar's own time; item 1 moved time("D", session) to
syminfo.timezone and item 2 made the D-chart reading the session's own day
bar, but the relaxation stayed. It is deleted: every reading is compared
with same_reading, and all W11 and W12 tapes match (w11-sess2400-btc1d 1980
readings, 0 differ; session_predicates 213 passed, 0 failed).
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
(cherry picked from commit eda2613937ea2b2d56d1f40171fa0e88b2a54d49)
INT29 pick note: W12-ENG-TIME 12
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
… thread ArgCache (src/session_time.cpp) kept 8 (session, zone) entries per thread and evicted the least recently read; a script with more session sites than that re-read the evicted sessions' windows and days on every bar. It keeps 32 now. Micro-benchmark, a year of 15-minute bars, pine_time per site, one zone (America/New_York): 12 interleaved sessions 14.32 us/bar with 8 entries, 0.84 us/bar with 32; 4 and 8 sessions unchanged (0.24 / 0.50). Twelve sites in twelve zones stay at about 2 ms/bar, before this lane too (a52d2191: 2069.7 us/bar): decompose_ms_local holds eight zones per thread (kZoneSlots) and a ninth pays setenv + tzset per call. Not changed here. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit c36de40da8200d76fd8f2f0e319d2837719009df) INT29 pick note: W12-ENG-TIME 13 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
… script, and a close placed on that bar keeps its size TradingView checks a book whose path after a fill is adverse only at the bar's close at that close, after the script has run there: the script reads the book before the call, the call executes at the close, and a strategy.close_all() the script placed on that bar keeps the size it was placed with, so at the next open it closes the rest and opens the called units on the other side. The adapter rested the call at the close's mark, so the path filled it before the script and the close order closed the rest. - schedule_margin_call_path marks the kernel check point whose remaining adverse mark is the close alone (close_margin_point_), where resolve_margin_call_units answers 0; on_bar_close books the call at the close after the script (close_point_margin_call, book_close_point_call) and turns the bar's close_all orders into plain Transacts of the book they were placed on (size_close_alls_at_placement). Such an order crosses zero, and validate_precommit admits it; a call that flattens the whole book leaves the close order to the flat purge, which retires it as before. - The full-margin long's one-contract money call follows the same rule outside process_orders_on_close (schedule_tv_money_long_margin_before_trail no longer rests a call the close fires; on_bar_close re-sizes the close orders when submit_tv_money_long_margin_call fired at the close). Under process_orders_on_close the call still rests and fills ahead of the close order, which close() sizes to the book before the call (W5B's w5b-sz-eur-p100-10m 2025-04-10 12:30 is this shape). - A commissioned full-margin short that one explicit-quantity MARKET entry opened on the bar keeps its post-script checkpoint (commissioned_explicit_short_opened). The kernel is untouched: every decision is an answer on an existing seam (resolve_margin_call_units, precommit verdicts, Transact, submit and cancel). Tapes (lab tv --no-note, synthetic, tests/fixtures/margin_opposite): w13-b1-close-f, w13-x1-close-xau2, w13-p1-eur, w13-p2-eur; controls w13-b5-none-f, w13-x5-none-xau2, w13-a3-mkt-flip-f. test_margin_opposite_tapes on 0cfaa78: the four CP rows fail, the three controls pass; here every row passes. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit c119c050832339f0589bc1efe047277726fbcddb) INT29 pick note: W13-ENG-MARGIN-OPP 1 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…call, which is placed again behind its orders The call a bar's close owes (rule CP) is an order the script's strategy.cancel_all() on that bar withdraws too. TradingView then places it again behind the script's orders, and it executes after them at the next open as a plain market order sized at the close: on the book the script's close_all flattened it opens the called units on the other side under the id "Margin call", on a book still held it reduces it. This is the ki62 shape (the population probes pf-probe-ki62-margin-deferral on NYSE:F and OANDA:XAUUSD call cancel_all before close_all on the fill bar). - cancel_all() records its script bar (close_margin_cancelled_bar_), and close_point_margin_call books a withdrawn call as a queued Transact for the next open (book_close_point_call, queued; close_margin_open_bar_). - The flat purge in on_applied keeps such a call when the close order flattens the book: it fills as placed on the flat book. - close_point_margin_call_at_open, at that open: behind orders the script placed at that close the call keeps its place and fills after them in the open's matching pass (on_bar_open counts it as a whole-market close that waits); with none it is the open's first execution. A re-placed one-unit call is taken only where its fill at that open restores the book of that close (w13-b2-cancel-close-f 2025-06-10 19:45 and 2025-06-30 14:15 UTC take none). Tapes (lab tv --no-note, synthetic, tests/fixtures/margin_opposite): w13-b2-cancel-close-f, w13-b2s-cancel-close-f, w13-b4-cancel-f, w13-x2-cancel-close-xau2. test_margin_opposite_tapes on CP (c119c050): the four CQ rows fail, the CP rows and controls pass; here every row passes. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit 853ffeadffac27534e9680290530f7623ddecb9d) INT29 pick note: W13-ENG-MARGIN-OPP 2 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…re taken at the next open, where they restore the book Lane INT28-FIX's first two open shapes. A one-unit call (a restore that floors below one lot) is taken only at a fill where the unit restores the book; one the close's own fill would not restore is tried again at the next open, and a follow-up that falls on the close is booked there after the script, so the strategy.close_all() the script placed on that bar, sized at placement, opens one unit on the other side at the next open (int28fix-ou-s2b 2025-04-03 19:00 UTC: a one-share long, closed at 9.34 the next day). - close_point_margin_call queues that one-unit call for the next open (book_close_point_call, queued); close_point_margin_call_at_open tests it at that open's fill against the money of the book at that close, and one the close left standing executes there ahead of the bar's orders (int28fix-adm-s-cs 2025-06-26: 810 shares 4.95 short at the 10.62 close mark give one up at 10.62 off the 10.61 open). - follow_one_unit_margin_call hands a follow-up whose next point is the close to the close's check after the script (close_margin_follow_up_bar_): adm-s-cs 2025-06-27. - close_point_follow_up: a call taken at the close whose book, re-marked at the call's own fill, is still short by more than two slippage steps (its exit fee added back) takes one more unit at the next open, behind the script's orders, where that open's print is not beyond the fill of the call it follows (PlacementSnapshot::follow_up_fill): w13-b1s-close-f, 33 of its 34 close calls. One so taken is followed alike at that same open (w13-b5s-none-f 2025-06-30 14:30 UTC: two units at the 10.73 open). - source_margin_units floors the shortfall as TradingView's ten-significant- digit money (source_money_round): 636 shares 21.52 short at the 10.76 mark floor to two units and call 8, not 4 (w13-b1s-close-f 2025-06-11). Tapes: w13-b1s-close-f, w13-b5s-none-f (through 2025-06-30 15:15 UTC) and w13-b4s-cancel-f (open cell 2025-06-06 16:45 UTC) in tests/fixtures/margin_opposite; INT28-FIX's int28fix-adm-s-cs over its whole window and int28fix-ou-s2b (open cells 2025-04-25 18:15 and 2025-05-30 15:15 UTC, each listed under "Open") in tests/fixtures/slipped_short. test_margin_opposite_tapes on CQ (853ffead): the five CU rows fail, the CP and CQ rows and the controls pass; here every row passes. test_slipped_short_tapes passes unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit d39a22fc4af910e7cf484c2cacfffaebb89da7c9) INT29 pick note: W13-ENG-MARGIN-OPP 3 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…ery point of its bar's path Lane INT28-FIX's third open shape. TradingView checks every point of a bar's path, not only its adverse extreme: a point the path reaches before that extreme can already be short of margin -- a short filled the slippage ticks under its print is still short at a low above its fill -- and its call is taken there; the rest of the path then checks the book it leaves. - schedule_margin_call_path rests that call at the first such point before the adverse extreme (rest_waypoint_margin_call: a touch of the print from the side the path reaches it from, filled at the print with the exit's slippage) instead of admitting the kernel's check at the extreme. - on_applied: the book such a call leaves is followed as a kernel one-unit call is (follow_one_unit_margin_call) and checked again over the rest of the path; a new schedule or the bar's close withdraws a point's call that has not filled (withdraw_waypoint_margin_calls). - Scope: shorts slipped on whole lots, the book the tapes measure. On a population replay the rule applied to every book dropped 31 probes a tier (BINANCE, OANDA and ETHUSDT.P fractional lots; 63 of the 71 worse probes were longs, whose full-margin call is the one-contract money call); scoped so, the replay's 7994 trade sets are those of the prototype without the rule (lab experiments exp-w13-proto4-all-20260928 against exp-w13-proto2-all-20260928). Tapes: INT28-FIX's int28fix-ou-s1 over its whole window, and int28fix-ou-s2 (slippage 2) through 2025-05-20 16:15 UTC, in tests/fixtures/slipped_short; 2025-04-01 14:15 UTC on -ou-s2: one unit at 9.91, then 12 at 9.97, where the extreme alone calls 16. test_margin_opposite_tapes on CU (d39a22fc): the two CW rows fail, every other row passes; here every row passes. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> (cherry picked from commit a37ddac5901de7a6518fad5e1a4b98c83d66f47a) INT29 pick note: W13-ENG-MARGIN-OPP 4 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…tegrated tree and attributed All thirteen harvest-switched tables are re-harvested once on the integrated tree (main 74491fa, lane W10-DIAG-UNKNOWN's ten picks, lane W11-ENG-TIME-COLOR's eleven, INT29's case-12, composition and comment commits, lane W12-ENG-TIME's thirteen and lane W13-ENG-MARGIN-OPP's four), each with its TU's own switch; the same harvest against main reproduces every old row of all thirteen. Two tables move, and one recorded-divergence pin. The lanes' own re-pins were harvested on their own trees and are not applied (the pick notes say so); each move below is placed by a harvest or run on each side of the pick named. - test_adapter_quiet_bar (PINEFORGE_QUIET_BAR_HARVEST): 4 of 276 runs, the one scenario with a positive max_intraday_filled_orders (IntradayCapDeferred, magnifier off and on, recording on and off). The tree just before the W10 CAP-ON pick reproduces main's rows, the tree at it already has the head's -- the values the lane harvested on its own tree. The harvests at the CAP-ON pick, just before W12's picks, after them and after W13's are the same file. - test_publication_witness (PINEFORGE_D2D_PUBLICATION_HARVEST): 1 of 156 runs, Config03, digest only (53 trades and every count unchanged): the tree just before the W13 CP pick reproduces main's row, the tree at it has the head's -- the value lane W13 harvested on its own tree. - test_cash_fee_sizing_tapes, the adapter's pinned rows on the RECORDED divergence pcf-order-p100-m100 (re-pinned deliberately, as the test asks): the rows W13 re-pinned, word for word. At the tree just before the CP pick main's pins pass (178 checks, 0 failures); at CP they fail (4 failures) and W13's pass (0); the head passes W13's. - test_adapter_live_state_equivalence does not move: the lane re-pinned COQ's two live-state digests (reversal seeds 2827683 and 3141870) on its own base (8633d944, without W5B and the rest of INT28); on this tree every one of those digests is main's. The report re-lowering, recording hash, continuation view, receipts, command allocations, lookup index, host-view memo, calendar and both brackets re-lowering witnesses do not move either. Each table's ledger names the moved rows' old and new values. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Counted with ctest -N on the integrated tree, each profile configured with ci_verify's own argv (launcher unset), against main 74491fa the same way: - release: 752 -> 759 registered, all run. +1 W11-ENG-TIME-COLOR test_color_tapes; +4 W10-DIAG-UNKNOWN test_coqueued_open_margin_tapes, test_intraday_cap_tv_tapes, test_pooc_gap_stop_tapes, test_same_open_reversal_tapes; +1 W13-ENG-MARGIN-OPP test_margin_opposite_tapes; +1 INT29 test_int29_rule_compositions. RELEASE_MIN_TESTS 752 -> 759. - kernel: 296 -> 297 registered (+1 test_color_tapes, source-free), 297 registered and 296 run: the WebSocket row still skips on a system libcurl. KERNEL_MIN_TESTS 295 -> 296. - debug and sanitizers 733 -> 740, native 742 -> 749: the same seven rows. EXCLUDED_REGISTERED_MIN {740, 740, 749}; scripts/test_ci_verify.py pins them, and docs/ci.md states the four floors. No row leaves any profile. Lane W12-ENG-TIME adds no row (its tapes extend existing tests), which the same count before and after its picks confirms. The lanes' own floor commits (W10 e8170ffa, W11 8b062966, W13 ce00d34c) are not picked. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…chored once, on the integrated tree The picked rule commits kept main's doc pages (their doc hunks renumbered anchors on their own lanes' trees), and the lanes' docs-and-anchors commits were not picked. This commit does both once, on the integrated tree. Doc text, from lane W12-ENG-TIME's docs commit d761f56d (not picked), word for word: - docs/coverage.md's "Time / Session / Timezone" says what pine_time / pine_time_close return under a session argument (the session's own D / W / M and intraday bars, in its timezone), that the chart's own intraday time_close is that grid on syminfo.session, that a close is the boundary itself, and that a 24-hour session's day in a DST zone runs wall clock to wall clock, citing tests/fixtures/session_period, time_close_function and dst_day_close. Where it said both return na "when the bar is outside the requested session", it now says "when no bar of tf built on the requested session holds the bar". - docs/pages/pine-to-native.md's session.ismarket row said the payload predicate pine_session_ismarket "misses every Sunday open under a weekday mask ... and every bar of 0000-2400, which it cannot parse as a whole day"; the picked W11-ENG-TIME-COLOR commits 1 and 1c made it read every HHMM as minutes and a day mask by each window's session day, and moved the tests/test_session_ismarket_tape.cpp pins to 0 misses. The row now says so. Anchors. Every page's digits were main's (74491fa), except W11 4b's plus_dm anchor (renumbered for the ta_volatility_trend.cpp it carries) and the seven W12 renumbered with the text above (lane W13-ENG-MARGIN-OPP's docs commit cb5d0d99, not picked either, renumbers digits only). The picks, INT29's composition and comment commits and the floors moved lines in pine_adapter.cpp, pine_adapter.hpp, pine_strategy_host.cpp, pine_state_hash.cpp, intraday_cap.hpp, session_time.hpp, session_time.cpp and ci_verify.py: - an exact difflib line map from the copy of each cited file that the digits were written against to this tree's, every claimed anchor verified by check_doc_anchors' own judge -- main first and alone where it carries the digits, then d761f56d's copy for W12's seven (its session files equal this tree's), then this tree's own for the plus_dm anchor: 243 anchors moved, 1,479 kept; - by hand, where the line itself changed: KERNEL_MIN_TESTS ci_verify.py:301 -> :306 and RELEASE_MIN_TESTS :511 -> :527 (CONTRIBUTING.md, docs/pages/contributing-llm.md twice each); - two ADR-0001 sha256 anchors into include/pineforge/ta.hpp (:333-340, :420-429) the map could not judge stay as they are: their lines are unchanged and the gate resolves them. check_doc_anchors.py: 1,730 of 1,730 resolve. check_doc_lint, check_design_inventory, check_kernel_seam_rows, check_dangling_comment_names, check_c_abi_runtime and check_twin_parity: 0 findings. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
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.
INT29: engine integration (W10, W11, W12, W13)
This PR integrates four accepted engine lanes onto main 74491fa. Every pick carries
-xand anINT29 pick note. All changes are in the Pine adapter and the Pine calendar/session runtime; no kernel file changes. It merges as a coordinated pair with the codegen PR that re-pins the session tests to this engine.Lanes
2400is the end of the day, and day lists are read per session day.time_close.ta.supertrendwarm-up.time_closeboundaries.cancel_allwithdraws that call.Integration
Verification (head 8988faf)
pineforge/parityfrom a sweep of this head paired with the codegen PR.🤖 Generated with Claude Code
https://claude.ai/code/session_01LifAW9e5J6gFx7gatuxETE