Skip to content

session symbols: syminfo-tz session windows, symbol-clock D/W/M anchors, zero-lot orders, margin call at the open - #162

Merged
luisleo526 merged 1 commit into
mainfrom
fix/symbol-r5-session-semantics
Aug 24, 2026
Merged

luisleo526 merged 1 commit into
mainfrom
fix/symbol-r5-session-semantics

Conversation

@luisleo526

Copy link
Copy Markdown
Collaborator

Four generic session-symbol semantics fixes, measured on the NASDAQ:AAPL and OANDA:EURUSD 15m populations and byte-inert on BINANCE:ETHUSDT.P (24x7/UTC) — ETH scraped 396/396 and corpus 309/2/1 unchanged.

  1. time(tf, session) / time_close session windows read in syminfo.timezone (finding 421/436). The session-filter tz defaulted to UTC; Pine resolves it in the exchange tz. Engine side: pine_time/pine_time_close gain a trailing syminfo_tz (default "" = old behaviour; feature macro PF_PINE_TIME_HAS_SYMINFO_TZ). Codegen PR passes syminfo_.timezone.
  2. Zero-lot orders are not placed (finding 426/438). An entry or pyramiding add whose lot-floored quantity is 0 was admitted as a phantom qty-0 position (opentrades==1, position_size==0), silently blocking every later signal. TV simply does not place it.
  3. Symbol-clock D/W/M anchors for ta.vwap, timeframe.change, time('D'|'W'|'M') (finding 423/440). These keyed on UTC midnight; for OANDA:EURUSD the trading day rolls 17:00 ET and the week opens Sun 17:00 ET. New helpers (session_day_index, session_period_open_ms/close_ms) built on the security: anchor HTF aggregation on the symbol clock (syminfo.timezone + session) #159–security: session-attributed weekly/monthly period keys #161 machinery; VWAP::compute (tz,session) overloads, 7-arg pine_time (macros PF_PINE_TIME_HAS_SESSION_DAY, PF_VWAP_HAS_SESSION_ANCHOR). Semantic decisions pending a TV probe are listed in finding 440 (valid explicit session defines the day in its own tz; wrapped-session month attribution).
  4. Forced liquidation at the bar open for carried leveraged positions (finding 430/441). TV fires the margin-call slice at the OPEN when the open already breaches (then a second slice at the extreme); the engine only checked the extreme. Rule fitted on 8,414 AAPL margin-call events (8,403 qty-exact).

Population evidence (lab findings 443–445; ladder-ranking harness 90fcb64): EURUSD excellent 251 → 271, e+s 327 → 347, 30 tier ups / 0 downs; AAPL excellent 210 → 235, e+s 291 → 307, 31 up / 5 down. Four-lane symbol gate PASS vs the 08-22 baseline (aapl 170 up / 19 down, eurusd 79 up / 36 down).

Tests: ctest green incl. new test_zero_lot_entry_decline, test_session_day_anchors (23,850 checks), test_margin_call_gap_open, session_time DST cases.

@luisleo526
luisleo526 merged commit b1449c3 into main Aug 24, 2026
7 checks passed
@luisleo526
luisleo526 deleted the fix/symbol-r5-session-semantics branch August 24, 2026 17:22
pull Bot pushed a commit to Malumbo21/pineforge-engine that referenced this pull request Sep 4, 2026
TradingView keys time("<intraday tf>") / time_close on the symbol's
DAY-STAMP-anchored HTF grid -- the grid 88cd0c8 gave request.security's
ratio buckets -- on every session symbol, and on the epoch grid only
where the stamp is 00:00 UTC; time("D") on OANDA's 1800-1700 session
is the 17:00 ET stamp the D bar opens on, not the 18:00 ET session
open, and time_close("D") the next stamp.

Pinned with `lab tv` (pin-time-hours: strategy.entry(qty =
hour(time(tf), "America/New_York") * 100 + minute(...) + 10000 /
20000 / 30000 for "D" / "240" / "60"), 15m charts, 2025-04-01..07-01):
  OANDA:XAUUSD 1800-1700 ET: "D" = 17:00 on 147/147 entries (the
    engine reported 18:00); "240" in {01:00, 05:00, 09:00, 13:00,
    17:00, 21:00}; "60" every hour on the hour except 17:00;
  NYSE:F 0930-1600 ET: "D" = 09:30; "60" in {09:30, 10:30, .., 15:30}
    -- session-anchored, not the epoch hour the engine reported;
    "240" in {09:30, 13:30};
  NSE:NIFTY 0915-1530 IST: "D" = 23:45 NY (09:15 IST); "240" in
    {23:45, 03:45} NY (09:15 / 13:15 IST);
  BINANCE:BTCUSDT 24x7 UTC: "D" = 20:00 NY (00:00 UTC), epoch grid.
CME_MINI:ES1! exported 0 rows: its request.security "240" grid (17:00
CT anchored) is pinned unchanged and time("240") reads it.

One grid, one place: session_intraday_bucket_open_ms (timeframe.cpp)
is the RATIO bucket of TimeframeAggregator::bucket_open_ms and the
intraday path of compute_tf_open_ms (session_time.cpp), which now
takes the symbol's tz/session from the seven-argument pine_time /
pine_time_close forms; the five-argument forms pass UTC / "" and stay
on the epoch grid bit-for-bit. session_period_open_ms opens the D/W/M
bar on its first session-day's stamp (session_day_stamp_real_ms) and
W/M close on the next period's stamp; the DAY close (open + length =
the next stamp) and session_day_open_real_ms -- the trading open that
session_covered_instant_ms and the close arithmetic use -- are
unchanged. The aux daily-bar router keys both sides through
session_period_open_ms, so its keys move together; the range-start
bucket cut now keys the 1800-1700 D bucket on the stamp, which is
where TradingView's D bar opens. Every session whose open is its
stamp (OANDA 1700-1700, CME 1700-1600 CT, NYSE, NSE, 24x7) is
bit-identical for D/W/M; their intraday time(tf) moves from the epoch
grid to the session grid, as the tapes read.

Re-pins, disclosed:
  - tests/test_session_day_anchors "Intraday tfs keep the epoch grid"
    arrived with b1449c3 (factorial: engine-symbol-r5, pineforge-4pass#162) as a
    design statement with no tape behind it; its "60" check on
    OANDA:EURUSD 1700-1700 never told the grids apart (17:00 ET is on
    the hour) and still holds; "240" is now pinned to the 17:00-ET
    grid.
  - tests/test_session_day_anchors "CME-style 1800-1700" (b1449c3, a
    session-length parser edge case written in the New York zone) is
    OANDA's metals session: its D / W open re-pinned to the stamp, the
    close unchanged. A real CME session (1700-1600 Chicago) is pinned
    with open == stamp.
  - tests/test_oanda_day_stamp_grid rule D (88cd0c8's design pin: the
    1800-1700 D/W/M open and D label at the 18:00 session open) now
    reads the 17:00 stamp; the W/M open follows the D bar (the same
    relation 1700-1700 has) -- extrapolated, no W/M tape.

tests/test_pine_time_day_stamp_grid pins the four tapes and the CME
regression grid (92 checks). ctest 154/154 (153 + the new binary;
test_oanda_day_stamp_grid 692, test_session_day_anchors 23853);
scripts unittest 102 OK; check_c_abi_runtime.py clean. Against the
previous library 53 / 18 / 4 of those checks fail respectively.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Dwbd239WT9zfcTLYM5UpUU
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant