Skip to content

Pine v6 semantics fixes from TV-parity campaign#38

Merged
luisleo526 merged 15 commits into
mainfrom
campaign/pine-semantics-fixes
Jul 4, 2026
Merged

Pine v6 semantics fixes from TV-parity campaign#38
luisleo526 merged 15 commits into
mainfrom
campaign/pine-semantics-fixes

Conversation

@luisleo526

Copy link
Copy Markdown
Contributor

Fifteen transpiler fixes from the TV-parity validation campaign, rebased onto v0.8.1:

  • 57e8545 Fix timezone timestamp DST inference
  • 837ffcd Alias UDT array elements when mutated
  • 21bfbda Emit Pine bar index through offset helper
  • db50a48 Fix security timeframe aliases and time history
  • 74366b2 Propagate na through math min max
  • 80914e3 Fix security helper history context
  • 2520e7f Fix timeframe namespace in security context
  • 8108915 Fix numeric ternary type promotion
  • 331429d Fix Pine for-loop direction with explicit by
  • 176dc5d Clear source-input series after TA precompute
  • (plus 5 earlier campaign commits in this range)

Gate after rebase: full suite with engine headers — 1429 passed, 1 skipped (71s), matching the expected baseline.

🤖 Generated with Claude Code

luisleo526 added 15 commits July 5, 2026 00:06
Bugs solved:
- Preserve tuple-returning TA results through request.security and mutable security history rebinds.
- Type untyped string params/locals/timeframe expressions correctly for string concatenation.
- Materialize inline expression args passed to UDF series params.
- Type array.new<T>(..., na), drawing-array constructors, str/syminfo/text constants, timestamp timezone expressions, and stdev/variance biased args.

Validation:
- pytest tests/test_codegen_validation_fixes.py tests/test_support_checker.py -q
- data/draft compile-error count: 5 -> 0
- data/standard+anomaly grade unchanged
Guard static TA precalculation so user series aliases that are not replayed in precalculate() use the live per-bar TA path instead of producing all-na results. Also emit strategy.exit profit/loss as relative tick offsets for the engine instead of freezing prices from position_entry_price_ before pending entries fill.
Teach codegen type inference to remember inline local declaration types outside helper functions and to carry array element TypeSpecs for for-in loop variables. This prevents string concatenation from wrapping existing strings, including UDT string fields and local string labels, in std::to_string; fixes standard compile failures in generic dashboard/label code.
Generated hour/day/time-field lambdas and timestamp(timezone, ...) used POSIX TZ directly. Emit calls to the engine timezone normalizer so TradingView-style GMT+/- and UTC+/- strings resolve with the same sign convention as Pine.\n\nUpdates timezone and timestamp regression tests to pin the normalized emission.
Preserve comma-separated simple statements so side-effecting assignments and array calls after the first comma are emitted.

Lower namespaced array.fill and array value arguments with typed na/default values instead of skipping or emitting incompatible na<double>() values.

Lower Pine v6 bool(x) casts so numeric na maps to false instead of C++ treating NaN as truthy.

Refresh the matrix PCA golden after the prior TA-precalc safety change and cover the new validation cases.
Reset replayed input.source Series members and native source backing series around static TA precompute so the cache pass cannot leak full-feed history into the real run.

Covered by a regression using input.source with static pivot precompute; validated with full codegen pytest, engine corpus, and all data/standard strategies.
Lower Pine for-loops through the same runtime direction path whether or not a by clause is present. This fixes descending loops such as array.size(x) - 1 to 0 by 1, where codegen previously emitted an ascending <=/+= loop and skipped array-removal bodies. Add regression coverage for explicit-by direction inference and compile-smoke coverage for descending array.remove loops.
Promote mixed int/double ternary branches to double in codegen type inference. This fixes ratio expressions such as range == 0 ? 0 : (close - low) / range being stored as int, which zeroed fractional values and suppressed valid entries. Adds regression coverage and passes codegen, engine corpus, engine ctest, and data/standard gates.
Lower timeframe.* reads inside request.security evaluators against the requested timeframe instead of the chart script timeframe. This fixes weekly/monthly security expressions such as timeframe.isintraday, timeframe.isweekly, and timeframe.ismonthly while preserving timeframe.main_period as the main chart/declaration timeframe.

Validation: focused security-timeframe TradingView probe; pytest -q; engine ctest 78/78; pineforge-engine scripts/run_corpus.sh 252 clean; scraper data/standard 77/77 ok.
request.security expressions like helper()[1] were lowered through a chart-context history lambda, so helper bodies could evaluate timeframe.*, OHLC, and nested math in the wrong context before applying the offset.

Add security-context history for non-TA helper call results and lower math.* calls while inlining helpers inside request.security. Verified with the TradingView-backed pf-probe-security-helper-history-context probe, full codegen tests, engine ctest, engine corpus, and data/standard.
math.min/math.max were lowered to std::min/std::max, which can turn NaN operands into numeric clamp results. Pine propagates na for these math calls, so expressions like math.max(-1, math.min(1, na)) must remain na.

Emit a shared is_na guard for math.min/math.max in both normal and request.security helper contexts. This fixes the Mayur weekly HTF score class where a weekly vwap component should be na and then nz(...)=0, improving the weak-tier probe from 0/4 to 3/4 and the original strategy from 0/289 to 193/304 matches.

Verified: focused tests, full pytest, engine ctest 78/78, data/standard 77/77 ok, engine corpus 252/252 with 251 excellent + 1 documented anomaly.
Register request.security evaluators with expanded runtime timeframe expressions when the timeframe comes from input-backed aliases, instead of default-initialized global members.

Add generic support for time/time[n] inside request.security bar-field history, including dynamic offsets and int64 history storage.

Validated against Nico weak mismatch, isolated security probes, standard data, engine corpus, engine ctest, and full codegen pytest.
Map Pine bar_index and drawing coordinates through pine_bar_index() so chart-history offsets do not leak into generated strategy logic.

Fix history-referenced bar_index[n] by feeding its Series from the offset-aware helper; this prevents unfed history buffers and inflated loop bounds.
Treat array<UDT>.get/first/last results as UDT lvalues when a local mutates their fields, so generated C++ emits references instead of value copies.

Preserve active function parameter TypeSpecs so typed array<UDT> parameters participate in lvalue detection; fixes Fluxchart-style zone state updates generically.
@luisleo526 luisleo526 merged commit 5933571 into main Jul 4, 2026
9 checks passed
@luisleo526 luisleo526 deleted the campaign/pine-semantics-fixes branch July 4, 2026 16:11
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