Repository navigation
Explain both EMA seeding modes in PF-W1505 and name the series_origin_ms run option - #342
Conversation
Tests only. The diagnostic-notes tests declare the one text change of PF-W1505 (message, hint, explanation) next to the declared lookahead migration, and a new test pins the note text. The note names ta.macd and ta.tsi as the functions whose seed the series_origin_ms run option changes and says that ta.kc and ta.kcw already start na and seed from the SMA in every run; the KC middle band test follows the note wording. On a tree without the catalog change these tests fail because the catalog still carries the old text. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…_ms run option Text only: the diagnostic code, severity (note), call sites and generated C++ are unchanged. The catalog message, hint and explanation state that ta.ema (and the EMA inside ta.macd and ta.tsi) seeds from the first value by default, which matches a TradingView chart with history before the range, and that a reference starting at the range start is declared with series_origin_ms. ta.kc and ta.kcw already start na and seed from the SMA in every run, because their generated shim applies the warm-up to the EMA basis: the contract and the reference row say so. The diagnostic-notes tests declare this one text change explicitly; the pin of PF-W1505 is updated. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
There was a problem hiding this comment.
Graphify reviewed this change.
No issues found by static checks — no coupling regressions or blocking issues in the code graph. That is not the same as safe to merge: see what was not checked.
Not checked: tests were not run; formal verification proved 0 of 1 changed function(s) (1 not verified).
Formal verification. PR-changed functions: 0/1 verified (0 proven, 0 may-equivalent, 0 distinguished) · 1 not verified (1 unsupported).
Not verified on this run: \_visit\_FuncCall (unsupported).
Graphify review — findings
Rewrites the PF-W1505 ta.ema note so it explains both EMA seeding modes instead of calling the behaviour a "warmup approximation". By default ta.ema (and ta.macd/ta.tsi) seeds from the first value and is finite from bar 0, which matches a TradingView chart with prior history. When the reference starts at the range start, declaring the series_origin_ms run option via syminfo gives na for the first length-1 bars, then an SMA seed. A wrong origin gives wrong values, and the option must not be set for live runs. The PUBLIC_CONTRACT.md and CHANGELOG.md text documents the origin option's effect on request.security, notes that ta.kc/ta.kcw already start that way, and cites the measured 336-exit reference. It also scopes the 1.5.0 "unchanged message" claim to that migration only. The note is still emitted unconditionally at every ta.ema call, and this is a text-only change: seeding and generated C++ are unchanged, and undeclared runs behave as before.
Review partial — this diff was larger than one review pass covers, so later files were not reviewed; some findings may be missing.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 3972 functions depend on the 310 functions this change touches.
Health — this change adds coupling hotspots:
- worse:
_generate()— 9 callers, 25 callees
Verification — 3972 functions in the blast radius were not formally verified this run (proofs are advisory here).
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 2921 function(s) in the blast radius were not formally verified this run
Cross-repo impact
Cross-repo impact
This change impacts 2 symbol(s) across 1 peer repo(s) — blast radius over derived cross-repo edges:
- pineforge-4pass/pineforge-hpo —
python/pineforge_hpo/transpile.py(via import_moniker, heuristic),tests/python/test_transpile.py(via import_moniker, heuristic)
1 peer repo(s) in this group are not yet indexed — cross-repo impact may be incomplete.
Cross-repo linkage is derived (SCIP-moniker matches are sound; name/contract matches are heuristic) and ADVISORY — it never affects this check's conclusion.
Formal verification
Could not verify: Could not verify \_visit\_FuncCall.
The verifier did not have enough to check \_visit\_FuncCall, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: method — first parameter is `self`, which needs a constructed instance (not synthesizable)
· 1 more finding(s) on lines outside this diff (see the check run).
Summary
The static note PF-W1505 that every
ta.emacall gets now explains both seeding modes and names the engine run option that declares where a reference series starts. Text only: the diagnostic code, its severity (note), its call sites and the generated C++ are unchanged.By default
ta.ema(and the EMA insideta.macdandta.tsi) seeds from the first value of the data PineForge runs. That matches a TradingView chart that had history before the range, and the difference has decayed by the time the range starts. When the TradingView reference starts at the range start, the engine run optionseries_origin_ms(the open time of the reference's first bar, in epoch milliseconds, passed through the run'ssyminfo) selects TradingView's seed:nafor the firstlength - 1bars, then the SMA of the firstlengthbars; it also startsrequest.securityseries at the first whole higher-timeframe bucket at or after that time.ta.kcandta.kcwalready start that way in every run, because their generated shim applies the warm-up to the EMA basis; the note says so and does not list them among the functions the option changes.Companion: pineforge-engine#766 adds the option; an engine without it ignores the key. This change should land after it and in the same release.
What changed
pineforge_codegen/support_checker.py.docs/PUBLIC_CONTRACT.mdand the row "Chart EMA warmup" ofdocs/reference/support-contracts.mdstate the same in the contract; the row keeps its description of the_PFKC/_PFKCWshims, the covered TradingView tape that records the KC middle band asnaon bar 0, and namestests/test_kc_middle_band.py.CHANGELOG.mdhas one bullet, including the measured size of the difference: on a 336-exit TradingView reference that starts at the range start, 37 exit comments differ by default (5 of them finite where TradingView isna) and none differ with the origin declared; six corpus cases add, drop or shift 1 to 3 trades in the first days by default and all six are exact with the declared origin. A wrong origin gives wrong values; the option has no defined meaning in a live run. Where those figures come from: they were measured on 2026-11-03 against the engine change that adds the option, with a private TradingView capture for the 336 exits and with six corpus cases; on 2026-11-07 the same capture was run again on the head of pineforge-engine#766 and all 336 exit comments are equal with the origin declared. The 37 differences by default and the six corpus cases were not repeated.tests/fixtures/diagnostic_codes_pin.json(one line, recomputed from the catalog entry).Tests
tests/test_warmup_note_text.py(new): the note's exact message and hint, the wordsseries_origin_ms,SMA,ta.macd,ta.tsiandrequest.securityin the hint, the sentence thatta.kcandta.kcwalready start that way, no unfilled braces;ta.rsiemits no such note.tests/test_diagnostic_notes.pyandtests/fixtures/diagnostic_notes/delta.json: the declared text change of the three PF-W1505 fields, next to the existing declared lookahead migration (both mechanisms are kept; neither side's assertions were dropped).tests/test_kc_middle_band.pyfollows the note wording; its native row pins that the generatedta.kcmiddle band isnaon bar 0 while a standaloneta.emais finite.Not covered
ta.macdandta.tsihave no generated shim, so they read the engine's ambient setting; that statement was read from the code and not run for these two functions.🤖 Generated with Claude Code