diff --git a/AGENTS.md b/AGENTS.md index 460cb47..532e83d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -344,10 +344,16 @@ Keyword arguments of the matrix methods and of the checked array methods (`get`, `pineforge_codegen.support_checker` is the gate. Its job is to fail loudly **before** codegen so users never get a silently miscompiled strategy. An error raises `CompileError` (carrying every diagnostic); the -warnings of a script that transpiles (support checker, then analyzer and +warnings and notes of a script that transpiles (support checker, then analyzer and codegen `ctx.diagnostics` -- the codegen appends through `_codegen_warning`) come back as `transpile_full(...)["diagnostics"]` and in `transpile_json`'s success envelope under `diagnostics`, in the error envelope's entry format. +A note (`Level.NOTE`, since 1.5.0, raised through `SupportChecker._note`) is nonfatal and +informational. Only PF-W1505, PF-W1508, PF-W1509 and PF-W1525 to PF-W1532 are +notes, each keeping its `PF-W` code; every other diagnostic keeps its level, +the other visual-only and display-only ones included (for example PF-W1078, +PF-W1502, PF-W1506, PF-W1507, PF-W1552). A `PF-E` code is an error; a +`PF-W` code can be a warning or a note, so read its declared severity. Checked settings string defaults and options use only known C++ string literals from the existing builtin lowering, never inert visual integer codes. Only the @@ -412,7 +418,7 @@ taxonomy: | `var` initializers | A `var` initializer runs once, in statement order, on the first bar that reaches its declaration: a primitive `var` at its declaration under a one-shot flag. One read with history (a `Series` member) keeps the first-bar preamble only for a top-level declaration of a constant, a string literal, `na` or a bar field (`_series_var_init_keeps_preamble`, byte for byte); one in a block, whatever its initializer, reads na history until the first bar that reaches it (the preamble pushed bar 0's value: a block's `var float fc = close` held the first bar's close), and any other initializer -- a UDT field (`var int signal = direction.neutral`), a global computed before it (`var float first2 = b`), a call, `ta.*`, an input's override, a `switch` / `if` selection (the preamble's spelling of one did not compile; `tests/test_e2e_cgint5_compositions.py`) -- runs at its declaration too, the preamble pushing its na until then. The preamble used to push the analyzer's spelling ahead of the body: raw Pine that did not compile (`signal.push(direction.neutral)`, the ten ai-distribution probes) or a global before it was assigned (0), and an input's default. `tests/test_e2e_series_var_init.py` replays TradingView's tapes, an override and a block included (`fixtures/silent_tv`). | | `request.security` helpers | A payload inlines the user functions and typed user methods it calls on the requested bar, under a builtin call too (`nz(f())`, `close.g()`, `nz(ta.sma(close, 3))`: the expression visitor that renders the builtin hands every user call, TA site, helper-bound name and requested-bar history back to `_build_security_expr`). Under a builtin, and for a method, only a single-expression body is inlined, every user call in it too, also through a global's value (`_security_body_is_expression`); a multi-statement one keeps the chart call and warns, because the evaluator writes its statements ahead of the payload, where a ternary arm or an `and`/`or` operand would run them on every bar. A TA site reached through several helper bindings gets one variant per binding, numbered (`_v0`, `_v1`, ...) by where each binding's value is written (`_security_variant_order_key`; the signature names nodes by `id()`, whose order is memory's; `tests/test_security_variant_order.py`). A helper called on its own result (`u(u(close))`) gets a variant per written call: the variant walk's recursion guard is keyed by the call, not the helper's name, which skipped the inner call as recursion and left it reading an undeclared base member (`tests/test_e2e_security_nested_helper_call.py`). A helper local's value is re-walked under the helper-name guard still (`_security_local_rewalks`): the evaluator reads the local's C++ variable, and entering the helper again there walked every earlier local once per read, 2**n walks over a chain of n locals. A call of a pure helper (one expression over its parameters, the requested bar's fields and literals, through operators and such calls) on arguments of that kind holds nothing a prepass collects, so the payload's walks stop at it; once its inlined text is 256 characters long its value is computed once where the evaluator opens (`_pf_shared__`, `_security_share_pure_call`) and every reach with the same arguments reads it, where a diamond of such helpers inlined its leaf once per path (`tests/test_security_helper_diamond.py`). A payload's `bar_index` is the requested bar's, the count of requested bars before it (`_sec_bar_index_`, advanced where the evaluator opens a requested slot; `bar_index[k]` k requested bars back, na before the first; `tests/test_e2e_security_bar_index.py`). A global the payload reads at an offset (`g[1]`) whose value is a user function's call or a numeric operator expression keeps its history on the requested clock: the value the payload reads as `g`, pushed once per completed requested bar where the evaluator closes (a helper inlines the read at each read of its parameter), and the payload lowers such a global once per evaluator (`g - g[1]` inlined the call at each read, which advanced its TA state once per read). The push takes the value of a read that ran, as an inline expression's history does: a read in a ternary arm, an if branch or a loop that did not run on a requested bar pushes nothing there, where TradingView's history holds every requested bar (a limit). The once-per-evaluator lowering holds within the block that emitted its locals: a later read outside a helper's if branch or loop lowers the call again, as every earlier build did at each read (it named the locals out of scope, which did not compile), except that a call with state (a TA site, a `var`, a request, a user method) whose global the payload also reads with history on the requested clock is refused where two of its lowerings can run on one requested bar, since its state would advance twice a bar (every earlier build refused that history read; one under a builtin keeps the chart's series and never counts, and the two arms of one if never run together). The builder refused the call's history ("helper call history is only supported in the payload itself") and indexed the operator expression's C++ scalar, which did not compile (`_security_global_history_value`). That history is a double (a bool's a bool), whose na reads na -- typed from the global's `int`, the first requested bar read `na()` as -2147483648 and a 64-bit integer ("Epoch ints": `g = bar_index * 86400000`, or an epoch) wrapped -- and an integer slot of the evaluator (a helper's `int` local, an int tuple element) takes it narrowed na-preserving (quirk 9; an int reaching the chart's double still reads `na()` as a number, as on main). Only a read lowered on the requested clock is so: one under a builtin (`nz(g[1], 0) / 2`) keeps the chart's int series and main's lowering, and a string global's history there is refused, as every earlier build refused it (`tests/test_e2e_cgint7_compositions.py`). A `request.security` of Heikin-Ashi bars inside the payload reads the requested context's Heikin-Ashi bars on TradingView, which the evaluator does not build: evaluating it stops the run (`_security_nested_heikinashi_request`), so a selection that never takes it (`useHA ? request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close) : close` at its default) runs on the requested bars, where rendering the call read the chart's own request. An `int` / `float` cast whose argument reads a helper's parameter or local (a TA length `int(math.round(_len / 2.0))`) is the builder's own where the TA constructors are planned: the expression visitor rendered the name as an unknown variable. `tests/test_security_global_history.py` replays TradingView's tapes (`fixtures/tail_a_tv`). A global under a builtin call (`nz(s)`) is re-evaluated on the requested bar as a bare payload global is, when the expression map holds it and it is neither replayed state nor a per-run value (`_security_fallback_owns_global`); its history there (`nz(s[1])`) keeps the chart's series and warns (`tests/test_e2e_security_global_under_builtin.py`). All or nothing per evaluator (`_emit_security_evaluator_requested`): when a builtin call also reads something else on the chart's terms (a global it does not re-evaluate, history the builder does not own, `timeframe.*`: `_security_root_chart_read`) beside a call the evaluator inlines, or it refuses such a call (a shape a bare payload refuses), the evaluator keeps the lowering every earlier build emitted, its calls on the chart, and warns; a method with a non-scalar receiver or argument keeps the chart call and warns. A global that a top-level tuple declaration binds to a TA tuple call's element reads that field of the requested result; one bound to another tuple (a user function's) is refused there, as is history of a TA tuple's element, both of which used to emit C++ that did not compile. History of a helper call inside a helper body the payload inlines (`h() => nz(g()[1])`) is the requested bar's, where the payload reaches it once; one it reaches twice (`h() + h()`) is refused where it is lowered (`_collect_security_expr_hist_subscripts`; `tests/test_e2e_security_helper_body_history.py`). Under a builtin, TA tuple element history, read directly or through a global's value, is refused where every earlier build pushed the whole result into a double history; where one compiled (a multi-statement helper reaches the tuple, the read is a user call's argument, or the tuple is a user function's) it keeps the chart's series and warns. An inlined helper's local takes `na` of its own type and narrows to int or bool through quirk 9's na-preserving cast. A helper body may hold declarations, tuple declarations (`[m, s, h] = ta.macd(...)`, a nested helper's tuple), assignments, if-branches and bare expression statements; a local holding a `switch` whose arms are single expressions lowers to their ternary chain, which evaluates only the arm its selector takes (`tests/test_e2e_security_helper_switch.py`: it rendered as `/* unknown */`, which did not compile); a `for` or `while` loop (with `break` / `continue`) runs on the requested bar: its counter is a local, `o[i]` reads the requested bar's open `i` requested bars back, and a `for` keeps Pine's direction, step magnitude and `to` refresh; a loop holds plain locals only, since the evaluator computes a TA call, pushes a history-read local and keeps a `var` once per requested bar (a TA call, a `var`, a local read with history, a `request.*` / `strategy.*` call or a user call in a loop is refused by name: "request.security helper loops cannot hold ..."; `tests/test_e2e_security_helper_loops.py`, `fixtures/tail_e_tv`), and so is one reaching the loop through a name the lowering expands where it is read: a helper parameter's argument (`h(ta.sma(close, 3), n)` computed the SMA once per iteration, and so did a TA variable, `h(ta.accdist, n)`), or a user call or a `request.*` / `strategy.*` call in a global's declaration (`cs = sm(close)`), whose own TA sites are computed once, before the payload, and read freely; a name a loop statement declares is the loop's own in its block after its declaration (its initializer and a read after its block read the enclosing name); a `for` loop's counter is a counted loop's binder for the 64-bit rule, as on the chart ("Epoch ints"; `fixtures/cgint7_tv/cgint7_loop_products`), while a product with another helper-bound operand, and a `while` loop's counter, keep the payload's 32-bit spelling (a limit); a `for ... in` loop, a `switch` statement and a block arm stay refused. Helper `var` state (int, float, bool, string: strings in `_security_helper_series_str_`) belongs to its call site and advances once per requested bar; its family is read in the epoch-only mode (`_security_helper_var_state_type`): a width only the 64-bit arithmetic rule ("Epoch ints") gives it, its own or a same-spelled name's in another callable (`g() => n = days * 86400000` beside a helper's `var int n`), keeps the int family, whose double series holds the value exactly (the arithmetic width refused such a script, which compiled before; `tests/test_e2e_cgint6_compositions.py`), while an epoch, or an int-literal product past int32 in its own initializer, reaching it stays refused, as it always was. A helper tuple mixes int, float, bool and string elements, each stored in its own family: before the first requested value and on a `gaps_on` bar completing none, a bool element reads `false`, a numeric one `na` and a string one empty; a string payload returns a `std::string`. A TA history index is a literal or a bar-invariant int over inputs; an input it or a helper's TA constructor argument reads is its getter, a never-reassigned `var` input's too (`_security_var_input_call`; `tests/test_e2e_security_var_input_length.py`), since `evaluate_security` can run before `on_bar` reads the inputs; a payload divides two ints as floats. A TA length chosen by comparing an `input.string` with its options (`mode == "A" ? 5 : 10`) is input-derived, on the chart and in a payload (string literals are spelled in `_arith_expr_to_str` and blanked out of the reset path's identifier scans). The evaluator's prologue orders its TA variants so each follows the variants its arguments read, all at the evaluator's top level (a later global's TA read by a helper's TA was computed inline and again, twice a bar; `_security_prologue_order` follows what each variant's arguments can reach, and learns the reads by building each variant's arguments once, every side effect undone, only where that graph has a cycle; `tests/test_security_price_history_and_later_globals.py`, `fixtures/xsym_a2_tv`, lane CG-XSYM-A2). `tests/test_e2e_security_*.py` replay eight TradingView tapes (`fixtures/security2_tv`). A helper local a requested TA length reads is a value of each requested bar when it is a `var`, rebinds from its own value (`c += 1`, `c := c + 1`, or through another local: `b = a` then `a := b + 1`) or is reassigned in an if arm (a local the arm declares shadows it there): `ta.highest` / `ta.lowest` / `ta.highestbars` / `ta.lowestbars` re-window every call with it, and any other `ta.*` is refused naming the local (TradingView refuses such a length for `ta.ema`; PineForge does not lower its `ta.sma`). The planner bound each to one expression: `c += 1` to the literal 1 (a constant length, lane CGINT4), `c := c + 1` to an expression reading itself (Python recursed until its stack ran out); `tests/test_e2e_security_helper_var_length.py` replays TradingView's tape (`fixtures/silent_tv`). | | `request.security` contexts | A request's symbol and timeframe are registered before the first bar. When they reach it through helper parameters, `security_contexts.specialize_security_contexts` (between the support check and the analyzer) resolves them on every call path from the top level, each parameter read in its caller's scope, down to globals, inputs, literals and built-ins: one context on every path is annotated on the request, several copy each helper on the paths once per context (`h__pfctx1`, ...; a copy's locals and loop variables are renamed too, `v__pfctx1`, since the analyzer keeps one history buffer per callable local name), and a parameter carrying one is declared `string`. It used to register the chart's timeframe (`input_tf_`), silently. A request whose timeframe or symbol is a bare parameter bound at every call site to a global expression keeps the analyzer's call-site clones (`callsite_idx`), which register a literal as a literal and anything else, an input too, as that expression (an input used to register its default, so an override was ignored), and a symbol clone its call site's Heikin-Ashi flag; a helper whose calls all pass one context is emitted once and its calls name it (they named a `f_cs0` nothing emitted: `f(string sym) => request.security(sym, "60", close[1])` did not compile; `tests/test_security_single_context_helpers.py`). A context no registration can compute (a series, a reassigned local, a user call, a method or overloaded helper on the path, too many paths) is refused by name; only a dead helper still registers the chart timeframe. A parameter of the helper that the request's payload reads is part of the context too, resolved the same way with bar series and user calls allowed: the request is copied per value and each copy's payload reads the value in the parameter's place. The evaluator never bound one: `nr(_s, _tf, _e) => request.security(_s, _tf, _e[1], ...)` read a member nothing pushed (`na`), a bare `_e` was an unknown variable, and `f(3)` and `f(6)` shared one `ta.sma(close, len)` built from the first call's length. Only a value the builder lowers on the requested bars in the read's place is put in (`_Lowered`): chart series, `ta.*` and `math.*` calls, inputs (an untitled one titled with its declaration's key), `input.source` values and stable globals built from them, a global declared after the helper too when it is a number or a bool (the copy's read carries its binding, `GLOBAL_ANNOTATION`, where the analyzer binds none: it read the chart's value; the analyzer types the name a float, so a later string keeps its refusal); a history object is a bar or price series (`hl2` to `hlcc4` too), a `ta.*` call (inline or a global's value), an `input.source` value, an inline operator expression, or a global holding a numeric operator expression or a call of a user function the builder inlines whole (one definition whose body declares plain locals and ends in an expression over its parameters, bar series and literals, through operators, single-valued `ta.*`, `math.*`, `int` / `float` / `nz` and such calls: `_inlined_function`), such a call's global also as a value; no global under a builtin rendered on the chart's terms. Any other value keeps its lowering, never a refusal, and a history read of such a parameter warns that it reads `na` (not in a helper nothing reaches). A length every top-level call passes one value keeps the analyzer's single evaluator; its call-site clones for differing timeframes built every clone from the first call's length. A Heikin-Ashi symbol alias declared after the helper keeps its flag. `tests/test_security_contexts.py`; `tests/test_e2e_security_nested_contexts.py` replays TradingView's nested-helper tape (`fixtures/xsym_tv`), `tests/test_security_payload_params.py` two payload-parameter tapes. | -| Requests with no data | `request.financial` / `earnings` / `dividends` / `splits` / `footprint` (`NO_DATA_REQUEST_FUNC`) and `request.security` on another symbol, whose value reaches display and alert sinks only or that read no recorded series or feed (the next rows), read data the engine does not load. `external_requests.TradeSlice` follows the value forward: one that reaches alerts, plots, tables and logs only -- through operators, na-safe built-ins, user functions and bindings, `var` too -- is lowered to na by `lower_no_data_requests` (between the support check and `security_contexts`; a helper's bool tuple becomes `[false, false]`) with the WARNING "value reaches only display/alert sinks; lowered to na; trades are unaffected". Every other one -- it can reach an order, `runtime.error`, a collection, a drawing, a method, a history offset or a `break`, or its arguments do anything but compute -- is a deferred refusal: it warns "no data is pinned for this request; the run stops with an error where its value is read" (the use named in the hint) and lowers to a value whose first READ stops the run with that request named. Binding it is no read: the reads of a declaration holding the whole request (its names never reassigned) stop the run, else evaluating the request does. TradingView never evaluates a `switch` arm its selector does not take (a default arm beside one stopping the script books its trades), and a script reading a request only in such an arm runs. TradingView's tapes of a strategy with an alerts-and-table watchlist and of the same strategy without it are byte for byte one tape on BINANCE:ETHUSDT.P 15 and NASDAQ:AAPL 15 (`tests/test_external_requests.py`, `fixtures/xsym_tv`). | +| Requests with no data | `request.financial` / `earnings` / `dividends` / `splits` / `footprint` (`NO_DATA_REQUEST_FUNC`) and `request.security` on another symbol, whose value reaches display and alert sinks only or that read no recorded series or feed (the next rows), read data the engine does not load. `external_requests.TradeSlice` follows the value forward: one that reaches alerts, plots, tables and logs only -- through operators, na-safe built-ins, user functions and bindings, `var` too -- is lowered to na by `lower_no_data_requests` (between the support check and `security_contexts`; a helper's bool tuple becomes `[false, false]`) with the NOTE "value reaches only display/alert sinks; lowered to na; trades are unaffected" (`Level.NOTE`, PF-W1525 to PF-W1532, raised by the support checker's `_lower_no_data_request`). Every other one -- it can reach an order, `runtime.error`, a collection, a drawing, a method, a history offset or a `break`, or its arguments do anything but compute -- is a deferred refusal: it warns "no data is pinned for this request; the run stops with an error where its value is read" (the use named in the hint) and lowers to a value whose first READ stops the run with that request named. Binding it is no read: the reads of a declaration holding the whole request (its names never reassigned) stop the run, else evaluating the request does. TradingView never evaluates a `switch` arm its selector does not take (a default arm beside one stopping the script books its trades), and a script reading a request only in such an arm runs. TradingView's tapes of a strategy with an alerts-and-table watchlist and of the same strategy without it are byte for byte one tape on BINANCE:ETHUSDT.P 15 and NASDAQ:AAPL 15 (`tests/test_external_requests.py`, `fixtures/xsym_tv`). | | Requests of other symbols | A `request.security` of another symbol whose value can reach a trade reads the feed a probe's requests manifest pins for it (`PINEFORGE_REQUESTS_ROOT`; the engine's instrument feeds, `FEED_LOWERING`), with the WARNING "another symbol's bars, read from the feed the requests manifest pins for it; with none installed, the run stops with an error where its value is read". `configure_security_evaluators()` registers it by its symbol string as the run computes it before the first bar -- a literal, an input's getter, the chart's `syminfo.*` strings and operators and ternaries over them (`ScriptIndex.registration_value`), or a helper's parameter resolved on every call path (`security_contexts` owns such a request whatever its timeframe, so three symbols at two timeframes through three helper levels are six contexts) -- and its `ignore_invalid_symbol` (na for a symbol whose facts say it is invalid; without it the run stops): on the chart when the string is the chart's (the one the manifest resolves it to, else the chart's ticker id or `syminfo.ticker`), on the installed feed of (symbol, timeframe) otherwise, and not at all without one, when its reads stop the run as a deferred refusal does (`_pf_sec_missing_N`), never reading the chart. Its payload runs on that symbol's own bars: history, `ta.*` state, `bar_index`, `time_close` (the host's, the feed's close) and `syminfo.*` are the requested context's, and `ta.ema` there is SMA-seeded (na until `length` values) as TradingView's is; an int tuple element is held as an na-preserving double (a millisecond stamp overflows an int); under gaps_on a chart bar the feed hands nothing reads na and the context's history carries on. A symbol that can select the chart's or another symbol's (`useOther ? "TVC:DXY" : syminfo.tickerid`) registers the same way when its value can reach a trade: it read the chart's bars for both arms; through a helper's parameter that registration cannot compute on some path, it keeps that chart lowering and its warning. A symbol registration cannot compute (a series, a reassigned name, a method's parameter, a block's local, a path the pass cannot follow), a timeframe it reads before the first bar with no value yet (a `var`, a reassigned name, a series: `ScriptIndex.registers_timeframe`; it registered the chart's), and a request inside another request's expression, written there or in a helper the expression calls, keep the deferred refusal, with a warning naming the path. `ticker.inherit(from_tickerid, symbol)` names its symbol second (`ticker_symbol_arg`; it was read as the chart's). A `request.security_lower_tf` of another symbol whose value can reach a trade stops the run where it is evaluated (`ABSENT_LOWERING`: it read the chart's intrabars); one that can select the chart's keeps its lowering and warns. A tuple request whose names are reassigned stops where it is evaluated (the tuple emitter never visited it, and a missing feed read na). A payload that is `request.footprint(ticks, va)` (literal whole numbers) reads the feed's `fp_delta__` column on the requested bar (`FOOTPRINT_COLUMN_ANNOTATION`), a feed without the column being missing data, the chart's own symbol too (the chart's bars carry no footprint: it read the chart, and na); a footprint value is its delta -- a declaration or helper parameter typed `footprint`, one holding the request or a helper's call returning it, a parameter a call passes one to -- so `fp.delta()` and `footprint.delta(fp)` read it (`read_footprint_deltas`: they did not compile) and every other `footprint.*` member is refused by name. TradingView's footprint delta of a range depends on the range (the month slices of a year disagree), so a footprint feed holds for the window it was captured over, where a synthetic BITSTAMP:BTCUSD delta filter on BINANCE:BTCUSDT 15 books its 1674 trades exactly. `currency=`, `ticker.new` and `ticker.modify` stay refused. A `barmerge` constant is a value (on 1, off 0), held and compared (`var gapStrategy = gaps ? barmerge.gaps_on : barmerge.gaps_off`, `TradingView/Request/3`); a request's gaps and lookahead read the constant as written: a computed one keeps a chart request's refusal, and makes a request of another symbol read no data (its first read stops the run) with its registration naming why (`fixtures/tail_f_tv/barmerge_values`). TradingView tapes of synthetic strategies (a TVC:DXY EMA cross on NYSE:F 15, BINANCE:BTCUSDT 1D and BINANCE:ETHUSDT.P 15, TVC:VIX 240 `ta.ema(close, 14)[1]` lookahead_on on NASDAQ:AAPL 1D and OANDA:XAUUSD 15, gaps_on on NYSE:F 15 and ETHUSDT.P 15) match trade for trade on the XSYM-B captures, and the XSYM-DESIGN alignment witnesses bar for bar; they stay outside this repository with the captures. `tests/test_foreign_requests.py` replays the rules on generated bars. | | Recorded requests | A `request.earnings` / `dividends` / `splits` / `financial` whose value can reach a trade reads the series TradingView returned per chart bar, which the requests manifest records (`chart_open_ms,value`, every bar TradingView answered non-na) under `||||gaps_|lookahead_` (`RECORDED_LOWERING`, the workflow's `formatRecordedKey`): TradingView's report-time and fiscal-period logic is recorded, not modelled. The key's symbol is the string the run passes (`syminfo.tickerid` is the lane symbol, the key the capture records), its other parts constants of the call: the `earnings.*` / `dividends.*` / `splits.*` field (default `actual` / `gross` / `denominator`), a literal financial id and period (`FQ`, `FY`, `FH`, `TTM`), `barmerge.*` gaps and lookahead (default off; `request.financial` has none). `_pf_recorded(key, _pf_rec_missing_N)` reads the value of the chart bar that opens at the tape's time, na elsewhere, and sets the request's flag from the key computed where the request is evaluated, which its reads test (a key re-rendered at a read, in a helper, read the helper's names), with the WARNING "TradingView's values per chart bar, read from the series the requests manifest records under ...". A key nobody installed reads na where the request is bound and stops the run where it is read, as a deferred refusal does; where TradingView answers na throughout (fundamentals of a crypto chart, an arm a probe never takes) the capture records a header-only tape, which reads na and runs. A spelling no key names -- a field or id that is not a constant of the grammar, a `currency`, a request inside `request.security`, written there or in a helper its expression calls -- keeps the deferred refusal. A PEAD-like synthetic strategy books TradingView's trades exactly on NASDAQ:AAPL 1D (4/4) and NYSE:F 15 (5/5) from the XSYM-B tapes, kept outside this repository; `tests/test_recorded_requests.py` checks keys and replay on generated tapes. | | Switch arms | The support checker visits every arm of a `switch` -- its condition and its block -- as it visits an `if`'s: the generic child walk skipped `cases`' `(condition, block)` tuples, so every arm but the default went unchecked, and a request of another symbol in one kept no lowering (the request contexts then refused it as a chart request they could not key: `TradingView/Request/3`'s `cryptoDerivativeMetric`). Such an arm gets its lowerings; what the checker would refuse there (an unsupported call, a text constant held as a value) warns instead, and keeps the lowering it compiled to, so a script that compiled keeps compiling (`SupportChecker._switch_arm_depth`). The C++ of the 1,384 population sources was unchanged by it (2026-09-29 census). | @@ -431,7 +437,7 @@ taxonomy: | `ta.*` call arguments | `_check_ta_arguments` binds every `ta.*` call to TradingView's signature (`signatures.TA_FUNCTIONS`: TradingView's parameter names, e.g. `series` for `ta.alma` / `bb` / `bbw` / `cmo` / `kc` / `kcw`, and required/optional split) and refuses what TradingView rejects: an unknown keyword, an argument too many, one given twice or a missing required one -- each used to be dropped, shifted into the next constructor slot or passed to a `compute()` that does not exist. `ta.vwap()` with no argument reads as the bare property, as it always has. | | `ta.*` TA1 arguments | The TA1 engine computes `ta.alma` `floor`, `ta.kc` / `ta.kcw` `useTrueRange`, explicit `ta.vwap` anchors, and `ta.pivot_point_levels` `anchor` / `developing` exactly. The generated TU selects those APIs with `PF_ALMA_HAS_FLOOR`, `PF_KC_HAS_USE_TRUE_RANGE`, `PF_VWAP_HAS_ANCHOR_INPUT`, and `PF_PIVOT_LEVELS_HAS_ANCHOR`; when a macro is absent, the shim falls back to the historical lowering. Only omitted-anchor VWAP keeps `ta::VWAP` / `ta::VWAPBands`; every explicit anchor, including `timeframe.change("1D"|"D")`, uses `ta::AnchoredVWAP` / `ta::AnchoredVWAPBands`. The pivot free function remains only for literal/aliased `anchor=true, developing=false`; every other spelling uses `ta::PivotPointLevels`. | | `ta.*` lengths the constructor cannot take | A length (or `ta.supertrend` factor) that is neither a compile-time constant nor an input/timeframe expression the runtime reset re-reads is lowered by its Pine qualifier, as TradingView answers it (lane K-TA-DYNLEN tapes; rules in the engine's `pineforge/source/pine_ta_length.hpp`). A simple length -- fixed for the run: a syminfo preset, `str.*`/`math.*` over those, expanded context-free so a `request.security` payload evaluates it too; a name counts only where it reads the top-level declaration, so one a block, loop or callable binds, or a value declared `series`, is series -- builds the constant-length class on the call's first execution (`pineforge::source::FirstCallBound`, the length checked by `simple_ta_length`: TradingView answers a simple length exactly as the constant, a sparse window through the constant ring). A series length of `ta.highest` / `ta.lowest` / `ta.highestbars` / `ta.lowestbars` re-windows every call (`pineforge::source::Series*`). `ta.supertrend` passes factor and atrPeriod on the call and reads them once (`pineforge::source::PineSupertrend`: TradingView compiles a series factor but uses the first execution's). A series length of any other family keeps the refusal: TradingView refuses it for `ta.rma`/`ema`/`rsi`/`atr`/`dmi`/`macd`/`kc`/`hma`/`tsi`/`rci`, and the other window functions (`ta.sma`, `ta.wma`, ...) are not lowered yet. Each `request.security` copy is planned from the length its own call passes (a helper call's binding, a per-call-site clone) and reads `timeframe.*` in the requested timeframe; a callable's one evaluator refuses call sites that pass different lengths, where a length the `request.security` contexts row copies the request for (a literal, an input, an `input.string` choice) gives each call path its own evaluator instead. Constant- and input-length calls keep their constructor byte for byte; an `input.string` choice of an int length the signature table knows is one (the `request.security` helpers row). Every other argument its spelled string literals would bring to the constructor -- a `syminfo.*` or `timeframe.*` comparison, or an `input.string` choice of a float parameter or of one the table does not know (a VWAP band multiplier, `math.sum`'s length) -- stays here, spelled from its declarations (`_ta_arg_takes_plan`): the reset path reads a payload's `timeframe.*` on the chart's timeframe and casts its expression to an int length. One this lowering cannot spell stays refused, and a callable's one evaluator still refuses call sites that pass different such lengths. `tests/test_e2e_ta_dynamic_length.py` replays five TradingView tapes, `tests/test_codegen_ta_dynamic_length.py` pins the C++. | -| Chart EMA warmup | The generated `_PFKC` / `_PFKCW` shims scope the engine's EMA warmup selector around their internal EMA basis. KC/KCW middle is `na` until the Pine length is warm, including bar 0, without changing unrelated chart EMA call sites. A covered TradingView tape records both KC middle and an independent EMA as `na` on bar 0 and first finite at bar 19 (length 20). The standalone engine EMA remains finite on bar 0, so `ta.ema` warns about that warmup approximation; `tests/test_kc_middle_band.py` pins the limited scope and warning. | +| Chart EMA warmup | The generated `_PFKC` / `_PFKCW` shims scope the engine's EMA warmup selector around their internal EMA basis. KC/KCW middle is `na` until the Pine length is warm, including bar 0, without changing unrelated chart EMA call sites. A covered TradingView tape records both KC middle and an independent EMA as `na` on bar 0 and first finite at bar 19 (length 20). The standalone engine EMA remains finite on bar 0, so `ta.ema` notes that warmup approximation (PF-W1505, a `Level.NOTE` raised at every `ta.ema` call: no runtime warmup sidecar exists and nothing suppresses it conditionally); `tests/test_kc_middle_band.py` pins the limited scope and the note. | | Color na conversions | Packed colors use `int64_t` storage, including typed scalar, array and matrix paths, so their `na()` sentinel survives. `array.from` of colors is a `std::vector`: a color literal, a `color.*` constant, a `color.new` / `rgb` / `from_gradient` call, a conditional selecting one or a script variable bound to one types the element on both sides (`_is_color_value`, the analyzer's `_is_color_constructor`); it was read as a float, and `var array A = array.from(...)` did not compile (`tests/test_e2e_color_arrays.py`, tape `fixtures/silent2_tv/cgs2_color_arrays`). `color.new` preserves an `na` base; `na` transparency becomes 100; an `na` `color.rgb` channel becomes zero. The covered TradingView color probes are pinned by `tests/test_na_truthiness.py`. A finite transparency reaches the engine's `new_color` as a double, whose alpha byte is the nearest to 255 * (100 - t) / 100, as TradingView's for an input or a series transparency and `color.rgb`'s: `color.new(c, t)` at t = 10.5 reads back 11 (a truncating cast read 10; an integer literal keeps its `(int)` spelling). TradingView truncates a constant `color.new` transparency (`color.new(color.red, 10.5)` and `10.6` read 10, `99.5` reads 99), which PineForge still reads through the byte (pinned: `tests/test_e2e_cgint6_compositions.py`, tape `fixtures/cgint6_tv/cgint6_const_transp`). `tests/test_e2e_color_tapes.py` replays the engine's `w11-color-v6-eth15` tape (`fixtures/color_tv`). `color.new(color, transp)`, `color.rgb(red, green, blue, transp)` and `color.r` / `g` / `b` / `t(color)` bind a keyword argument to its parameter's slot, in parameter order (`_color_arg_nodes`; a keyword transparency is converted as a positional one): a keyword was dropped, so `color.new(c, transp = 40)` lowered to the color 0 (`tests/test_e2e_color_keyword_arguments.py`, tape `fixtures/silent2_tv/cgs2_color_keywords`). | | Epoch ints | A Pine `int` slot an epoch reaches is `int64_t`: a name whose declaration or any reassignment gives it a wide value (an epoch builtin, a wide name or parameter, or an expression `_expr_returns_wide_int` traces to one), and a declared-`int` or untyped parameter a written call feeds one (`types._wide_int_provenance`, a fixed point keyed by spelling). The width used to stop at the first copy: `int sel = switch k => E2` over `const int E2 = timestamp(...)`, `alias = firstT` over `firstT := time`, and `f(int t)` called with `time` held 32 bits (1743468300000 read -288422176), and `int(x)` of an epoch casts to `int64_t` (`int(time)` was a 32-bit cast). A function's or method's local declared `float` keeps a float series when an epoch reaches it (`float x = time`: `_callable_series_local_symbol` reads the function's scope, `method__` for a method, which the global lookup missed): its `Series` read the integer sentinel for a missing `x[1]`, so `x - x[1]` was a garbage number on the first bar instead of na (`tests/test_e2e_float_time_local.py`, tapes `fixtures/silent2_tv/cgs2_float_time_local` and `cgs2_float_time_method`). `tests/test_e2e_krunerr_int64_provenance.py` replays TradingView's tape (`fixtures/krunerr_tv`). A method call's arguments do not widen its parameters. Integer arithmetic over literals and the constants emitted as literals keeps 64 bits too: `400 * MS` over `const int MS = 7200000` is 2880000000 (it was the C++ `int` product, -1414967296), folded where the tree is literal after the names are inlined (`_pure_int_literal_value`, `_inlined_int_constant`) and where the emitted C++ is (`_fold_int32_overflow_cpp`: a `request.security` payload expands a global into its declaration), and the slot a top-level declaration of an int constant past int32 initializes is `int64_t`, reassigned or not (`g = 3000000000`, `var int e = 300 * MS`: `_literal_wide_global`); a literal's width (`g = 3000000000`) reaches a declaration reading it while it is never reassigned (`h = g`) but does not travel by spelling into a reassignment (`k := g`), parameters, arrays, `request.security` helper state or a callable's local of the same name, which keep the types they compiled with, while constant arithmetic (`300 * MS`) is a 64-bit product too, whose width travels as the next sentences say. `tests/test_e2e_int64_constants.py` replays TradingView's tape (`fixtures/silent_tv`). An integer `+ - *` those folds leave, whose operands are both 32-bit C++ ints, is computed in 64 bits at run time when its magnitude can leave int32 (`_int_arith_leaves_int32`: literals and inlined constants exactly, an `input.int` by its declared range, else its default and 2**24, `bar_index`, a counted loop's binder, a `for ... in` binder whose spec is `int` (an int element, map value or index; a float element is a double: `v * 1000` over one was truncated) and any other runtime integer name 2**24 (a call's result does not widen); a callable's name resolves in its own callable, a declared `int` local included, whichever callable is being emitted; a reassigned top-level constant past int32, whose slot is `int64_t`, is no 32-bit operand, and an input's named bound reads the top-level constant), and its value is an epoch-like wide value for the slots above: `days * 86400000` over `days = input.int(30)` and `bar_index * 7200000` overflowed. An operand that can be na (a parameter, a local, a script variable) makes the value na: a double (`_wide_int_arith_cpp`, exact to 2**53; the widening cast read `na()` as -2147483648) that every integer store narrows na-preserving, a slot, a parameter, an array element, a map or matrix value. In a `request.security` payload a side the builder re-evaluates as a double computes in double and a name a helper binds keeps its spelling; the rest widens as on the chart, and the payload's copy of a script variable only such arithmetic makes wide is `int64_t` too (`_security_copy_is_arithmetic_wide`, stored na-preserving, a compound `%=` through `std::fmod`); an epoch's or an int-literal product's keeps its `int` copy, as it always did. A tuple element and a function's or method's result holding a constant past int32 (`_holds_wide_int_constant`), and a read of a UDT `int` field (`int64_t` storage) some write fills with one (`_wide_udt_int_fields`), are `int64_t` too. A `map<..., int>` value, `matrix` element or element of an int array only such a value reaches (only an epoch widens an array, `_wide_int_array_names`: a declared `array` parameter, result or field does not bind a `std::vector`) keeps its C++ `int` (its type also types the handle's parameters and its `values()` / `row()` arrays), narrows the value na-preserving and warns where it stores one (`tests/test_e2e_int64_products.py`, tapes `fixtures/silent2_tv/cgs2_int64_products`, `cgs2_int64_followup` and `cgs2_int64_followup2`). | | Array and matrix history | `a[k]` of an array or a matrix variable is TradingView's read-only copy of the collection as the variable left it at the end of its scope's execution k executions back: the bar k bars back for the top level, its block's previous run for a block's local (`tests/fixtures/array_history_tv`). A `var` array's history is the copy, one element shorter than the array it grows (`ahist_ref`), and a `var` matrix's holds the previous bar's value (`ahist_mtx`). The variable keeps its own `std::vector` or matrix member, so every other operation keeps its C++; `_pf_collection_hist_` (`_PFCollectionHistory`, `pineforge_codegen/collection_history.py`) keeps the copies of one declaration: each execution of the declaration (each bar, for a top-level `var`) opens a slot and the bar's end closes it with a copy. Sibling blocks declaring the same name share its member, so each declaration gets a history of its own (`_pf_collection_hist_1_`, ..., which no Pine name spells) and first closes the others' with the array their block left (`ahist_sibling`: one shared history read the other block's array, 336 of 336 exits wrong). `CollectionHistoryChecker.decide` gives every read one outcome. Supported, for a variable of the top level or one of its blocks: a built-in reads it (`(a[1]).size()`, `array.get(a[1], 0)`, `(m[1]).get(0, 0)`, `matrix.det(m[1])`; a matrix function's new matrix has the variable's type, `matrix.copy(mi[1])` of a `matrix` too); a built-in that changes it stops the run with TradingView's RE10051 text (`(a[1]).push(x)`; a zero offset is the variable itself, which changes); `na()` asks whether a copy exists; a `for...in` loop over it iterates the variable's current array, as TradingView's does (`ahist_loop`: `for v in b[1]` sums the current array); a variable bound to it holds a nullable reference to a copy (`_PFArrayHistoryValue` for arrays, the native na matrix for matrices), including a binding read only through `na()` or both through `na()` and array methods -- unless the value reaches a user function's or method's parameter, directly (`f(a[1])`, `(a[1]).m()`) or through a bound name (`pb = a[1]`, `f(pb)`, `pb.m()`): that stays the copy it was before the nullable value (`.value(k)`, an empty array before the variable has a history, where TradingView's is na: the callee's parameter is a `std::vector&` that holds no na array), and a callee that also reads it through `na()` keeps the earlier refusal (`NameUses.crosses_parameter`; `tests/test_arrseg_review_fixes.py`). An unavailable literal or dynamic offset yields an na ID, distinct from an empty collection. Aliases and array-valued ternary selections preserve that ID; an array method materializing it stops with the existing na-array error. Array-ID unwrapping retains temporary values for range loops. A method on a na history stops the run (RE10052, RE10053). Refused by name, what TradingView refuses: a method straight after the history (`a[1].size()`: CE10011), an object's array, matrix or map field's history (`h.xs[1]`, `(h.xs)[1]`: CE10290, in the analyzer), an array where a number, a condition, a string or an element is expected (CE10123: an operator, `nz`, `math.*`, a value slot of an array function such as `c.push(a[1])` or `array.new(2, a[1])`, `log.info`'s message, `label.new`'s text, `str.tostring` of colors; CE10173: a scalar variable or field; CE10101: an if or while condition; CE10122: `array.from`, `str.format` of colors; CE10009: a bare statement of the top level). Every other read keeps the lowering it had where that compiled -- an element of the current array (`na()` and `str.tostring()` in a function, a request payload, a loop, a block's `var`; a selection's history), a parameter's current array (a namespace call, a for...in loop, a typed copy), each with a warning, and anything in a function no call names, which the codegen does not emit (it emits every method and every function a call names, an uncalled function's call included: a read there is decided as any, and one an uncalled function hands to such a function's untyped parameter by how that body uses it) -- and is refused where it did not, as probes of every use and every array function in every scope and for every element type against the previous build showed (`_ELEMENT_LOWERING_FAILS` and its siblings): a collection use of a number element (a method, any `array.*` read but `array.copy` into a namespace call or a loop's local, a typed parameter or binding, a loop over a number) and the string ones `std::string` lacks, `na()` or `str.tostring()` of a parameter's array and its array-returning reads, a change through a variable or a slice bound to the history (TradingView stops there, RE10051; PineForge would change a copy), a matrix's history outside the scopes kept, a call's result's history. Whether an earlier lowering compiled often turns on the consumer of an array function's value, which the tags carry (`_array_result_consumer`: a method on the new array, a function returning it, rendering it, a member holding it; `_value_consumer`: a string value returned or bound), and an overloaded method given the history keeps the earlier lowering. `xs[k] := v`, which TradingView refuses (CE10009, CE10013), keeps its element assignment with checked bounds. Other legacy current-element reads keep their warning and return element na outside the array instead of indexing unchecked. `tests/test_collection_history_missing.py` compiles and runs missing-history witnesses for arrays, matrices, UDTs and drawings, na methods, aliases, dynamic offsets and legacy paths. An object's array or matrix field read through the object's history (`(h[1]).xs.size()`) is the field as it is now (`ahist_field`), as it compiled before. Map history stays refused. Two gaps keep the C++ the previous build emitted, which does not compile: an element function's value of a string array's history the earlier lowering reads (`f() => str.length(array.first(s[1]))`: a character of the current array's string, held as a number, which most string consumers do not take; the probes measured a value bound or returned), and the history of a variable or a call the analyzer does not type as an array or a matrix (a method's or `matrix.row`'s new array, a selection of arrays, a tuple's element, an array of drawings), which the checker never sees. `tests/test_array_history.py` compiles every shape and pins the refusals and the earlier lowerings; `tests/test_e2e_array_history.py` replays six tapes and the runtime stops. | @@ -1011,8 +1017,9 @@ or not, keep their variants (`_bounded_family_polymorphism`; - **Errors.** Use `errors.CompileError` for fatal issues raised from the transpiler. Carry `SourceLocation` so users can map back to the Pine line/col. Diagnostics inside the support checker use -`Level.WARNING` for divergences-but-not-broken, `Level.ERROR` -otherwise. +`Level.WARNING` for divergences-but-not-broken, `Level.NOTE` (`_note`) +only for the eleven informational codes named under `support_checker` +above, `Level.ERROR` otherwise. - **UDT array fields.** TradingView holds the array a UDT field is built from, and keeps a `var` array's value per bar: a push through `h.xs` reaches `a`, while an object kept from an earlier bar reads the array as diff --git a/CHANGELOG.md b/CHANGELOG.md index a6bee3d..fba3cbc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,77 @@ supported as exact pairs; on the 0.x line they are independent. See the the release commit. A prerelease note describes changes since the preceding prerelease or stable tag; the final stable note consolidates the series. +## 1.5.0 — Unreleased + +The planned number of the next release; it stays **Unreleased** until its tag +exists, and the package version is unchanged. This entry records the diagnostic +additions below and nothing else: the engine pairing, the rest of the content +and the date of 1.5.0 are set when the release is prepared. It changes +diagnostics only; no analyzer or code-generation file differs. + +### Compatibility and migration + +- **`note` is a third diagnostic severity, and it is nonfatal.** A diagnostic + is now an `error`, a `warning` or a `note`: `Level.NOTE` in Python and `"note"` + as the `severity` of a catalog entry and of a JSON diagnostic. A note is + nonfatal like a warning. `transpile_full()["diagnostics"]` and the success + envelope's `diagnostics` list warnings and notes, a script with only notes + still returns `ok: true` and its C++, and a `CompileError` can carry notes + beside its errors. `transpile()` still returns no nonfatal diagnostics. + `CompileError.format()` prints `note[...]` where it printed `warning[...]` for + the codes below. Code written for two severities must handle `note`: read an + unknown severity as a warning, never as an error. A note does not mean that + results are unaffected; PF-W1505 describes a warmup approximation. +- **Exactly eleven codes change from warning to note:** PF-W1505, PF-W1508, + PF-W1509, PF-W1525, PF-W1526, PF-W1527, PF-W1528, PF-W1529, PF-W1530, + PF-W1531 and PF-W1532. They describe calls PineForge skips as visual only + (`plot(...)`, `table.new(...)`), earnings, dividends, splits, financial, + footprint and other-symbol requests whose value reaches only display and alert + sinks and is lowered to `na`, and the `ta.ema` warmup approximation. Every + other code keeps its severity. PF-W1502 (`color(...)` cast), PF-W1506 + (`color.from_gradient`), PF-W1507 (drawing setters that drop color, style or + size), PF-W1078 (visual or style constants) and PF-W1552 (a + `request.security_lower_tf` whose value reaches only display and alert sinks) + also speak of visual-only or display-only handling and remain warnings: a + message's wording does not classify it. A consumer that tallied these eleven + codes as warnings, to gate a run, count warnings or color a banner, now + receives notes. PF-W1509 still classifies as PF-W1508 where the two templates + tie, so no new emitted code appears. +- **`user_message` is a raw ICU template over `args`.** Every catalog entry, + every `Diagnostic` (`Diagnostic.user_message`) and every JSON diagnostic gains + `user_message`: a short English ICU template that uses only that diagnostic's + existing `args` names and may be constant (`{name}() does nothing in a backtest.` + with `args.name = "plot"`). It is not pre-rendered English. Render it with + `args` as plain text, never as template syntax or markup, or translate by + `code`; do not display the unrendered template. It does not replace `message` + and `hint`. The templates of the eleven migrated codes are fixed string for + string by a delta fixture. Every template is checked for form (short, + parseable, over that code's own `args` names). Each of the 97 warning twins + of an error (`PF-W1nnn` for `PF-E1nnn`) has a sentence of its own that says + PineForge warns, and the 91 that warn only inside a `switch` arm also say it + keeps the arm's lowering. No warning or note template says that PineForge + refuses or rejects something, though one may say what TradingView refuses or + rejects. Beyond these checks a template's exact wording is not pinned. +- **Legacy fields are stable.** `code`, `args`, `message`, `hint`, `line`, + `col`, `endCol`, `ok`, `error` and the envelope keys keep their meaning and + values: no key is renamed or removed, and no code is renumbered or reused (the + notes keep their `PF-W` codes, and the prefix is not the severity). + `render_diagnostic()` still returns the unchanged English `message` and + `hint`. The catalog schema id stays `pineforge-diagnostics-catalog/v1`, so a + reader that checks `severity` against two values or rejects unknown entry + fields must accept `note` and `user_message`. The receiver examples in + `tests/fixtures/diagnostic_notes/receiver.json` specify the compatibility + rule; they are not evidence of any application's behavior. +- **The warmup sidecar is later work.** No compile-time or runtime sidecar + exists in this entry. PF-W1505 stays the static `ta.ema` note it was, with + only its severity changed: the support checker emits it at each `ta.ema` call + it visits, with no per-call condition or suppression and no call-site + identifier. The startup inventory and extraction that would bind a versioned + sidecar to a diagnostic by `call_site_id` and source range, so that a consumer + can show a startup sentence only for a known finite shortfall, are not part of + this entry, and no diagnostic carries a call-site identifier or a startup + length. + ## 1.4.0 — 2026-10-08 A minor release of the exact engine/codegen pair. Its behavior was validated diff --git a/CLAUDE.md b/CLAUDE.md index 0ca3bb3..a69e97b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -344,10 +344,16 @@ Keyword arguments of the matrix methods and of the checked array methods (`get`, `pineforge_codegen.support_checker` is the gate. Its job is to fail loudly **before** codegen so users never get a silently miscompiled strategy. An error raises `CompileError` (carrying every diagnostic); the -warnings of a script that transpiles (support checker, then analyzer and +warnings and notes of a script that transpiles (support checker, then analyzer and codegen `ctx.diagnostics` -- the codegen appends through `_codegen_warning`) come back as `transpile_full(...)["diagnostics"]` and in `transpile_json`'s success envelope under `diagnostics`, in the error envelope's entry format. +A note (`Level.NOTE`, since 1.5.0, raised through `SupportChecker._note`) is nonfatal and +informational. Only PF-W1505, PF-W1508, PF-W1509 and PF-W1525 to PF-W1532 are +notes, each keeping its `PF-W` code; every other diagnostic keeps its level, +the other visual-only and display-only ones included (for example PF-W1078, +PF-W1502, PF-W1506, PF-W1507, PF-W1552). A `PF-E` code is an error; a +`PF-W` code can be a warning or a note, so read its declared severity. Checked settings string defaults and options use only known C++ string literals from the existing builtin lowering, never inert visual integer codes. Only the @@ -412,7 +418,7 @@ taxonomy: | `var` initializers | A `var` initializer runs once, in statement order, on the first bar that reaches its declaration: a primitive `var` at its declaration under a one-shot flag. One read with history (a `Series` member) keeps the first-bar preamble only for a top-level declaration of a constant, a string literal, `na` or a bar field (`_series_var_init_keeps_preamble`, byte for byte); one in a block, whatever its initializer, reads na history until the first bar that reaches it (the preamble pushed bar 0's value: a block's `var float fc = close` held the first bar's close), and any other initializer -- a UDT field (`var int signal = direction.neutral`), a global computed before it (`var float first2 = b`), a call, `ta.*`, an input's override, a `switch` / `if` selection (the preamble's spelling of one did not compile; `tests/test_e2e_cgint5_compositions.py`) -- runs at its declaration too, the preamble pushing its na until then. The preamble used to push the analyzer's spelling ahead of the body: raw Pine that did not compile (`signal.push(direction.neutral)`, the ten ai-distribution probes) or a global before it was assigned (0), and an input's default. `tests/test_e2e_series_var_init.py` replays TradingView's tapes, an override and a block included (`fixtures/silent_tv`). | | `request.security` helpers | A payload inlines the user functions and typed user methods it calls on the requested bar, under a builtin call too (`nz(f())`, `close.g()`, `nz(ta.sma(close, 3))`: the expression visitor that renders the builtin hands every user call, TA site, helper-bound name and requested-bar history back to `_build_security_expr`). Under a builtin, and for a method, only a single-expression body is inlined, every user call in it too, also through a global's value (`_security_body_is_expression`); a multi-statement one keeps the chart call and warns, because the evaluator writes its statements ahead of the payload, where a ternary arm or an `and`/`or` operand would run them on every bar. A TA site reached through several helper bindings gets one variant per binding, numbered (`_v0`, `_v1`, ...) by where each binding's value is written (`_security_variant_order_key`; the signature names nodes by `id()`, whose order is memory's; `tests/test_security_variant_order.py`). A helper called on its own result (`u(u(close))`) gets a variant per written call: the variant walk's recursion guard is keyed by the call, not the helper's name, which skipped the inner call as recursion and left it reading an undeclared base member (`tests/test_e2e_security_nested_helper_call.py`). A helper local's value is re-walked under the helper-name guard still (`_security_local_rewalks`): the evaluator reads the local's C++ variable, and entering the helper again there walked every earlier local once per read, 2**n walks over a chain of n locals. A call of a pure helper (one expression over its parameters, the requested bar's fields and literals, through operators and such calls) on arguments of that kind holds nothing a prepass collects, so the payload's walks stop at it; once its inlined text is 256 characters long its value is computed once where the evaluator opens (`_pf_shared__`, `_security_share_pure_call`) and every reach with the same arguments reads it, where a diamond of such helpers inlined its leaf once per path (`tests/test_security_helper_diamond.py`). A payload's `bar_index` is the requested bar's, the count of requested bars before it (`_sec_bar_index_`, advanced where the evaluator opens a requested slot; `bar_index[k]` k requested bars back, na before the first; `tests/test_e2e_security_bar_index.py`). A global the payload reads at an offset (`g[1]`) whose value is a user function's call or a numeric operator expression keeps its history on the requested clock: the value the payload reads as `g`, pushed once per completed requested bar where the evaluator closes (a helper inlines the read at each read of its parameter), and the payload lowers such a global once per evaluator (`g - g[1]` inlined the call at each read, which advanced its TA state once per read). The push takes the value of a read that ran, as an inline expression's history does: a read in a ternary arm, an if branch or a loop that did not run on a requested bar pushes nothing there, where TradingView's history holds every requested bar (a limit). The once-per-evaluator lowering holds within the block that emitted its locals: a later read outside a helper's if branch or loop lowers the call again, as every earlier build did at each read (it named the locals out of scope, which did not compile), except that a call with state (a TA site, a `var`, a request, a user method) whose global the payload also reads with history on the requested clock is refused where two of its lowerings can run on one requested bar, since its state would advance twice a bar (every earlier build refused that history read; one under a builtin keeps the chart's series and never counts, and the two arms of one if never run together). The builder refused the call's history ("helper call history is only supported in the payload itself") and indexed the operator expression's C++ scalar, which did not compile (`_security_global_history_value`). That history is a double (a bool's a bool), whose na reads na -- typed from the global's `int`, the first requested bar read `na()` as -2147483648 and a 64-bit integer ("Epoch ints": `g = bar_index * 86400000`, or an epoch) wrapped -- and an integer slot of the evaluator (a helper's `int` local, an int tuple element) takes it narrowed na-preserving (quirk 9; an int reaching the chart's double still reads `na()` as a number, as on main). Only a read lowered on the requested clock is so: one under a builtin (`nz(g[1], 0) / 2`) keeps the chart's int series and main's lowering, and a string global's history there is refused, as every earlier build refused it (`tests/test_e2e_cgint7_compositions.py`). A `request.security` of Heikin-Ashi bars inside the payload reads the requested context's Heikin-Ashi bars on TradingView, which the evaluator does not build: evaluating it stops the run (`_security_nested_heikinashi_request`), so a selection that never takes it (`useHA ? request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close) : close` at its default) runs on the requested bars, where rendering the call read the chart's own request. An `int` / `float` cast whose argument reads a helper's parameter or local (a TA length `int(math.round(_len / 2.0))`) is the builder's own where the TA constructors are planned: the expression visitor rendered the name as an unknown variable. `tests/test_security_global_history.py` replays TradingView's tapes (`fixtures/tail_a_tv`). A global under a builtin call (`nz(s)`) is re-evaluated on the requested bar as a bare payload global is, when the expression map holds it and it is neither replayed state nor a per-run value (`_security_fallback_owns_global`); its history there (`nz(s[1])`) keeps the chart's series and warns (`tests/test_e2e_security_global_under_builtin.py`). All or nothing per evaluator (`_emit_security_evaluator_requested`): when a builtin call also reads something else on the chart's terms (a global it does not re-evaluate, history the builder does not own, `timeframe.*`: `_security_root_chart_read`) beside a call the evaluator inlines, or it refuses such a call (a shape a bare payload refuses), the evaluator keeps the lowering every earlier build emitted, its calls on the chart, and warns; a method with a non-scalar receiver or argument keeps the chart call and warns. A global that a top-level tuple declaration binds to a TA tuple call's element reads that field of the requested result; one bound to another tuple (a user function's) is refused there, as is history of a TA tuple's element, both of which used to emit C++ that did not compile. History of a helper call inside a helper body the payload inlines (`h() => nz(g()[1])`) is the requested bar's, where the payload reaches it once; one it reaches twice (`h() + h()`) is refused where it is lowered (`_collect_security_expr_hist_subscripts`; `tests/test_e2e_security_helper_body_history.py`). Under a builtin, TA tuple element history, read directly or through a global's value, is refused where every earlier build pushed the whole result into a double history; where one compiled (a multi-statement helper reaches the tuple, the read is a user call's argument, or the tuple is a user function's) it keeps the chart's series and warns. An inlined helper's local takes `na` of its own type and narrows to int or bool through quirk 9's na-preserving cast. A helper body may hold declarations, tuple declarations (`[m, s, h] = ta.macd(...)`, a nested helper's tuple), assignments, if-branches and bare expression statements; a local holding a `switch` whose arms are single expressions lowers to their ternary chain, which evaluates only the arm its selector takes (`tests/test_e2e_security_helper_switch.py`: it rendered as `/* unknown */`, which did not compile); a `for` or `while` loop (with `break` / `continue`) runs on the requested bar: its counter is a local, `o[i]` reads the requested bar's open `i` requested bars back, and a `for` keeps Pine's direction, step magnitude and `to` refresh; a loop holds plain locals only, since the evaluator computes a TA call, pushes a history-read local and keeps a `var` once per requested bar (a TA call, a `var`, a local read with history, a `request.*` / `strategy.*` call or a user call in a loop is refused by name: "request.security helper loops cannot hold ..."; `tests/test_e2e_security_helper_loops.py`, `fixtures/tail_e_tv`), and so is one reaching the loop through a name the lowering expands where it is read: a helper parameter's argument (`h(ta.sma(close, 3), n)` computed the SMA once per iteration, and so did a TA variable, `h(ta.accdist, n)`), or a user call or a `request.*` / `strategy.*` call in a global's declaration (`cs = sm(close)`), whose own TA sites are computed once, before the payload, and read freely; a name a loop statement declares is the loop's own in its block after its declaration (its initializer and a read after its block read the enclosing name); a `for` loop's counter is a counted loop's binder for the 64-bit rule, as on the chart ("Epoch ints"; `fixtures/cgint7_tv/cgint7_loop_products`), while a product with another helper-bound operand, and a `while` loop's counter, keep the payload's 32-bit spelling (a limit); a `for ... in` loop, a `switch` statement and a block arm stay refused. Helper `var` state (int, float, bool, string: strings in `_security_helper_series_str_`) belongs to its call site and advances once per requested bar; its family is read in the epoch-only mode (`_security_helper_var_state_type`): a width only the 64-bit arithmetic rule ("Epoch ints") gives it, its own or a same-spelled name's in another callable (`g() => n = days * 86400000` beside a helper's `var int n`), keeps the int family, whose double series holds the value exactly (the arithmetic width refused such a script, which compiled before; `tests/test_e2e_cgint6_compositions.py`), while an epoch, or an int-literal product past int32 in its own initializer, reaching it stays refused, as it always was. A helper tuple mixes int, float, bool and string elements, each stored in its own family: before the first requested value and on a `gaps_on` bar completing none, a bool element reads `false`, a numeric one `na` and a string one empty; a string payload returns a `std::string`. A TA history index is a literal or a bar-invariant int over inputs; an input it or a helper's TA constructor argument reads is its getter, a never-reassigned `var` input's too (`_security_var_input_call`; `tests/test_e2e_security_var_input_length.py`), since `evaluate_security` can run before `on_bar` reads the inputs; a payload divides two ints as floats. A TA length chosen by comparing an `input.string` with its options (`mode == "A" ? 5 : 10`) is input-derived, on the chart and in a payload (string literals are spelled in `_arith_expr_to_str` and blanked out of the reset path's identifier scans). The evaluator's prologue orders its TA variants so each follows the variants its arguments read, all at the evaluator's top level (a later global's TA read by a helper's TA was computed inline and again, twice a bar; `_security_prologue_order` follows what each variant's arguments can reach, and learns the reads by building each variant's arguments once, every side effect undone, only where that graph has a cycle; `tests/test_security_price_history_and_later_globals.py`, `fixtures/xsym_a2_tv`, lane CG-XSYM-A2). `tests/test_e2e_security_*.py` replay eight TradingView tapes (`fixtures/security2_tv`). A helper local a requested TA length reads is a value of each requested bar when it is a `var`, rebinds from its own value (`c += 1`, `c := c + 1`, or through another local: `b = a` then `a := b + 1`) or is reassigned in an if arm (a local the arm declares shadows it there): `ta.highest` / `ta.lowest` / `ta.highestbars` / `ta.lowestbars` re-window every call with it, and any other `ta.*` is refused naming the local (TradingView refuses such a length for `ta.ema`; PineForge does not lower its `ta.sma`). The planner bound each to one expression: `c += 1` to the literal 1 (a constant length, lane CGINT4), `c := c + 1` to an expression reading itself (Python recursed until its stack ran out); `tests/test_e2e_security_helper_var_length.py` replays TradingView's tape (`fixtures/silent_tv`). | | `request.security` contexts | A request's symbol and timeframe are registered before the first bar. When they reach it through helper parameters, `security_contexts.specialize_security_contexts` (between the support check and the analyzer) resolves them on every call path from the top level, each parameter read in its caller's scope, down to globals, inputs, literals and built-ins: one context on every path is annotated on the request, several copy each helper on the paths once per context (`h__pfctx1`, ...; a copy's locals and loop variables are renamed too, `v__pfctx1`, since the analyzer keeps one history buffer per callable local name), and a parameter carrying one is declared `string`. It used to register the chart's timeframe (`input_tf_`), silently. A request whose timeframe or symbol is a bare parameter bound at every call site to a global expression keeps the analyzer's call-site clones (`callsite_idx`), which register a literal as a literal and anything else, an input too, as that expression (an input used to register its default, so an override was ignored), and a symbol clone its call site's Heikin-Ashi flag; a helper whose calls all pass one context is emitted once and its calls name it (they named a `f_cs0` nothing emitted: `f(string sym) => request.security(sym, "60", close[1])` did not compile; `tests/test_security_single_context_helpers.py`). A context no registration can compute (a series, a reassigned local, a user call, a method or overloaded helper on the path, too many paths) is refused by name; only a dead helper still registers the chart timeframe. A parameter of the helper that the request's payload reads is part of the context too, resolved the same way with bar series and user calls allowed: the request is copied per value and each copy's payload reads the value in the parameter's place. The evaluator never bound one: `nr(_s, _tf, _e) => request.security(_s, _tf, _e[1], ...)` read a member nothing pushed (`na`), a bare `_e` was an unknown variable, and `f(3)` and `f(6)` shared one `ta.sma(close, len)` built from the first call's length. Only a value the builder lowers on the requested bars in the read's place is put in (`_Lowered`): chart series, `ta.*` and `math.*` calls, inputs (an untitled one titled with its declaration's key), `input.source` values and stable globals built from them, a global declared after the helper too when it is a number or a bool (the copy's read carries its binding, `GLOBAL_ANNOTATION`, where the analyzer binds none: it read the chart's value; the analyzer types the name a float, so a later string keeps its refusal); a history object is a bar or price series (`hl2` to `hlcc4` too), a `ta.*` call (inline or a global's value), an `input.source` value, an inline operator expression, or a global holding a numeric operator expression or a call of a user function the builder inlines whole (one definition whose body declares plain locals and ends in an expression over its parameters, bar series and literals, through operators, single-valued `ta.*`, `math.*`, `int` / `float` / `nz` and such calls: `_inlined_function`), such a call's global also as a value; no global under a builtin rendered on the chart's terms. Any other value keeps its lowering, never a refusal, and a history read of such a parameter warns that it reads `na` (not in a helper nothing reaches). A length every top-level call passes one value keeps the analyzer's single evaluator; its call-site clones for differing timeframes built every clone from the first call's length. A Heikin-Ashi symbol alias declared after the helper keeps its flag. `tests/test_security_contexts.py`; `tests/test_e2e_security_nested_contexts.py` replays TradingView's nested-helper tape (`fixtures/xsym_tv`), `tests/test_security_payload_params.py` two payload-parameter tapes. | -| Requests with no data | `request.financial` / `earnings` / `dividends` / `splits` / `footprint` (`NO_DATA_REQUEST_FUNC`) and `request.security` on another symbol, whose value reaches display and alert sinks only or that read no recorded series or feed (the next rows), read data the engine does not load. `external_requests.TradeSlice` follows the value forward: one that reaches alerts, plots, tables and logs only -- through operators, na-safe built-ins, user functions and bindings, `var` too -- is lowered to na by `lower_no_data_requests` (between the support check and `security_contexts`; a helper's bool tuple becomes `[false, false]`) with the WARNING "value reaches only display/alert sinks; lowered to na; trades are unaffected". Every other one -- it can reach an order, `runtime.error`, a collection, a drawing, a method, a history offset or a `break`, or its arguments do anything but compute -- is a deferred refusal: it warns "no data is pinned for this request; the run stops with an error where its value is read" (the use named in the hint) and lowers to a value whose first READ stops the run with that request named. Binding it is no read: the reads of a declaration holding the whole request (its names never reassigned) stop the run, else evaluating the request does. TradingView never evaluates a `switch` arm its selector does not take (a default arm beside one stopping the script books its trades), and a script reading a request only in such an arm runs. TradingView's tapes of a strategy with an alerts-and-table watchlist and of the same strategy without it are byte for byte one tape on BINANCE:ETHUSDT.P 15 and NASDAQ:AAPL 15 (`tests/test_external_requests.py`, `fixtures/xsym_tv`). | +| Requests with no data | `request.financial` / `earnings` / `dividends` / `splits` / `footprint` (`NO_DATA_REQUEST_FUNC`) and `request.security` on another symbol, whose value reaches display and alert sinks only or that read no recorded series or feed (the next rows), read data the engine does not load. `external_requests.TradeSlice` follows the value forward: one that reaches alerts, plots, tables and logs only -- through operators, na-safe built-ins, user functions and bindings, `var` too -- is lowered to na by `lower_no_data_requests` (between the support check and `security_contexts`; a helper's bool tuple becomes `[false, false]`) with the NOTE "value reaches only display/alert sinks; lowered to na; trades are unaffected" (`Level.NOTE`, PF-W1525 to PF-W1532, raised by the support checker's `_lower_no_data_request`). Every other one -- it can reach an order, `runtime.error`, a collection, a drawing, a method, a history offset or a `break`, or its arguments do anything but compute -- is a deferred refusal: it warns "no data is pinned for this request; the run stops with an error where its value is read" (the use named in the hint) and lowers to a value whose first READ stops the run with that request named. Binding it is no read: the reads of a declaration holding the whole request (its names never reassigned) stop the run, else evaluating the request does. TradingView never evaluates a `switch` arm its selector does not take (a default arm beside one stopping the script books its trades), and a script reading a request only in such an arm runs. TradingView's tapes of a strategy with an alerts-and-table watchlist and of the same strategy without it are byte for byte one tape on BINANCE:ETHUSDT.P 15 and NASDAQ:AAPL 15 (`tests/test_external_requests.py`, `fixtures/xsym_tv`). | | Requests of other symbols | A `request.security` of another symbol whose value can reach a trade reads the feed a probe's requests manifest pins for it (`PINEFORGE_REQUESTS_ROOT`; the engine's instrument feeds, `FEED_LOWERING`), with the WARNING "another symbol's bars, read from the feed the requests manifest pins for it; with none installed, the run stops with an error where its value is read". `configure_security_evaluators()` registers it by its symbol string as the run computes it before the first bar -- a literal, an input's getter, the chart's `syminfo.*` strings and operators and ternaries over them (`ScriptIndex.registration_value`), or a helper's parameter resolved on every call path (`security_contexts` owns such a request whatever its timeframe, so three symbols at two timeframes through three helper levels are six contexts) -- and its `ignore_invalid_symbol` (na for a symbol whose facts say it is invalid; without it the run stops): on the chart when the string is the chart's (the one the manifest resolves it to, else the chart's ticker id or `syminfo.ticker`), on the installed feed of (symbol, timeframe) otherwise, and not at all without one, when its reads stop the run as a deferred refusal does (`_pf_sec_missing_N`), never reading the chart. Its payload runs on that symbol's own bars: history, `ta.*` state, `bar_index`, `time_close` (the host's, the feed's close) and `syminfo.*` are the requested context's, and `ta.ema` there is SMA-seeded (na until `length` values) as TradingView's is; an int tuple element is held as an na-preserving double (a millisecond stamp overflows an int); under gaps_on a chart bar the feed hands nothing reads na and the context's history carries on. A symbol that can select the chart's or another symbol's (`useOther ? "TVC:DXY" : syminfo.tickerid`) registers the same way when its value can reach a trade: it read the chart's bars for both arms; through a helper's parameter that registration cannot compute on some path, it keeps that chart lowering and its warning. A symbol registration cannot compute (a series, a reassigned name, a method's parameter, a block's local, a path the pass cannot follow), a timeframe it reads before the first bar with no value yet (a `var`, a reassigned name, a series: `ScriptIndex.registers_timeframe`; it registered the chart's), and a request inside another request's expression, written there or in a helper the expression calls, keep the deferred refusal, with a warning naming the path. `ticker.inherit(from_tickerid, symbol)` names its symbol second (`ticker_symbol_arg`; it was read as the chart's). A `request.security_lower_tf` of another symbol whose value can reach a trade stops the run where it is evaluated (`ABSENT_LOWERING`: it read the chart's intrabars); one that can select the chart's keeps its lowering and warns. A tuple request whose names are reassigned stops where it is evaluated (the tuple emitter never visited it, and a missing feed read na). A payload that is `request.footprint(ticks, va)` (literal whole numbers) reads the feed's `fp_delta__` column on the requested bar (`FOOTPRINT_COLUMN_ANNOTATION`), a feed without the column being missing data, the chart's own symbol too (the chart's bars carry no footprint: it read the chart, and na); a footprint value is its delta -- a declaration or helper parameter typed `footprint`, one holding the request or a helper's call returning it, a parameter a call passes one to -- so `fp.delta()` and `footprint.delta(fp)` read it (`read_footprint_deltas`: they did not compile) and every other `footprint.*` member is refused by name. TradingView's footprint delta of a range depends on the range (the month slices of a year disagree), so a footprint feed holds for the window it was captured over, where a synthetic BITSTAMP:BTCUSD delta filter on BINANCE:BTCUSDT 15 books its 1674 trades exactly. `currency=`, `ticker.new` and `ticker.modify` stay refused. A `barmerge` constant is a value (on 1, off 0), held and compared (`var gapStrategy = gaps ? barmerge.gaps_on : barmerge.gaps_off`, `TradingView/Request/3`); a request's gaps and lookahead read the constant as written: a computed one keeps a chart request's refusal, and makes a request of another symbol read no data (its first read stops the run) with its registration naming why (`fixtures/tail_f_tv/barmerge_values`). TradingView tapes of synthetic strategies (a TVC:DXY EMA cross on NYSE:F 15, BINANCE:BTCUSDT 1D and BINANCE:ETHUSDT.P 15, TVC:VIX 240 `ta.ema(close, 14)[1]` lookahead_on on NASDAQ:AAPL 1D and OANDA:XAUUSD 15, gaps_on on NYSE:F 15 and ETHUSDT.P 15) match trade for trade on the XSYM-B captures, and the XSYM-DESIGN alignment witnesses bar for bar; they stay outside this repository with the captures. `tests/test_foreign_requests.py` replays the rules on generated bars. | | Recorded requests | A `request.earnings` / `dividends` / `splits` / `financial` whose value can reach a trade reads the series TradingView returned per chart bar, which the requests manifest records (`chart_open_ms,value`, every bar TradingView answered non-na) under `||||gaps_|lookahead_` (`RECORDED_LOWERING`, the workflow's `formatRecordedKey`): TradingView's report-time and fiscal-period logic is recorded, not modelled. The key's symbol is the string the run passes (`syminfo.tickerid` is the lane symbol, the key the capture records), its other parts constants of the call: the `earnings.*` / `dividends.*` / `splits.*` field (default `actual` / `gross` / `denominator`), a literal financial id and period (`FQ`, `FY`, `FH`, `TTM`), `barmerge.*` gaps and lookahead (default off; `request.financial` has none). `_pf_recorded(key, _pf_rec_missing_N)` reads the value of the chart bar that opens at the tape's time, na elsewhere, and sets the request's flag from the key computed where the request is evaluated, which its reads test (a key re-rendered at a read, in a helper, read the helper's names), with the WARNING "TradingView's values per chart bar, read from the series the requests manifest records under ...". A key nobody installed reads na where the request is bound and stops the run where it is read, as a deferred refusal does; where TradingView answers na throughout (fundamentals of a crypto chart, an arm a probe never takes) the capture records a header-only tape, which reads na and runs. A spelling no key names -- a field or id that is not a constant of the grammar, a `currency`, a request inside `request.security`, written there or in a helper its expression calls -- keeps the deferred refusal. A PEAD-like synthetic strategy books TradingView's trades exactly on NASDAQ:AAPL 1D (4/4) and NYSE:F 15 (5/5) from the XSYM-B tapes, kept outside this repository; `tests/test_recorded_requests.py` checks keys and replay on generated tapes. | | Switch arms | The support checker visits every arm of a `switch` -- its condition and its block -- as it visits an `if`'s: the generic child walk skipped `cases`' `(condition, block)` tuples, so every arm but the default went unchecked, and a request of another symbol in one kept no lowering (the request contexts then refused it as a chart request they could not key: `TradingView/Request/3`'s `cryptoDerivativeMetric`). Such an arm gets its lowerings; what the checker would refuse there (an unsupported call, a text constant held as a value) warns instead, and keeps the lowering it compiled to, so a script that compiled keeps compiling (`SupportChecker._switch_arm_depth`). The C++ of the 1,384 population sources was unchanged by it (2026-09-29 census). | @@ -431,7 +437,7 @@ taxonomy: | `ta.*` call arguments | `_check_ta_arguments` binds every `ta.*` call to TradingView's signature (`signatures.TA_FUNCTIONS`: TradingView's parameter names, e.g. `series` for `ta.alma` / `bb` / `bbw` / `cmo` / `kc` / `kcw`, and required/optional split) and refuses what TradingView rejects: an unknown keyword, an argument too many, one given twice or a missing required one -- each used to be dropped, shifted into the next constructor slot or passed to a `compute()` that does not exist. `ta.vwap()` with no argument reads as the bare property, as it always has. | | `ta.*` TA1 arguments | The TA1 engine computes `ta.alma` `floor`, `ta.kc` / `ta.kcw` `useTrueRange`, explicit `ta.vwap` anchors, and `ta.pivot_point_levels` `anchor` / `developing` exactly. The generated TU selects those APIs with `PF_ALMA_HAS_FLOOR`, `PF_KC_HAS_USE_TRUE_RANGE`, `PF_VWAP_HAS_ANCHOR_INPUT`, and `PF_PIVOT_LEVELS_HAS_ANCHOR`; when a macro is absent, the shim falls back to the historical lowering. Only omitted-anchor VWAP keeps `ta::VWAP` / `ta::VWAPBands`; every explicit anchor, including `timeframe.change("1D"|"D")`, uses `ta::AnchoredVWAP` / `ta::AnchoredVWAPBands`. The pivot free function remains only for literal/aliased `anchor=true, developing=false`; every other spelling uses `ta::PivotPointLevels`. | | `ta.*` lengths the constructor cannot take | A length (or `ta.supertrend` factor) that is neither a compile-time constant nor an input/timeframe expression the runtime reset re-reads is lowered by its Pine qualifier, as TradingView answers it (lane K-TA-DYNLEN tapes; rules in the engine's `pineforge/source/pine_ta_length.hpp`). A simple length -- fixed for the run: a syminfo preset, `str.*`/`math.*` over those, expanded context-free so a `request.security` payload evaluates it too; a name counts only where it reads the top-level declaration, so one a block, loop or callable binds, or a value declared `series`, is series -- builds the constant-length class on the call's first execution (`pineforge::source::FirstCallBound`, the length checked by `simple_ta_length`: TradingView answers a simple length exactly as the constant, a sparse window through the constant ring). A series length of `ta.highest` / `ta.lowest` / `ta.highestbars` / `ta.lowestbars` re-windows every call (`pineforge::source::Series*`). `ta.supertrend` passes factor and atrPeriod on the call and reads them once (`pineforge::source::PineSupertrend`: TradingView compiles a series factor but uses the first execution's). A series length of any other family keeps the refusal: TradingView refuses it for `ta.rma`/`ema`/`rsi`/`atr`/`dmi`/`macd`/`kc`/`hma`/`tsi`/`rci`, and the other window functions (`ta.sma`, `ta.wma`, ...) are not lowered yet. Each `request.security` copy is planned from the length its own call passes (a helper call's binding, a per-call-site clone) and reads `timeframe.*` in the requested timeframe; a callable's one evaluator refuses call sites that pass different lengths, where a length the `request.security` contexts row copies the request for (a literal, an input, an `input.string` choice) gives each call path its own evaluator instead. Constant- and input-length calls keep their constructor byte for byte; an `input.string` choice of an int length the signature table knows is one (the `request.security` helpers row). Every other argument its spelled string literals would bring to the constructor -- a `syminfo.*` or `timeframe.*` comparison, or an `input.string` choice of a float parameter or of one the table does not know (a VWAP band multiplier, `math.sum`'s length) -- stays here, spelled from its declarations (`_ta_arg_takes_plan`): the reset path reads a payload's `timeframe.*` on the chart's timeframe and casts its expression to an int length. One this lowering cannot spell stays refused, and a callable's one evaluator still refuses call sites that pass different such lengths. `tests/test_e2e_ta_dynamic_length.py` replays five TradingView tapes, `tests/test_codegen_ta_dynamic_length.py` pins the C++. | -| Chart EMA warmup | The generated `_PFKC` / `_PFKCW` shims scope the engine's EMA warmup selector around their internal EMA basis. KC/KCW middle is `na` until the Pine length is warm, including bar 0, without changing unrelated chart EMA call sites. A covered TradingView tape records both KC middle and an independent EMA as `na` on bar 0 and first finite at bar 19 (length 20). The standalone engine EMA remains finite on bar 0, so `ta.ema` warns about that warmup approximation; `tests/test_kc_middle_band.py` pins the limited scope and warning. | +| Chart EMA warmup | The generated `_PFKC` / `_PFKCW` shims scope the engine's EMA warmup selector around their internal EMA basis. KC/KCW middle is `na` until the Pine length is warm, including bar 0, without changing unrelated chart EMA call sites. A covered TradingView tape records both KC middle and an independent EMA as `na` on bar 0 and first finite at bar 19 (length 20). The standalone engine EMA remains finite on bar 0, so `ta.ema` notes that warmup approximation (PF-W1505, a `Level.NOTE` raised at every `ta.ema` call: no runtime warmup sidecar exists and nothing suppresses it conditionally); `tests/test_kc_middle_band.py` pins the limited scope and the note. | | Color na conversions | Packed colors use `int64_t` storage, including typed scalar, array and matrix paths, so their `na()` sentinel survives. `array.from` of colors is a `std::vector`: a color literal, a `color.*` constant, a `color.new` / `rgb` / `from_gradient` call, a conditional selecting one or a script variable bound to one types the element on both sides (`_is_color_value`, the analyzer's `_is_color_constructor`); it was read as a float, and `var array A = array.from(...)` did not compile (`tests/test_e2e_color_arrays.py`, tape `fixtures/silent2_tv/cgs2_color_arrays`). `color.new` preserves an `na` base; `na` transparency becomes 100; an `na` `color.rgb` channel becomes zero. The covered TradingView color probes are pinned by `tests/test_na_truthiness.py`. A finite transparency reaches the engine's `new_color` as a double, whose alpha byte is the nearest to 255 * (100 - t) / 100, as TradingView's for an input or a series transparency and `color.rgb`'s: `color.new(c, t)` at t = 10.5 reads back 11 (a truncating cast read 10; an integer literal keeps its `(int)` spelling). TradingView truncates a constant `color.new` transparency (`color.new(color.red, 10.5)` and `10.6` read 10, `99.5` reads 99), which PineForge still reads through the byte (pinned: `tests/test_e2e_cgint6_compositions.py`, tape `fixtures/cgint6_tv/cgint6_const_transp`). `tests/test_e2e_color_tapes.py` replays the engine's `w11-color-v6-eth15` tape (`fixtures/color_tv`). `color.new(color, transp)`, `color.rgb(red, green, blue, transp)` and `color.r` / `g` / `b` / `t(color)` bind a keyword argument to its parameter's slot, in parameter order (`_color_arg_nodes`; a keyword transparency is converted as a positional one): a keyword was dropped, so `color.new(c, transp = 40)` lowered to the color 0 (`tests/test_e2e_color_keyword_arguments.py`, tape `fixtures/silent2_tv/cgs2_color_keywords`). | | Epoch ints | A Pine `int` slot an epoch reaches is `int64_t`: a name whose declaration or any reassignment gives it a wide value (an epoch builtin, a wide name or parameter, or an expression `_expr_returns_wide_int` traces to one), and a declared-`int` or untyped parameter a written call feeds one (`types._wide_int_provenance`, a fixed point keyed by spelling). The width used to stop at the first copy: `int sel = switch k => E2` over `const int E2 = timestamp(...)`, `alias = firstT` over `firstT := time`, and `f(int t)` called with `time` held 32 bits (1743468300000 read -288422176), and `int(x)` of an epoch casts to `int64_t` (`int(time)` was a 32-bit cast). A function's or method's local declared `float` keeps a float series when an epoch reaches it (`float x = time`: `_callable_series_local_symbol` reads the function's scope, `method__` for a method, which the global lookup missed): its `Series` read the integer sentinel for a missing `x[1]`, so `x - x[1]` was a garbage number on the first bar instead of na (`tests/test_e2e_float_time_local.py`, tapes `fixtures/silent2_tv/cgs2_float_time_local` and `cgs2_float_time_method`). `tests/test_e2e_krunerr_int64_provenance.py` replays TradingView's tape (`fixtures/krunerr_tv`). A method call's arguments do not widen its parameters. Integer arithmetic over literals and the constants emitted as literals keeps 64 bits too: `400 * MS` over `const int MS = 7200000` is 2880000000 (it was the C++ `int` product, -1414967296), folded where the tree is literal after the names are inlined (`_pure_int_literal_value`, `_inlined_int_constant`) and where the emitted C++ is (`_fold_int32_overflow_cpp`: a `request.security` payload expands a global into its declaration), and the slot a top-level declaration of an int constant past int32 initializes is `int64_t`, reassigned or not (`g = 3000000000`, `var int e = 300 * MS`: `_literal_wide_global`); a literal's width (`g = 3000000000`) reaches a declaration reading it while it is never reassigned (`h = g`) but does not travel by spelling into a reassignment (`k := g`), parameters, arrays, `request.security` helper state or a callable's local of the same name, which keep the types they compiled with, while constant arithmetic (`300 * MS`) is a 64-bit product too, whose width travels as the next sentences say. `tests/test_e2e_int64_constants.py` replays TradingView's tape (`fixtures/silent_tv`). An integer `+ - *` those folds leave, whose operands are both 32-bit C++ ints, is computed in 64 bits at run time when its magnitude can leave int32 (`_int_arith_leaves_int32`: literals and inlined constants exactly, an `input.int` by its declared range, else its default and 2**24, `bar_index`, a counted loop's binder, a `for ... in` binder whose spec is `int` (an int element, map value or index; a float element is a double: `v * 1000` over one was truncated) and any other runtime integer name 2**24 (a call's result does not widen); a callable's name resolves in its own callable, a declared `int` local included, whichever callable is being emitted; a reassigned top-level constant past int32, whose slot is `int64_t`, is no 32-bit operand, and an input's named bound reads the top-level constant), and its value is an epoch-like wide value for the slots above: `days * 86400000` over `days = input.int(30)` and `bar_index * 7200000` overflowed. An operand that can be na (a parameter, a local, a script variable) makes the value na: a double (`_wide_int_arith_cpp`, exact to 2**53; the widening cast read `na()` as -2147483648) that every integer store narrows na-preserving, a slot, a parameter, an array element, a map or matrix value. In a `request.security` payload a side the builder re-evaluates as a double computes in double and a name a helper binds keeps its spelling; the rest widens as on the chart, and the payload's copy of a script variable only such arithmetic makes wide is `int64_t` too (`_security_copy_is_arithmetic_wide`, stored na-preserving, a compound `%=` through `std::fmod`); an epoch's or an int-literal product's keeps its `int` copy, as it always did. A tuple element and a function's or method's result holding a constant past int32 (`_holds_wide_int_constant`), and a read of a UDT `int` field (`int64_t` storage) some write fills with one (`_wide_udt_int_fields`), are `int64_t` too. A `map<..., int>` value, `matrix` element or element of an int array only such a value reaches (only an epoch widens an array, `_wide_int_array_names`: a declared `array` parameter, result or field does not bind a `std::vector`) keeps its C++ `int` (its type also types the handle's parameters and its `values()` / `row()` arrays), narrows the value na-preserving and warns where it stores one (`tests/test_e2e_int64_products.py`, tapes `fixtures/silent2_tv/cgs2_int64_products`, `cgs2_int64_followup` and `cgs2_int64_followup2`). | | Array and matrix history | `a[k]` of an array or a matrix variable is TradingView's read-only copy of the collection as the variable left it at the end of its scope's execution k executions back: the bar k bars back for the top level, its block's previous run for a block's local (`tests/fixtures/array_history_tv`). A `var` array's history is the copy, one element shorter than the array it grows (`ahist_ref`), and a `var` matrix's holds the previous bar's value (`ahist_mtx`). The variable keeps its own `std::vector` or matrix member, so every other operation keeps its C++; `_pf_collection_hist_` (`_PFCollectionHistory`, `pineforge_codegen/collection_history.py`) keeps the copies of one declaration: each execution of the declaration (each bar, for a top-level `var`) opens a slot and the bar's end closes it with a copy. Sibling blocks declaring the same name share its member, so each declaration gets a history of its own (`_pf_collection_hist_1_`, ..., which no Pine name spells) and first closes the others' with the array their block left (`ahist_sibling`: one shared history read the other block's array, 336 of 336 exits wrong). `CollectionHistoryChecker.decide` gives every read one outcome. Supported, for a variable of the top level or one of its blocks: a built-in reads it (`(a[1]).size()`, `array.get(a[1], 0)`, `(m[1]).get(0, 0)`, `matrix.det(m[1])`; a matrix function's new matrix has the variable's type, `matrix.copy(mi[1])` of a `matrix` too); a built-in that changes it stops the run with TradingView's RE10051 text (`(a[1]).push(x)`; a zero offset is the variable itself, which changes); `na()` asks whether a copy exists; a `for...in` loop over it iterates the variable's current array, as TradingView's does (`ahist_loop`: `for v in b[1]` sums the current array); a variable bound to it holds a nullable reference to a copy (`_PFArrayHistoryValue` for arrays, the native na matrix for matrices), including a binding read only through `na()` or both through `na()` and array methods -- unless the value reaches a user function's or method's parameter, directly (`f(a[1])`, `(a[1]).m()`) or through a bound name (`pb = a[1]`, `f(pb)`, `pb.m()`): that stays the copy it was before the nullable value (`.value(k)`, an empty array before the variable has a history, where TradingView's is na: the callee's parameter is a `std::vector&` that holds no na array), and a callee that also reads it through `na()` keeps the earlier refusal (`NameUses.crosses_parameter`; `tests/test_arrseg_review_fixes.py`). An unavailable literal or dynamic offset yields an na ID, distinct from an empty collection. Aliases and array-valued ternary selections preserve that ID; an array method materializing it stops with the existing na-array error. Array-ID unwrapping retains temporary values for range loops. A method on a na history stops the run (RE10052, RE10053). Refused by name, what TradingView refuses: a method straight after the history (`a[1].size()`: CE10011), an object's array, matrix or map field's history (`h.xs[1]`, `(h.xs)[1]`: CE10290, in the analyzer), an array where a number, a condition, a string or an element is expected (CE10123: an operator, `nz`, `math.*`, a value slot of an array function such as `c.push(a[1])` or `array.new(2, a[1])`, `log.info`'s message, `label.new`'s text, `str.tostring` of colors; CE10173: a scalar variable or field; CE10101: an if or while condition; CE10122: `array.from`, `str.format` of colors; CE10009: a bare statement of the top level). Every other read keeps the lowering it had where that compiled -- an element of the current array (`na()` and `str.tostring()` in a function, a request payload, a loop, a block's `var`; a selection's history), a parameter's current array (a namespace call, a for...in loop, a typed copy), each with a warning, and anything in a function no call names, which the codegen does not emit (it emits every method and every function a call names, an uncalled function's call included: a read there is decided as any, and one an uncalled function hands to such a function's untyped parameter by how that body uses it) -- and is refused where it did not, as probes of every use and every array function in every scope and for every element type against the previous build showed (`_ELEMENT_LOWERING_FAILS` and its siblings): a collection use of a number element (a method, any `array.*` read but `array.copy` into a namespace call or a loop's local, a typed parameter or binding, a loop over a number) and the string ones `std::string` lacks, `na()` or `str.tostring()` of a parameter's array and its array-returning reads, a change through a variable or a slice bound to the history (TradingView stops there, RE10051; PineForge would change a copy), a matrix's history outside the scopes kept, a call's result's history. Whether an earlier lowering compiled often turns on the consumer of an array function's value, which the tags carry (`_array_result_consumer`: a method on the new array, a function returning it, rendering it, a member holding it; `_value_consumer`: a string value returned or bound), and an overloaded method given the history keeps the earlier lowering. `xs[k] := v`, which TradingView refuses (CE10009, CE10013), keeps its element assignment with checked bounds. Other legacy current-element reads keep their warning and return element na outside the array instead of indexing unchecked. `tests/test_collection_history_missing.py` compiles and runs missing-history witnesses for arrays, matrices, UDTs and drawings, na methods, aliases, dynamic offsets and legacy paths. An object's array or matrix field read through the object's history (`(h[1]).xs.size()`) is the field as it is now (`ahist_field`), as it compiled before. Map history stays refused. Two gaps keep the C++ the previous build emitted, which does not compile: an element function's value of a string array's history the earlier lowering reads (`f() => str.length(array.first(s[1]))`: a character of the current array's string, held as a number, which most string consumers do not take; the probes measured a value bound or returned), and the history of a variable or a call the analyzer does not type as an array or a matrix (a method's or `matrix.row`'s new array, a selection of arrays, a tuple's element, an array of drawings), which the checker never sees. `tests/test_array_history.py` compiles every shape and pins the refusals and the earlier lowerings; `tests/test_e2e_array_history.py` replays six tapes and the runtime stops. | @@ -1011,8 +1017,9 @@ or not, keep their variants (`_bounded_family_polymorphism`; - **Errors.** Use `errors.CompileError` for fatal issues raised from the transpiler. Carry `SourceLocation` so users can map back to the Pine line/col. Diagnostics inside the support checker use -`Level.WARNING` for divergences-but-not-broken, `Level.ERROR` -otherwise. +`Level.WARNING` for divergences-but-not-broken, `Level.NOTE` (`_note`) +only for the eleven informational codes named under `support_checker` +above, `Level.ERROR` otherwise. - **UDT array fields.** TradingView holds the array a UDT field is built from, and keeps a `var` array's value per bar: a push through `h.xs` reaches `a`, while an object kept from an earlier bar reads the array as diff --git a/README.md b/README.md index a7ed912..657c51a 100644 --- a/README.md +++ b/README.md @@ -36,8 +36,8 @@ for the changes in each release from 1.0.0 on and the release-note policy. `transpile_full()` are the supported Python entry points. - **Located diagnostics** — the support checker rejects unsupported Pine with a `file:line:col` location before any C++ is emitted, and - `transpile_full()` returns warnings for supported scripts with documented - approximations. + `transpile_full()` returns nonfatal warnings and, since 1.5.0, notes for supported scripts, + including those with documented approximations. ## Releases and this README @@ -64,6 +64,10 @@ covers 1.0.0 on and links the notes of earlier releases. A source install reports the version in `VERSION`, which the release workflow sets when it tags a release. +Text that says "since 1.5.0" describes the source tree on `main`, not a +published package: 1.5.0 is the planned number of the next release, and the +statements about 1.4.0 keep their historical meaning. + ### Upgrading from 1.3.0 For the 1.4.0 pair, regenerate C++ and relink against engine @@ -190,8 +194,8 @@ transpile( Returns the generated C++ source as a string. Raises `pineforge_codegen.errors.CompileError` on a rejected construct and, since 1.0.0, on a syntax error or an input limit (0.10.4 recovers from some syntax errors -and has no input limits). It does not return nonfatal warnings; use -`transpile_full()` to inspect them. +and has no input limits). It does not return nonfatal diagnostics (warnings and, +since 1.5.0, notes); use `transpile_full()` to inspect them. `libraries` is new in 1.0.0. It maps an import path to the library's source (`{"user/name/version": source_text}`), and each import the script uses @@ -218,8 +222,8 @@ It returns `{"cpp": str, "inputs": list[dict], "strategyParams": dict, "diagnostics": list[Diagnostic], "requests": list[dict]}` on success (0.10.4 returns the first three keys; `requests` is new in 1.1.0). `inputs` is the input manifest; its `title` is the actual override key, and an `input.symbol` entry -also has `"kind": "symbol"` (since 1.1.0). `diagnostics` contains nonfatal -warnings. Since 1.4.0, each input also has `supported`, the checked-settings receipt's +also has `"kind": "symbol"` (since 1.1.0). `diagnostics` contains the nonfatal +warnings and, since 1.5.0, notes. Since 1.4.0, each input also has `supported`, the checked-settings receipt's flag. Hide inputs with a false flag, exclude them from sweeps and optimization, and do not send a value: the compiled default is used, and the paired engine refuses a supplied value with `setting_unsupported`. A true flag is not a full @@ -250,17 +254,29 @@ renamed or removed, and the changelog lists the values that changed. A rejected script raises `CompileError` with its diagnostics. The Pyodide package ships `gate/glue.py`'s `transpile_json(source) -> str`, whose JSON success and error envelopes carry the same manifest and, since 1.0.0, the same -warnings; since 1.1.0 the success envelope also carries `requests`. See the +warnings; since 1.1.0 the success envelope also carries `requests`. Since 1.5.0, notes, the +informational level described under [Diagnostic codes](#diagnostic-codes), +travel in the same `diagnostics` lists with `"severity": "note"`. See the [1.0 public contract](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/docs/PUBLIC_CONTRACT.md) for the exact fields, severity values, and input key rules. There is no installed CLI or exit-code contract. ### Diagnostic codes -Every diagnostic carries a stable `code` and named `args` (since 1.2.0): -`PF-E1203` for an error, `PF-W0412` for a warning, and the data its English -`message` and `hint` were built from — identifiers, types, keywords and -numbers, raw. +Every diagnostic carries a stable `code` (of the form `PF-E1203` or `PF-W0412`) +and named `args` (since 1.2.0): the data its English `message` and `hint` were +built from — identifiers, types, keywords and numbers, raw. + +An `E` code is an error. A `W` code can be a warning or, since 1.5.0, a note: +read its declared `level` (`severity` in JSON entries and the catalog). +A note is a nonfatal, informational diagnostic, and it keeps +the `PF-W` code it had as a warning. Eleven codes are notes: PF-W1505 (the +`ta.ema` initial-warmup approximation, reported at every `ta.ema` call as a +general caveat, not a measured shortfall), PF-W1508 and PF-W1509 (a call such as +`plot` or `alert` that has no effect in a backtest) and PF-W1525 to PF-W1532 (a +request for outside data whose value reaches only display and alert sinks, +lowered to `na`). Every other diagnostic keeps its severity, the other +visual-only and display-only ones included; the catalog is authoritative. ```python from pineforge_codegen import diagnostics_catalog, transpile_full @@ -272,15 +288,21 @@ for d in transpile_full(source)["diagnostics"]: entry = diagnostics_catalog()["codes"]["PF-W1067"] # {'severity': 'warning', 'area': 'support', # 'message': '{name} diverges from TradingView semantics in PineForge.', -# 'hint': '...', 'explanation': '...', 'args': {'name': {'kind': 'identifier'}}} +# 'hint': '...', 'explanation': '...', 'args': {'name': {'kind': 'identifier'}}, +# 'user_message': '...'} ``` The catalog (`pineforge_codegen/diagnostics_catalog.json`, also attached to each GitHub release) gives each code its severity, English ICU MessageFormat -templates and a one-line explanation; rendering the templates with `args` -gives the `message` and `hint` byte for byte, so an application can translate -a diagnostic by its code. Codes are never reused. See -[Diagnostic codes](docs/PUBLIC_CONTRACT.md#diagnostic-codes). +`message` and `hint` templates, a one-line explanation and a short +`user_message` template; rendering the `message` and `hint` templates with +`args` gives the diagnostic's `message` and `hint` byte for byte, so an +application can translate a diagnostic by its code. `user_message` is a +separate short English ICU template (since 1.5.0) over the same `args` (it may be constant): +the translation source and the fallback for a code an application does not +know. It is a template, not pre-rendered English, and each `Diagnostic` and +JSON diagnostic entry carries it as `user_message` too. Codes are never reused. +See [Diagnostic codes](docs/PUBLIC_CONTRACT.md#diagnostic-codes). ### List the other symbols a script requests @@ -371,7 +393,8 @@ transpile(src, filename="my_strategy.pine") Not every request for outside data is refused. A `request.financial()` whose value reaches only plots, alerts, tables or logs -transpiles with a warning and reads `na`; 0.10.4 refuses it. The +transpiles with a note since 1.5.0 (a warning in earlier releases) and reads `na`; 0.10.4 +refuses it. The [changelog](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/CHANGELOG.md) lists what 1.0.0 reads, warns about or refuses for such requests. diff --git a/docs/PUBLIC_CONTRACT.md b/docs/PUBLIC_CONTRACT.md index 41a4606..8347617 100644 --- a/docs/PUBLIC_CONTRACT.md +++ b/docs/PUBLIC_CONTRACT.md @@ -5,6 +5,12 @@ later additions. This revision includes the 1.4.0 pair (2026-10-08). Pre-tag validation used codegen `bfc4ddce` and engine `b3192bfc`, whose version files at that point read `1.3.0`. +Text marked **since 1.5.0** describes diagnostic additions that 1.4.0 and +earlier releases do not have: the `note` severity, the `user_message` template +and the eleven codes that became notes. 1.5.0 is the planned number of the +release that carries them; until that tag exists, this text describes the +source tree, not a published package. + ## Optional compiled execution capabilities Availability: **since 1.2.0**, with engine `v1.2.0`'s capability extension and @@ -300,7 +306,9 @@ transpile_full(pine_source: str, *, check_support: bool = True, `pineforge_codegen.errors.CompileError` for a located parse, support, analysis, or generation error; its `diagnostics` attribute carries `Diagnostic` objects. `filename` appears in their source locations and in `str(error)`. -`transpile()` does not return nonfatal warnings. +`transpile()` returns no nonfatal diagnostics, neither warnings nor (since +1.5.0) notes; use `transpile_full()` to read them. The `diagnostics` of a +`CompileError` can carry them beside its errors. `libraries` maps a Pine library's import path to its source (`{"user/name/version": source_text}`); each import the script uses is inlined @@ -318,13 +326,14 @@ success: | `cpp` | `str` | The generated source, identical to `transpile()` for the same inputs. | | `inputs` | `list[dict]` | Input manifest in global source order, one entry per global-scope input call, including inline calls. | | `strategyParams` | `dict` | Values extracted from the `strategy(...)` declaration; a nonliteral value can be `None`, and an omitted argument is absent even where the C++ applies a default. | -| `diagnostics` | `list[Diagnostic]` | Nonfatal warnings only, with `Level.WARNING` and source locations. | +| `diagnostics` | `list[Diagnostic]` | Nonfatal diagnostics with source locations: warnings (`Level.WARNING`) and, since 1.5.0, notes (`Level.NOTE`). | | `requests` | `list[dict]` | Since 1.1.0: the other symbols' feeds the script reads, one entry per request site; see [Request discovery](#request-discovery). | An error still raises `CompileError`; there is no partial success dict. The -diagnostic severity enum values are `"warning"` and `"error"`. A successful -`transpile_full()` returns only warnings; a `CompileError` can carry both -warnings and errors. +diagnostic severity enum values are `"warning"`, `"error"` and, since 1.5.0, +`"note"` ([Diagnostic codes](#diagnostic-codes)). A successful +`transpile_full()` returns warnings and notes; a `CompileError` can carry +errors together with either nonfatal level. ### Input manifest and override keys @@ -437,41 +446,65 @@ success and compile-error envelopes are: `ok` is a boolean. On success, `cpp`, `inputs`, `strategyParams` and (since 1.1.0) `requests` have the same meanings as in `transpile_full()`, and -`diagnostics` contains warnings. On a `CompileError`, `error` is `str(error)` -and `diagnostics` contains the error's diagnostics; `cpp`, `inputs`, +`diagnostics` contains warnings and, since 1.5.0, notes. On a `CompileError`, +`error` is `str(error)` and `diagnostics` contains the error's diagnostics, +nonfatal ones collected with the errors included; `cpp`, `inputs`, `strategyParams` and `requests` are absent. Every JSON diagnostic has 1-based integer `line` and `col`, a `message` string, and `severity` equal to -`"warning"` or `"error"`. `endCol` is included when the +`"warning"`, `"error"` or, since 1.5.0, `"note"`. `endCol` is included when the source location provides it. A diagnostic hint, when present, is appended to `message` after ` — `. Since 1.2.0 every JSON diagnostic also has `code` and -`args` ([Diagnostic codes](#diagnostic-codes)). The glue catches +`args`; since 1.5.0 it also has `user_message`, the short ICU template +([Diagnostic codes](#diagnostic-codes)). The glue catches `CompileError`; an unexpected Python exception may propagate instead of producing an envelope. The JSON entry point does not accept a `filename` argument. ## Diagnostic codes -Since 1.2.0 every `Diagnostic` (in `transpile_full(...)["diagnostics"]`, in a -`CompileError`'s `diagnostics`, and in the glue envelopes) carries: +Every `Diagnostic` (in `transpile_full(...)["diagnostics"]`, in a +`CompileError`'s `diagnostics`, and in the glue envelopes) carries the stable +`code` and `args` introduced in 1.2.0. Since 1.5.0 it also carries +`user_message`, and its severity can be `note`: -- `code`: a stable string `PF-`, `S` being `E` for an error and `W` - for a warning. Its first digit is the area that spells the text: `0` +- `code`: a stable string `PF-`. `E` and `W` are historical identity + prefixes, not the severity: the eleven codes that became notes in 1.5.0 + keep their `PF-W` codes. Its first digit is the area that spells the text: `0` source (lexer, parser, limits), `1` support checker and requests, `2` analysis, `3` `request.security`, `4` libraries and imports, `5` code generation, `6` array and matrix history, `7` `ta.*`. The support checker reports what it refuses inside a `switch` arm as a warning: `PF-W1nnn` with `nnn` below 500 is `PF-E1nnn` there. +- Severity (`Diagnostic.level`, the `severity` of a glue diagnostic and of a + catalog entry): `"error"`, `"warning"` or, since 1.5.0, `"note"`. An error is + fatal and raises `CompileError`. A warning and a note are nonfatal: a script + that transpiles with either returns its C++ (`ok: true` in the glue + envelope), and a `CompileError` can carry them beside its errors. The catalog + declares each code's severity and the diagnostic carries it; read it, never + infer it from the `E` / `W` prefix or from the words of a message ("visual + only", "display"). A note is a classification, not a statement that results + are unaffected: PF-W1505, a note, still describes a warmup approximation. - `args`: an object of named values, raw: identifiers, types, keywords and Pine spellings as strings, counts as JSON numbers; never quoting, backticks or a formatted number. +- `user_message` (since 1.5.0): one short English ICU **template**, identical + on the catalog entry, `Diagnostic.user_message` and the JSON diagnostic. It + uses only the diagnostic's existing `args` names and may be constant. It is + the raw template over `args`, not pre-rendered English; it does not replace + `message` and `hint`, and it never substitutes the unbounded raw diagnostic + as its whole sentence. For example, `"{name}() does nothing in a backtest."` + travels with `args.name = "plot"`; a receiver renders or translates it. `diagnostics_catalog()` returns the catalog, which ships as `pineforge_codegen/diagnostics_catalog.json` (schema -`pineforge-diagnostics-catalog/v1`) and is attached to each GitHub release +`pineforge-diagnostics-catalog/v1`, whose id the 1.5.0 additions do not +change) and is attached to each GitHub release (`diagnostics_catalog-v1.3.0.json` for 1.3.0). -Per code it gives `severity`, `area`, the English ICU MessageFormat `message` -template, the `hint` template or `null`, a one-line `explanation`, and `args`: -per argument its `kind` — `identifier`, `type`, `keyword`, `number`, `vocab` +Per code it gives `severity` (`error`, `warning` or, since 1.5.0, `note`), +`area`, the English ICU MessageFormat `message` template, the `hint` template +or `null`, a one-line `explanation`, `args` and, since 1.5.0, the short +`user_message` template. `args` gives each argument's +`kind` — `identifier`, `type`, `keyword`, `number`, `vocab` (an English word or phrase the transpiler picks from the closed set listed in `values`, which an application may translate) or `text` (open English text the transpiler builds, such as a nested reason; shown as is). The templates use @@ -482,12 +515,92 @@ decimal digits. `render_diagnostic(code, args)` returns the English byte; in the glue envelope `message` is the message, plus ` — ` and the hint when there is one. +From 1.5.0 on, receivers translate by stable code using their own locale +catalogs; the English `user_message` template is the translation source and +fallback for an unknown code. An unknown code is shown at its declared +recognized severity. An unknown severity is read as `warning`, including when +the code is known; code prefixes do not override that rule. Render the +template with the separate argument values as text, not as new template syntax +or markup. +The receiver examples in `tests/fixtures/diagnostic_notes/receiver.json` +specify this compatibility rule; they are not evidence of an app deployment. + +Since 1.5.0 the reviewed warning-to-note migration is exactly PF-W1505, +PF-W1508, PF-W1509, PF-W1525, PF-W1526, PF-W1527, PF-W1528, PF-W1529, +PF-W1530, PF-W1531 and PF-W1532, each a warning in 1.4.0. All other +severities, all stable codes and every existing message, hint, explanation and +argument definition are unchanged, and no existing key of a `Diagnostic`, a +JSON diagnostic, the catalog or the envelopes is renamed or removed: `severity` +gains the value `note` and `user_message` is added, while `code`, `args`, +`message`, `hint`, `line`, `col` and `endCol` keep their values. +The prior catalog and pin remain explicit legacy fixtures beside the exact +delta in `tests/fixtures/diagnostic_notes/`. PF-W1509 remains a legacy +template alias: the existing text classifier selects PF-W1508 when those +two templates tie. The migration does not invent a new emitted identity. + +Those eleven are the only codes the catalog declares as notes; a message that +says "visual only" or "display" does not make its code one. PF-W1508 and +PF-W1509 describe a call PineForge skips as visual only (`plot(...)`, +`table.new(...)`). PF-W1525 to PF-W1532 describe an earnings, dividends, +splits, financial, footprint or other-symbol request whose value reaches only +display and alert sinks and is lowered to `na`. PF-W1505 describes the +`ta.ema` warmup approximation, a note by the explicit acceptance of the +initialization-note foundation. Five diagnostics that also speak of +visual-only or display-only handling remain warnings: PF-W1502 (a `color(...)` +cast), PF-W1506 (`color.from_gradient`), PF-W1507 (a drawing setter that drops +color, style or size), PF-W1078 (a visual or style constant) and PF-W1552 (a +`request.security_lower_tf` whose symbol can be another symbol's and whose +value reaches only display and alert sinks). Every other diagnostic keeps its +declared severity as well: executable missing feeds, partial risk support, +ignored trading values, repainting, numerical approximations, lossy values and +invalid arguments stay warnings or errors. + +PF-W1505 is a static note: the support checker emits it at each `ta.ema` call +it visits, with no condition on the run, an input or the timeframe, and nothing +in this revision suppresses or qualifies it per call. It still carries its +original compile-time EMA caveat. This foundation does not establish startup +adequacy or change seeding. The selected-window consumer may show its startup +sentence only for a known finite shortfall in bars of that site's +evaluation-context timeframe; absence is not parity. No sidecar exists yet, at +compile time or at run time: this revision emits no `call_site_id` and no +startup fact. The subsequent startup inventory and extraction must bind a +versioned sidecar to Pine/generated identities, and share `call_site_id` and +the exact source range with the diagnostic rather than joining by text; until +that work lands, the static notes stay as they are. Input-bound lengths retain +the input name or expression; runs/trials resolve submitted values and studies +retain searched ranges. Recursive adequacy and seeding facts remain separate +and may be unknown. The typed consumer fixtures (`warmup_consumer.py` and +`warmup_handoff.json` in `tests/fixtures/diagnostic_notes/`) describe that +later handoff; they are contract examples, not transpiler output. + A code is never removed or reused, and a changed meaning gets a new code -(`tests/fixtures/diagnostic_codes_pin.json` pins each code's templates). A -text no template renders carries `PF-E0000` / `PF-W0000` with the text in -`args.message` (and `args.hint`); the test suite refuses it. The `message` -text itself is unchanged and stays the English rendering; `runtime.error` -text a strategy authors is not a transpile diagnostic. +(`tests/fixtures/diagnostic_codes_pin.json` pins each code's severity, +`message` and `hint` templates and argument names; it does not pin +`user_message`). Since 1.5.0 the `user_message` templates are checked as +follows. The templates of the eleven migrated codes are fixed string for string +by `tests/fixtures/diagnostic_notes/delta.json`. Every template is checked for +form: a short, parseable sentence over the entry's own argument names. Each of +the 97 warning twins of an error (`PF-W1nnn` for `PF-E1nnn`) has a sentence of +its own, not its error's, that says PineForge warns; the 91 that warn only +inside a `switch` arm also say that PineForge keeps the arm's lowering, and +PF-W1067 to PF-W1072, which warn everywhere, name no arm. No warning or note +template says that PineForge refuses or rejects something, though one may say +what TradingView refuses or rejects. Beyond these checks a template's exact +wording is not pinned. A text no template +renders carries `PF-E0000` / `PF-W0000` with the text in `args.message` (and +`args.hint`); the test suite refuses it. The `message` text itself is +unchanged and stays the English rendering; `runtime.error` text a strategy +authors is not a transpile diagnostic. Since 1.5.0 an uncatalogued note uses +the existing PF-W0000 fallback with its actual `note` level preserved; +PF-W0000's catalog severity remains `warning`. The diagnostic level is the +wire authority in that fallback case. No new fallback code is allocated. + +`scripts/gen_diagnostics_catalog.py --write` adds identities for newly +spelled templates and preserves existing pins. Since 1.5.0 new entries require +an authored `user_message`; the generator reports missing, malformed or +unknown-argument presentation templates rather than copying raw diagnostics. +The eleven reviewed severity pin changes above are explicit fixture-backed +exceptions, not a general permission to regenerate existing pins. ## Compatibility boundary diff --git a/gate/glue.py b/gate/glue.py index 9e36468..44bfe80 100644 --- a/gate/glue.py +++ b/gate/glue.py @@ -27,6 +27,8 @@ def _diagnostic_entries(diagnostics) -> list: # message (and the hint after " — ") render from. "code": d.code, "args": d.args, + # A template for translation/fallback, not pre-rendered English. + "user_message": d.user_message, } end_col = getattr(loc, "end_col", None) if loc else None if end_col is not None: @@ -41,7 +43,7 @@ def transpile_json(source: str) -> str: except CompileError as e: return json.dumps({"ok": False, "error": str(e), "diagnostics": _diagnostic_entries(e.diagnostics)}) - # A script that transpiled carries its warnings in the same entry format. + # A script that transpiled carries warnings and notes in the same format. return json.dumps({"ok": True, "cpp": full["cpp"], "inputs": full["inputs"], "strategyParams": full["strategyParams"], "diagnostics": _diagnostic_entries(full["diagnostics"]), diff --git a/pineforge_codegen/__init__.py b/pineforge_codegen/__init__.py index b8901ee..6bd2489 100644 --- a/pineforge_codegen/__init__.py +++ b/pineforge_codegen/__init__.py @@ -172,10 +172,10 @@ def transpile_full(pine_source: str, *, check_support: bool = True, See :meth:`CodeGen.extract_input_manifest`. - ``strategyParams``: the literal ``strategy(...)`` kwargs the analyzer surfaced (e.g. ``initial_capital``, ``pyramiding``). - - ``diagnostics``: the warnings (:class:`~pineforge_codegen.errors.Diagnostic`, - ``Level.WARNING``) the support checker and the analyzer raised for a + - ``diagnostics``: the warnings and notes (:class:`~pineforge_codegen.errors.Diagnostic`, + ``Level.WARNING`` / ``Level.NOTE``) the support checker and the analyzer raised for a script that transpiled -- e.g. an approximated ``ta.vwap`` anchor. An - error still raises ``CompileError``, which carries the warnings too. + error still raises ``CompileError``, which carries nonfatal diagnostics too. - ``requests``: every request site that reads another symbol's feed, by line: its symbol and timeframe as registration computes them before the first bar (``literal`` / ``input`` / ``computed`` / @@ -198,6 +198,6 @@ def transpile_full(pine_source: str, *, check_support: bool = True, "inputs": gen.extract_input_manifest(), "strategyParams": dict(ctx.strategy_params), "diagnostics": [d for d in (*support_diagnostics, *ctx.diagnostics) - if d.level == Level.WARNING], + if d.level in (Level.WARNING, Level.NOTE)], "requests": discover_requests(gen, ctx, sites), } diff --git a/pineforge_codegen/diagnostic_codes.py b/pineforge_codegen/diagnostic_codes.py index da19448..4b8ca4c 100644 --- a/pineforge_codegen/diagnostic_codes.py +++ b/pineforge_codegen/diagnostic_codes.py @@ -1,7 +1,7 @@ """Stable codes and named arguments for every transpile diagnostic. Every :class:`~pineforge_codegen.errors.Diagnostic` carries a ``code`` -(``PF-E1203`` for an error, ``PF-W0412`` for a warning) and ``args``, the +(``PF-E1203`` / ``PF-W0412``) and ``args``, the named data its English ``message`` and ``hint`` were built from. The codes, their severities, English ICU MessageFormat templates and one-line explanations live in ``diagnostics_catalog.json`` beside this module, which @@ -40,7 +40,9 @@ CATALOG_PATH = Path(__file__).with_name("diagnostics_catalog.json") CATALOG_SCHEMA = "pineforge-diagnostics-catalog/v1" -UNCATALOGUED = {"error": "PF-E0000", "warning": "PF-W0000"} +# Notes keep historical PF-W identities. The nonfatal fallback is shared; +# its catalog severity remains warning, while a Diagnostic retains its level. +UNCATALOGUED = {"error": "PF-E0000", "warning": "PF-W0000", "note": "PF-W0000"} @lru_cache(maxsize=1) @@ -52,16 +54,22 @@ def _load() -> dict: def diagnostics_catalog() -> dict: """The diagnostics catalog: ``{"schema", "codes": {code: entry}}``. - Each entry gives ``severity`` (``error`` / ``warning``), ``area``, the + Each entry gives ``severity`` (``error`` / ``warning`` / ``note``), ``area``, the English ICU MessageFormat ``message`` template, the ``hint`` template or ``None``, a one-line ``explanation`` and ``args``: per argument name its ``kind`` (``identifier``, ``type``, ``keyword``, ``number``, ``vocab`` or - ``text``) and, for ``vocab``, its closed set of ``values``. A fresh copy - is returned on every call. + ``text``) and, for ``vocab``, its closed set of ``values``. ``user_message`` + is a short ICU template over those same arguments, not rendered English. + A fresh copy is returned on every call. """ return json.loads(json.dumps(_load())) +def _user_message_template(code: str) -> str: + """The short presentation template; never classify from or render it here.""" + return _load()["codes"][code]["user_message"] + + # --------------------------------------------------------------------------- # ICU MessageFormat subset # --------------------------------------------------------------------------- @@ -308,7 +316,7 @@ def match(self, message: str, hint: str | None) -> dict | None: @lru_cache(maxsize=1) def _matchers() -> dict[str, list[_Matcher]]: - by_severity: dict[str, list[_Matcher]] = {"error": [], "warning": []} + by_severity: dict[str, list[_Matcher]] = {"error": [], "warning": [], "note": []} for code, entry in _load()["codes"].items(): if code in UNCATALOGUED.values(): continue @@ -323,8 +331,10 @@ def _matchers() -> dict[str, list[_Matcher]]: def classify(severity: str, message: str, hint: str | None = None) -> tuple[str, dict]: """The ``(code, args)`` of a diagnostic's English text. - ``severity`` is ``"error"`` or ``"warning"``. A text no catalog template - renders gets ``PF-E0000`` / ``PF-W0000`` with its text as ``args``. + ``severity`` is ``"error"``, ``"warning"`` or ``"note"``; the catalog's + declared severity selects the templates, never a code's prefix. A text + no template renders gets ``PF-E0000`` for an error or ``PF-W0000`` for + a warning/note, with its text as ``args`` and no new fallback identity. """ for matcher in _matchers().get(severity, ()): if matcher.has_hint != (hint is not None): diff --git a/pineforge_codegen/diagnostics_catalog.json b/pineforge_codegen/diagnostics_catalog.json index df1cfd7..64424f7 100644 --- a/pineforge_codegen/diagnostics_catalog.json +++ b/pineforge_codegen/diagnostics_catalog.json @@ -1,632 +1,632 @@ {"schema": "pineforge-diagnostics-catalog/v1", "codes": { - "PF-E0000": {"severity": "error", "area": "uncatalogued", "message": "{message}", "hint": "{hint}", "explanation": "A diagnostic whose text no catalog template renders; the test suite refuses it, so a release never emits it.", "args": {"message": {"kind": "text"}, "hint": {"kind": "text"}}}, - "PF-E0001": {"severity": "error", "area": "source", "message": "Block nesting depth exceeds {max_nesting_depth} levels.", "hint": null, "explanation": "Indented blocks (if, for, while, functions) are nested deeper than PineForge allows; flatten the structure.", "args": {"max_nesting_depth": {"kind": "number"}}}, - "PF-E0002": {"severity": "error", "area": "source", "message": "Invalid color literal: expected hex digits after ''#''", "hint": "Color literals must be #RRGGBB or #RRGGBBAA", "explanation": "A '#' starts a color literal but no hex digits follow it; write the color as #RRGGBB or #RRGGBBAA.", "args": {}}, - "PF-E0003": {"severity": "error", "area": "source", "message": "Delimiter nesting depth exceeds {max_nesting_depth} levels.", "hint": null, "explanation": "Parentheses or square brackets are nested deeper than PineForge allows; split the expression into simpler steps.", "args": {"max_nesting_depth": {"kind": "number"}}}, - "PF-E0004": {"severity": "error", "area": "source", "message": "Unexpected character: ''{ch}''", "hint": null, "explanation": "The script contains a character that is not valid Pine syntax outside a string; remove or replace it.", "args": {"ch": {"kind": "identifier"}}}, - "PF-E0005": {"severity": "error", "area": "source", "message": "Malformed scientific notation: expected digits after exponent", "hint": "Example: 1.5e-3 or 2E10", "explanation": "A number in scientific notation has an exponent marker (e or E) with no digits after it; add the exponent digits or drop the marker.", "args": {}}, - "PF-E0006": {"severity": "error", "area": "source", "message": "Unterminated string literal: the line ends before its closing quote and the next line is not indented as a wrapped line.", "hint": "Close the string on its line, indent the line it wraps onto, or use a multiline string (\"\"\"...\"\"\").", "explanation": "A string is not closed on its line and the next line is not an indented continuation; close the quote or use a triple-quoted string.", "args": {}}, - "PF-E0007": {"severity": "error", "area": "source", "message": "Unterminated multiline string literal: no closing {delimiter} before the end of the script.", "hint": "A multiline string ends at the next \"\"\" (or '''''' for one opened with ''''''); escape a quote that would end it early.", "explanation": "A triple-quoted string never reaches its closing delimiter before the script ends; add the closing triple quote or escape an early quote.", "args": {"delimiter": {"kind": "identifier"}}}, - "PF-E0008": {"severity": "error", "area": "source", "message": "Source size exceeds {max_source_chars} characters.", "hint": null, "explanation": "The script is larger than the maximum source size PineForge accepts; shorten it.", "args": {"max_source_chars": {"kind": "number"}}}, - "PF-E0009": {"severity": "error", "area": "source", "message": "AST nesting depth exceeds {max_nesting_depth} nodes.", "hint": null, "explanation": "An expression or operator chain is so long that its syntax tree is deeper than PineForge allows; break it into several statements.", "args": {"max_nesting_depth": {"kind": "number"}}}, - "PF-E0010": {"severity": "error", "area": "source", "message": "Transpilation time exceeds {max_transpile_seconds} seconds.", "hint": null, "explanation": "Transpiling the script ran past the time limit; simplify it, for example by reducing very large or deeply nested code.", "args": {"max_transpile_seconds": {"kind": "number"}}}, - "PF-E0011": {"severity": "error", "area": "source", "message": "Expected {expected_token}, got {token_type}(''{token}''). {msg}", "hint": null, "explanation": "The parser required one specific token here and found another; fix the syntax at the reported position.", "args": {"expected_token": {"kind": "keyword"}, "token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}, "msg": {"kind": "text"}}}, - "PF-E0012": {"severity": "error", "area": "source", "message": "Nesting depth exceeds {max_nesting_depth} levels.", "hint": null, "explanation": "Blocks, else-if chains, prefix operators or nested expressions go deeper than PineForge's nesting limit; flatten the code.", "args": {"max_nesting_depth": {"kind": "number"}}}, - "PF-E0013": {"severity": "error", "area": "source", "message": "Unexpected token {token_type}(''{token}'') after statement; expected a line break or comma", "hint": null, "explanation": "Two expressions sit on one line with nothing between them; separate statements with a line break or a comma.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0014": {"severity": "error", "area": "source", "message": "''export'' declarations belong to Pine libraries; PineForge transpiles strategies only", "hint": null, "explanation": "export marks a Pine library declaration, but PineForge transpiles strategies only; remove export or write a strategy.", "args": {}}, - "PF-E0015": {"severity": "error", "area": "source", "message": "Expected LPAREN, got {token_type}(''{token}'').", "hint": null, "explanation": "A '(' is missing where a call, a declaration's argument list or a function definition requires one.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0016": {"severity": "error", "area": "source", "message": "Expected RPAREN, got {token_type}(''{token}'').", "hint": null, "explanation": "A ')' is missing or misplaced: a call, parameter list or parenthesized expression is not closed properly.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0017": {"severity": "error", "area": "source", "message": "''export'' must precede a function, method, type, enum or const declaration", "hint": null, "explanation": "In a library, export must be followed by a function, method, type, enum or const declaration; nothing else can be exported.", "args": {}}, - "PF-E0018": {"severity": "error", "area": "source", "message": "Expected IMPORT, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the import keyword to start an import statement but found another token; check the line's spelling.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0019": {"severity": "error", "area": "source", "message": "Expected IDENT, got {token_type}(''{token}'').", "hint": null, "explanation": "A name was expected here (a variable, function, parameter, field, type or loop variable) but another token was found.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0020": {"severity": "error", "area": "source", "message": "Expected EQUALS, got {token_type}(''{token}'').", "hint": null, "explanation": "An '=' was expected after the declared name (variable, tuple or for-loop start); add it or fix the declaration.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0021": {"severity": "error", "area": "source", "message": "Expected LBRACKET, got {token_type}(''{token}'').", "hint": null, "explanation": "A tuple declaration must start with '[' as in [a, b] = f(); the opening bracket is missing or misplaced.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0022": {"severity": "error", "area": "source", "message": "Expected RBRACKET, got {token_type}(''{token}'').", "hint": null, "explanation": "A ']' is missing: a tuple declaration, for-in destructuring, array literal or index expression is not closed.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0023": {"severity": "error", "area": "source", "message": "Expected FAT_ARROW, got {token_type}(''{token}'').", "hint": null, "explanation": "A function or method definition, or a switch case, needs '=>' here; it is missing or misplaced.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0024": {"severity": "error", "area": "source", "message": "Expected IF, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the if keyword at the start of an if statement but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0025": {"severity": "error", "area": "source", "message": "Expected NEWLINE, got {token_type}(''{token}'').", "hint": null, "explanation": "An if, else, for, while or switch header must end its line before its indented body; other tokens follow it on the same line.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0026": {"severity": "error", "area": "source", "message": "Expected INDENT, got {token_type}(''{token}'').", "hint": null, "explanation": "An indented block was expected after the header or definition, but the next line is not indented further; indent the block's statements.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0027": {"severity": "error", "area": "source", "message": "Expected DEDENT, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected an indented block to end but found other tokens; check the indentation of the block's lines.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0028": {"severity": "error", "area": "source", "message": "Expected FOR, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the for keyword at the start of a for loop but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0029": {"severity": "error", "area": "source", "message": "Expected IN, got {token_type}(''{token}'').", "hint": null, "explanation": "A for-in loop with destructured variables is missing the in keyword after them.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0030": {"severity": "error", "area": "source", "message": "Expected TO, got {token_type}(''{token}'').", "hint": null, "explanation": "A counted for loop is missing the to keyword between its start and end values, as in for i = 0 to n.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0031": {"severity": "error", "area": "source", "message": "Expected WHILE, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the while keyword at the start of a while loop but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0032": {"severity": "error", "area": "source", "message": "Expected SWITCH, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the switch keyword at the start of a switch but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0033": {"severity": "error", "area": "source", "message": "Expected COLON, got {token_type}(''{token}''). Expected '':'' in ternary", "hint": null, "explanation": "A ternary condition ? value must be followed by ':' and an else value; add the colon or complete the expression.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0034": {"severity": "error", "area": "source", "message": "Expected IDENT, got {token_type}(''{token}''). Expected member name", "hint": null, "explanation": "A '.' must be followed by a member name (a field or method); the token after the dot is not a name.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E0035": {"severity": "error", "area": "source", "message": "duplicate keyword argument ''{key_tok}''", "hint": "Remove one ''{key_tok}='' binding; a keyword argument may be specified only once.", "explanation": "A call binds the same keyword argument twice; keep only one binding.", "args": {"key_tok": {"kind": "identifier"}}}, - "PF-E0036": {"severity": "error", "area": "source", "message": "Numeric literal exceeds the generated C++ range.", "hint": null, "explanation": "A numeric literal is too large to be written in the generated C++ code; use a smaller number.", "args": {}}, - "PF-E0037": {"severity": "error", "area": "source", "message": "Unexpected token {token_type}(''{token}'')", "hint": null, "explanation": "The parser found a token that cannot start or continue an expression here; look for a stray or misplaced token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, - "PF-E1001": {"severity": "error", "area": "support", "message": "{context}: map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps with string keys only; declare the map's key type as string.", "args": {"context": {"kind": "text"}}}, - "PF-E1002": {"severity": "error", "area": "support", "message": "{context}: map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps whose values are float, int, bool or string only; use one of those as the value type.", "args": {"context": {"kind": "text"}}}, - "PF-E1003": {"severity": "error", "area": "support", "message": "matrix<{element_type}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead.", "args": {"element_type": {"kind": "type"}}}, - "PF-E1004": {"severity": "error", "area": "support", "message": "matrix<{element_type}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type.", "args": {"element_type": {"kind": "type"}}}, - "PF-E1005": {"severity": "error", "area": "support", "message": "input.color(...) requires a color defval (e.g. color.red or color.new(color.red, 50)).", "hint": null, "explanation": "input.color needs a color as its default value, for example color.red or color.new(color.red, 50).", "args": {}}, - "PF-E1006": {"severity": "error", "area": "support", "message": "input.color(...) defval must be a color constant (color.red, ...), a color literal (#rrggbb), or a color.new(...) / color.rgb(...) builder. Arbitrary expressions are not supported: the engine has no color helper, so codegen routes input.color through the int getter — any non-color defval would silently store a numeric value with no color encoding.", "hint": "Replace the defval with color. or color.new(...).", "explanation": "The default of input.color must be a color constant, a #rrggbb literal or a color.new or color.rgb call; other expressions are refused.", "args": {}}, - "PF-E1007": {"severity": "error", "area": "support", "message": "input.source(...) requires a native series defval (close, open, high, low, hl2, hlc3, ohlc4, ...).", "hint": null, "explanation": "input.source needs a default chart series such as close as its first argument or defval.", "args": {}}, - "PF-E1008": {"severity": "error", "area": "support", "message": "input.source(...) defval must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4). User series, computed expressions, and indicator outputs are not supported: input.source is restricted to native OHLCV series.", "hint": "Use one of: close, open, high, low, hl2, hlc3, ohlc4.", "explanation": "The default of input.source must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4); computed series are refused.", "args": {}}, - "PF-E1009": {"severity": "error", "area": "support", "message": "{kind}() declarations are not supported; PineForge runs strategies only.", "hint": "Replace the declaration with strategy(...) and add explicit entry/exit calls.", "explanation": "PineForge runs strategies only, so a script declared with indicator() or library() is refused; declare it with strategy() and add orders.", "args": {"kind": {"kind": "identifier"}}}, - "PF-E1010": {"severity": "error", "area": "support", "message": "Tuple reassignment [..] {op} is not Pine syntax: TradingView declares a tuple with ''='' and has no tuple reassignment.", "hint": "Declare new names with [a, b] = f(), then reassign each variable on its own line.", "explanation": "Pine has no tuple reassignment: declare a tuple once with '=' and reassign each variable on its own line.", "args": {"op": {"kind": "keyword"}}}, - "PF-E1011": {"severity": "error", "area": "support", "message": "A tuple literal [..] cannot be a variable''s value: TradingView rejects it here (Syntax error at input ''['', CE10156). A tuple is only a function''s or an if/switch arm''s value or a request.security expression.", "hint": "Declare each variable on its own line (a = x, b = y), or return the tuple from a function: f() => [x, y], then [a, b] = f().", "explanation": "A tuple literal such as [a, b] cannot be assigned to a variable; return it from a function or if/switch arm and destructure the result.", "args": {}}, - "PF-E1012": {"severity": "error", "area": "support", "message": "A ternary cannot return a tuple: TradingView rejects [a, b] = c ? [..] : [..] (\"Ternary operations cannot return tuples\").", "hint": "Select the tuple with an if or switch: [a, b] = if c, each arm ending in its tuple.", "explanation": "A ternary cannot produce a tuple (TradingView rejects it too); choose between tuples with an if or switch instead.", "args": {}}, - "PF-E1013": {"severity": "error", "area": "support", "message": "ta.stoch(...) returns a single series in PineForge; tuple destructuring is not supported.", "hint": "Use k = ta.stoch(...) and compute smoothing separately if needed.", "explanation": "ta.stoch returns one series in PineForge, so destructuring it into a tuple is refused; assign it to a single variable.", "args": {}}, - "PF-E1014": {"severity": "error", "area": "support", "message": "History references on UDT drawing fields are not supported in PineForge.", "hint": "{var_name}.{object_member}[...] would be read as the current-bar field, not prior-bar history. Copy the field to a bare drawing variable first, or remove the history reference.", "explanation": "A history index on a drawing field of a user-defined type would silently read the current field, so it is refused; copy the field to a variable first.", "args": {"var_name": {"kind": "identifier"}, "object_member": {"kind": "identifier"}}}, - "PF-E1015": {"severity": "error", "area": "support", "message": "History references on tuple-destructured drawing handles are not supported in PineForge.", "hint": "{object_name}[...] is a drawing handle from tuple destructuring; PineForge cannot historize that tuple element safely.", "explanation": "A drawing handle bound by tuple destructuring cannot be read through a history index; remove the history reference.", "args": {"object_name": {"kind": "identifier"}}}, - "PF-E1016": {"severity": "error", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}}}, - "PF-E1017": {"severity": "error", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}}, - "PF-E1018": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1019": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1020": {"severity": "error", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}}}, - "PF-E1021": {"severity": "error", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}}, - "PF-E1022": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1023": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1024": {"severity": "error", "area": "support", "message": "footprint.{footprint}(...) is not supported.", "hint": "PineForge reads a footprint''s delta() only: the fp_delta__ column of the feed a requests manifest pins for the symbol requested.", "explanation": "PineForge reads only the delta of a footprint value; every other footprint member is refused.", "args": {"footprint": {"kind": "identifier"}}}, - "PF-E1025": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "Currency conversion data not available in PineForge.", "explanation": "PineForge has no currency-conversion data, so request.currency_rate is refused; supply the rate yourself, for example as an input.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1026": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "External Quandl data not available in PineForge.", "explanation": "PineForge cannot load external Quandl data, so request.quandl is refused; remove it.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1027": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "External seed data feeds not available in PineForge.", "explanation": "PineForge cannot load external seed data feeds, so request.seed is refused; remove it.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1028": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.kagi() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.kagi builds a Kagi symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1029": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.linebreak() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.linebreak builds a Line Break symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1030": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.modify() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.modify builds a modified symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1031": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.new() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.new builds another symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1032": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.pointfigure() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.pointfigure builds a Point and Figure symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1033": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.renko() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.renko builds a Renko symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1034": {"severity": "error", "area": "support", "message": "ticker.heikinashi(...) is supported only for the chart''s own symbol.", "hint": "Pass syminfo.tickerid: PineForge applies the Heikin-Ashi candle transform to the chart symbol inside request.security, but cannot load an alternate symbol''s HA candles.", "explanation": "ticker.heikinashi is accepted only for the chart's own symbol (syminfo.tickerid); another symbol's Heikin-Ashi candles cannot be loaded.", "args": {}}, - "PF-E1035": {"severity": "error", "area": "support", "message": "{full}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1036": {"severity": "error", "area": "support", "message": "{name}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1037": {"severity": "error", "area": "support", "message": "{full}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "footprint.* calls need tick-level bid/ask volume rows, which a PineForge batch backtest does not load.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1038": {"severity": "error", "area": "support", "message": "{full}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "volume_row.* calls need tick-level volume rows, which a PineForge batch backtest does not load.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1039": {"severity": "error", "area": "support", "message": "library() declarations are not supported; PineForge runs strategies only.", "hint": "Use strategy(...) and inline or pre-expand library code before uploading.", "explanation": "PineForge runs strategies only, so a library() declaration is refused; use strategy() and paste any library code into the script.", "args": {}}, - "PF-E1040": {"severity": "error", "area": "support", "message": "Bare barssince(...) is broken in PineForge codegen.", "hint": "Use ta.barssince(...) instead.", "explanation": "The bare barssince(...) form does not work in PineForge; call ta.barssince(...) instead.", "args": {}}, - "PF-E1041": {"severity": "error", "area": "support", "message": "ta.sum is not a PineScript v6 function.", "hint": "Use math.sum(...) instead.", "explanation": "ta.sum does not exist in Pine v6; use math.sum(source, length) for a rolling sum.", "args": {}}, - "PF-E1042": {"severity": "error", "area": "support", "message": "ta.{name} is a PineScript v6 variable, not a function.", "hint": "Use ta.{name} without parentheses.", "explanation": "This ta.* name is a built-in variable, not a function, so write it without parentheses.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1043": {"severity": "error", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.closedtrades or strategy.opentrades accessor is not available in PineForge; use one of the supported trade accessors.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1044": {"severity": "error", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": "{hint}", "explanation": "Open trades have no exit data in Pine v6: this accessor exists only on strategy.closedtrades, so it cannot be read from strategy.opentrades.", "args": {"full": {"kind": "identifier"}, "hint": {"kind": "text"}}}, - "PF-E1045": {"severity": "error", "area": "support", "message": "strategy.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.* function is not implemented in PineForge; check the spelling or use a supported strategy function.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1046": {"severity": "error", "area": "support", "message": "strategy.exit(...) requires at least one price or trailing parameter in PineForge.", "hint": "Use strategy.close(...) for market exits.", "explanation": "strategy.exit needs a price or trailing parameter (profit, loss, limit, stop or a trail setting); use strategy.close for a plain market exit.", "args": {}}, - "PF-E1047": {"severity": "error", "area": "support", "message": "{full}(...) is not supported. Only request.security(...) and request.security_lower_tf(...) are available in PineForge.", "hint": "External request feeds and other request.* variants are intentionally unavailable.", "explanation": "Only request.security and request.security_lower_tf are supported; other request.* calls need data feeds PineForge does not provide.", "args": {"full": {"kind": "identifier"}}}, - "PF-E1048": {"severity": "error", "area": "support", "message": "ta.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this ta.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1049": {"severity": "error", "area": "support", "message": "math.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this math.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1050": {"severity": "error", "area": "support", "message": "str.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this str.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1051": {"severity": "error", "area": "support", "message": "input.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this input.* function, so the call is refused; use one of the supported input functions.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1052": {"severity": "error", "area": "support", "message": "timeframe.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only timeframe.change and timeframe.in_seconds; any other timeframe.* function is refused.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1053": {"severity": "error", "area": "support", "message": "color.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only color.new, color.rgb and color.r/g/b/t; any other color.* function is refused.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1054": {"severity": "error", "area": "support", "message": "runtime.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only runtime.error; any other runtime.* function is refused.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1055": {"severity": "error", "area": "support", "message": "log.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only log.info, log.warning and log.error; any other log.* function is refused.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1056": {"severity": "error", "area": "support", "message": "array.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this array.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1057": {"severity": "error", "area": "support", "message": "map.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this map.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1058": {"severity": "error", "area": "support", "message": "map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps support only string keys; declare the map with string as its key type.", "args": {}}, - "PF-E1059": {"severity": "error", "area": "support", "message": "map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps can hold only float, int, bool or string values; other value types such as collections or objects are refused.", "args": {}}, - "PF-E1060": {"severity": "error", "area": "support", "message": "matrix<{t}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type.", "args": {"t": {"kind": "type"}}}, - "PF-E1061": {"severity": "error", "area": "support", "message": "matrix<{t}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead.", "args": {"t": {"kind": "type"}}}, - "PF-E1062": {"severity": "error", "area": "support", "message": "matrix<{t}> element type not supported. Allowed: float, int, bool, string, color, or a declared UDT.", "hint": null, "explanation": "A matrix element must be float, int, bool, string, color or a declared user-defined type; any other element type is refused.", "args": {"t": {"kind": "type"}}}, - "PF-E1063": {"severity": "error", "area": "support", "message": "matrix.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this matrix.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1064": {"severity": "error", "area": "support", "message": "{ns}.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only part of the line, box, label and linefill functions; this one is not implemented, so the call is refused.", "args": {"ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-E1065": {"severity": "error", "area": "support", "message": "chart.point.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only chart.point.new, now, from_index, from_time and copy; any other chart.point.* function is refused.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1066": {"severity": "error", "area": "support", "message": "''export'' is a Pine library keyword; PineForge runs strategies only and does not support exported functions/types.", "hint": "Remove the ''export'' keyword (and inline any library code into the strategy script).", "explanation": "'export' marks library code; PineForge runs strategies only, so remove the keyword and inline any library code into the strategy.", "args": {}}, - "PF-E1067": {"severity": "error", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1068": {"severity": "error", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1069": {"severity": "error", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"name": {"kind": "identifier"}}}, - "PF-E1070": {"severity": "error", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"chain": {"kind": "identifier"}}}, - "PF-E1071": {"severity": "error", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"chain": {"kind": "identifier"}}}, - "PF-E1072": {"severity": "error", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"chain": {"kind": "identifier"}}}, - "PF-E1073": {"severity": "error", "area": "support", "message": "{object_name}.{member}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": null, "explanation": "Members of the footprint.* namespace need tick-level bid/ask volume rows, which a PineForge batch backtest does not load.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1074": {"severity": "error", "area": "support", "message": "{object_name}.{member}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": null, "explanation": "Members of the volume_row.* namespace need tick-level volume rows, which a PineForge batch backtest does not load.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1075": {"severity": "error", "area": "support", "message": "{object_name}.{member}: dividends.* is not available in PineForge — fundamental dividend data is not loaded.", "hint": null, "explanation": "dividends.* fields read fundamental dividend data, which PineForge does not load outside a recorded request.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1076": {"severity": "error", "area": "support", "message": "{object_name}.{member}: earnings.* is not available in PineForge — fundamental earnings data is not loaded.", "hint": null, "explanation": "earnings.* fields read fundamental earnings data, which PineForge does not load outside a recorded request.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1077": {"severity": "error", "area": "support", "message": "{object_name}.{member}: splits.* is not available in PineForge — corporate-action split data is not loaded.", "hint": null, "explanation": "splits.* fields read corporate-action split data, which PineForge does not load outside a recorded request.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1078": {"severity": "error", "area": "support", "message": "{object_name}.{member} is a visual/style constant with no runtime value in PineForge backtests; it is only accepted as an argument to visual calls (plot, plotshape, hline, label.new, table.cell, ...), which PineForge parses and skips.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "A visual or style constant has no value in a backtest; it may only be passed to plotting and drawing calls, which PineForge skips.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1079": {"severity": "error", "area": "support", "message": "{object_name}.{member} is not a Pine alert constant; only alert.freq_all, alert.freq_once_per_bar and alert.freq_once_per_bar_close exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The alert.* member is not one of Pine's alert frequency constants.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1080": {"severity": "error", "area": "support", "message": "{object_name}.{member} is not a barmerge constant; only barmerge.gaps_on, barmerge.gaps_off, barmerge.lookahead_on and barmerge.lookahead_off exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The barmerge.* member is not one of Pine's gaps or lookahead constants.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E1081": {"severity": "error", "area": "support", "message": "syminfo.{member} is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge does not implement this syminfo.* member, so reading it is refused.", "args": {"member": {"kind": "identifier"}}}, - "PF-E1082": {"severity": "error", "area": "support", "message": "request.security parameter ''{kw_name}'' is not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts only a few named parameters in PineForge; this one is refused instead of being silently ignored, so remove it.", "args": {"kw_name": {"kind": "identifier"}}}, - "PF-E1083": {"severity": "error", "area": "support", "message": "Extra positional arguments to request.security are not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts at most five positional arguments (symbol, timeframe, expression, gaps, lookahead); remove the extra ones.", "args": {}}, - "PF-E1084": {"severity": "error", "area": "support", "message": "request.security gaps must be barmerge.gaps_on or barmerge.gaps_off.", "hint": "Codegen only recognizes the barmerge.gaps_* literal; other values are silently treated as gaps_off.", "explanation": "The gaps argument of request.security must be written literally as barmerge.gaps_on or barmerge.gaps_off, the only forms PineForge reads.", "args": {}}, - "PF-E1085": {"severity": "error", "area": "support", "message": "request.security lookahead must be barmerge.lookahead_on or barmerge.lookahead_off.", "hint": "Codegen only recognizes the barmerge.lookahead_* literal; other values are silently treated as lookahead_off.", "explanation": "The lookahead argument of request.security must be written literally as barmerge.lookahead_on or barmerge.lookahead_off, the only forms PineForge reads.", "args": {}}, - "PF-E1086": {"severity": "error", "area": "support", "message": "request.security: {kw_name}={object_name}.{val_member} is not supported. The engine ignores this kwarg, which would silently produce different prices from TradingView.", "hint": "Allowed values: {allowed}.", "explanation": "PineForge ignores request.security's price-adjustment settings, so only no-op values are accepted; others would silently give prices unlike TradingView's.", "args": {"kw_name": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "val_member": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}}, - "PF-E1087": {"severity": "error", "area": "support", "message": "request.security: {kw_name}=... must be a constant member access of the form {kw_name}. (got a non-constant expression).", "hint": "Allowed values: {allowed}.", "explanation": "A request.security price-adjustment setting must be a plain constant of the form name.value (like adjustment.none), not a computed expression.", "args": {"kw_name": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}}, - "PF-E1088": {"severity": "error", "area": "support", "message": "{name} {message} (TradingView: {spelled}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A nz or fixnan call whose arguments match none of TradingView's signatures (unknown name, too many or missing arguments) is refused, as TradingView refuses it.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "spelled": {"kind": "identifier"}}}, - "PF-E1089": {"severity": "error", "area": "support", "message": "ta.{name} {message} (TradingView: {signature}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A ta.* call whose arguments match none of TradingView's signatures (unknown or repeated parameter, too many or missing arguments) is refused.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "signature": {"kind": "identifier"}}}, - "PF-E1090": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}}, - "PF-E1091": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}}, - "PF-E1092": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}}, - "PF-E1093": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}}, - "PF-E1094": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}}, - "PF-E1095": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}}, - "PF-E1096": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}}, - "PF-E1097": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}}, - "PF-E2001": {"severity": "error", "area": "analysis", "message": "Missing PineScript version directive. PineForge supports PineScript v6 only.", "hint": "Add //@version=6 as the first line of your script.", "explanation": "PineForge accepts only Pine v6 scripts; add //@version=6 as the first line.", "args": {}}, - "PF-E2002": {"severity": "error", "area": "analysis", "message": "PineForge supports PineScript v6 only (found //@version={version}).", "hint": "Migrate the script to //@version=6 using TradingView''s editor.", "explanation": "The script declares a Pine version other than 6, which PineForge does not support; migrate it to v6 using TradingView's editor.", "args": {"version": {"kind": "number"}}}, - "PF-E2003": {"severity": "error", "area": "analysis", "message": "Direct temporary-array element call ''{callee_name}()'' resolves to a local or parameter, not a user-defined function.", "hint": null, "explanation": "A function ends by reading a temporary array built from a call such as f(), but f is a local or parameter there, not a user-defined function; rename it.", "args": {"callee_name": {"kind": "identifier"}}}, - "PF-E2004": {"severity": "error", "area": "analysis", "message": "Tuple-return helper wrapper ''{wrapper_name}'' calls later-defined helper ''{callee_name}''; forward tuple-wrapper calls are not supported yet. Move ''{callee_name}'' above ''{wrapper_name}'' before passing the wrapper to request.security().", "hint": null, "explanation": "A function that returns another function's tuple must come after it; define the called helper above the wrapper before passing the wrapper to request.security.", "args": {"wrapper_name": {"kind": "identifier"}, "callee_name": {"kind": "identifier"}}}, - "PF-E2005": {"severity": "error", "area": "analysis", "message": "Recursive direct temporary-array reader cycle is not supported: {cycle}.", "hint": null, "explanation": "Functions that read an element of a temporary array call each other in a cycle; Pine forbids recursion and PineForge cannot emit it.", "args": {"cycle": {"kind": "identifier"}}}, - "PF-E2006": {"severity": "error", "area": "analysis", "message": "Persistent bindings named ''{raw_name}'' still share generated storage across distinct lexical declarations; this declaration shape is not supported yet.", "hint": null, "explanation": "A var declaration reuses a name that another declaration in a different scope also uses, and PineForge would give them one shared storage slot; rename one.", "args": {"raw_name": {"kind": "identifier"}}}, - "PF-E2007": {"severity": "error", "area": "analysis", "message": "A top-level block history binding named ''{name}'' shares raw generated Series state with another lexical declaration; declaration-exact block storage is not supported yet.", "hint": null, "explanation": "A top-level block variable whose history is read shares its name with another declaration, so PineForge cannot keep their histories apart; rename one.", "args": {"name": {"kind": "identifier"}}}, - "PF-E2008": {"severity": "error", "area": "analysis", "message": "A callable history local named ''{name}'' shares raw generated Series state with another lexical declaration; declaration-exact callable storage is not supported yet.", "hint": null, "explanation": "A function-local variable has its history read and shares its name with another declaration, so PineForge cannot keep separate history; rename one.", "args": {"name": {"kind": "identifier"}}}, - "PF-E2009": {"severity": "error", "area": "analysis", "message": "History references on a scalar callable local named ''{raw_name}'' conflict with a persistent map local of the same name in another callable; scoped Series member storage is not implemented yet.", "hint": null, "explanation": "A function-local scalar read with history shares its name with a persistent map variable in another function, which PineForge cannot yet separate; rename one.", "args": {"raw_name": {"kind": "identifier"}}}, - "PF-E2010": {"severity": "error", "area": "analysis", "message": "A top-level block binding named ''{name}'' shadows a direct script binding with history, aggregate, or incompatible typed state; declaration-exact block storage is not supported yet.", "hint": null, "explanation": "A variable declared inside a top-level block reuses the name of a script-level variable with history, a collection or a different type; rename one.", "args": {"name": {"kind": "identifier"}}}, - "PF-E2011": {"severity": "error", "area": "analysis", "message": "Persistent drawing bindings named ''{name}'' in distinct lexical owners would share one generated state member; rename one binding until callable-owned persistent storage is owner-qualified.", "hint": null, "explanation": "Two var-declared drawing objects (line, box, label or linefill) in different scopes share one name and would share one state member; rename one.", "args": {"name": {"kind": "identifier"}}}, - "PF-E2012": {"severity": "error", "area": "analysis", "message": "Persistent drawing state named ''{name}'' collides with a top-level class-member binding; rename one binding until persistent storage is owner-qualified.", "hint": null, "explanation": "A var-declared drawing object shares its name with a top-level script variable, so PineForge would give them one state member; rename one.", "args": {"name": {"kind": "identifier"}}}, - "PF-E2013": {"severity": "error", "area": "analysis", "message": "Persistent drawing binding ''{name}'' shadows an ancestor callable parameter or local; rename one binding until callable-owned persistent storage has lexical owner qualification.", "hint": null, "explanation": "A var-declared drawing object inside a function reuses the name of an enclosing parameter or local; rename one.", "args": {"name": {"kind": "identifier"}}}, - "PF-E2014": {"severity": "error", "area": "analysis", "message": "Callable TA ownership propagation did not converge; recursive stateful call paths are unsupported.", "hint": null, "explanation": "PineForge could not work out which functions own the ta.* state because stateful functions call each other recursively; remove the recursion.", "args": {}}, - "PF-E2015": {"severity": "error", "area": "analysis", "message": "Cannot safely specialize untyped parameter ''{param}'' of callable ''{callee}'': distinct primitive types collapse onto the same written-call variant cs{cs_idx}. Inline the calls or declare an explicit parameter type.", "hint": null, "explanation": "An untyped parameter receives different primitive types (such as int and float) from calls PineForge cannot tell apart; declare its type or inline the calls.", "args": {"param": {"kind": "identifier"}, "callee": {"kind": "identifier"}, "cs_idx": {"kind": "number"}}}, - "PF-E2016": {"severity": "error", "area": "analysis", "message": "Cannot infer the per-callsite primitive type of history parameter ''{param}'' in callable ''{name}'' variant cs{cs_idx}; declare its type explicitly.", "hint": null, "explanation": "A function reads history of a parameter whose type PineForge cannot infer at this call; declare the parameter type explicitly.", "args": {"param": {"kind": "identifier"}, "name": {"kind": "identifier"}, "cs_idx": {"kind": "number"}}}, - "PF-E2017": {"severity": "error", "area": "analysis", "message": "request.security timeframe parameter ''{tf_param}'' of function ''{containing}'' is passed a timeframe that reads the chart bar (''{series}''): PineForge registers each call site''s timeframe before the first bar.", "hint": null, "explanation": "A timeframe passed to a helper's request.security reads chart-bar data, but PineForge fixes it before the first bar; pass a constant or input timeframe instead.", "args": {"tf_param": {"kind": "identifier"}, "containing": {"kind": "identifier"}, "series": {"kind": "identifier"}}}, - "PF-E2018": {"severity": "error", "area": "analysis", "message": "Import is not supported: ''{import_path}''", "hint": null, "explanation": "The script imports a library PineForge cannot inline, usually because its source was not supplied or pinned, or it is not open source.", "args": {"import_path": {"kind": "identifier"}}}, - "PF-E2019": {"severity": "error", "area": "analysis", "message": "Import is not supported: ''{import_path}'': {reason}", "hint": null, "explanation": "The script imports a library PineForge cannot inline, usually because its source was not supplied or pinned, or it is not open source.", "args": {"import_path": {"kind": "identifier"}, "reason": {"kind": "text"}}}, - "PF-E2020": {"severity": "error", "area": "analysis", "message": "Undefined variable: ''{name}''", "hint": null, "explanation": "The script assigns a new value (:=) to a name that was never declared; declare the variable first.", "args": {"name": {"kind": "identifier"}}}, - "PF-E2021": {"severity": "error", "area": "analysis", "message": "PineScript has no ta.sum; use math.sum(source, length) for rolling sum", "hint": null, "explanation": "ta.sum does not exist in Pine v6; use math.sum(source, length) for a rolling sum.", "args": {}}, - "PF-E2022": {"severity": "error", "area": "analysis", "message": "{name}.copy(...) expects exactly one object argument", "hint": null, "explanation": "The functional copy form Type.copy(obj) needs exactly one object argument and no named arguments.", "args": {"name": {"kind": "type"}}}, - "PF-E2023": {"severity": "error", "area": "analysis", "message": "{receiver_spec_name}.copy() expects no arguments", "hint": null, "explanation": "obj.copy() on a user-defined type takes no arguments; call it with empty parentheses.", "args": {"receiver_spec_name": {"kind": "type"}}}, - "PF-E2024": {"severity": "error", "area": "analysis", "message": "{key}: argument ''{name}'' passed both positionally and by keyword", "hint": null, "explanation": "A call to a typed method gives the same parameter both by position and by keyword; pass it only once.", "args": {"key": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-E2025": {"severity": "error", "area": "analysis", "message": "{key}: missing required argument ''{name}''", "hint": null, "explanation": "A call to a typed method omits a parameter that has no default value; pass an argument for it.", "args": {"key": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-E2026": {"severity": "error", "area": "analysis", "message": "{key}: too many positional arguments (expected {names_count}, got {args_count})", "hint": null, "explanation": "A call to a typed method passes more positional arguments than the method declares; remove the extra arguments.", "args": {"key": {"kind": "identifier"}, "names_count": {"kind": "number"}, "args_count": {"kind": "number"}}}, - "PF-E2027": {"severity": "error", "area": "analysis", "message": "{key}: unknown keyword argument ''{name}''", "hint": null, "explanation": "A call to a typed method uses a keyword argument name that the method does not declare; check the parameter spelling.", "args": {"key": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-E2028": {"severity": "error", "area": "analysis", "message": "History references on map IDs are not supported in PineForge; map rollback uses identity snapshots rather than Series.", "hint": null, "explanation": "PineForge cannot read earlier-bar history of a map with the [] operator; read the map directly or keep earlier values in other variables.", "args": {}}, - "PF-E2029": {"severity": "error", "area": "analysis", "message": "History references on map-bearing UDTs or collections are not supported in PineForge; their Series value copy would retain live map aliases.", "hint": null, "explanation": "PineForge cannot read earlier-bar history of a user-defined type or collection that contains a map, because the copy would keep live map references.", "args": {}}, - "PF-E2030": {"severity": "error", "area": "analysis", "message": "User function ''{owner}'' is called with incompatible map parameter types; PineForge cannot emit multiple map specializations for one untyped function.", "hint": null, "explanation": "A function with untyped parameters is called with different map types, and PineForge can generate only one map specialization per function; declare the type.", "args": {"owner": {"kind": "identifier"}}}, - "PF-E2031": {"severity": "error", "area": "analysis", "message": "History references on scalar local or loop bindings that shadow a map ID are not supported until PineForge can allocate a lexically scoped Series buffer for that binding.", "hint": null, "explanation": "A local or loop variable that reuses a map's name is read with history ([n]), which PineForge cannot buffer yet; rename the variable.", "args": {}}, - "PF-E2032": {"severity": "error", "area": "analysis", "message": "{receiver}.{member}[...]: TradingView refuses the history-referencing operator on fields of user-defined types (CE10290).", "hint": "Read the field of the object''s history: ({receiver}[1]).{member}.", "explanation": "TradingView refuses the [] history operator on a field of a user-defined type; read the field of the object's history instead, as (obj[1]).field.", "args": {"receiver": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E2033": {"severity": "error", "area": "analysis", "message": "request.security tuple-return helpers support two or more int, float, bool or string elements; inferred {tuple_size} element(s) [{inferred_types}]", "hint": null, "explanation": "A tuple-returning helper called inside request.security must yield two or more int, float, bool or string elements; its inferred shape did not qualify.", "args": {"tuple_size": {"kind": "number"}, "inferred_types": {"kind": "type"}}}, - "PF-E2034": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf has unknown parameter(s): {unknown}. Supported parameters: {param_names}", "hint": null, "explanation": "request.security_lower_tf was called with keyword arguments it does not accept; use only the supported parameters listed.", "args": {"unknown": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, - "PF-E2035": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf requires an expression argument", "hint": null, "explanation": "request.security_lower_tf was called without its expression argument, so there is nothing to evaluate on the lower timeframe.", "args": {}}, - "PF-E2036": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf does not support tuple expressions yet. Issue separate request.security_lower_tf calls for each series.", "hint": null, "explanation": "request.security_lower_tf cannot return a tuple; issue one request.security_lower_tf call for each series you need.", "args": {}}, - "PF-E2037": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf element type ''{element_label}'' is not yet supported. Supported element types: float, int, bool. UDT / color / string element types are out of scope.", "hint": null, "explanation": "request.security_lower_tf can only collect float, int or bool values per intrabar; string, color and object expressions are not supported.", "args": {"element_label": {"kind": "type"}}}, - "PF-E2038": {"severity": "error", "area": "analysis", "message": "Enum ''{ename}'' must be declared above this input.enum() call (or the name is misspelled).", "hint": null, "explanation": "input.enum() names an enum that is not declared above the call (or is misspelled); declare the enum first or fix the name.", "args": {"ename": {"kind": "identifier"}}}, - "PF-E2039": {"severity": "error", "area": "analysis", "message": "Cannot materialize callable state for unknown function ''{func_name}''.", "hint": null, "explanation": "Internal error: PineForge could not find a user function or method whose indicator state it needed to copy; this is a transpiler bug to report.", "args": {"func_name": {"kind": "identifier"}}}, - "PF-E3001": {"severity": "error", "area": "request-security", "message": "request.security timeframe ''{name}'' cannot be resolved before the first bar: PineForge registers every requested timeframe before the script runs.", "hint": "Pass a literal, an input or a global to the helper that holds request.security.", "explanation": "The timeframe given to request.security is a name whose value PineForge cannot compute before the first bar; use a literal, an input or a global.", "args": {"name": {"kind": "identifier"}}}, - "PF-E3002": {"severity": "error", "area": "request-security", "message": "request.security timeframe expression cannot be resolved before the first bar: PineForge registers every requested timeframe before the script runs.", "hint": "Pass a literal, an input or a global to the helper that holds request.security.", "explanation": "The timeframe expression given to request.security cannot be computed before the first bar; use a literal, an input or a global.", "args": {}}, - "PF-E3003": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch arms must contain one expression", "hint": "Compute multi-statement timeframe logic before the request.security call or rewrite it as pure switch arms.", "explanation": "A switch that picks a request.security timeframe must have exactly one expression in each arm; compute multi-statement logic beforehand.", "args": {}}, - "PF-E3004": {"severity": "error", "area": "request-security", "message": "request.security_lower_tf timeframe switch arm is na", "hint": "TradingView reads an na timeframe as the chart''s, which the engine''s lower-timeframe request rejects: spell a strictly finer timeframe.", "explanation": "A switch arm in a request.security_lower_tf timeframe is na, which a lower-timeframe request rejects; spell a strictly finer timeframe.", "args": {}}, - "PF-E3005": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch arm is na", "hint": "TradingView reads an na timeframe as the chart''s: spell the arm timeframe.period.", "explanation": "A switch arm in a request.security timeframe is na, which TradingView reads as the chart's timeframe; write timeframe.period instead.", "args": {}}, - "PF-E3006": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch arm could not be resolved at setup", "hint": null, "explanation": "A switch arm used as a request.security timeframe could not be evaluated, because PineForge registers every request before the first bar.", "args": {}}, - "PF-E3007": {"severity": "error", "area": "request-security", "message": "request.security_lower_tf timeframe switch requires a default arm", "hint": "When no arm matches, TradingView reads the chart''s timeframe (one intrabar per chart bar); the engine''s lower-timeframe request needs a strictly finer timeframe.", "explanation": "A switch picking a request.security_lower_tf timeframe needs a default arm; without one TradingView uses the chart's timeframe, which is rejected.", "args": {}}, - "PF-E3008": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch selector could not be resolved at setup", "hint": null, "explanation": "The selector of a switch that picks a request.security timeframe could not be evaluated before the first bar; use literals, inputs or timeframe values.", "args": {}}, - "PF-E3009": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch case could not be resolved at setup", "hint": null, "explanation": "A case value in a switch that picks a request.security timeframe could not be evaluated before the first bar; use literals, inputs or timeframe values.", "args": {}}, - "PF-E3010": {"severity": "error", "area": "request-security", "message": "request.security timeframe parameter ''{param_name}'' of ''{func_name}'' has no single timeframe across its call sites", "hint": "Pass the timeframe as a positional literal, input or global.", "explanation": "A helper's timeframe parameter used by request.security receives different timeframes at its call sites; pass one literal, input or global.", "args": {"param_name": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}}, - "PF-E3011": {"severity": "error", "area": "request-security", "message": "request.security helper-parameter history currently requires a direct OHLC/time bar-series binding", "hint": null, "explanation": "History of a helper parameter inside request.security is only supported when the argument is a plain bar series such as close or time.", "args": {}}, - "PF-E3012": {"severity": "error", "area": "request-security", "message": "request.security payload reads ''{name}'' with history and outside the helper block its call is lowered in: its state would advance twice a bar", "hint": "Read ''{name}'' once at the helper''s top level and use that local in the block.", "explanation": "A global holding a stateful call is read with history both inside and outside the helper block that lowers it, so its state would advance twice per bar.", "args": {"name": {"kind": "identifier"}}}, - "PF-E3013": {"severity": "error", "area": "request-security", "message": "Internal: request.security string helper state without its declared series map", "hint": null, "explanation": "Internal error: string state in a request.security helper was used before its series storage was declared; this is a transpiler bug to report.", "args": {}}, - "PF-E3014": {"severity": "error", "area": "request-security", "message": "Internal security helper emission requested for a non-linear helper plan", "hint": null, "explanation": "Internal error: PineForge tried to emit a request.security helper as straight-line code although its shape is not; this is a transpiler bug to report.", "args": {}}, - "PF-E3015": {"severity": "error", "area": "request-security", "message": "request.security helper-local var state currently supports only int, float, bool and string values", "hint": "Hoist collection, UDT, or drawing state outside request.security().", "explanation": "A var inside a request.security helper can only hold int, float, bool or string values; move collection, object or drawing state outside the request.", "args": {}}, - "PF-E3016": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers may only assign to local identifier temporaries", "hint": null, "explanation": "A multi-statement request.security helper can only assign to plain local variables, not to fields, array elements or other targets.", "args": {}}, - "PF-E3017": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helper assignment target must be declared before use", "hint": null, "explanation": "A multi-statement request.security helper assigns to a variable it never declared; declare the local before assigning to it.", "args": {}}, - "PF-E3018": {"severity": "error", "area": "request-security", "message": "request.security helper tuple declaration: a string element read with history is not supported", "hint": "Declare the element with its own string variable.", "explanation": "A string element of a tuple declared in a request.security helper is read with history, which is unsupported; declare it as its own string variable.", "args": {}}, - "PF-E3019": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers may only use local declarations, assignments, and if-branches before the final expression", "hint": null, "explanation": "A multi-statement request.security helper may contain only local declarations, assignments, if-branches and loops before its final expression.", "args": {}}, - "PF-E3020": {"severity": "error", "area": "request-security", "message": "request.security helper while-loop conditions must be plain expressions of the helper''s values", "hint": null, "explanation": "A while-loop condition in a request.security helper must be a plain expression of the helper's own values.", "args": {}}, - "PF-E3021": {"severity": "error", "area": "request-security", "message": "request.security helper calls must target named user-defined functions", "hint": null, "explanation": "request.security can only inline calls to named user-defined functions or typed methods, not other call forms.", "args": {}}, - "PF-E3022": {"severity": "error", "area": "request-security", "message": "request.security helper function ''{func_name}'' is not defined", "hint": null, "explanation": "A function called while inlining a request.security helper is not a user-defined function PineForge knows, so it cannot be inlined.", "args": {"func_name": {"kind": "identifier"}}}, - "PF-E3023": {"severity": "error", "area": "request-security", "message": "request.security helper call has unknown parameter(s): {unknown_list}", "hint": null, "explanation": "A helper called inside request.security is given keyword arguments that are not among the function's parameters.", "args": {"unknown_list": {"kind": "identifier"}}}, - "PF-E3024": {"severity": "error", "area": "request-security", "message": "request.security helper calls must bind every parameter explicitly", "hint": null, "explanation": "A helper called inside request.security must be given an argument for every parameter; omitted defaults are not filled in there.", "args": {}}, - "PF-E3025": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers must end with a final expression result", "hint": null, "explanation": "A multi-statement request.security helper must end with an expression, declaration or assignment that gives its result.", "args": {}}, - "PF-E3026": {"severity": "error", "area": "request-security", "message": "request.security does not support multi-statement helpers with control flow", "hint": "Inline a straight-line helper body or hoist the control-flow helper outside request.security().", "explanation": "request.security cannot inline a multi-statement helper that contains for-in, switch, break or continue; inline a straight-line body or move it out.", "args": {}}, - "PF-E3027": {"severity": "error", "area": "request-security", "message": "request.security does not support helper-local varip state", "hint": "Use var for requested-context bar state; varip tick state is unavailable in batch backtests.", "explanation": "varip state is not available in a request.security helper; use var instead, since tick-level varip state does not exist in batch backtests.", "args": {}}, - "PF-E3028": {"severity": "error", "area": "request-security", "message": "request.security helper-local var declarations inside conditional control flow are not supported", "hint": "Declare persistent requested-context state at the helper''s top level.", "explanation": "A var declared inside an if or other conditional block of a request.security helper is not supported; declare it at the helper's top level.", "args": {}}, - "PF-E3029": {"severity": "error", "area": "request-security", "message": "request.security method TA constructor argument ''{cpp}'' is not a stable per-run scalar", "hint": null, "explanation": "A typed method called inside request.security builds a TA indicator whose argument is not fixed for the whole run; use a constant or input value.", "args": {"cpp": {"kind": "identifier"}}}, - "PF-E3030": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a TA call", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot contain a ta.* call; compute it before the loop, on the requested bar.", "args": {}}, - "PF-E3031": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a TA call (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a ta.* call through a parameter or global it reads; compute that value before the loop.", "args": {"via": {"kind": "text"}}}, - "PF-E3032": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a user function call", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot call a user-defined function; compute the value before the loop.", "args": {}}, - "PF-E3033": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a user function call (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a user function call through a parameter or global it reads; compute that value before the loop.", "args": {"via": {"kind": "text"}}}, - "PF-E3034": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a var declaration", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot declare a var; compute the value before the loop.", "args": {}}, - "PF-E3035": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a var declaration (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a var declaration through a parameter or global it reads; compute that value before the loop.", "args": {"via": {"kind": "text"}}}, - "PF-E3036": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a {namespace}.* call", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot call request.* or strategy.* functions; compute the value before the loop.", "args": {"namespace": {"kind": "identifier"}}}, - "PF-E3037": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a {namespace}.* call (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a request.* or strategy.* call through a parameter or global it reads; compute it before the loop.", "args": {"namespace": {"kind": "identifier"}, "via": {"kind": "text"}}}, - "PF-E3038": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold the local ''{name}'', which is read with history", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper cannot read a local that is also read with history; compute that local before the loop.", "args": {"name": {"kind": "identifier"}}}, - "PF-E3039": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold the local ''{name}'', which is read with history (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a local read with history through a parameter or global; compute that local before the loop.", "args": {"name": {"kind": "identifier"}, "via": {"kind": "text"}}}, - "PF-E3040": {"severity": "error", "area": "request-security", "message": "request.security mutable global rebinding does not support top-level switch", "hint": "Rewrite the switch as if/else assignments before passing the value to request.security().", "explanation": "A global read by the request.security expression is rebound inside a top-level switch, which PineForge cannot replay; rewrite it as if/else assignments.", "args": {}}, - "PF-E3041": {"severity": "error", "area": "request-security", "message": "request.security mutable global rebinding does not support top-level loops", "hint": "Move loop-driven mutable state out of request.security() expressions or rewrite it as direct assignments.", "explanation": "A global read by the request.security expression is rebound inside a top-level loop, which PineForge cannot replay; use direct assignments or move it out.", "args": {}}, - "PF-E3042": {"severity": "error", "area": "request-security", "message": "request.security does not support TA constructor args that depend on rebound mutable globals", "hint": "Keep TA constructor arguments immutable/simple inside request.security(), or hoist the TA call outside the security expression.", "explanation": "A TA length or other indicator argument inside request.security depends on a global the script reassigns; keep it constant or compute the TA outside.", "args": {}}, - "PF-E3043": {"severity": "error", "area": "request-security", "message": "History of a {kind} reference inside a request.security expression is not supported in PineForge: TradingView reads the references the variable held on the requested timeframe''s bars, which PineForge does not keep.", "hint": "Request the field values the expression needs (request.security(..., obj.field)) and read their history on the chart.", "explanation": "request.security cannot read the history of a user-defined type or drawing reference, because PineForge keeps no references from the requested bars.", "args": {"kind": {"kind": "type"}}}, - "PF-E3044": {"severity": "error", "area": "request-security", "message": "request.security payload reads ''{name}'', an element of a tuple declaration it cannot re-evaluate", "hint": null, "explanation": "The request.security expression reads a name bound by a tuple declaration that PineForge cannot re-evaluate on the requested bar.", "args": {"name": {"kind": "identifier"}}}, - "PF-E3045": {"severity": "error", "area": "request-security", "message": "request.security payload reads ''{name}'', an element of a TA tuple it does not compute once per requested bar", "hint": null, "explanation": "The request.security expression reads an element of a TA tuple that PineForge does not compute once per requested bar.", "args": {"name": {"kind": "identifier"}}}, - "PF-E3046": {"severity": "error", "area": "request-security", "message": "request.security() bar-field history index must be non-negative", "hint": null, "explanation": "A negative history offset on a bar series such as close[-1] is not allowed inside request.security.", "args": {}}, - "PF-E3047": {"severity": "error", "area": "request-security", "message": "request.security payload reads the history of ''{object_name}'', an element of a tuple declaration", "hint": null, "explanation": "The request.security expression reads the history of a name bound by a tuple declaration, which PineForge cannot do on the requested bars.", "args": {"object_name": {"kind": "identifier"}}}, - "PF-E3048": {"severity": "error", "area": "request-security", "message": "request.security payload reads the string global ''{object_name}'' with history, which the requested clock does not keep", "hint": null, "explanation": "A string global read with history inside request.security is not supported, because the requested clock keeps no string history.", "args": {"object_name": {"kind": "identifier"}}}, - "PF-E3049": {"severity": "error", "area": "request-security", "message": "request.security() TA history index must be a literal integer (e.g. ta.ema(close, 55)[1])", "hint": "An int computed from inputs and literals is admitted; a series index is not.", "explanation": "A history offset on a TA call inside request.security must be an integer literal or a number computed from inputs and literals, not a series.", "args": {}}, - "PF-E3050": {"severity": "error", "area": "request-security", "message": "request.security() TA history index must be non-negative", "hint": null, "explanation": "A negative history offset on a TA call inside request.security is not allowed.", "args": {}}, - "PF-E3051": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helper TA history is not supported", "hint": "Use a single-expression helper for TA history offsets.", "explanation": "A TA history offset inside a multi-statement request.security helper is not supported; use a single-expression helper.", "args": {}}, - "PF-E3052": {"severity": "error", "area": "request-security", "message": "request.security helper functions must not recurse while building a security context", "hint": null, "explanation": "A request.security helper calls itself, directly or through other helpers, which PineForge cannot inline; remove the recursion.", "args": {}}, - "PF-E3053": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers require statement-capable security evaluation context", "hint": null, "explanation": "A multi-statement helper is used inside a request.security expression at a spot where PineForge cannot emit statements, so it cannot be inlined there.", "args": {}}, - "PF-E3054": {"severity": "error", "area": "request-security", "message": "the payload reads ''{func_name}'' on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"func_name": {"kind": "identifier"}}}, - "PF-E3055": {"severity": "error", "area": "request-security", "message": "the payload reads ''{namespace}.{func_name}'' on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"namespace": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}}, - "PF-E3056": {"severity": "error", "area": "request-security", "message": "the payload reads ''{name}'' on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"name": {"kind": "identifier"}}}, - "PF-E3057": {"severity": "error", "area": "request-security", "message": "the payload reads a user call it cannot inline on the chart''s bar", "hint": null, "explanation": "A request.security payload reads something PineForge would evaluate on the chart's bar, where TradingView evaluates it on the requested bar, so it is refused.", "args": {}}, - "PF-E3058": {"severity": "error", "area": "request-security", "message": "the payload reads a {node_type} on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"node_type": {"kind": "identifier"}}}, - "PF-E3059": {"severity": "error", "area": "request-security", "message": "the payload reads history it does not keep on the requested clock on the chart''s bar", "hint": null, "explanation": "A request.security payload reads something PineForge would evaluate on the chart's bar, where TradingView evaluates it on the requested bar, so it is refused.", "args": {}}, - "PF-E3060": {"severity": "error", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', an element of a tuple declaration", "hint": null, "explanation": "The request.security expression reads the history of a name bound by a tuple declaration, which PineForge cannot do on the requested bars.", "args": {"name": {"kind": "identifier"}}}, - "PF-E3061": {"severity": "error", "area": "request-security", "message": "request.security helper switch arms must each be one expression", "hint": "Compute a multi-statement arm in its own helper, or on the chart.", "explanation": "A switch used as a request.security helper's value must have a single expression in each arm; move multi-statement arms into their own helper.", "args": {}}, - "PF-E3062": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: helper ''{func}'' {problem}", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A helper holding a request.security cannot have its symbol and timeframe resolved per call path, because it is overloaded or called from a method.", "args": {"request_name": {"kind": "identifier"}, "func": {"kind": "identifier"}, "problem": {"kind": "text"}}}, - "PF-E3063": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{expr_name}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}}, - "PF-E3064": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{expr}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr": {"kind": "identifier"}}}, - "PF-E3065": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{func}'' declares ''{names}''", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "func": {"kind": "identifier"}, "names": {"kind": "identifier"}}}, - "PF-E3066": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{name}'' is not a value the requested bars recompute", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-E3067": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{name}'' is reassigned or declared var", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-E3068": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: a {node_type} is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "node_type": {"kind": "identifier"}}}, - "PF-E3069": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: it holds a request.{request_name2} call", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "request_name2": {"kind": "identifier"}}}, - "PF-E3070": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: it reads ''{expr_name}'', a series", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}}, - "PF-E3071": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: its value is too large", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}}}, - "PF-E3072": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: parameter ''{binding}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "binding": {"kind": "identifier"}}}, - "PF-E3073": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: parameter ''{param}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "param": {"kind": "identifier"}}}, - "PF-E3074": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the helpers reach it through too many call paths", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}}}, - "PF-E3075": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the method call {expr}", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr": {"kind": "identifier"}}}, - "PF-E3076": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the user function call {callee_name}(...)", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "callee_name": {"kind": "identifier"}}}, - "PF-E3077": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the value of ''{param}'' is not lowered on the requested bars", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "param": {"kind": "identifier"}}}, - "PF-E3078": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{expr_name}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}}, - "PF-E3079": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{expr}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr": {"kind": "identifier"}}}, - "PF-E3080": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{func}'' declares ''{names}''", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "func": {"kind": "identifier"}, "names": {"kind": "identifier"}}}, - "PF-E3081": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{name}'' is not a value the requested bars recompute", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-E3082": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{name}'' is reassigned or declared var", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-E3083": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: a {node_type} is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "node_type": {"kind": "identifier"}}}, - "PF-E3084": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: it holds a request.{request_name2} call", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe holds another request, which PineForge cannot compute before the first bar.", "args": {"request_name": {"kind": "identifier"}, "request_name2": {"kind": "identifier"}}}, - "PF-E3085": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: it reads ''{expr_name}'', a series", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}}, - "PF-E3086": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: its value is too large", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The value a request's context reads is too large for PineForge to resolve before the first bar.", "args": {"request_name": {"kind": "identifier"}}}, - "PF-E3087": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: parameter ''{binding}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A helper call leaves out the parameter the request's symbol or timeframe reads, so PineForge cannot resolve the request's context.", "args": {"request_name": {"kind": "identifier"}, "binding": {"kind": "identifier"}}}, - "PF-E3088": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: parameter ''{param}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A helper call leaves out the parameter the request's symbol or timeframe reads, so PineForge cannot resolve the request's context.", "args": {"request_name": {"kind": "identifier"}, "param": {"kind": "identifier"}}}, - "PF-E3089": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the helpers reach it through too many call paths", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The helpers holding this request are reached through too many call paths for PineForge to resolve each one's symbol and timeframe.", "args": {"request_name": {"kind": "identifier"}}}, - "PF-E3090": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the method call {expr}", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr": {"kind": "identifier"}}}, - "PF-E3091": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the user function call {callee_name}(...)", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "callee_name": {"kind": "identifier"}}}, - "PF-E3092": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the value of ''{param}'' is not lowered on the requested bars", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "param": {"kind": "identifier"}}}, - "PF-E4001": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' has no valid sha256 in {where}", "hint": null, "explanation": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "text"}}}, - "PF-E4002": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not among the libraries passed to transpile()", "hint": null, "explanation": "The imported library was not among the library sources supplied to the transpiler, so it cannot be inlined; supply its source text.", "args": {"path": {"kind": "identifier"}}}, - "PF-E4003": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not open-source (access ''{access}''); PineForge inlines open libraries only", "hint": null, "explanation": "The library's manifest entry says it is not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "access": {"kind": "identifier"}}}, - "PF-E4004": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not open-source (access ''{indexed_access}'' in libraries.json); PineForge inlines open libraries only", "hint": null, "explanation": "The library index marks this library as not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "indexed_access": {"kind": "identifier"}}}, - "PF-E4005": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not pinned by this script''s requests manifest ({where})", "hint": null, "explanation": "The script's requests manifest does not pin this imported library, so PineForge will not use any other source for it; add the library to the manifest.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "identifier"}}}, - "PF-E4006": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' source does not match its pinned sha256 {sha}... (found {found_sha}...)", "hint": null, "explanation": "The library source that was found does not match the SHA-256 hash pinned in the manifest, so PineForge refuses to use it.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "found_sha": {"kind": "identifier"}}}, - "PF-E4007": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' source is missing (sha256 {sha}... under ${requests_env}/{slug_dir_name}/files and ${libraries_env})", "hint": null, "explanation": "No file matching the library's pinned SHA-256 hash was found in the configured directories, so its source is missing.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "requests_env": {"kind": "identifier"}, "slug_dir_name": {"kind": "identifier"}, "libraries_env": {"kind": "identifier"}}}, - "PF-E4008": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' source is not UTF-8 text", "hint": null, "explanation": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script.", "args": {"path": {"kind": "identifier"}}}, - "PF-E4009": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': no library sources are configured", "hint": null, "explanation": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script.", "args": {"path": {"kind": "identifier"}}}, - "PF-E4010": {"severity": "error", "area": "libraries", "message": "library ''{path}'' spells ''{clash}'', a name PineForge gave to an inlined definition", "hint": null, "explanation": "An imported library uses a name PineForge generates for its own inlined definitions, so the library cannot be inlined without a name clash.", "args": {"path": {"kind": "identifier"}, "clash": {"kind": "identifier"}}}, - "PF-E4011": {"severity": "error", "area": "libraries", "message": "library ''{path}'' defines ''{name}'' {defs_count} times (overloads); PineForge does not inline an overloaded library function", "hint": null, "explanation": "The library defines this function several times (overloads) in a way PineForge cannot resolve, so it will not inline it; call a non-overloaded function.", "args": {"path": {"kind": "identifier"}, "name": {"kind": "identifier"}, "defs_count": {"kind": "number"}}}, - "PF-E4012": {"severity": "error", "area": "libraries", "message": "no overload of ''{name}'' of library ''{path}'' takes the arguments of this call", "hint": null, "explanation": "None of the library function's overloads accepts the arguments in this call; check the number of arguments and any keyword names.", "args": {"name": {"kind": "identifier"}, "path": {"kind": "identifier"}}}, - "PF-E4013": {"severity": "error", "area": "libraries", "message": "library ''{path}'' does not export ''{member}''", "hint": null, "explanation": "The name exists in the imported library but is not exported, so the script cannot use it through the import; use an exported name.", "args": {"path": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E4014": {"severity": "error", "area": "libraries", "message": "library ''{path}'' does not export ''{member}'': it has no ''{member}''", "hint": null, "explanation": "The imported library has no such name at all; check the spelling of the member you access through the import alias.", "args": {"path": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E4015": {"severity": "error", "area": "libraries", "message": "''{token}'' is not a type of library ''{targets}''", "hint": null, "explanation": "A type written as alias.Type is not an exported type or enum of that library; check the type's name and that the library exports it.", "args": {"token": {"kind": "identifier"}, "targets": {"kind": "identifier"}}}, - "PF-E4016": {"severity": "error", "area": "libraries", "message": "library ''{path}'': a {statement} inside a function is not supported", "hint": null, "explanation": "A function in an imported library contains a nested declaration (function, method, type, enum, import or script declaration), which PineForge cannot inline.", "args": {"path": {"kind": "identifier"}, "statement": {"kind": "vocab", "values": ["EnumDecl", "FuncDef", "ImportStmt", "MethodDef", "StrategyDecl", "TypeDecl"]}}}, - "PF-E4017": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{targets}'' is a {kind}, not a value", "hint": null, "explanation": "The script reads a library function or method as a plain value; only exported constants, types and enums can be read that way, so call it instead.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["function", "method"]}}}, - "PF-E4018": {"severity": "error", "area": "libraries", "message": "library method ''{member}'' called without its receiver as the first positional argument", "hint": null, "explanation": "A library method was called through its import alias without the receiver as the first argument; pass the receiver first or call it as receiver.method().", "args": {"member": {"kind": "identifier"}}}, - "PF-E4019": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{targets}'' is a {kind}, not a function", "hint": null, "explanation": "The script calls an exported library type or constant like a function; only exported functions and methods can be called, so use it as a type or value.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["const", "type"]}}}, - "PF-E4020": {"severity": "error", "area": "libraries", "message": "method ''{member}'' is exported by {exporters_count} imported libraries; a keyword argument cannot be bound to one", "hint": null, "explanation": "Several imported libraries export a method with this name, so a call that uses keyword arguments is ambiguous; pass the arguments by position.", "args": {"member": {"kind": "identifier"}, "exporters_count": {"kind": "number"}}}, - "PF-E4021": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{main_targets}'' is a {kind}, not a value", "hint": null, "explanation": "The script reads a library function or method as a plain value; only exported constants, types and enums can be read that way, so call it instead.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "main_targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["function", "method"]}}}, - "PF-E4022": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{main_targets}'' is a {kind}, not a function", "hint": null, "explanation": "The script calls an exported library type or constant like a function; only exported functions and methods can be called, so use it as a type or value.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "main_targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["const", "type"]}}}, - "PF-E4023": {"severity": "error", "area": "libraries", "message": "import alias ''{alias}'' is used by two imports", "hint": null, "explanation": "Two imports use the same alias, so names like alias.member would be ambiguous; give each import its own alias.", "args": {"alias": {"kind": "identifier"}}}, - "PF-E4024": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{import_path}'': its alias ''{alias}'' is a built-in namespace other than ta, math or str", "hint": null, "explanation": "The import's alias is a built-in namespace other than ta, math or str, which PineForge does not allow; choose a different alias.", "args": {"import_path": {"kind": "identifier"}, "alias": {"kind": "identifier"}}}, - "PF-E4025": {"severity": "error", "area": "libraries", "message": "import alias ''{alias}'' is also declared as a variable, parameter or function", "hint": null, "explanation": "The import alias is also the name of a variable, parameter or function in the script, which would make the alias ambiguous; rename one of them.", "args": {"alias": {"kind": "identifier"}}}, - "PF-E4026": {"severity": "error", "area": "libraries", "message": "method ''{name}'' of library ''{path}'' has the same receiver type as a method of {other}", "hint": null, "explanation": "Two methods share a name and receiver type, one in this library and one in the script or another library, so one would be unreachable.", "args": {"name": {"kind": "identifier"}, "path": {"kind": "identifier"}, "other": {"kind": "text"}}}, - "PF-E4027": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is //@version=5: its function reached from a request.{callee_member}() payload would run outside v5''s rules there", "hint": null, "explanation": "A function from a Pine v5 library is reached from a request.*() expression, where PineForge cannot apply v5 rules, so it is refused.", "args": {"path": {"kind": "identifier"}, "callee_member": {"kind": "identifier"}}}, - "PF-E4028": {"severity": "error", "area": "libraries", "message": "library ''{path}'' has {found}; PineForge inlines v5 and v6 libraries only", "hint": null, "explanation": "The imported library has no //@version line or a version other than 5 or 6; PineForge inlines only version 5 and 6 libraries.", "args": {"path": {"kind": "identifier"}, "found": {"kind": "text"}}}, - "PF-E4029": {"severity": "error", "area": "libraries", "message": "''{path}'' is not a library: it has {found}, not one library() declaration", "hint": null, "explanation": "The imported source is not a library: it must hold exactly one library() declaration, but it has none or a different kind of declaration.", "args": {"path": {"kind": "identifier"}, "found": {"kind": "text"}}}, - "PF-E4030": {"severity": "error", "area": "libraries", "message": "library ''{path}'' has a malformed import: ''{path2}''", "hint": null, "explanation": "An import inside the library is malformed (it lacks a version or an alias), so PineForge cannot follow it.", "args": {"path": {"kind": "identifier"}, "path2": {"kind": "identifier"}}}, - "PF-E4031": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is //@version=5: {exc}", "hint": null, "explanation": "A Pine v5 library uses a v5 behaviour that PineForge does not implement, so the library is refused; the reason names the construct.", "args": {"path": {"kind": "identifier"}, "exc": {"kind": "text"}}}, - "PF-E4032": {"severity": "error", "area": "libraries", "message": "no library sources are configured", "hint": null, "explanation": "No library sources were given to the transpiler and none are configured in the environment, so imports cannot be resolved.", "args": {}}, - "PF-E4033": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not among the libraries passed to transpile()", "hint": null, "explanation": "The imported library was not among the library sources supplied to the transpiler, so it cannot be inlined; supply its source text.", "args": {"path": {"kind": "identifier"}}}, - "PF-E4034": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not pinned by this script''s requests manifest ({where})", "hint": null, "explanation": "The script's requests manifest does not pin this imported library, so PineForge will not use any other source for it; add the library to the manifest.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "identifier"}}}, - "PF-E4035": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not open-source (access ''{access}''); PineForge inlines open libraries only", "hint": null, "explanation": "The library's manifest entry says it is not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "access": {"kind": "identifier"}}}, - "PF-E4036": {"severity": "error", "area": "libraries", "message": "library ''{path}'' has no valid sha256 in {where}", "hint": null, "explanation": "The library's entry in the requests manifest has no valid SHA-256 hash, so its source cannot be verified; fix the entry.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "identifier"}}}, - "PF-E4037": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not open-source (access ''{indexed_access}'' in libraries.json); PineForge inlines open libraries only", "hint": null, "explanation": "The library index marks this library as not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "indexed_access": {"kind": "identifier"}}}, - "PF-E4038": {"severity": "error", "area": "libraries", "message": "library ''{path}'' source is not UTF-8 text", "hint": null, "explanation": "The library's source is not valid UTF-8 text, so it cannot be read or inlined.", "args": {"path": {"kind": "identifier"}}}, - "PF-E4039": {"severity": "error", "area": "libraries", "message": "library ''{path}'' source does not match its pinned sha256 {sha}... (found {found_sha}...)", "hint": null, "explanation": "The library source that was found does not match the SHA-256 hash pinned in the manifest, so PineForge refuses to use it.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "found_sha": {"kind": "identifier"}}}, - "PF-E4040": {"severity": "error", "area": "libraries", "message": "library ''{path}'' source is missing (sha256 {sha}... under ${requests_env}/{slug_dir_name}/files and ${libraries_env})", "hint": null, "explanation": "No file matching the library's pinned SHA-256 hash was found in the configured directories, so its source is missing.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "requests_env": {"kind": "identifier"}, "slug_dir_name": {"kind": "identifier"}, "libraries_env": {"kind": "identifier"}}}, - "PF-E5001": {"severity": "error", "area": "codegen", "message": "Recursive stateful callable cycle is not supported: {cycle}.", "hint": "Remove the recursive call; Pine user-defined functions cannot execute recursively.", "explanation": "Stateful functions (with TA calls, var variables or history reads) call each other in a cycle; Pine forbids recursion, so remove the recursive call.", "args": {"cycle": {"kind": "identifier"}}}, - "PF-E5002": {"severity": "error", "area": "codegen", "message": "matrix.{meth_name} requires matrix; got matrix<{elem_str}>", "hint": "Numeric-only methods are not available for matrix, matrix, matrix, or matrix.", "explanation": "This matrix method works only on matrix; it cannot be used on a matrix of int, bool, string or objects.", "args": {"meth_name": {"kind": "identifier"}, "elem_str": {"kind": "type"}}}, - "PF-E5003": {"severity": "error", "area": "codegen", "message": "matrix.sort requires int, bool, string, or float element type; got {elem_name}", "hint": null, "explanation": "matrix.sort can sort only int, bool, string or float matrices, and this matrix has a different element type.", "args": {"elem_name": {"kind": "type"}}}, - "PF-E5004": {"severity": "error", "area": "codegen", "message": "matrix.sort requires int, bool, string, or float element type; UDT matrices cannot be sorted", "hint": null, "explanation": "matrix.sort cannot sort a matrix of user-defined objects; only int, bool, string and float matrices can be sorted.", "args": {}}, - "PF-E5005": {"severity": "error", "area": "codegen", "message": "request.security helper call history is only supported in the payload itself", "hint": null, "explanation": "Reading the history ([k]) of a call inside a function used by request.security is not supported; do it in the expression passed to request.security itself.", "args": {}}, - "PF-E5006": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor flag ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot initialize the indicator with a stable per-run value.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA constructor arguments.", "explanation": "A TA indicator's boolean argument is neither a literal nor derived from an input, so PineForge cannot fix it once per run; use a literal or an input.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}}, - "PF-E5007": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor flag ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot initialize the indicator with a stable per-run value.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA lengths.", "explanation": "A TA indicator's flag argument is neither a constant nor input-derived, so PineForge cannot set it once per run; use a literal or an input-based value.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}}, - "PF-E5008": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor length ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot size the indicator buffer.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA constructor arguments.", "explanation": "A TA indicator's length is neither a constant nor derived from an input, so PineForge cannot size its buffer; use a literal, an input or arithmetic on those.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}}, - "PF-E5009": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor length ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot size the indicator buffer.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA lengths.", "explanation": "A TA indicator's length is not a literal and not derived from an input, so PineForge cannot size its buffer; use a literal, an input or arithmetic on those.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}}, - "PF-E5010": {"severity": "error", "area": "codegen", "message": "request.security timeframe was not resolved for registration", "hint": null, "explanation": "PineForge could not work out this request.security timeframe before the run starts, so it cannot register the request; use a constant, input or syminfo value.", "args": {}}, - "PF-E5011": {"severity": "error", "area": "codegen", "message": "input title {spelled}is not a constant string: TradingView declares title (const string), and PineForge keys an input override by its title.", "hint": "Use a string literal, or a name bound once at global scope to one (T = \"Length\").", "explanation": "An input's title must be a constant string (a literal or a name bound once to one), because PineForge keys each input override by its title.", "args": {"spelled": {"kind": "text"}}}, - "PF-E5012": {"severity": "error", "area": "codegen", "message": "{type_name}.copy() is unsupported because direct array field(s) {rendered} still use value storage", "hint": "Move the array outside the UDT and store a supported shared-ID map/matrix or nested UDT handle until array fields gain handle identity.", "explanation": "Copying an object whose type has array fields is unsupported, since PineForge would copy the arrays by value; keep the arrays outside the type.", "args": {"type_name": {"kind": "type"}, "rendered": {"kind": "identifier"}}}, - "PF-E5013": {"severity": "error", "area": "codegen", "message": "array.{method} requires a numeric array", "hint": "Use numeric arrays for aggregate/statistical array functions.", "explanation": "This array function (sum, avg, stdev and similar) needs an array of numbers, and the array has another element type.", "args": {"method": {"kind": "identifier"}}}, - "PF-E5014": {"severity": "error", "area": "codegen", "message": "{func_name}() with bars_back / timeframe_bars_back inside request.security is not supported", "hint": "Read {func_name}() with its offset outside request.security().", "explanation": "time() or time_close() with a bars-back offset is not supported inside request.security; read the offset time outside the request.", "args": {"func_name": {"kind": "identifier"}}}, - "PF-E5015": {"severity": "error", "area": "codegen", "message": "array.copy: expected exactly one receiver ''id''", "hint": "Use array.copy(source) or array.copy(id=source).", "explanation": "array.copy takes exactly one array, either positionally or as id=; this call does not match that.", "args": {}}, - "PF-E5016": {"severity": "error", "area": "codegen", "message": "map.{method}: unknown keyword argument ''{name}''", "hint": "Expected map.{method}({param_names}).", "explanation": "A map function was called with a keyword argument it does not have; use the parameter names it expects.", "args": {"method": {"kind": "identifier"}, "name": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, - "PF-E5017": {"severity": "error", "area": "codegen", "message": "map.{method}: unknown keyword argument ''{name}''", "hint": "Use ''id2='' for the source map. Expected map.{method}({param_names}).", "explanation": "map.put_all was called with from=; its source map parameter is named id2, so use id2= or pass the map by position.", "args": {"method": {"kind": "identifier"}, "name": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, - "PF-E5018": {"severity": "error", "area": "codegen", "message": "map.{method}: too many positional arguments (expected {param_names_count}, got {args_count})", "hint": "Expected map.{method}({param_names}).", "explanation": "A map function got more positional arguments than it accepts; remove the extra ones.", "args": {"method": {"kind": "identifier"}, "param_names_count": {"kind": "number"}, "args_count": {"kind": "number"}, "param_names": {"kind": "identifier"}}}, - "PF-E5019": {"severity": "error", "area": "codegen", "message": "map.{method}: argument ''{name}'' passed both positionally and by keyword", "hint": "Expected map.{method}({param_names}); bind each argument once.", "explanation": "A map function argument is given both by position and by keyword; pass each argument only once.", "args": {"method": {"kind": "identifier"}, "name": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, - "PF-E5020": {"severity": "error", "area": "codegen", "message": "map.{method}: missing required argument ''{missing}''", "hint": "Expected map.{method}({param_names}).", "explanation": "A required argument of a map function is missing from the call; pass it by position or by keyword.", "args": {"method": {"kind": "identifier"}, "missing": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, - "PF-E5021": {"severity": "error", "area": "codegen", "message": "map.{method}: keyword arguments are not supported for this functional call form", "hint": "Use the established positional form: map.{method}({param_names}).", "explanation": "Keyword arguments are not supported in this function-style map call; pass the arguments by position.", "args": {"method": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, - "PF-E5022": {"severity": "error", "area": "codegen", "message": "map.{method}: keyword arguments are not supported for this receiver-method call form", "hint": "Use the established positional form: map.{method}({param_names}).", "explanation": "Keyword arguments are not supported in this method-style map call; pass the arguments by position.", "args": {"method": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, - "PF-E5023": {"severity": "error", "area": "codegen", "message": "an array a call returns is passed to parameter ''{param}'' of ''{func_info_name}'', which takes the array itself: PineForge would pass a copy of it", "hint": "TradingView passes the array a function returns as itself, so the callee''s changes to it reach every variable holding it; pass a variable holding the array instead.", "explanation": "An array returned by a function call is passed to a parameter that can change it in place; PineForge would pass a copy, so store it in a variable first.", "args": {"param": {"kind": "identifier"}, "func_info_name": {"kind": "identifier"}}}, - "PF-E5024": {"severity": "error", "area": "codegen", "message": "{recv_spec_name}.copy() expects no arguments", "hint": "Call copy() on the UDT object without arguments.", "explanation": "copy() on an object takes no arguments; call it as object.copy().", "args": {"recv_spec_name": {"kind": "type"}}}, - "PF-E5025": {"severity": "error", "area": "codegen", "message": "matrix.{meth_raw}: wrong number of arguments", "hint": "Check Pine v6 matrix method signature (positional vs keyword).", "explanation": "A matrix method call has the wrong number of arguments; check the Pine v6 matrix method signature and whether arguments are positional or keyword.", "args": {"meth_raw": {"kind": "identifier"}}}, - "PF-E5026": {"severity": "error", "area": "codegen", "message": "matrix.{func_name}: wrong number of arguments", "hint": "Check Pine v6 matrix method signature (positional vs keyword).", "explanation": "A matrix method call has the wrong number of arguments; check the Pine v6 matrix method signature and whether arguments are positional or keyword.", "args": {"func_name": {"kind": "identifier"}}}, - "PF-E5027": {"severity": "error", "area": "codegen", "message": "timestamp(dateString): could not parse ''{args}''.", "hint": "Supported forms: ISO-8601 (\"2025-01-01[THH:MM:SS][±HH:MM]\") and \"DD MMM YYYY [hh:mm[:ss]] [±HHMM]\" / \"MMM DD YYYY ...\"; no time zone = GMT+0.", "explanation": "timestamp() got a date string PineForge cannot parse; use an ISO-8601 or 'DD MMM YYYY' form, or pass year, month and day numbers.", "args": {"args": {"kind": "identifier"}}}, - "PF-E5028": {"severity": "error", "area": "codegen", "message": "timestamp(dateString) requires a literal string in PineForge (Pine v6 dateString is a const string).", "hint": "Use a string literal, or timestamp(year, month, day[, hour, minute, second]).", "explanation": "timestamp(dateString) needs a string literal, because PineForge parses the date at transpile time; use a literal or numeric arguments.", "args": {}}, - "PF-E5029": {"severity": "error", "area": "codegen", "message": "timestamp(timezone, ...) requires year, month, and day arguments.", "hint": "Pine v6 signature: timestamp(timezone, year, month, day[, hour, minute, second]).", "explanation": "timestamp() with a timezone first needs year, month and day after it; add the missing arguments.", "args": {}}, - "PF-E5030": {"severity": "error", "area": "codegen", "message": "timestamp(...) with {merged_count} argument(s) is not supported — year, month, and day are required.", "hint": "Pine v6 signature: timestamp(year, month, day[, hour, minute, second]); the dateString overload is not supported in PineForge.", "explanation": "timestamp() with numeric arguments needs at least year, month and day; add the missing ones.", "args": {"merged_count": {"kind": "number"}}}, - "PF-E5031": {"severity": "error", "area": "codegen", "message": "matrix.{func_name} receiver must be a variable reference", "hint": null, "explanation": "This numeric-only matrix function needs its matrix as a plain variable so PineForge can check the element type; assign the matrix to a variable first.", "args": {"func_name": {"kind": "identifier"}}}, - "PF-E5032": {"severity": "error", "area": "codegen", "message": "matrix.{func_name}: receiver ''{recv_name}'' is not a known matrix variable", "hint": null, "explanation": "The matrix function's first argument is a variable PineForge does not know as a matrix, so it cannot check its element type.", "args": {"func_name": {"kind": "identifier"}, "recv_name": {"kind": "identifier"}}}, - "PF-E5033": {"severity": "error", "area": "codegen", "message": "{namespace}.copy(...) expects exactly one object argument", "hint": "Prefer the canonical object.copy() form.", "explanation": "Type.copy(...) takes exactly one object of that type; pass one object, or write object.copy().", "args": {"namespace": {"kind": "type"}}}, - "PF-E5034": {"severity": "error", "area": "codegen", "message": "Unknown function ''{func_name}(...)'' — not a PineForge builtin or a user-defined function.", "hint": "Check the spelling; the function may not be supported by PineForge, or needs its namespace (e.g. math./str.).", "explanation": "The called function is neither a PineForge built-in nor defined in the script; check the spelling or add its namespace, such as math. or str.", "args": {"func_name": {"kind": "identifier"}}}, - "PF-E5035": {"severity": "error", "area": "codegen", "message": "Unknown call ''{namespace}.{func_name}(...)'' — ''{namespace}'' is not a PineForge-supported namespace or a user-defined type.", "hint": "Check the spelling; this namespace may not be supported by PineForge.", "explanation": "The call's namespace is neither a supported PineForge namespace nor a user-defined type; check the spelling.", "args": {"namespace": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}}, - "PF-E5036": {"severity": "error", "area": "codegen", "message": "Unknown variable ''{name}'' — not a PineForge builtin or a declared variable.", "hint": null, "explanation": "The script reads a name that is neither a PineForge built-in nor a declared variable; check the spelling or declare it first.", "args": {"name": {"kind": "identifier"}}}, - "PF-E5037": {"severity": "error", "area": "codegen", "message": "Unknown variable ''{name}'' — not a PineForge builtin or a declared variable.", "hint": "{hint}", "explanation": "The script reads a realtime-only built-in variable, which has no value in a batch backtest; remove it or compute the value another way.", "args": {"name": {"kind": "identifier"}, "hint": {"kind": "text"}}}, - "PF-E5038": {"severity": "error", "area": "codegen", "message": "ta.{member} property read could not be bound to a TA call site.", "hint": "Use the function form ta.{member}(...) instead of the bare property read.", "explanation": "A bare ta. read could not be tied to a calculation; call the function form ta.name(...) instead.", "args": {"member": {"kind": "identifier"}}}, - "PF-E5039": {"severity": "error", "area": "codegen", "message": "ta.{member} is not readable as a bare property in PineForge.", "hint": "Call the function form ta.{member}(...) with its arguments instead.", "explanation": "That ta member is not a variable in PineForge, so it cannot be read without parentheses; call it as a function with its arguments.", "args": {"member": {"kind": "identifier"}}}, - "PF-E5040": {"severity": "error", "area": "codegen", "message": "{op} na on a {kind} reference: TradingView refuses a comparison with na (CE10187: \"Cannot compare a value to \\\"na\\\" directly\").", "hint": "Test the reference with na(...).", "explanation": "Comparing an object or drawing reference with na using == or != is rejected, as in TradingView; test it with na(...) instead.", "args": {"op": {"kind": "keyword"}, "kind": {"kind": "type"}}}, - "PF-E5041": {"severity": "error", "area": "codegen", "message": "{op} on a {kind} reference: TradingView compares only line and label references (CE10123: \"Cannot call ''operator {op}''\" with an argument of the {kind} type).", "hint": "Compare the fields or getter values the objects hold, or test na(...).", "explanation": "PineForge refuses == and != on object or drawing references other than line or label of the same kind, as TradingView does; compare fields or test na().", "args": {"op": {"kind": "keyword"}, "kind": {"kind": "type"}}}, - "PF-E5042": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: ''{op}'' of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library compares a bool with == or !=, but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the library.", "args": {"library": {"kind": "identifier"}, "op": {"kind": "keyword"}}}, - "PF-E5043": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: str.format() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library passes a bool to str.format(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}}}, - "PF-E5044": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: str.tostring() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library passes a bool to str.tostring(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}}}, - "PF-E5045": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: string() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library passes a bool to string(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}}}, - "PF-E5046": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: {func_name}() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library tests a bool with na(), nz() or fixnan(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}}, - "PF-E5047": {"severity": "error", "area": "codegen", "message": "session.{flag}[...] cannot be read here: PineForge keeps a session flag''s history on the requested clock only for a read the request.security expression reaches through its own operators, not through a call''s argument, a function or a variable.", "hint": null, "explanation": "A session flag history read inside request.security works only when the expression's own operators reach it, not via a call argument, function or variable.", "args": {"flag": {"kind": "identifier"}}}, - "PF-E5048": {"severity": "error", "area": "codegen", "message": "session.{flag}[...] cannot be read in {owner}(), {why}: PineForge keeps a session flag''s history in a function by each of its call sites, and cannot tell this one apart.", "hint": null, "explanation": "A session flag history read is in a function PineForge cannot split per call site: a method, or one a method, request.security or UDT field default calls.", "args": {"flag": {"kind": "identifier"}, "owner": {"kind": "identifier"}, "why": {"kind": "vocab", "values": ["a method, whose calls PineForge cannot always tell apart", "which a UDT field default calls once for every new()", "which a method calls", "which a request.security expression evaluates on the requested clock"]}}}, - "PF-E5049": {"severity": "error", "area": "codegen", "message": "session.{flag}[...] is not supported here: PineForge keeps a session flag''s history for the script''s top level, a function body and a request.security expression that reads it.", "hint": null, "explanation": "A session flag history read is supported only at the top level, in a function body or in a request.security expression, and this read is none of those.", "args": {"flag": {"kind": "identifier"}}}, - "PF-E5050": {"severity": "error", "area": "codegen", "message": "History of the chart.point {object_name} is not supported in PineForge when the script changes its fields: PineForge holds a chart.point as a value, where TradingView''s history reads the point object as it is now.", "hint": "Keep the field in a variable of its own and read that variable''s history, or build a new point instead of changing a field.", "explanation": "History of a chart.point variable whose fields the script changes is refused because PineForge holds points as values; use a separate variable or build a new point.", "args": {"object_name": {"kind": "identifier"}}}, - "PF-E5051": {"severity": "error", "area": "codegen", "message": "matrix ''{target_label}'' element type mismatch on reassignment: expected {target_type}, got {rhs_type}", "hint": null, "explanation": "A matrix variable is reassigned a matrix with a different element type, which Pine forbids; make the new matrix's element type match the variable's.", "args": {"target_label": {"kind": "identifier"}, "target_type": {"kind": "type"}, "rhs_type": {"kind": "type"}}}, - "PF-E5052": {"severity": "error", "area": "codegen", "message": "array.{method}: wrong number of arguments", "hint": null, "explanation": "An array method call has too few arguments for its lowering; check the Pine v6 array method signature.", "args": {"method": {"kind": "identifier"}}}, - "PF-E6001": {"severity": "error", "area": "collection-history", "message": "matrix.{method}: wrong number of arguments", "hint": "Check Pine v6 matrix method signature (positional vs keyword).", "explanation": "A matrix method call has the wrong number of arguments; check the Pine v6 matrix method signature and whether arguments are positional or keyword.", "args": {"method": {"kind": "identifier"}}}, - "PF-E6002": {"severity": "error", "area": "collection-history", "message": "{label} := ...: an assignment to the history-referencing operator is not supported in PineForge.", "hint": null, "explanation": "TradingView refuses an assignment to a history reference; assign the variable itself.", "args": {"label": {"kind": "text"}}}, - "PF-E6003": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for operator {op} (CE10123).", "hint": null, "explanation": "An array or matrix history read such as a[1] is an operand of an operator, which TradingView refuses; read an element or the size and use that instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "op": {"kind": "keyword"}}}, - "PF-E6004": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for operator {op} (CE10123).", "hint": null, "explanation": "An array or matrix history read such as a[1] is an operand of an operator, which TradingView refuses; read an element or the size and use that instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "op": {"kind": "keyword"}}}, - "PF-E6005": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the condition of ?: (CE10123).", "hint": null, "explanation": "An array or matrix history read is the condition of a ?: expression, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6006": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the condition of ?: (CE10123).", "hint": null, "explanation": "An array or matrix history read is the condition of a ?: expression, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6007": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the condition of an if statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of an if statement, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6008": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the condition of an while statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of a while loop, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6009": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the condition of an if statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of an if statement, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6010": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the condition of an while statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of a while loop, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6011": {"severity": "error", "area": "collection-history", "message": "({label})[...]: the history of a {kind}''s history is not supported in PineForge.", "hint": null, "explanation": "The history of a collection's history is not kept by PineForge.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6012": {"severity": "error", "area": "collection-history", "message": "({label})[...]: the history of an {kind}''s history is not supported in PineForge.", "hint": null, "explanation": "The history of a collection's history is not kept by PineForge.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6013": {"severity": "error", "area": "collection-history", "message": "{label} is not supported in PineForge here.", "hint": null, "explanation": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower; use it only with built-in array or matrix functions.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6014": {"severity": "error", "area": "collection-history", "message": "{label}.{method}: a {kind} has no fields.", "hint": null, "explanation": "An array or a matrix has no fields; a field read after its history reference is refused.", "args": {"label": {"kind": "text"}, "method": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6015": {"severity": "error", "area": "collection-history", "message": "{label}.{method}: an {kind} has no fields.", "hint": null, "explanation": "An array or a matrix has no fields; a field read after its history reference is refused.", "args": {"label": {"kind": "text"}, "method": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6016": {"severity": "error", "area": "collection-history", "message": "{label}.{method}(): no array or matrix method of that name.", "hint": null, "explanation": "No array or matrix method has this name, so the call on the collection's history is refused.", "args": {"label": {"kind": "text"}, "method": {"kind": "identifier"}}}, - "PF-E6017": {"severity": "error", "area": "collection-history", "message": "matrix.sum of {label} is not supported in PineForge: the matrix it returns does not compile.", "hint": null, "explanation": "matrix.sum of a matrix's history returns a matrix that never compiled in PineForge, so it is refused.", "args": {"label": {"kind": "text"}}}, - "PF-E6018": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an argument of {name} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in function that takes only plain numbers, strings or conditions, which TradingView refuses; pass an element.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}}, - "PF-E6019": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an argument of {name} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in function that takes only plain numbers, strings or conditions, which TradingView refuses; pass an element.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}}, - "PF-E6020": {"severity": "error", "area": "collection-history", "message": "{label} as an argument of {name} is not supported in PineForge.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "name": {"kind": "identifier"}}}, - "PF-E6021": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an element of array.from (CE10122).", "hint": null, "explanation": "An array or matrix history read is used as an element of array.from(), which TradingView refuses; pass its elements instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6022": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an element of array.from (CE10122).", "hint": null, "explanation": "An array or matrix history read is used as an element of array.from(), which TradingView refuses; pass its elements instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6023": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an argument of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in namespace function that takes plain values, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E6024": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an argument of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in namespace function that takes plain values, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E6025": {"severity": "error", "area": "collection-history", "message": "{label} as a field of a new {namespace} is not supported in PineForge: the field would hold a changeable copy, where TradingView''s holds the read-only history.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "namespace": {"kind": "identifier"}}}, - "PF-E6026": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an argument of str.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a str function that takes a plain value, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, - "PF-E6027": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an argument of str.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a str function that takes a plain value, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, - "PF-E6028": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the message of log.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is used as the message of a log call, which TradingView refuses; log an element or a string built from it instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, - "PF-E6029": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the message of log.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is used as the message of a log call, which TradingView refuses; log an element or a string built from it instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, - "PF-E6030": {"severity": "error", "area": "collection-history", "message": "{label} as an argument of the overloaded method {member} is not supported in PineForge.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "member": {"kind": "identifier"}}}, - "PF-E6031": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as a value of {member}() (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix method, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, - "PF-E6032": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as a value of {member}() (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix method, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, - "PF-E6033": {"severity": "error", "area": "collection-history", "message": "{label} as an argument of {function}.{member} is not supported in PineForge.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "function": {"kind": "text"}, "member": {"kind": "identifier"}}}, - "PF-E6034": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as a value of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix function, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E6035": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as a value of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix function, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E6036": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for log.{member} (CE10122).", "hint": null, "explanation": "A history read of an array of colors is a format argument of a log call, which TradingView refuses; log its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E6037": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for log.{member} (CE10123).", "hint": null, "explanation": "A history read of an array of colors is passed to a log call, which TradingView refuses; log its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E6038": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.format (CE10122).", "hint": null, "explanation": "A history read of an array of colors is a format argument of str.format, which TradingView refuses; format its elements instead.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6039": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.format (CE10123).", "hint": null, "explanation": "A history read of an array of colors is passed to str.format, which TradingView refuses; format its elements instead.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6040": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.tostring (CE10122).", "hint": null, "explanation": "A history read of an array of colors is passed to str.tostring, which TradingView refuses; convert its elements instead.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6041": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.tostring (CE10123).", "hint": null, "explanation": "A history read of an array of colors is passed to str.tostring, which TradingView refuses; convert its elements instead.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6042": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for log.{member} (CE10122).", "hint": null, "explanation": "A history read of an array of objects is a format argument of a log call, which TradingView refuses; log fields of its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E6043": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for log.{member} (CE10123).", "hint": null, "explanation": "A history read of an array of objects is passed to a log call, which TradingView refuses; log fields of its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-E6044": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.format (CE10122).", "hint": null, "explanation": "A history read of an array of objects is a format argument of str.format, which TradingView refuses; format fields of its elements instead.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6045": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.format (CE10123).", "hint": null, "explanation": "A history read of an array of objects is passed to str.format, which TradingView refuses; format fields of its elements instead.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6046": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.tostring (CE10122).", "hint": null, "explanation": "A history read of an array of objects is passed to str.tostring, which TradingView refuses; convert fields of its elements instead.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6047": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.tostring (CE10123).", "hint": null, "explanation": "A history read of an array of objects is passed to str.tostring, which TradingView refuses; convert fields of its elements instead.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6048": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for the {type_hint} variable {name} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to a variable declared with a scalar type, which TradingView refuses; assign an element or declare a collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "type_hint": {"kind": "type"}, "name": {"kind": "identifier"}}}, - "PF-E6049": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for the {type_hint} variable {name} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to a variable declared with a scalar type, which TradingView refuses; assign an element or declare a collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "type_hint": {"kind": "type"}, "name": {"kind": "identifier"}}}, - "PF-E6050": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for the {field_type} field {member} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an object field of a scalar type, which TradingView refuses; assign an element or change the field's type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "field_type": {"kind": "type"}, "member": {"kind": "identifier"}}}, - "PF-E6051": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for the {field_type} field {member} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an object field of a scalar type, which TradingView refuses; assign an element or change the field's type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "field_type": {"kind": "type"}, "member": {"kind": "identifier"}}}, - "PF-E6052": {"severity": "error", "area": "collection-history", "message": "{label} assigned to a field is not supported in PineForge: the field would hold a changeable copy, where TradingView''s holds the read-only history.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}}}, - "PF-E6053": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for the variable {name} of another type (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an existing variable of another type, which TradingView refuses; use a variable of the matching collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}}, - "PF-E6054": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for the variable {name} of another type (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an existing variable of another type, which TradingView refuses; use a variable of the matching collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}}, - "PF-E6055": {"severity": "error", "area": "collection-history", "message": "{label} assigned to {name} is not supported in PineForge here.", "hint": null, "explanation": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower; use it only with built-in array or matrix functions.", "args": {"label": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-E6056": {"severity": "error", "area": "collection-history", "message": "{label} as a statement: TradingView reads it as a declaration and refuses it (CE10009, \"Extraneous input\").", "hint": null, "explanation": "An array or matrix history read written alone as a top-level statement is refused because TradingView reads it as a declaration; remove it or bind it to a variable.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6057": {"severity": "error", "area": "collection-history", "message": "{label} in a tuple is not supported in PineForge.", "hint": null, "explanation": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower; use it only with built-in array or matrix functions.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6058": {"severity": "error", "area": "collection-history", "message": "{label}.slice() is not supported in PineForge here.", "hint": null, "explanation": "A slice of an array's history is used in a way PineForge cannot lower; simplify the expression or copy the array first.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6059": {"severity": "error", "area": "collection-history", "message": "{label} is bound where the script reads it both as a {kind} and through na() or str.tostring(): that is not supported in PineForge, which holds no na {kind} and does not render one.", "hint": null, "explanation": "A variable bound to an array or matrix history is read both as a collection and through na() or str.tostring(); PineForge has no na collection, so it refuses this.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6060": {"severity": "error", "area": "collection-history", "message": "{label} is bound where the script reads it both as an {kind} and through na() or str.tostring(): that is not supported in PineForge, which holds no na {kind} and does not render one.", "hint": null, "explanation": "A variable bound to an array or matrix history is read both as a collection and through na() or str.tostring(); PineForge has no na collection, so it refuses this.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6061": {"severity": "error", "area": "collection-history", "message": "{label} is not supported in PineForge here: the history of a matrix is supported as the receiver or an argument of a matrix function, na(), and the value of a variable or a function''s argument that reads it.", "hint": null, "explanation": "A matrix history is supported only as a matrix function's receiver or argument, in na(), or via a variable or function argument that reads it; this use is not.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6062": {"severity": "error", "area": "collection-history", "message": "{label} inside a request.security expression is not supported in PineForge: TradingView reads the copies the requested timeframe''s bars left, which PineForge does not keep.", "hint": null, "explanation": "request.security cannot read the history of a user-defined type or drawing reference, because PineForge keeps no references from the requested bars.", "args": {"label": {"kind": "text"}}}, - "PF-E6063": {"severity": "error", "area": "collection-history", "message": "{label} is not supported in PineForge here: the history of an array is supported as the receiver or an argument of an array function, a for...in iterable, na(), and the value of a variable or a function''s argument that reads it.", "hint": null, "explanation": "An array history is supported only as an array function's receiver or argument, a for...in iterable, in na(), or via a variable or function argument that reads it.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6064": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a block''s var {read_kind} is not supported in PineForge.", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "read_kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6065": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} declared in a block that redeclares a script variable is not supported in PineForge (such a block''s declarations are C++ locals).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6066": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} declared in a loop is not supported in PineForge.", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6067": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} function''s local is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6068": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} parameter is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6069": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} script variable read in a function is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6070": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} declared in a block that redeclares a script variable is not supported in PineForge (such a block''s declarations are C++ locals).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6071": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} declared in a loop is not supported in PineForge.", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6072": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} function''s local is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6073": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} parameter is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6074": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} script variable read in a function is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6075": {"severity": "error", "area": "collection-history", "message": "{label}: the history of this {read_kind} is not supported in PineForge (only a variable the script''s top level or one of its blocks declares keeps one).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for a variable the script's top level or one of its blocks declares.", "args": {"label": {"kind": "text"}, "read_kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6076": {"severity": "error", "area": "collection-history", "message": "The history of a call''s {kind} is not supported in PineForge here: TradingView reads the copy that expression produced that many bars back, which PineForge does not keep.", "hint": "Bind the expression to a variable and read the variable''s history.", "explanation": "The history of a function call's array or matrix result is refused as PineForge keeps no per-bar copy of it; bind the call to a variable and read its history.", "args": {"kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6077": {"severity": "error", "area": "collection-history", "message": "The history of a selection''s {kind} is not supported in PineForge here: TradingView reads the copy that expression produced that many bars back, which PineForge does not keep.", "hint": "Bind the expression to a variable and read the variable''s history.", "explanation": "The history of a ?: selection's array or matrix is refused as PineForge keeps no per-bar copy of it; bind the selection to a variable and read its history.", "args": {"kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6078": {"severity": "error", "area": "collection-history", "message": "The history of an expression''s {kind} is not supported in PineForge here: TradingView reads the copy that expression produced that many bars back, which PineForge does not keep.", "hint": "Bind the expression to a variable and read the variable''s history.", "explanation": "The history of an expression's array or matrix is refused as PineForge keeps no per-bar copy of it; bind the expression to a variable and read its history.", "args": {"kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-E6079": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a name bound to it (line ?): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A name bound to an array or matrix history is changed, which stops the run on TradingView; PineForge would change a copy silently, so copy the history first.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6080": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a name bound to it (line {line}): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A name bound to an array or matrix history is changed on the given line, which stops the run on TradingView; PineForge would change a copy, so copy it first.", "args": {"label": {"kind": "identifier"}, "line": {"kind": "number"}}}, - "PF-E6081": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a slice of it (line ?): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A slice of an array or matrix history is changed, which stops the run on TradingView; PineForge would silently change a copy, so copy the history first.", "args": {"label": {"kind": "identifier"}}}, - "PF-E6082": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a slice of it (line {line}): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A slice of an array or matrix history is changed on the given line, which stops the run on TradingView; PineForge would change a copy, so copy it first.", "args": {"label": {"kind": "identifier"}, "line": {"kind": "number"}}}, - "PF-E7001": {"severity": "error", "area": "ta", "message": "Unsupported requested-context TA constructor for {class_name}: PineForge cannot bind the helper call''s arguments to its constructor arguments.", "hint": "Call the ta.* function directly inside request.security().", "explanation": "A TA function called through a helper inside request.security cannot have the helper's arguments bound to its constructor; call the ta.* function directly.", "args": {"class_name": {"kind": "identifier"}}}, - "PF-E7002": {"severity": "error", "area": "ta", "message": "Unsupported requested-context TA constructor flag ''{shown}'' for {class_name}: the helper-bound expression is not a stable per-run scalar{reason}.", "hint": "Use a literal, an input.*() value, timeframe.* metadata, or arithmetic over those for TA lengths.", "explanation": "A boolean option of a TA call inside request.security comes from a helper-bound value that is not fixed for the run; use a literal, an input or timeframe metadata.", "args": {"shown": {"kind": "identifier"}, "class_name": {"kind": "identifier"}, "reason": {"kind": "text"}}}, - "PF-E7003": {"severity": "error", "area": "ta", "message": "Unsupported requested-context TA constructor length ''{shown}'' for {class_name}: the helper-bound expression is not a stable per-run scalar{reason}.", "hint": "Use a literal, an input.*() value, timeframe.* metadata, or arithmetic over those for TA lengths.", "explanation": "A TA length inside request.security comes from a helper-bound value not fixed for the run; use a literal, an input, timeframe metadata or arithmetic on them.", "args": {"shown": {"kind": "identifier"}, "class_name": {"kind": "identifier"}, "reason": {"kind": "text"}}}, - "PF-E7004": {"severity": "error", "area": "ta", "message": "Unsupported TA constructor length for {class_name} inside request.security in ''{containing}'': its call sites pass different lengths ({spellings}), and one requested-context evaluator serves them all.", "hint": "Call request.security() at each call site, or pass the same length from every call.", "explanation": "A function with a request.security TA call is called with different lengths, but one evaluator serves all calls; use one length or call request.security per site.", "args": {"class_name": {"kind": "identifier"}, "containing": {"kind": "identifier"}, "spellings": {"kind": "identifier"}}}, - "PF-W0000": {"severity": "warning", "area": "uncatalogued", "message": "{message}", "hint": "{hint}", "explanation": "A diagnostic whose text no catalog template renders; the test suite refuses it, so a release never emits it.", "args": {"message": {"kind": "text"}, "hint": {"kind": "text"}}}, - "PF-W1001": {"severity": "warning", "area": "support", "message": "{context}: map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps with string keys only; declare the map's key type as string; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"context": {"kind": "text"}}}, - "PF-W1002": {"severity": "warning", "area": "support", "message": "{context}: map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps whose values are float, int, bool or string only; use one of those as the value type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"context": {"kind": "text"}}}, - "PF-W1003": {"severity": "warning", "area": "support", "message": "matrix<{element_type}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"element_type": {"kind": "type"}}}, - "PF-W1004": {"severity": "warning", "area": "support", "message": "matrix<{element_type}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"element_type": {"kind": "type"}}}, - "PF-W1005": {"severity": "warning", "area": "support", "message": "input.color(...) requires a color defval (e.g. color.red or color.new(color.red, 50)).", "hint": null, "explanation": "input.color needs a color as its default value, for example color.red or color.new(color.red, 50); inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1006": {"severity": "warning", "area": "support", "message": "input.color(...) defval must be a color constant (color.red, ...), a color literal (#rrggbb), or a color.new(...) / color.rgb(...) builder. Arbitrary expressions are not supported: the engine has no color helper, so codegen routes input.color through the int getter — any non-color defval would silently store a numeric value with no color encoding.", "hint": "Replace the defval with color. or color.new(...).", "explanation": "The default of input.color must be a color constant, a #rrggbb literal or a color.new or color.rgb call; other expressions are refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1007": {"severity": "warning", "area": "support", "message": "input.source(...) requires a native series defval (close, open, high, low, hl2, hlc3, ohlc4, ...).", "hint": null, "explanation": "input.source needs a default chart series such as close as its first argument or defval; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1008": {"severity": "warning", "area": "support", "message": "input.source(...) defval must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4). User series, computed expressions, and indicator outputs are not supported: input.source is restricted to native OHLCV series.", "hint": "Use one of: close, open, high, low, hl2, hlc3, ohlc4.", "explanation": "The default of input.source must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4); computed series are refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1009": {"severity": "warning", "area": "support", "message": "{kind}() declarations are not supported; PineForge runs strategies only.", "hint": "Replace the declaration with strategy(...) and add explicit entry/exit calls.", "explanation": "PineForge runs strategies only, so a script declared with indicator() or library() is refused; declare it with strategy() and add orders; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kind": {"kind": "identifier"}}}, - "PF-W1010": {"severity": "warning", "area": "support", "message": "Tuple reassignment [..] {op} is not Pine syntax: TradingView declares a tuple with ''='' and has no tuple reassignment.", "hint": "Declare new names with [a, b] = f(), then reassign each variable on its own line.", "explanation": "Pine has no tuple reassignment: declare a tuple once with '=' and reassign each variable on its own line; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"op": {"kind": "keyword"}}}, - "PF-W1011": {"severity": "warning", "area": "support", "message": "A tuple literal [..] cannot be a variable''s value: TradingView rejects it here (Syntax error at input ''['', CE10156). A tuple is only a function''s or an if/switch arm''s value or a request.security expression.", "hint": "Declare each variable on its own line (a = x, b = y), or return the tuple from a function: f() => [x, y], then [a, b] = f().", "explanation": "A tuple literal such as [a, b] cannot be assigned to a variable; return it from a function or if/switch arm and destructure the result; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1012": {"severity": "warning", "area": "support", "message": "A ternary cannot return a tuple: TradingView rejects [a, b] = c ? [..] : [..] (\"Ternary operations cannot return tuples\").", "hint": "Select the tuple with an if or switch: [a, b] = if c, each arm ending in its tuple.", "explanation": "A ternary cannot produce a tuple (TradingView rejects it too); choose between tuples with an if or switch instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1013": {"severity": "warning", "area": "support", "message": "ta.stoch(...) returns a single series in PineForge; tuple destructuring is not supported.", "hint": "Use k = ta.stoch(...) and compute smoothing separately if needed.", "explanation": "ta.stoch returns one series in PineForge, so destructuring it into a tuple is refused; assign it to a single variable; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1014": {"severity": "warning", "area": "support", "message": "History references on UDT drawing fields are not supported in PineForge.", "hint": "{var_name}.{object_member}[...] would be read as the current-bar field, not prior-bar history. Copy the field to a bare drawing variable first, or remove the history reference.", "explanation": "A history index on a drawing field of a user-defined type would silently read the current field, so it is refused; copy the field to a variable first; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"var_name": {"kind": "identifier"}, "object_member": {"kind": "identifier"}}}, - "PF-W1015": {"severity": "warning", "area": "support", "message": "History references on tuple-destructured drawing handles are not supported in PineForge.", "hint": "{object_name}[...] is a drawing handle from tuple destructuring; PineForge cannot historize that tuple element safely.", "explanation": "A drawing handle bound by tuple destructuring cannot be read through a history index; remove the history reference; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}}}, - "PF-W1016": {"severity": "warning", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}}}, - "PF-W1017": {"severity": "warning", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}}, - "PF-W1018": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1019": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1020": {"severity": "warning", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}}}, - "PF-W1021": {"severity": "warning", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}}, - "PF-W1022": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1023": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1024": {"severity": "warning", "area": "support", "message": "footprint.{footprint}(...) is not supported.", "hint": "PineForge reads a footprint''s delta() only: the fp_delta__ column of the feed a requests manifest pins for the symbol requested.", "explanation": "PineForge reads only the delta of a footprint value; every other footprint member is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"footprint": {"kind": "identifier"}}}, - "PF-W1025": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "Currency conversion data not available in PineForge.", "explanation": "PineForge has no currency-conversion data, so request.currency_rate is refused; supply the rate yourself, for example as an input; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1026": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "External Quandl data not available in PineForge.", "explanation": "PineForge cannot load external Quandl data, so request.quandl is refused; remove it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1027": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "External seed data feeds not available in PineForge.", "explanation": "PineForge cannot load external seed data feeds, so request.seed is refused; remove it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1028": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.kagi() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.kagi builds a Kagi symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1029": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.linebreak() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.linebreak builds a Line Break symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1030": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.modify() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.modify builds a modified symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1031": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.new() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.new builds another symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1032": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.pointfigure() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.pointfigure builds a Point and Figure symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1033": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.renko() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.renko builds a Renko symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1034": {"severity": "warning", "area": "support", "message": "ticker.heikinashi(...) is supported only for the chart''s own symbol.", "hint": "Pass syminfo.tickerid: PineForge applies the Heikin-Ashi candle transform to the chart symbol inside request.security, but cannot load an alternate symbol''s HA candles.", "explanation": "ticker.heikinashi is accepted only for the chart's own symbol (syminfo.tickerid); another symbol's Heikin-Ashi candles cannot be loaded; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1035": {"severity": "warning", "area": "support", "message": "{full}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1036": {"severity": "warning", "area": "support", "message": "{name}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1037": {"severity": "warning", "area": "support", "message": "{full}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "footprint.* calls need tick-level bid/ask volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1038": {"severity": "warning", "area": "support", "message": "{full}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "volume_row.* calls need tick-level volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1039": {"severity": "warning", "area": "support", "message": "library() declarations are not supported; PineForge runs strategies only.", "hint": "Use strategy(...) and inline or pre-expand library code before uploading.", "explanation": "PineForge runs strategies only, so a library() declaration is refused; use strategy() and paste any library code into the script; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1040": {"severity": "warning", "area": "support", "message": "Bare barssince(...) is broken in PineForge codegen.", "hint": "Use ta.barssince(...) instead.", "explanation": "The bare barssince(...) form does not work in PineForge; call ta.barssince(...) instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1041": {"severity": "warning", "area": "support", "message": "ta.sum is not a PineScript v6 function.", "hint": "Use math.sum(...) instead.", "explanation": "ta.sum does not exist in Pine v6; use math.sum(source, length) for a rolling sum; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1042": {"severity": "warning", "area": "support", "message": "ta.{name} is a PineScript v6 variable, not a function.", "hint": "Use ta.{name} without parentheses.", "explanation": "This ta.* name is a built-in variable, not a function, so write it without parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1043": {"severity": "warning", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.closedtrades or strategy.opentrades accessor is not available in PineForge; use one of the supported trade accessors; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1044": {"severity": "warning", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": "{hint}", "explanation": "Open trades have no exit data in Pine v6: this accessor exists only on strategy.closedtrades, so it cannot be read from strategy.opentrades; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}, "hint": {"kind": "text"}}}, - "PF-W1045": {"severity": "warning", "area": "support", "message": "strategy.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.* function is not implemented in PineForge; check the spelling or use a supported strategy function; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1046": {"severity": "warning", "area": "support", "message": "strategy.exit(...) requires at least one price or trailing parameter in PineForge.", "hint": "Use strategy.close(...) for market exits.", "explanation": "strategy.exit needs a price or trailing parameter (profit, loss, limit, stop or a trail setting); use strategy.close for a plain market exit; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1047": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported. Only request.security(...) and request.security_lower_tf(...) are available in PineForge.", "hint": "External request feeds and other request.* variants are intentionally unavailable.", "explanation": "Only request.security and request.security_lower_tf are supported; other request.* calls need data feeds PineForge does not provide; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1048": {"severity": "warning", "area": "support", "message": "ta.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this ta.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1049": {"severity": "warning", "area": "support", "message": "math.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this math.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1050": {"severity": "warning", "area": "support", "message": "str.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this str.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1051": {"severity": "warning", "area": "support", "message": "input.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this input.* function, so the call is refused; use one of the supported input functions; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1052": {"severity": "warning", "area": "support", "message": "timeframe.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only timeframe.change and timeframe.in_seconds; any other timeframe.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1053": {"severity": "warning", "area": "support", "message": "color.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only color.new, color.rgb and color.r/g/b/t; any other color.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1054": {"severity": "warning", "area": "support", "message": "runtime.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only runtime.error; any other runtime.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1055": {"severity": "warning", "area": "support", "message": "log.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only log.info, log.warning and log.error; any other log.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1056": {"severity": "warning", "area": "support", "message": "array.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this array.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1057": {"severity": "warning", "area": "support", "message": "map.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this map.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1058": {"severity": "warning", "area": "support", "message": "map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps support only string keys; declare the map with string as its key type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1059": {"severity": "warning", "area": "support", "message": "map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps can hold only float, int, bool or string values; other value types such as collections or objects are refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1060": {"severity": "warning", "area": "support", "message": "matrix<{t}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"t": {"kind": "type"}}}, - "PF-W1061": {"severity": "warning", "area": "support", "message": "matrix<{t}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"t": {"kind": "type"}}}, - "PF-W1062": {"severity": "warning", "area": "support", "message": "matrix<{t}> element type not supported. Allowed: float, int, bool, string, color, or a declared UDT.", "hint": null, "explanation": "A matrix element must be float, int, bool, string, color or a declared user-defined type; any other element type is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"t": {"kind": "type"}}}, - "PF-W1063": {"severity": "warning", "area": "support", "message": "matrix.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this matrix.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1064": {"severity": "warning", "area": "support", "message": "{ns}.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only part of the line, box, label and linefill functions; this one is not implemented, so the call is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-W1065": {"severity": "warning", "area": "support", "message": "chart.point.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only chart.point.new, now, from_index, from_time and copy; any other chart.point.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1066": {"severity": "warning", "area": "support", "message": "''export'' is a Pine library keyword; PineForge runs strategies only and does not support exported functions/types.", "hint": "Remove the ''export'' keyword (and inline any library code into the strategy script).", "explanation": "'export' marks library code; PineForge runs strategies only, so remove the keyword and inline any library code into the strategy; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1067": {"severity": "warning", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1068": {"severity": "warning", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1069": {"severity": "warning", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1070": {"severity": "warning", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"chain": {"kind": "identifier"}}}, - "PF-W1071": {"severity": "warning", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"chain": {"kind": "identifier"}}}, - "PF-W1072": {"severity": "warning", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"chain": {"kind": "identifier"}}}, - "PF-W1073": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": null, "explanation": "Members of the footprint.* namespace need tick-level bid/ask volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1074": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": null, "explanation": "Members of the volume_row.* namespace need tick-level volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1075": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: dividends.* is not available in PineForge — fundamental dividend data is not loaded.", "hint": null, "explanation": "dividends.* fields read fundamental dividend data, which PineForge does not load outside a recorded request; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1076": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: earnings.* is not available in PineForge — fundamental earnings data is not loaded.", "hint": null, "explanation": "earnings.* fields read fundamental earnings data, which PineForge does not load outside a recorded request; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1077": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: splits.* is not available in PineForge — corporate-action split data is not loaded.", "hint": null, "explanation": "splits.* fields read corporate-action split data, which PineForge does not load outside a recorded request; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1078": {"severity": "warning", "area": "support", "message": "{object_name}.{member} is a visual/style constant with no runtime value in PineForge backtests; it is only accepted as an argument to visual calls (plot, plotshape, hline, label.new, table.cell, ...), which PineForge parses and skips.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "A visual or style constant has no value in a backtest; it may only be passed to plotting and drawing calls, which PineForge skips; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1079": {"severity": "warning", "area": "support", "message": "{object_name}.{member} is not a Pine alert constant; only alert.freq_all, alert.freq_once_per_bar and alert.freq_once_per_bar_close exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The alert.* member is not one of Pine's alert frequency constants; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1080": {"severity": "warning", "area": "support", "message": "{object_name}.{member} is not a barmerge constant; only barmerge.gaps_on, barmerge.gaps_off, barmerge.lookahead_on and barmerge.lookahead_off exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The barmerge.* member is not one of Pine's gaps or lookahead constants; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1081": {"severity": "warning", "area": "support", "message": "syminfo.{member} is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge does not implement this syminfo.* member, so reading it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}}}, - "PF-W1082": {"severity": "warning", "area": "support", "message": "request.security parameter ''{kw_name}'' is not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts only a few named parameters in PineForge; this one is refused instead of being silently ignored, so remove it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kw_name": {"kind": "identifier"}}}, - "PF-W1083": {"severity": "warning", "area": "support", "message": "Extra positional arguments to request.security are not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts at most five positional arguments (symbol, timeframe, expression, gaps, lookahead); remove the extra ones; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1084": {"severity": "warning", "area": "support", "message": "request.security gaps must be barmerge.gaps_on or barmerge.gaps_off.", "hint": "Codegen only recognizes the barmerge.gaps_* literal; other values are silently treated as gaps_off.", "explanation": "The gaps argument of request.security must be written literally as barmerge.gaps_on or barmerge.gaps_off, the only forms PineForge reads; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1085": {"severity": "warning", "area": "support", "message": "request.security lookahead must be barmerge.lookahead_on or barmerge.lookahead_off.", "hint": "Codegen only recognizes the barmerge.lookahead_* literal; other values are silently treated as lookahead_off.", "explanation": "The lookahead argument of request.security must be written literally as barmerge.lookahead_on or barmerge.lookahead_off, the only forms PineForge reads; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, - "PF-W1086": {"severity": "warning", "area": "support", "message": "request.security: {kw_name}={object_name}.{val_member} is not supported. The engine ignores this kwarg, which would silently produce different prices from TradingView.", "hint": "Allowed values: {allowed}.", "explanation": "PineForge ignores request.security's price-adjustment settings, so only no-op values are accepted; others would silently give prices unlike TradingView's; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kw_name": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "val_member": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}}, - "PF-W1087": {"severity": "warning", "area": "support", "message": "request.security: {kw_name}=... must be a constant member access of the form {kw_name}. (got a non-constant expression).", "hint": "Allowed values: {allowed}.", "explanation": "A request.security price-adjustment setting must be a plain constant of the form name.value (like adjustment.none), not a computed expression; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kw_name": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}}, - "PF-W1088": {"severity": "warning", "area": "support", "message": "{name} {message} (TradingView: {spelled}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A nz or fixnan call whose arguments match none of TradingView's signatures (unknown name, too many or missing arguments) is refused, as TradingView refuses it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "spelled": {"kind": "identifier"}}}, - "PF-W1089": {"severity": "warning", "area": "support", "message": "ta.{name} {message} (TradingView: {signature}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A ta.* call whose arguments match none of TradingView's signatures (unknown or repeated parameter, too many or missing arguments) is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "signature": {"kind": "identifier"}}}, - "PF-W1090": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}}, - "PF-W1091": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}}, - "PF-W1092": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}}, - "PF-W1093": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}}, - "PF-W1094": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}}, - "PF-W1095": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}}, - "PF-W1096": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}}, - "PF-W1097": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}}, - "PF-W1500": {"severity": "warning", "area": "support", "message": "{call}: request.security symbol can select an alternate symbol, but PineForge always loads the current chart symbol.", "hint": "It reads no feed of another symbol: {reasons}. Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "A request.security whose symbol can select another symbol is approximated by the chart's own symbol, because no other-symbol feed can be registered for it.", "args": {"call": {"kind": "identifier"}, "reasons": {"kind": "text"}}}, - "PF-W1501": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "PineForge reads another symbol''s feed only for a symbol and timeframe registration computes before the first bar; {reasons}.", "explanation": "A request.security of another symbol has no pinned data, so the run stops with an error where its value is read; its symbol and timeframe must be known up front.", "args": {"call": {"kind": "identifier"}, "reasons": {"kind": "text"}}}, - "PF-W1502": {"severity": "warning", "area": "support", "message": "color(...) cast has no effect in PineForge backtests (visual only); it emits a default color.", "hint": null, "explanation": "A color(...) cast is visual only and has no effect on a backtest, so PineForge ignores it and uses a default color.", "args": {}}, - "PF-W1503": {"severity": "warning", "area": "support", "message": "strategy.risk.{name}(...) has partial PineForge runtime support.", "hint": "Verify risk behavior against PineForge results; unsupported risk edge cases may diverge from TradingView.", "explanation": "A strategy.risk.* call has only partial runtime support in PineForge, so check that your risk limits behave as they do on TradingView.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1504": {"severity": "warning", "area": "support", "message": "strategy.{name} parameter ''{param_name}'' is not supported by PineForge and is ignored.", "hint": null, "explanation": "A strategy order call passes a parameter PineForge does not support, so the parameter is ignored and the order runs without it.", "args": {"name": {"kind": "identifier"}, "param_name": {"kind": "identifier"}}}, - "PF-W1505": {"severity": "warning", "area": "support", "message": "ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does.", "hint": "A covered length-20 TradingView tape first returns a finite EMA at bar 19; standalone PineForge EMA is finite at bar 0. Its established lowering stays in place pending per-call-site population parity.", "explanation": "ta.ema is approximated during warmup: PineForge may return a finite value on early bars where TradingView still returns na, so early results can differ.", "args": {}}, - "PF-W1506": {"severity": "warning", "area": "support", "message": "color.{name}(...) has no effect in PineForge backtests (visual only); it evaluates its arguments and emits a default color.", "hint": null, "explanation": "A cosmetic color function has no effect on a backtest, so PineForge evaluates its arguments and uses a default color.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1507": {"severity": "warning", "area": "support", "message": "{ns}.{name}(...) is a visual no-op in PineForge backtests (drawing geometry is data; color/style/size are dropped).", "hint": null, "explanation": "A drawing setter for color, style or size is a visual no-op in PineForge, which keeps only the drawing's geometry as data.", "args": {"ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-W1508": {"severity": "warning", "area": "support", "message": "{name}(...) has no effect in PineForge backtests (visual only).", "hint": null, "explanation": "A call into a visual-only namespace such as table or polyline has no effect on backtest results, so PineForge ignores it.", "args": {"name": {"kind": "identifier"}}}, - "PF-W1509": {"severity": "warning", "area": "support", "message": "{full}(...) has no effect in PineForge backtests (visual only).", "hint": null, "explanation": "A call into a visual-only namespace such as table or polyline has no effect on backtest results, so PineForge ignores it.", "args": {"full": {"kind": "identifier"}}}, - "PF-W1510": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "In direct batch chart-scope evaluation, barstate.islast is true only on the final bar of PineForge''s fed chart-data window. Inside a request.security() history index, PineForge currently selects the false branch; requested-context last-bar state is not modeled.", "explanation": "barstate.islast is true only on the last bar of PineForge's fed data, and inside a request.security history index it selects the false branch.", "args": {"chain": {"kind": "identifier"}}}, - "PF-W1511": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "In direct historical batch chart-scope evaluation, PineForge approximates barstate.islastconfirmedhistory as true only on the final bar of the fed chart-data window. Inside a request.security() history index, PineForge currently selects the false branch; TradingView''s requested-context and realtime-boundary semantics are not modeled.", "explanation": "barstate.islastconfirmedhistory is approximated as true only on the final bar of the fed data window, and as false inside a request.security history index.", "args": {"chain": {"kind": "identifier"}}}, - "PF-W1512": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.isconfirmed follows PineForge last-tick execution state.", "explanation": "barstate.isconfirmed follows PineForge's last-tick execution state, so it can differ from TradingView's confirmation behavior.", "args": {"chain": {"kind": "identifier"}}}, - "PF-W1513": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.ishistory is always true in PineForge batch backtests.", "explanation": "barstate.ishistory is always true in PineForge batch backtests, because there is no real-time bar.", "args": {"chain": {"kind": "identifier"}}}, - "PF-W1514": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.isnew follows PineForge first-tick execution state.", "explanation": "barstate.isnew is only approximated in PineForge, following its first-tick execution state, so it may behave differently from TradingView.", "args": {"chain": {"kind": "identifier"}}}, - "PF-W1515": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.isrealtime is always false in PineForge batch backtests.", "explanation": "barstate.isrealtime is always false because PineForge runs batch backtests on historical bars only, so real-time-only logic never runs.", "args": {"chain": {"kind": "identifier"}}}, - "PF-W1516": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.bg_color has no meaning in a batch backtest (no chart theme); emits a default color.", "hint": null, "explanation": "chart.bg_color depends on the chart theme, which a batch backtest does not have, so PineForge substitutes a default color.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1517": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.fg_color has no meaning in a batch backtest (no chart theme); emits a default color.", "hint": null, "explanation": "chart.fg_color depends on the chart theme, which a batch backtest does not have, so PineForge substitutes a default color.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1518": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.left_visible_bar_time has no meaning in a batch backtest (no viewport); emits 0.", "hint": null, "explanation": "chart.left_visible_bar_time depends on the chart viewport, which a batch backtest does not have, so PineForge substitutes 0.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1519": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.right_visible_bar_time has no meaning in a batch backtest (no viewport); emits 0.", "hint": null, "explanation": "chart.right_visible_bar_time depends on the chart viewport, which a batch backtest does not have, so PineForge substitutes 0.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, - "PF-W1520": {"severity": "warning", "area": "support", "message": "syminfo.{member} is na unless the run declares the symbol''s {member} (syminfo metadata \"{member}\", a lane fact).", "hint": null, "explanation": "This syminfo field has no built-in value in PineForge: it is na unless the run supplies the symbol's value as metadata, so anything computed from it is na.", "args": {"member": {"kind": "identifier"}}}, - "PF-W1521": {"severity": "warning", "area": "support", "message": "syminfo.{member} returns na in current PineForge; any expression using it will be na. Will be backfilled by pineforge-data product.", "hint": null, "explanation": "This syminfo field is not provided by PineForge yet and always reads na, so any expression using it is na.", "args": {"member": {"kind": "identifier"}}}, - "PF-W1522": {"severity": "warning", "area": "support", "message": "syminfo.{member} returns na in current PineForge; condition will always be false. Will be backfilled by pineforge-data product.", "hint": null, "explanation": "This syminfo field is not provided by PineForge yet and always reads na, so a condition built on it is always false.", "args": {"member": {"kind": "identifier"}}}, - "PF-W1523": {"severity": "warning", "area": "support", "message": "request.security symbol can select an alternate symbol, but PineForge always loads the current chart symbol.", "hint": "Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "The request.security symbol can select another symbol, but PineForge always loads the chart's symbol; resolve every value to syminfo.tickerid for exact results.", "args": {}}, - "PF-W1524": {"severity": "warning", "area": "support", "message": "request.security lookahead_on changes HTF timing: the completed higher-timeframe value is exposed from the bucket''s first chart bar. PineForge emits this (engine-supported) but results differ from lookahead_off and, with a 0-offset HTF expression, repaint future data.", "hint": "The safe non-repainting form pairs lookahead_on with a [1] offset (e.g. close[1]) to read only completed prior HTF bars.", "explanation": "request.security with lookahead_on exposes higher-timeframe values early and can repaint future data; pair it with a [1] offset such as close[1] to stay safe.", "args": {}}, - "PF-W1525": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External corporate-action data not available in PineForge. A recorded series is read when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "No recorded series applies to this earnings, dividends or splits request, but its value only feeds plots, alerts or tables, so it becomes na; trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}}}, - "PF-W1526": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External corporate-action data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge has no earnings, dividends or splits data; this request's value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}}, - "PF-W1527": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External fundamentals data not available in PineForge. A recorded series is read when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "No recorded series applies to this request.financial call, but its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}}}, - "PF-W1528": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External fundamentals data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge has no fundamentals data for request.financial; its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}}, - "PF-W1529": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "Footprint (bid/ask volume) data not available in PineForge. A recorded series is read when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "No recorded series applies to this request.footprint call, but its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}}}, - "PF-W1530": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "Footprint (bid/ask volume) data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge has no footprint (bid/ask volume) data for request.footprint; its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}}, - "PF-W1531": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker), and reads another symbol''s feed only when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "Another symbol's feed is read only in the stated case; here the request's value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "vocab", "values": ["it is outside another request's expression", "it is request.security", "its expression holds no request of its own", "its gaps and lookahead are barmerge constants", "its request.footprint states ticks_per_row and va_percent as literal whole numbers", "registration computes its ignore_invalid_symbol before the first bar", "registration computes its symbol before the first bar", "registration computes its timeframe before the first bar"]}}}, - "PF-W1532": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker). The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge loads only the chart's symbol; this request for another symbol only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}}, - "PF-W1533": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External corporate-action data not available in PineForge. A recorded series is read when {blocker}. Its value can reach a trade: {reason}.", "explanation": "No recorded series applies to this earnings, dividends or splits request and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}, "reason": {"kind": "text"}}}, - "PF-W1534": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External corporate-action data not available in PineForge. Its value can reach a trade: {reason}.", "explanation": "PineForge has no earnings, dividends or splits data and this request's value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}}, - "PF-W1535": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External fundamentals data not available in PineForge. A recorded series is read when {blocker}. Its value can reach a trade: {reason}.", "explanation": "No recorded series applies to this request.financial call and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}, "reason": {"kind": "text"}}}, - "PF-W1536": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External fundamentals data not available in PineForge. Its value can reach a trade: {reason}.", "explanation": "PineForge has no fundamentals data for request.financial and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}}, - "PF-W1537": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "Footprint (bid/ask volume) data not available in PineForge. A recorded series is read when {blocker}. Its value can reach a trade: {reason}.", "explanation": "No recorded series applies to this request.footprint call and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}, "reason": {"kind": "text"}}}, - "PF-W1538": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "Footprint (bid/ask volume) data not available in PineForge. Its value can reach a trade: {reason}.", "explanation": "PineForge has no footprint (bid/ask volume) data and this request's value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}}, - "PF-W1539": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker), and reads another symbol''s feed only when {blocker}. Its value can reach a trade: {reason}.", "explanation": "PineForge reads another symbol's feed only in the stated case, and this request's value can reach a trade, so the run stops with an error where it is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "vocab", "values": ["it is outside another request's expression", "it is request.security", "its expression holds no request of its own", "its gaps and lookahead are barmerge constants", "its request.footprint states ticks_per_row and va_percent as literal whole numbers", "registration computes its ignore_invalid_symbol before the first bar", "registration computes its symbol before the first bar", "registration computes its timeframe before the first bar"]}, "reason": {"kind": "text"}}}, - "PF-W1540": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker). Its value can reach a trade: {reason}.", "explanation": "PineForge loads only the chart's symbol, and this request for another symbol can reach a trade, so the run stops with an error where its value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}}, - "PF-W1541": {"severity": "warning", "area": "support", "message": "{call}: another symbol''s bars, read from the feed the requests manifest pins for it; with none installed, the run stops with an error where its value is read.", "hint": "PineForge runs the expression on that symbol''s own bars (history, ta.* and syminfo.* in its context) and merges them by time as TradingView does; a symbol equal to the chart''s reads the chart.", "explanation": "request.security on another symbol reads that symbol's pinned feed; if none is installed, the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}}}, - "PF-W1542": {"severity": "warning", "area": "support", "message": "{call}: its symbol can select another symbol: registered by the string the run computes, a footprint reads the feed the requests manifest pins for each symbol, the chart''s too (the chart''s bars carry no footprint); with none installed, the run stops with an error where its value is read.", "hint": "It read the chart''s bars for every symbol: another symbol''s value never comes from the chart.", "explanation": "The footprint symbol can vary: every symbol, the chart's too, reads its own pinned feed, and a missing feed stops the run where the value is read.", "args": {"call": {"kind": "identifier"}}}, - "PF-W1543": {"severity": "warning", "area": "support", "message": "{call}: its symbol can select another symbol: registered by the string the run computes, the chart''s reads the chart and another symbol''s the feed the requests manifest pins for it; with none installed, the run stops with an error where its value is read.", "hint": "It read the chart''s bars for every symbol: another symbol''s value never comes from the chart.", "explanation": "The request.security symbol can be the chart's or another symbol: the chart's reads the chart, another reads its pinned feed, and a missing feed stops the run.", "args": {"call": {"kind": "identifier"}}}, - "PF-W1544": {"severity": "warning", "area": "support", "message": "{call}: TradingView''s values per chart bar, read from the series the requests manifest records under {parts}||{parts2}|{parts3}|gaps_{parts4}|lookahead_{parts5}; with none installed, the run stops with an error where its value is read.", "hint": "PineForge replays the values TradingView returned on the chart''s own bars (chart_open_ms,value): a bar the tape has no row for reads na.", "explanation": "This request replays the values TradingView returned on each chart bar, from the requests manifest; with no recording installed the run stops where it is read.", "args": {"call": {"kind": "identifier"}, "parts": {"kind": "identifier"}, "parts2": {"kind": "identifier"}, "parts3": {"kind": "identifier"}, "parts4": {"kind": "identifier"}, "parts5": {"kind": "identifier"}}}, - "PF-W1545": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it decides a loop''s break or continue.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}}}, - "PF-W1546": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it is a history offset.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}}}, - "PF-W1547": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it is written to a field or element.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}}}, - "PF-W1548": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it reaches {label}.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}, "label": {"kind": "text"}}}, - "PF-W1549": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: its expression calls {label}.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}, "label": {"kind": "text"}}}, - "PF-W1550": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: its expression calls {ns}.{name}.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}, "ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, - "PF-W1551": {"severity": "warning", "area": "support", "message": "{call}: its symbol can be another symbol''s, whose lower-timeframe bars PineForge reads from the chart.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "The request.security_lower_tf symbol can be another symbol, but PineForge only has the chart's lower-timeframe bars and reads those, so results can differ.", "args": {"call": {"kind": "identifier"}}}, - "PF-W1552": {"severity": "warning", "area": "support", "message": "{call}: its symbol can be another symbol''s, whose lower-timeframe bars PineForge reads from the chart; its value reaches only display/alert sinks, so trades are unaffected.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "The lower-timeframe request may name another symbol but reads the chart's bars; its value only feeds plots, alerts or tables, so trades are unaffected.", "args": {"call": {"kind": "identifier"}}}, - "PF-W2001": {"severity": "warning", "area": "analysis", "message": "Untyped parameter ''{param}'' of callable ''{callee}'' receives {shared} and {incoming} at its written calls; a copy per call path would exceed {max_family_variants} copies and four per written call, so PineForge types it {shared}, as its first call, and converts the other argument. Declare the parameter type to choose it.", "hint": null, "explanation": "An untyped parameter receives two argument types and one copy per call would be too many, so PineForge types it as the first call's; declare the type to choose.", "args": {"param": {"kind": "identifier"}, "callee": {"kind": "identifier"}, "shared": {"kind": "type"}, "incoming": {"kind": "type"}, "max_family_variants": {"kind": "number"}}}, - "PF-W2002": {"severity": "warning", "area": "analysis", "message": "Untyped parameter ''{param}'' of callable ''{callee}'' receives {current} and {candidate} through calls that share one written-call variant (cs{cs_idx}); PineForge types it {current}, so the other argument is converted. Declare the parameter type to choose it.", "hint": null, "explanation": "An untyped parameter receives two argument types through calls sharing one variant; PineForge types it by the first and converts the other, so declare the type.", "args": {"param": {"kind": "identifier"}, "callee": {"kind": "identifier"}, "current": {"kind": "type"}, "candidate": {"kind": "type"}, "cs_idx": {"kind": "number"}}}, - "PF-W2003": {"severity": "warning", "area": "analysis", "message": "(...)[...] reads an element of the selected current array in PineForge: no history of a selection is kept, where TradingView reads the array it selected that many bars back.", "hint": null, "explanation": "Indexing a selected array with [] reads the current array, since PineForge keeps no history of selections; TradingView reads the array from that many bars back.", "args": {}}, - "PF-W2004": {"severity": "warning", "area": "analysis", "message": "input.source defval is not a native chart series (open, high, low, close, …); complex indicators or expressions are not supported in PineForge.", "hint": null, "explanation": "input.source needs a built-in chart series such as close as its default; indicators or other expressions are not supported in PineForge.", "args": {}}, - "PF-W2005": {"severity": "warning", "area": "analysis", "message": "input.timeframe defval ''{defval}'' is not a typical Pine timeframe string.", "hint": null, "explanation": "The default of input.timeframe is not a usual Pine timeframe string such as 15, 1D or W; check its spelling.", "args": {"defval": {"kind": "identifier"}}}, - "PF-W2006": {"severity": "warning", "area": "analysis", "message": "input.session defval ''{defval}'' may be invalid (expected e.g. ''24x7'', ''0930-1600'', or weekday flags).", "hint": null, "explanation": "The default of input.session may not be a valid session string; use forms like 24x7 or 0930-1600, optionally with weekday flags.", "args": {"defval": {"kind": "identifier"}}}, - "PF-W2007": {"severity": "warning", "area": "analysis", "message": "input.string defval is not among the options list values.", "hint": null, "explanation": "The default of input.string is not among its listed options; choose a default that appears in the options list.", "args": {}}, - "PF-W2008": {"severity": "warning", "area": "analysis", "message": "input.enum defval {ename}.{emem} is not a member of enum {ename}.", "hint": null, "explanation": "The default of input.enum names a member the enum does not declare; use one of the enum's own members.", "args": {"ename": {"kind": "identifier"}, "emem": {"kind": "identifier"}}}, - "PF-W2009": {"severity": "warning", "area": "analysis", "message": "input defval ''{name}'' is not a known chart series (open, high, low, close, …); verify spelling or use a series variable.", "hint": null, "explanation": "The default of this input is not a known chart series such as close; check the spelling or use a series variable.", "args": {"name": {"kind": "identifier"}}}, - "PF-W3001": {"severity": "warning", "area": "request-security", "message": "request.security timeframe reads ''{name}'', which the script reassigns: PineForge registers every request before the first bar, where it holds its initial value, and cannot compute it there (''{where}'' {reason})", "hint": null, "explanation": "The request.security timeframe reads a reassigned variable PineForge cannot compute before the first bar, so the request uses its initial value.", "args": {"name": {"kind": "identifier"}, "where": {"kind": "identifier"}, "reason": {"kind": "vocab", "values": ["is assigned a value it cannot compute there", "is assigned after the first request", "is not a scalar int, float, bool or string", "is not declared at the top level"]}}}, - "PF-W3002": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', a parameter of ''{helper}'' whose argument PineForge does not recompute on the requested bars: it reads na", "hint": null, "explanation": "A request.security expression reads the history of a function parameter PineForge does not recompute on the requested bars, so the read gives na.", "args": {"name": {"kind": "identifier"}, "helper": {"kind": "identifier"}}}, - "PF-W3003": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', a parameter of ''{helper}'' whose argument PineForge does not recompute on the requested bars: it reads the global ''{name}'' instead", "hint": null, "explanation": "A request.security expression reads the history of a function parameter PineForge does not recompute on requested bars, so it reads the same-named global instead.", "args": {"name": {"kind": "identifier"}, "helper": {"kind": "identifier"}}}, - "PF-W3004": {"severity": "warning", "area": "request-security", "message": "request.security payload calls function ''{callee_name}'' on the chart''s bar: a payload inlines a function under a builtin call only when its body is a single expression and so is every user call it makes, directly or through a global''s value; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A function called in a request.security expression runs on the chart's bar, since under a builtin call PineForge inlines only single-expression functions and calls.", "args": {"callee_name": {"kind": "identifier"}}}, - "PF-W3005": {"severity": "warning", "area": "request-security", "message": "request.security payload calls function ''{callee_name}'' on the chart''s bar: a payload inlines a method on the requested bar only for a scalar receiver and arguments and a single-expression body reading no mutable global, whose user calls, directly or through a global''s value, are single expressions too; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A user call in a request.security expression runs on the chart's bar, since PineForge inlines a method on the requested bar only for scalar, single-expression cases.", "args": {"callee_name": {"kind": "identifier"}}}, - "PF-W3006": {"severity": "warning", "area": "request-security", "message": "request.security payload calls function ''{callee_name}'' on the chart''s bar: the evaluator cannot inline it ({reason}); TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A function in a request.security expression runs on the chart's bar, not the requested one, because PineForge's evaluator cannot inline it for the stated reason.", "args": {"callee_name": {"kind": "identifier"}, "reason": {"kind": "text"}}}, - "PF-W3007": {"severity": "warning", "area": "request-security", "message": "request.security payload calls method ''{callee_member}'' on the chart''s bar: a payload inlines a function under a builtin call only when its body is a single expression and so is every user call it makes, directly or through a global''s value; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A method called in a request.security expression runs on the chart's bar, since under a builtin call PineForge inlines only single-expression functions and calls.", "args": {"callee_member": {"kind": "identifier"}}}, - "PF-W3008": {"severity": "warning", "area": "request-security", "message": "request.security payload calls method ''{callee_member}'' on the chart''s bar: a payload inlines a method on the requested bar only for a scalar receiver and arguments and a single-expression body reading no mutable global, whose user calls, directly or through a global''s value, are single expressions too; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A method called in a request.security expression runs on the chart's bar, since only scalar, single-expression methods are inlined on the requested bar.", "args": {"callee_member": {"kind": "identifier"}}}, - "PF-W3009": {"severity": "warning", "area": "request-security", "message": "request.security payload calls method ''{callee_member}'' on the chart''s bar: the evaluator cannot inline it ({reason}); TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A method in a request.security expression runs on the chart's bar, not the requested one, because PineForge's evaluator cannot inline it for the stated reason.", "args": {"callee_member": {"kind": "identifier"}, "reason": {"kind": "text"}}}, - "PF-W3010": {"severity": "warning", "area": "request-security", "message": "request.security payload keeps its user calls under builtin calls and its methods on the chart''s bar, as before: {message} (line {line}); TradingView evaluates them on the requested bar.", "hint": null, "explanation": "PineForge keeps this request.security payload's user calls under builtin calls and its methods on the chart's bar, for the stated reason, unlike TradingView.", "args": {"message": {"kind": "text"}, "line": {"kind": "number"}}}, - "PF-W3011": {"severity": "warning", "area": "request-security", "message": "request.security payload keeps its user calls under builtin calls and its methods on the chart''s bar, as before: {message}; TradingView evaluates them on the requested bar.", "hint": null, "explanation": "PineForge keeps this request.security payload's user calls under builtin calls and its methods on the chart's bar, for the stated reason, unlike TradingView.", "args": {"message": {"kind": "text"}}}, - "PF-W3012": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', an element of a tuple declaration, on the chart''s bar; TradingView reads it on the requested bar.", "hint": null, "explanation": "A request.security expression reads the history of a tuple-declared variable on the chart's bar, where TradingView reads it on the requested bar.", "args": {"name": {"kind": "identifier"}}}, - "PF-W3013": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{object_name}'' under a builtin call on the chart''s bar; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A request.security expression reads a variable's history inside a builtin call on the chart's bar, where TradingView evaluates it on the requested bar.", "args": {"object_name": {"kind": "identifier"}}}, - "PF-W5001": {"severity": "warning", "area": "codegen", "message": "strategy(use_bar_magnifier=...) is not a literal bool: the generated strategy does not declare the bar magnifier, so a host runs it without one.", "hint": "Write use_bar_magnifier = true or false.", "explanation": "Write use_bar_magnifier as a literal true or false; any other expression is ignored, so the strategy declares no bar magnifier and the host runs without one.", "args": {}}, - "PF-W5002": {"severity": "warning", "area": "codegen", "message": "input key ''{key}'' is shared by the inputs at {spots} and {spots2}: PineForge sets an input override by its title, else by the name of the declaration holding it, so one override sets all of them.", "hint": "Give each input its own title to override them apart.", "explanation": "Several inputs share one override key (their title, else their declaration's name), so one override sets all of them; give each input its own title.", "args": {"key": {"kind": "identifier"}, "spots": {"kind": "text"}, "spots2": {"kind": "text"}}}, - "PF-W5003": {"severity": "warning", "area": "codegen", "message": "array.slice returns a copy in PineForge; TradingView slices share source elements, so writes through either array can diverge.", "hint": "Avoid mutating a slice or its source while the slice is used.", "explanation": "array.slice returns an independent copy in PineForge, while TradingView's slice shares elements, so avoid mutating a slice or its source while both are used.", "args": {}}, - "PF-W5004": {"severity": "warning", "area": "codegen", "message": "A {kind} is stored as a 32-bit int in PineForge; this value can exceed int32, where TradingView''s int is 64-bit, and is truncated (or read as na) there.", "hint": "Declare the values float to keep every digit.", "explanation": "This collection element is stored as a 32-bit int, so a value beyond int32 is truncated or read as na, unlike TradingView's 64-bit int; declare the values float.", "args": {"kind": {"kind": "vocab", "values": ["map<..., int> value", "matrix element"]}}}, - "PF-W5005": {"severity": "warning", "area": "codegen", "message": "An {kind} is stored as a 32-bit int in PineForge; this value can exceed int32, where TradingView''s int is 64-bit, and is truncated (or read as na) there.", "hint": "Declare the values float to keep every digit.", "explanation": "This collection element is stored as a 32-bit int, so a value beyond int32 is truncated or read as na, unlike TradingView's 64-bit int; declare the values float.", "args": {"kind": {"kind": "vocab", "values": ["array element"]}}}, - "PF-W5006": {"severity": "warning", "area": "codegen", "message": "na() of a string reads the empty string as na: PineForge stores a string na as \"\", so an authored empty string is na here, while TradingView tells the two apart.", "hint": null, "explanation": "na() of a string treats the empty string as na because PineForge stores a string na as an empty string, so an authored empty string reads as na.", "args": {}}, - "PF-W5007": {"severity": "warning", "area": "codegen", "message": "str.repeat is missing its count argument; PineForge emits an empty string for this invalid TradingView call.", "hint": null, "explanation": "str.repeat was called without its count argument, which TradingView rejects; PineForge emits an empty string instead.", "args": {}}, - "PF-W5008": {"severity": "warning", "area": "codegen", "message": "str.repeat count can be na: PineForge returns an empty string for that value, while TradingView returns na string. The engine has no nullable string value.", "hint": "Check na(count) before calling str.repeat when the result affects strategy logic.", "explanation": "str.repeat's count can be na; PineForge then returns an empty string where TradingView returns na, so check na(count) first if the result drives logic.", "args": {}}, - "PF-W5009": {"severity": "warning", "area": "codegen", "message": "session.{member} inside request.security keeps the time-of-day predicate at the security bar''s open time, which can differ from TradingView: {opens}a D/W/M bar, {daily} on TradingView, reads its open''s time of day. The chart''s own session flags read the engine''s session facts.", "hint": null, "explanation": "A session flag inside request.security is tested at the security bar's open time, which can differ from TradingView, notably for D/W/M bars.", "args": {"member": {"kind": "identifier"}, "opens": {"kind": "vocab", "values": ["", "a bar that opens in a session break and holds the reopen reads as out of market, and "]}, "daily": {"kind": "vocab", "values": ["always in market", "never post-market", "never pre-market"]}}}, - "PF-W5010": {"severity": "warning", "area": "codegen", "message": "{object_name}[...] reads the current {kind} in PineForge: no history of this parameter is kept, where TradingView reads the copy the call that many calls back left (fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "Indexing a function parameter's array or matrix with [] reads the current collection in PineForge, while TradingView reads the copy from that many calls back.", "args": {"object_name": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, - "PF-W5011": {"severity": "warning", "area": "codegen", "message": "{object_name}[...] reads the current {name} reference in PineForge: no history of this variable is kept here, where TradingView reads the reference it held that many bars back.", "hint": null, "explanation": "Indexing an object or drawing variable with [] reads its current reference in PineForge, while TradingView reads the reference it held that many bars back.", "args": {"object_name": {"kind": "identifier"}, "name": {"kind": "type"}}}, - "PF-W5012": {"severity": "warning", "area": "codegen", "message": "{kind} history indexing uses the current collection element in PineForge; the engine does not retain per-bar collection IDs, so this result can differ from TradingView and a missing index is not represented faithfully.", "hint": null, "explanation": "History indexing of an array or map reads the current element, as PineForge keeps no per-bar collection history, so results can differ from TradingView.", "args": {"kind": {"kind": "vocab", "values": ["array", "map"]}}} + "PF-E0000": {"severity": "error", "area": "uncatalogued", "message": "{message}", "hint": "{hint}", "explanation": "A diagnostic whose text no catalog template renders; the test suite refuses it, so a release never emits it.", "args": {"message": {"kind": "text"}, "hint": {"kind": "text"}}, "user_message": "PineForge reported an unrecognized compilation error."}, + "PF-E0001": {"severity": "error", "area": "source", "message": "Block nesting depth exceeds {max_nesting_depth} levels.", "hint": null, "explanation": "Indented blocks (if, for, while, functions) are nested deeper than PineForge allows; flatten the structure.", "args": {"max_nesting_depth": {"kind": "number"}}, "user_message": "Indented blocks (if, for, while, functions) are nested deeper than PineForge allows."}, + "PF-E0002": {"severity": "error", "area": "source", "message": "Invalid color literal: expected hex digits after ''#''", "hint": "Color literals must be #RRGGBB or #RRGGBBAA", "explanation": "A '#' starts a color literal but no hex digits follow it; write the color as #RRGGBB or #RRGGBBAA.", "args": {}, "user_message": "A ''#'' starts a color literal but no hex digits follow it."}, + "PF-E0003": {"severity": "error", "area": "source", "message": "Delimiter nesting depth exceeds {max_nesting_depth} levels.", "hint": null, "explanation": "Parentheses or square brackets are nested deeper than PineForge allows; split the expression into simpler steps.", "args": {"max_nesting_depth": {"kind": "number"}}, "user_message": "Parentheses or square brackets are nested deeper than PineForge allows."}, + "PF-E0004": {"severity": "error", "area": "source", "message": "Unexpected character: ''{ch}''", "hint": null, "explanation": "The script contains a character that is not valid Pine syntax outside a string; remove or replace it.", "args": {"ch": {"kind": "identifier"}}, "user_message": "The script contains a character that is not valid Pine syntax outside a string."}, + "PF-E0005": {"severity": "error", "area": "source", "message": "Malformed scientific notation: expected digits after exponent", "hint": "Example: 1.5e-3 or 2E10", "explanation": "A number in scientific notation has an exponent marker (e or E) with no digits after it; add the exponent digits or drop the marker.", "args": {}, "user_message": "A number in scientific notation has an exponent marker (e or E) with no digits after it."}, + "PF-E0006": {"severity": "error", "area": "source", "message": "Unterminated string literal: the line ends before its closing quote and the next line is not indented as a wrapped line.", "hint": "Close the string on its line, indent the line it wraps onto, or use a multiline string (\"\"\"...\"\"\").", "explanation": "A string is not closed on its line and the next line is not an indented continuation; close the quote or use a triple-quoted string.", "args": {}, "user_message": "A string is not closed on its line and the next line is not an indented continuation."}, + "PF-E0007": {"severity": "error", "area": "source", "message": "Unterminated multiline string literal: no closing {delimiter} before the end of the script.", "hint": "A multiline string ends at the next \"\"\" (or '''''' for one opened with ''''''); escape a quote that would end it early.", "explanation": "A triple-quoted string never reaches its closing delimiter before the script ends; add the closing triple quote or escape an early quote.", "args": {"delimiter": {"kind": "identifier"}}, "user_message": "A triple-quoted string never reaches its closing delimiter before the script ends."}, + "PF-E0008": {"severity": "error", "area": "source", "message": "Source size exceeds {max_source_chars} characters.", "hint": null, "explanation": "The script is larger than the maximum source size PineForge accepts; shorten it.", "args": {"max_source_chars": {"kind": "number"}}, "user_message": "The script is larger than the maximum source size PineForge accepts."}, + "PF-E0009": {"severity": "error", "area": "source", "message": "AST nesting depth exceeds {max_nesting_depth} nodes.", "hint": null, "explanation": "An expression or operator chain is so long that its syntax tree is deeper than PineForge allows; break it into several statements.", "args": {"max_nesting_depth": {"kind": "number"}}, "user_message": "An expression or operator chain is so long that its syntax tree is deeper than PineForge allows."}, + "PF-E0010": {"severity": "error", "area": "source", "message": "Transpilation time exceeds {max_transpile_seconds} seconds.", "hint": null, "explanation": "Transpiling the script ran past the time limit; simplify it, for example by reducing very large or deeply nested code.", "args": {"max_transpile_seconds": {"kind": "number"}}, "user_message": "Transpiling the script ran past the time limit."}, + "PF-E0011": {"severity": "error", "area": "source", "message": "Expected {expected_token}, got {token_type}(''{token}''). {msg}", "hint": null, "explanation": "The parser required one specific token here and found another; fix the syntax at the reported position.", "args": {"expected_token": {"kind": "keyword"}, "token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}, "msg": {"kind": "text"}}, "user_message": "The parser required one specific token here and found another."}, + "PF-E0012": {"severity": "error", "area": "source", "message": "Nesting depth exceeds {max_nesting_depth} levels.", "hint": null, "explanation": "Blocks, else-if chains, prefix operators or nested expressions go deeper than PineForge's nesting limit; flatten the code.", "args": {"max_nesting_depth": {"kind": "number"}}, "user_message": "Blocks, else-if chains, prefix operators or nested expressions go deeper than PineForge''s nesting limit."}, + "PF-E0013": {"severity": "error", "area": "source", "message": "Unexpected token {token_type}(''{token}'') after statement; expected a line break or comma", "hint": null, "explanation": "Two expressions sit on one line with nothing between them; separate statements with a line break or a comma.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "Two expressions sit on one line with nothing between them."}, + "PF-E0014": {"severity": "error", "area": "source", "message": "''export'' declarations belong to Pine libraries; PineForge transpiles strategies only", "hint": null, "explanation": "export marks a Pine library declaration, but PineForge transpiles strategies only; remove export or write a strategy.", "args": {}, "user_message": "export marks a Pine library declaration, but PineForge transpiles strategies only."}, + "PF-E0015": {"severity": "error", "area": "source", "message": "Expected LPAREN, got {token_type}(''{token}'').", "hint": null, "explanation": "A '(' is missing where a call, a declaration's argument list or a function definition requires one.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "A ''('' is missing where a call, a declaration''s argument list or a function definition requires one."}, + "PF-E0016": {"severity": "error", "area": "source", "message": "Expected RPAREN, got {token_type}(''{token}'').", "hint": null, "explanation": "A ')' is missing or misplaced: a call, parameter list or parenthesized expression is not closed properly.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "A '')'' is missing or misplaced: a call, parameter list or parenthesized expression is not closed properly."}, + "PF-E0017": {"severity": "error", "area": "source", "message": "''export'' must precede a function, method, type, enum or const declaration", "hint": null, "explanation": "In a library, export must be followed by a function, method, type, enum or const declaration; nothing else can be exported.", "args": {}, "user_message": "In a library, export must be followed by a function, method, type, enum or const declaration."}, + "PF-E0018": {"severity": "error", "area": "source", "message": "Expected IMPORT, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the import keyword to start an import statement but found another token; check the line's spelling.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "The parser expected the import keyword to start an import statement but found another token."}, + "PF-E0019": {"severity": "error", "area": "source", "message": "Expected IDENT, got {token_type}(''{token}'').", "hint": null, "explanation": "A name was expected here (a variable, function, parameter, field, type or loop variable) but another token was found.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "A name was expected here (a variable, function, parameter, field, type or loop variable) but another token was found."}, + "PF-E0020": {"severity": "error", "area": "source", "message": "Expected EQUALS, got {token_type}(''{token}'').", "hint": null, "explanation": "An '=' was expected after the declared name (variable, tuple or for-loop start); add it or fix the declaration.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "An ''='' was expected after the declared name (variable, tuple or for-loop start)."}, + "PF-E0021": {"severity": "error", "area": "source", "message": "Expected LBRACKET, got {token_type}(''{token}'').", "hint": null, "explanation": "A tuple declaration must start with '[' as in [a, b] = f(); the opening bracket is missing or misplaced.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "A tuple declaration must start with ''['' as in [a, b] = f()."}, + "PF-E0022": {"severity": "error", "area": "source", "message": "Expected RBRACKET, got {token_type}(''{token}'').", "hint": null, "explanation": "A ']' is missing: a tuple declaration, for-in destructuring, array literal or index expression is not closed.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "A '']'' is missing: a tuple declaration, for-in destructuring, array literal or index expression is not closed."}, + "PF-E0023": {"severity": "error", "area": "source", "message": "Expected FAT_ARROW, got {token_type}(''{token}'').", "hint": null, "explanation": "A function or method definition, or a switch case, needs '=>' here; it is missing or misplaced.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "A function or method definition, or a switch case, needs ''=>'' here."}, + "PF-E0024": {"severity": "error", "area": "source", "message": "Expected IF, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the if keyword at the start of an if statement but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "The parser expected the if keyword at the start of an if statement but found another token."}, + "PF-E0025": {"severity": "error", "area": "source", "message": "Expected NEWLINE, got {token_type}(''{token}'').", "hint": null, "explanation": "An if, else, for, while or switch header must end its line before its indented body; other tokens follow it on the same line.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "An if, else, for, while or switch header must end its line before its indented body."}, + "PF-E0026": {"severity": "error", "area": "source", "message": "Expected INDENT, got {token_type}(''{token}'').", "hint": null, "explanation": "An indented block was expected after the header or definition, but the next line is not indented further; indent the block's statements.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "An indented block was expected after the header or definition, but the next line is not indented further."}, + "PF-E0027": {"severity": "error", "area": "source", "message": "Expected DEDENT, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected an indented block to end but found other tokens; check the indentation of the block's lines.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "The parser expected an indented block to end but found other tokens."}, + "PF-E0028": {"severity": "error", "area": "source", "message": "Expected FOR, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the for keyword at the start of a for loop but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "The parser expected the for keyword at the start of a for loop but found another token."}, + "PF-E0029": {"severity": "error", "area": "source", "message": "Expected IN, got {token_type}(''{token}'').", "hint": null, "explanation": "A for-in loop with destructured variables is missing the in keyword after them.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "A for-in loop with destructured variables is missing the in keyword after them."}, + "PF-E0030": {"severity": "error", "area": "source", "message": "Expected TO, got {token_type}(''{token}'').", "hint": null, "explanation": "A counted for loop is missing the to keyword between its start and end values, as in for i = 0 to n.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "A counted for loop is missing the to keyword between its start and end values, as in for i = 0 to n."}, + "PF-E0031": {"severity": "error", "area": "source", "message": "Expected WHILE, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the while keyword at the start of a while loop but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "The parser expected the while keyword at the start of a while loop but found another token."}, + "PF-E0032": {"severity": "error", "area": "source", "message": "Expected SWITCH, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the switch keyword at the start of a switch but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "The parser expected the switch keyword at the start of a switch but found another token."}, + "PF-E0033": {"severity": "error", "area": "source", "message": "Expected COLON, got {token_type}(''{token}''). Expected '':'' in ternary", "hint": null, "explanation": "A ternary condition ? value must be followed by ':' and an else value; add the colon or complete the expression.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "A ternary condition ? value must be followed by '':'' and an else value."}, + "PF-E0034": {"severity": "error", "area": "source", "message": "Expected IDENT, got {token_type}(''{token}''). Expected member name", "hint": null, "explanation": "A '.' must be followed by a member name (a field or method); the token after the dot is not a name.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "A ''.'' must be followed by a member name (a field or method)."}, + "PF-E0035": {"severity": "error", "area": "source", "message": "duplicate keyword argument ''{key_tok}''", "hint": "Remove one ''{key_tok}='' binding; a keyword argument may be specified only once.", "explanation": "A call binds the same keyword argument twice; keep only one binding.", "args": {"key_tok": {"kind": "identifier"}}, "user_message": "A call binds the same keyword argument twice."}, + "PF-E0036": {"severity": "error", "area": "source", "message": "Numeric literal exceeds the generated C++ range.", "hint": null, "explanation": "A numeric literal is too large to be written in the generated C++ code; use a smaller number.", "args": {}, "user_message": "A numeric literal is too large to be written in the generated C++ code."}, + "PF-E0037": {"severity": "error", "area": "source", "message": "Unexpected token {token_type}(''{token}'')", "hint": null, "explanation": "The parser found a token that cannot start or continue an expression here; look for a stray or misplaced token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}, "user_message": "The parser found a token that cannot start or continue an expression here."}, + "PF-E1001": {"severity": "error", "area": "support", "message": "{context}: map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps with string keys only; declare the map's key type as string.", "args": {"context": {"kind": "text"}}, "user_message": "PineForge supports maps with string keys only."}, + "PF-E1002": {"severity": "error", "area": "support", "message": "{context}: map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps whose values are float, int, bool or string only; use one of those as the value type.", "args": {"context": {"kind": "text"}}, "user_message": "PineForge supports maps whose values are float, int, bool or string only."}, + "PF-E1003": {"severity": "error", "area": "support", "message": "matrix<{element_type}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead.", "args": {"element_type": {"kind": "type"}}, "user_message": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references."}, + "PF-E1004": {"severity": "error", "area": "support", "message": "matrix<{element_type}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type.", "args": {"element_type": {"kind": "type"}}, "user_message": "A matrix cannot hold another collection as its element type in PineForge."}, + "PF-E1005": {"severity": "error", "area": "support", "message": "input.color(...) requires a color defval (e.g. color.red or color.new(color.red, 50)).", "hint": null, "explanation": "input.color needs a color as its default value, for example color.red or color.new(color.red, 50).", "args": {}, "user_message": "input.color needs a color as its default value, for example color.red or color.new(color.red, 50)."}, + "PF-E1006": {"severity": "error", "area": "support", "message": "input.color(...) defval must be a color constant (color.red, ...), a color literal (#rrggbb), or a color.new(...) / color.rgb(...) builder. Arbitrary expressions are not supported: the engine has no color helper, so codegen routes input.color through the int getter — any non-color defval would silently store a numeric value with no color encoding.", "hint": "Replace the defval with color. or color.new(...).", "explanation": "The default of input.color must be a color constant, a #rrggbb literal or a color.new or color.rgb call; other expressions are refused.", "args": {}, "user_message": "The default of input.color must be a color constant, a #rrggbb literal or a color.new or color.rgb call."}, + "PF-E1007": {"severity": "error", "area": "support", "message": "input.source(...) requires a native series defval (close, open, high, low, hl2, hlc3, ohlc4, ...).", "hint": null, "explanation": "input.source needs a default chart series such as close as its first argument or defval.", "args": {}, "user_message": "input.source needs a default chart series such as close as its first argument or defval."}, + "PF-E1008": {"severity": "error", "area": "support", "message": "input.source(...) defval must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4). User series, computed expressions, and indicator outputs are not supported: input.source is restricted to native OHLCV series.", "hint": "Use one of: close, open, high, low, hl2, hlc3, ohlc4.", "explanation": "The default of input.source must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4); computed series are refused.", "args": {}, "user_message": "The default of input.source must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4)."}, + "PF-E1009": {"severity": "error", "area": "support", "message": "{kind}() declarations are not supported; PineForge runs strategies only.", "hint": "Replace the declaration with strategy(...) and add explicit entry/exit calls.", "explanation": "PineForge runs strategies only, so a script declared with indicator() or library() is refused; declare it with strategy() and add orders.", "args": {"kind": {"kind": "identifier"}}, "user_message": "PineForge runs strategies only, so a script declared with indicator() or library() is refused."}, + "PF-E1010": {"severity": "error", "area": "support", "message": "Tuple reassignment [..] {op} is not Pine syntax: TradingView declares a tuple with ''='' and has no tuple reassignment.", "hint": "Declare new names with [a, b] = f(), then reassign each variable on its own line.", "explanation": "Pine has no tuple reassignment: declare a tuple once with '=' and reassign each variable on its own line.", "args": {"op": {"kind": "keyword"}}, "user_message": "Pine has no tuple reassignment: declare a tuple once with ''='' and reassign each variable on its own line."}, + "PF-E1011": {"severity": "error", "area": "support", "message": "A tuple literal [..] cannot be a variable''s value: TradingView rejects it here (Syntax error at input ''['', CE10156). A tuple is only a function''s or an if/switch arm''s value or a request.security expression.", "hint": "Declare each variable on its own line (a = x, b = y), or return the tuple from a function: f() => [x, y], then [a, b] = f().", "explanation": "A tuple literal such as [a, b] cannot be assigned to a variable; return it from a function or if/switch arm and destructure the result.", "args": {}, "user_message": "A tuple literal such as [a, b] cannot be assigned to a variable."}, + "PF-E1012": {"severity": "error", "area": "support", "message": "A ternary cannot return a tuple: TradingView rejects [a, b] = c ? [..] : [..] (\"Ternary operations cannot return tuples\").", "hint": "Select the tuple with an if or switch: [a, b] = if c, each arm ending in its tuple.", "explanation": "A ternary cannot produce a tuple (TradingView rejects it too); choose between tuples with an if or switch instead.", "args": {}, "user_message": "A ternary cannot produce a tuple (TradingView rejects it too)."}, + "PF-E1013": {"severity": "error", "area": "support", "message": "ta.stoch(...) returns a single series in PineForge; tuple destructuring is not supported.", "hint": "Use k = ta.stoch(...) and compute smoothing separately if needed.", "explanation": "ta.stoch returns one series in PineForge, so destructuring it into a tuple is refused; assign it to a single variable.", "args": {}, "user_message": "ta.stoch returns one series in PineForge, so destructuring it into a tuple is refused."}, + "PF-E1014": {"severity": "error", "area": "support", "message": "History references on UDT drawing fields are not supported in PineForge.", "hint": "{var_name}.{object_member}[...] would be read as the current-bar field, not prior-bar history. Copy the field to a bare drawing variable first, or remove the history reference.", "explanation": "A history index on a drawing field of a user-defined type would silently read the current field, so it is refused; copy the field to a variable first.", "args": {"var_name": {"kind": "identifier"}, "object_member": {"kind": "identifier"}}, "user_message": "A history index on a drawing field of a user-defined type would silently read the current field, so it is refused."}, + "PF-E1015": {"severity": "error", "area": "support", "message": "History references on tuple-destructured drawing handles are not supported in PineForge.", "hint": "{object_name}[...] is a drawing handle from tuple destructuring; PineForge cannot historize that tuple element safely.", "explanation": "A drawing handle bound by tuple destructuring cannot be read through a history index; remove the history reference.", "args": {"object_name": {"kind": "identifier"}}, "user_message": "A drawing handle bound by tuple destructuring cannot be read through a history index."}, + "PF-E1016": {"severity": "error", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}}, "user_message": "TradingView rejects a method call written straight after a history index, x[k].method()."}, + "PF-E1017": {"severity": "error", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}, "user_message": "TradingView rejects a method call written straight after a history index, x[k].method()."}, + "PF-E1018": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "TradingView rejects a method call written straight after a history index, x[k].method()."}, + "PF-E1019": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "TradingView rejects a method call written straight after a history index, x[k].method()."}, + "PF-E1020": {"severity": "error", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}}, "user_message": "TradingView rejects a field read written straight after a history index, x[k].field."}, + "PF-E1021": {"severity": "error", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}, "user_message": "TradingView rejects a field read written straight after a history index, x[k].field."}, + "PF-E1022": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "TradingView rejects a field read written straight after a history index, x[k].field."}, + "PF-E1023": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "TradingView rejects a field read written straight after a history index, x[k].field."}, + "PF-E1024": {"severity": "error", "area": "support", "message": "footprint.{footprint}(...) is not supported.", "hint": "PineForge reads a footprint''s delta() only: the fp_delta__ column of the feed a requests manifest pins for the symbol requested.", "explanation": "PineForge reads only the delta of a footprint value; every other footprint member is refused.", "args": {"footprint": {"kind": "identifier"}}, "user_message": "PineForge reads only the delta of a footprint value."}, + "PF-E1025": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "Currency conversion data not available in PineForge.", "explanation": "PineForge has no currency-conversion data, so request.currency_rate is refused; supply the rate yourself, for example as an input.", "args": {"full": {"kind": "identifier"}}, "user_message": "PineForge has no currency-conversion data, so request.currency_rate is refused."}, + "PF-E1026": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "External Quandl data not available in PineForge.", "explanation": "PineForge cannot load external Quandl data, so request.quandl is refused; remove it.", "args": {"full": {"kind": "identifier"}}, "user_message": "PineForge cannot load external Quandl data, so request.quandl is refused."}, + "PF-E1027": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "External seed data feeds not available in PineForge.", "explanation": "PineForge cannot load external seed data feeds, so request.seed is refused; remove it.", "args": {"full": {"kind": "identifier"}}, "user_message": "PineForge cannot load external seed data feeds, so request.seed is refused."}, + "PF-E1028": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.kagi() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.kagi builds a Kagi symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.kagi builds a Kagi symbol, which PineForge cannot run."}, + "PF-E1029": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.linebreak() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.linebreak builds a Line Break symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.linebreak builds a Line Break symbol, which PineForge cannot run."}, + "PF-E1030": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.modify() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.modify builds a modified symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.modify builds a modified symbol identifier, which PineForge cannot request."}, + "PF-E1031": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.new() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.new builds another symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.new builds another symbol identifier, which PineForge cannot request."}, + "PF-E1032": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.pointfigure() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.pointfigure builds a Point and Figure symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.pointfigure builds a Point and Figure symbol, which PineForge cannot run."}, + "PF-E1033": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.renko() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.renko builds a Renko symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.renko builds a Renko symbol, which PineForge cannot run."}, + "PF-E1034": {"severity": "error", "area": "support", "message": "ticker.heikinashi(...) is supported only for the chart''s own symbol.", "hint": "Pass syminfo.tickerid: PineForge applies the Heikin-Ashi candle transform to the chart symbol inside request.security, but cannot load an alternate symbol''s HA candles.", "explanation": "ticker.heikinashi is accepted only for the chart's own symbol (syminfo.tickerid); another symbol's Heikin-Ashi candles cannot be loaded.", "args": {}, "user_message": "ticker.heikinashi is accepted only for the chart''s own symbol (syminfo.tickerid)."}, + "PF-E1035": {"severity": "error", "area": "support", "message": "{full}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves.", "args": {"full": {"kind": "identifier"}}, "user_message": "This call names a function on PineForge''s not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves."}, + "PF-E1036": {"severity": "error", "area": "support", "message": "{name}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves.", "args": {"name": {"kind": "identifier"}}, "user_message": "This call names a function on PineForge''s not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves."}, + "PF-E1037": {"severity": "error", "area": "support", "message": "{full}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "footprint.* calls need tick-level bid/ask volume rows, which a PineForge batch backtest does not load.", "args": {"full": {"kind": "identifier"}}, "user_message": "footprint.* calls need tick-level bid/ask volume rows, which a PineForge batch backtest does not load."}, + "PF-E1038": {"severity": "error", "area": "support", "message": "{full}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "volume_row.* calls need tick-level volume rows, which a PineForge batch backtest does not load.", "args": {"full": {"kind": "identifier"}}, "user_message": "volume_row.* calls need tick-level volume rows, which a PineForge batch backtest does not load."}, + "PF-E1039": {"severity": "error", "area": "support", "message": "library() declarations are not supported; PineForge runs strategies only.", "hint": "Use strategy(...) and inline or pre-expand library code before uploading.", "explanation": "PineForge runs strategies only, so a library() declaration is refused; use strategy() and paste any library code into the script.", "args": {}, "user_message": "PineForge runs strategies only, so a library() declaration is refused."}, + "PF-E1040": {"severity": "error", "area": "support", "message": "Bare barssince(...) is broken in PineForge codegen.", "hint": "Use ta.barssince(...) instead.", "explanation": "The bare barssince(...) form does not work in PineForge; call ta.barssince(...) instead.", "args": {}, "user_message": "The bare barssince(...) form does not work in PineForge."}, + "PF-E1041": {"severity": "error", "area": "support", "message": "ta.sum is not a PineScript v6 function.", "hint": "Use math.sum(...) instead.", "explanation": "ta.sum does not exist in Pine v6; use math.sum(source, length) for a rolling sum.", "args": {}, "user_message": "ta.sum does not exist in Pine v6."}, + "PF-E1042": {"severity": "error", "area": "support", "message": "ta.{name} is a PineScript v6 variable, not a function.", "hint": "Use ta.{name} without parentheses.", "explanation": "This ta.* name is a built-in variable, not a function, so write it without parentheses.", "args": {"name": {"kind": "identifier"}}, "user_message": "This ta.* name is a built-in variable, not a function, so write it without parentheses."}, + "PF-E1043": {"severity": "error", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.closedtrades or strategy.opentrades accessor is not available in PineForge; use one of the supported trade accessors.", "args": {"full": {"kind": "identifier"}}, "user_message": "This strategy.closedtrades or strategy.opentrades accessor is not available in PineForge."}, + "PF-E1044": {"severity": "error", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": "{hint}", "explanation": "Open trades have no exit data in Pine v6: this accessor exists only on strategy.closedtrades, so it cannot be read from strategy.opentrades.", "args": {"full": {"kind": "identifier"}, "hint": {"kind": "text"}}, "user_message": "Open trades have no exit data in Pine v6: this accessor exists only on strategy.closedtrades, so it cannot be read from strategy.opentrades."}, + "PF-E1045": {"severity": "error", "area": "support", "message": "strategy.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.* function is not implemented in PineForge; check the spelling or use a supported strategy function.", "args": {"name": {"kind": "identifier"}}, "user_message": "This strategy.* function is not implemented in PineForge."}, + "PF-E1046": {"severity": "error", "area": "support", "message": "strategy.exit(...) requires at least one price or trailing parameter in PineForge.", "hint": "Use strategy.close(...) for market exits.", "explanation": "strategy.exit needs a price or trailing parameter (profit, loss, limit, stop or a trail setting); use strategy.close for a plain market exit.", "args": {}, "user_message": "strategy.exit needs a price or trailing parameter (profit, loss, limit, stop or a trail setting)."}, + "PF-E1047": {"severity": "error", "area": "support", "message": "{full}(...) is not supported. Only request.security(...) and request.security_lower_tf(...) are available in PineForge.", "hint": "External request feeds and other request.* variants are intentionally unavailable.", "explanation": "Only request.security and request.security_lower_tf are supported; other request.* calls need data feeds PineForge does not provide.", "args": {"full": {"kind": "identifier"}}, "user_message": "Only request.security and request.security_lower_tf are supported."}, + "PF-E1048": {"severity": "error", "area": "support", "message": "ta.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this ta.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this ta.* function, so the call is refused instead of compiling to a silent stub."}, + "PF-E1049": {"severity": "error", "area": "support", "message": "math.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this math.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this math.* function, so the call is refused instead of compiling to a silent stub."}, + "PF-E1050": {"severity": "error", "area": "support", "message": "str.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this str.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this str.* function, so the call is refused instead of compiling to a silent stub."}, + "PF-E1051": {"severity": "error", "area": "support", "message": "input.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this input.* function, so the call is refused; use one of the supported input functions.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this input.* function, so the call is refused."}, + "PF-E1052": {"severity": "error", "area": "support", "message": "timeframe.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only timeframe.change and timeframe.in_seconds; any other timeframe.* function is refused.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge implements only timeframe.change and timeframe.in_seconds."}, + "PF-E1053": {"severity": "error", "area": "support", "message": "color.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only color.new, color.rgb and color.r/g/b/t; any other color.* function is refused.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge implements only color.new, color.rgb and color.r/g/b/t."}, + "PF-E1054": {"severity": "error", "area": "support", "message": "runtime.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only runtime.error; any other runtime.* function is refused.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge implements only runtime.error."}, + "PF-E1055": {"severity": "error", "area": "support", "message": "log.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only log.info, log.warning and log.error; any other log.* function is refused.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge implements only log.info, log.warning and log.error."}, + "PF-E1056": {"severity": "error", "area": "support", "message": "array.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this array.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this array.* function, so the call is refused instead of compiling to a silent stub."}, + "PF-E1057": {"severity": "error", "area": "support", "message": "map.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this map.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this map.* function, so the call is refused instead of compiling to a silent stub."}, + "PF-E1058": {"severity": "error", "area": "support", "message": "map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps support only string keys; declare the map with string as its key type.", "args": {}, "user_message": "PineForge maps support only string keys."}, + "PF-E1059": {"severity": "error", "area": "support", "message": "map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps can hold only float, int, bool or string values; other value types such as collections or objects are refused.", "args": {}, "user_message": "PineForge maps can hold only float, int, bool or string values."}, + "PF-E1060": {"severity": "error", "area": "support", "message": "matrix<{t}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type.", "args": {"t": {"kind": "type"}}, "user_message": "A matrix cannot hold another collection as its element type in PineForge."}, + "PF-E1061": {"severity": "error", "area": "support", "message": "matrix<{t}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead.", "args": {"t": {"kind": "type"}}, "user_message": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references."}, + "PF-E1062": {"severity": "error", "area": "support", "message": "matrix<{t}> element type not supported. Allowed: float, int, bool, string, color, or a declared UDT.", "hint": null, "explanation": "A matrix element must be float, int, bool, string, color or a declared user-defined type; any other element type is refused.", "args": {"t": {"kind": "type"}}, "user_message": "A matrix element must be float, int, bool, string, color or a declared user-defined type."}, + "PF-E1063": {"severity": "error", "area": "support", "message": "matrix.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this matrix.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this matrix.* function, so the call is refused instead of compiling to a silent stub."}, + "PF-E1064": {"severity": "error", "area": "support", "message": "{ns}.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only part of the line, box, label and linefill functions; this one is not implemented, so the call is refused.", "args": {"ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "PineForge implements only part of the line, box, label and linefill functions."}, + "PF-E1065": {"severity": "error", "area": "support", "message": "chart.point.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only chart.point.new, now, from_index, from_time and copy; any other chart.point.* function is refused.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge implements only chart.point.new, now, from_index, from_time and copy."}, + "PF-E1066": {"severity": "error", "area": "support", "message": "''export'' is a Pine library keyword; PineForge runs strategies only and does not support exported functions/types.", "hint": "Remove the ''export'' keyword (and inline any library code into the strategy script).", "explanation": "'export' marks library code; PineForge runs strategies only, so remove the keyword and inline any library code into the strategy.", "args": {}, "user_message": "Exported declarations are not supported in a strategy."}, + "PF-E1067": {"severity": "error", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"name": {"kind": "identifier"}}, "user_message": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView''s for the same script."}, + "PF-E1068": {"severity": "error", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"name": {"kind": "identifier"}}, "user_message": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView''s when the history windows differ."}, + "PF-E1069": {"severity": "error", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"name": {"kind": "identifier"}}, "user_message": "timenow is aliased to the current bar''s time in PineForge, not real wall-clock time, so logic relying on the real time will differ."}, + "PF-E1070": {"severity": "error", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"chain": {"kind": "identifier"}}, "user_message": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView''s for the same script."}, + "PF-E1071": {"severity": "error", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"chain": {"kind": "identifier"}}, "user_message": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView''s when the history windows differ."}, + "PF-E1072": {"severity": "error", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"chain": {"kind": "identifier"}}, "user_message": "timenow is aliased to the current bar''s time in PineForge, not real wall-clock time, so logic relying on the real time will differ."}, + "PF-E1073": {"severity": "error", "area": "support", "message": "{object_name}.{member}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": null, "explanation": "Members of the footprint.* namespace need tick-level bid/ask volume rows, which a PineForge batch backtest does not load.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "Members of the footprint.* namespace need tick-level bid/ask volume rows, which a PineForge batch backtest does not load."}, + "PF-E1074": {"severity": "error", "area": "support", "message": "{object_name}.{member}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": null, "explanation": "Members of the volume_row.* namespace need tick-level volume rows, which a PineForge batch backtest does not load.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "Members of the volume_row.* namespace need tick-level volume rows, which a PineForge batch backtest does not load."}, + "PF-E1075": {"severity": "error", "area": "support", "message": "{object_name}.{member}: dividends.* is not available in PineForge — fundamental dividend data is not loaded.", "hint": null, "explanation": "dividends.* fields read fundamental dividend data, which PineForge does not load outside a recorded request.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "dividends.* fields read fundamental dividend data, which PineForge does not load outside a recorded request."}, + "PF-E1076": {"severity": "error", "area": "support", "message": "{object_name}.{member}: earnings.* is not available in PineForge — fundamental earnings data is not loaded.", "hint": null, "explanation": "earnings.* fields read fundamental earnings data, which PineForge does not load outside a recorded request.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "earnings.* fields read fundamental earnings data, which PineForge does not load outside a recorded request."}, + "PF-E1077": {"severity": "error", "area": "support", "message": "{object_name}.{member}: splits.* is not available in PineForge — corporate-action split data is not loaded.", "hint": null, "explanation": "splits.* fields read corporate-action split data, which PineForge does not load outside a recorded request.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "splits.* fields read corporate-action split data, which PineForge does not load outside a recorded request."}, + "PF-E1078": {"severity": "error", "area": "support", "message": "{object_name}.{member} is a visual/style constant with no runtime value in PineForge backtests; it is only accepted as an argument to visual calls (plot, plotshape, hline, label.new, table.cell, ...), which PineForge parses and skips.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "A visual or style constant has no value in a backtest; it may only be passed to plotting and drawing calls, which PineForge skips.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "A visual or style constant has no value in a backtest."}, + "PF-E1079": {"severity": "error", "area": "support", "message": "{object_name}.{member} is not a Pine alert constant; only alert.freq_all, alert.freq_once_per_bar and alert.freq_once_per_bar_close exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The alert.* member is not one of Pine's alert frequency constants.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "The alert.* member is not one of Pine''s alert frequency constants."}, + "PF-E1080": {"severity": "error", "area": "support", "message": "{object_name}.{member} is not a barmerge constant; only barmerge.gaps_on, barmerge.gaps_off, barmerge.lookahead_on and barmerge.lookahead_off exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The barmerge.* member is not one of Pine's gaps or lookahead constants.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "The barmerge.* member is not one of Pine''s gaps or lookahead constants."}, + "PF-E1081": {"severity": "error", "area": "support", "message": "syminfo.{member} is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge does not implement this syminfo.* member, so reading it is refused.", "args": {"member": {"kind": "identifier"}}, "user_message": "PineForge does not implement this syminfo.* member, so reading it is refused."}, + "PF-E1082": {"severity": "error", "area": "support", "message": "request.security parameter ''{kw_name}'' is not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts only a few named parameters in PineForge; this one is refused instead of being silently ignored, so remove it.", "args": {"kw_name": {"kind": "identifier"}}, "user_message": "request.security accepts only a few named parameters in PineForge."}, + "PF-E1083": {"severity": "error", "area": "support", "message": "Extra positional arguments to request.security are not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts at most five positional arguments (symbol, timeframe, expression, gaps, lookahead); remove the extra ones.", "args": {}, "user_message": "request.security accepts at most five positional arguments (symbol, timeframe, expression, gaps, lookahead)."}, + "PF-E1084": {"severity": "error", "area": "support", "message": "request.security gaps must be barmerge.gaps_on or barmerge.gaps_off.", "hint": "Codegen only recognizes the barmerge.gaps_* literal; other values are silently treated as gaps_off.", "explanation": "The gaps argument of request.security must be written literally as barmerge.gaps_on or barmerge.gaps_off, the only forms PineForge reads.", "args": {}, "user_message": "The gaps argument of request.security must be written literally as barmerge.gaps_on or barmerge.gaps_off, the only forms PineForge reads."}, + "PF-E1085": {"severity": "error", "area": "support", "message": "request.security lookahead must be barmerge.lookahead_on or barmerge.lookahead_off.", "hint": "Codegen only recognizes the barmerge.lookahead_* literal; other values are silently treated as lookahead_off.", "explanation": "The lookahead argument of request.security must be written literally as barmerge.lookahead_on or barmerge.lookahead_off, the only forms PineForge reads.", "args": {}, "user_message": "The lookahead argument of request.security must be written literally as barmerge.lookahead_on or barmerge.lookahead_off, the only forms PineForge reads."}, + "PF-E1086": {"severity": "error", "area": "support", "message": "request.security: {kw_name}={object_name}.{val_member} is not supported. The engine ignores this kwarg, which would silently produce different prices from TradingView.", "hint": "Allowed values: {allowed}.", "explanation": "PineForge ignores request.security's price-adjustment settings, so only no-op values are accepted; others would silently give prices unlike TradingView's.", "args": {"kw_name": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "val_member": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}, "user_message": "PineForge ignores request.security''s price-adjustment settings, so only no-op values are accepted."}, + "PF-E1087": {"severity": "error", "area": "support", "message": "request.security: {kw_name}=... must be a constant member access of the form {kw_name}. (got a non-constant expression).", "hint": "Allowed values: {allowed}.", "explanation": "A request.security price-adjustment setting must be a plain constant of the form name.value (like adjustment.none), not a computed expression.", "args": {"kw_name": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}, "user_message": "A request.security price-adjustment setting must be a plain constant of the form name.value (like adjustment.none), not a computed expression."}, + "PF-E1088": {"severity": "error", "area": "support", "message": "{name} {message} (TradingView: {spelled}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A nz or fixnan call whose arguments match none of TradingView's signatures (unknown name, too many or missing arguments) is refused, as TradingView refuses it.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "spelled": {"kind": "identifier"}}, "user_message": "A nz or fixnan call whose arguments match none of TradingView''s signatures (unknown name, too many or missing arguments) is refused, as TradingView refuses it."}, + "PF-E1089": {"severity": "error", "area": "support", "message": "ta.{name} {message} (TradingView: {signature}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A ta.* call whose arguments match none of TradingView's signatures (unknown or repeated parameter, too many or missing arguments) is refused.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "signature": {"kind": "identifier"}}, "user_message": "A ta.* call whose arguments match none of TradingView''s signatures (unknown or repeated parameter, too many or missing arguments) is refused."}, + "PF-E1090": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}, "user_message": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused."}, + "PF-E1091": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}, "user_message": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused."}, + "PF-E1092": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}, "user_message": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused."}, + "PF-E1093": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}, "user_message": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused."}, + "PF-E1094": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}, "user_message": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused."}, + "PF-E1095": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}, "user_message": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused."}, + "PF-E1096": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}, "user_message": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused."}, + "PF-E1097": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}, "user_message": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused."}, + "PF-E2001": {"severity": "error", "area": "analysis", "message": "Missing PineScript version directive. PineForge supports PineScript v6 only.", "hint": "Add //@version=6 as the first line of your script.", "explanation": "PineForge accepts only Pine v6 scripts; add //@version=6 as the first line.", "args": {}, "user_message": "The script needs a Pine v6 version directive."}, + "PF-E2002": {"severity": "error", "area": "analysis", "message": "PineForge supports PineScript v6 only (found //@version={version}).", "hint": "Migrate the script to //@version=6 using TradingView''s editor.", "explanation": "The script declares a Pine version other than 6, which PineForge does not support; migrate it to v6 using TradingView's editor.", "args": {"version": {"kind": "number"}}, "user_message": "The script declares a Pine version other than 6, which PineForge does not support."}, + "PF-E2003": {"severity": "error", "area": "analysis", "message": "Direct temporary-array element call ''{callee_name}()'' resolves to a local or parameter, not a user-defined function.", "hint": null, "explanation": "A function ends by reading a temporary array built from a call such as f(), but f is a local or parameter there, not a user-defined function; rename it.", "args": {"callee_name": {"kind": "identifier"}}, "user_message": "A function ends by reading a temporary array built from a call such as f(), but f is a local or parameter there, not a user-defined function."}, + "PF-E2004": {"severity": "error", "area": "analysis", "message": "Tuple-return helper wrapper ''{wrapper_name}'' calls later-defined helper ''{callee_name}''; forward tuple-wrapper calls are not supported yet. Move ''{callee_name}'' above ''{wrapper_name}'' before passing the wrapper to request.security().", "hint": null, "explanation": "A function that returns another function's tuple must come after it; define the called helper above the wrapper before passing the wrapper to request.security.", "args": {"wrapper_name": {"kind": "identifier"}, "callee_name": {"kind": "identifier"}}, "user_message": "A function that returns another function''s tuple must come after it."}, + "PF-E2005": {"severity": "error", "area": "analysis", "message": "Recursive direct temporary-array reader cycle is not supported: {cycle}.", "hint": null, "explanation": "Functions that read an element of a temporary array call each other in a cycle; Pine forbids recursion and PineForge cannot emit it.", "args": {"cycle": {"kind": "identifier"}}, "user_message": "Functions that read an element of a temporary array call each other in a cycle."}, + "PF-E2006": {"severity": "error", "area": "analysis", "message": "Persistent bindings named ''{raw_name}'' still share generated storage across distinct lexical declarations; this declaration shape is not supported yet.", "hint": null, "explanation": "A var declaration reuses a name that another declaration in a different scope also uses, and PineForge would give them one shared storage slot; rename one.", "args": {"raw_name": {"kind": "identifier"}}, "user_message": "A var declaration reuses a name that another declaration in a different scope also uses, and PineForge would give them one shared storage slot."}, + "PF-E2007": {"severity": "error", "area": "analysis", "message": "A top-level block history binding named ''{name}'' shares raw generated Series state with another lexical declaration; declaration-exact block storage is not supported yet.", "hint": null, "explanation": "A top-level block variable whose history is read shares its name with another declaration, so PineForge cannot keep their histories apart; rename one.", "args": {"name": {"kind": "identifier"}}, "user_message": "A top-level block variable whose history is read shares its name with another declaration, so PineForge cannot keep their histories apart."}, + "PF-E2008": {"severity": "error", "area": "analysis", "message": "A callable history local named ''{name}'' shares raw generated Series state with another lexical declaration; declaration-exact callable storage is not supported yet.", "hint": null, "explanation": "A function-local variable has its history read and shares its name with another declaration, so PineForge cannot keep separate history; rename one.", "args": {"name": {"kind": "identifier"}}, "user_message": "A function-local variable has its history read and shares its name with another declaration, so PineForge cannot keep separate history."}, + "PF-E2009": {"severity": "error", "area": "analysis", "message": "History references on a scalar callable local named ''{raw_name}'' conflict with a persistent map local of the same name in another callable; scoped Series member storage is not implemented yet.", "hint": null, "explanation": "A function-local scalar read with history shares its name with a persistent map variable in another function, which PineForge cannot yet separate; rename one.", "args": {"raw_name": {"kind": "identifier"}}, "user_message": "A function-local scalar read with history shares its name with a persistent map variable in another function, which PineForge cannot yet separate."}, + "PF-E2010": {"severity": "error", "area": "analysis", "message": "A top-level block binding named ''{name}'' shadows a direct script binding with history, aggregate, or incompatible typed state; declaration-exact block storage is not supported yet.", "hint": null, "explanation": "A variable declared inside a top-level block reuses the name of a script-level variable with history, a collection or a different type; rename one.", "args": {"name": {"kind": "identifier"}}, "user_message": "A variable declared inside a top-level block reuses the name of a script-level variable with history, a collection or a different type."}, + "PF-E2011": {"severity": "error", "area": "analysis", "message": "Persistent drawing bindings named ''{name}'' in distinct lexical owners would share one generated state member; rename one binding until callable-owned persistent storage is owner-qualified.", "hint": null, "explanation": "Two var-declared drawing objects (line, box, label or linefill) in different scopes share one name and would share one state member; rename one.", "args": {"name": {"kind": "identifier"}}, "user_message": "Two var-declared drawing objects (line, box, label or linefill) in different scopes share one name and would share one state member."}, + "PF-E2012": {"severity": "error", "area": "analysis", "message": "Persistent drawing state named ''{name}'' collides with a top-level class-member binding; rename one binding until persistent storage is owner-qualified.", "hint": null, "explanation": "A var-declared drawing object shares its name with a top-level script variable, so PineForge would give them one state member; rename one.", "args": {"name": {"kind": "identifier"}}, "user_message": "A var-declared drawing object shares its name with a top-level script variable, so PineForge would give them one state member."}, + "PF-E2013": {"severity": "error", "area": "analysis", "message": "Persistent drawing binding ''{name}'' shadows an ancestor callable parameter or local; rename one binding until callable-owned persistent storage has lexical owner qualification.", "hint": null, "explanation": "A var-declared drawing object inside a function reuses the name of an enclosing parameter or local; rename one.", "args": {"name": {"kind": "identifier"}}, "user_message": "A var-declared drawing object inside a function reuses the name of an enclosing parameter or local."}, + "PF-E2014": {"severity": "error", "area": "analysis", "message": "Callable TA ownership propagation did not converge; recursive stateful call paths are unsupported.", "hint": null, "explanation": "PineForge could not work out which functions own the ta.* state because stateful functions call each other recursively; remove the recursion.", "args": {}, "user_message": "PineForge could not work out which functions own the ta.* state because stateful functions call each other recursively."}, + "PF-E2015": {"severity": "error", "area": "analysis", "message": "Cannot safely specialize untyped parameter ''{param}'' of callable ''{callee}'': distinct primitive types collapse onto the same written-call variant cs{cs_idx}. Inline the calls or declare an explicit parameter type.", "hint": null, "explanation": "An untyped parameter receives different primitive types (such as int and float) from calls PineForge cannot tell apart; declare its type or inline the calls.", "args": {"param": {"kind": "identifier"}, "callee": {"kind": "identifier"}, "cs_idx": {"kind": "number"}}, "user_message": "An untyped parameter receives different primitive types (such as int and float) from calls PineForge cannot tell apart."}, + "PF-E2016": {"severity": "error", "area": "analysis", "message": "Cannot infer the per-callsite primitive type of history parameter ''{param}'' in callable ''{name}'' variant cs{cs_idx}; declare its type explicitly.", "hint": null, "explanation": "A function reads history of a parameter whose type PineForge cannot infer at this call; declare the parameter type explicitly.", "args": {"param": {"kind": "identifier"}, "name": {"kind": "identifier"}, "cs_idx": {"kind": "number"}}, "user_message": "A function reads history of a parameter whose type PineForge cannot infer at this call."}, + "PF-E2017": {"severity": "error", "area": "analysis", "message": "request.security timeframe parameter ''{tf_param}'' of function ''{containing}'' is passed a timeframe that reads the chart bar (''{series}''): PineForge registers each call site''s timeframe before the first bar.", "hint": null, "explanation": "A timeframe passed to a helper's request.security reads chart-bar data, but PineForge fixes it before the first bar; pass a constant or input timeframe instead.", "args": {"tf_param": {"kind": "identifier"}, "containing": {"kind": "identifier"}, "series": {"kind": "identifier"}}, "user_message": "A timeframe passed to a helper''s request.security reads chart-bar data, but PineForge fixes it before the first bar."}, + "PF-E2018": {"severity": "error", "area": "analysis", "message": "Import is not supported: ''{import_path}''", "hint": null, "explanation": "The script imports a library PineForge cannot inline, usually because its source was not supplied or pinned, or it is not open source.", "args": {"import_path": {"kind": "identifier"}}, "user_message": "The script imports a library PineForge cannot inline, usually because its source was not supplied or pinned, or it is not open source."}, + "PF-E2019": {"severity": "error", "area": "analysis", "message": "Import is not supported: ''{import_path}'': {reason}", "hint": null, "explanation": "The script imports a library PineForge cannot inline, usually because its source was not supplied or pinned, or it is not open source.", "args": {"import_path": {"kind": "identifier"}, "reason": {"kind": "text"}}, "user_message": "The script imports a library PineForge cannot inline, usually because its source was not supplied or pinned, or it is not open source."}, + "PF-E2020": {"severity": "error", "area": "analysis", "message": "Undefined variable: ''{name}''", "hint": null, "explanation": "The script assigns a new value (:=) to a name that was never declared; declare the variable first.", "args": {"name": {"kind": "identifier"}}, "user_message": "The script assigns a new value (:=) to a name that was never declared."}, + "PF-E2021": {"severity": "error", "area": "analysis", "message": "PineScript has no ta.sum; use math.sum(source, length) for rolling sum", "hint": null, "explanation": "ta.sum does not exist in Pine v6; use math.sum(source, length) for a rolling sum.", "args": {}, "user_message": "ta.sum does not exist in Pine v6."}, + "PF-E2022": {"severity": "error", "area": "analysis", "message": "{name}.copy(...) expects exactly one object argument", "hint": null, "explanation": "The functional copy form Type.copy(obj) needs exactly one object argument and no named arguments.", "args": {"name": {"kind": "type"}}, "user_message": "The functional copy form Type.copy(obj) needs exactly one object argument and no named arguments."}, + "PF-E2023": {"severity": "error", "area": "analysis", "message": "{receiver_spec_name}.copy() expects no arguments", "hint": null, "explanation": "obj.copy() on a user-defined type takes no arguments; call it with empty parentheses.", "args": {"receiver_spec_name": {"kind": "type"}}, "user_message": "obj.copy() on a user-defined type takes no arguments."}, + "PF-E2024": {"severity": "error", "area": "analysis", "message": "{key}: argument ''{name}'' passed both positionally and by keyword", "hint": null, "explanation": "A call to a typed method gives the same parameter both by position and by keyword; pass it only once.", "args": {"key": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "A call to a typed method gives the same parameter both by position and by keyword."}, + "PF-E2025": {"severity": "error", "area": "analysis", "message": "{key}: missing required argument ''{name}''", "hint": null, "explanation": "A call to a typed method omits a parameter that has no default value; pass an argument for it.", "args": {"key": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "A call to a typed method omits a parameter that has no default value."}, + "PF-E2026": {"severity": "error", "area": "analysis", "message": "{key}: too many positional arguments (expected {names_count}, got {args_count})", "hint": null, "explanation": "A call to a typed method passes more positional arguments than the method declares; remove the extra arguments.", "args": {"key": {"kind": "identifier"}, "names_count": {"kind": "number"}, "args_count": {"kind": "number"}}, "user_message": "A call to a typed method passes more positional arguments than the method declares."}, + "PF-E2027": {"severity": "error", "area": "analysis", "message": "{key}: unknown keyword argument ''{name}''", "hint": null, "explanation": "A call to a typed method uses a keyword argument name that the method does not declare; check the parameter spelling.", "args": {"key": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "A call to a typed method uses a keyword argument name that the method does not declare."}, + "PF-E2028": {"severity": "error", "area": "analysis", "message": "History references on map IDs are not supported in PineForge; map rollback uses identity snapshots rather than Series.", "hint": null, "explanation": "PineForge cannot read earlier-bar history of a map with the [] operator; read the map directly or keep earlier values in other variables.", "args": {}, "user_message": "PineForge cannot read earlier-bar history of a map with the [] operator."}, + "PF-E2029": {"severity": "error", "area": "analysis", "message": "History references on map-bearing UDTs or collections are not supported in PineForge; their Series value copy would retain live map aliases.", "hint": null, "explanation": "PineForge cannot read earlier-bar history of a user-defined type or collection that contains a map, because the copy would keep live map references.", "args": {}, "user_message": "PineForge cannot read earlier-bar history of a user-defined type or collection that contains a map, because the copy would keep live map references."}, + "PF-E2030": {"severity": "error", "area": "analysis", "message": "User function ''{owner}'' is called with incompatible map parameter types; PineForge cannot emit multiple map specializations for one untyped function.", "hint": null, "explanation": "A function with untyped parameters is called with different map types, and PineForge can generate only one map specialization per function; declare the type.", "args": {"owner": {"kind": "identifier"}}, "user_message": "A function with untyped parameters is called with different map types, and PineForge can generate only one map specialization per function."}, + "PF-E2031": {"severity": "error", "area": "analysis", "message": "History references on scalar local or loop bindings that shadow a map ID are not supported until PineForge can allocate a lexically scoped Series buffer for that binding.", "hint": null, "explanation": "A local or loop variable that reuses a map's name is read with history ([n]), which PineForge cannot buffer yet; rename the variable.", "args": {}, "user_message": "A local or loop variable that reuses a map''s name is read with history ([n]), which PineForge cannot buffer yet."}, + "PF-E2032": {"severity": "error", "area": "analysis", "message": "{receiver}.{member}[...]: TradingView refuses the history-referencing operator on fields of user-defined types (CE10290).", "hint": "Read the field of the object''s history: ({receiver}[1]).{member}.", "explanation": "TradingView refuses the [] history operator on a field of a user-defined type; read the field of the object's history instead, as (obj[1]).field.", "args": {"receiver": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "TradingView refuses the [] history operator on a field of a user-defined type."}, + "PF-E2033": {"severity": "error", "area": "analysis", "message": "request.security tuple-return helpers support two or more int, float, bool or string elements; inferred {tuple_size} element(s) [{inferred_types}]", "hint": null, "explanation": "A tuple-returning helper called inside request.security must yield two or more int, float, bool or string elements; its inferred shape did not qualify.", "args": {"tuple_size": {"kind": "number"}, "inferred_types": {"kind": "type"}}, "user_message": "A tuple-returning helper called inside request.security must yield two or more int, float, bool or string elements."}, + "PF-E2034": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf has unknown parameter(s): {unknown}. Supported parameters: {param_names}", "hint": null, "explanation": "request.security_lower_tf was called with keyword arguments it does not accept; use only the supported parameters listed.", "args": {"unknown": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}, "user_message": "request.security_lower_tf was called with keyword arguments it does not accept."}, + "PF-E2035": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf requires an expression argument", "hint": null, "explanation": "request.security_lower_tf was called without its expression argument, so there is nothing to evaluate on the lower timeframe.", "args": {}, "user_message": "request.security_lower_tf was called without its expression argument, so there is nothing to evaluate on the lower timeframe."}, + "PF-E2036": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf does not support tuple expressions yet. Issue separate request.security_lower_tf calls for each series.", "hint": null, "explanation": "request.security_lower_tf cannot return a tuple; issue one request.security_lower_tf call for each series you need.", "args": {}, "user_message": "request.security_lower_tf cannot return a tuple."}, + "PF-E2037": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf element type ''{element_label}'' is not yet supported. Supported element types: float, int, bool. UDT / color / string element types are out of scope.", "hint": null, "explanation": "request.security_lower_tf can only collect float, int or bool values per intrabar; string, color and object expressions are not supported.", "args": {"element_label": {"kind": "type"}}, "user_message": "request.security_lower_tf can only collect float, int or bool values per intrabar."}, + "PF-E2038": {"severity": "error", "area": "analysis", "message": "Enum ''{ename}'' must be declared above this input.enum() call (or the name is misspelled).", "hint": null, "explanation": "input.enum() names an enum that is not declared above the call (or is misspelled); declare the enum first or fix the name.", "args": {"ename": {"kind": "identifier"}}, "user_message": "input.enum() names an enum that is not declared above the call (or is misspelled)."}, + "PF-E2039": {"severity": "error", "area": "analysis", "message": "Cannot materialize callable state for unknown function ''{func_name}''.", "hint": null, "explanation": "Internal error: PineForge could not find a user function or method whose indicator state it needed to copy; this is a transpiler bug to report.", "args": {"func_name": {"kind": "identifier"}}, "user_message": "Internal error: PineForge could not find a user function or method whose indicator state it needed to copy."}, + "PF-E3001": {"severity": "error", "area": "request-security", "message": "request.security timeframe ''{name}'' cannot be resolved before the first bar: PineForge registers every requested timeframe before the script runs.", "hint": "Pass a literal, an input or a global to the helper that holds request.security.", "explanation": "The timeframe given to request.security is a name whose value PineForge cannot compute before the first bar; use a literal, an input or a global.", "args": {"name": {"kind": "identifier"}}, "user_message": "The timeframe given to request.security is a name whose value PineForge cannot compute before the first bar."}, + "PF-E3002": {"severity": "error", "area": "request-security", "message": "request.security timeframe expression cannot be resolved before the first bar: PineForge registers every requested timeframe before the script runs.", "hint": "Pass a literal, an input or a global to the helper that holds request.security.", "explanation": "The timeframe expression given to request.security cannot be computed before the first bar; use a literal, an input or a global.", "args": {}, "user_message": "The timeframe expression given to request.security cannot be computed before the first bar."}, + "PF-E3003": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch arms must contain one expression", "hint": "Compute multi-statement timeframe logic before the request.security call or rewrite it as pure switch arms.", "explanation": "A switch that picks a request.security timeframe must have exactly one expression in each arm; compute multi-statement logic beforehand.", "args": {}, "user_message": "A switch that picks a request.security timeframe must have exactly one expression in each arm."}, + "PF-E3004": {"severity": "error", "area": "request-security", "message": "request.security_lower_tf timeframe switch arm is na", "hint": "TradingView reads an na timeframe as the chart''s, which the engine''s lower-timeframe request rejects: spell a strictly finer timeframe.", "explanation": "A switch arm in a request.security_lower_tf timeframe is na, which a lower-timeframe request rejects; spell a strictly finer timeframe.", "args": {}, "user_message": "A switch arm in a request.security_lower_tf timeframe is na, which a lower-timeframe request rejects."}, + "PF-E3005": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch arm is na", "hint": "TradingView reads an na timeframe as the chart''s: spell the arm timeframe.period.", "explanation": "A switch arm in a request.security timeframe is na, which TradingView reads as the chart's timeframe; write timeframe.period instead.", "args": {}, "user_message": "A switch arm in a request.security timeframe is na, which TradingView reads as the chart''s timeframe."}, + "PF-E3006": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch arm could not be resolved at setup", "hint": null, "explanation": "A switch arm used as a request.security timeframe could not be evaluated, because PineForge registers every request before the first bar.", "args": {}, "user_message": "A switch arm used as a request.security timeframe could not be evaluated, because PineForge registers every request before the first bar."}, + "PF-E3007": {"severity": "error", "area": "request-security", "message": "request.security_lower_tf timeframe switch requires a default arm", "hint": "When no arm matches, TradingView reads the chart''s timeframe (one intrabar per chart bar); the engine''s lower-timeframe request needs a strictly finer timeframe.", "explanation": "A switch picking a request.security_lower_tf timeframe needs a default arm; without one TradingView uses the chart's timeframe, which is rejected.", "args": {}, "user_message": "A switch picking a request.security_lower_tf timeframe needs a default arm."}, + "PF-E3008": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch selector could not be resolved at setup", "hint": null, "explanation": "The selector of a switch that picks a request.security timeframe could not be evaluated before the first bar; use literals, inputs or timeframe values.", "args": {}, "user_message": "The selector of a switch that picks a request.security timeframe could not be evaluated before the first bar."}, + "PF-E3009": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch case could not be resolved at setup", "hint": null, "explanation": "A case value in a switch that picks a request.security timeframe could not be evaluated before the first bar; use literals, inputs or timeframe values.", "args": {}, "user_message": "A case value in a switch that picks a request.security timeframe could not be evaluated before the first bar."}, + "PF-E3010": {"severity": "error", "area": "request-security", "message": "request.security timeframe parameter ''{param_name}'' of ''{func_name}'' has no single timeframe across its call sites", "hint": "Pass the timeframe as a positional literal, input or global.", "explanation": "A helper's timeframe parameter used by request.security receives different timeframes at its call sites; pass one literal, input or global.", "args": {"param_name": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}, "user_message": "A helper''s timeframe parameter used by request.security receives different timeframes at its call sites."}, + "PF-E3011": {"severity": "error", "area": "request-security", "message": "request.security helper-parameter history currently requires a direct OHLC/time bar-series binding", "hint": null, "explanation": "History of a helper parameter inside request.security is only supported when the argument is a plain bar series such as close or time.", "args": {}, "user_message": "History of a helper parameter inside request.security is only supported when the argument is a plain bar series such as close or time."}, + "PF-E3012": {"severity": "error", "area": "request-security", "message": "request.security payload reads ''{name}'' with history and outside the helper block its call is lowered in: its state would advance twice a bar", "hint": "Read ''{name}'' once at the helper''s top level and use that local in the block.", "explanation": "A global holding a stateful call is read with history both inside and outside the helper block that lowers it, so its state would advance twice per bar.", "args": {"name": {"kind": "identifier"}}, "user_message": "A global holding a stateful call is read with history both inside and outside the helper block that lowers it, so its state would advance twice per bar."}, + "PF-E3013": {"severity": "error", "area": "request-security", "message": "Internal: request.security string helper state without its declared series map", "hint": null, "explanation": "Internal error: string state in a request.security helper was used before its series storage was declared; this is a transpiler bug to report.", "args": {}, "user_message": "Internal error: string state in a request.security helper was used before its series storage was declared."}, + "PF-E3014": {"severity": "error", "area": "request-security", "message": "Internal security helper emission requested for a non-linear helper plan", "hint": null, "explanation": "Internal error: PineForge tried to emit a request.security helper as straight-line code although its shape is not; this is a transpiler bug to report.", "args": {}, "user_message": "Internal error: PineForge tried to emit a request.security helper as straight-line code although its shape is not."}, + "PF-E3015": {"severity": "error", "area": "request-security", "message": "request.security helper-local var state currently supports only int, float, bool and string values", "hint": "Hoist collection, UDT, or drawing state outside request.security().", "explanation": "A var inside a request.security helper can only hold int, float, bool or string values; move collection, object or drawing state outside the request.", "args": {}, "user_message": "A var inside a request.security helper can only hold int, float, bool or string values."}, + "PF-E3016": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers may only assign to local identifier temporaries", "hint": null, "explanation": "A multi-statement request.security helper can only assign to plain local variables, not to fields, array elements or other targets.", "args": {}, "user_message": "A multi-statement request.security helper can only assign to plain local variables, not to fields, array elements or other targets."}, + "PF-E3017": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helper assignment target must be declared before use", "hint": null, "explanation": "A multi-statement request.security helper assigns to a variable it never declared; declare the local before assigning to it.", "args": {}, "user_message": "A multi-statement request.security helper assigns to a variable it never declared."}, + "PF-E3018": {"severity": "error", "area": "request-security", "message": "request.security helper tuple declaration: a string element read with history is not supported", "hint": "Declare the element with its own string variable.", "explanation": "A string element of a tuple declared in a request.security helper is read with history, which is unsupported; declare it as its own string variable.", "args": {}, "user_message": "A string element of a tuple declared in a request.security helper is read with history, which is unsupported."}, + "PF-E3019": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers may only use local declarations, assignments, and if-branches before the final expression", "hint": null, "explanation": "A multi-statement request.security helper may contain only local declarations, assignments, if-branches and loops before its final expression.", "args": {}, "user_message": "A multi-statement request.security helper may contain only local declarations, assignments, if-branches and loops before its final expression."}, + "PF-E3020": {"severity": "error", "area": "request-security", "message": "request.security helper while-loop conditions must be plain expressions of the helper''s values", "hint": null, "explanation": "A while-loop condition in a request.security helper must be a plain expression of the helper's own values.", "args": {}, "user_message": "A while-loop condition in a request.security helper must be a plain expression of the helper''s own values."}, + "PF-E3021": {"severity": "error", "area": "request-security", "message": "request.security helper calls must target named user-defined functions", "hint": null, "explanation": "request.security can only inline calls to named user-defined functions or typed methods, not other call forms.", "args": {}, "user_message": "request.security can only inline calls to named user-defined functions or typed methods, not other call forms."}, + "PF-E3022": {"severity": "error", "area": "request-security", "message": "request.security helper function ''{func_name}'' is not defined", "hint": null, "explanation": "A function called while inlining a request.security helper is not a user-defined function PineForge knows, so it cannot be inlined.", "args": {"func_name": {"kind": "identifier"}}, "user_message": "A function called while inlining a request.security helper is not a user-defined function PineForge knows, so it cannot be inlined."}, + "PF-E3023": {"severity": "error", "area": "request-security", "message": "request.security helper call has unknown parameter(s): {unknown_list}", "hint": null, "explanation": "A helper called inside request.security is given keyword arguments that are not among the function's parameters.", "args": {"unknown_list": {"kind": "identifier"}}, "user_message": "A helper called inside request.security is given keyword arguments that are not among the function''s parameters."}, + "PF-E3024": {"severity": "error", "area": "request-security", "message": "request.security helper calls must bind every parameter explicitly", "hint": null, "explanation": "A helper called inside request.security must be given an argument for every parameter; omitted defaults are not filled in there.", "args": {}, "user_message": "A helper called inside request.security must be given an argument for every parameter."}, + "PF-E3025": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers must end with a final expression result", "hint": null, "explanation": "A multi-statement request.security helper must end with an expression, declaration or assignment that gives its result.", "args": {}, "user_message": "A multi-statement request.security helper must end with an expression, declaration or assignment that gives its result."}, + "PF-E3026": {"severity": "error", "area": "request-security", "message": "request.security does not support multi-statement helpers with control flow", "hint": "Inline a straight-line helper body or hoist the control-flow helper outside request.security().", "explanation": "request.security cannot inline a multi-statement helper that contains for-in, switch, break or continue; inline a straight-line body or move it out.", "args": {}, "user_message": "request.security cannot inline a multi-statement helper that contains for-in, switch, break or continue."}, + "PF-E3027": {"severity": "error", "area": "request-security", "message": "request.security does not support helper-local varip state", "hint": "Use var for requested-context bar state; varip tick state is unavailable in batch backtests.", "explanation": "varip state is not available in a request.security helper; use var instead, since tick-level varip state does not exist in batch backtests.", "args": {}, "user_message": "varip state is not available in a request.security helper."}, + "PF-E3028": {"severity": "error", "area": "request-security", "message": "request.security helper-local var declarations inside conditional control flow are not supported", "hint": "Declare persistent requested-context state at the helper''s top level.", "explanation": "A var declared inside an if or other conditional block of a request.security helper is not supported; declare it at the helper's top level.", "args": {}, "user_message": "A var declared inside an if or other conditional block of a request.security helper is not supported."}, + "PF-E3029": {"severity": "error", "area": "request-security", "message": "request.security method TA constructor argument ''{cpp}'' is not a stable per-run scalar", "hint": null, "explanation": "A typed method called inside request.security builds a TA indicator whose argument is not fixed for the whole run; use a constant or input value.", "args": {"cpp": {"kind": "identifier"}}, "user_message": "A typed method called inside request.security builds a TA indicator whose argument is not fixed for the whole run."}, + "PF-E3030": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a TA call", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot contain a ta.* call; compute it before the loop, on the requested bar.", "args": {}, "user_message": "A for or while loop in a request.security helper cannot contain a ta.* call."}, + "PF-E3031": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a TA call (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a ta.* call through a parameter or global it reads; compute that value before the loop.", "args": {"via": {"kind": "text"}}, "user_message": "A loop in a request.security helper reaches a ta.* call through a parameter or global it reads."}, + "PF-E3032": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a user function call", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot call a user-defined function; compute the value before the loop.", "args": {}, "user_message": "A for or while loop in a request.security helper cannot call a user-defined function."}, + "PF-E3033": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a user function call (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a user function call through a parameter or global it reads; compute that value before the loop.", "args": {"via": {"kind": "text"}}, "user_message": "A loop in a request.security helper reaches a user function call through a parameter or global it reads."}, + "PF-E3034": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a var declaration", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot declare a var; compute the value before the loop.", "args": {}, "user_message": "A for or while loop in a request.security helper cannot declare a var."}, + "PF-E3035": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a var declaration (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a var declaration through a parameter or global it reads; compute that value before the loop.", "args": {"via": {"kind": "text"}}, "user_message": "A loop in a request.security helper reaches a var declaration through a parameter or global it reads."}, + "PF-E3036": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a {namespace}.* call", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot call request.* or strategy.* functions; compute the value before the loop.", "args": {"namespace": {"kind": "identifier"}}, "user_message": "A for or while loop in a request.security helper cannot call request.* or strategy.* functions."}, + "PF-E3037": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a {namespace}.* call (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a request.* or strategy.* call through a parameter or global it reads; compute it before the loop.", "args": {"namespace": {"kind": "identifier"}, "via": {"kind": "text"}}, "user_message": "A loop in a request.security helper reaches a request.* or strategy.* call through a parameter or global it reads."}, + "PF-E3038": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold the local ''{name}'', which is read with history", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper cannot read a local that is also read with history; compute that local before the loop.", "args": {"name": {"kind": "identifier"}}, "user_message": "A loop in a request.security helper cannot read a local that is also read with history."}, + "PF-E3039": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold the local ''{name}'', which is read with history (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a local read with history through a parameter or global; compute that local before the loop.", "args": {"name": {"kind": "identifier"}, "via": {"kind": "text"}}, "user_message": "A loop in a request.security helper reaches a local read with history through a parameter or global."}, + "PF-E3040": {"severity": "error", "area": "request-security", "message": "request.security mutable global rebinding does not support top-level switch", "hint": "Rewrite the switch as if/else assignments before passing the value to request.security().", "explanation": "A global read by the request.security expression is rebound inside a top-level switch, which PineForge cannot replay; rewrite it as if/else assignments.", "args": {}, "user_message": "A global read by the request.security expression is rebound inside a top-level switch, which PineForge cannot replay."}, + "PF-E3041": {"severity": "error", "area": "request-security", "message": "request.security mutable global rebinding does not support top-level loops", "hint": "Move loop-driven mutable state out of request.security() expressions or rewrite it as direct assignments.", "explanation": "A global read by the request.security expression is rebound inside a top-level loop, which PineForge cannot replay; use direct assignments or move it out.", "args": {}, "user_message": "A global read by the request.security expression is rebound inside a top-level loop, which PineForge cannot replay."}, + "PF-E3042": {"severity": "error", "area": "request-security", "message": "request.security does not support TA constructor args that depend on rebound mutable globals", "hint": "Keep TA constructor arguments immutable/simple inside request.security(), or hoist the TA call outside the security expression.", "explanation": "A TA length or other indicator argument inside request.security depends on a global the script reassigns; keep it constant or compute the TA outside.", "args": {}, "user_message": "A TA length or other indicator argument inside request.security depends on a global the script reassigns."}, + "PF-E3043": {"severity": "error", "area": "request-security", "message": "History of a {kind} reference inside a request.security expression is not supported in PineForge: TradingView reads the references the variable held on the requested timeframe''s bars, which PineForge does not keep.", "hint": "Request the field values the expression needs (request.security(..., obj.field)) and read their history on the chart.", "explanation": "request.security cannot read the history of a user-defined type or drawing reference, because PineForge keeps no references from the requested bars.", "args": {"kind": {"kind": "type"}}, "user_message": "request.security cannot read the history of a user-defined type or drawing reference, because PineForge keeps no references from the requested bars."}, + "PF-E3044": {"severity": "error", "area": "request-security", "message": "request.security payload reads ''{name}'', an element of a tuple declaration it cannot re-evaluate", "hint": null, "explanation": "The request.security expression reads a name bound by a tuple declaration that PineForge cannot re-evaluate on the requested bar.", "args": {"name": {"kind": "identifier"}}, "user_message": "The request.security expression reads a name bound by a tuple declaration that PineForge cannot re-evaluate on the requested bar."}, + "PF-E3045": {"severity": "error", "area": "request-security", "message": "request.security payload reads ''{name}'', an element of a TA tuple it does not compute once per requested bar", "hint": null, "explanation": "The request.security expression reads an element of a TA tuple that PineForge does not compute once per requested bar.", "args": {"name": {"kind": "identifier"}}, "user_message": "The request.security expression reads an element of a TA tuple that PineForge does not compute once per requested bar."}, + "PF-E3046": {"severity": "error", "area": "request-security", "message": "request.security() bar-field history index must be non-negative", "hint": null, "explanation": "A negative history offset on a bar series such as close[-1] is not allowed inside request.security.", "args": {}, "user_message": "A negative history offset on a bar series such as close[-1] is not allowed inside request.security."}, + "PF-E3047": {"severity": "error", "area": "request-security", "message": "request.security payload reads the history of ''{object_name}'', an element of a tuple declaration", "hint": null, "explanation": "The request.security expression reads the history of a name bound by a tuple declaration, which PineForge cannot do on the requested bars.", "args": {"object_name": {"kind": "identifier"}}, "user_message": "The request.security expression reads the history of a name bound by a tuple declaration, which PineForge cannot do on the requested bars."}, + "PF-E3048": {"severity": "error", "area": "request-security", "message": "request.security payload reads the string global ''{object_name}'' with history, which the requested clock does not keep", "hint": null, "explanation": "A string global read with history inside request.security is not supported, because the requested clock keeps no string history.", "args": {"object_name": {"kind": "identifier"}}, "user_message": "A string global read with history inside request.security is not supported, because the requested clock keeps no string history."}, + "PF-E3049": {"severity": "error", "area": "request-security", "message": "request.security() TA history index must be a literal integer (e.g. ta.ema(close, 55)[1])", "hint": "An int computed from inputs and literals is admitted; a series index is not.", "explanation": "A history offset on a TA call inside request.security must be an integer literal or a number computed from inputs and literals, not a series.", "args": {}, "user_message": "A history offset on a TA call inside request.security must be an integer literal or a number computed from inputs and literals, not a series."}, + "PF-E3050": {"severity": "error", "area": "request-security", "message": "request.security() TA history index must be non-negative", "hint": null, "explanation": "A negative history offset on a TA call inside request.security is not allowed.", "args": {}, "user_message": "A negative history offset on a TA call inside request.security is not allowed."}, + "PF-E3051": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helper TA history is not supported", "hint": "Use a single-expression helper for TA history offsets.", "explanation": "A TA history offset inside a multi-statement request.security helper is not supported; use a single-expression helper.", "args": {}, "user_message": "A TA history offset inside a multi-statement request.security helper is not supported."}, + "PF-E3052": {"severity": "error", "area": "request-security", "message": "request.security helper functions must not recurse while building a security context", "hint": null, "explanation": "A request.security helper calls itself, directly or through other helpers, which PineForge cannot inline; remove the recursion.", "args": {}, "user_message": "A request.security helper calls itself, directly or through other helpers, which PineForge cannot inline."}, + "PF-E3053": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers require statement-capable security evaluation context", "hint": null, "explanation": "A multi-statement helper is used inside a request.security expression at a spot where PineForge cannot emit statements, so it cannot be inlined there.", "args": {}, "user_message": "A multi-statement helper is used inside a request.security expression at a spot where PineForge cannot emit statements, so it cannot be inlined there."}, + "PF-E3054": {"severity": "error", "area": "request-security", "message": "the payload reads ''{func_name}'' on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"func_name": {"kind": "identifier"}}, "user_message": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart''s bar."}, + "PF-E3055": {"severity": "error", "area": "request-security", "message": "the payload reads ''{namespace}.{func_name}'' on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"namespace": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}, "user_message": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart''s bar."}, + "PF-E3056": {"severity": "error", "area": "request-security", "message": "the payload reads ''{name}'' on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"name": {"kind": "identifier"}}, "user_message": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart''s bar."}, + "PF-E3057": {"severity": "error", "area": "request-security", "message": "the payload reads a user call it cannot inline on the chart''s bar", "hint": null, "explanation": "A request.security payload reads something PineForge would evaluate on the chart's bar, where TradingView evaluates it on the requested bar, so it is refused.", "args": {}, "user_message": "A request.security payload reads something PineForge would evaluate on the chart''s bar, where TradingView evaluates it on the requested bar, so it is refused."}, + "PF-E3058": {"severity": "error", "area": "request-security", "message": "the payload reads a {node_type} on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"node_type": {"kind": "identifier"}}, "user_message": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart''s bar."}, + "PF-E3059": {"severity": "error", "area": "request-security", "message": "the payload reads history it does not keep on the requested clock on the chart''s bar", "hint": null, "explanation": "A request.security payload reads something PineForge would evaluate on the chart's bar, where TradingView evaluates it on the requested bar, so it is refused.", "args": {}, "user_message": "A request.security payload reads something PineForge would evaluate on the chart''s bar, where TradingView evaluates it on the requested bar, so it is refused."}, + "PF-E3060": {"severity": "error", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', an element of a tuple declaration", "hint": null, "explanation": "The request.security expression reads the history of a name bound by a tuple declaration, which PineForge cannot do on the requested bars.", "args": {"name": {"kind": "identifier"}}, "user_message": "The request.security expression reads the history of a name bound by a tuple declaration, which PineForge cannot do on the requested bars."}, + "PF-E3061": {"severity": "error", "area": "request-security", "message": "request.security helper switch arms must each be one expression", "hint": "Compute a multi-statement arm in its own helper, or on the chart.", "explanation": "A switch used as a request.security helper's value must have a single expression in each arm; move multi-statement arms into their own helper.", "args": {}, "user_message": "A switch used as a request.security helper''s value must have a single expression in each arm."}, + "PF-E3062": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: helper ''{func}'' {problem}", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A helper holding a request.security cannot have its symbol and timeframe resolved per call path, because it is overloaded or called from a method.", "args": {"request_name": {"kind": "identifier"}, "func": {"kind": "identifier"}, "problem": {"kind": "text"}}, "user_message": "A helper holding a request.security cannot have its symbol and timeframe resolved per call path, because it is overloaded or called from a method."}, + "PF-E3063": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{expr_name}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3064": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{expr}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3065": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{func}'' declares ''{names}''", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "func": {"kind": "identifier"}, "names": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3066": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{name}'' is not a value the requested bars recompute", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "A request''s symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path."}, + "PF-E3067": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{name}'' is reassigned or declared var", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3068": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: a {node_type} is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "node_type": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3069": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: it holds a request.{request_name2} call", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "request_name2": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3070": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: it reads ''{expr_name}'', a series", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3071": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: its value is too large", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3072": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: parameter ''{binding}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "binding": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3073": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: parameter ''{param}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "param": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3074": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the helpers reach it through too many call paths", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}}, "user_message": "A request''s symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path."}, + "PF-E3075": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the method call {expr}", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3076": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the user function call {callee_name}(...)", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "callee_name": {"kind": "identifier"}}, "user_message": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path."}, + "PF-E3077": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the value of ''{param}'' is not lowered on the requested bars", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "param": {"kind": "identifier"}}, "user_message": "A request''s symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path."}, + "PF-E3078": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{expr_name}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}, "user_message": "A request''s symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars."}, + "PF-E3079": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{expr}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr": {"kind": "identifier"}}, "user_message": "A request''s symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars."}, + "PF-E3080": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{func}'' declares ''{names}''", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "func": {"kind": "identifier"}, "names": {"kind": "identifier"}}, "user_message": "A request''s symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars."}, + "PF-E3081": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{name}'' is not a value the requested bars recompute", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "A request''s symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars."}, + "PF-E3082": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{name}'' is reassigned or declared var", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "A request''s symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars."}, + "PF-E3083": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: a {node_type} is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "node_type": {"kind": "identifier"}}, "user_message": "A request''s symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars."}, + "PF-E3084": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: it holds a request.{request_name2} call", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe holds another request, which PineForge cannot compute before the first bar.", "args": {"request_name": {"kind": "identifier"}, "request_name2": {"kind": "identifier"}}, "user_message": "A request''s symbol or timeframe holds another request, which PineForge cannot compute before the first bar."}, + "PF-E3085": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: it reads ''{expr_name}'', a series", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}, "user_message": "A request''s symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars."}, + "PF-E3086": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: its value is too large", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The value a request's context reads is too large for PineForge to resolve before the first bar.", "args": {"request_name": {"kind": "identifier"}}, "user_message": "The value a request''s context reads is too large for PineForge to resolve before the first bar."}, + "PF-E3087": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: parameter ''{binding}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A helper call leaves out the parameter the request's symbol or timeframe reads, so PineForge cannot resolve the request's context.", "args": {"request_name": {"kind": "identifier"}, "binding": {"kind": "identifier"}}, "user_message": "A helper call leaves out the parameter the request''s symbol or timeframe reads, so PineForge cannot resolve the request''s context."}, + "PF-E3088": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: parameter ''{param}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A helper call leaves out the parameter the request's symbol or timeframe reads, so PineForge cannot resolve the request's context.", "args": {"request_name": {"kind": "identifier"}, "param": {"kind": "identifier"}}, "user_message": "A helper call leaves out the parameter the request''s symbol or timeframe reads, so PineForge cannot resolve the request''s context."}, + "PF-E3089": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the helpers reach it through too many call paths", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The helpers holding this request are reached through too many call paths for PineForge to resolve each one's symbol and timeframe.", "args": {"request_name": {"kind": "identifier"}}, "user_message": "The helpers holding this request are reached through too many call paths for PineForge to resolve each one''s symbol and timeframe."}, + "PF-E3090": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the method call {expr}", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr": {"kind": "identifier"}}, "user_message": "A request''s symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars."}, + "PF-E3091": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the user function call {callee_name}(...)", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "callee_name": {"kind": "identifier"}}, "user_message": "A request''s symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars."}, + "PF-E3092": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the value of ''{param}'' is not lowered on the requested bars", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "param": {"kind": "identifier"}}, "user_message": "A request''s symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars."}, + "PF-E4001": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' has no valid sha256 in {where}", "hint": null, "explanation": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "text"}}, "user_message": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script."}, + "PF-E4002": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not among the libraries passed to transpile()", "hint": null, "explanation": "The imported library was not among the library sources supplied to the transpiler, so it cannot be inlined; supply its source text.", "args": {"path": {"kind": "identifier"}}, "user_message": "The imported library was not among the library sources supplied to the transpiler, so it cannot be inlined."}, + "PF-E4003": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not open-source (access ''{access}''); PineForge inlines open libraries only", "hint": null, "explanation": "The library's manifest entry says it is not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "access": {"kind": "identifier"}}, "user_message": "The library''s manifest entry says it is not open-source, and PineForge inlines open libraries only."}, + "PF-E4004": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not open-source (access ''{indexed_access}'' in libraries.json); PineForge inlines open libraries only", "hint": null, "explanation": "The library index marks this library as not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "indexed_access": {"kind": "identifier"}}, "user_message": "The library index marks this library as not open-source, and PineForge inlines open libraries only."}, + "PF-E4005": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not pinned by this script''s requests manifest ({where})", "hint": null, "explanation": "The script's requests manifest does not pin this imported library, so PineForge will not use any other source for it; add the library to the manifest.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "identifier"}}, "user_message": "The script''s requests manifest does not pin this imported library, so PineForge will not use any other source for it."}, + "PF-E4006": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' source does not match its pinned sha256 {sha}... (found {found_sha}...)", "hint": null, "explanation": "The library source that was found does not match the SHA-256 hash pinned in the manifest, so PineForge refuses to use it.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "found_sha": {"kind": "identifier"}}, "user_message": "The library source that was found does not match the SHA-256 hash pinned in the manifest, so PineForge refuses to use it."}, + "PF-E4007": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' source is missing (sha256 {sha}... under ${requests_env}/{slug_dir_name}/files and ${libraries_env})", "hint": null, "explanation": "No file matching the library's pinned SHA-256 hash was found in the configured directories, so its source is missing.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "requests_env": {"kind": "identifier"}, "slug_dir_name": {"kind": "identifier"}, "libraries_env": {"kind": "identifier"}}, "user_message": "No file matching the library''s pinned SHA-256 hash was found in the configured directories, so its source is missing."}, + "PF-E4008": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' source is not UTF-8 text", "hint": null, "explanation": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script.", "args": {"path": {"kind": "identifier"}}, "user_message": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script."}, + "PF-E4009": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': no library sources are configured", "hint": null, "explanation": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script.", "args": {"path": {"kind": "identifier"}}, "user_message": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script."}, + "PF-E4010": {"severity": "error", "area": "libraries", "message": "library ''{path}'' spells ''{clash}'', a name PineForge gave to an inlined definition", "hint": null, "explanation": "An imported library uses a name PineForge generates for its own inlined definitions, so the library cannot be inlined without a name clash.", "args": {"path": {"kind": "identifier"}, "clash": {"kind": "identifier"}}, "user_message": "An imported library uses a name PineForge generates for its own inlined definitions, so the library cannot be inlined without a name clash."}, + "PF-E4011": {"severity": "error", "area": "libraries", "message": "library ''{path}'' defines ''{name}'' {defs_count} times (overloads); PineForge does not inline an overloaded library function", "hint": null, "explanation": "The library defines this function several times (overloads) in a way PineForge cannot resolve, so it will not inline it; call a non-overloaded function.", "args": {"path": {"kind": "identifier"}, "name": {"kind": "identifier"}, "defs_count": {"kind": "number"}}, "user_message": "The library defines this function several times (overloads) in a way PineForge cannot resolve, so it will not inline it."}, + "PF-E4012": {"severity": "error", "area": "libraries", "message": "no overload of ''{name}'' of library ''{path}'' takes the arguments of this call", "hint": null, "explanation": "None of the library function's overloads accepts the arguments in this call; check the number of arguments and any keyword names.", "args": {"name": {"kind": "identifier"}, "path": {"kind": "identifier"}}, "user_message": "None of the library function''s overloads accepts the arguments in this call."}, + "PF-E4013": {"severity": "error", "area": "libraries", "message": "library ''{path}'' does not export ''{member}''", "hint": null, "explanation": "The name exists in the imported library but is not exported, so the script cannot use it through the import; use an exported name.", "args": {"path": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "The name exists in the imported library but is not exported, so the script cannot use it through the import."}, + "PF-E4014": {"severity": "error", "area": "libraries", "message": "library ''{path}'' does not export ''{member}'': it has no ''{member}''", "hint": null, "explanation": "The imported library has no such name at all; check the spelling of the member you access through the import alias.", "args": {"path": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "The imported library has no such name at all."}, + "PF-E4015": {"severity": "error", "area": "libraries", "message": "''{token}'' is not a type of library ''{targets}''", "hint": null, "explanation": "A type written as alias.Type is not an exported type or enum of that library; check the type's name and that the library exports it.", "args": {"token": {"kind": "identifier"}, "targets": {"kind": "identifier"}}, "user_message": "A type written as alias.Type is not an exported type or enum of that library."}, + "PF-E4016": {"severity": "error", "area": "libraries", "message": "library ''{path}'': a {statement} inside a function is not supported", "hint": null, "explanation": "A function in an imported library contains a nested declaration (function, method, type, enum, import or script declaration), which PineForge cannot inline.", "args": {"path": {"kind": "identifier"}, "statement": {"kind": "vocab", "values": ["EnumDecl", "FuncDef", "ImportStmt", "MethodDef", "StrategyDecl", "TypeDecl"]}}, "user_message": "A function in an imported library contains a nested declaration (function, method, type, enum, import or script declaration), which PineForge cannot inline."}, + "PF-E4017": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{targets}'' is a {kind}, not a value", "hint": null, "explanation": "The script reads a library function or method as a plain value; only exported constants, types and enums can be read that way, so call it instead.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["function", "method"]}}, "user_message": "The script reads a library function or method as a plain value."}, + "PF-E4018": {"severity": "error", "area": "libraries", "message": "library method ''{member}'' called without its receiver as the first positional argument", "hint": null, "explanation": "A library method was called through its import alias without the receiver as the first argument; pass the receiver first or call it as receiver.method().", "args": {"member": {"kind": "identifier"}}, "user_message": "A library method was called through its import alias without the receiver as the first argument."}, + "PF-E4019": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{targets}'' is a {kind}, not a function", "hint": null, "explanation": "The script calls an exported library type or constant like a function; only exported functions and methods can be called, so use it as a type or value.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["const", "type"]}}, "user_message": "The script calls an exported library type or constant like a function."}, + "PF-E4020": {"severity": "error", "area": "libraries", "message": "method ''{member}'' is exported by {exporters_count} imported libraries; a keyword argument cannot be bound to one", "hint": null, "explanation": "Several imported libraries export a method with this name, so a call that uses keyword arguments is ambiguous; pass the arguments by position.", "args": {"member": {"kind": "identifier"}, "exporters_count": {"kind": "number"}}, "user_message": "Several imported libraries export a method with this name, so a call that uses keyword arguments is ambiguous."}, + "PF-E4021": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{main_targets}'' is a {kind}, not a value", "hint": null, "explanation": "The script reads a library function or method as a plain value; only exported constants, types and enums can be read that way, so call it instead.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "main_targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["function", "method"]}}, "user_message": "The script reads a library function or method as a plain value."}, + "PF-E4022": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{main_targets}'' is a {kind}, not a function", "hint": null, "explanation": "The script calls an exported library type or constant like a function; only exported functions and methods can be called, so use it as a type or value.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "main_targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["const", "type"]}}, "user_message": "The script calls an exported library type or constant like a function."}, + "PF-E4023": {"severity": "error", "area": "libraries", "message": "import alias ''{alias}'' is used by two imports", "hint": null, "explanation": "Two imports use the same alias, so names like alias.member would be ambiguous; give each import its own alias.", "args": {"alias": {"kind": "identifier"}}, "user_message": "Two imports use the same alias, so names like alias.member would be ambiguous."}, + "PF-E4024": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{import_path}'': its alias ''{alias}'' is a built-in namespace other than ta, math or str", "hint": null, "explanation": "The import's alias is a built-in namespace other than ta, math or str, which PineForge does not allow; choose a different alias.", "args": {"import_path": {"kind": "identifier"}, "alias": {"kind": "identifier"}}, "user_message": "The import''s alias is a built-in namespace other than ta, math or str, which PineForge does not allow."}, + "PF-E4025": {"severity": "error", "area": "libraries", "message": "import alias ''{alias}'' is also declared as a variable, parameter or function", "hint": null, "explanation": "The import alias is also the name of a variable, parameter or function in the script, which would make the alias ambiguous; rename one of them.", "args": {"alias": {"kind": "identifier"}}, "user_message": "The import alias is also the name of a variable, parameter or function in the script, which would make the alias ambiguous."}, + "PF-E4026": {"severity": "error", "area": "libraries", "message": "method ''{name}'' of library ''{path}'' has the same receiver type as a method of {other}", "hint": null, "explanation": "Two methods share a name and receiver type, one in this library and one in the script or another library, so one would be unreachable.", "args": {"name": {"kind": "identifier"}, "path": {"kind": "identifier"}, "other": {"kind": "text"}}, "user_message": "Two methods share a name and receiver type, one in this library and one in the script or another library, so one would be unreachable."}, + "PF-E4027": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is //@version=5: its function reached from a request.{callee_member}() payload would run outside v5''s rules there", "hint": null, "explanation": "A function from a Pine v5 library is reached from a request.*() expression, where PineForge cannot apply v5 rules, so it is refused.", "args": {"path": {"kind": "identifier"}, "callee_member": {"kind": "identifier"}}, "user_message": "A function from a Pine v5 library is reached from a request.*() expression, where PineForge cannot apply v5 rules, so it is refused."}, + "PF-E4028": {"severity": "error", "area": "libraries", "message": "library ''{path}'' has {found}; PineForge inlines v5 and v6 libraries only", "hint": null, "explanation": "The imported library has no //@version line or a version other than 5 or 6; PineForge inlines only version 5 and 6 libraries.", "args": {"path": {"kind": "identifier"}, "found": {"kind": "text"}}, "user_message": "The imported library has no //@version line or a version other than 5 or 6."}, + "PF-E4029": {"severity": "error", "area": "libraries", "message": "''{path}'' is not a library: it has {found}, not one library() declaration", "hint": null, "explanation": "The imported source is not a library: it must hold exactly one library() declaration, but it has none or a different kind of declaration.", "args": {"path": {"kind": "identifier"}, "found": {"kind": "text"}}, "user_message": "The imported source is not a library: it must hold exactly one library() declaration, but it has none or a different kind of declaration."}, + "PF-E4030": {"severity": "error", "area": "libraries", "message": "library ''{path}'' has a malformed import: ''{path2}''", "hint": null, "explanation": "An import inside the library is malformed (it lacks a version or an alias), so PineForge cannot follow it.", "args": {"path": {"kind": "identifier"}, "path2": {"kind": "identifier"}}, "user_message": "An import inside the library is malformed (it lacks a version or an alias), so PineForge cannot follow it."}, + "PF-E4031": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is //@version=5: {exc}", "hint": null, "explanation": "A Pine v5 library uses a v5 behaviour that PineForge does not implement, so the library is refused; the reason names the construct.", "args": {"path": {"kind": "identifier"}, "exc": {"kind": "text"}}, "user_message": "A Pine v5 library uses a v5 behaviour that PineForge does not implement, so the library is refused."}, + "PF-E4032": {"severity": "error", "area": "libraries", "message": "no library sources are configured", "hint": null, "explanation": "No library sources were given to the transpiler and none are configured in the environment, so imports cannot be resolved.", "args": {}, "user_message": "No library sources were given to the transpiler and none are configured in the environment, so imports cannot be resolved."}, + "PF-E4033": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not among the libraries passed to transpile()", "hint": null, "explanation": "The imported library was not among the library sources supplied to the transpiler, so it cannot be inlined; supply its source text.", "args": {"path": {"kind": "identifier"}}, "user_message": "The imported library was not among the library sources supplied to the transpiler, so it cannot be inlined."}, + "PF-E4034": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not pinned by this script''s requests manifest ({where})", "hint": null, "explanation": "The script's requests manifest does not pin this imported library, so PineForge will not use any other source for it; add the library to the manifest.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "identifier"}}, "user_message": "The script''s requests manifest does not pin this imported library, so PineForge will not use any other source for it."}, + "PF-E4035": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not open-source (access ''{access}''); PineForge inlines open libraries only", "hint": null, "explanation": "The library's manifest entry says it is not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "access": {"kind": "identifier"}}, "user_message": "The library''s manifest entry says it is not open-source, and PineForge inlines open libraries only."}, + "PF-E4036": {"severity": "error", "area": "libraries", "message": "library ''{path}'' has no valid sha256 in {where}", "hint": null, "explanation": "The library's entry in the requests manifest has no valid SHA-256 hash, so its source cannot be verified; fix the entry.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "identifier"}}, "user_message": "The library''s entry in the requests manifest has no valid SHA-256 hash, so its source cannot be verified."}, + "PF-E4037": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not open-source (access ''{indexed_access}'' in libraries.json); PineForge inlines open libraries only", "hint": null, "explanation": "The library index marks this library as not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "indexed_access": {"kind": "identifier"}}, "user_message": "The library index marks this library as not open-source, and PineForge inlines open libraries only."}, + "PF-E4038": {"severity": "error", "area": "libraries", "message": "library ''{path}'' source is not UTF-8 text", "hint": null, "explanation": "The library's source is not valid UTF-8 text, so it cannot be read or inlined.", "args": {"path": {"kind": "identifier"}}, "user_message": "The library''s source is not valid UTF-8 text, so it cannot be read or inlined."}, + "PF-E4039": {"severity": "error", "area": "libraries", "message": "library ''{path}'' source does not match its pinned sha256 {sha}... (found {found_sha}...)", "hint": null, "explanation": "The library source that was found does not match the SHA-256 hash pinned in the manifest, so PineForge refuses to use it.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "found_sha": {"kind": "identifier"}}, "user_message": "The library source that was found does not match the SHA-256 hash pinned in the manifest, so PineForge refuses to use it."}, + "PF-E4040": {"severity": "error", "area": "libraries", "message": "library ''{path}'' source is missing (sha256 {sha}... under ${requests_env}/{slug_dir_name}/files and ${libraries_env})", "hint": null, "explanation": "No file matching the library's pinned SHA-256 hash was found in the configured directories, so its source is missing.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "requests_env": {"kind": "identifier"}, "slug_dir_name": {"kind": "identifier"}, "libraries_env": {"kind": "identifier"}}, "user_message": "No file matching the library''s pinned SHA-256 hash was found in the configured directories, so its source is missing."}, + "PF-E5001": {"severity": "error", "area": "codegen", "message": "Recursive stateful callable cycle is not supported: {cycle}.", "hint": "Remove the recursive call; Pine user-defined functions cannot execute recursively.", "explanation": "Stateful functions (with TA calls, var variables or history reads) call each other in a cycle; Pine forbids recursion, so remove the recursive call.", "args": {"cycle": {"kind": "identifier"}}, "user_message": "Stateful functions (with TA calls, var variables or history reads) call each other in a cycle."}, + "PF-E5002": {"severity": "error", "area": "codegen", "message": "matrix.{meth_name} requires matrix; got matrix<{elem_str}>", "hint": "Numeric-only methods are not available for matrix, matrix, matrix, or matrix.", "explanation": "This matrix method works only on matrix; it cannot be used on a matrix of int, bool, string or objects.", "args": {"meth_name": {"kind": "identifier"}, "elem_str": {"kind": "type"}}, "user_message": "This matrix method works only on matrix."}, + "PF-E5003": {"severity": "error", "area": "codegen", "message": "matrix.sort requires int, bool, string, or float element type; got {elem_name}", "hint": null, "explanation": "matrix.sort can sort only int, bool, string or float matrices, and this matrix has a different element type.", "args": {"elem_name": {"kind": "type"}}, "user_message": "matrix.sort can sort only int, bool, string or float matrices, and this matrix has a different element type."}, + "PF-E5004": {"severity": "error", "area": "codegen", "message": "matrix.sort requires int, bool, string, or float element type; UDT matrices cannot be sorted", "hint": null, "explanation": "matrix.sort cannot sort a matrix of user-defined objects; only int, bool, string and float matrices can be sorted.", "args": {}, "user_message": "matrix.sort cannot sort a matrix of user-defined objects."}, + "PF-E5005": {"severity": "error", "area": "codegen", "message": "request.security helper call history is only supported in the payload itself", "hint": null, "explanation": "Reading the history ([k]) of a call inside a function used by request.security is not supported; do it in the expression passed to request.security itself.", "args": {}, "user_message": "Reading the history ([k]) of a call inside a function used by request.security is not supported."}, + "PF-E5006": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor flag ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot initialize the indicator with a stable per-run value.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA constructor arguments.", "explanation": "A TA indicator's boolean argument is neither a literal nor derived from an input, so PineForge cannot fix it once per run; use a literal or an input.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}, "user_message": "A TA indicator''s boolean argument is neither a literal nor derived from an input, so PineForge cannot fix it once per run."}, + "PF-E5007": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor flag ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot initialize the indicator with a stable per-run value.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA lengths.", "explanation": "A TA indicator's flag argument is neither a constant nor input-derived, so PineForge cannot set it once per run; use a literal or an input-based value.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}, "user_message": "A TA indicator''s flag argument is neither a constant nor input-derived, so PineForge cannot set it once per run."}, + "PF-E5008": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor length ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot size the indicator buffer.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA constructor arguments.", "explanation": "A TA indicator's length is neither a constant nor derived from an input, so PineForge cannot size its buffer; use a literal, an input or arithmetic on those.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}, "user_message": "A TA indicator''s length is neither a constant nor derived from an input, so PineForge cannot size its buffer."}, + "PF-E5009": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor length ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot size the indicator buffer.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA lengths.", "explanation": "A TA indicator's length is not a literal and not derived from an input, so PineForge cannot size its buffer; use a literal, an input or arithmetic on those.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}, "user_message": "A TA indicator''s length is not a literal and not derived from an input, so PineForge cannot size its buffer."}, + "PF-E5010": {"severity": "error", "area": "codegen", "message": "request.security timeframe was not resolved for registration", "hint": null, "explanation": "PineForge could not work out this request.security timeframe before the run starts, so it cannot register the request; use a constant, input or syminfo value.", "args": {}, "user_message": "PineForge could not work out this request.security timeframe before the run starts, so it cannot register the request."}, + "PF-E5011": {"severity": "error", "area": "codegen", "message": "input title {spelled}is not a constant string: TradingView declares title (const string), and PineForge keys an input override by its title.", "hint": "Use a string literal, or a name bound once at global scope to one (T = \"Length\").", "explanation": "An input's title must be a constant string (a literal or a name bound once to one), because PineForge keys each input override by its title.", "args": {"spelled": {"kind": "text"}}, "user_message": "An input''s title must be a constant string (a literal or a name bound once to one), because PineForge keys each input override by its title."}, + "PF-E5012": {"severity": "error", "area": "codegen", "message": "{type_name}.copy() is unsupported because direct array field(s) {rendered} still use value storage", "hint": "Move the array outside the UDT and store a supported shared-ID map/matrix or nested UDT handle until array fields gain handle identity.", "explanation": "Copying an object whose type has array fields is unsupported, since PineForge would copy the arrays by value; keep the arrays outside the type.", "args": {"type_name": {"kind": "type"}, "rendered": {"kind": "identifier"}}, "user_message": "Copying an object whose type has array fields is unsupported, since PineForge would copy the arrays by value."}, + "PF-E5013": {"severity": "error", "area": "codegen", "message": "array.{method} requires a numeric array", "hint": "Use numeric arrays for aggregate/statistical array functions.", "explanation": "This array function (sum, avg, stdev and similar) needs an array of numbers, and the array has another element type.", "args": {"method": {"kind": "identifier"}}, "user_message": "This array function (sum, avg, stdev and similar) needs an array of numbers, and the array has another element type."}, + "PF-E5014": {"severity": "error", "area": "codegen", "message": "{func_name}() with bars_back / timeframe_bars_back inside request.security is not supported", "hint": "Read {func_name}() with its offset outside request.security().", "explanation": "time() or time_close() with a bars-back offset is not supported inside request.security; read the offset time outside the request.", "args": {"func_name": {"kind": "identifier"}}, "user_message": "time() or time_close() with a bars-back offset is not supported inside request.security."}, + "PF-E5015": {"severity": "error", "area": "codegen", "message": "array.copy: expected exactly one receiver ''id''", "hint": "Use array.copy(source) or array.copy(id=source).", "explanation": "array.copy takes exactly one array, either positionally or as id=; this call does not match that.", "args": {}, "user_message": "array.copy takes exactly one array, either positionally or as id=."}, + "PF-E5016": {"severity": "error", "area": "codegen", "message": "map.{method}: unknown keyword argument ''{name}''", "hint": "Expected map.{method}({param_names}).", "explanation": "A map function was called with a keyword argument it does not have; use the parameter names it expects.", "args": {"method": {"kind": "identifier"}, "name": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}, "user_message": "A map function was called with a keyword argument it does not have."}, + "PF-E5017": {"severity": "error", "area": "codegen", "message": "map.{method}: unknown keyword argument ''{name}''", "hint": "Use ''id2='' for the source map. Expected map.{method}({param_names}).", "explanation": "map.put_all was called with from=; its source map parameter is named id2, so use id2= or pass the map by position.", "args": {"method": {"kind": "identifier"}, "name": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}, "user_message": "map.put_all requires the source map parameter name id2 instead of from."}, + "PF-E5018": {"severity": "error", "area": "codegen", "message": "map.{method}: too many positional arguments (expected {param_names_count}, got {args_count})", "hint": "Expected map.{method}({param_names}).", "explanation": "A map function got more positional arguments than it accepts; remove the extra ones.", "args": {"method": {"kind": "identifier"}, "param_names_count": {"kind": "number"}, "args_count": {"kind": "number"}, "param_names": {"kind": "identifier"}}, "user_message": "A map function got more positional arguments than it accepts."}, + "PF-E5019": {"severity": "error", "area": "codegen", "message": "map.{method}: argument ''{name}'' passed both positionally and by keyword", "hint": "Expected map.{method}({param_names}); bind each argument once.", "explanation": "A map function argument is given both by position and by keyword; pass each argument only once.", "args": {"method": {"kind": "identifier"}, "name": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}, "user_message": "A map function argument is given both by position and by keyword."}, + "PF-E5020": {"severity": "error", "area": "codegen", "message": "map.{method}: missing required argument ''{missing}''", "hint": "Expected map.{method}({param_names}).", "explanation": "A required argument of a map function is missing from the call; pass it by position or by keyword.", "args": {"method": {"kind": "identifier"}, "missing": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}, "user_message": "A required argument of a map function is missing from the call."}, + "PF-E5021": {"severity": "error", "area": "codegen", "message": "map.{method}: keyword arguments are not supported for this functional call form", "hint": "Use the established positional form: map.{method}({param_names}).", "explanation": "Keyword arguments are not supported in this function-style map call; pass the arguments by position.", "args": {"method": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}, "user_message": "Keyword arguments are not supported in this function-style map call."}, + "PF-E5022": {"severity": "error", "area": "codegen", "message": "map.{method}: keyword arguments are not supported for this receiver-method call form", "hint": "Use the established positional form: map.{method}({param_names}).", "explanation": "Keyword arguments are not supported in this method-style map call; pass the arguments by position.", "args": {"method": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}, "user_message": "Keyword arguments are not supported in this method-style map call."}, + "PF-E5023": {"severity": "error", "area": "codegen", "message": "an array a call returns is passed to parameter ''{param}'' of ''{func_info_name}'', which takes the array itself: PineForge would pass a copy of it", "hint": "TradingView passes the array a function returns as itself, so the callee''s changes to it reach every variable holding it; pass a variable holding the array instead.", "explanation": "An array returned by a function call is passed to a parameter that can change it in place; PineForge would pass a copy, so store it in a variable first.", "args": {"param": {"kind": "identifier"}, "func_info_name": {"kind": "identifier"}}, "user_message": "An array returned by a function call is passed to a parameter that can change it in place."}, + "PF-E5024": {"severity": "error", "area": "codegen", "message": "{recv_spec_name}.copy() expects no arguments", "hint": "Call copy() on the UDT object without arguments.", "explanation": "copy() on an object takes no arguments; call it as object.copy().", "args": {"recv_spec_name": {"kind": "type"}}, "user_message": "copy() on an object takes no arguments."}, + "PF-E5025": {"severity": "error", "area": "codegen", "message": "matrix.{meth_raw}: wrong number of arguments", "hint": "Check Pine v6 matrix method signature (positional vs keyword).", "explanation": "A matrix method call has the wrong number of arguments; check the Pine v6 matrix method signature and whether arguments are positional or keyword.", "args": {"meth_raw": {"kind": "identifier"}}, "user_message": "A matrix method call has the wrong number of arguments."}, + "PF-E5026": {"severity": "error", "area": "codegen", "message": "matrix.{func_name}: wrong number of arguments", "hint": "Check Pine v6 matrix method signature (positional vs keyword).", "explanation": "A matrix method call has the wrong number of arguments; check the Pine v6 matrix method signature and whether arguments are positional or keyword.", "args": {"func_name": {"kind": "identifier"}}, "user_message": "A matrix method call has the wrong number of arguments."}, + "PF-E5027": {"severity": "error", "area": "codegen", "message": "timestamp(dateString): could not parse ''{args}''.", "hint": "Supported forms: ISO-8601 (\"2025-01-01[THH:MM:SS][±HH:MM]\") and \"DD MMM YYYY [hh:mm[:ss]] [±HHMM]\" / \"MMM DD YYYY ...\"; no time zone = GMT+0.", "explanation": "timestamp() got a date string PineForge cannot parse; use an ISO-8601 or 'DD MMM YYYY' form, or pass year, month and day numbers.", "args": {"args": {"kind": "identifier"}}, "user_message": "timestamp() got a date string PineForge cannot parse."}, + "PF-E5028": {"severity": "error", "area": "codegen", "message": "timestamp(dateString) requires a literal string in PineForge (Pine v6 dateString is a const string).", "hint": "Use a string literal, or timestamp(year, month, day[, hour, minute, second]).", "explanation": "timestamp(dateString) needs a string literal, because PineForge parses the date at transpile time; use a literal or numeric arguments.", "args": {}, "user_message": "timestamp(dateString) needs a string literal, because PineForge parses the date at transpile time."}, + "PF-E5029": {"severity": "error", "area": "codegen", "message": "timestamp(timezone, ...) requires year, month, and day arguments.", "hint": "Pine v6 signature: timestamp(timezone, year, month, day[, hour, minute, second]).", "explanation": "timestamp() with a timezone first needs year, month and day after it; add the missing arguments.", "args": {}, "user_message": "timestamp() with a timezone first needs year, month and day after it."}, + "PF-E5030": {"severity": "error", "area": "codegen", "message": "timestamp(...) with {merged_count} argument(s) is not supported — year, month, and day are required.", "hint": "Pine v6 signature: timestamp(year, month, day[, hour, minute, second]); the dateString overload is not supported in PineForge.", "explanation": "timestamp() with numeric arguments needs at least year, month and day; add the missing ones.", "args": {"merged_count": {"kind": "number"}}, "user_message": "timestamp() with numeric arguments needs at least year, month and day."}, + "PF-E5031": {"severity": "error", "area": "codegen", "message": "matrix.{func_name} receiver must be a variable reference", "hint": null, "explanation": "This numeric-only matrix function needs its matrix as a plain variable so PineForge can check the element type; assign the matrix to a variable first.", "args": {"func_name": {"kind": "identifier"}}, "user_message": "This numeric-only matrix function needs its matrix as a plain variable so PineForge can check the element type."}, + "PF-E5032": {"severity": "error", "area": "codegen", "message": "matrix.{func_name}: receiver ''{recv_name}'' is not a known matrix variable", "hint": null, "explanation": "The matrix function's first argument is a variable PineForge does not know as a matrix, so it cannot check its element type.", "args": {"func_name": {"kind": "identifier"}, "recv_name": {"kind": "identifier"}}, "user_message": "The matrix function''s first argument is a variable PineForge does not know as a matrix, so it cannot check its element type."}, + "PF-E5033": {"severity": "error", "area": "codegen", "message": "{namespace}.copy(...) expects exactly one object argument", "hint": "Prefer the canonical object.copy() form.", "explanation": "Type.copy(...) takes exactly one object of that type; pass one object, or write object.copy().", "args": {"namespace": {"kind": "type"}}, "user_message": "Type.copy(...) takes exactly one object of that type."}, + "PF-E5034": {"severity": "error", "area": "codegen", "message": "Unknown function ''{func_name}(...)'' — not a PineForge builtin or a user-defined function.", "hint": "Check the spelling; the function may not be supported by PineForge, or needs its namespace (e.g. math./str.).", "explanation": "The called function is neither a PineForge built-in nor defined in the script; check the spelling or add its namespace, such as math. or str.", "args": {"func_name": {"kind": "identifier"}}, "user_message": "The called function is neither a PineForge built-in nor defined in the script."}, + "PF-E5035": {"severity": "error", "area": "codegen", "message": "Unknown call ''{namespace}.{func_name}(...)'' — ''{namespace}'' is not a PineForge-supported namespace or a user-defined type.", "hint": "Check the spelling; this namespace may not be supported by PineForge.", "explanation": "The call's namespace is neither a supported PineForge namespace nor a user-defined type; check the spelling.", "args": {"namespace": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}, "user_message": "The call''s namespace is neither a supported PineForge namespace nor a user-defined type."}, + "PF-E5036": {"severity": "error", "area": "codegen", "message": "Unknown variable ''{name}'' — not a PineForge builtin or a declared variable.", "hint": null, "explanation": "The script reads a name that is neither a PineForge built-in nor a declared variable; check the spelling or declare it first.", "args": {"name": {"kind": "identifier"}}, "user_message": "The script reads a name that is neither a PineForge built-in nor a declared variable."}, + "PF-E5037": {"severity": "error", "area": "codegen", "message": "Unknown variable ''{name}'' — not a PineForge builtin or a declared variable.", "hint": "{hint}", "explanation": "The script reads a realtime-only built-in variable, which has no value in a batch backtest; remove it or compute the value another way.", "args": {"name": {"kind": "identifier"}, "hint": {"kind": "text"}}, "user_message": "The script reads a realtime-only built-in variable, which has no value in a batch backtest."}, + "PF-E5038": {"severity": "error", "area": "codegen", "message": "ta.{member} property read could not be bound to a TA call site.", "hint": "Use the function form ta.{member}(...) instead of the bare property read.", "explanation": "A bare ta. read could not be tied to a calculation; call the function form ta.name(...) instead.", "args": {"member": {"kind": "identifier"}}, "user_message": "A bare ta. read could not be tied to a calculation."}, + "PF-E5039": {"severity": "error", "area": "codegen", "message": "ta.{member} is not readable as a bare property in PineForge.", "hint": "Call the function form ta.{member}(...) with its arguments instead.", "explanation": "That ta member is not a variable in PineForge, so it cannot be read without parentheses; call it as a function with its arguments.", "args": {"member": {"kind": "identifier"}}, "user_message": "That ta member is not a variable in PineForge, so it cannot be read without parentheses."}, + "PF-E5040": {"severity": "error", "area": "codegen", "message": "{op} na on a {kind} reference: TradingView refuses a comparison with na (CE10187: \"Cannot compare a value to \\\"na\\\" directly\").", "hint": "Test the reference with na(...).", "explanation": "Comparing an object or drawing reference with na using == or != is rejected, as in TradingView; test it with na(...) instead.", "args": {"op": {"kind": "keyword"}, "kind": {"kind": "type"}}, "user_message": "Comparing an object or drawing reference with na using == or != is rejected, as in TradingView."}, + "PF-E5041": {"severity": "error", "area": "codegen", "message": "{op} on a {kind} reference: TradingView compares only line and label references (CE10123: \"Cannot call ''operator {op}''\" with an argument of the {kind} type).", "hint": "Compare the fields or getter values the objects hold, or test na(...).", "explanation": "PineForge refuses == and != on object or drawing references other than line or label of the same kind, as TradingView does; compare fields or test na().", "args": {"op": {"kind": "keyword"}, "kind": {"kind": "type"}}, "user_message": "PineForge refuses == and != on object or drawing references other than line or label of the same kind, as TradingView does."}, + "PF-E5042": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: ''{op}'' of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library compares a bool with == or !=, but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the library.", "args": {"library": {"kind": "identifier"}, "op": {"kind": "keyword"}}, "user_message": "A //@version=5 library compares a bool with == or !=, but v5 bools can be na and PineForge''s two-state bool cannot, so it refuses the library."}, + "PF-E5043": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: str.format() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library passes a bool to str.format(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}}, "user_message": "A //@version=5 library passes a bool to str.format(), but v5 bools can be na and PineForge''s two-state bool cannot, so it refuses the call."}, + "PF-E5044": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: str.tostring() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library passes a bool to str.tostring(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}}, "user_message": "A //@version=5 library passes a bool to str.tostring(), but v5 bools can be na and PineForge''s two-state bool cannot, so it refuses the call."}, + "PF-E5045": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: string() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library passes a bool to string(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}}, "user_message": "A //@version=5 library passes a bool to string(), but v5 bools can be na and PineForge''s two-state bool cannot, so it refuses the call."}, + "PF-E5046": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: {func_name}() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library tests a bool with na(), nz() or fixnan(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}, "user_message": "A //@version=5 library tests a bool with na(), nz() or fixnan(), but v5 bools can be na and PineForge''s two-state bool cannot, so it refuses the call."}, + "PF-E5047": {"severity": "error", "area": "codegen", "message": "session.{flag}[...] cannot be read here: PineForge keeps a session flag''s history on the requested clock only for a read the request.security expression reaches through its own operators, not through a call''s argument, a function or a variable.", "hint": null, "explanation": "A session flag history read inside request.security works only when the expression's own operators reach it, not via a call argument, function or variable.", "args": {"flag": {"kind": "identifier"}}, "user_message": "A session flag history read inside request.security works only when the expression''s own operators reach it, not via a call argument, function or variable."}, + "PF-E5048": {"severity": "error", "area": "codegen", "message": "session.{flag}[...] cannot be read in {owner}(), {why}: PineForge keeps a session flag''s history in a function by each of its call sites, and cannot tell this one apart.", "hint": null, "explanation": "A session flag history read is in a function PineForge cannot split per call site: a method, or one a method, request.security or UDT field default calls.", "args": {"flag": {"kind": "identifier"}, "owner": {"kind": "identifier"}, "why": {"kind": "vocab", "values": ["a method, whose calls PineForge cannot always tell apart", "which a UDT field default calls once for every new()", "which a method calls", "which a request.security expression evaluates on the requested clock"]}}, "user_message": "A session flag history read is in a function PineForge cannot split per call site: a method, or one a method, request.security or UDT field default calls."}, + "PF-E5049": {"severity": "error", "area": "codegen", "message": "session.{flag}[...] is not supported here: PineForge keeps a session flag''s history for the script''s top level, a function body and a request.security expression that reads it.", "hint": null, "explanation": "A session flag history read is supported only at the top level, in a function body or in a request.security expression, and this read is none of those.", "args": {"flag": {"kind": "identifier"}}, "user_message": "A session flag history read is supported only at the top level, in a function body or in a request.security expression, and this read is none of those."}, + "PF-E5050": {"severity": "error", "area": "codegen", "message": "History of the chart.point {object_name} is not supported in PineForge when the script changes its fields: PineForge holds a chart.point as a value, where TradingView''s history reads the point object as it is now.", "hint": "Keep the field in a variable of its own and read that variable''s history, or build a new point instead of changing a field.", "explanation": "History of a chart.point variable whose fields the script changes is refused because PineForge holds points as values; use a separate variable or build a new point.", "args": {"object_name": {"kind": "identifier"}}, "user_message": "History of a chart.point variable whose fields the script changes is refused because PineForge holds points as values."}, + "PF-E5051": {"severity": "error", "area": "codegen", "message": "matrix ''{target_label}'' element type mismatch on reassignment: expected {target_type}, got {rhs_type}", "hint": null, "explanation": "A matrix variable is reassigned a matrix with a different element type, which Pine forbids; make the new matrix's element type match the variable's.", "args": {"target_label": {"kind": "identifier"}, "target_type": {"kind": "type"}, "rhs_type": {"kind": "type"}}, "user_message": "A matrix variable is reassigned a matrix with a different element type, which Pine forbids."}, + "PF-E5052": {"severity": "error", "area": "codegen", "message": "array.{method}: wrong number of arguments", "hint": null, "explanation": "An array method call has too few arguments for its lowering; check the Pine v6 array method signature.", "args": {"method": {"kind": "identifier"}}, "user_message": "An array method call has too few arguments for its lowering."}, + "PF-E6001": {"severity": "error", "area": "collection-history", "message": "matrix.{method}: wrong number of arguments", "hint": "Check Pine v6 matrix method signature (positional vs keyword).", "explanation": "A matrix method call has the wrong number of arguments; check the Pine v6 matrix method signature and whether arguments are positional or keyword.", "args": {"method": {"kind": "identifier"}}, "user_message": "A matrix method call has the wrong number of arguments."}, + "PF-E6002": {"severity": "error", "area": "collection-history", "message": "{label} := ...: an assignment to the history-referencing operator is not supported in PineForge.", "hint": null, "explanation": "TradingView refuses an assignment to a history reference; assign the variable itself.", "args": {"label": {"kind": "text"}}, "user_message": "TradingView refuses an assignment to a history reference."}, + "PF-E6003": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for operator {op} (CE10123).", "hint": null, "explanation": "An array or matrix history read such as a[1] is an operand of an operator, which TradingView refuses; read an element or the size and use that instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "op": {"kind": "keyword"}}, "user_message": "An array or matrix history read such as a[1] is an operand of an operator, which TradingView refuses."}, + "PF-E6004": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for operator {op} (CE10123).", "hint": null, "explanation": "An array or matrix history read such as a[1] is an operand of an operator, which TradingView refuses; read an element or the size and use that instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "op": {"kind": "keyword"}}, "user_message": "An array or matrix history read such as a[1] is an operand of an operator, which TradingView refuses."}, + "PF-E6005": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the condition of ?: (CE10123).", "hint": null, "explanation": "An array or matrix history read is the condition of a ?: expression, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "An array or matrix history read is the condition of a ?: expression, which TradingView refuses."}, + "PF-E6006": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the condition of ?: (CE10123).", "hint": null, "explanation": "An array or matrix history read is the condition of a ?: expression, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "An array or matrix history read is the condition of a ?: expression, which TradingView refuses."}, + "PF-E6007": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the condition of an if statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of an if statement, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "An array or matrix history read is the condition of an if statement, which TradingView refuses."}, + "PF-E6008": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the condition of an while statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of a while loop, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "An array or matrix history read is the condition of a while loop, which TradingView refuses."}, + "PF-E6009": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the condition of an if statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of an if statement, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "An array or matrix history read is the condition of an if statement, which TradingView refuses."}, + "PF-E6010": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the condition of an while statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of a while loop, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "An array or matrix history read is the condition of a while loop, which TradingView refuses."}, + "PF-E6011": {"severity": "error", "area": "collection-history", "message": "({label})[...]: the history of a {kind}''s history is not supported in PineForge.", "hint": null, "explanation": "The history of a collection's history is not kept by PineForge.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "The history of a collection''s history is not kept by PineForge."}, + "PF-E6012": {"severity": "error", "area": "collection-history", "message": "({label})[...]: the history of an {kind}''s history is not supported in PineForge.", "hint": null, "explanation": "The history of a collection's history is not kept by PineForge.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "The history of a collection''s history is not kept by PineForge."}, + "PF-E6013": {"severity": "error", "area": "collection-history", "message": "{label} is not supported in PineForge here.", "hint": null, "explanation": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower; use it only with built-in array or matrix functions.", "args": {"label": {"kind": "identifier"}}, "user_message": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower."}, + "PF-E6014": {"severity": "error", "area": "collection-history", "message": "{label}.{method}: a {kind} has no fields.", "hint": null, "explanation": "An array or a matrix has no fields; a field read after its history reference is refused.", "args": {"label": {"kind": "text"}, "method": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "An array or a matrix has no fields."}, + "PF-E6015": {"severity": "error", "area": "collection-history", "message": "{label}.{method}: an {kind} has no fields.", "hint": null, "explanation": "An array or a matrix has no fields; a field read after its history reference is refused.", "args": {"label": {"kind": "text"}, "method": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "An array or a matrix has no fields."}, + "PF-E6016": {"severity": "error", "area": "collection-history", "message": "{label}.{method}(): no array or matrix method of that name.", "hint": null, "explanation": "No array or matrix method has this name, so the call on the collection's history is refused.", "args": {"label": {"kind": "text"}, "method": {"kind": "identifier"}}, "user_message": "No array or matrix method has this name, so the call on the collection''s history is refused."}, + "PF-E6017": {"severity": "error", "area": "collection-history", "message": "matrix.sum of {label} is not supported in PineForge: the matrix it returns does not compile.", "hint": null, "explanation": "matrix.sum of a matrix's history returns a matrix that never compiled in PineForge, so it is refused.", "args": {"label": {"kind": "text"}}, "user_message": "matrix.sum of a matrix''s history returns a matrix that never compiled in PineForge, so it is refused."}, + "PF-E6018": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an argument of {name} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in function that takes only plain numbers, strings or conditions, which TradingView refuses; pass an element.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}, "user_message": "An array or matrix history read is passed to a built-in function that takes only plain numbers, strings or conditions, which TradingView refuses."}, + "PF-E6019": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an argument of {name} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in function that takes only plain numbers, strings or conditions, which TradingView refuses; pass an element.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}, "user_message": "An array or matrix history read is passed to a built-in function that takes only plain numbers, strings or conditions, which TradingView refuses."}, + "PF-E6020": {"severity": "error", "area": "collection-history", "message": "{label} as an argument of {name} is not supported in PineForge.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "name": {"kind": "identifier"}}, "user_message": "PineForge would hand over a changeable copy of the collection''s history here, where TradingView passes the read-only history, so the use is refused."}, + "PF-E6021": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an element of array.from (CE10122).", "hint": null, "explanation": "An array or matrix history read is used as an element of array.from(), which TradingView refuses; pass its elements instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "An array or matrix history read is used as an element of array.from(), which TradingView refuses."}, + "PF-E6022": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an element of array.from (CE10122).", "hint": null, "explanation": "An array or matrix history read is used as an element of array.from(), which TradingView refuses; pass its elements instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "An array or matrix history read is used as an element of array.from(), which TradingView refuses."}, + "PF-E6023": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an argument of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in namespace function that takes plain values, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is passed to a built-in namespace function that takes plain values, which TradingView refuses."}, + "PF-E6024": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an argument of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in namespace function that takes plain values, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is passed to a built-in namespace function that takes plain values, which TradingView refuses."}, + "PF-E6025": {"severity": "error", "area": "collection-history", "message": "{label} as a field of a new {namespace} is not supported in PineForge: the field would hold a changeable copy, where TradingView''s holds the read-only history.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "namespace": {"kind": "identifier"}}, "user_message": "PineForge would hand over a changeable copy of the collection''s history here, where TradingView passes the read-only history, so the use is refused."}, + "PF-E6026": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an argument of str.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a str function that takes a plain value, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is passed to a str function that takes a plain value, which TradingView refuses."}, + "PF-E6027": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an argument of str.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a str function that takes a plain value, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is passed to a str function that takes a plain value, which TradingView refuses."}, + "PF-E6028": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the message of log.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is used as the message of a log call, which TradingView refuses; log an element or a string built from it instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is used as the message of a log call, which TradingView refuses."}, + "PF-E6029": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the message of log.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is used as the message of a log call, which TradingView refuses; log an element or a string built from it instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is used as the message of a log call, which TradingView refuses."}, + "PF-E6030": {"severity": "error", "area": "collection-history", "message": "{label} as an argument of the overloaded method {member} is not supported in PineForge.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "member": {"kind": "identifier"}}, "user_message": "PineForge would hand over a changeable copy of the collection''s history here, where TradingView passes the read-only history, so the use is refused."}, + "PF-E6031": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as a value of {member}() (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix method, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix method, which TradingView refuses."}, + "PF-E6032": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as a value of {member}() (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix method, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix method, which TradingView refuses."}, + "PF-E6033": {"severity": "error", "area": "collection-history", "message": "{label} as an argument of {function}.{member} is not supported in PineForge.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "function": {"kind": "text"}, "member": {"kind": "identifier"}}, "user_message": "PineForge would hand over a changeable copy of the collection''s history here, where TradingView passes the read-only history, so the use is refused."}, + "PF-E6034": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as a value of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix function, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix function, which TradingView refuses."}, + "PF-E6035": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as a value of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix function, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix function, which TradingView refuses."}, + "PF-E6036": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for log.{member} (CE10122).", "hint": null, "explanation": "A history read of an array of colors is a format argument of a log call, which TradingView refuses; log its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "A history read of an array of colors is a format argument of a log call, which TradingView refuses."}, + "PF-E6037": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for log.{member} (CE10123).", "hint": null, "explanation": "A history read of an array of colors is passed to a log call, which TradingView refuses; log its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "A history read of an array of colors is passed to a log call, which TradingView refuses."}, + "PF-E6038": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.format (CE10122).", "hint": null, "explanation": "A history read of an array of colors is a format argument of str.format, which TradingView refuses; format its elements instead.", "args": {"label": {"kind": "identifier"}}, "user_message": "A history read of an array of colors is a format argument of str.format, which TradingView refuses."}, + "PF-E6039": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.format (CE10123).", "hint": null, "explanation": "A history read of an array of colors is passed to str.format, which TradingView refuses; format its elements instead.", "args": {"label": {"kind": "identifier"}}, "user_message": "A history read of an array of colors is passed to str.format, which TradingView refuses."}, + "PF-E6040": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.tostring (CE10122).", "hint": null, "explanation": "A history read of an array of colors is passed to str.tostring, which TradingView refuses; convert its elements instead.", "args": {"label": {"kind": "identifier"}}, "user_message": "A history read of an array of colors is passed to str.tostring, which TradingView refuses."}, + "PF-E6041": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.tostring (CE10123).", "hint": null, "explanation": "A history read of an array of colors is passed to str.tostring, which TradingView refuses; convert its elements instead.", "args": {"label": {"kind": "identifier"}}, "user_message": "A history read of an array of colors is passed to str.tostring, which TradingView refuses."}, + "PF-E6042": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for log.{member} (CE10122).", "hint": null, "explanation": "A history read of an array of objects is a format argument of a log call, which TradingView refuses; log fields of its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "A history read of an array of objects is a format argument of a log call, which TradingView refuses."}, + "PF-E6043": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for log.{member} (CE10123).", "hint": null, "explanation": "A history read of an array of objects is passed to a log call, which TradingView refuses; log fields of its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "A history read of an array of objects is passed to a log call, which TradingView refuses."}, + "PF-E6044": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.format (CE10122).", "hint": null, "explanation": "A history read of an array of objects is a format argument of str.format, which TradingView refuses; format fields of its elements instead.", "args": {"label": {"kind": "identifier"}}, "user_message": "A history read of an array of objects is a format argument of str.format, which TradingView refuses."}, + "PF-E6045": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.format (CE10123).", "hint": null, "explanation": "A history read of an array of objects is passed to str.format, which TradingView refuses; format fields of its elements instead.", "args": {"label": {"kind": "identifier"}}, "user_message": "A history read of an array of objects is passed to str.format, which TradingView refuses."}, + "PF-E6046": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.tostring (CE10122).", "hint": null, "explanation": "A history read of an array of objects is passed to str.tostring, which TradingView refuses; convert fields of its elements instead.", "args": {"label": {"kind": "identifier"}}, "user_message": "A history read of an array of objects is passed to str.tostring, which TradingView refuses."}, + "PF-E6047": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.tostring (CE10123).", "hint": null, "explanation": "A history read of an array of objects is passed to str.tostring, which TradingView refuses; convert fields of its elements instead.", "args": {"label": {"kind": "identifier"}}, "user_message": "A history read of an array of objects is passed to str.tostring, which TradingView refuses."}, + "PF-E6048": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for the {type_hint} variable {name} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to a variable declared with a scalar type, which TradingView refuses; assign an element or declare a collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "type_hint": {"kind": "type"}, "name": {"kind": "identifier"}}, "user_message": "An array or matrix history read is assigned to a variable declared with a scalar type, which TradingView refuses."}, + "PF-E6049": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for the {type_hint} variable {name} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to a variable declared with a scalar type, which TradingView refuses; assign an element or declare a collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "type_hint": {"kind": "type"}, "name": {"kind": "identifier"}}, "user_message": "An array or matrix history read is assigned to a variable declared with a scalar type, which TradingView refuses."}, + "PF-E6050": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for the {field_type} field {member} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an object field of a scalar type, which TradingView refuses; assign an element or change the field's type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "field_type": {"kind": "type"}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is assigned to an object field of a scalar type, which TradingView refuses."}, + "PF-E6051": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for the {field_type} field {member} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an object field of a scalar type, which TradingView refuses; assign an element or change the field's type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "field_type": {"kind": "type"}, "member": {"kind": "identifier"}}, "user_message": "An array or matrix history read is assigned to an object field of a scalar type, which TradingView refuses."}, + "PF-E6052": {"severity": "error", "area": "collection-history", "message": "{label} assigned to a field is not supported in PineForge: the field would hold a changeable copy, where TradingView''s holds the read-only history.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}}, "user_message": "PineForge would hand over a changeable copy of the collection''s history here, where TradingView passes the read-only history, so the use is refused."}, + "PF-E6053": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for the variable {name} of another type (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an existing variable of another type, which TradingView refuses; use a variable of the matching collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}, "user_message": "An array or matrix history read is assigned to an existing variable of another type, which TradingView refuses."}, + "PF-E6054": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for the variable {name} of another type (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an existing variable of another type, which TradingView refuses; use a variable of the matching collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}, "user_message": "An array or matrix history read is assigned to an existing variable of another type, which TradingView refuses."}, + "PF-E6055": {"severity": "error", "area": "collection-history", "message": "{label} assigned to {name} is not supported in PineForge here.", "hint": null, "explanation": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower; use it only with built-in array or matrix functions.", "args": {"label": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower."}, + "PF-E6056": {"severity": "error", "area": "collection-history", "message": "{label} as a statement: TradingView reads it as a declaration and refuses it (CE10009, \"Extraneous input\").", "hint": null, "explanation": "An array or matrix history read written alone as a top-level statement is refused because TradingView reads it as a declaration; remove it or bind it to a variable.", "args": {"label": {"kind": "identifier"}}, "user_message": "An array or matrix history read written alone as a top-level statement is refused because TradingView reads it as a declaration."}, + "PF-E6057": {"severity": "error", "area": "collection-history", "message": "{label} in a tuple is not supported in PineForge.", "hint": null, "explanation": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower; use it only with built-in array or matrix functions.", "args": {"label": {"kind": "identifier"}}, "user_message": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower."}, + "PF-E6058": {"severity": "error", "area": "collection-history", "message": "{label}.slice() is not supported in PineForge here.", "hint": null, "explanation": "A slice of an array's history is used in a way PineForge cannot lower; simplify the expression or copy the array first.", "args": {"label": {"kind": "identifier"}}, "user_message": "A slice of an array''s history is used in a way PineForge cannot lower."}, + "PF-E6059": {"severity": "error", "area": "collection-history", "message": "{label} is bound where the script reads it both as a {kind} and through na() or str.tostring(): that is not supported in PineForge, which holds no na {kind} and does not render one.", "hint": null, "explanation": "A variable bound to an array or matrix history is read both as a collection and through na() or str.tostring(); PineForge has no na collection, so it refuses this.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "A variable bound to an array or matrix history is read both as a collection and through na() or str.tostring()."}, + "PF-E6060": {"severity": "error", "area": "collection-history", "message": "{label} is bound where the script reads it both as an {kind} and through na() or str.tostring(): that is not supported in PineForge, which holds no na {kind} and does not render one.", "hint": null, "explanation": "A variable bound to an array or matrix history is read both as a collection and through na() or str.tostring(); PineForge has no na collection, so it refuses this.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "A variable bound to an array or matrix history is read both as a collection and through na() or str.tostring()."}, + "PF-E6061": {"severity": "error", "area": "collection-history", "message": "{label} is not supported in PineForge here: the history of a matrix is supported as the receiver or an argument of a matrix function, na(), and the value of a variable or a function''s argument that reads it.", "hint": null, "explanation": "A matrix history is supported only as a matrix function's receiver or argument, in na(), or via a variable or function argument that reads it; this use is not.", "args": {"label": {"kind": "identifier"}}, "user_message": "A matrix history is supported only as a matrix function''s receiver or argument, in na(), or via a variable or function argument that reads it."}, + "PF-E6062": {"severity": "error", "area": "collection-history", "message": "{label} inside a request.security expression is not supported in PineForge: TradingView reads the copies the requested timeframe''s bars left, which PineForge does not keep.", "hint": null, "explanation": "request.security cannot read the history of a user-defined type or drawing reference, because PineForge keeps no references from the requested bars.", "args": {"label": {"kind": "text"}}, "user_message": "A request.security expression cannot read an array or matrix history such as a[1], because PineForge keeps no copies from the requested timeframe''s bars."}, + "PF-E6063": {"severity": "error", "area": "collection-history", "message": "{label} is not supported in PineForge here: the history of an array is supported as the receiver or an argument of an array function, a for...in iterable, na(), and the value of a variable or a function''s argument that reads it.", "hint": null, "explanation": "An array history is supported only as an array function's receiver or argument, a for...in iterable, in na(), or via a variable or function argument that reads it.", "args": {"label": {"kind": "identifier"}}, "user_message": "An array history is supported only as an array function''s receiver or argument, a for...in iterable, in na(), or via a variable or function argument that reads it."}, + "PF-E6064": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a block''s var {read_kind} is not supported in PineForge.", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "read_kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for the script''s top level and its blocks, not for this kind of declaration."}, + "PF-E6065": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} declared in a block that redeclares a script variable is not supported in PineForge (such a block''s declarations are C++ locals).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for the script''s top level and its blocks, not for this kind of declaration."}, + "PF-E6066": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} declared in a loop is not supported in PineForge.", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for the script''s top level and its blocks, not for this kind of declaration."}, + "PF-E6067": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} function''s local is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for the script''s top level and its blocks, not for this kind of declaration."}, + "PF-E6068": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} parameter is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for the script''s top level and its blocks, not for this kind of declaration."}, + "PF-E6069": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} script variable read in a function is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for the script''s top level and its blocks, not for this kind of declaration."}, + "PF-E6070": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} declared in a block that redeclares a script variable is not supported in PineForge (such a block''s declarations are C++ locals).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for the script''s top level and its blocks, not for this kind of declaration."}, + "PF-E6071": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} declared in a loop is not supported in PineForge.", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for the script''s top level and its blocks, not for this kind of declaration."}, + "PF-E6072": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} function''s local is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for the script''s top level and its blocks, not for this kind of declaration."}, + "PF-E6073": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} parameter is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for the script''s top level and its blocks, not for this kind of declaration."}, + "PF-E6074": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} script variable read in a function is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for the script''s top level and its blocks, not for this kind of declaration."}, + "PF-E6075": {"severity": "error", "area": "collection-history", "message": "{label}: the history of this {read_kind} is not supported in PineForge (only a variable the script''s top level or one of its blocks declares keeps one).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for a variable the script's top level or one of its blocks declares.", "args": {"label": {"kind": "text"}, "read_kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "PineForge keeps the history of an array or matrix only for a variable the script''s top level or one of its blocks declares."}, + "PF-E6076": {"severity": "error", "area": "collection-history", "message": "The history of a call''s {kind} is not supported in PineForge here: TradingView reads the copy that expression produced that many bars back, which PineForge does not keep.", "hint": "Bind the expression to a variable and read the variable''s history.", "explanation": "The history of a function call's array or matrix result is refused as PineForge keeps no per-bar copy of it; bind the call to a variable and read its history.", "args": {"kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "The history of a function call''s array or matrix result is refused as PineForge keeps no per-bar copy of it."}, + "PF-E6077": {"severity": "error", "area": "collection-history", "message": "The history of a selection''s {kind} is not supported in PineForge here: TradingView reads the copy that expression produced that many bars back, which PineForge does not keep.", "hint": "Bind the expression to a variable and read the variable''s history.", "explanation": "The history of a ?: selection's array or matrix is refused as PineForge keeps no per-bar copy of it; bind the selection to a variable and read its history.", "args": {"kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "The history of a ?: selection''s array or matrix is refused as PineForge keeps no per-bar copy of it."}, + "PF-E6078": {"severity": "error", "area": "collection-history", "message": "The history of an expression''s {kind} is not supported in PineForge here: TradingView reads the copy that expression produced that many bars back, which PineForge does not keep.", "hint": "Bind the expression to a variable and read the variable''s history.", "explanation": "The history of an expression's array or matrix is refused as PineForge keeps no per-bar copy of it; bind the expression to a variable and read its history.", "args": {"kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "The history of an expression''s array or matrix is refused as PineForge keeps no per-bar copy of it."}, + "PF-E6079": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a name bound to it (line ?): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A name bound to an array or matrix history is changed, which stops the run on TradingView; PineForge would change a copy silently, so copy the history first.", "args": {"label": {"kind": "identifier"}}, "user_message": "A name bound to an array or matrix history is changed, which stops the run on TradingView."}, + "PF-E6080": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a name bound to it (line {line}): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A name bound to an array or matrix history is changed on the given line, which stops the run on TradingView; PineForge would change a copy, so copy it first.", "args": {"label": {"kind": "identifier"}, "line": {"kind": "number"}}, "user_message": "A name bound to an array or matrix history is changed on the given line, which stops the run on TradingView."}, + "PF-E6081": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a slice of it (line ?): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A slice of an array or matrix history is changed, which stops the run on TradingView; PineForge would silently change a copy, so copy the history first.", "args": {"label": {"kind": "identifier"}}, "user_message": "A slice of an array or matrix history is changed, which stops the run on TradingView."}, + "PF-E6082": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a slice of it (line {line}): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A slice of an array or matrix history is changed on the given line, which stops the run on TradingView; PineForge would change a copy, so copy it first.", "args": {"label": {"kind": "identifier"}, "line": {"kind": "number"}}, "user_message": "A slice of an array or matrix history is changed on the given line, which stops the run on TradingView."}, + "PF-E7001": {"severity": "error", "area": "ta", "message": "Unsupported requested-context TA constructor for {class_name}: PineForge cannot bind the helper call''s arguments to its constructor arguments.", "hint": "Call the ta.* function directly inside request.security().", "explanation": "A TA function called through a helper inside request.security cannot have the helper's arguments bound to its constructor; call the ta.* function directly.", "args": {"class_name": {"kind": "identifier"}}, "user_message": "A TA function called through a helper inside request.security cannot have the helper''s arguments bound to its constructor."}, + "PF-E7002": {"severity": "error", "area": "ta", "message": "Unsupported requested-context TA constructor flag ''{shown}'' for {class_name}: the helper-bound expression is not a stable per-run scalar{reason}.", "hint": "Use a literal, an input.*() value, timeframe.* metadata, or arithmetic over those for TA lengths.", "explanation": "A boolean option of a TA call inside request.security comes from a helper-bound value that is not fixed for the run; use a literal, an input or timeframe metadata.", "args": {"shown": {"kind": "identifier"}, "class_name": {"kind": "identifier"}, "reason": {"kind": "text"}}, "user_message": "A boolean option of a TA call inside request.security comes from a helper-bound value that is not fixed for the run."}, + "PF-E7003": {"severity": "error", "area": "ta", "message": "Unsupported requested-context TA constructor length ''{shown}'' for {class_name}: the helper-bound expression is not a stable per-run scalar{reason}.", "hint": "Use a literal, an input.*() value, timeframe.* metadata, or arithmetic over those for TA lengths.", "explanation": "A TA length inside request.security comes from a helper-bound value not fixed for the run; use a literal, an input, timeframe metadata or arithmetic on them.", "args": {"shown": {"kind": "identifier"}, "class_name": {"kind": "identifier"}, "reason": {"kind": "text"}}, "user_message": "A TA length inside request.security comes from a helper-bound value not fixed for the run."}, + "PF-E7004": {"severity": "error", "area": "ta", "message": "Unsupported TA constructor length for {class_name} inside request.security in ''{containing}'': its call sites pass different lengths ({spellings}), and one requested-context evaluator serves them all.", "hint": "Call request.security() at each call site, or pass the same length from every call.", "explanation": "A function with a request.security TA call is called with different lengths, but one evaluator serves all calls; use one length or call request.security per site.", "args": {"class_name": {"kind": "identifier"}, "containing": {"kind": "identifier"}, "spellings": {"kind": "identifier"}}, "user_message": "A function with a request.security TA call is called with different lengths, but one evaluator serves all calls."}, + "PF-W0000": {"severity": "warning", "area": "uncatalogued", "message": "{message}", "hint": "{hint}", "explanation": "A diagnostic whose text no catalog template renders; the test suite refuses it, so a release never emits it.", "args": {"message": {"kind": "text"}, "hint": {"kind": "text"}}, "user_message": "PineForge reported an unrecognized diagnostic."}, + "PF-W1001": {"severity": "warning", "area": "support", "message": "{context}: map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps with string keys only; declare the map's key type as string; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"context": {"kind": "text"}}, "user_message": "PineForge supports maps with string keys only. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1002": {"severity": "warning", "area": "support", "message": "{context}: map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps whose values are float, int, bool or string only; use one of those as the value type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"context": {"kind": "text"}}, "user_message": "PineForge supports maps whose values are float, int, bool or string only. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1003": {"severity": "warning", "area": "support", "message": "matrix<{element_type}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"element_type": {"kind": "type"}}, "user_message": "A matrix of a user-defined type with a map field is not supported: rollback would keep live map references. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1004": {"severity": "warning", "area": "support", "message": "matrix<{element_type}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"element_type": {"kind": "type"}}, "user_message": "A matrix cannot hold another collection as its element type in PineForge. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1005": {"severity": "warning", "area": "support", "message": "input.color(...) requires a color defval (e.g. color.red or color.new(color.red, 50)).", "hint": null, "explanation": "input.color needs a color as its default value, for example color.red or color.new(color.red, 50); inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "input.color needs a color as its default value, for example color.red or color.new(color.red, 50). In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1006": {"severity": "warning", "area": "support", "message": "input.color(...) defval must be a color constant (color.red, ...), a color literal (#rrggbb), or a color.new(...) / color.rgb(...) builder. Arbitrary expressions are not supported: the engine has no color helper, so codegen routes input.color through the int getter — any non-color defval would silently store a numeric value with no color encoding.", "hint": "Replace the defval with color. or color.new(...).", "explanation": "The default of input.color must be a color constant, a #rrggbb literal or a color.new or color.rgb call; other expressions are refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "The default of input.color must be a color constant, a #rrggbb literal or a color.new or color.rgb call. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1007": {"severity": "warning", "area": "support", "message": "input.source(...) requires a native series defval (close, open, high, low, hl2, hlc3, ohlc4, ...).", "hint": null, "explanation": "input.source needs a default chart series such as close as its first argument or defval; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "input.source needs a default chart series such as close as its first argument or defval. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1008": {"severity": "warning", "area": "support", "message": "input.source(...) defval must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4). User series, computed expressions, and indicator outputs are not supported: input.source is restricted to native OHLCV series.", "hint": "Use one of: close, open, high, low, hl2, hlc3, ohlc4.", "explanation": "The default of input.source must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4); computed series are refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "The default of input.source must be a native chart series such as open, close, volume or hl2. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1009": {"severity": "warning", "area": "support", "message": "{kind}() declarations are not supported; PineForge runs strategies only.", "hint": "Replace the declaration with strategy(...) and add explicit entry/exit calls.", "explanation": "PineForge runs strategies only, so a script declared with indicator() or library() is refused; declare it with strategy() and add orders; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kind": {"kind": "identifier"}}, "user_message": "PineForge runs strategies only, so an indicator() or library() declaration is not supported. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1010": {"severity": "warning", "area": "support", "message": "Tuple reassignment [..] {op} is not Pine syntax: TradingView declares a tuple with ''='' and has no tuple reassignment.", "hint": "Declare new names with [a, b] = f(), then reassign each variable on its own line.", "explanation": "Pine has no tuple reassignment: declare a tuple once with '=' and reassign each variable on its own line; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"op": {"kind": "keyword"}}, "user_message": "Pine has no tuple reassignment: declare a tuple once with ''='' and reassign each variable on its own line. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1011": {"severity": "warning", "area": "support", "message": "A tuple literal [..] cannot be a variable''s value: TradingView rejects it here (Syntax error at input ''['', CE10156). A tuple is only a function''s or an if/switch arm''s value or a request.security expression.", "hint": "Declare each variable on its own line (a = x, b = y), or return the tuple from a function: f() => [x, y], then [a, b] = f().", "explanation": "A tuple literal such as [a, b] cannot be assigned to a variable; return it from a function or if/switch arm and destructure the result; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "A tuple literal such as [a, b] cannot be assigned to a variable. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1012": {"severity": "warning", "area": "support", "message": "A ternary cannot return a tuple: TradingView rejects [a, b] = c ? [..] : [..] (\"Ternary operations cannot return tuples\").", "hint": "Select the tuple with an if or switch: [a, b] = if c, each arm ending in its tuple.", "explanation": "A ternary cannot produce a tuple (TradingView rejects it too); choose between tuples with an if or switch instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "A ternary cannot produce a tuple, and TradingView rejects it too. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1013": {"severity": "warning", "area": "support", "message": "ta.stoch(...) returns a single series in PineForge; tuple destructuring is not supported.", "hint": "Use k = ta.stoch(...) and compute smoothing separately if needed.", "explanation": "ta.stoch returns one series in PineForge, so destructuring it into a tuple is refused; assign it to a single variable; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "ta.stoch returns one series in PineForge, so it cannot be destructured into a tuple. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1014": {"severity": "warning", "area": "support", "message": "History references on UDT drawing fields are not supported in PineForge.", "hint": "{var_name}.{object_member}[...] would be read as the current-bar field, not prior-bar history. Copy the field to a bare drawing variable first, or remove the history reference.", "explanation": "A history index on a drawing field of a user-defined type would silently read the current field, so it is refused; copy the field to a variable first; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"var_name": {"kind": "identifier"}, "object_member": {"kind": "identifier"}}, "user_message": "A history index on a drawing field of a user-defined type is read as the current field, not the earlier bar''s. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1015": {"severity": "warning", "area": "support", "message": "History references on tuple-destructured drawing handles are not supported in PineForge.", "hint": "{object_name}[...] is a drawing handle from tuple destructuring; PineForge cannot historize that tuple element safely.", "explanation": "A drawing handle bound by tuple destructuring cannot be read through a history index; remove the history reference; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}}, "user_message": "A drawing handle bound by tuple destructuring cannot be read through a history index. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1016": {"severity": "warning", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}}, "user_message": "TradingView rejects a method call written straight after a history index, x[k].method(). In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1017": {"severity": "warning", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}, "user_message": "TradingView rejects a method call written straight after a history index, x[k].method(). In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1018": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "TradingView rejects a method call written straight after a history index, x[k].method(). In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1019": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "TradingView rejects a method call written straight after a history index, x[k].method(). In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1020": {"severity": "warning", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}}, "user_message": "TradingView rejects a field read written straight after a history index, x[k].field. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1021": {"severity": "warning", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}, "user_message": "TradingView rejects a field read written straight after a history index, x[k].field. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1022": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "TradingView rejects a field read written straight after a history index, x[k].field. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1023": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "TradingView rejects a field read written straight after a history index, x[k].field. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1024": {"severity": "warning", "area": "support", "message": "footprint.{footprint}(...) is not supported.", "hint": "PineForge reads a footprint''s delta() only: the fp_delta__ column of the feed a requests manifest pins for the symbol requested.", "explanation": "PineForge reads only the delta of a footprint value; every other footprint member is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"footprint": {"kind": "identifier"}}, "user_message": "PineForge reads only the delta of a footprint value. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1025": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "Currency conversion data not available in PineForge.", "explanation": "PineForge has no currency-conversion data, so request.currency_rate is refused; supply the rate yourself, for example as an input; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "PineForge has no currency-conversion data, so request.currency_rate cannot return a rate. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1026": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "External Quandl data not available in PineForge.", "explanation": "PineForge cannot load external Quandl data, so request.quandl is refused; remove it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "PineForge cannot load external Quandl data, so request.quandl cannot return any. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1027": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "External seed data feeds not available in PineForge.", "explanation": "PineForge cannot load external seed data feeds, so request.seed is refused; remove it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "PineForge cannot load external seed data feeds, so request.seed cannot return any. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1028": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.kagi() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.kagi builds a Kagi symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.kagi builds a Kagi symbol, which PineForge cannot run. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1029": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.linebreak() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.linebreak builds a Line Break symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.linebreak builds a Line Break symbol, which PineForge cannot run. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1030": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.modify() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.modify builds a modified symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.modify builds a modified symbol identifier, which PineForge cannot request. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1031": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.new() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.new builds another symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.new builds another symbol identifier, which PineForge cannot request. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1032": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.pointfigure() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.pointfigure builds a Point and Figure symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.pointfigure builds a Point and Figure symbol, which PineForge cannot run. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1033": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.renko() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.renko builds a Renko symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "ticker.renko builds a Renko symbol, which PineForge cannot run. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1034": {"severity": "warning", "area": "support", "message": "ticker.heikinashi(...) is supported only for the chart''s own symbol.", "hint": "Pass syminfo.tickerid: PineForge applies the Heikin-Ashi candle transform to the chart symbol inside request.security, but cannot load an alternate symbol''s HA candles.", "explanation": "ticker.heikinashi is accepted only for the chart's own symbol (syminfo.tickerid); another symbol's Heikin-Ashi candles cannot be loaded; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "ticker.heikinashi is supported only for the chart''s own symbol (syminfo.tickerid). In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1035": {"severity": "warning", "area": "support", "message": "{full}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "This call names a function on PineForge''s not-yet-implemented list, so it can silently misbehave. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1036": {"severity": "warning", "area": "support", "message": "{name}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "This call names a function on PineForge''s not-yet-implemented list, so it can silently misbehave. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1037": {"severity": "warning", "area": "support", "message": "{full}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "footprint.* calls need tick-level bid/ask volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "footprint.* calls need tick-level bid/ask volume rows, which a PineForge batch backtest does not load. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1038": {"severity": "warning", "area": "support", "message": "{full}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "volume_row.* calls need tick-level volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "volume_row.* calls need tick-level volume rows, which a PineForge batch backtest does not load. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1039": {"severity": "warning", "area": "support", "message": "library() declarations are not supported; PineForge runs strategies only.", "hint": "Use strategy(...) and inline or pre-expand library code before uploading.", "explanation": "PineForge runs strategies only, so a library() declaration is refused; use strategy() and paste any library code into the script; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "PineForge runs strategies only, so a library() declaration is not supported. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1040": {"severity": "warning", "area": "support", "message": "Bare barssince(...) is broken in PineForge codegen.", "hint": "Use ta.barssince(...) instead.", "explanation": "The bare barssince(...) form does not work in PineForge; call ta.barssince(...) instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "The bare barssince(...) form does not work in PineForge. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1041": {"severity": "warning", "area": "support", "message": "ta.sum is not a PineScript v6 function.", "hint": "Use math.sum(...) instead.", "explanation": "ta.sum does not exist in Pine v6; use math.sum(source, length) for a rolling sum; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "ta.sum does not exist in Pine v6. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1042": {"severity": "warning", "area": "support", "message": "ta.{name} is a PineScript v6 variable, not a function.", "hint": "Use ta.{name} without parentheses.", "explanation": "This ta.* name is a built-in variable, not a function, so write it without parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "This ta.* name is a built-in variable, not a function, so write it without parentheses. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1043": {"severity": "warning", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.closedtrades or strategy.opentrades accessor is not available in PineForge; use one of the supported trade accessors; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "This strategy.closedtrades or strategy.opentrades accessor is not available in PineForge. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1044": {"severity": "warning", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": "{hint}", "explanation": "Open trades have no exit data in Pine v6: this accessor exists only on strategy.closedtrades, so it cannot be read from strategy.opentrades; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}, "hint": {"kind": "text"}}, "user_message": "This accessor exists only on strategy.closedtrades: open trades have no exit data in Pine v6. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1045": {"severity": "warning", "area": "support", "message": "strategy.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.* function is not implemented in PineForge; check the spelling or use a supported strategy function; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "This strategy.* function is not implemented in PineForge. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1046": {"severity": "warning", "area": "support", "message": "strategy.exit(...) requires at least one price or trailing parameter in PineForge.", "hint": "Use strategy.close(...) for market exits.", "explanation": "strategy.exit needs a price or trailing parameter (profit, loss, limit, stop or a trail setting); use strategy.close for a plain market exit; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "strategy.exit needs a price or trailing parameter (profit, loss, limit, stop or a trail setting). In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1047": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported. Only request.security(...) and request.security_lower_tf(...) are available in PineForge.", "hint": "External request feeds and other request.* variants are intentionally unavailable.", "explanation": "Only request.security and request.security_lower_tf are supported; other request.* calls need data feeds PineForge does not provide; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}, "user_message": "Only request.security and request.security_lower_tf are supported. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1048": {"severity": "warning", "area": "support", "message": "ta.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this ta.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this ta.* function, so the call can compile to a silent stub. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1049": {"severity": "warning", "area": "support", "message": "math.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this math.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this math.* function, so the call can compile to a silent stub. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1050": {"severity": "warning", "area": "support", "message": "str.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this str.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this str.* function, so the call can compile to a silent stub. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1051": {"severity": "warning", "area": "support", "message": "input.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this input.* function, so the call is refused; use one of the supported input functions; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this input.* function. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1052": {"severity": "warning", "area": "support", "message": "timeframe.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only timeframe.change and timeframe.in_seconds; any other timeframe.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge implements only timeframe.change and timeframe.in_seconds. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1053": {"severity": "warning", "area": "support", "message": "color.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only color.new, color.rgb and color.r/g/b/t; any other color.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge implements only color.new, color.rgb and color.r/g/b/t. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1054": {"severity": "warning", "area": "support", "message": "runtime.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only runtime.error; any other runtime.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge implements only runtime.error. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1055": {"severity": "warning", "area": "support", "message": "log.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only log.info, log.warning and log.error; any other log.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge implements only log.info, log.warning and log.error. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1056": {"severity": "warning", "area": "support", "message": "array.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this array.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this array.* function, so the call can compile to a silent stub. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1057": {"severity": "warning", "area": "support", "message": "map.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this map.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this map.* function, so the call can compile to a silent stub. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1058": {"severity": "warning", "area": "support", "message": "map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps support only string keys; declare the map with string as its key type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "PineForge maps support only string keys. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1059": {"severity": "warning", "area": "support", "message": "map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps can hold only float, int, bool or string values; other value types such as collections or objects are refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "PineForge maps can hold only float, int, bool or string values. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1060": {"severity": "warning", "area": "support", "message": "matrix<{t}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"t": {"kind": "type"}}, "user_message": "A matrix cannot hold another collection as its element type in PineForge. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1061": {"severity": "warning", "area": "support", "message": "matrix<{t}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"t": {"kind": "type"}}, "user_message": "A matrix of a user-defined type with a map field is not supported: rollback would keep live map references. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1062": {"severity": "warning", "area": "support", "message": "matrix<{t}> element type not supported. Allowed: float, int, bool, string, color, or a declared UDT.", "hint": null, "explanation": "A matrix element must be float, int, bool, string, color or a declared user-defined type; any other element type is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"t": {"kind": "type"}}, "user_message": "A matrix element must be float, int, bool, string, color or a declared user-defined type. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1063": {"severity": "warning", "area": "support", "message": "matrix.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this matrix.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge has no implementation of this matrix.* function, so the call can compile to a silent stub. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1064": {"severity": "warning", "area": "support", "message": "{ns}.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only part of the line, box, label and linefill functions; this one is not implemented, so the call is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "PineForge implements only part of the line, box, label and linefill functions. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1065": {"severity": "warning", "area": "support", "message": "chart.point.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only chart.point.new, now, from_index, from_time and copy; any other chart.point.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge implements only chart.point.new, now, from_index, from_time and copy. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1066": {"severity": "warning", "area": "support", "message": "''export'' is a Pine library keyword; PineForge runs strategies only and does not support exported functions/types.", "hint": "Remove the ''export'' keyword (and inline any library code into the strategy script).", "explanation": "'export' marks library code; PineForge runs strategies only, so remove the keyword and inline any library code into the strategy; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "Exported declarations are not supported in a strategy. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1067": {"severity": "warning", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge warns that bar_index counts bars of the data window it is fed, so its value can differ from TradingView''s for the same script."}, + "PF-W1068": {"severity": "warning", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge warns that last_bar_index is the last index of the data window it is fed, so it can differ from TradingView''s when the history windows differ."}, + "PF-W1069": {"severity": "warning", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"name": {"kind": "identifier"}}, "user_message": "PineForge warns that timenow is the current bar''s time, not real wall-clock time, so logic relying on the real time will differ."}, + "PF-W1070": {"severity": "warning", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"chain": {"kind": "identifier"}}, "user_message": "PineForge warns that bar_index counts bars of the data window it is fed, so its value can differ from TradingView''s for the same script."}, + "PF-W1071": {"severity": "warning", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"chain": {"kind": "identifier"}}, "user_message": "PineForge warns that last_bar_index is the last index of the data window it is fed, so it can differ from TradingView''s when the history windows differ."}, + "PF-W1072": {"severity": "warning", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"chain": {"kind": "identifier"}}, "user_message": "PineForge warns that timenow is the current bar''s time, not real wall-clock time, so logic relying on the real time will differ."}, + "PF-W1073": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": null, "explanation": "Members of the footprint.* namespace need tick-level bid/ask volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "footprint.* members need tick-level bid/ask volume rows, which a PineForge batch backtest does not load. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1074": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": null, "explanation": "Members of the volume_row.* namespace need tick-level volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "volume_row.* members need tick-level volume rows, which a PineForge batch backtest does not load. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1075": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: dividends.* is not available in PineForge — fundamental dividend data is not loaded.", "hint": null, "explanation": "dividends.* fields read fundamental dividend data, which PineForge does not load outside a recorded request; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "dividends.* fields read fundamental dividend data, which PineForge does not load outside a recorded request. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1076": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: earnings.* is not available in PineForge — fundamental earnings data is not loaded.", "hint": null, "explanation": "earnings.* fields read fundamental earnings data, which PineForge does not load outside a recorded request; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "earnings.* fields read fundamental earnings data, which PineForge does not load outside a recorded request. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1077": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: splits.* is not available in PineForge — corporate-action split data is not loaded.", "hint": null, "explanation": "splits.* fields read corporate-action split data, which PineForge does not load outside a recorded request; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "splits.* fields read corporate-action split data, which PineForge does not load outside a recorded request. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1078": {"severity": "warning", "area": "support", "message": "{object_name}.{member} is a visual/style constant with no runtime value in PineForge backtests; it is only accepted as an argument to visual calls (plot, plotshape, hline, label.new, table.cell, ...), which PineForge parses and skips.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "A visual or style constant has no value in a backtest; it may only be passed to plotting and drawing calls, which PineForge skips; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "A visual or style constant has no value in a backtest. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1079": {"severity": "warning", "area": "support", "message": "{object_name}.{member} is not a Pine alert constant; only alert.freq_all, alert.freq_once_per_bar and alert.freq_once_per_bar_close exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The alert.* member is not one of Pine's alert frequency constants; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "The alert.* member is not one of Pine''s alert frequency constants. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1080": {"severity": "warning", "area": "support", "message": "{object_name}.{member} is not a barmerge constant; only barmerge.gaps_on, barmerge.gaps_off, barmerge.lookahead_on and barmerge.lookahead_off exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The barmerge.* member is not one of Pine's gaps or lookahead constants; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "The barmerge.* member is not one of Pine''s gaps or lookahead constants. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1081": {"severity": "warning", "area": "support", "message": "syminfo.{member} is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge does not implement this syminfo.* member, so reading it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}}, "user_message": "PineForge does not implement this syminfo.* member. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1082": {"severity": "warning", "area": "support", "message": "request.security parameter ''{kw_name}'' is not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts only a few named parameters in PineForge; this one is refused instead of being silently ignored, so remove it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kw_name": {"kind": "identifier"}}, "user_message": "request.security accepts only a few named parameters in PineForge. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1083": {"severity": "warning", "area": "support", "message": "Extra positional arguments to request.security are not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts at most five positional arguments (symbol, timeframe, expression, gaps, lookahead); remove the extra ones; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "request.security accepts at most five positional arguments (symbol, timeframe, expression, gaps, lookahead). In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1084": {"severity": "warning", "area": "support", "message": "request.security gaps must be barmerge.gaps_on or barmerge.gaps_off.", "hint": "Codegen only recognizes the barmerge.gaps_* literal; other values are silently treated as gaps_off.", "explanation": "The gaps argument of request.security must be written literally as barmerge.gaps_on or barmerge.gaps_off, the only forms PineForge reads; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "request.security reads gaps only as the literal barmerge.gaps_on or barmerge.gaps_off. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1085": {"severity": "warning", "area": "support", "message": "request.security lookahead must be barmerge.lookahead_on or barmerge.lookahead_off.", "hint": "Codegen only recognizes the barmerge.lookahead_* literal; other values are silently treated as lookahead_off.", "explanation": "The lookahead argument of request.security must be written literally as barmerge.lookahead_on or barmerge.lookahead_off, the only forms PineForge reads; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}, "user_message": "request.security reads lookahead only as the literal barmerge.lookahead_on or barmerge.lookahead_off. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1086": {"severity": "warning", "area": "support", "message": "request.security: {kw_name}={object_name}.{val_member} is not supported. The engine ignores this kwarg, which would silently produce different prices from TradingView.", "hint": "Allowed values: {allowed}.", "explanation": "PineForge ignores request.security's price-adjustment settings, so only no-op values are accepted; others would silently give prices unlike TradingView's; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kw_name": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "val_member": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}, "user_message": "PineForge ignores request.security''s price-adjustment settings, so prices can differ from TradingView''s. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1087": {"severity": "warning", "area": "support", "message": "request.security: {kw_name}=... must be a constant member access of the form {kw_name}. (got a non-constant expression).", "hint": "Allowed values: {allowed}.", "explanation": "A request.security price-adjustment setting must be a plain constant of the form name.value (like adjustment.none), not a computed expression; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kw_name": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}, "user_message": "A request.security price-adjustment setting must be a constant such as adjustment.none, not an expression. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1088": {"severity": "warning", "area": "support", "message": "{name} {message} (TradingView: {spelled}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A nz or fixnan call whose arguments match none of TradingView's signatures (unknown name, too many or missing arguments) is refused, as TradingView refuses it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "spelled": {"kind": "identifier"}}, "user_message": "TradingView refuses a nz or fixnan call whose arguments match none of its signatures. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1089": {"severity": "warning", "area": "support", "message": "ta.{name} {message} (TradingView: {signature}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A ta.* call whose arguments match none of TradingView's signatures (unknown or repeated parameter, too many or missing arguments) is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "signature": {"kind": "identifier"}}, "user_message": "TradingView refuses a ta.* call whose arguments match none of its signatures. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1090": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}, "user_message": "The timeframe string of request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1091": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}, "user_message": "The timeframe string of request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1092": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}, "user_message": "The timeframe string of request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1093": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}, "user_message": "The timeframe string of request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1094": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}, "user_message": "The timeframe string of request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1095": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}, "user_message": "The timeframe string of request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1096": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}, "user_message": "The timeframe string of request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1097": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}, "user_message": "The timeframe string of request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S. In a switch arm PineForge only warns and keeps the arm''s lowering."}, + "PF-W1500": {"severity": "warning", "area": "support", "message": "{call}: request.security symbol can select an alternate symbol, but PineForge always loads the current chart symbol.", "hint": "It reads no feed of another symbol: {reasons}. Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "A request.security whose symbol can select another symbol is approximated by the chart's own symbol, because no other-symbol feed can be registered for it.", "args": {"call": {"kind": "identifier"}, "reasons": {"kind": "text"}}, "user_message": "This request may read the chart''s symbol when another symbol was requested."}, + "PF-W1501": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "PineForge reads another symbol''s feed only for a symbol and timeframe registration computes before the first bar; {reasons}.", "explanation": "A request.security of another symbol has no pinned data, so the run stops with an error where its value is read; its symbol and timeframe must be known up front.", "args": {"call": {"kind": "identifier"}, "reasons": {"kind": "text"}}, "user_message": "This request has no pinned data and stops the run when its value is read."}, + "PF-W1502": {"severity": "warning", "area": "support", "message": "color(...) cast has no effect in PineForge backtests (visual only); it emits a default color.", "hint": null, "explanation": "A color(...) cast is visual only and has no effect on a backtest, so PineForge ignores it and uses a default color.", "args": {}, "user_message": "The color cast is replaced with a default color."}, + "PF-W1503": {"severity": "warning", "area": "support", "message": "strategy.risk.{name}(...) has partial PineForge runtime support.", "hint": "Verify risk behavior against PineForge results; unsupported risk edge cases may diverge from TradingView.", "explanation": "A strategy.risk.* call has only partial runtime support in PineForge, so check that your risk limits behave as they do on TradingView.", "args": {"name": {"kind": "identifier"}}, "user_message": "This risk control has partial runtime support and may differ from TradingView."}, + "PF-W1504": {"severity": "warning", "area": "support", "message": "strategy.{name} parameter ''{param_name}'' is not supported by PineForge and is ignored.", "hint": null, "explanation": "A strategy order call passes a parameter PineForge does not support, so the parameter is ignored and the order runs without it.", "args": {"name": {"kind": "identifier"}, "param_name": {"kind": "identifier"}}, "user_message": "This trading parameter is ignored, so the order runs without it."}, + "PF-W1505": {"severity": "note", "area": "support", "message": "ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does.", "hint": "A covered length-20 TradingView tape first returns a finite EMA at bar 19; standalone PineForge EMA is finite at bar 0. Its established lowering stays in place pending per-call-site population parity.", "explanation": "ta.ema is approximated during warmup: PineForge may return a finite value on early bars where TradingView still returns na, so early results can differ.", "args": {}, "user_message": "This EMA may need more earlier bars to initialize."}, + "PF-W1506": {"severity": "warning", "area": "support", "message": "color.{name}(...) has no effect in PineForge backtests (visual only); it evaluates its arguments and emits a default color.", "hint": null, "explanation": "A cosmetic color function has no effect on a backtest, so PineForge evaluates its arguments and uses a default color.", "args": {"name": {"kind": "identifier"}}, "user_message": "This color function uses a default color after evaluating its arguments."}, + "PF-W1507": {"severity": "warning", "area": "support", "message": "{ns}.{name}(...) is a visual no-op in PineForge backtests (drawing geometry is data; color/style/size are dropped).", "hint": null, "explanation": "A drawing setter for color, style or size is a visual no-op in PineForge, which keeps only the drawing's geometry as data.", "args": {"ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "This drawing setter drops color, style or size changes while retaining geometry."}, + "PF-W1508": {"severity": "note", "area": "support", "message": "{name}(...) has no effect in PineForge backtests (visual only).", "hint": null, "explanation": "A call into a visual-only namespace such as table or polyline has no effect on backtest results, so PineForge ignores it.", "args": {"name": {"kind": "identifier"}}, "user_message": "{name}() does nothing in a backtest."}, + "PF-W1509": {"severity": "note", "area": "support", "message": "{full}(...) has no effect in PineForge backtests (visual only).", "hint": null, "explanation": "A call into a visual-only namespace such as table or polyline has no effect on backtest results, so PineForge ignores it.", "args": {"full": {"kind": "identifier"}}, "user_message": "{full}() does nothing in a backtest."}, + "PF-W1510": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "In direct batch chart-scope evaluation, barstate.islast is true only on the final bar of PineForge''s fed chart-data window. Inside a request.security() history index, PineForge currently selects the false branch; requested-context last-bar state is not modeled.", "explanation": "barstate.islast is true only on the last bar of PineForge's fed data, and inside a request.security history index it selects the false branch.", "args": {"chain": {"kind": "identifier"}}, "user_message": "barstate.islast is true only on the last bar of PineForge''s fed data, and inside a request.security history index it selects the false branch."}, + "PF-W1511": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "In direct historical batch chart-scope evaluation, PineForge approximates barstate.islastconfirmedhistory as true only on the final bar of the fed chart-data window. Inside a request.security() history index, PineForge currently selects the false branch; TradingView''s requested-context and realtime-boundary semantics are not modeled.", "explanation": "barstate.islastconfirmedhistory is approximated as true only on the final bar of the fed data window, and as false inside a request.security history index.", "args": {"chain": {"kind": "identifier"}}, "user_message": "barstate.islastconfirmedhistory is approximated as true only on the final bar of the fed data window, and as false inside a request.security history index."}, + "PF-W1512": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.isconfirmed follows PineForge last-tick execution state.", "explanation": "barstate.isconfirmed follows PineForge's last-tick execution state, so it can differ from TradingView's confirmation behavior.", "args": {"chain": {"kind": "identifier"}}, "user_message": "barstate.isconfirmed follows PineForge''s last-tick execution state, so it can differ from TradingView''s confirmation behavior."}, + "PF-W1513": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.ishistory is always true in PineForge batch backtests.", "explanation": "barstate.ishistory is always true in PineForge batch backtests, because there is no real-time bar.", "args": {"chain": {"kind": "identifier"}}, "user_message": "barstate.ishistory is always true in PineForge batch backtests, because there is no real-time bar."}, + "PF-W1514": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.isnew follows PineForge first-tick execution state.", "explanation": "barstate.isnew is only approximated in PineForge, following its first-tick execution state, so it may behave differently from TradingView.", "args": {"chain": {"kind": "identifier"}}, "user_message": "barstate.isnew is only approximated in PineForge, following its first-tick execution state, so it may behave differently from TradingView."}, + "PF-W1515": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.isrealtime is always false in PineForge batch backtests.", "explanation": "barstate.isrealtime is always false because PineForge runs batch backtests on historical bars only, so real-time-only logic never runs.", "args": {"chain": {"kind": "identifier"}}, "user_message": "barstate.isrealtime is always false because PineForge runs batch backtests on historical bars only, so real-time-only logic never runs."}, + "PF-W1516": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.bg_color has no meaning in a batch backtest (no chart theme); emits a default color.", "hint": null, "explanation": "chart.bg_color depends on the chart theme, which a batch backtest does not have, so PineForge substitutes a default color.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "chart.bg_color depends on the chart theme, which a batch backtest does not have, so PineForge substitutes a default color."}, + "PF-W1517": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.fg_color has no meaning in a batch backtest (no chart theme); emits a default color.", "hint": null, "explanation": "chart.fg_color depends on the chart theme, which a batch backtest does not have, so PineForge substitutes a default color.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "chart.fg_color depends on the chart theme, which a batch backtest does not have, so PineForge substitutes a default color."}, + "PF-W1518": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.left_visible_bar_time has no meaning in a batch backtest (no viewport); emits 0.", "hint": null, "explanation": "chart.left_visible_bar_time depends on the chart viewport, which a batch backtest does not have, so PineForge substitutes 0.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "chart.left_visible_bar_time depends on the chart viewport, which a batch backtest does not have, so PineForge substitutes 0."}, + "PF-W1519": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.right_visible_bar_time has no meaning in a batch backtest (no viewport); emits 0.", "hint": null, "explanation": "chart.right_visible_bar_time depends on the chart viewport, which a batch backtest does not have, so PineForge substitutes 0.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}, "user_message": "chart.right_visible_bar_time depends on the chart viewport, which a batch backtest does not have, so PineForge substitutes 0."}, + "PF-W1520": {"severity": "warning", "area": "support", "message": "syminfo.{member} is na unless the run declares the symbol''s {member} (syminfo metadata \"{member}\", a lane fact).", "hint": null, "explanation": "This syminfo field has no built-in value in PineForge: it is na unless the run supplies the symbol's value as metadata, so anything computed from it is na.", "args": {"member": {"kind": "identifier"}}, "user_message": "This symbol field is na unless the run supplies its metadata."}, + "PF-W1521": {"severity": "warning", "area": "support", "message": "syminfo.{member} returns na in current PineForge; any expression using it will be na. Will be backfilled by pineforge-data product.", "hint": null, "explanation": "This syminfo field is not provided by PineForge yet and always reads na, so any expression using it is na.", "args": {"member": {"kind": "identifier"}}, "user_message": "This syminfo field is not provided by PineForge yet and always reads na, so any expression using it is na."}, + "PF-W1522": {"severity": "warning", "area": "support", "message": "syminfo.{member} returns na in current PineForge; condition will always be false. Will be backfilled by pineforge-data product.", "hint": null, "explanation": "This syminfo field is not provided by PineForge yet and always reads na, so a condition built on it is always false.", "args": {"member": {"kind": "identifier"}}, "user_message": "This syminfo field is not provided by PineForge yet and always reads na, so a condition built on it is always false."}, + "PF-W1523": {"severity": "warning", "area": "support", "message": "request.security symbol can select an alternate symbol, but PineForge always loads the current chart symbol.", "hint": "Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "The request.security symbol can select another symbol, but PineForge always loads the chart's symbol; resolve every value to syminfo.tickerid for exact results.", "args": {}, "user_message": "The request.security symbol can select another symbol, but PineForge always loads the chart''s symbol."}, + "PF-W1524": {"severity": "warning", "area": "support", "message": "request.security lookahead_on changes HTF timing: the completed higher-timeframe value is exposed from the bucket''s first chart bar. PineForge emits this (engine-supported) but results differ from lookahead_off and, with a 0-offset HTF expression, repaint future data.", "hint": "The safe non-repainting form pairs lookahead_on with a [1] offset (e.g. close[1]) to read only completed prior HTF bars.", "explanation": "request.security with lookahead_on exposes higher-timeframe values early and can repaint future data; pair it with a [1] offset such as close[1] to stay safe.", "args": {}, "user_message": "request.security with lookahead_on exposes higher-timeframe values early and can repaint future data."}, + "PF-W1525": {"severity": "note", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External corporate-action data not available in PineForge. A recorded series is read when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "No recorded series applies to this earnings, dividends or splits request, but its value only feeds plots, alerts or tables, so it becomes na; trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}}, "user_message": "Display-only corporate-action data is unavailable for {call}."}, + "PF-W1526": {"severity": "note", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External corporate-action data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge has no earnings, dividends or splits data; this request's value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}, "user_message": "Display-only corporate-action data is unavailable for {call}."}, + "PF-W1527": {"severity": "note", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External fundamentals data not available in PineForge. A recorded series is read when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "No recorded series applies to this request.financial call, but its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}}, "user_message": "Display-only financial data is unavailable for {call}."}, + "PF-W1528": {"severity": "note", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External fundamentals data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge has no fundamentals data for request.financial; its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}, "user_message": "Display-only financial data is unavailable for {call}."}, + "PF-W1529": {"severity": "note", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "Footprint (bid/ask volume) data not available in PineForge. A recorded series is read when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "No recorded series applies to this request.footprint call, but its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}}, "user_message": "Display-only footprint data is unavailable for {call}."}, + "PF-W1530": {"severity": "note", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "Footprint (bid/ask volume) data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge has no footprint (bid/ask volume) data for request.footprint; its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}, "user_message": "Display-only footprint data is unavailable for {call}."}, + "PF-W1531": {"severity": "note", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker), and reads another symbol''s feed only when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "Another symbol's feed is read only in the stated case; here the request's value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "vocab", "values": ["it is outside another request's expression", "it is request.security", "its expression holds no request of its own", "its gaps and lookahead are barmerge constants", "its request.footprint states ticks_per_row and va_percent as literal whole numbers", "registration computes its ignore_invalid_symbol before the first bar", "registration computes its symbol before the first bar", "registration computes its timeframe before the first bar"]}}, "user_message": "Display-only symbol data is unavailable for {call}."}, + "PF-W1532": {"severity": "note", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker). The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge loads only the chart's symbol; this request for another symbol only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}, "user_message": "Display-only symbol data is unavailable for {call}."}, + "PF-W1533": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External corporate-action data not available in PineForge. A recorded series is read when {blocker}. Its value can reach a trade: {reason}.", "explanation": "No recorded series applies to this earnings, dividends or splits request and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}, "reason": {"kind": "text"}}, "user_message": "No recorded series applies to this earnings, dividends or splits request and its value can reach a trade, so the run stops with an error where the value is read."}, + "PF-W1534": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External corporate-action data not available in PineForge. Its value can reach a trade: {reason}.", "explanation": "PineForge has no earnings, dividends or splits data and this request's value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}, "user_message": "PineForge has no earnings, dividends or splits data and this request''s value can reach a trade, so the run stops with an error where the value is read."}, + "PF-W1535": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External fundamentals data not available in PineForge. A recorded series is read when {blocker}. Its value can reach a trade: {reason}.", "explanation": "No recorded series applies to this request.financial call and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}, "reason": {"kind": "text"}}, "user_message": "No recorded series applies to this request.financial call and its value can reach a trade, so the run stops with an error where the value is read."}, + "PF-W1536": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External fundamentals data not available in PineForge. Its value can reach a trade: {reason}.", "explanation": "PineForge has no fundamentals data for request.financial and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}, "user_message": "PineForge has no fundamentals data for request.financial and its value can reach a trade, so the run stops with an error where the value is read."}, + "PF-W1537": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "Footprint (bid/ask volume) data not available in PineForge. A recorded series is read when {blocker}. Its value can reach a trade: {reason}.", "explanation": "No recorded series applies to this request.footprint call and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}, "reason": {"kind": "text"}}, "user_message": "No recorded series applies to this request.footprint call and its value can reach a trade, so the run stops with an error where the value is read."}, + "PF-W1538": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "Footprint (bid/ask volume) data not available in PineForge. Its value can reach a trade: {reason}.", "explanation": "PineForge has no footprint (bid/ask volume) data and this request's value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}, "user_message": "PineForge has no footprint (bid/ask volume) data and this request''s value can reach a trade, so the run stops with an error where the value is read."}, + "PF-W1539": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker), and reads another symbol''s feed only when {blocker}. Its value can reach a trade: {reason}.", "explanation": "PineForge reads another symbol's feed only in the stated case, and this request's value can reach a trade, so the run stops with an error where it is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "vocab", "values": ["it is outside another request's expression", "it is request.security", "its expression holds no request of its own", "its gaps and lookahead are barmerge constants", "its request.footprint states ticks_per_row and va_percent as literal whole numbers", "registration computes its ignore_invalid_symbol before the first bar", "registration computes its symbol before the first bar", "registration computes its timeframe before the first bar"]}, "reason": {"kind": "text"}}, "user_message": "PineForge reads another symbol''s feed only in the stated case, and this request''s value can reach a trade, so the run stops with an error where it is read."}, + "PF-W1540": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker). Its value can reach a trade: {reason}.", "explanation": "PineForge loads only the chart's symbol, and this request for another symbol can reach a trade, so the run stops with an error where its value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}, "user_message": "PineForge loads only the chart''s symbol, and this request for another symbol can reach a trade, so the run stops with an error where its value is read."}, + "PF-W1541": {"severity": "warning", "area": "support", "message": "{call}: another symbol''s bars, read from the feed the requests manifest pins for it; with none installed, the run stops with an error where its value is read.", "hint": "PineForge runs the expression on that symbol''s own bars (history, ta.* and syminfo.* in its context) and merges them by time as TradingView does; a symbol equal to the chart''s reads the chart.", "explanation": "request.security on another symbol reads that symbol's pinned feed; if none is installed, the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}}, "user_message": "This request requires a pinned symbol feed and stops the run if it is missing."}, + "PF-W1542": {"severity": "warning", "area": "support", "message": "{call}: its symbol can select another symbol: registered by the string the run computes, a footprint reads the feed the requests manifest pins for each symbol, the chart''s too (the chart''s bars carry no footprint); with none installed, the run stops with an error where its value is read.", "hint": "It read the chart''s bars for every symbol: another symbol''s value never comes from the chart.", "explanation": "The footprint symbol can vary: every symbol, the chart's too, reads its own pinned feed, and a missing feed stops the run where the value is read.", "args": {"call": {"kind": "identifier"}}, "user_message": "Each requested footprint needs its own pinned feed, and a missing feed stops the run."}, + "PF-W1543": {"severity": "warning", "area": "support", "message": "{call}: its symbol can select another symbol: registered by the string the run computes, the chart''s reads the chart and another symbol''s the feed the requests manifest pins for it; with none installed, the run stops with an error where its value is read.", "hint": "It read the chart''s bars for every symbol: another symbol''s value never comes from the chart.", "explanation": "The request.security symbol can be the chart's or another symbol: the chart's reads the chart, another reads its pinned feed, and a missing feed stops the run.", "args": {"call": {"kind": "identifier"}}, "user_message": "This request reads chart data for the chart symbol; another symbol needs a pinned feed or stops the run."}, + "PF-W1544": {"severity": "warning", "area": "support", "message": "{call}: TradingView''s values per chart bar, read from the series the requests manifest records under {parts}||{parts2}|{parts3}|gaps_{parts4}|lookahead_{parts5}; with none installed, the run stops with an error where its value is read.", "hint": "PineForge replays the values TradingView returned on the chart''s own bars (chart_open_ms,value): a bar the tape has no row for reads na.", "explanation": "This request replays the values TradingView returned on each chart bar, from the requests manifest; with no recording installed the run stops where it is read.", "args": {"call": {"kind": "identifier"}, "parts": {"kind": "identifier"}, "parts2": {"kind": "identifier"}, "parts3": {"kind": "identifier"}, "parts4": {"kind": "identifier"}, "parts5": {"kind": "identifier"}}, "user_message": "This request replays recorded TradingView values and stops the run if its recording is missing."}, + "PF-W1545": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it decides a loop''s break or continue.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}}, "user_message": "PineForge loads no other symbol''s lower-timeframe bars, and this request''s value can reach a trade, so the run stops with an error where it is evaluated."}, + "PF-W1546": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it is a history offset.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}}, "user_message": "PineForge loads no other symbol''s lower-timeframe bars, and this request''s value can reach a trade, so the run stops with an error where it is evaluated."}, + "PF-W1547": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it is written to a field or element.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}}, "user_message": "PineForge loads no other symbol''s lower-timeframe bars, and this request''s value can reach a trade, so the run stops with an error where it is evaluated."}, + "PF-W1548": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it reaches {label}.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}, "label": {"kind": "text"}}, "user_message": "PineForge loads no other symbol''s lower-timeframe bars, and this request''s value can reach a trade, so the run stops with an error where it is evaluated."}, + "PF-W1549": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: its expression calls {label}.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}, "label": {"kind": "text"}}, "user_message": "PineForge loads no other symbol''s lower-timeframe bars, and this request''s value can reach a trade, so the run stops with an error where it is evaluated."}, + "PF-W1550": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: its expression calls {ns}.{name}.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}, "ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}, "user_message": "PineForge loads no other symbol''s lower-timeframe bars, and this request''s value can reach a trade, so the run stops with an error where it is evaluated."}, + "PF-W1551": {"severity": "warning", "area": "support", "message": "{call}: its symbol can be another symbol''s, whose lower-timeframe bars PineForge reads from the chart.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "The request.security_lower_tf symbol can be another symbol, but PineForge only has the chart's lower-timeframe bars and reads those, so results can differ.", "args": {"call": {"kind": "identifier"}}, "user_message": "The request.security_lower_tf symbol can be another symbol, but PineForge only has the chart''s lower-timeframe bars and reads those, so results can differ."}, + "PF-W1552": {"severity": "warning", "area": "support", "message": "{call}: its symbol can be another symbol''s, whose lower-timeframe bars PineForge reads from the chart; its value reaches only display/alert sinks, so trades are unaffected.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "The lower-timeframe request may name another symbol but reads the chart's bars; its value only feeds plots, alerts or tables, so trades are unaffected.", "args": {"call": {"kind": "identifier"}}, "user_message": "The lower-timeframe request may name another symbol but reads the chart''s bars."}, + "PF-W2001": {"severity": "warning", "area": "analysis", "message": "Untyped parameter ''{param}'' of callable ''{callee}'' receives {shared} and {incoming} at its written calls; a copy per call path would exceed {max_family_variants} copies and four per written call, so PineForge types it {shared}, as its first call, and converts the other argument. Declare the parameter type to choose it.", "hint": null, "explanation": "An untyped parameter receives two argument types and one copy per call would be too many, so PineForge types it as the first call's; declare the type to choose.", "args": {"param": {"kind": "identifier"}, "callee": {"kind": "identifier"}, "shared": {"kind": "type"}, "incoming": {"kind": "type"}, "max_family_variants": {"kind": "number"}}, "user_message": "An untyped parameter receives two argument types and one copy per call would be too many, so PineForge types it as the first call''s."}, + "PF-W2002": {"severity": "warning", "area": "analysis", "message": "Untyped parameter ''{param}'' of callable ''{callee}'' receives {current} and {candidate} through calls that share one written-call variant (cs{cs_idx}); PineForge types it {current}, so the other argument is converted. Declare the parameter type to choose it.", "hint": null, "explanation": "An untyped parameter receives two argument types through calls sharing one variant; PineForge types it by the first and converts the other, so declare the type.", "args": {"param": {"kind": "identifier"}, "callee": {"kind": "identifier"}, "current": {"kind": "type"}, "candidate": {"kind": "type"}, "cs_idx": {"kind": "number"}}, "user_message": "Calls share one parameter type despite supplying different types, which can lose information."}, + "PF-W2003": {"severity": "warning", "area": "analysis", "message": "(...)[...] reads an element of the selected current array in PineForge: no history of a selection is kept, where TradingView reads the array it selected that many bars back.", "hint": null, "explanation": "Indexing a selected array with [] reads the current array, since PineForge keeps no history of selections; TradingView reads the array from that many bars back.", "args": {}, "user_message": "Indexing a selected array with [] reads the current array, since PineForge keeps no history of selections."}, + "PF-W2004": {"severity": "warning", "area": "analysis", "message": "input.source defval is not a native chart series (open, high, low, close, …); complex indicators or expressions are not supported in PineForge.", "hint": null, "explanation": "input.source needs a built-in chart series such as close as its default; indicators or other expressions are not supported in PineForge.", "args": {}, "user_message": "input.source needs a built-in chart series such as close as its default."}, + "PF-W2005": {"severity": "warning", "area": "analysis", "message": "input.timeframe defval ''{defval}'' is not a typical Pine timeframe string.", "hint": null, "explanation": "The default of input.timeframe is not a usual Pine timeframe string such as 15, 1D or W; check its spelling.", "args": {"defval": {"kind": "identifier"}}, "user_message": "The default of input.timeframe is not a usual Pine timeframe string such as 15, 1D or W."}, + "PF-W2006": {"severity": "warning", "area": "analysis", "message": "input.session defval ''{defval}'' may be invalid (expected e.g. ''24x7'', ''0930-1600'', or weekday flags).", "hint": null, "explanation": "The default of input.session may not be a valid session string; use forms like 24x7 or 0930-1600, optionally with weekday flags.", "args": {"defval": {"kind": "identifier"}}, "user_message": "The default of input.session may not be a valid session string."}, + "PF-W2007": {"severity": "warning", "area": "analysis", "message": "input.string defval is not among the options list values.", "hint": null, "explanation": "The default of input.string is not among its listed options; choose a default that appears in the options list.", "args": {}, "user_message": "The default of input.string is not among its listed options."}, + "PF-W2008": {"severity": "warning", "area": "analysis", "message": "input.enum defval {ename}.{emem} is not a member of enum {ename}.", "hint": null, "explanation": "The default of input.enum names a member the enum does not declare; use one of the enum's own members.", "args": {"ename": {"kind": "identifier"}, "emem": {"kind": "identifier"}}, "user_message": "The default of input.enum names a member the enum does not declare."}, + "PF-W2009": {"severity": "warning", "area": "analysis", "message": "input defval ''{name}'' is not a known chart series (open, high, low, close, …); verify spelling or use a series variable.", "hint": null, "explanation": "The default of this input is not a known chart series such as close; check the spelling or use a series variable.", "args": {"name": {"kind": "identifier"}}, "user_message": "The default of this input is not a known chart series such as close."}, + "PF-W3001": {"severity": "warning", "area": "request-security", "message": "request.security timeframe reads ''{name}'', which the script reassigns: PineForge registers every request before the first bar, where it holds its initial value, and cannot compute it there (''{where}'' {reason})", "hint": null, "explanation": "The request.security timeframe reads a reassigned variable PineForge cannot compute before the first bar, so the request uses its initial value.", "args": {"name": {"kind": "identifier"}, "where": {"kind": "identifier"}, "reason": {"kind": "vocab", "values": ["is assigned a value it cannot compute there", "is assigned after the first request", "is not a scalar int, float, bool or string", "is not declared at the top level"]}}, "user_message": "The request.security timeframe reads a reassigned variable PineForge cannot compute before the first bar, so the request uses its initial value."}, + "PF-W3002": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', a parameter of ''{helper}'' whose argument PineForge does not recompute on the requested bars: it reads na", "hint": null, "explanation": "A request.security expression reads the history of a function parameter PineForge does not recompute on the requested bars, so the read gives na.", "args": {"name": {"kind": "identifier"}, "helper": {"kind": "identifier"}}, "user_message": "A request.security expression reads the history of a function parameter PineForge does not recompute on the requested bars, so the read gives na."}, + "PF-W3003": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', a parameter of ''{helper}'' whose argument PineForge does not recompute on the requested bars: it reads the global ''{name}'' instead", "hint": null, "explanation": "A request.security expression reads the history of a function parameter PineForge does not recompute on requested bars, so it reads the same-named global instead.", "args": {"name": {"kind": "identifier"}, "helper": {"kind": "identifier"}}, "user_message": "This requested-context history reads the same-named chart global instead of the function parameter."}, + "PF-W3004": {"severity": "warning", "area": "request-security", "message": "request.security payload calls function ''{callee_name}'' on the chart''s bar: a payload inlines a function under a builtin call only when its body is a single expression and so is every user call it makes, directly or through a global''s value; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A function called in a request.security expression runs on the chart's bar, since under a builtin call PineForge inlines only single-expression functions and calls.", "args": {"callee_name": {"kind": "identifier"}}, "user_message": "This function runs on the chart''s bar because it cannot be inlined under the requested-context builtin."}, + "PF-W3005": {"severity": "warning", "area": "request-security", "message": "request.security payload calls function ''{callee_name}'' on the chart''s bar: a payload inlines a method on the requested bar only for a scalar receiver and arguments and a single-expression body reading no mutable global, whose user calls, directly or through a global''s value, are single expressions too; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A user call in a request.security expression runs on the chart's bar, since PineForge inlines a method on the requested bar only for scalar, single-expression cases.", "args": {"callee_name": {"kind": "identifier"}}, "user_message": "This user call runs on the chart''s bar because it cannot be inlined on the requested bar."}, + "PF-W3006": {"severity": "warning", "area": "request-security", "message": "request.security payload calls function ''{callee_name}'' on the chart''s bar: the evaluator cannot inline it ({reason}); TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A function in a request.security expression runs on the chart's bar, not the requested one, because PineForge's evaluator cannot inline it for the stated reason.", "args": {"callee_name": {"kind": "identifier"}, "reason": {"kind": "text"}}, "user_message": "This function runs on the chart''s bar because it cannot be inlined on the requested bar."}, + "PF-W3007": {"severity": "warning", "area": "request-security", "message": "request.security payload calls method ''{callee_member}'' on the chart''s bar: a payload inlines a function under a builtin call only when its body is a single expression and so is every user call it makes, directly or through a global''s value; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A method called in a request.security expression runs on the chart's bar, since under a builtin call PineForge inlines only single-expression functions and calls.", "args": {"callee_member": {"kind": "identifier"}}, "user_message": "This method runs on the chart''s bar because it cannot be inlined under the requested-context builtin."}, + "PF-W3008": {"severity": "warning", "area": "request-security", "message": "request.security payload calls method ''{callee_member}'' on the chart''s bar: a payload inlines a method on the requested bar only for a scalar receiver and arguments and a single-expression body reading no mutable global, whose user calls, directly or through a global''s value, are single expressions too; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A method called in a request.security expression runs on the chart's bar, since only scalar, single-expression methods are inlined on the requested bar.", "args": {"callee_member": {"kind": "identifier"}}, "user_message": "This method runs on the chart''s bar because it cannot be inlined on the requested bar."}, + "PF-W3009": {"severity": "warning", "area": "request-security", "message": "request.security payload calls method ''{callee_member}'' on the chart''s bar: the evaluator cannot inline it ({reason}); TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A method in a request.security expression runs on the chart's bar, not the requested one, because PineForge's evaluator cannot inline it for the stated reason.", "args": {"callee_member": {"kind": "identifier"}, "reason": {"kind": "text"}}, "user_message": "This method runs on the chart''s bar because it cannot be inlined on the requested bar."}, + "PF-W3010": {"severity": "warning", "area": "request-security", "message": "request.security payload keeps its user calls under builtin calls and its methods on the chart''s bar, as before: {message} (line {line}); TradingView evaluates them on the requested bar.", "hint": null, "explanation": "PineForge keeps this request.security payload's user calls under builtin calls and its methods on the chart's bar, for the stated reason, unlike TradingView.", "args": {"message": {"kind": "text"}, "line": {"kind": "number"}}, "user_message": "Some calls in this requested-context expression still run on the chart''s bar."}, + "PF-W3011": {"severity": "warning", "area": "request-security", "message": "request.security payload keeps its user calls under builtin calls and its methods on the chart''s bar, as before: {message}; TradingView evaluates them on the requested bar.", "hint": null, "explanation": "PineForge keeps this request.security payload's user calls under builtin calls and its methods on the chart's bar, for the stated reason, unlike TradingView.", "args": {"message": {"kind": "text"}}, "user_message": "Some calls in this requested-context expression still run on the chart''s bar."}, + "PF-W3012": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', an element of a tuple declaration, on the chart''s bar; TradingView reads it on the requested bar.", "hint": null, "explanation": "A request.security expression reads the history of a tuple-declared variable on the chart's bar, where TradingView reads it on the requested bar.", "args": {"name": {"kind": "identifier"}}, "user_message": "A request.security expression reads the history of a tuple-declared variable on the chart''s bar, where TradingView reads it on the requested bar."}, + "PF-W3013": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{object_name}'' under a builtin call on the chart''s bar; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A request.security expression reads a variable's history inside a builtin call on the chart's bar, where TradingView evaluates it on the requested bar.", "args": {"object_name": {"kind": "identifier"}}, "user_message": "A request.security expression reads a variable''s history inside a builtin call on the chart''s bar, where TradingView evaluates it on the requested bar."}, + "PF-W5001": {"severity": "warning", "area": "codegen", "message": "strategy(use_bar_magnifier=...) is not a literal bool: the generated strategy does not declare the bar magnifier, so a host runs it without one.", "hint": "Write use_bar_magnifier = true or false.", "explanation": "Write use_bar_magnifier as a literal true or false; any other expression is ignored, so the strategy declares no bar magnifier and the host runs without one.", "args": {}, "user_message": "A nonliteral use_bar_magnifier value leaves the generated strategy without a bar-magnifier declaration."}, + "PF-W5002": {"severity": "warning", "area": "codegen", "message": "input key ''{key}'' is shared by the inputs at {spots} and {spots2}: PineForge sets an input override by its title, else by the name of the declaration holding it, so one override sets all of them.", "hint": "Give each input its own title to override them apart.", "explanation": "Several inputs share one override key (their title, else their declaration's name), so one override sets all of them; give each input its own title.", "args": {"key": {"kind": "identifier"}, "spots": {"kind": "text"}, "spots2": {"kind": "text"}}, "user_message": "Several inputs share an override key, so their overrides are ambiguous."}, + "PF-W5003": {"severity": "warning", "area": "codegen", "message": "array.slice returns a copy in PineForge; TradingView slices share source elements, so writes through either array can diverge.", "hint": "Avoid mutating a slice or its source while the slice is used.", "explanation": "array.slice returns an independent copy in PineForge, while TradingView's slice shares elements, so avoid mutating a slice or its source while both are used.", "args": {}, "user_message": "array.slice returns an independent copy in PineForge, while TradingView''s slice shares elements, so avoid mutating a slice or its source while both are used."}, + "PF-W5004": {"severity": "warning", "area": "codegen", "message": "A {kind} is stored as a 32-bit int in PineForge; this value can exceed int32, where TradingView''s int is 64-bit, and is truncated (or read as na) there.", "hint": "Declare the values float to keep every digit.", "explanation": "This collection element is stored as a 32-bit int, so a value beyond int32 is truncated or read as na, unlike TradingView's 64-bit int; declare the values float.", "args": {"kind": {"kind": "vocab", "values": ["map<..., int> value", "matrix element"]}}, "user_message": "This collection element is stored as a 32-bit int, so a value beyond int32 is truncated or read as na, unlike TradingView''s 64-bit int."}, + "PF-W5005": {"severity": "warning", "area": "codegen", "message": "An {kind} is stored as a 32-bit int in PineForge; this value can exceed int32, where TradingView''s int is 64-bit, and is truncated (or read as na) there.", "hint": "Declare the values float to keep every digit.", "explanation": "This collection element is stored as a 32-bit int, so a value beyond int32 is truncated or read as na, unlike TradingView's 64-bit int; declare the values float.", "args": {"kind": {"kind": "vocab", "values": ["array element"]}}, "user_message": "This collection element is stored as a 32-bit int, so a value beyond int32 is truncated or read as na, unlike TradingView''s 64-bit int."}, + "PF-W5006": {"severity": "warning", "area": "codegen", "message": "na() of a string reads the empty string as na: PineForge stores a string na as \"\", so an authored empty string is na here, while TradingView tells the two apart.", "hint": null, "explanation": "na() of a string treats the empty string as na because PineForge stores a string na as an empty string, so an authored empty string reads as na.", "args": {}, "user_message": "na() of a string treats the empty string as na because PineForge stores a string na as an empty string, so an authored empty string reads as na."}, + "PF-W5007": {"severity": "warning", "area": "codegen", "message": "str.repeat is missing its count argument; PineForge emits an empty string for this invalid TradingView call.", "hint": null, "explanation": "str.repeat was called without its count argument, which TradingView rejects; PineForge emits an empty string instead.", "args": {}, "user_message": "The missing str.repeat count produces an empty string for a call TradingView rejects."}, + "PF-W5008": {"severity": "warning", "area": "codegen", "message": "str.repeat count can be na: PineForge returns an empty string for that value, while TradingView returns na string. The engine has no nullable string value.", "hint": "Check na(count) before calling str.repeat when the result affects strategy logic.", "explanation": "str.repeat's count can be na; PineForge then returns an empty string where TradingView returns na, so check na(count) first if the result drives logic.", "args": {}, "user_message": "A missing str.repeat count value produces an empty string instead of TradingView''s na string."}, + "PF-W5009": {"severity": "warning", "area": "codegen", "message": "session.{member} inside request.security keeps the time-of-day predicate at the security bar''s open time, which can differ from TradingView: {opens}a D/W/M bar, {daily} on TradingView, reads its open''s time of day. The chart''s own session flags read the engine''s session facts.", "hint": null, "explanation": "A session flag inside request.security is tested at the security bar's open time, which can differ from TradingView, notably for D/W/M bars.", "args": {"member": {"kind": "identifier"}, "opens": {"kind": "vocab", "values": ["", "a bar that opens in a session break and holds the reopen reads as out of market, and "]}, "daily": {"kind": "vocab", "values": ["always in market", "never post-market", "never pre-market"]}}, "user_message": "A session flag inside request.security is tested at the security bar''s open time, which can differ from TradingView, notably for D/W/M bars."}, + "PF-W5010": {"severity": "warning", "area": "codegen", "message": "{object_name}[...] reads the current {kind} in PineForge: no history of this parameter is kept, where TradingView reads the copy the call that many calls back left (fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "Indexing a function parameter's array or matrix with [] reads the current collection in PineForge, while TradingView reads the copy from that many calls back.", "args": {"object_name": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}, "user_message": "This collection history reads the current function argument instead of its historical copy."}, + "PF-W5011": {"severity": "warning", "area": "codegen", "message": "{object_name}[...] reads the current {name} reference in PineForge: no history of this variable is kept here, where TradingView reads the reference it held that many bars back.", "hint": null, "explanation": "Indexing an object or drawing variable with [] reads its current reference in PineForge, while TradingView reads the reference it held that many bars back.", "args": {"object_name": {"kind": "identifier"}, "name": {"kind": "type"}}, "user_message": "Indexing an object or drawing variable with [] reads its current reference in PineForge, while TradingView reads the reference it held that many bars back."}, + "PF-W5012": {"severity": "warning", "area": "codegen", "message": "{kind} history indexing uses the current collection element in PineForge; the engine does not retain per-bar collection IDs, so this result can differ from TradingView and a missing index is not represented faithfully.", "hint": null, "explanation": "History indexing of an array or map reads the current element, as PineForge keeps no per-bar collection history, so results can differ from TradingView.", "args": {"kind": {"kind": "vocab", "values": ["array", "map"]}}, "user_message": "History indexing of an array or map reads the current element, as PineForge keeps no per-bar collection history, so results can differ from TradingView."} }} diff --git a/pineforge_codegen/errors.py b/pineforge_codegen/errors.py index dc62d9d..b5362e4 100644 --- a/pineforge_codegen/errors.py +++ b/pineforge_codegen/errors.py @@ -7,6 +7,7 @@ class Level(Enum): ERROR = "error" WARNING = "warning" + NOTE = "note" class Phase(Enum): @@ -45,6 +46,16 @@ def code(self) -> str: def args(self) -> dict: return self._coded()[1] + @property + def user_message(self) -> str: + """The catalog's short ICU template, with values supplied by ``args``. + + This is intentionally not rendered English: receivers translate by + stable code or render the template with the existing named arguments. + """ + from .diagnostic_codes import _user_message_template + return _user_message_template(self.code) + def _coded(self) -> tuple[str, dict]: severity = getattr(self.level, "value", self.level) key = (severity, self.message, self.hint) @@ -81,7 +92,7 @@ def format(self, source: str) -> str: for d in self.diagnostics: loc = d.location - level_str = d.level.value # "error" or "warning" + level_str = d.level.value # "error", "warning" or "note" phase_str = d.phase.value # "ANALYZER", etc. # Header: error[ANALYZER]: message diff --git a/pineforge_codegen/support_checker.py b/pineforge_codegen/support_checker.py index 8393665..f914298 100644 --- a/pineforge_codegen/support_checker.py +++ b/pineforge_codegen/support_checker.py @@ -1183,6 +1183,15 @@ def _warn(self, node: ASTNode | None, message: str, hint: str | None = None) -> hint=hint, )) + def _note(self, node: ASTNode | None, message: str, hint: str | None = None) -> None: + self._diagnostics.append(Diagnostic( + level=Level.NOTE, + phase=Phase.ANALYZER, + location=_loc(node, self._filename), + message=message, + hint=hint, + )) + def _reject_if_in( self, table: dict, @@ -1858,7 +1867,7 @@ def _visit_FuncCall(self, node: FuncCall) -> None: if ns == "ta": self._check_ta_call(node, name) if name == "ema": - self._warn( + self._note( node, "ta.ema initial warmup is approximated: PineForge may " "return a finite value before TradingView does.", @@ -1990,20 +1999,20 @@ def _visit_FuncCall(self, node: FuncCall) -> None: self._visit_children_const_ok(node) return - # Drawing / charting / alert namespaces — codegen drops silently. Warn, + # Drawing / charting / alert namespaces — codegen drops silently. Note, # don't error: many strategies include these for the TradingView UI. # Their argument subtrees legitimately carry constant-namespace # members (plot.style_*, text.align_*, alert.freq_*, ...), so visit # children with those reads allowed. if ns is None and name in SKIP_FUNC_NAMES: - self._warn( + self._note( node, f"{name}(...) has no effect in PineForge backtests (visual only).", ) self._visit_children_const_ok(node) return if ns is not None and ns in SKIP_NAMESPACES: - self._warn( + self._note( node, f"{full}(...) has no effect in PineForge backtests (visual only).", ) @@ -2321,7 +2330,7 @@ def _check_request_security(self, node: FuncCall) -> None: def _lower_no_data_request(self, node: FuncCall, at: ASTNode, why: str, reason: str | None | object = ...) -> None: """A request PineForge has no data for: lowered to na, with a - warning, when its value reaches display and alert sinks only; else a + note, when its value reaches display and alert sinks only; else a deferred refusal whose first read stops the run (``external_requests``). ``reason`` is the trade slice's, when the caller has it.""" @@ -2332,7 +2341,7 @@ def _lower_no_data_request(self, node: FuncCall, at: ASTNode, why: str, lowering = "inert" if reason is None else "unpinned" node.annotations = {**(node.annotations or {}), LOWERING_ANNOTATION: lowering} if reason is None: - self._warn( + self._note( at, f"{spell_call(node)}: value reaches only display/alert sinks; " "lowered to na; trades are unaffected.", diff --git a/scripts/gen_diagnostics_catalog.py b/scripts/gen_diagnostics_catalog.py index a5f7f0b..d375c64 100644 --- a/scripts/gen_diagnostics_catalog.py +++ b/scripts/gen_diagnostics_catalog.py @@ -38,10 +38,10 @@ sys.path.insert(0, str(ROOT)) from pineforge_codegen.diagnostic_codes import ( # noqa: E402 - CATALOG_PATH, CATALOG_SCHEMA, UNCATALOGUED, escape_literal, + CATALOG_PATH, CATALOG_SCHEMA, UNCATALOGUED, escape_literal, parse_template, ) -ERR, WARN = "error", "warning" +ERR, WARN, NOTE = "error", "warning", "note" MAX_VARIANTS = 48 # Area digit of a code, by the module that spells the template. @@ -82,6 +82,7 @@ def area_of(path: str) -> int: # index of a positional argument, its keyword being "message" / "hint". def emitter(name: str, path: str): table = { + "_note": (NOTE, 1, 2), "_err": (ERR, 1, 2), "_codegen_error": (ERR, 1, 2), "_codegen_warning": (WARN, 1, 2), "_codegen_error_diagnostic": (ERR, 1, 2), "_reject": (ERR, 1, 2), "_feed_warning": (WARN, 2, 3), "pass_warning": (WARN, 1, 2), @@ -712,6 +713,8 @@ def _level_of(mod: Module, call: ast.Call) -> list[str]: out.append(ERR) if "WARNING" in src: out.append(WARN) + if "NOTE" in src: + out.append(NOTE) return out @@ -750,7 +753,7 @@ def extract() -> list[dict]: message, hint = _reject_if_in_message(mod, call) if message is None or _forwards_parameter(mod, message): continue - severities = [severity] if severity in (ERR, WARN) else _level_of(mod, call) + severities = [severity] if severity in (ERR, WARN, NOTE) else _level_of(mod, call) if severity_choices: severities = severity_choices if name == "ParseError" or name == "MethodBindError" or name == "LibraryResolveError": @@ -877,10 +880,12 @@ def load_catalog() -> dict: def _next_code(codes: dict, severity: str, area: int) -> str: - letter = "E" if severity == ERR else "W" + # The declared severity drives allocation; historical W identities are + # shared by warnings and notes, and existing identities never move. + letter = {ERR: "E", WARN: "W", NOTE: "W"}[severity] used = {int(c[4:]) for c in codes if c.startswith(f"PF-{letter}{area}")} start = area * 1000 + 1 - if area == 1 and severity == WARN: + if area == 1 and severity in (WARN, NOTE): start = 1000 + SWITCH_ARM_TWIN_LIMIT if area == 1 and severity == ERR: limit = 1000 + SWITCH_ARM_TWIN_LIMIT @@ -912,6 +917,9 @@ def merge(catalog: dict, templates: list[dict]) -> list[str]: "message": t["message"], "hint": t["hint"], "explanation": "", "args": {name: {"kind": _guess_kind(name, src)} for name, src in t["sources"].items()}, + # New templates need an authored short sentence; never copy a + # possibly unbounded raw diagnostic into the presentation field. + "user_message": "", } by_key[key] = code added.append(code) @@ -987,15 +995,38 @@ def ensure_uncatalogued(catalog: dict) -> None: "explanation": ("A diagnostic whose text no catalog template renders; the " "test suite refuses it, so a release never emits it."), "args": {"message": {"kind": "text"}, "hint": {"kind": "text"}}, + "user_message": ("PineForge reported an unrecognized compilation error." + if severity == ERR else "PineForge reported an unrecognized diagnostic."), }) +def invalid_user_messages(catalog: dict) -> list[str]: + """Require short ICU templates over existing argument names for every code.""" + invalid = [] + for code, entry in catalog["codes"].items(): + template = entry.get("user_message") + if (not isinstance(template, str) or not template or len(template) > 180 + or template != template.strip() or "\n" in template or not template.endswith(".")): + invalid.append(code) + continue + try: + parts = parse_template(template) + except ValueError: + invalid.append(code) + continue + names = {part[0] for part in parts if isinstance(part, tuple)} + if (not names <= set(entry.get("args", {})) + or not any(isinstance(part, str) and part.strip(" .") for part in parts)): + invalid.append(code) + return invalid + + def dump(catalog: dict) -> str: """One code per line: compact for the Pyodide bundle, readable in a diff.""" codes = sorted(catalog["codes"].items()) lines = [f'{{"schema": {json.dumps(CATALOG_SCHEMA)},', ' "codes": {'] for i, (code, entry) in enumerate(codes): - ordered = {k: entry[k] for k in ("severity", "area", "message", "hint", "explanation", "args") + ordered = {k: entry[k] for k in ("severity", "area", "message", "hint", "explanation", "args", "user_message") if k in entry} tail = "," if i < len(codes) - 1 else "" lines.append(f" {json.dumps(code)}: {json.dumps(ordered, ensure_ascii=False)}{tail}") @@ -1023,12 +1054,18 @@ def main(argv=None) -> int: write_pin(catalog) CATALOG_PATH.write_text(dump(catalog), encoding="utf-8") print(f"{len(added)} code(s) added; {len(catalog['codes'])} in the catalog") - return 0 + invalid = invalid_user_messages(catalog) + for code in invalid: + print(f"author a short user_message template over existing args: {code}") + return 1 if invalid else 0 have = {(e["severity"], e["message"], e.get("hint")) for e in catalog["codes"].values()} missing = [t for t in templates if (t["severity"], t["message"], t["hint"]) not in have] for t in missing: print(f"no code: [{t['severity']}] {t['message']!r} hint={t['hint']!r} at {', '.join(t['sites'])}") - return 1 if missing else 0 + invalid = invalid_user_messages(catalog) + for code in invalid: + print(f"invalid or missing user_message: {code}") + return 1 if missing or invalid else 0 if __name__ == "__main__": diff --git a/tests/fixtures/diagnostic_codes_pin.json b/tests/fixtures/diagnostic_codes_pin.json index 95e2813..ae88501 100644 --- a/tests/fixtures/diagnostic_codes_pin.json +++ b/tests/fixtures/diagnostic_codes_pin.json @@ -548,11 +548,11 @@ "PF-W1502": "7414dde57f8560fef4a235df1712edcdd104dabb912301c0b7955cd6180806e2", "PF-W1503": "d01282d4267e74bee4f2410d627a53659dfb8ef4d3a7da52aa6d2472ca3cdd44", "PF-W1504": "a47b0c03eca361d8efc488ad9978d80981fa62ece90917d644e652f526965ec2", - "PF-W1505": "787177596255e23d0b59c8aa9892f69d71a1a745c89982b96610389c129f4735", + "PF-W1505": "fde078aa4775cda6e64a60305bbcf7498b878a0a609c747e08c7fb3325a95a30", "PF-W1506": "4a3de9263a6aee53db84e33bdc89120475693bc33f8817897c5e3b0c4f600e70", "PF-W1507": "6abcc1fbd882466757a9c052cefccec32d0ea79551eafc1b2dd8418a68ecae08", - "PF-W1508": "e6a55746d8cd3e273e1a160f8d40005667d7276f14e43679802b7acea59eb8a5", - "PF-W1509": "14a7dc566b33c9ac37dbaddff8ec88284778798cb6ed2c6b82e734f741e2db64", + "PF-W1508": "790f6f5b770d7fe6d8b38d1f87ee97f3ce3eb0eb5775c03f67b13e11b22e2900", + "PF-W1509": "ed323b3fdca49ba438e0b0297a092928a316e18b05c0d0cb89de880f40a89b12", "PF-W1510": "2c8994cfc4ca7de7a63f18306b1b25147d9ed0fccb13799fb24e01b5aaae1b1e", "PF-W1511": "7a7077a3ea2c89a607a74bbba0fa197b193af52a8d2dbbb10c186a97e562e6e0", "PF-W1512": "621ae32351ea33c51a2f12e668f0314341354fef423a4e02e272d03874080dce", @@ -568,14 +568,14 @@ "PF-W1522": "ef8bdb005216265ab866cfe24f869b04bc7b76187776f51ee326e3d124799646", "PF-W1523": "6048f792bbe012075b1f1af01ba2a4a7e92ed31471adaae94a3b4fcdff9294e0", "PF-W1524": "eb43a104276e90b07fd37ece812f5c1206dabc36943ef2bf56188744ff5ea6cd", - "PF-W1525": "7f05cf12e7274bf5ae4e4164f975fc4185864e3dc9658a128bd8f3413213d06b", - "PF-W1526": "9a7990cadb1fe7eda3d35cdd345836889d5e8a7a28d0279e2c2e3e8d8334b91d", - "PF-W1527": "6f7b920851e88a42f7a414060750870806bbab9209aa93e24d008affbba3360f", - "PF-W1528": "c7b73144ec5143b30f2914ea891277630110c77150aec2b766643e023bd6c15e", - "PF-W1529": "ccc27d2ce0c2216a63bde293f052cf39e913e8135a5d5df3b0ea19b428048912", - "PF-W1530": "095838c70d9f3e88f202c92312b649d717a4749e7b205f90f4b1e2e3f88d736b", - "PF-W1531": "75e41d964c941d0b16e7f1b74fe60aea944a2a24bcdd8f7438bd84263be55705", - "PF-W1532": "e844cd922c91555618673691479c7dc64d280d7621da59b4f2a6f9cfe83205c4", + "PF-W1525": "80ea1867d77a411a20ee83a9e23fad6997aa24f69dd373e23c195cb54903519e", + "PF-W1526": "98157eb7a44df784d4960dbcc6362dd39b4c5e4fa9b6c6cd3e21082361f95e1a", + "PF-W1527": "e47ce43025d8070e3a3e880bb644531e869695cf0a3585ea8dd45daad1613af7", + "PF-W1528": "a9ad97295ab0721b0a53633c5ad878ba6072eb0e4cded628b4e25122ac3867c2", + "PF-W1529": "0f260c8ff407b95db738ccfdae2ce026e6791e187d2444d2fab552bd80437ca6", + "PF-W1530": "53f85e6926d44274bce372a450d84603f6e5a34b7a486b1106ffada6bd22f1da", + "PF-W1531": "6c5a0cd14e422a9e6052453a7d475160917c0e521280a86082ef3de77b381e7f", + "PF-W1532": "5788cccd9ee1fcf0402f894c09df19b8d2078ea69966e8ef679b31acec0a9423", "PF-W1533": "c244f2332d60b36aee58c5d46a62c73da9cfded5a8c4065821787dadaabaeab6", "PF-W1534": "6f62f69665b802bf9f80cdeb10e2a720379b4f296b71d3c922b463cf1112c5d8", "PF-W1535": "cb45ba282f87aae25883dedd8287263de9bfcb60c3ae9a97bbc5f32e872622f6", diff --git a/tests/fixtures/diagnostic_notes/catalog.before.json b/tests/fixtures/diagnostic_notes/catalog.before.json new file mode 100644 index 0000000..df1cfd7 --- /dev/null +++ b/tests/fixtures/diagnostic_notes/catalog.before.json @@ -0,0 +1,632 @@ +{"schema": "pineforge-diagnostics-catalog/v1", + "codes": { + "PF-E0000": {"severity": "error", "area": "uncatalogued", "message": "{message}", "hint": "{hint}", "explanation": "A diagnostic whose text no catalog template renders; the test suite refuses it, so a release never emits it.", "args": {"message": {"kind": "text"}, "hint": {"kind": "text"}}}, + "PF-E0001": {"severity": "error", "area": "source", "message": "Block nesting depth exceeds {max_nesting_depth} levels.", "hint": null, "explanation": "Indented blocks (if, for, while, functions) are nested deeper than PineForge allows; flatten the structure.", "args": {"max_nesting_depth": {"kind": "number"}}}, + "PF-E0002": {"severity": "error", "area": "source", "message": "Invalid color literal: expected hex digits after ''#''", "hint": "Color literals must be #RRGGBB or #RRGGBBAA", "explanation": "A '#' starts a color literal but no hex digits follow it; write the color as #RRGGBB or #RRGGBBAA.", "args": {}}, + "PF-E0003": {"severity": "error", "area": "source", "message": "Delimiter nesting depth exceeds {max_nesting_depth} levels.", "hint": null, "explanation": "Parentheses or square brackets are nested deeper than PineForge allows; split the expression into simpler steps.", "args": {"max_nesting_depth": {"kind": "number"}}}, + "PF-E0004": {"severity": "error", "area": "source", "message": "Unexpected character: ''{ch}''", "hint": null, "explanation": "The script contains a character that is not valid Pine syntax outside a string; remove or replace it.", "args": {"ch": {"kind": "identifier"}}}, + "PF-E0005": {"severity": "error", "area": "source", "message": "Malformed scientific notation: expected digits after exponent", "hint": "Example: 1.5e-3 or 2E10", "explanation": "A number in scientific notation has an exponent marker (e or E) with no digits after it; add the exponent digits or drop the marker.", "args": {}}, + "PF-E0006": {"severity": "error", "area": "source", "message": "Unterminated string literal: the line ends before its closing quote and the next line is not indented as a wrapped line.", "hint": "Close the string on its line, indent the line it wraps onto, or use a multiline string (\"\"\"...\"\"\").", "explanation": "A string is not closed on its line and the next line is not an indented continuation; close the quote or use a triple-quoted string.", "args": {}}, + "PF-E0007": {"severity": "error", "area": "source", "message": "Unterminated multiline string literal: no closing {delimiter} before the end of the script.", "hint": "A multiline string ends at the next \"\"\" (or '''''' for one opened with ''''''); escape a quote that would end it early.", "explanation": "A triple-quoted string never reaches its closing delimiter before the script ends; add the closing triple quote or escape an early quote.", "args": {"delimiter": {"kind": "identifier"}}}, + "PF-E0008": {"severity": "error", "area": "source", "message": "Source size exceeds {max_source_chars} characters.", "hint": null, "explanation": "The script is larger than the maximum source size PineForge accepts; shorten it.", "args": {"max_source_chars": {"kind": "number"}}}, + "PF-E0009": {"severity": "error", "area": "source", "message": "AST nesting depth exceeds {max_nesting_depth} nodes.", "hint": null, "explanation": "An expression or operator chain is so long that its syntax tree is deeper than PineForge allows; break it into several statements.", "args": {"max_nesting_depth": {"kind": "number"}}}, + "PF-E0010": {"severity": "error", "area": "source", "message": "Transpilation time exceeds {max_transpile_seconds} seconds.", "hint": null, "explanation": "Transpiling the script ran past the time limit; simplify it, for example by reducing very large or deeply nested code.", "args": {"max_transpile_seconds": {"kind": "number"}}}, + "PF-E0011": {"severity": "error", "area": "source", "message": "Expected {expected_token}, got {token_type}(''{token}''). {msg}", "hint": null, "explanation": "The parser required one specific token here and found another; fix the syntax at the reported position.", "args": {"expected_token": {"kind": "keyword"}, "token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}, "msg": {"kind": "text"}}}, + "PF-E0012": {"severity": "error", "area": "source", "message": "Nesting depth exceeds {max_nesting_depth} levels.", "hint": null, "explanation": "Blocks, else-if chains, prefix operators or nested expressions go deeper than PineForge's nesting limit; flatten the code.", "args": {"max_nesting_depth": {"kind": "number"}}}, + "PF-E0013": {"severity": "error", "area": "source", "message": "Unexpected token {token_type}(''{token}'') after statement; expected a line break or comma", "hint": null, "explanation": "Two expressions sit on one line with nothing between them; separate statements with a line break or a comma.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0014": {"severity": "error", "area": "source", "message": "''export'' declarations belong to Pine libraries; PineForge transpiles strategies only", "hint": null, "explanation": "export marks a Pine library declaration, but PineForge transpiles strategies only; remove export or write a strategy.", "args": {}}, + "PF-E0015": {"severity": "error", "area": "source", "message": "Expected LPAREN, got {token_type}(''{token}'').", "hint": null, "explanation": "A '(' is missing where a call, a declaration's argument list or a function definition requires one.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0016": {"severity": "error", "area": "source", "message": "Expected RPAREN, got {token_type}(''{token}'').", "hint": null, "explanation": "A ')' is missing or misplaced: a call, parameter list or parenthesized expression is not closed properly.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0017": {"severity": "error", "area": "source", "message": "''export'' must precede a function, method, type, enum or const declaration", "hint": null, "explanation": "In a library, export must be followed by a function, method, type, enum or const declaration; nothing else can be exported.", "args": {}}, + "PF-E0018": {"severity": "error", "area": "source", "message": "Expected IMPORT, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the import keyword to start an import statement but found another token; check the line's spelling.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0019": {"severity": "error", "area": "source", "message": "Expected IDENT, got {token_type}(''{token}'').", "hint": null, "explanation": "A name was expected here (a variable, function, parameter, field, type or loop variable) but another token was found.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0020": {"severity": "error", "area": "source", "message": "Expected EQUALS, got {token_type}(''{token}'').", "hint": null, "explanation": "An '=' was expected after the declared name (variable, tuple or for-loop start); add it or fix the declaration.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0021": {"severity": "error", "area": "source", "message": "Expected LBRACKET, got {token_type}(''{token}'').", "hint": null, "explanation": "A tuple declaration must start with '[' as in [a, b] = f(); the opening bracket is missing or misplaced.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0022": {"severity": "error", "area": "source", "message": "Expected RBRACKET, got {token_type}(''{token}'').", "hint": null, "explanation": "A ']' is missing: a tuple declaration, for-in destructuring, array literal or index expression is not closed.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0023": {"severity": "error", "area": "source", "message": "Expected FAT_ARROW, got {token_type}(''{token}'').", "hint": null, "explanation": "A function or method definition, or a switch case, needs '=>' here; it is missing or misplaced.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0024": {"severity": "error", "area": "source", "message": "Expected IF, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the if keyword at the start of an if statement but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0025": {"severity": "error", "area": "source", "message": "Expected NEWLINE, got {token_type}(''{token}'').", "hint": null, "explanation": "An if, else, for, while or switch header must end its line before its indented body; other tokens follow it on the same line.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0026": {"severity": "error", "area": "source", "message": "Expected INDENT, got {token_type}(''{token}'').", "hint": null, "explanation": "An indented block was expected after the header or definition, but the next line is not indented further; indent the block's statements.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0027": {"severity": "error", "area": "source", "message": "Expected DEDENT, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected an indented block to end but found other tokens; check the indentation of the block's lines.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0028": {"severity": "error", "area": "source", "message": "Expected FOR, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the for keyword at the start of a for loop but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0029": {"severity": "error", "area": "source", "message": "Expected IN, got {token_type}(''{token}'').", "hint": null, "explanation": "A for-in loop with destructured variables is missing the in keyword after them.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0030": {"severity": "error", "area": "source", "message": "Expected TO, got {token_type}(''{token}'').", "hint": null, "explanation": "A counted for loop is missing the to keyword between its start and end values, as in for i = 0 to n.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0031": {"severity": "error", "area": "source", "message": "Expected WHILE, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the while keyword at the start of a while loop but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0032": {"severity": "error", "area": "source", "message": "Expected SWITCH, got {token_type}(''{token}'').", "hint": null, "explanation": "The parser expected the switch keyword at the start of a switch but found another token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0033": {"severity": "error", "area": "source", "message": "Expected COLON, got {token_type}(''{token}''). Expected '':'' in ternary", "hint": null, "explanation": "A ternary condition ? value must be followed by ':' and an else value; add the colon or complete the expression.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0034": {"severity": "error", "area": "source", "message": "Expected IDENT, got {token_type}(''{token}''). Expected member name", "hint": null, "explanation": "A '.' must be followed by a member name (a field or method); the token after the dot is not a name.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E0035": {"severity": "error", "area": "source", "message": "duplicate keyword argument ''{key_tok}''", "hint": "Remove one ''{key_tok}='' binding; a keyword argument may be specified only once.", "explanation": "A call binds the same keyword argument twice; keep only one binding.", "args": {"key_tok": {"kind": "identifier"}}}, + "PF-E0036": {"severity": "error", "area": "source", "message": "Numeric literal exceeds the generated C++ range.", "hint": null, "explanation": "A numeric literal is too large to be written in the generated C++ code; use a smaller number.", "args": {}}, + "PF-E0037": {"severity": "error", "area": "source", "message": "Unexpected token {token_type}(''{token}'')", "hint": null, "explanation": "The parser found a token that cannot start or continue an expression here; look for a stray or misplaced token.", "args": {"token_type": {"kind": "keyword"}, "token": {"kind": "identifier"}}}, + "PF-E1001": {"severity": "error", "area": "support", "message": "{context}: map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps with string keys only; declare the map's key type as string.", "args": {"context": {"kind": "text"}}}, + "PF-E1002": {"severity": "error", "area": "support", "message": "{context}: map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps whose values are float, int, bool or string only; use one of those as the value type.", "args": {"context": {"kind": "text"}}}, + "PF-E1003": {"severity": "error", "area": "support", "message": "matrix<{element_type}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead.", "args": {"element_type": {"kind": "type"}}}, + "PF-E1004": {"severity": "error", "area": "support", "message": "matrix<{element_type}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type.", "args": {"element_type": {"kind": "type"}}}, + "PF-E1005": {"severity": "error", "area": "support", "message": "input.color(...) requires a color defval (e.g. color.red or color.new(color.red, 50)).", "hint": null, "explanation": "input.color needs a color as its default value, for example color.red or color.new(color.red, 50).", "args": {}}, + "PF-E1006": {"severity": "error", "area": "support", "message": "input.color(...) defval must be a color constant (color.red, ...), a color literal (#rrggbb), or a color.new(...) / color.rgb(...) builder. Arbitrary expressions are not supported: the engine has no color helper, so codegen routes input.color through the int getter — any non-color defval would silently store a numeric value with no color encoding.", "hint": "Replace the defval with color. or color.new(...).", "explanation": "The default of input.color must be a color constant, a #rrggbb literal or a color.new or color.rgb call; other expressions are refused.", "args": {}}, + "PF-E1007": {"severity": "error", "area": "support", "message": "input.source(...) requires a native series defval (close, open, high, low, hl2, hlc3, ohlc4, ...).", "hint": null, "explanation": "input.source needs a default chart series such as close as its first argument or defval.", "args": {}}, + "PF-E1008": {"severity": "error", "area": "support", "message": "input.source(...) defval must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4). User series, computed expressions, and indicator outputs are not supported: input.source is restricted to native OHLCV series.", "hint": "Use one of: close, open, high, low, hl2, hlc3, ohlc4.", "explanation": "The default of input.source must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4); computed series are refused.", "args": {}}, + "PF-E1009": {"severity": "error", "area": "support", "message": "{kind}() declarations are not supported; PineForge runs strategies only.", "hint": "Replace the declaration with strategy(...) and add explicit entry/exit calls.", "explanation": "PineForge runs strategies only, so a script declared with indicator() or library() is refused; declare it with strategy() and add orders.", "args": {"kind": {"kind": "identifier"}}}, + "PF-E1010": {"severity": "error", "area": "support", "message": "Tuple reassignment [..] {op} is not Pine syntax: TradingView declares a tuple with ''='' and has no tuple reassignment.", "hint": "Declare new names with [a, b] = f(), then reassign each variable on its own line.", "explanation": "Pine has no tuple reassignment: declare a tuple once with '=' and reassign each variable on its own line.", "args": {"op": {"kind": "keyword"}}}, + "PF-E1011": {"severity": "error", "area": "support", "message": "A tuple literal [..] cannot be a variable''s value: TradingView rejects it here (Syntax error at input ''['', CE10156). A tuple is only a function''s or an if/switch arm''s value or a request.security expression.", "hint": "Declare each variable on its own line (a = x, b = y), or return the tuple from a function: f() => [x, y], then [a, b] = f().", "explanation": "A tuple literal such as [a, b] cannot be assigned to a variable; return it from a function or if/switch arm and destructure the result.", "args": {}}, + "PF-E1012": {"severity": "error", "area": "support", "message": "A ternary cannot return a tuple: TradingView rejects [a, b] = c ? [..] : [..] (\"Ternary operations cannot return tuples\").", "hint": "Select the tuple with an if or switch: [a, b] = if c, each arm ending in its tuple.", "explanation": "A ternary cannot produce a tuple (TradingView rejects it too); choose between tuples with an if or switch instead.", "args": {}}, + "PF-E1013": {"severity": "error", "area": "support", "message": "ta.stoch(...) returns a single series in PineForge; tuple destructuring is not supported.", "hint": "Use k = ta.stoch(...) and compute smoothing separately if needed.", "explanation": "ta.stoch returns one series in PineForge, so destructuring it into a tuple is refused; assign it to a single variable.", "args": {}}, + "PF-E1014": {"severity": "error", "area": "support", "message": "History references on UDT drawing fields are not supported in PineForge.", "hint": "{var_name}.{object_member}[...] would be read as the current-bar field, not prior-bar history. Copy the field to a bare drawing variable first, or remove the history reference.", "explanation": "A history index on a drawing field of a user-defined type would silently read the current field, so it is refused; copy the field to a variable first.", "args": {"var_name": {"kind": "identifier"}, "object_member": {"kind": "identifier"}}}, + "PF-E1015": {"severity": "error", "area": "support", "message": "History references on tuple-destructured drawing handles are not supported in PineForge.", "hint": "{object_name}[...] is a drawing handle from tuple destructuring; PineForge cannot historize that tuple element safely.", "explanation": "A drawing handle bound by tuple destructuring cannot be read through a history index; remove the history reference.", "args": {"object_name": {"kind": "identifier"}}}, + "PF-E1016": {"severity": "error", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}}}, + "PF-E1017": {"severity": "error", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}}, + "PF-E1018": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1019": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1020": {"severity": "error", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}}}, + "PF-E1021": {"severity": "error", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}}, + "PF-E1022": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1023": {"severity": "error", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1024": {"severity": "error", "area": "support", "message": "footprint.{footprint}(...) is not supported.", "hint": "PineForge reads a footprint''s delta() only: the fp_delta__ column of the feed a requests manifest pins for the symbol requested.", "explanation": "PineForge reads only the delta of a footprint value; every other footprint member is refused.", "args": {"footprint": {"kind": "identifier"}}}, + "PF-E1025": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "Currency conversion data not available in PineForge.", "explanation": "PineForge has no currency-conversion data, so request.currency_rate is refused; supply the rate yourself, for example as an input.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1026": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "External Quandl data not available in PineForge.", "explanation": "PineForge cannot load external Quandl data, so request.quandl is refused; remove it.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1027": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "External seed data feeds not available in PineForge.", "explanation": "PineForge cannot load external seed data feeds, so request.seed is refused; remove it.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1028": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.kagi() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.kagi builds a Kagi symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1029": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.linebreak() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.linebreak builds a Line Break symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1030": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.modify() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.modify builds a modified symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1031": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.new() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.new builds another symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1032": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.pointfigure() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.pointfigure builds a Point and Figure symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1033": {"severity": "error", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.renko() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.renko builds a Renko symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1034": {"severity": "error", "area": "support", "message": "ticker.heikinashi(...) is supported only for the chart''s own symbol.", "hint": "Pass syminfo.tickerid: PineForge applies the Heikin-Ashi candle transform to the chart symbol inside request.security, but cannot load an alternate symbol''s HA candles.", "explanation": "ticker.heikinashi is accepted only for the chart's own symbol (syminfo.tickerid); another symbol's Heikin-Ashi candles cannot be loaded.", "args": {}}, + "PF-E1035": {"severity": "error", "area": "support", "message": "{full}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1036": {"severity": "error", "area": "support", "message": "{name}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1037": {"severity": "error", "area": "support", "message": "{full}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "footprint.* calls need tick-level bid/ask volume rows, which a PineForge batch backtest does not load.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1038": {"severity": "error", "area": "support", "message": "{full}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "volume_row.* calls need tick-level volume rows, which a PineForge batch backtest does not load.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1039": {"severity": "error", "area": "support", "message": "library() declarations are not supported; PineForge runs strategies only.", "hint": "Use strategy(...) and inline or pre-expand library code before uploading.", "explanation": "PineForge runs strategies only, so a library() declaration is refused; use strategy() and paste any library code into the script.", "args": {}}, + "PF-E1040": {"severity": "error", "area": "support", "message": "Bare barssince(...) is broken in PineForge codegen.", "hint": "Use ta.barssince(...) instead.", "explanation": "The bare barssince(...) form does not work in PineForge; call ta.barssince(...) instead.", "args": {}}, + "PF-E1041": {"severity": "error", "area": "support", "message": "ta.sum is not a PineScript v6 function.", "hint": "Use math.sum(...) instead.", "explanation": "ta.sum does not exist in Pine v6; use math.sum(source, length) for a rolling sum.", "args": {}}, + "PF-E1042": {"severity": "error", "area": "support", "message": "ta.{name} is a PineScript v6 variable, not a function.", "hint": "Use ta.{name} without parentheses.", "explanation": "This ta.* name is a built-in variable, not a function, so write it without parentheses.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1043": {"severity": "error", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.closedtrades or strategy.opentrades accessor is not available in PineForge; use one of the supported trade accessors.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1044": {"severity": "error", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": "{hint}", "explanation": "Open trades have no exit data in Pine v6: this accessor exists only on strategy.closedtrades, so it cannot be read from strategy.opentrades.", "args": {"full": {"kind": "identifier"}, "hint": {"kind": "text"}}}, + "PF-E1045": {"severity": "error", "area": "support", "message": "strategy.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.* function is not implemented in PineForge; check the spelling or use a supported strategy function.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1046": {"severity": "error", "area": "support", "message": "strategy.exit(...) requires at least one price or trailing parameter in PineForge.", "hint": "Use strategy.close(...) for market exits.", "explanation": "strategy.exit needs a price or trailing parameter (profit, loss, limit, stop or a trail setting); use strategy.close for a plain market exit.", "args": {}}, + "PF-E1047": {"severity": "error", "area": "support", "message": "{full}(...) is not supported. Only request.security(...) and request.security_lower_tf(...) are available in PineForge.", "hint": "External request feeds and other request.* variants are intentionally unavailable.", "explanation": "Only request.security and request.security_lower_tf are supported; other request.* calls need data feeds PineForge does not provide.", "args": {"full": {"kind": "identifier"}}}, + "PF-E1048": {"severity": "error", "area": "support", "message": "ta.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this ta.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1049": {"severity": "error", "area": "support", "message": "math.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this math.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1050": {"severity": "error", "area": "support", "message": "str.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this str.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1051": {"severity": "error", "area": "support", "message": "input.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this input.* function, so the call is refused; use one of the supported input functions.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1052": {"severity": "error", "area": "support", "message": "timeframe.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only timeframe.change and timeframe.in_seconds; any other timeframe.* function is refused.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1053": {"severity": "error", "area": "support", "message": "color.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only color.new, color.rgb and color.r/g/b/t; any other color.* function is refused.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1054": {"severity": "error", "area": "support", "message": "runtime.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only runtime.error; any other runtime.* function is refused.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1055": {"severity": "error", "area": "support", "message": "log.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only log.info, log.warning and log.error; any other log.* function is refused.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1056": {"severity": "error", "area": "support", "message": "array.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this array.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1057": {"severity": "error", "area": "support", "message": "map.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this map.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1058": {"severity": "error", "area": "support", "message": "map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps support only string keys; declare the map with string as its key type.", "args": {}}, + "PF-E1059": {"severity": "error", "area": "support", "message": "map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps can hold only float, int, bool or string values; other value types such as collections or objects are refused.", "args": {}}, + "PF-E1060": {"severity": "error", "area": "support", "message": "matrix<{t}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type.", "args": {"t": {"kind": "type"}}}, + "PF-E1061": {"severity": "error", "area": "support", "message": "matrix<{t}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead.", "args": {"t": {"kind": "type"}}}, + "PF-E1062": {"severity": "error", "area": "support", "message": "matrix<{t}> element type not supported. Allowed: float, int, bool, string, color, or a declared UDT.", "hint": null, "explanation": "A matrix element must be float, int, bool, string, color or a declared user-defined type; any other element type is refused.", "args": {"t": {"kind": "type"}}}, + "PF-E1063": {"severity": "error", "area": "support", "message": "matrix.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this matrix.* function, so the call is refused instead of compiling to a silent stub.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1064": {"severity": "error", "area": "support", "message": "{ns}.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only part of the line, box, label and linefill functions; this one is not implemented, so the call is refused.", "args": {"ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-E1065": {"severity": "error", "area": "support", "message": "chart.point.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only chart.point.new, now, from_index, from_time and copy; any other chart.point.* function is refused.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1066": {"severity": "error", "area": "support", "message": "''export'' is a Pine library keyword; PineForge runs strategies only and does not support exported functions/types.", "hint": "Remove the ''export'' keyword (and inline any library code into the strategy script).", "explanation": "'export' marks library code; PineForge runs strategies only, so remove the keyword and inline any library code into the strategy.", "args": {}}, + "PF-E1067": {"severity": "error", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1068": {"severity": "error", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1069": {"severity": "error", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"name": {"kind": "identifier"}}}, + "PF-E1070": {"severity": "error", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"chain": {"kind": "identifier"}}}, + "PF-E1071": {"severity": "error", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"chain": {"kind": "identifier"}}}, + "PF-E1072": {"severity": "error", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"chain": {"kind": "identifier"}}}, + "PF-E1073": {"severity": "error", "area": "support", "message": "{object_name}.{member}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": null, "explanation": "Members of the footprint.* namespace need tick-level bid/ask volume rows, which a PineForge batch backtest does not load.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1074": {"severity": "error", "area": "support", "message": "{object_name}.{member}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": null, "explanation": "Members of the volume_row.* namespace need tick-level volume rows, which a PineForge batch backtest does not load.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1075": {"severity": "error", "area": "support", "message": "{object_name}.{member}: dividends.* is not available in PineForge — fundamental dividend data is not loaded.", "hint": null, "explanation": "dividends.* fields read fundamental dividend data, which PineForge does not load outside a recorded request.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1076": {"severity": "error", "area": "support", "message": "{object_name}.{member}: earnings.* is not available in PineForge — fundamental earnings data is not loaded.", "hint": null, "explanation": "earnings.* fields read fundamental earnings data, which PineForge does not load outside a recorded request.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1077": {"severity": "error", "area": "support", "message": "{object_name}.{member}: splits.* is not available in PineForge — corporate-action split data is not loaded.", "hint": null, "explanation": "splits.* fields read corporate-action split data, which PineForge does not load outside a recorded request.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1078": {"severity": "error", "area": "support", "message": "{object_name}.{member} is a visual/style constant with no runtime value in PineForge backtests; it is only accepted as an argument to visual calls (plot, plotshape, hline, label.new, table.cell, ...), which PineForge parses and skips.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "A visual or style constant has no value in a backtest; it may only be passed to plotting and drawing calls, which PineForge skips.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1079": {"severity": "error", "area": "support", "message": "{object_name}.{member} is not a Pine alert constant; only alert.freq_all, alert.freq_once_per_bar and alert.freq_once_per_bar_close exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The alert.* member is not one of Pine's alert frequency constants.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1080": {"severity": "error", "area": "support", "message": "{object_name}.{member} is not a barmerge constant; only barmerge.gaps_on, barmerge.gaps_off, barmerge.lookahead_on and barmerge.lookahead_off exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The barmerge.* member is not one of Pine's gaps or lookahead constants.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E1081": {"severity": "error", "area": "support", "message": "syminfo.{member} is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge does not implement this syminfo.* member, so reading it is refused.", "args": {"member": {"kind": "identifier"}}}, + "PF-E1082": {"severity": "error", "area": "support", "message": "request.security parameter ''{kw_name}'' is not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts only a few named parameters in PineForge; this one is refused instead of being silently ignored, so remove it.", "args": {"kw_name": {"kind": "identifier"}}}, + "PF-E1083": {"severity": "error", "area": "support", "message": "Extra positional arguments to request.security are not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts at most five positional arguments (symbol, timeframe, expression, gaps, lookahead); remove the extra ones.", "args": {}}, + "PF-E1084": {"severity": "error", "area": "support", "message": "request.security gaps must be barmerge.gaps_on or barmerge.gaps_off.", "hint": "Codegen only recognizes the barmerge.gaps_* literal; other values are silently treated as gaps_off.", "explanation": "The gaps argument of request.security must be written literally as barmerge.gaps_on or barmerge.gaps_off, the only forms PineForge reads.", "args": {}}, + "PF-E1085": {"severity": "error", "area": "support", "message": "request.security lookahead must be barmerge.lookahead_on or barmerge.lookahead_off.", "hint": "Codegen only recognizes the barmerge.lookahead_* literal; other values are silently treated as lookahead_off.", "explanation": "The lookahead argument of request.security must be written literally as barmerge.lookahead_on or barmerge.lookahead_off, the only forms PineForge reads.", "args": {}}, + "PF-E1086": {"severity": "error", "area": "support", "message": "request.security: {kw_name}={object_name}.{val_member} is not supported. The engine ignores this kwarg, which would silently produce different prices from TradingView.", "hint": "Allowed values: {allowed}.", "explanation": "PineForge ignores request.security's price-adjustment settings, so only no-op values are accepted; others would silently give prices unlike TradingView's.", "args": {"kw_name": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "val_member": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}}, + "PF-E1087": {"severity": "error", "area": "support", "message": "request.security: {kw_name}=... must be a constant member access of the form {kw_name}. (got a non-constant expression).", "hint": "Allowed values: {allowed}.", "explanation": "A request.security price-adjustment setting must be a plain constant of the form name.value (like adjustment.none), not a computed expression.", "args": {"kw_name": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}}, + "PF-E1088": {"severity": "error", "area": "support", "message": "{name} {message} (TradingView: {spelled}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A nz or fixnan call whose arguments match none of TradingView's signatures (unknown name, too many or missing arguments) is refused, as TradingView refuses it.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "spelled": {"kind": "identifier"}}}, + "PF-E1089": {"severity": "error", "area": "support", "message": "ta.{name} {message} (TradingView: {signature}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A ta.* call whose arguments match none of TradingView's signatures (unknown or repeated parameter, too many or missing arguments) is refused.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "signature": {"kind": "identifier"}}}, + "PF-E1090": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}}, + "PF-E1091": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}}, + "PF-E1092": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}}, + "PF-E1093": {"severity": "error", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}}, + "PF-E1094": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}}, + "PF-E1095": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}}, + "PF-E1096": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}}}, + "PF-E1097": {"severity": "error", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}}, + "PF-E2001": {"severity": "error", "area": "analysis", "message": "Missing PineScript version directive. PineForge supports PineScript v6 only.", "hint": "Add //@version=6 as the first line of your script.", "explanation": "PineForge accepts only Pine v6 scripts; add //@version=6 as the first line.", "args": {}}, + "PF-E2002": {"severity": "error", "area": "analysis", "message": "PineForge supports PineScript v6 only (found //@version={version}).", "hint": "Migrate the script to //@version=6 using TradingView''s editor.", "explanation": "The script declares a Pine version other than 6, which PineForge does not support; migrate it to v6 using TradingView's editor.", "args": {"version": {"kind": "number"}}}, + "PF-E2003": {"severity": "error", "area": "analysis", "message": "Direct temporary-array element call ''{callee_name}()'' resolves to a local or parameter, not a user-defined function.", "hint": null, "explanation": "A function ends by reading a temporary array built from a call such as f(), but f is a local or parameter there, not a user-defined function; rename it.", "args": {"callee_name": {"kind": "identifier"}}}, + "PF-E2004": {"severity": "error", "area": "analysis", "message": "Tuple-return helper wrapper ''{wrapper_name}'' calls later-defined helper ''{callee_name}''; forward tuple-wrapper calls are not supported yet. Move ''{callee_name}'' above ''{wrapper_name}'' before passing the wrapper to request.security().", "hint": null, "explanation": "A function that returns another function's tuple must come after it; define the called helper above the wrapper before passing the wrapper to request.security.", "args": {"wrapper_name": {"kind": "identifier"}, "callee_name": {"kind": "identifier"}}}, + "PF-E2005": {"severity": "error", "area": "analysis", "message": "Recursive direct temporary-array reader cycle is not supported: {cycle}.", "hint": null, "explanation": "Functions that read an element of a temporary array call each other in a cycle; Pine forbids recursion and PineForge cannot emit it.", "args": {"cycle": {"kind": "identifier"}}}, + "PF-E2006": {"severity": "error", "area": "analysis", "message": "Persistent bindings named ''{raw_name}'' still share generated storage across distinct lexical declarations; this declaration shape is not supported yet.", "hint": null, "explanation": "A var declaration reuses a name that another declaration in a different scope also uses, and PineForge would give them one shared storage slot; rename one.", "args": {"raw_name": {"kind": "identifier"}}}, + "PF-E2007": {"severity": "error", "area": "analysis", "message": "A top-level block history binding named ''{name}'' shares raw generated Series state with another lexical declaration; declaration-exact block storage is not supported yet.", "hint": null, "explanation": "A top-level block variable whose history is read shares its name with another declaration, so PineForge cannot keep their histories apart; rename one.", "args": {"name": {"kind": "identifier"}}}, + "PF-E2008": {"severity": "error", "area": "analysis", "message": "A callable history local named ''{name}'' shares raw generated Series state with another lexical declaration; declaration-exact callable storage is not supported yet.", "hint": null, "explanation": "A function-local variable has its history read and shares its name with another declaration, so PineForge cannot keep separate history; rename one.", "args": {"name": {"kind": "identifier"}}}, + "PF-E2009": {"severity": "error", "area": "analysis", "message": "History references on a scalar callable local named ''{raw_name}'' conflict with a persistent map local of the same name in another callable; scoped Series member storage is not implemented yet.", "hint": null, "explanation": "A function-local scalar read with history shares its name with a persistent map variable in another function, which PineForge cannot yet separate; rename one.", "args": {"raw_name": {"kind": "identifier"}}}, + "PF-E2010": {"severity": "error", "area": "analysis", "message": "A top-level block binding named ''{name}'' shadows a direct script binding with history, aggregate, or incompatible typed state; declaration-exact block storage is not supported yet.", "hint": null, "explanation": "A variable declared inside a top-level block reuses the name of a script-level variable with history, a collection or a different type; rename one.", "args": {"name": {"kind": "identifier"}}}, + "PF-E2011": {"severity": "error", "area": "analysis", "message": "Persistent drawing bindings named ''{name}'' in distinct lexical owners would share one generated state member; rename one binding until callable-owned persistent storage is owner-qualified.", "hint": null, "explanation": "Two var-declared drawing objects (line, box, label or linefill) in different scopes share one name and would share one state member; rename one.", "args": {"name": {"kind": "identifier"}}}, + "PF-E2012": {"severity": "error", "area": "analysis", "message": "Persistent drawing state named ''{name}'' collides with a top-level class-member binding; rename one binding until persistent storage is owner-qualified.", "hint": null, "explanation": "A var-declared drawing object shares its name with a top-level script variable, so PineForge would give them one state member; rename one.", "args": {"name": {"kind": "identifier"}}}, + "PF-E2013": {"severity": "error", "area": "analysis", "message": "Persistent drawing binding ''{name}'' shadows an ancestor callable parameter or local; rename one binding until callable-owned persistent storage has lexical owner qualification.", "hint": null, "explanation": "A var-declared drawing object inside a function reuses the name of an enclosing parameter or local; rename one.", "args": {"name": {"kind": "identifier"}}}, + "PF-E2014": {"severity": "error", "area": "analysis", "message": "Callable TA ownership propagation did not converge; recursive stateful call paths are unsupported.", "hint": null, "explanation": "PineForge could not work out which functions own the ta.* state because stateful functions call each other recursively; remove the recursion.", "args": {}}, + "PF-E2015": {"severity": "error", "area": "analysis", "message": "Cannot safely specialize untyped parameter ''{param}'' of callable ''{callee}'': distinct primitive types collapse onto the same written-call variant cs{cs_idx}. Inline the calls or declare an explicit parameter type.", "hint": null, "explanation": "An untyped parameter receives different primitive types (such as int and float) from calls PineForge cannot tell apart; declare its type or inline the calls.", "args": {"param": {"kind": "identifier"}, "callee": {"kind": "identifier"}, "cs_idx": {"kind": "number"}}}, + "PF-E2016": {"severity": "error", "area": "analysis", "message": "Cannot infer the per-callsite primitive type of history parameter ''{param}'' in callable ''{name}'' variant cs{cs_idx}; declare its type explicitly.", "hint": null, "explanation": "A function reads history of a parameter whose type PineForge cannot infer at this call; declare the parameter type explicitly.", "args": {"param": {"kind": "identifier"}, "name": {"kind": "identifier"}, "cs_idx": {"kind": "number"}}}, + "PF-E2017": {"severity": "error", "area": "analysis", "message": "request.security timeframe parameter ''{tf_param}'' of function ''{containing}'' is passed a timeframe that reads the chart bar (''{series}''): PineForge registers each call site''s timeframe before the first bar.", "hint": null, "explanation": "A timeframe passed to a helper's request.security reads chart-bar data, but PineForge fixes it before the first bar; pass a constant or input timeframe instead.", "args": {"tf_param": {"kind": "identifier"}, "containing": {"kind": "identifier"}, "series": {"kind": "identifier"}}}, + "PF-E2018": {"severity": "error", "area": "analysis", "message": "Import is not supported: ''{import_path}''", "hint": null, "explanation": "The script imports a library PineForge cannot inline, usually because its source was not supplied or pinned, or it is not open source.", "args": {"import_path": {"kind": "identifier"}}}, + "PF-E2019": {"severity": "error", "area": "analysis", "message": "Import is not supported: ''{import_path}'': {reason}", "hint": null, "explanation": "The script imports a library PineForge cannot inline, usually because its source was not supplied or pinned, or it is not open source.", "args": {"import_path": {"kind": "identifier"}, "reason": {"kind": "text"}}}, + "PF-E2020": {"severity": "error", "area": "analysis", "message": "Undefined variable: ''{name}''", "hint": null, "explanation": "The script assigns a new value (:=) to a name that was never declared; declare the variable first.", "args": {"name": {"kind": "identifier"}}}, + "PF-E2021": {"severity": "error", "area": "analysis", "message": "PineScript has no ta.sum; use math.sum(source, length) for rolling sum", "hint": null, "explanation": "ta.sum does not exist in Pine v6; use math.sum(source, length) for a rolling sum.", "args": {}}, + "PF-E2022": {"severity": "error", "area": "analysis", "message": "{name}.copy(...) expects exactly one object argument", "hint": null, "explanation": "The functional copy form Type.copy(obj) needs exactly one object argument and no named arguments.", "args": {"name": {"kind": "type"}}}, + "PF-E2023": {"severity": "error", "area": "analysis", "message": "{receiver_spec_name}.copy() expects no arguments", "hint": null, "explanation": "obj.copy() on a user-defined type takes no arguments; call it with empty parentheses.", "args": {"receiver_spec_name": {"kind": "type"}}}, + "PF-E2024": {"severity": "error", "area": "analysis", "message": "{key}: argument ''{name}'' passed both positionally and by keyword", "hint": null, "explanation": "A call to a typed method gives the same parameter both by position and by keyword; pass it only once.", "args": {"key": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-E2025": {"severity": "error", "area": "analysis", "message": "{key}: missing required argument ''{name}''", "hint": null, "explanation": "A call to a typed method omits a parameter that has no default value; pass an argument for it.", "args": {"key": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-E2026": {"severity": "error", "area": "analysis", "message": "{key}: too many positional arguments (expected {names_count}, got {args_count})", "hint": null, "explanation": "A call to a typed method passes more positional arguments than the method declares; remove the extra arguments.", "args": {"key": {"kind": "identifier"}, "names_count": {"kind": "number"}, "args_count": {"kind": "number"}}}, + "PF-E2027": {"severity": "error", "area": "analysis", "message": "{key}: unknown keyword argument ''{name}''", "hint": null, "explanation": "A call to a typed method uses a keyword argument name that the method does not declare; check the parameter spelling.", "args": {"key": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-E2028": {"severity": "error", "area": "analysis", "message": "History references on map IDs are not supported in PineForge; map rollback uses identity snapshots rather than Series.", "hint": null, "explanation": "PineForge cannot read earlier-bar history of a map with the [] operator; read the map directly or keep earlier values in other variables.", "args": {}}, + "PF-E2029": {"severity": "error", "area": "analysis", "message": "History references on map-bearing UDTs or collections are not supported in PineForge; their Series value copy would retain live map aliases.", "hint": null, "explanation": "PineForge cannot read earlier-bar history of a user-defined type or collection that contains a map, because the copy would keep live map references.", "args": {}}, + "PF-E2030": {"severity": "error", "area": "analysis", "message": "User function ''{owner}'' is called with incompatible map parameter types; PineForge cannot emit multiple map specializations for one untyped function.", "hint": null, "explanation": "A function with untyped parameters is called with different map types, and PineForge can generate only one map specialization per function; declare the type.", "args": {"owner": {"kind": "identifier"}}}, + "PF-E2031": {"severity": "error", "area": "analysis", "message": "History references on scalar local or loop bindings that shadow a map ID are not supported until PineForge can allocate a lexically scoped Series buffer for that binding.", "hint": null, "explanation": "A local or loop variable that reuses a map's name is read with history ([n]), which PineForge cannot buffer yet; rename the variable.", "args": {}}, + "PF-E2032": {"severity": "error", "area": "analysis", "message": "{receiver}.{member}[...]: TradingView refuses the history-referencing operator on fields of user-defined types (CE10290).", "hint": "Read the field of the object''s history: ({receiver}[1]).{member}.", "explanation": "TradingView refuses the [] history operator on a field of a user-defined type; read the field of the object's history instead, as (obj[1]).field.", "args": {"receiver": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E2033": {"severity": "error", "area": "analysis", "message": "request.security tuple-return helpers support two or more int, float, bool or string elements; inferred {tuple_size} element(s) [{inferred_types}]", "hint": null, "explanation": "A tuple-returning helper called inside request.security must yield two or more int, float, bool or string elements; its inferred shape did not qualify.", "args": {"tuple_size": {"kind": "number"}, "inferred_types": {"kind": "type"}}}, + "PF-E2034": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf has unknown parameter(s): {unknown}. Supported parameters: {param_names}", "hint": null, "explanation": "request.security_lower_tf was called with keyword arguments it does not accept; use only the supported parameters listed.", "args": {"unknown": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, + "PF-E2035": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf requires an expression argument", "hint": null, "explanation": "request.security_lower_tf was called without its expression argument, so there is nothing to evaluate on the lower timeframe.", "args": {}}, + "PF-E2036": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf does not support tuple expressions yet. Issue separate request.security_lower_tf calls for each series.", "hint": null, "explanation": "request.security_lower_tf cannot return a tuple; issue one request.security_lower_tf call for each series you need.", "args": {}}, + "PF-E2037": {"severity": "error", "area": "analysis", "message": "request.security_lower_tf element type ''{element_label}'' is not yet supported. Supported element types: float, int, bool. UDT / color / string element types are out of scope.", "hint": null, "explanation": "request.security_lower_tf can only collect float, int or bool values per intrabar; string, color and object expressions are not supported.", "args": {"element_label": {"kind": "type"}}}, + "PF-E2038": {"severity": "error", "area": "analysis", "message": "Enum ''{ename}'' must be declared above this input.enum() call (or the name is misspelled).", "hint": null, "explanation": "input.enum() names an enum that is not declared above the call (or is misspelled); declare the enum first or fix the name.", "args": {"ename": {"kind": "identifier"}}}, + "PF-E2039": {"severity": "error", "area": "analysis", "message": "Cannot materialize callable state for unknown function ''{func_name}''.", "hint": null, "explanation": "Internal error: PineForge could not find a user function or method whose indicator state it needed to copy; this is a transpiler bug to report.", "args": {"func_name": {"kind": "identifier"}}}, + "PF-E3001": {"severity": "error", "area": "request-security", "message": "request.security timeframe ''{name}'' cannot be resolved before the first bar: PineForge registers every requested timeframe before the script runs.", "hint": "Pass a literal, an input or a global to the helper that holds request.security.", "explanation": "The timeframe given to request.security is a name whose value PineForge cannot compute before the first bar; use a literal, an input or a global.", "args": {"name": {"kind": "identifier"}}}, + "PF-E3002": {"severity": "error", "area": "request-security", "message": "request.security timeframe expression cannot be resolved before the first bar: PineForge registers every requested timeframe before the script runs.", "hint": "Pass a literal, an input or a global to the helper that holds request.security.", "explanation": "The timeframe expression given to request.security cannot be computed before the first bar; use a literal, an input or a global.", "args": {}}, + "PF-E3003": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch arms must contain one expression", "hint": "Compute multi-statement timeframe logic before the request.security call or rewrite it as pure switch arms.", "explanation": "A switch that picks a request.security timeframe must have exactly one expression in each arm; compute multi-statement logic beforehand.", "args": {}}, + "PF-E3004": {"severity": "error", "area": "request-security", "message": "request.security_lower_tf timeframe switch arm is na", "hint": "TradingView reads an na timeframe as the chart''s, which the engine''s lower-timeframe request rejects: spell a strictly finer timeframe.", "explanation": "A switch arm in a request.security_lower_tf timeframe is na, which a lower-timeframe request rejects; spell a strictly finer timeframe.", "args": {}}, + "PF-E3005": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch arm is na", "hint": "TradingView reads an na timeframe as the chart''s: spell the arm timeframe.period.", "explanation": "A switch arm in a request.security timeframe is na, which TradingView reads as the chart's timeframe; write timeframe.period instead.", "args": {}}, + "PF-E3006": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch arm could not be resolved at setup", "hint": null, "explanation": "A switch arm used as a request.security timeframe could not be evaluated, because PineForge registers every request before the first bar.", "args": {}}, + "PF-E3007": {"severity": "error", "area": "request-security", "message": "request.security_lower_tf timeframe switch requires a default arm", "hint": "When no arm matches, TradingView reads the chart''s timeframe (one intrabar per chart bar); the engine''s lower-timeframe request needs a strictly finer timeframe.", "explanation": "A switch picking a request.security_lower_tf timeframe needs a default arm; without one TradingView uses the chart's timeframe, which is rejected.", "args": {}}, + "PF-E3008": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch selector could not be resolved at setup", "hint": null, "explanation": "The selector of a switch that picks a request.security timeframe could not be evaluated before the first bar; use literals, inputs or timeframe values.", "args": {}}, + "PF-E3009": {"severity": "error", "area": "request-security", "message": "request.security timeframe switch case could not be resolved at setup", "hint": null, "explanation": "A case value in a switch that picks a request.security timeframe could not be evaluated before the first bar; use literals, inputs or timeframe values.", "args": {}}, + "PF-E3010": {"severity": "error", "area": "request-security", "message": "request.security timeframe parameter ''{param_name}'' of ''{func_name}'' has no single timeframe across its call sites", "hint": "Pass the timeframe as a positional literal, input or global.", "explanation": "A helper's timeframe parameter used by request.security receives different timeframes at its call sites; pass one literal, input or global.", "args": {"param_name": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}}, + "PF-E3011": {"severity": "error", "area": "request-security", "message": "request.security helper-parameter history currently requires a direct OHLC/time bar-series binding", "hint": null, "explanation": "History of a helper parameter inside request.security is only supported when the argument is a plain bar series such as close or time.", "args": {}}, + "PF-E3012": {"severity": "error", "area": "request-security", "message": "request.security payload reads ''{name}'' with history and outside the helper block its call is lowered in: its state would advance twice a bar", "hint": "Read ''{name}'' once at the helper''s top level and use that local in the block.", "explanation": "A global holding a stateful call is read with history both inside and outside the helper block that lowers it, so its state would advance twice per bar.", "args": {"name": {"kind": "identifier"}}}, + "PF-E3013": {"severity": "error", "area": "request-security", "message": "Internal: request.security string helper state without its declared series map", "hint": null, "explanation": "Internal error: string state in a request.security helper was used before its series storage was declared; this is a transpiler bug to report.", "args": {}}, + "PF-E3014": {"severity": "error", "area": "request-security", "message": "Internal security helper emission requested for a non-linear helper plan", "hint": null, "explanation": "Internal error: PineForge tried to emit a request.security helper as straight-line code although its shape is not; this is a transpiler bug to report.", "args": {}}, + "PF-E3015": {"severity": "error", "area": "request-security", "message": "request.security helper-local var state currently supports only int, float, bool and string values", "hint": "Hoist collection, UDT, or drawing state outside request.security().", "explanation": "A var inside a request.security helper can only hold int, float, bool or string values; move collection, object or drawing state outside the request.", "args": {}}, + "PF-E3016": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers may only assign to local identifier temporaries", "hint": null, "explanation": "A multi-statement request.security helper can only assign to plain local variables, not to fields, array elements or other targets.", "args": {}}, + "PF-E3017": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helper assignment target must be declared before use", "hint": null, "explanation": "A multi-statement request.security helper assigns to a variable it never declared; declare the local before assigning to it.", "args": {}}, + "PF-E3018": {"severity": "error", "area": "request-security", "message": "request.security helper tuple declaration: a string element read with history is not supported", "hint": "Declare the element with its own string variable.", "explanation": "A string element of a tuple declared in a request.security helper is read with history, which is unsupported; declare it as its own string variable.", "args": {}}, + "PF-E3019": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers may only use local declarations, assignments, and if-branches before the final expression", "hint": null, "explanation": "A multi-statement request.security helper may contain only local declarations, assignments, if-branches and loops before its final expression.", "args": {}}, + "PF-E3020": {"severity": "error", "area": "request-security", "message": "request.security helper while-loop conditions must be plain expressions of the helper''s values", "hint": null, "explanation": "A while-loop condition in a request.security helper must be a plain expression of the helper's own values.", "args": {}}, + "PF-E3021": {"severity": "error", "area": "request-security", "message": "request.security helper calls must target named user-defined functions", "hint": null, "explanation": "request.security can only inline calls to named user-defined functions or typed methods, not other call forms.", "args": {}}, + "PF-E3022": {"severity": "error", "area": "request-security", "message": "request.security helper function ''{func_name}'' is not defined", "hint": null, "explanation": "A function called while inlining a request.security helper is not a user-defined function PineForge knows, so it cannot be inlined.", "args": {"func_name": {"kind": "identifier"}}}, + "PF-E3023": {"severity": "error", "area": "request-security", "message": "request.security helper call has unknown parameter(s): {unknown_list}", "hint": null, "explanation": "A helper called inside request.security is given keyword arguments that are not among the function's parameters.", "args": {"unknown_list": {"kind": "identifier"}}}, + "PF-E3024": {"severity": "error", "area": "request-security", "message": "request.security helper calls must bind every parameter explicitly", "hint": null, "explanation": "A helper called inside request.security must be given an argument for every parameter; omitted defaults are not filled in there.", "args": {}}, + "PF-E3025": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers must end with a final expression result", "hint": null, "explanation": "A multi-statement request.security helper must end with an expression, declaration or assignment that gives its result.", "args": {}}, + "PF-E3026": {"severity": "error", "area": "request-security", "message": "request.security does not support multi-statement helpers with control flow", "hint": "Inline a straight-line helper body or hoist the control-flow helper outside request.security().", "explanation": "request.security cannot inline a multi-statement helper that contains for-in, switch, break or continue; inline a straight-line body or move it out.", "args": {}}, + "PF-E3027": {"severity": "error", "area": "request-security", "message": "request.security does not support helper-local varip state", "hint": "Use var for requested-context bar state; varip tick state is unavailable in batch backtests.", "explanation": "varip state is not available in a request.security helper; use var instead, since tick-level varip state does not exist in batch backtests.", "args": {}}, + "PF-E3028": {"severity": "error", "area": "request-security", "message": "request.security helper-local var declarations inside conditional control flow are not supported", "hint": "Declare persistent requested-context state at the helper''s top level.", "explanation": "A var declared inside an if or other conditional block of a request.security helper is not supported; declare it at the helper's top level.", "args": {}}, + "PF-E3029": {"severity": "error", "area": "request-security", "message": "request.security method TA constructor argument ''{cpp}'' is not a stable per-run scalar", "hint": null, "explanation": "A typed method called inside request.security builds a TA indicator whose argument is not fixed for the whole run; use a constant or input value.", "args": {"cpp": {"kind": "identifier"}}}, + "PF-E3030": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a TA call", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot contain a ta.* call; compute it before the loop, on the requested bar.", "args": {}}, + "PF-E3031": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a TA call (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a ta.* call through a parameter or global it reads; compute that value before the loop.", "args": {"via": {"kind": "text"}}}, + "PF-E3032": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a user function call", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot call a user-defined function; compute the value before the loop.", "args": {}}, + "PF-E3033": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a user function call (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a user function call through a parameter or global it reads; compute that value before the loop.", "args": {"via": {"kind": "text"}}}, + "PF-E3034": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a var declaration", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot declare a var; compute the value before the loop.", "args": {}}, + "PF-E3035": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a var declaration (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a var declaration through a parameter or global it reads; compute that value before the loop.", "args": {"via": {"kind": "text"}}}, + "PF-E3036": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a {namespace}.* call", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A for or while loop in a request.security helper cannot call request.* or strategy.* functions; compute the value before the loop.", "args": {"namespace": {"kind": "identifier"}}}, + "PF-E3037": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold a {namespace}.* call (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a request.* or strategy.* call through a parameter or global it reads; compute it before the loop.", "args": {"namespace": {"kind": "identifier"}, "via": {"kind": "text"}}}, + "PF-E3038": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold the local ''{name}'', which is read with history", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper cannot read a local that is also read with history; compute that local before the loop.", "args": {"name": {"kind": "identifier"}}}, + "PF-E3039": {"severity": "error", "area": "request-security", "message": "request.security helper loops cannot hold the local ''{name}'', which is read with history (through {via})", "hint": "Compute it before the loop, on the requested bar.", "explanation": "A loop in a request.security helper reaches a local read with history through a parameter or global; compute that local before the loop.", "args": {"name": {"kind": "identifier"}, "via": {"kind": "text"}}}, + "PF-E3040": {"severity": "error", "area": "request-security", "message": "request.security mutable global rebinding does not support top-level switch", "hint": "Rewrite the switch as if/else assignments before passing the value to request.security().", "explanation": "A global read by the request.security expression is rebound inside a top-level switch, which PineForge cannot replay; rewrite it as if/else assignments.", "args": {}}, + "PF-E3041": {"severity": "error", "area": "request-security", "message": "request.security mutable global rebinding does not support top-level loops", "hint": "Move loop-driven mutable state out of request.security() expressions or rewrite it as direct assignments.", "explanation": "A global read by the request.security expression is rebound inside a top-level loop, which PineForge cannot replay; use direct assignments or move it out.", "args": {}}, + "PF-E3042": {"severity": "error", "area": "request-security", "message": "request.security does not support TA constructor args that depend on rebound mutable globals", "hint": "Keep TA constructor arguments immutable/simple inside request.security(), or hoist the TA call outside the security expression.", "explanation": "A TA length or other indicator argument inside request.security depends on a global the script reassigns; keep it constant or compute the TA outside.", "args": {}}, + "PF-E3043": {"severity": "error", "area": "request-security", "message": "History of a {kind} reference inside a request.security expression is not supported in PineForge: TradingView reads the references the variable held on the requested timeframe''s bars, which PineForge does not keep.", "hint": "Request the field values the expression needs (request.security(..., obj.field)) and read their history on the chart.", "explanation": "request.security cannot read the history of a user-defined type or drawing reference, because PineForge keeps no references from the requested bars.", "args": {"kind": {"kind": "type"}}}, + "PF-E3044": {"severity": "error", "area": "request-security", "message": "request.security payload reads ''{name}'', an element of a tuple declaration it cannot re-evaluate", "hint": null, "explanation": "The request.security expression reads a name bound by a tuple declaration that PineForge cannot re-evaluate on the requested bar.", "args": {"name": {"kind": "identifier"}}}, + "PF-E3045": {"severity": "error", "area": "request-security", "message": "request.security payload reads ''{name}'', an element of a TA tuple it does not compute once per requested bar", "hint": null, "explanation": "The request.security expression reads an element of a TA tuple that PineForge does not compute once per requested bar.", "args": {"name": {"kind": "identifier"}}}, + "PF-E3046": {"severity": "error", "area": "request-security", "message": "request.security() bar-field history index must be non-negative", "hint": null, "explanation": "A negative history offset on a bar series such as close[-1] is not allowed inside request.security.", "args": {}}, + "PF-E3047": {"severity": "error", "area": "request-security", "message": "request.security payload reads the history of ''{object_name}'', an element of a tuple declaration", "hint": null, "explanation": "The request.security expression reads the history of a name bound by a tuple declaration, which PineForge cannot do on the requested bars.", "args": {"object_name": {"kind": "identifier"}}}, + "PF-E3048": {"severity": "error", "area": "request-security", "message": "request.security payload reads the string global ''{object_name}'' with history, which the requested clock does not keep", "hint": null, "explanation": "A string global read with history inside request.security is not supported, because the requested clock keeps no string history.", "args": {"object_name": {"kind": "identifier"}}}, + "PF-E3049": {"severity": "error", "area": "request-security", "message": "request.security() TA history index must be a literal integer (e.g. ta.ema(close, 55)[1])", "hint": "An int computed from inputs and literals is admitted; a series index is not.", "explanation": "A history offset on a TA call inside request.security must be an integer literal or a number computed from inputs and literals, not a series.", "args": {}}, + "PF-E3050": {"severity": "error", "area": "request-security", "message": "request.security() TA history index must be non-negative", "hint": null, "explanation": "A negative history offset on a TA call inside request.security is not allowed.", "args": {}}, + "PF-E3051": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helper TA history is not supported", "hint": "Use a single-expression helper for TA history offsets.", "explanation": "A TA history offset inside a multi-statement request.security helper is not supported; use a single-expression helper.", "args": {}}, + "PF-E3052": {"severity": "error", "area": "request-security", "message": "request.security helper functions must not recurse while building a security context", "hint": null, "explanation": "A request.security helper calls itself, directly or through other helpers, which PineForge cannot inline; remove the recursion.", "args": {}}, + "PF-E3053": {"severity": "error", "area": "request-security", "message": "request.security multi-statement helpers require statement-capable security evaluation context", "hint": null, "explanation": "A multi-statement helper is used inside a request.security expression at a spot where PineForge cannot emit statements, so it cannot be inlined there.", "args": {}}, + "PF-E3054": {"severity": "error", "area": "request-security", "message": "the payload reads ''{func_name}'' on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"func_name": {"kind": "identifier"}}}, + "PF-E3055": {"severity": "error", "area": "request-security", "message": "the payload reads ''{namespace}.{func_name}'' on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"namespace": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}}, + "PF-E3056": {"severity": "error", "area": "request-security", "message": "the payload reads ''{name}'' on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"name": {"kind": "identifier"}}}, + "PF-E3057": {"severity": "error", "area": "request-security", "message": "the payload reads a user call it cannot inline on the chart''s bar", "hint": null, "explanation": "A request.security payload reads something PineForge would evaluate on the chart's bar, where TradingView evaluates it on the requested bar, so it is refused.", "args": {}}, + "PF-E3058": {"severity": "error", "area": "request-security", "message": "the payload reads a {node_type} on the chart''s bar", "hint": null, "explanation": "The request.security expression mixes a value evaluated on the requested bar with one PineForge can only read on the chart's bar.", "args": {"node_type": {"kind": "identifier"}}}, + "PF-E3059": {"severity": "error", "area": "request-security", "message": "the payload reads history it does not keep on the requested clock on the chart''s bar", "hint": null, "explanation": "A request.security payload reads something PineForge would evaluate on the chart's bar, where TradingView evaluates it on the requested bar, so it is refused.", "args": {}}, + "PF-E3060": {"severity": "error", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', an element of a tuple declaration", "hint": null, "explanation": "The request.security expression reads the history of a name bound by a tuple declaration, which PineForge cannot do on the requested bars.", "args": {"name": {"kind": "identifier"}}}, + "PF-E3061": {"severity": "error", "area": "request-security", "message": "request.security helper switch arms must each be one expression", "hint": "Compute a multi-statement arm in its own helper, or on the chart.", "explanation": "A switch used as a request.security helper's value must have a single expression in each arm; move multi-statement arms into their own helper.", "args": {}}, + "PF-E3062": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: helper ''{func}'' {problem}", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A helper holding a request.security cannot have its symbol and timeframe resolved per call path, because it is overloaded or called from a method.", "args": {"request_name": {"kind": "identifier"}, "func": {"kind": "identifier"}, "problem": {"kind": "text"}}}, + "PF-E3063": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{expr_name}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}}, + "PF-E3064": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{expr}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr": {"kind": "identifier"}}}, + "PF-E3065": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{func}'' declares ''{names}''", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "func": {"kind": "identifier"}, "names": {"kind": "identifier"}}}, + "PF-E3066": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{name}'' is not a value the requested bars recompute", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-E3067": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: ''{name}'' is reassigned or declared var", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-E3068": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: a {node_type} is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "node_type": {"kind": "identifier"}}}, + "PF-E3069": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: it holds a request.{request_name2} call", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "request_name2": {"kind": "identifier"}}}, + "PF-E3070": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: it reads ''{expr_name}'', a series", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}}, + "PF-E3071": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: its value is too large", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}}}, + "PF-E3072": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: parameter ''{binding}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "binding": {"kind": "identifier"}}}, + "PF-E3073": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: parameter ''{param}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "param": {"kind": "identifier"}}}, + "PF-E3074": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the helpers reach it through too many call paths", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}}}, + "PF-E3075": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the method call {expr}", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "expr": {"kind": "identifier"}}}, + "PF-E3076": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the user function call {callee_name}(...)", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The symbol or timeframe of a request inside a helper cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "callee_name": {"kind": "identifier"}}}, + "PF-E3077": {"severity": "error", "area": "request-security", "message": "request.{request_name} {what} cannot be resolved before the first bar on the call path {chain}: the value of ''{param}'' is not lowered on the requested bars", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe reached through helper parameters cannot be computed before the first bar on this call path; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "what": {"kind": "text"}, "chain": {"kind": "identifier"}, "param": {"kind": "identifier"}}}, + "PF-E3078": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{expr_name}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}}, + "PF-E3079": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{expr}'' is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr": {"kind": "identifier"}}}, + "PF-E3080": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{func}'' declares ''{names}''", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "func": {"kind": "identifier"}, "names": {"kind": "identifier"}}}, + "PF-E3081": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{name}'' is not a value the requested bars recompute", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-E3082": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: ''{name}'' is reassigned or declared var", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-E3083": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: a {node_type} is not a value fixed before the first bar", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "node_type": {"kind": "identifier"}}}, + "PF-E3084": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: it holds a request.{request_name2} call", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol or timeframe holds another request, which PineForge cannot compute before the first bar.", "args": {"request_name": {"kind": "identifier"}, "request_name2": {"kind": "identifier"}}}, + "PF-E3085": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: it reads ''{expr_name}'', a series", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr_name": {"kind": "identifier"}}}, + "PF-E3086": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: its value is too large", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The value a request's context reads is too large for PineForge to resolve before the first bar.", "args": {"request_name": {"kind": "identifier"}}}, + "PF-E3087": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: parameter ''{binding}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A helper call leaves out the parameter the request's symbol or timeframe reads, so PineForge cannot resolve the request's context.", "args": {"request_name": {"kind": "identifier"}, "binding": {"kind": "identifier"}}}, + "PF-E3088": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: parameter ''{param}'' has no argument", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A helper call leaves out the parameter the request's symbol or timeframe reads, so PineForge cannot resolve the request's context.", "args": {"request_name": {"kind": "identifier"}, "param": {"kind": "identifier"}}}, + "PF-E3089": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the helpers reach it through too many call paths", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "The helpers holding this request are reached through too many call paths for PineForge to resolve each one's symbol and timeframe.", "args": {"request_name": {"kind": "identifier"}}}, + "PF-E3090": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the method call {expr}", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "expr": {"kind": "identifier"}}}, + "PF-E3091": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the user function call {callee_name}(...)", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "callee_name": {"kind": "identifier"}}}, + "PF-E3092": {"severity": "error", "area": "request-security", "message": "request.{request_name} context: the value of ''{param}'' is not lowered on the requested bars", "hint": "Pass the symbol and timeframe as literals, inputs or globals at the helper''s call sites.", "explanation": "A request's symbol, timeframe or payload parameter reads a value PineForge cannot compute before the first bar or recompute on the requested bars; pass literals, inputs or globals.", "args": {"request_name": {"kind": "identifier"}, "param": {"kind": "identifier"}}}, + "PF-E4001": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' has no valid sha256 in {where}", "hint": null, "explanation": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "text"}}}, + "PF-E4002": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not among the libraries passed to transpile()", "hint": null, "explanation": "The imported library was not among the library sources supplied to the transpiler, so it cannot be inlined; supply its source text.", "args": {"path": {"kind": "identifier"}}}, + "PF-E4003": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not open-source (access ''{access}''); PineForge inlines open libraries only", "hint": null, "explanation": "The library's manifest entry says it is not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "access": {"kind": "identifier"}}}, + "PF-E4004": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not open-source (access ''{indexed_access}'' in libraries.json); PineForge inlines open libraries only", "hint": null, "explanation": "The library index marks this library as not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "indexed_access": {"kind": "identifier"}}}, + "PF-E4005": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' is not pinned by this script''s requests manifest ({where})", "hint": null, "explanation": "The script's requests manifest does not pin this imported library, so PineForge will not use any other source for it; add the library to the manifest.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "identifier"}}}, + "PF-E4006": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' source does not match its pinned sha256 {sha}... (found {found_sha}...)", "hint": null, "explanation": "The library source that was found does not match the SHA-256 hash pinned in the manifest, so PineForge refuses to use it.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "found_sha": {"kind": "identifier"}}}, + "PF-E4007": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' source is missing (sha256 {sha}... under ${requests_env}/{slug_dir_name}/files and ${libraries_env})", "hint": null, "explanation": "No file matching the library's pinned SHA-256 hash was found in the configured directories, so its source is missing.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "requests_env": {"kind": "identifier"}, "slug_dir_name": {"kind": "identifier"}, "libraries_env": {"kind": "identifier"}}}, + "PF-E4008": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': library ''{path}'' source is not UTF-8 text", "hint": null, "explanation": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script.", "args": {"path": {"kind": "identifier"}}}, + "PF-E4009": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{path}'': no library sources are configured", "hint": null, "explanation": "The imported library cannot be inlined: its pinned source is missing, unreadable or not configured for this script.", "args": {"path": {"kind": "identifier"}}}, + "PF-E4010": {"severity": "error", "area": "libraries", "message": "library ''{path}'' spells ''{clash}'', a name PineForge gave to an inlined definition", "hint": null, "explanation": "An imported library uses a name PineForge generates for its own inlined definitions, so the library cannot be inlined without a name clash.", "args": {"path": {"kind": "identifier"}, "clash": {"kind": "identifier"}}}, + "PF-E4011": {"severity": "error", "area": "libraries", "message": "library ''{path}'' defines ''{name}'' {defs_count} times (overloads); PineForge does not inline an overloaded library function", "hint": null, "explanation": "The library defines this function several times (overloads) in a way PineForge cannot resolve, so it will not inline it; call a non-overloaded function.", "args": {"path": {"kind": "identifier"}, "name": {"kind": "identifier"}, "defs_count": {"kind": "number"}}}, + "PF-E4012": {"severity": "error", "area": "libraries", "message": "no overload of ''{name}'' of library ''{path}'' takes the arguments of this call", "hint": null, "explanation": "None of the library function's overloads accepts the arguments in this call; check the number of arguments and any keyword names.", "args": {"name": {"kind": "identifier"}, "path": {"kind": "identifier"}}}, + "PF-E4013": {"severity": "error", "area": "libraries", "message": "library ''{path}'' does not export ''{member}''", "hint": null, "explanation": "The name exists in the imported library but is not exported, so the script cannot use it through the import; use an exported name.", "args": {"path": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E4014": {"severity": "error", "area": "libraries", "message": "library ''{path}'' does not export ''{member}'': it has no ''{member}''", "hint": null, "explanation": "The imported library has no such name at all; check the spelling of the member you access through the import alias.", "args": {"path": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E4015": {"severity": "error", "area": "libraries", "message": "''{token}'' is not a type of library ''{targets}''", "hint": null, "explanation": "A type written as alias.Type is not an exported type or enum of that library; check the type's name and that the library exports it.", "args": {"token": {"kind": "identifier"}, "targets": {"kind": "identifier"}}}, + "PF-E4016": {"severity": "error", "area": "libraries", "message": "library ''{path}'': a {statement} inside a function is not supported", "hint": null, "explanation": "A function in an imported library contains a nested declaration (function, method, type, enum, import or script declaration), which PineForge cannot inline.", "args": {"path": {"kind": "identifier"}, "statement": {"kind": "vocab", "values": ["EnumDecl", "FuncDef", "ImportStmt", "MethodDef", "StrategyDecl", "TypeDecl"]}}}, + "PF-E4017": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{targets}'' is a {kind}, not a value", "hint": null, "explanation": "The script reads a library function or method as a plain value; only exported constants, types and enums can be read that way, so call it instead.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["function", "method"]}}}, + "PF-E4018": {"severity": "error", "area": "libraries", "message": "library method ''{member}'' called without its receiver as the first positional argument", "hint": null, "explanation": "A library method was called through its import alias without the receiver as the first argument; pass the receiver first or call it as receiver.method().", "args": {"member": {"kind": "identifier"}}}, + "PF-E4019": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{targets}'' is a {kind}, not a function", "hint": null, "explanation": "The script calls an exported library type or constant like a function; only exported functions and methods can be called, so use it as a type or value.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["const", "type"]}}}, + "PF-E4020": {"severity": "error", "area": "libraries", "message": "method ''{member}'' is exported by {exporters_count} imported libraries; a keyword argument cannot be bound to one", "hint": null, "explanation": "Several imported libraries export a method with this name, so a call that uses keyword arguments is ambiguous; pass the arguments by position.", "args": {"member": {"kind": "identifier"}, "exporters_count": {"kind": "number"}}}, + "PF-E4021": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{main_targets}'' is a {kind}, not a value", "hint": null, "explanation": "The script reads a library function or method as a plain value; only exported constants, types and enums can be read that way, so call it instead.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "main_targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["function", "method"]}}}, + "PF-E4022": {"severity": "error", "area": "libraries", "message": "''{alias}.{member}'' of library ''{main_targets}'' is a {kind}, not a function", "hint": null, "explanation": "The script calls an exported library type or constant like a function; only exported functions and methods can be called, so use it as a type or value.", "args": {"alias": {"kind": "identifier"}, "member": {"kind": "identifier"}, "main_targets": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["const", "type"]}}}, + "PF-E4023": {"severity": "error", "area": "libraries", "message": "import alias ''{alias}'' is used by two imports", "hint": null, "explanation": "Two imports use the same alias, so names like alias.member would be ambiguous; give each import its own alias.", "args": {"alias": {"kind": "identifier"}}}, + "PF-E4024": {"severity": "error", "area": "libraries", "message": "Import is not supported: ''{import_path}'': its alias ''{alias}'' is a built-in namespace other than ta, math or str", "hint": null, "explanation": "The import's alias is a built-in namespace other than ta, math or str, which PineForge does not allow; choose a different alias.", "args": {"import_path": {"kind": "identifier"}, "alias": {"kind": "identifier"}}}, + "PF-E4025": {"severity": "error", "area": "libraries", "message": "import alias ''{alias}'' is also declared as a variable, parameter or function", "hint": null, "explanation": "The import alias is also the name of a variable, parameter or function in the script, which would make the alias ambiguous; rename one of them.", "args": {"alias": {"kind": "identifier"}}}, + "PF-E4026": {"severity": "error", "area": "libraries", "message": "method ''{name}'' of library ''{path}'' has the same receiver type as a method of {other}", "hint": null, "explanation": "Two methods share a name and receiver type, one in this library and one in the script or another library, so one would be unreachable.", "args": {"name": {"kind": "identifier"}, "path": {"kind": "identifier"}, "other": {"kind": "text"}}}, + "PF-E4027": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is //@version=5: its function reached from a request.{callee_member}() payload would run outside v5''s rules there", "hint": null, "explanation": "A function from a Pine v5 library is reached from a request.*() expression, where PineForge cannot apply v5 rules, so it is refused.", "args": {"path": {"kind": "identifier"}, "callee_member": {"kind": "identifier"}}}, + "PF-E4028": {"severity": "error", "area": "libraries", "message": "library ''{path}'' has {found}; PineForge inlines v5 and v6 libraries only", "hint": null, "explanation": "The imported library has no //@version line or a version other than 5 or 6; PineForge inlines only version 5 and 6 libraries.", "args": {"path": {"kind": "identifier"}, "found": {"kind": "text"}}}, + "PF-E4029": {"severity": "error", "area": "libraries", "message": "''{path}'' is not a library: it has {found}, not one library() declaration", "hint": null, "explanation": "The imported source is not a library: it must hold exactly one library() declaration, but it has none or a different kind of declaration.", "args": {"path": {"kind": "identifier"}, "found": {"kind": "text"}}}, + "PF-E4030": {"severity": "error", "area": "libraries", "message": "library ''{path}'' has a malformed import: ''{path2}''", "hint": null, "explanation": "An import inside the library is malformed (it lacks a version or an alias), so PineForge cannot follow it.", "args": {"path": {"kind": "identifier"}, "path2": {"kind": "identifier"}}}, + "PF-E4031": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is //@version=5: {exc}", "hint": null, "explanation": "A Pine v5 library uses a v5 behaviour that PineForge does not implement, so the library is refused; the reason names the construct.", "args": {"path": {"kind": "identifier"}, "exc": {"kind": "text"}}}, + "PF-E4032": {"severity": "error", "area": "libraries", "message": "no library sources are configured", "hint": null, "explanation": "No library sources were given to the transpiler and none are configured in the environment, so imports cannot be resolved.", "args": {}}, + "PF-E4033": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not among the libraries passed to transpile()", "hint": null, "explanation": "The imported library was not among the library sources supplied to the transpiler, so it cannot be inlined; supply its source text.", "args": {"path": {"kind": "identifier"}}}, + "PF-E4034": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not pinned by this script''s requests manifest ({where})", "hint": null, "explanation": "The script's requests manifest does not pin this imported library, so PineForge will not use any other source for it; add the library to the manifest.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "identifier"}}}, + "PF-E4035": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not open-source (access ''{access}''); PineForge inlines open libraries only", "hint": null, "explanation": "The library's manifest entry says it is not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "access": {"kind": "identifier"}}}, + "PF-E4036": {"severity": "error", "area": "libraries", "message": "library ''{path}'' has no valid sha256 in {where}", "hint": null, "explanation": "The library's entry in the requests manifest has no valid SHA-256 hash, so its source cannot be verified; fix the entry.", "args": {"path": {"kind": "identifier"}, "where": {"kind": "identifier"}}}, + "PF-E4037": {"severity": "error", "area": "libraries", "message": "library ''{path}'' is not open-source (access ''{indexed_access}'' in libraries.json); PineForge inlines open libraries only", "hint": null, "explanation": "The library index marks this library as not open-source, and PineForge inlines open libraries only.", "args": {"path": {"kind": "identifier"}, "indexed_access": {"kind": "identifier"}}}, + "PF-E4038": {"severity": "error", "area": "libraries", "message": "library ''{path}'' source is not UTF-8 text", "hint": null, "explanation": "The library's source is not valid UTF-8 text, so it cannot be read or inlined.", "args": {"path": {"kind": "identifier"}}}, + "PF-E4039": {"severity": "error", "area": "libraries", "message": "library ''{path}'' source does not match its pinned sha256 {sha}... (found {found_sha}...)", "hint": null, "explanation": "The library source that was found does not match the SHA-256 hash pinned in the manifest, so PineForge refuses to use it.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "found_sha": {"kind": "identifier"}}}, + "PF-E4040": {"severity": "error", "area": "libraries", "message": "library ''{path}'' source is missing (sha256 {sha}... under ${requests_env}/{slug_dir_name}/files and ${libraries_env})", "hint": null, "explanation": "No file matching the library's pinned SHA-256 hash was found in the configured directories, so its source is missing.", "args": {"path": {"kind": "identifier"}, "sha": {"kind": "identifier"}, "requests_env": {"kind": "identifier"}, "slug_dir_name": {"kind": "identifier"}, "libraries_env": {"kind": "identifier"}}}, + "PF-E5001": {"severity": "error", "area": "codegen", "message": "Recursive stateful callable cycle is not supported: {cycle}.", "hint": "Remove the recursive call; Pine user-defined functions cannot execute recursively.", "explanation": "Stateful functions (with TA calls, var variables or history reads) call each other in a cycle; Pine forbids recursion, so remove the recursive call.", "args": {"cycle": {"kind": "identifier"}}}, + "PF-E5002": {"severity": "error", "area": "codegen", "message": "matrix.{meth_name} requires matrix; got matrix<{elem_str}>", "hint": "Numeric-only methods are not available for matrix, matrix, matrix, or matrix.", "explanation": "This matrix method works only on matrix; it cannot be used on a matrix of int, bool, string or objects.", "args": {"meth_name": {"kind": "identifier"}, "elem_str": {"kind": "type"}}}, + "PF-E5003": {"severity": "error", "area": "codegen", "message": "matrix.sort requires int, bool, string, or float element type; got {elem_name}", "hint": null, "explanation": "matrix.sort can sort only int, bool, string or float matrices, and this matrix has a different element type.", "args": {"elem_name": {"kind": "type"}}}, + "PF-E5004": {"severity": "error", "area": "codegen", "message": "matrix.sort requires int, bool, string, or float element type; UDT matrices cannot be sorted", "hint": null, "explanation": "matrix.sort cannot sort a matrix of user-defined objects; only int, bool, string and float matrices can be sorted.", "args": {}}, + "PF-E5005": {"severity": "error", "area": "codegen", "message": "request.security helper call history is only supported in the payload itself", "hint": null, "explanation": "Reading the history ([k]) of a call inside a function used by request.security is not supported; do it in the expression passed to request.security itself.", "args": {}}, + "PF-E5006": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor flag ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot initialize the indicator with a stable per-run value.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA constructor arguments.", "explanation": "A TA indicator's boolean argument is neither a literal nor derived from an input, so PineForge cannot fix it once per run; use a literal or an input.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}}, + "PF-E5007": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor flag ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot initialize the indicator with a stable per-run value.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA lengths.", "explanation": "A TA indicator's flag argument is neither a constant nor input-derived, so PineForge cannot set it once per run; use a literal or an input-based value.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}}, + "PF-E5008": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor length ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot size the indicator buffer.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA constructor arguments.", "explanation": "A TA indicator's length is neither a constant nor derived from an input, so PineForge cannot size its buffer; use a literal, an input or arithmetic on those.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}}, + "PF-E5009": {"severity": "error", "area": "codegen", "message": "Unsupported TA constructor length ''{a}'' for {class_name}: it is neither a compile-time constant nor derived from an input, so PineForge cannot size the indicator buffer.", "hint": "Use a literal, an input.*() value, or arithmetic over those for TA lengths.", "explanation": "A TA indicator's length is not a literal and not derived from an input, so PineForge cannot size its buffer; use a literal, an input or arithmetic on those.", "args": {"a": {"kind": "identifier"}, "class_name": {"kind": "type"}}}, + "PF-E5010": {"severity": "error", "area": "codegen", "message": "request.security timeframe was not resolved for registration", "hint": null, "explanation": "PineForge could not work out this request.security timeframe before the run starts, so it cannot register the request; use a constant, input or syminfo value.", "args": {}}, + "PF-E5011": {"severity": "error", "area": "codegen", "message": "input title {spelled}is not a constant string: TradingView declares title (const string), and PineForge keys an input override by its title.", "hint": "Use a string literal, or a name bound once at global scope to one (T = \"Length\").", "explanation": "An input's title must be a constant string (a literal or a name bound once to one), because PineForge keys each input override by its title.", "args": {"spelled": {"kind": "text"}}}, + "PF-E5012": {"severity": "error", "area": "codegen", "message": "{type_name}.copy() is unsupported because direct array field(s) {rendered} still use value storage", "hint": "Move the array outside the UDT and store a supported shared-ID map/matrix or nested UDT handle until array fields gain handle identity.", "explanation": "Copying an object whose type has array fields is unsupported, since PineForge would copy the arrays by value; keep the arrays outside the type.", "args": {"type_name": {"kind": "type"}, "rendered": {"kind": "identifier"}}}, + "PF-E5013": {"severity": "error", "area": "codegen", "message": "array.{method} requires a numeric array", "hint": "Use numeric arrays for aggregate/statistical array functions.", "explanation": "This array function (sum, avg, stdev and similar) needs an array of numbers, and the array has another element type.", "args": {"method": {"kind": "identifier"}}}, + "PF-E5014": {"severity": "error", "area": "codegen", "message": "{func_name}() with bars_back / timeframe_bars_back inside request.security is not supported", "hint": "Read {func_name}() with its offset outside request.security().", "explanation": "time() or time_close() with a bars-back offset is not supported inside request.security; read the offset time outside the request.", "args": {"func_name": {"kind": "identifier"}}}, + "PF-E5015": {"severity": "error", "area": "codegen", "message": "array.copy: expected exactly one receiver ''id''", "hint": "Use array.copy(source) or array.copy(id=source).", "explanation": "array.copy takes exactly one array, either positionally or as id=; this call does not match that.", "args": {}}, + "PF-E5016": {"severity": "error", "area": "codegen", "message": "map.{method}: unknown keyword argument ''{name}''", "hint": "Expected map.{method}({param_names}).", "explanation": "A map function was called with a keyword argument it does not have; use the parameter names it expects.", "args": {"method": {"kind": "identifier"}, "name": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, + "PF-E5017": {"severity": "error", "area": "codegen", "message": "map.{method}: unknown keyword argument ''{name}''", "hint": "Use ''id2='' for the source map. Expected map.{method}({param_names}).", "explanation": "map.put_all was called with from=; its source map parameter is named id2, so use id2= or pass the map by position.", "args": {"method": {"kind": "identifier"}, "name": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, + "PF-E5018": {"severity": "error", "area": "codegen", "message": "map.{method}: too many positional arguments (expected {param_names_count}, got {args_count})", "hint": "Expected map.{method}({param_names}).", "explanation": "A map function got more positional arguments than it accepts; remove the extra ones.", "args": {"method": {"kind": "identifier"}, "param_names_count": {"kind": "number"}, "args_count": {"kind": "number"}, "param_names": {"kind": "identifier"}}}, + "PF-E5019": {"severity": "error", "area": "codegen", "message": "map.{method}: argument ''{name}'' passed both positionally and by keyword", "hint": "Expected map.{method}({param_names}); bind each argument once.", "explanation": "A map function argument is given both by position and by keyword; pass each argument only once.", "args": {"method": {"kind": "identifier"}, "name": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, + "PF-E5020": {"severity": "error", "area": "codegen", "message": "map.{method}: missing required argument ''{missing}''", "hint": "Expected map.{method}({param_names}).", "explanation": "A required argument of a map function is missing from the call; pass it by position or by keyword.", "args": {"method": {"kind": "identifier"}, "missing": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, + "PF-E5021": {"severity": "error", "area": "codegen", "message": "map.{method}: keyword arguments are not supported for this functional call form", "hint": "Use the established positional form: map.{method}({param_names}).", "explanation": "Keyword arguments are not supported in this function-style map call; pass the arguments by position.", "args": {"method": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, + "PF-E5022": {"severity": "error", "area": "codegen", "message": "map.{method}: keyword arguments are not supported for this receiver-method call form", "hint": "Use the established positional form: map.{method}({param_names}).", "explanation": "Keyword arguments are not supported in this method-style map call; pass the arguments by position.", "args": {"method": {"kind": "identifier"}, "param_names": {"kind": "identifier"}}}, + "PF-E5023": {"severity": "error", "area": "codegen", "message": "an array a call returns is passed to parameter ''{param}'' of ''{func_info_name}'', which takes the array itself: PineForge would pass a copy of it", "hint": "TradingView passes the array a function returns as itself, so the callee''s changes to it reach every variable holding it; pass a variable holding the array instead.", "explanation": "An array returned by a function call is passed to a parameter that can change it in place; PineForge would pass a copy, so store it in a variable first.", "args": {"param": {"kind": "identifier"}, "func_info_name": {"kind": "identifier"}}}, + "PF-E5024": {"severity": "error", "area": "codegen", "message": "{recv_spec_name}.copy() expects no arguments", "hint": "Call copy() on the UDT object without arguments.", "explanation": "copy() on an object takes no arguments; call it as object.copy().", "args": {"recv_spec_name": {"kind": "type"}}}, + "PF-E5025": {"severity": "error", "area": "codegen", "message": "matrix.{meth_raw}: wrong number of arguments", "hint": "Check Pine v6 matrix method signature (positional vs keyword).", "explanation": "A matrix method call has the wrong number of arguments; check the Pine v6 matrix method signature and whether arguments are positional or keyword.", "args": {"meth_raw": {"kind": "identifier"}}}, + "PF-E5026": {"severity": "error", "area": "codegen", "message": "matrix.{func_name}: wrong number of arguments", "hint": "Check Pine v6 matrix method signature (positional vs keyword).", "explanation": "A matrix method call has the wrong number of arguments; check the Pine v6 matrix method signature and whether arguments are positional or keyword.", "args": {"func_name": {"kind": "identifier"}}}, + "PF-E5027": {"severity": "error", "area": "codegen", "message": "timestamp(dateString): could not parse ''{args}''.", "hint": "Supported forms: ISO-8601 (\"2025-01-01[THH:MM:SS][±HH:MM]\") and \"DD MMM YYYY [hh:mm[:ss]] [±HHMM]\" / \"MMM DD YYYY ...\"; no time zone = GMT+0.", "explanation": "timestamp() got a date string PineForge cannot parse; use an ISO-8601 or 'DD MMM YYYY' form, or pass year, month and day numbers.", "args": {"args": {"kind": "identifier"}}}, + "PF-E5028": {"severity": "error", "area": "codegen", "message": "timestamp(dateString) requires a literal string in PineForge (Pine v6 dateString is a const string).", "hint": "Use a string literal, or timestamp(year, month, day[, hour, minute, second]).", "explanation": "timestamp(dateString) needs a string literal, because PineForge parses the date at transpile time; use a literal or numeric arguments.", "args": {}}, + "PF-E5029": {"severity": "error", "area": "codegen", "message": "timestamp(timezone, ...) requires year, month, and day arguments.", "hint": "Pine v6 signature: timestamp(timezone, year, month, day[, hour, minute, second]).", "explanation": "timestamp() with a timezone first needs year, month and day after it; add the missing arguments.", "args": {}}, + "PF-E5030": {"severity": "error", "area": "codegen", "message": "timestamp(...) with {merged_count} argument(s) is not supported — year, month, and day are required.", "hint": "Pine v6 signature: timestamp(year, month, day[, hour, minute, second]); the dateString overload is not supported in PineForge.", "explanation": "timestamp() with numeric arguments needs at least year, month and day; add the missing ones.", "args": {"merged_count": {"kind": "number"}}}, + "PF-E5031": {"severity": "error", "area": "codegen", "message": "matrix.{func_name} receiver must be a variable reference", "hint": null, "explanation": "This numeric-only matrix function needs its matrix as a plain variable so PineForge can check the element type; assign the matrix to a variable first.", "args": {"func_name": {"kind": "identifier"}}}, + "PF-E5032": {"severity": "error", "area": "codegen", "message": "matrix.{func_name}: receiver ''{recv_name}'' is not a known matrix variable", "hint": null, "explanation": "The matrix function's first argument is a variable PineForge does not know as a matrix, so it cannot check its element type.", "args": {"func_name": {"kind": "identifier"}, "recv_name": {"kind": "identifier"}}}, + "PF-E5033": {"severity": "error", "area": "codegen", "message": "{namespace}.copy(...) expects exactly one object argument", "hint": "Prefer the canonical object.copy() form.", "explanation": "Type.copy(...) takes exactly one object of that type; pass one object, or write object.copy().", "args": {"namespace": {"kind": "type"}}}, + "PF-E5034": {"severity": "error", "area": "codegen", "message": "Unknown function ''{func_name}(...)'' — not a PineForge builtin or a user-defined function.", "hint": "Check the spelling; the function may not be supported by PineForge, or needs its namespace (e.g. math./str.).", "explanation": "The called function is neither a PineForge built-in nor defined in the script; check the spelling or add its namespace, such as math. or str.", "args": {"func_name": {"kind": "identifier"}}}, + "PF-E5035": {"severity": "error", "area": "codegen", "message": "Unknown call ''{namespace}.{func_name}(...)'' — ''{namespace}'' is not a PineForge-supported namespace or a user-defined type.", "hint": "Check the spelling; this namespace may not be supported by PineForge.", "explanation": "The call's namespace is neither a supported PineForge namespace nor a user-defined type; check the spelling.", "args": {"namespace": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}}, + "PF-E5036": {"severity": "error", "area": "codegen", "message": "Unknown variable ''{name}'' — not a PineForge builtin or a declared variable.", "hint": null, "explanation": "The script reads a name that is neither a PineForge built-in nor a declared variable; check the spelling or declare it first.", "args": {"name": {"kind": "identifier"}}}, + "PF-E5037": {"severity": "error", "area": "codegen", "message": "Unknown variable ''{name}'' — not a PineForge builtin or a declared variable.", "hint": "{hint}", "explanation": "The script reads a realtime-only built-in variable, which has no value in a batch backtest; remove it or compute the value another way.", "args": {"name": {"kind": "identifier"}, "hint": {"kind": "text"}}}, + "PF-E5038": {"severity": "error", "area": "codegen", "message": "ta.{member} property read could not be bound to a TA call site.", "hint": "Use the function form ta.{member}(...) instead of the bare property read.", "explanation": "A bare ta. read could not be tied to a calculation; call the function form ta.name(...) instead.", "args": {"member": {"kind": "identifier"}}}, + "PF-E5039": {"severity": "error", "area": "codegen", "message": "ta.{member} is not readable as a bare property in PineForge.", "hint": "Call the function form ta.{member}(...) with its arguments instead.", "explanation": "That ta member is not a variable in PineForge, so it cannot be read without parentheses; call it as a function with its arguments.", "args": {"member": {"kind": "identifier"}}}, + "PF-E5040": {"severity": "error", "area": "codegen", "message": "{op} na on a {kind} reference: TradingView refuses a comparison with na (CE10187: \"Cannot compare a value to \\\"na\\\" directly\").", "hint": "Test the reference with na(...).", "explanation": "Comparing an object or drawing reference with na using == or != is rejected, as in TradingView; test it with na(...) instead.", "args": {"op": {"kind": "keyword"}, "kind": {"kind": "type"}}}, + "PF-E5041": {"severity": "error", "area": "codegen", "message": "{op} on a {kind} reference: TradingView compares only line and label references (CE10123: \"Cannot call ''operator {op}''\" with an argument of the {kind} type).", "hint": "Compare the fields or getter values the objects hold, or test na(...).", "explanation": "PineForge refuses == and != on object or drawing references other than line or label of the same kind, as TradingView does; compare fields or test na().", "args": {"op": {"kind": "keyword"}, "kind": {"kind": "type"}}}, + "PF-E5042": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: ''{op}'' of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library compares a bool with == or !=, but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the library.", "args": {"library": {"kind": "identifier"}, "op": {"kind": "keyword"}}}, + "PF-E5043": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: str.format() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library passes a bool to str.format(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}}}, + "PF-E5044": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: str.tostring() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library passes a bool to str.tostring(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}}}, + "PF-E5045": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: string() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library passes a bool to string(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}}}, + "PF-E5046": {"severity": "error", "area": "codegen", "message": "library ''{library}'' is //@version=5: {func_name}() of a bool reads v5''s third bool state (na), which PineForge''s two-state bool does not keep", "hint": null, "explanation": "A //@version=5 library tests a bool with na(), nz() or fixnan(), but v5 bools can be na and PineForge's two-state bool cannot, so it refuses the call.", "args": {"library": {"kind": "identifier"}, "func_name": {"kind": "identifier"}}}, + "PF-E5047": {"severity": "error", "area": "codegen", "message": "session.{flag}[...] cannot be read here: PineForge keeps a session flag''s history on the requested clock only for a read the request.security expression reaches through its own operators, not through a call''s argument, a function or a variable.", "hint": null, "explanation": "A session flag history read inside request.security works only when the expression's own operators reach it, not via a call argument, function or variable.", "args": {"flag": {"kind": "identifier"}}}, + "PF-E5048": {"severity": "error", "area": "codegen", "message": "session.{flag}[...] cannot be read in {owner}(), {why}: PineForge keeps a session flag''s history in a function by each of its call sites, and cannot tell this one apart.", "hint": null, "explanation": "A session flag history read is in a function PineForge cannot split per call site: a method, or one a method, request.security or UDT field default calls.", "args": {"flag": {"kind": "identifier"}, "owner": {"kind": "identifier"}, "why": {"kind": "vocab", "values": ["a method, whose calls PineForge cannot always tell apart", "which a UDT field default calls once for every new()", "which a method calls", "which a request.security expression evaluates on the requested clock"]}}}, + "PF-E5049": {"severity": "error", "area": "codegen", "message": "session.{flag}[...] is not supported here: PineForge keeps a session flag''s history for the script''s top level, a function body and a request.security expression that reads it.", "hint": null, "explanation": "A session flag history read is supported only at the top level, in a function body or in a request.security expression, and this read is none of those.", "args": {"flag": {"kind": "identifier"}}}, + "PF-E5050": {"severity": "error", "area": "codegen", "message": "History of the chart.point {object_name} is not supported in PineForge when the script changes its fields: PineForge holds a chart.point as a value, where TradingView''s history reads the point object as it is now.", "hint": "Keep the field in a variable of its own and read that variable''s history, or build a new point instead of changing a field.", "explanation": "History of a chart.point variable whose fields the script changes is refused because PineForge holds points as values; use a separate variable or build a new point.", "args": {"object_name": {"kind": "identifier"}}}, + "PF-E5051": {"severity": "error", "area": "codegen", "message": "matrix ''{target_label}'' element type mismatch on reassignment: expected {target_type}, got {rhs_type}", "hint": null, "explanation": "A matrix variable is reassigned a matrix with a different element type, which Pine forbids; make the new matrix's element type match the variable's.", "args": {"target_label": {"kind": "identifier"}, "target_type": {"kind": "type"}, "rhs_type": {"kind": "type"}}}, + "PF-E5052": {"severity": "error", "area": "codegen", "message": "array.{method}: wrong number of arguments", "hint": null, "explanation": "An array method call has too few arguments for its lowering; check the Pine v6 array method signature.", "args": {"method": {"kind": "identifier"}}}, + "PF-E6001": {"severity": "error", "area": "collection-history", "message": "matrix.{method}: wrong number of arguments", "hint": "Check Pine v6 matrix method signature (positional vs keyword).", "explanation": "A matrix method call has the wrong number of arguments; check the Pine v6 matrix method signature and whether arguments are positional or keyword.", "args": {"method": {"kind": "identifier"}}}, + "PF-E6002": {"severity": "error", "area": "collection-history", "message": "{label} := ...: an assignment to the history-referencing operator is not supported in PineForge.", "hint": null, "explanation": "TradingView refuses an assignment to a history reference; assign the variable itself.", "args": {"label": {"kind": "text"}}}, + "PF-E6003": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for operator {op} (CE10123).", "hint": null, "explanation": "An array or matrix history read such as a[1] is an operand of an operator, which TradingView refuses; read an element or the size and use that instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "op": {"kind": "keyword"}}}, + "PF-E6004": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for operator {op} (CE10123).", "hint": null, "explanation": "An array or matrix history read such as a[1] is an operand of an operator, which TradingView refuses; read an element or the size and use that instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "op": {"kind": "keyword"}}}, + "PF-E6005": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the condition of ?: (CE10123).", "hint": null, "explanation": "An array or matrix history read is the condition of a ?: expression, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6006": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the condition of ?: (CE10123).", "hint": null, "explanation": "An array or matrix history read is the condition of a ?: expression, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6007": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the condition of an if statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of an if statement, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6008": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the condition of an while statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of a while loop, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6009": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the condition of an if statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of an if statement, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6010": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the condition of an while statement (CE10101).", "hint": null, "explanation": "An array or matrix history read is the condition of a while loop, which TradingView refuses; test an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6011": {"severity": "error", "area": "collection-history", "message": "({label})[...]: the history of a {kind}''s history is not supported in PineForge.", "hint": null, "explanation": "The history of a collection's history is not kept by PineForge.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6012": {"severity": "error", "area": "collection-history", "message": "({label})[...]: the history of an {kind}''s history is not supported in PineForge.", "hint": null, "explanation": "The history of a collection's history is not kept by PineForge.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6013": {"severity": "error", "area": "collection-history", "message": "{label} is not supported in PineForge here.", "hint": null, "explanation": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower; use it only with built-in array or matrix functions.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6014": {"severity": "error", "area": "collection-history", "message": "{label}.{method}: a {kind} has no fields.", "hint": null, "explanation": "An array or a matrix has no fields; a field read after its history reference is refused.", "args": {"label": {"kind": "text"}, "method": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6015": {"severity": "error", "area": "collection-history", "message": "{label}.{method}: an {kind} has no fields.", "hint": null, "explanation": "An array or a matrix has no fields; a field read after its history reference is refused.", "args": {"label": {"kind": "text"}, "method": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6016": {"severity": "error", "area": "collection-history", "message": "{label}.{method}(): no array or matrix method of that name.", "hint": null, "explanation": "No array or matrix method has this name, so the call on the collection's history is refused.", "args": {"label": {"kind": "text"}, "method": {"kind": "identifier"}}}, + "PF-E6017": {"severity": "error", "area": "collection-history", "message": "matrix.sum of {label} is not supported in PineForge: the matrix it returns does not compile.", "hint": null, "explanation": "matrix.sum of a matrix's history returns a matrix that never compiled in PineForge, so it is refused.", "args": {"label": {"kind": "text"}}}, + "PF-E6018": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an argument of {name} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in function that takes only plain numbers, strings or conditions, which TradingView refuses; pass an element.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}}, + "PF-E6019": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an argument of {name} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in function that takes only plain numbers, strings or conditions, which TradingView refuses; pass an element.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}}, + "PF-E6020": {"severity": "error", "area": "collection-history", "message": "{label} as an argument of {name} is not supported in PineForge.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "name": {"kind": "identifier"}}}, + "PF-E6021": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an element of array.from (CE10122).", "hint": null, "explanation": "An array or matrix history read is used as an element of array.from(), which TradingView refuses; pass its elements instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6022": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an element of array.from (CE10122).", "hint": null, "explanation": "An array or matrix history read is used as an element of array.from(), which TradingView refuses; pass its elements instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6023": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an argument of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in namespace function that takes plain values, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E6024": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an argument of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a built-in namespace function that takes plain values, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E6025": {"severity": "error", "area": "collection-history", "message": "{label} as a field of a new {namespace} is not supported in PineForge: the field would hold a changeable copy, where TradingView''s holds the read-only history.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "namespace": {"kind": "identifier"}}}, + "PF-E6026": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as an argument of str.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a str function that takes a plain value, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, + "PF-E6027": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as an argument of str.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed to a str function that takes a plain value, which TradingView refuses; pass an element or the size instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, + "PF-E6028": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as the message of log.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is used as the message of a log call, which TradingView refuses; log an element or a string built from it instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, + "PF-E6029": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as the message of log.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is used as the message of a log call, which TradingView refuses; log an element or a string built from it instead.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, + "PF-E6030": {"severity": "error", "area": "collection-history", "message": "{label} as an argument of the overloaded method {member} is not supported in PineForge.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "member": {"kind": "identifier"}}}, + "PF-E6031": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as a value of {member}() (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix method, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, + "PF-E6032": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as a value of {member}() (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix method, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "member": {"kind": "identifier"}}}, + "PF-E6033": {"severity": "error", "area": "collection-history", "message": "{label} as an argument of {function}.{member} is not supported in PineForge.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}, "function": {"kind": "text"}, "member": {"kind": "identifier"}}}, + "PF-E6034": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses as a value of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix function, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E6035": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses as a value of {namespace}.{member} (CE10123).", "hint": null, "explanation": "An array or matrix history read is passed as a plain value, not as the collection, to an array or matrix function, which TradingView refuses.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "namespace": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E6036": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for log.{member} (CE10122).", "hint": null, "explanation": "A history read of an array of colors is a format argument of a log call, which TradingView refuses; log its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E6037": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for log.{member} (CE10123).", "hint": null, "explanation": "A history read of an array of colors is passed to a log call, which TradingView refuses; log its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E6038": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.format (CE10122).", "hint": null, "explanation": "A history read of an array of colors is a format argument of str.format, which TradingView refuses; format its elements instead.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6039": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.format (CE10123).", "hint": null, "explanation": "A history read of an array of colors is passed to str.format, which TradingView refuses; format its elements instead.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6040": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.tostring (CE10122).", "hint": null, "explanation": "A history read of an array of colors is passed to str.tostring, which TradingView refuses; convert its elements instead.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6041": {"severity": "error", "area": "collection-history", "message": "{label} is an array of colors, which TradingView refuses for str.tostring (CE10123).", "hint": null, "explanation": "A history read of an array of colors is passed to str.tostring, which TradingView refuses; convert its elements instead.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6042": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for log.{member} (CE10122).", "hint": null, "explanation": "A history read of an array of objects is a format argument of a log call, which TradingView refuses; log fields of its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E6043": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for log.{member} (CE10123).", "hint": null, "explanation": "A history read of an array of objects is passed to a log call, which TradingView refuses; log fields of its elements instead.", "args": {"label": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-E6044": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.format (CE10122).", "hint": null, "explanation": "A history read of an array of objects is a format argument of str.format, which TradingView refuses; format fields of its elements instead.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6045": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.format (CE10123).", "hint": null, "explanation": "A history read of an array of objects is passed to str.format, which TradingView refuses; format fields of its elements instead.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6046": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.tostring (CE10122).", "hint": null, "explanation": "A history read of an array of objects is passed to str.tostring, which TradingView refuses; convert fields of its elements instead.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6047": {"severity": "error", "area": "collection-history", "message": "{label} is an array of objects, which TradingView refuses for str.tostring (CE10123).", "hint": null, "explanation": "A history read of an array of objects is passed to str.tostring, which TradingView refuses; convert fields of its elements instead.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6048": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for the {type_hint} variable {name} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to a variable declared with a scalar type, which TradingView refuses; assign an element or declare a collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "type_hint": {"kind": "type"}, "name": {"kind": "identifier"}}}, + "PF-E6049": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for the {type_hint} variable {name} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to a variable declared with a scalar type, which TradingView refuses; assign an element or declare a collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "type_hint": {"kind": "type"}, "name": {"kind": "identifier"}}}, + "PF-E6050": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for the {field_type} field {member} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an object field of a scalar type, which TradingView refuses; assign an element or change the field's type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "field_type": {"kind": "type"}, "member": {"kind": "identifier"}}}, + "PF-E6051": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for the {field_type} field {member} (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an object field of a scalar type, which TradingView refuses; assign an element or change the field's type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "field_type": {"kind": "type"}, "member": {"kind": "identifier"}}}, + "PF-E6052": {"severity": "error", "area": "collection-history", "message": "{label} assigned to a field is not supported in PineForge: the field would hold a changeable copy, where TradingView''s holds the read-only history.", "hint": null, "explanation": "PineForge would hand over a changeable copy of the collection's history here, where TradingView passes the read-only history, so the use is refused.", "args": {"label": {"kind": "text"}}}, + "PF-E6053": {"severity": "error", "area": "collection-history", "message": "{label} is a {kind}, which TradingView refuses for the variable {name} of another type (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an existing variable of another type, which TradingView refuses; use a variable of the matching collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}}, + "PF-E6054": {"severity": "error", "area": "collection-history", "message": "{label} is an {kind}, which TradingView refuses for the variable {name} of another type (CE10173).", "hint": null, "explanation": "An array or matrix history read is assigned to an existing variable of another type, which TradingView refuses; use a variable of the matching collection type.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}, "name": {"kind": "identifier"}}}, + "PF-E6055": {"severity": "error", "area": "collection-history", "message": "{label} assigned to {name} is not supported in PineForge here.", "hint": null, "explanation": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower; use it only with built-in array or matrix functions.", "args": {"label": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-E6056": {"severity": "error", "area": "collection-history", "message": "{label} as a statement: TradingView reads it as a declaration and refuses it (CE10009, \"Extraneous input\").", "hint": null, "explanation": "An array or matrix history read written alone as a top-level statement is refused because TradingView reads it as a declaration; remove it or bind it to a variable.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6057": {"severity": "error", "area": "collection-history", "message": "{label} in a tuple is not supported in PineForge.", "hint": null, "explanation": "A history read bound to a variable or passed to a function is used there in a way PineForge cannot lower; use it only with built-in array or matrix functions.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6058": {"severity": "error", "area": "collection-history", "message": "{label}.slice() is not supported in PineForge here.", "hint": null, "explanation": "A slice of an array's history is used in a way PineForge cannot lower; simplify the expression or copy the array first.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6059": {"severity": "error", "area": "collection-history", "message": "{label} is bound where the script reads it both as a {kind} and through na() or str.tostring(): that is not supported in PineForge, which holds no na {kind} and does not render one.", "hint": null, "explanation": "A variable bound to an array or matrix history is read both as a collection and through na() or str.tostring(); PineForge has no na collection, so it refuses this.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6060": {"severity": "error", "area": "collection-history", "message": "{label} is bound where the script reads it both as an {kind} and through na() or str.tostring(): that is not supported in PineForge, which holds no na {kind} and does not render one.", "hint": null, "explanation": "A variable bound to an array or matrix history is read both as a collection and through na() or str.tostring(); PineForge has no na collection, so it refuses this.", "args": {"label": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6061": {"severity": "error", "area": "collection-history", "message": "{label} is not supported in PineForge here: the history of a matrix is supported as the receiver or an argument of a matrix function, na(), and the value of a variable or a function''s argument that reads it.", "hint": null, "explanation": "A matrix history is supported only as a matrix function's receiver or argument, in na(), or via a variable or function argument that reads it; this use is not.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6062": {"severity": "error", "area": "collection-history", "message": "{label} inside a request.security expression is not supported in PineForge: TradingView reads the copies the requested timeframe''s bars left, which PineForge does not keep.", "hint": null, "explanation": "request.security cannot read the history of a user-defined type or drawing reference, because PineForge keeps no references from the requested bars.", "args": {"label": {"kind": "text"}}}, + "PF-E6063": {"severity": "error", "area": "collection-history", "message": "{label} is not supported in PineForge here: the history of an array is supported as the receiver or an argument of an array function, a for...in iterable, na(), and the value of a variable or a function''s argument that reads it.", "hint": null, "explanation": "An array history is supported only as an array function's receiver or argument, a for...in iterable, in na(), or via a variable or function argument that reads it.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6064": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a block''s var {read_kind} is not supported in PineForge.", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "read_kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6065": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} declared in a block that redeclares a script variable is not supported in PineForge (such a block''s declarations are C++ locals).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6066": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} declared in a loop is not supported in PineForge.", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6067": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} function''s local is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6068": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} parameter is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6069": {"severity": "error", "area": "collection-history", "message": "{label}: the history of a {kind} script variable read in a function is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6070": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} declared in a block that redeclares a script variable is not supported in PineForge (such a block''s declarations are C++ locals).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6071": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} declared in a loop is not supported in PineForge.", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6072": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} function''s local is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6073": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} parameter is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6074": {"severity": "error", "area": "collection-history", "message": "{label}: the history of an {kind} script variable read in a function is not supported in PineForge (TradingView reads one copy per call: fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for the script's top level and its blocks, not for this kind of declaration.", "args": {"label": {"kind": "text"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6075": {"severity": "error", "area": "collection-history", "message": "{label}: the history of this {read_kind} is not supported in PineForge (only a variable the script''s top level or one of its blocks declares keeps one).", "hint": null, "explanation": "PineForge keeps the history of an array or matrix only for a variable the script's top level or one of its blocks declares.", "args": {"label": {"kind": "text"}, "read_kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6076": {"severity": "error", "area": "collection-history", "message": "The history of a call''s {kind} is not supported in PineForge here: TradingView reads the copy that expression produced that many bars back, which PineForge does not keep.", "hint": "Bind the expression to a variable and read the variable''s history.", "explanation": "The history of a function call's array or matrix result is refused as PineForge keeps no per-bar copy of it; bind the call to a variable and read its history.", "args": {"kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6077": {"severity": "error", "area": "collection-history", "message": "The history of a selection''s {kind} is not supported in PineForge here: TradingView reads the copy that expression produced that many bars back, which PineForge does not keep.", "hint": "Bind the expression to a variable and read the variable''s history.", "explanation": "The history of a ?: selection's array or matrix is refused as PineForge keeps no per-bar copy of it; bind the selection to a variable and read its history.", "args": {"kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6078": {"severity": "error", "area": "collection-history", "message": "The history of an expression''s {kind} is not supported in PineForge here: TradingView reads the copy that expression produced that many bars back, which PineForge does not keep.", "hint": "Bind the expression to a variable and read the variable''s history.", "explanation": "The history of an expression's array or matrix is refused as PineForge keeps no per-bar copy of it; bind the expression to a variable and read its history.", "args": {"kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-E6079": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a name bound to it (line ?): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A name bound to an array or matrix history is changed, which stops the run on TradingView; PineForge would change a copy silently, so copy the history first.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6080": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a name bound to it (line {line}): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A name bound to an array or matrix history is changed on the given line, which stops the run on TradingView; PineForge would change a copy, so copy it first.", "args": {"label": {"kind": "identifier"}, "line": {"kind": "number"}}}, + "PF-E6081": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a slice of it (line ?): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A slice of an array or matrix history is changed, which stops the run on TradingView; PineForge would silently change a copy, so copy the history first.", "args": {"label": {"kind": "identifier"}}}, + "PF-E6082": {"severity": "error", "area": "collection-history", "message": "{label} reaches a change through a slice of it (line {line}): TradingView stops the run there (RE10051: \"Cannot modify the elements of a historical array\"); PineForge, which holds a copy, does not.", "hint": "Copy it first (array.copy({label}) or matrix.copy()) to change it.", "explanation": "A slice of an array or matrix history is changed on the given line, which stops the run on TradingView; PineForge would change a copy, so copy it first.", "args": {"label": {"kind": "identifier"}, "line": {"kind": "number"}}}, + "PF-E7001": {"severity": "error", "area": "ta", "message": "Unsupported requested-context TA constructor for {class_name}: PineForge cannot bind the helper call''s arguments to its constructor arguments.", "hint": "Call the ta.* function directly inside request.security().", "explanation": "A TA function called through a helper inside request.security cannot have the helper's arguments bound to its constructor; call the ta.* function directly.", "args": {"class_name": {"kind": "identifier"}}}, + "PF-E7002": {"severity": "error", "area": "ta", "message": "Unsupported requested-context TA constructor flag ''{shown}'' for {class_name}: the helper-bound expression is not a stable per-run scalar{reason}.", "hint": "Use a literal, an input.*() value, timeframe.* metadata, or arithmetic over those for TA lengths.", "explanation": "A boolean option of a TA call inside request.security comes from a helper-bound value that is not fixed for the run; use a literal, an input or timeframe metadata.", "args": {"shown": {"kind": "identifier"}, "class_name": {"kind": "identifier"}, "reason": {"kind": "text"}}}, + "PF-E7003": {"severity": "error", "area": "ta", "message": "Unsupported requested-context TA constructor length ''{shown}'' for {class_name}: the helper-bound expression is not a stable per-run scalar{reason}.", "hint": "Use a literal, an input.*() value, timeframe.* metadata, or arithmetic over those for TA lengths.", "explanation": "A TA length inside request.security comes from a helper-bound value not fixed for the run; use a literal, an input, timeframe metadata or arithmetic on them.", "args": {"shown": {"kind": "identifier"}, "class_name": {"kind": "identifier"}, "reason": {"kind": "text"}}}, + "PF-E7004": {"severity": "error", "area": "ta", "message": "Unsupported TA constructor length for {class_name} inside request.security in ''{containing}'': its call sites pass different lengths ({spellings}), and one requested-context evaluator serves them all.", "hint": "Call request.security() at each call site, or pass the same length from every call.", "explanation": "A function with a request.security TA call is called with different lengths, but one evaluator serves all calls; use one length or call request.security per site.", "args": {"class_name": {"kind": "identifier"}, "containing": {"kind": "identifier"}, "spellings": {"kind": "identifier"}}}, + "PF-W0000": {"severity": "warning", "area": "uncatalogued", "message": "{message}", "hint": "{hint}", "explanation": "A diagnostic whose text no catalog template renders; the test suite refuses it, so a release never emits it.", "args": {"message": {"kind": "text"}, "hint": {"kind": "text"}}}, + "PF-W1001": {"severity": "warning", "area": "support", "message": "{context}: map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps with string keys only; declare the map's key type as string; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"context": {"kind": "text"}}}, + "PF-W1002": {"severity": "warning", "area": "support", "message": "{context}: map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge supports maps whose values are float, int, bool or string only; use one of those as the value type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"context": {"kind": "text"}}}, + "PF-W1003": {"severity": "warning", "area": "support", "message": "matrix<{element_type}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"element_type": {"kind": "type"}}}, + "PF-W1004": {"severity": "warning", "area": "support", "message": "matrix<{element_type}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"element_type": {"kind": "type"}}}, + "PF-W1005": {"severity": "warning", "area": "support", "message": "input.color(...) requires a color defval (e.g. color.red or color.new(color.red, 50)).", "hint": null, "explanation": "input.color needs a color as its default value, for example color.red or color.new(color.red, 50); inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1006": {"severity": "warning", "area": "support", "message": "input.color(...) defval must be a color constant (color.red, ...), a color literal (#rrggbb), or a color.new(...) / color.rgb(...) builder. Arbitrary expressions are not supported: the engine has no color helper, so codegen routes input.color through the int getter — any non-color defval would silently store a numeric value with no color encoding.", "hint": "Replace the defval with color. or color.new(...).", "explanation": "The default of input.color must be a color constant, a #rrggbb literal or a color.new or color.rgb call; other expressions are refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1007": {"severity": "warning", "area": "support", "message": "input.source(...) requires a native series defval (close, open, high, low, hl2, hlc3, ohlc4, ...).", "hint": null, "explanation": "input.source needs a default chart series such as close as its first argument or defval; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1008": {"severity": "warning", "area": "support", "message": "input.source(...) defval must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4). User series, computed expressions, and indicator outputs are not supported: input.source is restricted to native OHLCV series.", "hint": "Use one of: close, open, high, low, hl2, hlc3, ohlc4.", "explanation": "The default of input.source must be a native chart series (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4); computed series are refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1009": {"severity": "warning", "area": "support", "message": "{kind}() declarations are not supported; PineForge runs strategies only.", "hint": "Replace the declaration with strategy(...) and add explicit entry/exit calls.", "explanation": "PineForge runs strategies only, so a script declared with indicator() or library() is refused; declare it with strategy() and add orders; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kind": {"kind": "identifier"}}}, + "PF-W1010": {"severity": "warning", "area": "support", "message": "Tuple reassignment [..] {op} is not Pine syntax: TradingView declares a tuple with ''='' and has no tuple reassignment.", "hint": "Declare new names with [a, b] = f(), then reassign each variable on its own line.", "explanation": "Pine has no tuple reassignment: declare a tuple once with '=' and reassign each variable on its own line; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"op": {"kind": "keyword"}}}, + "PF-W1011": {"severity": "warning", "area": "support", "message": "A tuple literal [..] cannot be a variable''s value: TradingView rejects it here (Syntax error at input ''['', CE10156). A tuple is only a function''s or an if/switch arm''s value or a request.security expression.", "hint": "Declare each variable on its own line (a = x, b = y), or return the tuple from a function: f() => [x, y], then [a, b] = f().", "explanation": "A tuple literal such as [a, b] cannot be assigned to a variable; return it from a function or if/switch arm and destructure the result; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1012": {"severity": "warning", "area": "support", "message": "A ternary cannot return a tuple: TradingView rejects [a, b] = c ? [..] : [..] (\"Ternary operations cannot return tuples\").", "hint": "Select the tuple with an if or switch: [a, b] = if c, each arm ending in its tuple.", "explanation": "A ternary cannot produce a tuple (TradingView rejects it too); choose between tuples with an if or switch instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1013": {"severity": "warning", "area": "support", "message": "ta.stoch(...) returns a single series in PineForge; tuple destructuring is not supported.", "hint": "Use k = ta.stoch(...) and compute smoothing separately if needed.", "explanation": "ta.stoch returns one series in PineForge, so destructuring it into a tuple is refused; assign it to a single variable; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1014": {"severity": "warning", "area": "support", "message": "History references on UDT drawing fields are not supported in PineForge.", "hint": "{var_name}.{object_member}[...] would be read as the current-bar field, not prior-bar history. Copy the field to a bare drawing variable first, or remove the history reference.", "explanation": "A history index on a drawing field of a user-defined type would silently read the current field, so it is refused; copy the field to a variable first; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"var_name": {"kind": "identifier"}, "object_member": {"kind": "identifier"}}}, + "PF-W1015": {"severity": "warning", "area": "support", "message": "History references on tuple-destructured drawing handles are not supported in PineForge.", "hint": "{object_name}[...] is a drawing handle from tuple destructuring; PineForge cannot historize that tuple element safely.", "explanation": "A drawing handle bound by tuple destructuring cannot be read through a history index; remove the history reference; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}}}, + "PF-W1016": {"severity": "warning", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}}}, + "PF-W1017": {"severity": "warning", "area": "support", "message": "x[k].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}}, + "PF-W1018": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: (x[k]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1019": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}(): TradingView refuses a method call straight after the history-referencing operator (CE10010; CE10011 after an array''s or a matrix''s history).", "hint": "Call the method on the history reference in parentheses: ({object_name}[{index}]).{member}().", "explanation": "TradingView rejects a method call written straight after a history index, x[k].method(); put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1020": {"severity": "warning", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}}}, + "PF-W1021": {"severity": "warning", "area": "support", "message": "x[k].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}}}, + "PF-W1022": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: (x[k]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1023": {"severity": "warning", "area": "support", "message": "{object_name}[{index}].{member}: TradingView refuses a field read straight after the history-referencing operator (CE10011: \"User variable identifiers should not contain ''.''\").", "hint": "Read the field of the history reference in parentheses: ({object_name}[{index}]).{member}.", "explanation": "TradingView rejects a field read written straight after a history index, x[k].field; put the history reference in parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "index": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1024": {"severity": "warning", "area": "support", "message": "footprint.{footprint}(...) is not supported.", "hint": "PineForge reads a footprint''s delta() only: the fp_delta__ column of the feed a requests manifest pins for the symbol requested.", "explanation": "PineForge reads only the delta of a footprint value; every other footprint member is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"footprint": {"kind": "identifier"}}}, + "PF-W1025": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "Currency conversion data not available in PineForge.", "explanation": "PineForge has no currency-conversion data, so request.currency_rate is refused; supply the rate yourself, for example as an input; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1026": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "External Quandl data not available in PineForge.", "explanation": "PineForge cannot load external Quandl data, so request.quandl is refused; remove it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1027": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "External seed data feeds not available in PineForge.", "explanation": "PineForge cannot load external seed data feeds, so request.seed is refused; remove it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1028": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.kagi() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.kagi builds a Kagi symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1029": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.linebreak() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.linebreak builds a Line Break symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1030": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.modify() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.modify builds a modified symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1031": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.new() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.new builds another symbol identifier, which PineForge cannot request; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1032": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.pointfigure() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.pointfigure builds a Point and Figure symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1033": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported.", "hint": "ticker.renko() chart-type modifier / cross-symbol construction not supported — PineForge runs same-symbol MTF only via request.security with the chart''s own tickerid.", "explanation": "ticker.renko builds a Renko symbol, which PineForge cannot run; PineForge supports multi-timeframe requests on the chart's own symbol only; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1034": {"severity": "warning", "area": "support", "message": "ticker.heikinashi(...) is supported only for the chart''s own symbol.", "hint": "Pass syminfo.tickerid: PineForge applies the Heikin-Ashi candle transform to the chart symbol inside request.security, but cannot load an alternate symbol''s HA candles.", "explanation": "ticker.heikinashi is accepted only for the chart's own symbol (syminfo.tickerid); another symbol's Heikin-Ashi candles cannot be loaded; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1035": {"severity": "warning", "area": "support", "message": "{full}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1036": {"severity": "warning", "area": "support", "message": "{name}(...) is not implemented yet.", "hint": "timeframe.from_seconds is not yet implemented; codegen would emit ''false'' and silently produce wrong TF strings.", "explanation": "This call names a function on PineForge's not-yet-implemented list, so it is refused rather than compiled into something that silently misbehaves; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1037": {"severity": "warning", "area": "support", "message": "{full}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "footprint.* calls need tick-level bid/ask volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1038": {"severity": "warning", "area": "support", "message": "{full}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": "Remove the call or replace it with native OHLCV-based logic.", "explanation": "volume_row.* calls need tick-level volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1039": {"severity": "warning", "area": "support", "message": "library() declarations are not supported; PineForge runs strategies only.", "hint": "Use strategy(...) and inline or pre-expand library code before uploading.", "explanation": "PineForge runs strategies only, so a library() declaration is refused; use strategy() and paste any library code into the script; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1040": {"severity": "warning", "area": "support", "message": "Bare barssince(...) is broken in PineForge codegen.", "hint": "Use ta.barssince(...) instead.", "explanation": "The bare barssince(...) form does not work in PineForge; call ta.barssince(...) instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1041": {"severity": "warning", "area": "support", "message": "ta.sum is not a PineScript v6 function.", "hint": "Use math.sum(...) instead.", "explanation": "ta.sum does not exist in Pine v6; use math.sum(source, length) for a rolling sum; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1042": {"severity": "warning", "area": "support", "message": "ta.{name} is a PineScript v6 variable, not a function.", "hint": "Use ta.{name} without parentheses.", "explanation": "This ta.* name is a built-in variable, not a function, so write it without parentheses; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1043": {"severity": "warning", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.closedtrades or strategy.opentrades accessor is not available in PineForge; use one of the supported trade accessors; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1044": {"severity": "warning", "area": "support", "message": "{full}(...) is not implemented in PineForge runtime.", "hint": "{hint}", "explanation": "Open trades have no exit data in Pine v6: this accessor exists only on strategy.closedtrades, so it cannot be read from strategy.opentrades; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}, "hint": {"kind": "text"}}}, + "PF-W1045": {"severity": "warning", "area": "support", "message": "strategy.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "This strategy.* function is not implemented in PineForge; check the spelling or use a supported strategy function; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1046": {"severity": "warning", "area": "support", "message": "strategy.exit(...) requires at least one price or trailing parameter in PineForge.", "hint": "Use strategy.close(...) for market exits.", "explanation": "strategy.exit needs a price or trailing parameter (profit, loss, limit, stop or a trail setting); use strategy.close for a plain market exit; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1047": {"severity": "warning", "area": "support", "message": "{full}(...) is not supported. Only request.security(...) and request.security_lower_tf(...) are available in PineForge.", "hint": "External request feeds and other request.* variants are intentionally unavailable.", "explanation": "Only request.security and request.security_lower_tf are supported; other request.* calls need data feeds PineForge does not provide; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1048": {"severity": "warning", "area": "support", "message": "ta.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this ta.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1049": {"severity": "warning", "area": "support", "message": "math.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this math.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1050": {"severity": "warning", "area": "support", "message": "str.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this str.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1051": {"severity": "warning", "area": "support", "message": "input.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this input.* function, so the call is refused; use one of the supported input functions; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1052": {"severity": "warning", "area": "support", "message": "timeframe.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only timeframe.change and timeframe.in_seconds; any other timeframe.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1053": {"severity": "warning", "area": "support", "message": "color.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only color.new, color.rgb and color.r/g/b/t; any other color.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1054": {"severity": "warning", "area": "support", "message": "runtime.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only runtime.error; any other runtime.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1055": {"severity": "warning", "area": "support", "message": "log.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only log.info, log.warning and log.error; any other log.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1056": {"severity": "warning", "area": "support", "message": "array.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this array.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1057": {"severity": "warning", "area": "support", "message": "map.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this map.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1058": {"severity": "warning", "area": "support", "message": "map keys must be string in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps support only string keys; declare the map with string as its key type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1059": {"severity": "warning", "area": "support", "message": "map values must be primitive in PineForge''s supported map subset.", "hint": null, "explanation": "PineForge maps can hold only float, int, bool or string values; other value types such as collections or objects are refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1060": {"severity": "warning", "area": "support", "message": "matrix<{t}>: nested collection element types not supported in v1.", "hint": null, "explanation": "A matrix cannot hold another collection as its element type in PineForge; use float, int, bool, string, color or a user-defined type; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"t": {"kind": "type"}}}, + "PF-W1061": {"severity": "warning", "area": "support", "message": "matrix<{t}> is not supported when the UDT contains a map field; rollback would retain live map aliases.", "hint": "Use array for recursively checkpointed state.", "explanation": "A matrix of a user-defined type with a map field is refused because rollback would keep live map references; use an array of that type instead; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"t": {"kind": "type"}}}, + "PF-W1062": {"severity": "warning", "area": "support", "message": "matrix<{t}> element type not supported. Allowed: float, int, bool, string, color, or a declared UDT.", "hint": null, "explanation": "A matrix element must be float, int, bool, string, color or a declared user-defined type; any other element type is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"t": {"kind": "type"}}}, + "PF-W1063": {"severity": "warning", "area": "support", "message": "matrix.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge has no implementation of this matrix.* function, so the call is refused instead of compiling to a silent stub; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1064": {"severity": "warning", "area": "support", "message": "{ns}.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only part of the line, box, label and linefill functions; this one is not implemented, so the call is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-W1065": {"severity": "warning", "area": "support", "message": "chart.point.{name}(...) is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge implements only chart.point.new, now, from_index, from_time and copy; any other chart.point.* function is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1066": {"severity": "warning", "area": "support", "message": "''export'' is a Pine library keyword; PineForge runs strategies only and does not support exported functions/types.", "hint": "Remove the ''export'' keyword (and inline any library code into the strategy script).", "explanation": "'export' marks library code; PineForge runs strategies only, so remove the keyword and inline any library code into the strategy; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1067": {"severity": "warning", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1068": {"severity": "warning", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1069": {"severity": "warning", "area": "support", "message": "{name} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1070": {"severity": "warning", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "bar_index depends on the data window; PineForge and TradingView produce different values for the same script.", "explanation": "bar_index counts bars of the data window PineForge is fed, so its value can differ from TradingView's for the same script.", "args": {"chain": {"kind": "identifier"}}}, + "PF-W1071": {"severity": "warning", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "last_bar_index is the final index of PineForge''s fed data window; it can diverge from TradingView when the window does not cover the same chart history.", "explanation": "last_bar_index is the last index of the data window PineForge is fed, so it can differ from TradingView's when the history windows differ.", "args": {"chain": {"kind": "identifier"}}}, + "PF-W1072": {"severity": "warning", "area": "support", "message": "{chain} diverges from TradingView semantics in PineForge.", "hint": "timenow is aliased to the current bar timestamp in PineForge; it is not real wall-clock time.", "explanation": "timenow is aliased to the current bar's time in PineForge, not real wall-clock time, so logic relying on the real time will differ.", "args": {"chain": {"kind": "identifier"}}}, + "PF-W1073": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: footprint.* (bid/ask volume rows) is not supported in PineForge batch backtests; it requires tick-level data the engine does not consume.", "hint": null, "explanation": "Members of the footprint.* namespace need tick-level bid/ask volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1074": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: volume_row.* is not supported in PineForge batch backtests; same reason as footprint.*.", "hint": null, "explanation": "Members of the volume_row.* namespace need tick-level volume rows, which a PineForge batch backtest does not load; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1075": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: dividends.* is not available in PineForge — fundamental dividend data is not loaded.", "hint": null, "explanation": "dividends.* fields read fundamental dividend data, which PineForge does not load outside a recorded request; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1076": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: earnings.* is not available in PineForge — fundamental earnings data is not loaded.", "hint": null, "explanation": "earnings.* fields read fundamental earnings data, which PineForge does not load outside a recorded request; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1077": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: splits.* is not available in PineForge — corporate-action split data is not loaded.", "hint": null, "explanation": "splits.* fields read corporate-action split data, which PineForge does not load outside a recorded request; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1078": {"severity": "warning", "area": "support", "message": "{object_name}.{member} is a visual/style constant with no runtime value in PineForge backtests; it is only accepted as an argument to visual calls (plot, plotshape, hline, label.new, table.cell, ...), which PineForge parses and skips.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "A visual or style constant has no value in a backtest; it may only be passed to plotting and drawing calls, which PineForge skips; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1079": {"severity": "warning", "area": "support", "message": "{object_name}.{member} is not a Pine alert constant; only alert.freq_all, alert.freq_once_per_bar and alert.freq_once_per_bar_close exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The alert.* member is not one of Pine's alert frequency constants; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1080": {"severity": "warning", "area": "support", "message": "{object_name}.{member} is not a barmerge constant; only barmerge.gaps_on, barmerge.gaps_off, barmerge.lookahead_on and barmerge.lookahead_off exist.", "hint": "Constant-namespace members cannot flow into strategy logic; codegen would emit a string literal while the analyzer types the read as int.", "explanation": "The barmerge.* member is not one of Pine's gaps or lookahead constants; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1081": {"severity": "warning", "area": "support", "message": "syminfo.{member} is not implemented in PineForge runtime.", "hint": null, "explanation": "PineForge does not implement this syminfo.* member, so reading it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"member": {"kind": "identifier"}}}, + "PF-W1082": {"severity": "warning", "area": "support", "message": "request.security parameter ''{kw_name}'' is not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts only a few named parameters in PineForge; this one is refused instead of being silently ignored, so remove it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kw_name": {"kind": "identifier"}}}, + "PF-W1083": {"severity": "warning", "area": "support", "message": "Extra positional arguments to request.security are not allowed in PineForge.", "hint": "Only symbol, timeframe, expression, gaps, and lookahead are accepted.", "explanation": "request.security accepts at most five positional arguments (symbol, timeframe, expression, gaps, lookahead); remove the extra ones; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1084": {"severity": "warning", "area": "support", "message": "request.security gaps must be barmerge.gaps_on or barmerge.gaps_off.", "hint": "Codegen only recognizes the barmerge.gaps_* literal; other values are silently treated as gaps_off.", "explanation": "The gaps argument of request.security must be written literally as barmerge.gaps_on or barmerge.gaps_off, the only forms PineForge reads; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1085": {"severity": "warning", "area": "support", "message": "request.security lookahead must be barmerge.lookahead_on or barmerge.lookahead_off.", "hint": "Codegen only recognizes the barmerge.lookahead_* literal; other values are silently treated as lookahead_off.", "explanation": "The lookahead argument of request.security must be written literally as barmerge.lookahead_on or barmerge.lookahead_off, the only forms PineForge reads; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {}}, + "PF-W1086": {"severity": "warning", "area": "support", "message": "request.security: {kw_name}={object_name}.{val_member} is not supported. The engine ignores this kwarg, which would silently produce different prices from TradingView.", "hint": "Allowed values: {allowed}.", "explanation": "PineForge ignores request.security's price-adjustment settings, so only no-op values are accepted; others would silently give prices unlike TradingView's; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kw_name": {"kind": "identifier"}, "object_name": {"kind": "identifier"}, "val_member": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}}, + "PF-W1087": {"severity": "warning", "area": "support", "message": "request.security: {kw_name}=... must be a constant member access of the form {kw_name}. (got a non-constant expression).", "hint": "Allowed values: {allowed}.", "explanation": "A request.security price-adjustment setting must be a plain constant of the form name.value (like adjustment.none), not a computed expression; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"kw_name": {"kind": "identifier"}, "allowed": {"kind": "identifier"}}}, + "PF-W1088": {"severity": "warning", "area": "support", "message": "{name} {message} (TradingView: {spelled}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A nz or fixnan call whose arguments match none of TradingView's signatures (unknown name, too many or missing arguments) is refused, as TradingView refuses it; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "spelled": {"kind": "identifier"}}}, + "PF-W1089": {"severity": "warning", "area": "support", "message": "ta.{name} {message} (TradingView: {signature}).", "hint": "Use the parameters of TradingView''s signature.", "explanation": "A ta.* call whose arguments match none of TradingView's signatures (unknown or repeated parameter, too many or missing arguments) is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"name": {"kind": "identifier"}, "message": {"kind": "text"}, "signature": {"kind": "identifier"}}}, + "PF-W1090": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}}, + "PF-W1091": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}}, + "PF-W1092": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}}, + "PF-W1093": {"severity": "warning", "area": "support", "message": "request.security: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}}, + "PF-W1094": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "empty timeframe literal", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}}, + "PF-W1095": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "non-integer timeframe magnitude ''{digits}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "digits": {"kind": "identifier"}}}, + "PF-W1096": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "timeframe magnitude must be positive", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}}}, + "PF-W1097": {"severity": "warning", "area": "support", "message": "request.security_lower_tf: invalid timeframe literal ''{timeframe}''. Expected Pine TF format like ''1'', ''15'', ''1H'', ''1D'', ''15S''.", "hint": "unknown timeframe suffix ''{suffix}''", "explanation": "The timeframe string given to request.security_lower_tf is not a valid Pine timeframe such as 1, 15, 1H, 1D or 15S, so it is refused; inside a switch arm PineForge warns instead and keeps the arm's lowering.", "args": {"timeframe": {"kind": "identifier"}, "suffix": {"kind": "identifier"}}}, + "PF-W1500": {"severity": "warning", "area": "support", "message": "{call}: request.security symbol can select an alternate symbol, but PineForge always loads the current chart symbol.", "hint": "It reads no feed of another symbol: {reasons}. Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "A request.security whose symbol can select another symbol is approximated by the chart's own symbol, because no other-symbol feed can be registered for it.", "args": {"call": {"kind": "identifier"}, "reasons": {"kind": "text"}}}, + "PF-W1501": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "PineForge reads another symbol''s feed only for a symbol and timeframe registration computes before the first bar; {reasons}.", "explanation": "A request.security of another symbol has no pinned data, so the run stops with an error where its value is read; its symbol and timeframe must be known up front.", "args": {"call": {"kind": "identifier"}, "reasons": {"kind": "text"}}}, + "PF-W1502": {"severity": "warning", "area": "support", "message": "color(...) cast has no effect in PineForge backtests (visual only); it emits a default color.", "hint": null, "explanation": "A color(...) cast is visual only and has no effect on a backtest, so PineForge ignores it and uses a default color.", "args": {}}, + "PF-W1503": {"severity": "warning", "area": "support", "message": "strategy.risk.{name}(...) has partial PineForge runtime support.", "hint": "Verify risk behavior against PineForge results; unsupported risk edge cases may diverge from TradingView.", "explanation": "A strategy.risk.* call has only partial runtime support in PineForge, so check that your risk limits behave as they do on TradingView.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1504": {"severity": "warning", "area": "support", "message": "strategy.{name} parameter ''{param_name}'' is not supported by PineForge and is ignored.", "hint": null, "explanation": "A strategy order call passes a parameter PineForge does not support, so the parameter is ignored and the order runs without it.", "args": {"name": {"kind": "identifier"}, "param_name": {"kind": "identifier"}}}, + "PF-W1505": {"severity": "warning", "area": "support", "message": "ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does.", "hint": "A covered length-20 TradingView tape first returns a finite EMA at bar 19; standalone PineForge EMA is finite at bar 0. Its established lowering stays in place pending per-call-site population parity.", "explanation": "ta.ema is approximated during warmup: PineForge may return a finite value on early bars where TradingView still returns na, so early results can differ.", "args": {}}, + "PF-W1506": {"severity": "warning", "area": "support", "message": "color.{name}(...) has no effect in PineForge backtests (visual only); it evaluates its arguments and emits a default color.", "hint": null, "explanation": "A cosmetic color function has no effect on a backtest, so PineForge evaluates its arguments and uses a default color.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1507": {"severity": "warning", "area": "support", "message": "{ns}.{name}(...) is a visual no-op in PineForge backtests (drawing geometry is data; color/style/size are dropped).", "hint": null, "explanation": "A drawing setter for color, style or size is a visual no-op in PineForge, which keeps only the drawing's geometry as data.", "args": {"ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-W1508": {"severity": "warning", "area": "support", "message": "{name}(...) has no effect in PineForge backtests (visual only).", "hint": null, "explanation": "A call into a visual-only namespace such as table or polyline has no effect on backtest results, so PineForge ignores it.", "args": {"name": {"kind": "identifier"}}}, + "PF-W1509": {"severity": "warning", "area": "support", "message": "{full}(...) has no effect in PineForge backtests (visual only).", "hint": null, "explanation": "A call into a visual-only namespace such as table or polyline has no effect on backtest results, so PineForge ignores it.", "args": {"full": {"kind": "identifier"}}}, + "PF-W1510": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "In direct batch chart-scope evaluation, barstate.islast is true only on the final bar of PineForge''s fed chart-data window. Inside a request.security() history index, PineForge currently selects the false branch; requested-context last-bar state is not modeled.", "explanation": "barstate.islast is true only on the last bar of PineForge's fed data, and inside a request.security history index it selects the false branch.", "args": {"chain": {"kind": "identifier"}}}, + "PF-W1511": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "In direct historical batch chart-scope evaluation, PineForge approximates barstate.islastconfirmedhistory as true only on the final bar of the fed chart-data window. Inside a request.security() history index, PineForge currently selects the false branch; TradingView''s requested-context and realtime-boundary semantics are not modeled.", "explanation": "barstate.islastconfirmedhistory is approximated as true only on the final bar of the fed data window, and as false inside a request.security history index.", "args": {"chain": {"kind": "identifier"}}}, + "PF-W1512": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.isconfirmed follows PineForge last-tick execution state.", "explanation": "barstate.isconfirmed follows PineForge's last-tick execution state, so it can differ from TradingView's confirmation behavior.", "args": {"chain": {"kind": "identifier"}}}, + "PF-W1513": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.ishistory is always true in PineForge batch backtests.", "explanation": "barstate.ishistory is always true in PineForge batch backtests, because there is no real-time bar.", "args": {"chain": {"kind": "identifier"}}}, + "PF-W1514": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.isnew follows PineForge first-tick execution state.", "explanation": "barstate.isnew is only approximated in PineForge, following its first-tick execution state, so it may behave differently from TradingView.", "args": {"chain": {"kind": "identifier"}}}, + "PF-W1515": {"severity": "warning", "area": "support", "message": "{chain} is approximated in PineForge.", "hint": "barstate.isrealtime is always false in PineForge batch backtests.", "explanation": "barstate.isrealtime is always false because PineForge runs batch backtests on historical bars only, so real-time-only logic never runs.", "args": {"chain": {"kind": "identifier"}}}, + "PF-W1516": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.bg_color has no meaning in a batch backtest (no chart theme); emits a default color.", "hint": null, "explanation": "chart.bg_color depends on the chart theme, which a batch backtest does not have, so PineForge substitutes a default color.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1517": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.fg_color has no meaning in a batch backtest (no chart theme); emits a default color.", "hint": null, "explanation": "chart.fg_color depends on the chart theme, which a batch backtest does not have, so PineForge substitutes a default color.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1518": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.left_visible_bar_time has no meaning in a batch backtest (no viewport); emits 0.", "hint": null, "explanation": "chart.left_visible_bar_time depends on the chart viewport, which a batch backtest does not have, so PineForge substitutes 0.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1519": {"severity": "warning", "area": "support", "message": "{object_name}.{member}: chart.right_visible_bar_time has no meaning in a batch backtest (no viewport); emits 0.", "hint": null, "explanation": "chart.right_visible_bar_time depends on the chart viewport, which a batch backtest does not have, so PineForge substitutes 0.", "args": {"object_name": {"kind": "identifier"}, "member": {"kind": "identifier"}}}, + "PF-W1520": {"severity": "warning", "area": "support", "message": "syminfo.{member} is na unless the run declares the symbol''s {member} (syminfo metadata \"{member}\", a lane fact).", "hint": null, "explanation": "This syminfo field has no built-in value in PineForge: it is na unless the run supplies the symbol's value as metadata, so anything computed from it is na.", "args": {"member": {"kind": "identifier"}}}, + "PF-W1521": {"severity": "warning", "area": "support", "message": "syminfo.{member} returns na in current PineForge; any expression using it will be na. Will be backfilled by pineforge-data product.", "hint": null, "explanation": "This syminfo field is not provided by PineForge yet and always reads na, so any expression using it is na.", "args": {"member": {"kind": "identifier"}}}, + "PF-W1522": {"severity": "warning", "area": "support", "message": "syminfo.{member} returns na in current PineForge; condition will always be false. Will be backfilled by pineforge-data product.", "hint": null, "explanation": "This syminfo field is not provided by PineForge yet and always reads na, so a condition built on it is always false.", "args": {"member": {"kind": "identifier"}}}, + "PF-W1523": {"severity": "warning", "area": "support", "message": "request.security symbol can select an alternate symbol, but PineForge always loads the current chart symbol.", "hint": "Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "The request.security symbol can select another symbol, but PineForge always loads the chart's symbol; resolve every value to syminfo.tickerid for exact results.", "args": {}}, + "PF-W1524": {"severity": "warning", "area": "support", "message": "request.security lookahead_on changes HTF timing: the completed higher-timeframe value is exposed from the bucket''s first chart bar. PineForge emits this (engine-supported) but results differ from lookahead_off and, with a 0-offset HTF expression, repaint future data.", "hint": "The safe non-repainting form pairs lookahead_on with a [1] offset (e.g. close[1]) to read only completed prior HTF bars.", "explanation": "request.security with lookahead_on exposes higher-timeframe values early and can repaint future data; pair it with a [1] offset such as close[1] to stay safe.", "args": {}}, + "PF-W1525": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External corporate-action data not available in PineForge. A recorded series is read when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "No recorded series applies to this earnings, dividends or splits request, but its value only feeds plots, alerts or tables, so it becomes na; trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}}}, + "PF-W1526": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External corporate-action data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge has no earnings, dividends or splits data; this request's value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}}, + "PF-W1527": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External fundamentals data not available in PineForge. A recorded series is read when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "No recorded series applies to this request.financial call, but its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}}}, + "PF-W1528": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "External fundamentals data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge has no fundamentals data for request.financial; its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}}, + "PF-W1529": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "Footprint (bid/ask volume) data not available in PineForge. A recorded series is read when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "No recorded series applies to this request.footprint call, but its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}}}, + "PF-W1530": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "Footprint (bid/ask volume) data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge has no footprint (bid/ask volume) data for request.footprint; its value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}}, + "PF-W1531": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker), and reads another symbol''s feed only when {blocker}. The value it lowers to reaches alerts, plots and tables only.", "explanation": "Another symbol's feed is read only in the stated case; here the request's value only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "vocab", "values": ["it is outside another request's expression", "it is request.security", "its expression holds no request of its own", "its gaps and lookahead are barmerge constants", "its request.footprint states ticks_per_row and va_percent as literal whole numbers", "registration computes its ignore_invalid_symbol before the first bar", "registration computes its symbol before the first bar", "registration computes its timeframe before the first bar"]}}}, + "PF-W1532": {"severity": "warning", "area": "support", "message": "{call}: value reaches only display/alert sinks; lowered to na; trades are unaffected.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker). The value it lowers to reaches alerts, plots and tables only.", "explanation": "PineForge loads only the chart's symbol; this request for another symbol only feeds plots, alerts or tables, so it becomes na and trades are unaffected.", "args": {"call": {"kind": "identifier"}}}, + "PF-W1533": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External corporate-action data not available in PineForge. A recorded series is read when {blocker}. Its value can reach a trade: {reason}.", "explanation": "No recorded series applies to this earnings, dividends or splits request and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}, "reason": {"kind": "text"}}}, + "PF-W1534": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External corporate-action data not available in PineForge. Its value can reach a trade: {reason}.", "explanation": "PineForge has no earnings, dividends or splits data and this request's value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}}, + "PF-W1535": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External fundamentals data not available in PineForge. A recorded series is read when {blocker}. Its value can reach a trade: {reason}.", "explanation": "No recorded series applies to this request.financial call and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}, "reason": {"kind": "text"}}}, + "PF-W1536": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "External fundamentals data not available in PineForge. Its value can reach a trade: {reason}.", "explanation": "PineForge has no fundamentals data for request.financial and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}}, + "PF-W1537": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "Footprint (bid/ask volume) data not available in PineForge. A recorded series is read when {blocker}. Its value can reach a trade: {reason}.", "explanation": "No recorded series applies to this request.footprint call and its value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "text"}, "reason": {"kind": "text"}}}, + "PF-W1538": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "Footprint (bid/ask volume) data not available in PineForge. Its value can reach a trade: {reason}.", "explanation": "PineForge has no footprint (bid/ask volume) data and this request's value can reach a trade, so the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}}, + "PF-W1539": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker), and reads another symbol''s feed only when {blocker}. Its value can reach a trade: {reason}.", "explanation": "PineForge reads another symbol's feed only in the stated case, and this request's value can reach a trade, so the run stops with an error where it is read.", "args": {"call": {"kind": "identifier"}, "blocker": {"kind": "vocab", "values": ["it is outside another request's expression", "it is request.security", "its expression holds no request of its own", "its gaps and lookahead are barmerge constants", "its request.footprint states ticks_per_row and va_percent as literal whole numbers", "registration computes its ignore_invalid_symbol before the first bar", "registration computes its symbol before the first bar", "registration computes its timeframe before the first bar"]}, "reason": {"kind": "text"}}}, + "PF-W1540": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where its value is read.", "hint": "PineForge backtests load the chart''s symbol only (syminfo.tickerid, syminfo.ticker). Its value can reach a trade: {reason}.", "explanation": "PineForge loads only the chart's symbol, and this request for another symbol can reach a trade, so the run stops with an error where its value is read.", "args": {"call": {"kind": "identifier"}, "reason": {"kind": "text"}}}, + "PF-W1541": {"severity": "warning", "area": "support", "message": "{call}: another symbol''s bars, read from the feed the requests manifest pins for it; with none installed, the run stops with an error where its value is read.", "hint": "PineForge runs the expression on that symbol''s own bars (history, ta.* and syminfo.* in its context) and merges them by time as TradingView does; a symbol equal to the chart''s reads the chart.", "explanation": "request.security on another symbol reads that symbol's pinned feed; if none is installed, the run stops with an error where the value is read.", "args": {"call": {"kind": "identifier"}}}, + "PF-W1542": {"severity": "warning", "area": "support", "message": "{call}: its symbol can select another symbol: registered by the string the run computes, a footprint reads the feed the requests manifest pins for each symbol, the chart''s too (the chart''s bars carry no footprint); with none installed, the run stops with an error where its value is read.", "hint": "It read the chart''s bars for every symbol: another symbol''s value never comes from the chart.", "explanation": "The footprint symbol can vary: every symbol, the chart's too, reads its own pinned feed, and a missing feed stops the run where the value is read.", "args": {"call": {"kind": "identifier"}}}, + "PF-W1543": {"severity": "warning", "area": "support", "message": "{call}: its symbol can select another symbol: registered by the string the run computes, the chart''s reads the chart and another symbol''s the feed the requests manifest pins for it; with none installed, the run stops with an error where its value is read.", "hint": "It read the chart''s bars for every symbol: another symbol''s value never comes from the chart.", "explanation": "The request.security symbol can be the chart's or another symbol: the chart's reads the chart, another reads its pinned feed, and a missing feed stops the run.", "args": {"call": {"kind": "identifier"}}}, + "PF-W1544": {"severity": "warning", "area": "support", "message": "{call}: TradingView''s values per chart bar, read from the series the requests manifest records under {parts}||{parts2}|{parts3}|gaps_{parts4}|lookahead_{parts5}; with none installed, the run stops with an error where its value is read.", "hint": "PineForge replays the values TradingView returned on the chart''s own bars (chart_open_ms,value): a bar the tape has no row for reads na.", "explanation": "This request replays the values TradingView returned on each chart bar, from the requests manifest; with no recording installed the run stops where it is read.", "args": {"call": {"kind": "identifier"}, "parts": {"kind": "identifier"}, "parts2": {"kind": "identifier"}, "parts3": {"kind": "identifier"}, "parts4": {"kind": "identifier"}, "parts5": {"kind": "identifier"}}}, + "PF-W1545": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it decides a loop''s break or continue.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}}}, + "PF-W1546": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it is a history offset.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}}}, + "PF-W1547": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it is written to a field or element.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}}}, + "PF-W1548": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: it reaches {label}.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}, "label": {"kind": "text"}}}, + "PF-W1549": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: its expression calls {label}.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}, "label": {"kind": "text"}}}, + "PF-W1550": {"severity": "warning", "area": "support", "message": "{call}: no data is pinned for this request; the run stops with an error where it is evaluated.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Its value can reach a trade: its expression calls {ns}.{name}.", "explanation": "PineForge loads no other symbol's lower-timeframe bars, and this request's value can reach a trade, so the run stops with an error where it is evaluated.", "args": {"call": {"kind": "identifier"}, "ns": {"kind": "identifier"}, "name": {"kind": "identifier"}}}, + "PF-W1551": {"severity": "warning", "area": "support", "message": "{call}: its symbol can be another symbol''s, whose lower-timeframe bars PineForge reads from the chart.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "The request.security_lower_tf symbol can be another symbol, but PineForge only has the chart's lower-timeframe bars and reads those, so results can differ.", "args": {"call": {"kind": "identifier"}}}, + "PF-W1552": {"severity": "warning", "area": "support", "message": "{call}: its symbol can be another symbol''s, whose lower-timeframe bars PineForge reads from the chart; its value reaches only display/alert sinks, so trades are unaffected.", "hint": "PineForge loads no other symbol''s lower-timeframe bars. Every reachable symbol value must resolve to syminfo.tickerid or syminfo.ticker for exact results.", "explanation": "The lower-timeframe request may name another symbol but reads the chart's bars; its value only feeds plots, alerts or tables, so trades are unaffected.", "args": {"call": {"kind": "identifier"}}}, + "PF-W2001": {"severity": "warning", "area": "analysis", "message": "Untyped parameter ''{param}'' of callable ''{callee}'' receives {shared} and {incoming} at its written calls; a copy per call path would exceed {max_family_variants} copies and four per written call, so PineForge types it {shared}, as its first call, and converts the other argument. Declare the parameter type to choose it.", "hint": null, "explanation": "An untyped parameter receives two argument types and one copy per call would be too many, so PineForge types it as the first call's; declare the type to choose.", "args": {"param": {"kind": "identifier"}, "callee": {"kind": "identifier"}, "shared": {"kind": "type"}, "incoming": {"kind": "type"}, "max_family_variants": {"kind": "number"}}}, + "PF-W2002": {"severity": "warning", "area": "analysis", "message": "Untyped parameter ''{param}'' of callable ''{callee}'' receives {current} and {candidate} through calls that share one written-call variant (cs{cs_idx}); PineForge types it {current}, so the other argument is converted. Declare the parameter type to choose it.", "hint": null, "explanation": "An untyped parameter receives two argument types through calls sharing one variant; PineForge types it by the first and converts the other, so declare the type.", "args": {"param": {"kind": "identifier"}, "callee": {"kind": "identifier"}, "current": {"kind": "type"}, "candidate": {"kind": "type"}, "cs_idx": {"kind": "number"}}}, + "PF-W2003": {"severity": "warning", "area": "analysis", "message": "(...)[...] reads an element of the selected current array in PineForge: no history of a selection is kept, where TradingView reads the array it selected that many bars back.", "hint": null, "explanation": "Indexing a selected array with [] reads the current array, since PineForge keeps no history of selections; TradingView reads the array from that many bars back.", "args": {}}, + "PF-W2004": {"severity": "warning", "area": "analysis", "message": "input.source defval is not a native chart series (open, high, low, close, …); complex indicators or expressions are not supported in PineForge.", "hint": null, "explanation": "input.source needs a built-in chart series such as close as its default; indicators or other expressions are not supported in PineForge.", "args": {}}, + "PF-W2005": {"severity": "warning", "area": "analysis", "message": "input.timeframe defval ''{defval}'' is not a typical Pine timeframe string.", "hint": null, "explanation": "The default of input.timeframe is not a usual Pine timeframe string such as 15, 1D or W; check its spelling.", "args": {"defval": {"kind": "identifier"}}}, + "PF-W2006": {"severity": "warning", "area": "analysis", "message": "input.session defval ''{defval}'' may be invalid (expected e.g. ''24x7'', ''0930-1600'', or weekday flags).", "hint": null, "explanation": "The default of input.session may not be a valid session string; use forms like 24x7 or 0930-1600, optionally with weekday flags.", "args": {"defval": {"kind": "identifier"}}}, + "PF-W2007": {"severity": "warning", "area": "analysis", "message": "input.string defval is not among the options list values.", "hint": null, "explanation": "The default of input.string is not among its listed options; choose a default that appears in the options list.", "args": {}}, + "PF-W2008": {"severity": "warning", "area": "analysis", "message": "input.enum defval {ename}.{emem} is not a member of enum {ename}.", "hint": null, "explanation": "The default of input.enum names a member the enum does not declare; use one of the enum's own members.", "args": {"ename": {"kind": "identifier"}, "emem": {"kind": "identifier"}}}, + "PF-W2009": {"severity": "warning", "area": "analysis", "message": "input defval ''{name}'' is not a known chart series (open, high, low, close, …); verify spelling or use a series variable.", "hint": null, "explanation": "The default of this input is not a known chart series such as close; check the spelling or use a series variable.", "args": {"name": {"kind": "identifier"}}}, + "PF-W3001": {"severity": "warning", "area": "request-security", "message": "request.security timeframe reads ''{name}'', which the script reassigns: PineForge registers every request before the first bar, where it holds its initial value, and cannot compute it there (''{where}'' {reason})", "hint": null, "explanation": "The request.security timeframe reads a reassigned variable PineForge cannot compute before the first bar, so the request uses its initial value.", "args": {"name": {"kind": "identifier"}, "where": {"kind": "identifier"}, "reason": {"kind": "vocab", "values": ["is assigned a value it cannot compute there", "is assigned after the first request", "is not a scalar int, float, bool or string", "is not declared at the top level"]}}}, + "PF-W3002": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', a parameter of ''{helper}'' whose argument PineForge does not recompute on the requested bars: it reads na", "hint": null, "explanation": "A request.security expression reads the history of a function parameter PineForge does not recompute on the requested bars, so the read gives na.", "args": {"name": {"kind": "identifier"}, "helper": {"kind": "identifier"}}}, + "PF-W3003": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', a parameter of ''{helper}'' whose argument PineForge does not recompute on the requested bars: it reads the global ''{name}'' instead", "hint": null, "explanation": "A request.security expression reads the history of a function parameter PineForge does not recompute on requested bars, so it reads the same-named global instead.", "args": {"name": {"kind": "identifier"}, "helper": {"kind": "identifier"}}}, + "PF-W3004": {"severity": "warning", "area": "request-security", "message": "request.security payload calls function ''{callee_name}'' on the chart''s bar: a payload inlines a function under a builtin call only when its body is a single expression and so is every user call it makes, directly or through a global''s value; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A function called in a request.security expression runs on the chart's bar, since under a builtin call PineForge inlines only single-expression functions and calls.", "args": {"callee_name": {"kind": "identifier"}}}, + "PF-W3005": {"severity": "warning", "area": "request-security", "message": "request.security payload calls function ''{callee_name}'' on the chart''s bar: a payload inlines a method on the requested bar only for a scalar receiver and arguments and a single-expression body reading no mutable global, whose user calls, directly or through a global''s value, are single expressions too; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A user call in a request.security expression runs on the chart's bar, since PineForge inlines a method on the requested bar only for scalar, single-expression cases.", "args": {"callee_name": {"kind": "identifier"}}}, + "PF-W3006": {"severity": "warning", "area": "request-security", "message": "request.security payload calls function ''{callee_name}'' on the chart''s bar: the evaluator cannot inline it ({reason}); TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A function in a request.security expression runs on the chart's bar, not the requested one, because PineForge's evaluator cannot inline it for the stated reason.", "args": {"callee_name": {"kind": "identifier"}, "reason": {"kind": "text"}}}, + "PF-W3007": {"severity": "warning", "area": "request-security", "message": "request.security payload calls method ''{callee_member}'' on the chart''s bar: a payload inlines a function under a builtin call only when its body is a single expression and so is every user call it makes, directly or through a global''s value; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A method called in a request.security expression runs on the chart's bar, since under a builtin call PineForge inlines only single-expression functions and calls.", "args": {"callee_member": {"kind": "identifier"}}}, + "PF-W3008": {"severity": "warning", "area": "request-security", "message": "request.security payload calls method ''{callee_member}'' on the chart''s bar: a payload inlines a method on the requested bar only for a scalar receiver and arguments and a single-expression body reading no mutable global, whose user calls, directly or through a global''s value, are single expressions too; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A method called in a request.security expression runs on the chart's bar, since only scalar, single-expression methods are inlined on the requested bar.", "args": {"callee_member": {"kind": "identifier"}}}, + "PF-W3009": {"severity": "warning", "area": "request-security", "message": "request.security payload calls method ''{callee_member}'' on the chart''s bar: the evaluator cannot inline it ({reason}); TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A method in a request.security expression runs on the chart's bar, not the requested one, because PineForge's evaluator cannot inline it for the stated reason.", "args": {"callee_member": {"kind": "identifier"}, "reason": {"kind": "text"}}}, + "PF-W3010": {"severity": "warning", "area": "request-security", "message": "request.security payload keeps its user calls under builtin calls and its methods on the chart''s bar, as before: {message} (line {line}); TradingView evaluates them on the requested bar.", "hint": null, "explanation": "PineForge keeps this request.security payload's user calls under builtin calls and its methods on the chart's bar, for the stated reason, unlike TradingView.", "args": {"message": {"kind": "text"}, "line": {"kind": "number"}}}, + "PF-W3011": {"severity": "warning", "area": "request-security", "message": "request.security payload keeps its user calls under builtin calls and its methods on the chart''s bar, as before: {message}; TradingView evaluates them on the requested bar.", "hint": null, "explanation": "PineForge keeps this request.security payload's user calls under builtin calls and its methods on the chart's bar, for the stated reason, unlike TradingView.", "args": {"message": {"kind": "text"}}}, + "PF-W3012": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{name}'', an element of a tuple declaration, on the chart''s bar; TradingView reads it on the requested bar.", "hint": null, "explanation": "A request.security expression reads the history of a tuple-declared variable on the chart's bar, where TradingView reads it on the requested bar.", "args": {"name": {"kind": "identifier"}}}, + "PF-W3013": {"severity": "warning", "area": "request-security", "message": "request.security payload reads the history of ''{object_name}'' under a builtin call on the chart''s bar; TradingView evaluates it on the requested bar.", "hint": null, "explanation": "A request.security expression reads a variable's history inside a builtin call on the chart's bar, where TradingView evaluates it on the requested bar.", "args": {"object_name": {"kind": "identifier"}}}, + "PF-W5001": {"severity": "warning", "area": "codegen", "message": "strategy(use_bar_magnifier=...) is not a literal bool: the generated strategy does not declare the bar magnifier, so a host runs it without one.", "hint": "Write use_bar_magnifier = true or false.", "explanation": "Write use_bar_magnifier as a literal true or false; any other expression is ignored, so the strategy declares no bar magnifier and the host runs without one.", "args": {}}, + "PF-W5002": {"severity": "warning", "area": "codegen", "message": "input key ''{key}'' is shared by the inputs at {spots} and {spots2}: PineForge sets an input override by its title, else by the name of the declaration holding it, so one override sets all of them.", "hint": "Give each input its own title to override them apart.", "explanation": "Several inputs share one override key (their title, else their declaration's name), so one override sets all of them; give each input its own title.", "args": {"key": {"kind": "identifier"}, "spots": {"kind": "text"}, "spots2": {"kind": "text"}}}, + "PF-W5003": {"severity": "warning", "area": "codegen", "message": "array.slice returns a copy in PineForge; TradingView slices share source elements, so writes through either array can diverge.", "hint": "Avoid mutating a slice or its source while the slice is used.", "explanation": "array.slice returns an independent copy in PineForge, while TradingView's slice shares elements, so avoid mutating a slice or its source while both are used.", "args": {}}, + "PF-W5004": {"severity": "warning", "area": "codegen", "message": "A {kind} is stored as a 32-bit int in PineForge; this value can exceed int32, where TradingView''s int is 64-bit, and is truncated (or read as na) there.", "hint": "Declare the values float to keep every digit.", "explanation": "This collection element is stored as a 32-bit int, so a value beyond int32 is truncated or read as na, unlike TradingView's 64-bit int; declare the values float.", "args": {"kind": {"kind": "vocab", "values": ["map<..., int> value", "matrix element"]}}}, + "PF-W5005": {"severity": "warning", "area": "codegen", "message": "An {kind} is stored as a 32-bit int in PineForge; this value can exceed int32, where TradingView''s int is 64-bit, and is truncated (or read as na) there.", "hint": "Declare the values float to keep every digit.", "explanation": "This collection element is stored as a 32-bit int, so a value beyond int32 is truncated or read as na, unlike TradingView's 64-bit int; declare the values float.", "args": {"kind": {"kind": "vocab", "values": ["array element"]}}}, + "PF-W5006": {"severity": "warning", "area": "codegen", "message": "na() of a string reads the empty string as na: PineForge stores a string na as \"\", so an authored empty string is na here, while TradingView tells the two apart.", "hint": null, "explanation": "na() of a string treats the empty string as na because PineForge stores a string na as an empty string, so an authored empty string reads as na.", "args": {}}, + "PF-W5007": {"severity": "warning", "area": "codegen", "message": "str.repeat is missing its count argument; PineForge emits an empty string for this invalid TradingView call.", "hint": null, "explanation": "str.repeat was called without its count argument, which TradingView rejects; PineForge emits an empty string instead.", "args": {}}, + "PF-W5008": {"severity": "warning", "area": "codegen", "message": "str.repeat count can be na: PineForge returns an empty string for that value, while TradingView returns na string. The engine has no nullable string value.", "hint": "Check na(count) before calling str.repeat when the result affects strategy logic.", "explanation": "str.repeat's count can be na; PineForge then returns an empty string where TradingView returns na, so check na(count) first if the result drives logic.", "args": {}}, + "PF-W5009": {"severity": "warning", "area": "codegen", "message": "session.{member} inside request.security keeps the time-of-day predicate at the security bar''s open time, which can differ from TradingView: {opens}a D/W/M bar, {daily} on TradingView, reads its open''s time of day. The chart''s own session flags read the engine''s session facts.", "hint": null, "explanation": "A session flag inside request.security is tested at the security bar's open time, which can differ from TradingView, notably for D/W/M bars.", "args": {"member": {"kind": "identifier"}, "opens": {"kind": "vocab", "values": ["", "a bar that opens in a session break and holds the reopen reads as out of market, and "]}, "daily": {"kind": "vocab", "values": ["always in market", "never post-market", "never pre-market"]}}}, + "PF-W5010": {"severity": "warning", "area": "codegen", "message": "{object_name}[...] reads the current {kind} in PineForge: no history of this parameter is kept, where TradingView reads the copy the call that many calls back left (fixtures/array_history_tv ahist_fn).", "hint": null, "explanation": "Indexing a function parameter's array or matrix with [] reads the current collection in PineForge, while TradingView reads the copy from that many calls back.", "args": {"object_name": {"kind": "identifier"}, "kind": {"kind": "vocab", "values": ["array", "matrix"]}}}, + "PF-W5011": {"severity": "warning", "area": "codegen", "message": "{object_name}[...] reads the current {name} reference in PineForge: no history of this variable is kept here, where TradingView reads the reference it held that many bars back.", "hint": null, "explanation": "Indexing an object or drawing variable with [] reads its current reference in PineForge, while TradingView reads the reference it held that many bars back.", "args": {"object_name": {"kind": "identifier"}, "name": {"kind": "type"}}}, + "PF-W5012": {"severity": "warning", "area": "codegen", "message": "{kind} history indexing uses the current collection element in PineForge; the engine does not retain per-bar collection IDs, so this result can differ from TradingView and a missing index is not represented faithfully.", "hint": null, "explanation": "History indexing of an array or map reads the current element, as PineForge keeps no per-bar collection history, so results can differ from TradingView.", "args": {"kind": {"kind": "vocab", "values": ["array", "map"]}}} + }} diff --git a/tests/fixtures/diagnostic_notes/delta.json b/tests/fixtures/diagnostic_notes/delta.json new file mode 100644 index 0000000..4891b47 --- /dev/null +++ b/tests/fixtures/diagnostic_notes/delta.json @@ -0,0 +1,63 @@ +{ + "status": "FROZEN: user_message is an existing-args template; APP-TOP approval relayed through TOP and WIN-CX", + "allowed_added_fields": [ + "user_message" + ], + "severity_changes": { + "PF-W1505": { + "before": "warning", + "after": "note", + "user_message": "This EMA may need more earlier bars to initialize." + }, + "PF-W1508": { + "before": "warning", + "after": "note", + "user_message": "{name}() does nothing in a backtest." + }, + "PF-W1509": { + "before": "warning", + "after": "note", + "user_message": "{full}() does nothing in a backtest." + }, + "PF-W1525": { + "before": "warning", + "after": "note", + "user_message": "Display-only corporate-action data is unavailable for {call}." + }, + "PF-W1526": { + "before": "warning", + "after": "note", + "user_message": "Display-only corporate-action data is unavailable for {call}." + }, + "PF-W1527": { + "before": "warning", + "after": "note", + "user_message": "Display-only financial data is unavailable for {call}." + }, + "PF-W1528": { + "before": "warning", + "after": "note", + "user_message": "Display-only financial data is unavailable for {call}." + }, + "PF-W1529": { + "before": "warning", + "after": "note", + "user_message": "Display-only footprint data is unavailable for {call}." + }, + "PF-W1530": { + "before": "warning", + "after": "note", + "user_message": "Display-only footprint data is unavailable for {call}." + }, + "PF-W1531": { + "before": "warning", + "after": "note", + "user_message": "Display-only symbol data is unavailable for {call}." + }, + "PF-W1532": { + "before": "warning", + "after": "note", + "user_message": "Display-only symbol data is unavailable for {call}." + } + } +} diff --git a/tests/fixtures/diagnostic_notes/diagnostic_codes_pin.legacy.json b/tests/fixtures/diagnostic_notes/diagnostic_codes_pin.legacy.json new file mode 100644 index 0000000..95e2813 --- /dev/null +++ b/tests/fixtures/diagnostic_notes/diagnostic_codes_pin.legacy.json @@ -0,0 +1,634 @@ +{ + "note": "Each code's meaning, pinned: a code is never removed or repurposed (tests/test_diagnostic_codes.py). scripts/gen_diagnostics_catalog.py --write pins new codes; never edit a line by hand.", + "codes": { + "PF-E0000": "3303a72fb4a697c60229aa4df7bae3acd712f6b37461a667ad0d2a052375ea40", + "PF-E0001": "29c9dd2bfdf64fc925e41a81a5fb07db9502500ea30c2e61ac44d5f39901acc1", + "PF-E0002": "36990d22db401d89c7a815e8e77e617b82f4651d78703a2a93956c9d879e87da", + "PF-E0003": "b83fd5bb5cc41388d7f1c11c05d179619e37462a7a2c8542a97e0f63a2ade00e", + "PF-E0004": "1616ea93f84b452761852af4961044b0232cb94b540873e5d069d34ce31455b5", + "PF-E0005": "abcd916fe7d3e16854554c841d8b9436e9572c17d8ea4a2b2861257e5f2ad1ff", + "PF-E0006": "f81600b8577abc42c8a858dc5b6b791c2d374f58c372e85ec532d5c3f3a1b53c", + "PF-E0007": "210b5660f1f992d71c31990a21e595095cb58e5e54bcd039cb619c126860ba51", + "PF-E0008": "6d9f5393c4534eb181f85afb34c5874705badab92a72fc34151223b70c50893d", + "PF-E0009": "f32e34c0a0a97a54299840e781ea7751c56ead6082f67e0df522391e170302b0", + "PF-E0010": "2234e279fdd806dfe1c97ebca47788ffd544b9d4ae3bdfeded8f615053498f87", + "PF-E0011": "4a72e9264dd3f89defd2e150ce9a8d8d9fdeae13b4277e202ed3b69d542b4777", + "PF-E0012": "ffc14241b3262c862d27d0f869918a20145bdf6b31b456f221dadcdcaaaaba2c", + "PF-E0013": "ee19b8fd08fd017a1a0d7d00fac32d8a2bef1b0b31d25fa91acc32aebd8f50e6", + "PF-E0014": "4c6420930cd06757e390b7714f48dd78d4e6a3528fc4d6114cd84da4aa05bf78", + "PF-E0015": "2300fb466d7ee168e3ea3de5d3eb19c45d239cd2b6b5503b169201c9528ae7a0", + "PF-E0016": "3049ec1ad1c8981dbeaa6024a2cff418c845c7bd21171c9e8ee0c80d349266ab", + "PF-E0017": "c8ae91a95af3d8136f020b8f177d9fde9938b6ec377ad380cc66883aaefaa596", + "PF-E0018": "507fd91137005a49351ba64609c9810ced13f0c94ece57b7dbf699bb50f358b6", + "PF-E0019": "ad1b95bbde239b797e173e5836712db42224ac99e724a7e6d829bf59e2824dd3", + "PF-E0020": "c4552d1d5b68b83429ebe51ccc784d51330a8ad7e48f0b5fd027012ea0b8d51b", + "PF-E0021": "372b5c00cbe1588b2e9fc043ea1cb78b99873b0e4c3a0385fb0ca22275807f68", + "PF-E0022": "ef27748eb4f5dcfc5bd2afddc24d53a08f16909943024efc88f96910447c9099", + "PF-E0023": "099aa2cc655d3e567b8a24510e359143fe64b7b9426fc7b098d94d1d6745134a", + "PF-E0024": "1fb1c8e85e86cfce0e7005a991b086fcb58d9a4e1f387d6b493b0212a98f2007", + "PF-E0025": "f6a6e747efb4556ba5eec94bf0311b319164b89617d1032fcdfd17dc1a7b125e", + "PF-E0026": "e16a5cc563fc3de1ed9676bac5f9499331b65299b8f14f37b1753291fd627a0f", + "PF-E0027": "d01364c87572de29e4b12d6845e4df24ad6ba46bd5087dfb458cc68f8f20ab29", + "PF-E0028": "822d6e1a6fed818f03de1b962dc9710eeae3099908b705306cfa77d7d9e5066d", + "PF-E0029": "fa4fde3e86d94d3d7c67a9d6cd4e4dbef184e5ccc8fca3bef285985d8f795db1", + "PF-E0030": "b7e6be364706546d82908ec49b6eb7a890ff7a0fc5dc358924e93f4f21c5f108", + "PF-E0031": "e7dc8694d8e2ce048d0de8e9ffb1b8e3439282c7554ce1b4a35161f74a4c863f", + "PF-E0032": "3157b077ee2856ad64a16ce89d182b43862ca59e9ebf233786d90e26d828ff81", + "PF-E0033": "06a36eb14950b1385c3d083d8940d38ad288c74531f845fa825d9134892d7de1", + "PF-E0034": "6b77657d71442fd9723f72856cd6fdc1a7b9e2d868ea83d8d06b83361f4ab073", + "PF-E0035": "c161306f62b0446d8e296dce48030c5831a6263bac67031e9ea0469fdf7c70a0", + "PF-E0036": "9796a21f482d814a51886c4b64e6cd069c409fb95997b2398c76afef78b6f4f5", + "PF-E0037": "2b0c8a85e42b7c601dd8d581793ea66b2aa43d421b63bc040e1b06d6d79ec97b", + "PF-E1001": "1bed9afb69614235acc3e9508a5191e19494bf664a4e2936298eb7f2e7a69957", + "PF-E1002": "9d6ed241629fbbc3efc7d3968246ee246974c294e727713df03a6c8284c0508f", + "PF-E1003": "b5bb7f7fab047bff1014739e2f9154986a69f325c936adc81c9d70606f21ab98", + "PF-E1004": "51b3e5484f965c5d956ad93f6fbc48e953dbbd8d82998a651ef64a35a13085e1", + "PF-E1005": "22e8be2a13c7cf5c3afa1b7c60983965a633b1baa0aa34f8ef0596a02294d849", + "PF-E1006": "437f348f804e641a56477fdc5a74faf47a331f6e96c15e32fd9720dcbb26a630", + "PF-E1007": "1b6402b558b5487ea6c418596ba923d30af47022a725b8b56adb421dbb12d482", + "PF-E1008": "33ff0698e0004b33429da9c831170e16019686aac8c1b422402ee12fded36960", + "PF-E1009": "173b4dfba927a43e065cf2fcb1dd7db6aa12f4e077e65a3c257aaf90ce70933a", + "PF-E1010": "4d4cda0a6b41e201ec1ff3c7006466e3b7b014735a39b275057a787b7ca3abf3", + "PF-E1011": "fa17a79d979caa9ca025e07278bf66c3c29fe81ee8d115c20aad3e118e06d8ec", + "PF-E1012": "c39586601bb38ada0cec8ef66ff83c370d5b5b6125d7647ff6933484407f097c", + "PF-E1013": "e301533861f3354b2e2cd2a82a7cfe9c952841a37ccf94d269096ad1f2d12fc8", + "PF-E1014": "70fa8e94a796e070b45801f40e8e501f08118e00fd92735fb176521e52aa6d7a", + "PF-E1015": "fd490d92ad548a814db8edf6082b0ed7bc275666c1ae8aebd4df4c1570042d07", + "PF-E1016": "458e9536182df4330f09348eae00b5ac70a9e2af69842a82157406cd3b6f590e", + "PF-E1017": "858385946e624c55bd0e59955329f8a141bb6a88ce780f61d5fd2367eb6deeac", + "PF-E1018": "64b1465d3acdca716809e388a3aeb1400cb6f1aae761c298ced07072bfecfcef", + "PF-E1019": "48f02152ba040e1266e242389f3ed03941340fe674c86d11e932ac0042572467", + "PF-E1020": "a1f7e47fd2465c00984bee8e1527e659e3e249916aa2e658d184bd792a4d14a7", + "PF-E1021": "3698fa26cf92549fc38ceb4982c8b2d4d0e42f8c938be4022311188476a478b7", + "PF-E1022": "8588b893f175392e0b7eb9e24f5a56ae2bea040e0996e6456ee215205de896cc", + "PF-E1023": "bce1bb8175fe931513ced732855122dbc46b96fac5141c100599d5b77c8969af", + "PF-E1024": "679188aac383acfdc5162b1ce3d9ac78aadad347a2340c6281c318c373c9b897", + "PF-E1025": "5bc73b96e7e3b4a9783d7d183f2d9900a1080d024a679000c3aecb24e6d2ac81", + "PF-E1026": "764919ee132b32e651d1a38e5e8f98ea7a0196339fffb1e225401b91d54bf54d", + "PF-E1027": "5664466bca10822dc7efae605d6b53bd3b934e092ff000df6950eff7acf63688", + "PF-E1028": "20b465aa8b748c16cf87f240819a58bb8e1708781e56d2d3d822b47553ad4457", + "PF-E1029": "9aa2efd2266155b64432feb1adbf72af692a7ebf3e70cc61077911ec05f1c7d1", + "PF-E1030": "37069bc589799b7d203a2e45d87849467ba044ec9752e859def214278db1f1de", + "PF-E1031": "404c4a0c840768896e5cc8c0fc77927e7adeda8175e78612f8a31b078eafd130", + "PF-E1032": "c2d1f32850bce4e5e400d3495682cb7662ab9efb67b16fde62da57a8bfcfbcc5", + "PF-E1033": "d94a27292287e167797cdf87e3aa73d7242e293df553ccb9db6fa3e417866b1b", + "PF-E1034": "535f42ca9296137c6cc570654ccd6ba30d0f3a5105cc730efd6a863b40f8cab6", + "PF-E1035": "3c57912dbd899cd6e922f08843ae1d24e642ec132dd7932a0be2ebaccff517f3", + "PF-E1036": "15f9bd1f1d29b0fd9302f581bb6cfff4e9bdf8a4b256974fdd3ead3b8f83a4a6", + "PF-E1037": "b76e22f251a0cb1d7ab39d5d073611fb05559a54b0546e206cfae4dc0fc203f6", + "PF-E1038": "8e6bef18dc20184c696fc0bab1fbd3cfc60abaabc64f2528f00605b4f4844ffd", + "PF-E1039": "2476b79e61e40a6685433f3bd4f76dc0570e1432366ce219f8036573e13ba10f", + "PF-E1040": "cb3a20c4bb51a88303ae9d49e2a5ac81cb3b6b5e5f7ca8c39f3ce08a8ebfb3cb", + "PF-E1041": "ff9e464d9a2c652f54db5b7567b77727c9e9c2818c7430a9c457f5aef96d94d2", + "PF-E1042": "bc3847b2cb22490d3480bd0139eb86a549bccde7d87f112bab75f16eb9655fb1", + "PF-E1043": "f36786bbbb28805e6a0551837851e7e76dae525b774c2277079077d4f42a3302", + "PF-E1044": "77b75f585c908c82ecb2efd1e32d6f22285f25500129a7676d8312c678b6902f", + "PF-E1045": "3a200af246d0b0ced5e6b59498efff32b462a0a79ccde83131af2c51ff4b3ac9", + "PF-E1046": "bf065b22d86c924f17c13b29f32b4aabdd65fe01d1f475559f54e17ebce06cae", + "PF-E1047": "a40d392da18f8fe6a15ab2e6bf752789501701638e729619e4d29f4a3442e724", + "PF-E1048": "929a1e9c5608d25cda73c60af38ca72115bb0fedb4e746a95d49dc87b10878d1", + "PF-E1049": "ae892e48c09c3ed4cc1ad29311d133bcfa9736fbe6042d1455fc1ce2640330e3", + "PF-E1050": "b5dbf9eb16770628b035d6a352be4c18eb32b4106cad185af2b87a65d6360d37", + "PF-E1051": "d20276d20e738e46baaa339e413fd92516e831673a0128963514702df4cc9b6f", + "PF-E1052": "0eead5cd442efea5f23a1ad5c7ac658bc1b440dc488b205ae960ab111d3b0f37", + "PF-E1053": "9c08971e4ca1bf7318cd1741c26f8766f0c2cac3a107000fcf6d5e78750da26a", + "PF-E1054": "d9aebb93769ff9f111f081cef1373923613f9f06e24dedc4f224dff68ed8313f", + "PF-E1055": "145414ca24f9caff188be99fde48927c67481434397ddffc081156e10fffdcc4", + "PF-E1056": "e105f547ca0ffa7e3df825f5a715bc1d05252166435e8ae0a1a97c2dbfd635bd", + "PF-E1057": "bdb97a4cd5ac96bdc11c862b6c9a2e4e70a7db2a4f963b26e785a16e5b54cab9", + "PF-E1058": "56dd32f3829d5385dde5244a1a90aeda233032dd5a06724dc8150763b9cf4f99", + "PF-E1059": "1179765dfc36619a0510270fe598186de9330af8534444cf13bb1ca8b4901b84", + "PF-E1060": "90862bd9768a41c6b07c66dc2670cc8e9930cd77a366e2ec6122d129919262a2", + "PF-E1061": "5553514226b4e30917f3dc1fffc22ebbf7d5dff30efdfcfde514a8021a5e489b", + "PF-E1062": "72a442b2ffcff2a108a32f4587e776c1ecdf45df039f7ed828d5375323ec675e", + "PF-E1063": "5c640b6d92bd3ec34f6e99e7f7e678fa8d54201665a46d80c77c1a6a946bd14f", + "PF-E1064": "59198c7b49e30690b69c087331d1c4f5d178c8711fb8f868715dfeefe0caec84", + "PF-E1065": "8b1b041e967baef61789ba92168063ef212e97de06ddc233291993cee36123c8", + "PF-E1066": "42dbc247b2b77d8b49f55bd358c06f6bbadb8ed6e517f63f84f061c60b399ee6", + "PF-E1067": "a1f9c954532f20f7e762e6998be2a98b43ddf9ed261c4e7c6dfffdf8aeedee54", + "PF-E1068": "2e7a534c1082989cbe4645f4257e6e58e77f4675fc5489e78d79ed7f83da14c9", + "PF-E1069": "3f215b252d9479aeb7a710778294258360a9b8cffc7da5631f60432da3b830b6", + "PF-E1070": "b6831c4fd31600e9aecf5540afb5362f68318ca3aef0789248fae3ff020e343f", + "PF-E1071": "ccdf791c46e739e190597e6f2b2e433098a597d10e55d378f69eb2c8c1c3a484", + "PF-E1072": "27d7e531c1a6b4ad4ddd794ce1a150e57abb55053e271596abd357b3a33fa864", + "PF-E1073": "b6599c5e23e9de1a60590ddbe4de0a1d4ba5a4ef36cc267a3933d0c62352aa26", + "PF-E1074": "73e41717c8b7630d8132691cf5867ddac80fb008c31630fb71ad765ebe3fe010", + "PF-E1075": "d0062fb698e43045a8c6866ef2b57436aff835b08c841fa842694d59ec1a5911", + "PF-E1076": "290880d06826cc1edb9ea055c4331f5cbf48789d2a41b33de3ec2b78c694f548", + "PF-E1077": "5d72fb258c8977b05f4675b0bf403fd9d444b193a40a6e2fbf81f122b20f1935", + "PF-E1078": "41e0d6d76295257c06ffde6e4597290ce685d83c062b1d2284be72c038d603cb", + "PF-E1079": "c332589a012c6abf43d1fe975caa6b7280fde4c2342b94635a7828cb73a495d1", + "PF-E1080": "d8498a80cbc979d85813f0b4dd7e235779fbc1e9390c590acb012276c175a5e1", + "PF-E1081": "3509dcaefa46ea1397a3082ead0f0ac8aee5ea9798a85d95998b5e01219744f8", + "PF-E1082": "def7e36f522cf9a1444b22493040fdd43b04a5b85e8ee2723764f0ea788533d2", + "PF-E1083": "92a73c19f401e96e028dad397421e6ab5ecc3fb29c9b20e353bb144151771fa8", + "PF-E1084": "34a5509dcff63e3f60db49caa603e3998f436dcb9a955e23121c46d1aa583aca", + "PF-E1085": "a19299b5d7cc970dd325a7a4063a14ee67ea3b890e1b3508ad04d3cb8036769f", + "PF-E1086": "413662092933423f190920300b0fda36c90cf155925f505c7744941085483988", + "PF-E1087": "684d95fc2b64d892837a557753d51c09ae3efc22ef26d5909bcf77e61f616c32", + "PF-E1088": "44d462e966b0e13484b2a90ec78080342773249d29ae2d01f83c298a8149b24c", + "PF-E1089": "874465bf1340ce9975cc461a896157178e6322a1eb5de2701529e1f7299dfb88", + "PF-E1090": "d9918762788990ac9654cf27faad21ef01ea76a951332fca0bccad79970b5517", + "PF-E1091": "21f37b95b0ea5b60015cfcf0146d8637ac82781ed823a2984ce08bc1ecb4b66e", + "PF-E1092": "bb6d80f38d438415b2c97f14bdb1f2b53789062c5df00584c247fe055c7d2671", + "PF-E1093": "25f723dd14de607e9d4043e132eede221a95fec1fc82f15399cffee435af6c5a", + "PF-E1094": "422815b4e44dd125dcfee488472288f116938a442404594623d1f19151b8f1ed", + "PF-E1095": "2ddeba7d392fb7ec5a8604554ad2513dc611f3c4ae80d1018433984c52bc6c81", + "PF-E1096": "d79acecc8126afe5f42b06ea07b2831a66e60caa44e958a22a9b4767de0c26ba", + "PF-E1097": "43c81f56957a39ecffde08c686c24d0534279ef22d031d1c1493a8920820337e", + "PF-E2001": "fa5a3e66b03da2eb1e43410c56925b3b3279009ce9f5dacd9bd0d57687f21c00", + "PF-E2002": "db6538bbf69995ea3d5c5c502f44820ff19a43d57bbd5c148ff975a00596c184", + "PF-E2003": "4b389b9f153243dedd087ae7c4c7aa009f9c3c8ec80bc12572e6fd477b48485d", + "PF-E2004": "d1283530f053a45311f1f9fecdd48f1c019b0c77d74591f8ccde64422ca70583", + "PF-E2005": "17be7493735ae53a7f0187a852b4d8944f97b326be3e05a0a27f0761960f06b3", + "PF-E2006": "71f69c37fd3e02047aefc8d261802ab09630d3518e3e0b84f5a35e79faabdf94", + "PF-E2007": "cfe579ed93ebb0bd4043168a8a781cc3bfad8f773205a95b34e6a4d17bd9b253", + "PF-E2008": "daa1fa9753ab6c66cb044156a4c680da03ebb4232e95ad60c239a5ce0b3d5578", + "PF-E2009": "3b881f66bc60ed536c0df01f2b230f1942d99db4fbdd733bc7a073871880bb4b", + "PF-E2010": "d1fe014b3699158ef4c1dd8cece1e3d420f221e835a7bb6bf75c709168e785ab", + "PF-E2011": "5936dde0794e96b6ab8597b67473266afc41e73fda2517a155214d82765783f0", + "PF-E2012": "a624c4ddcfbd48e57b56328d89cb4108c958d396b6ddd63deed1f982b54caf9c", + "PF-E2013": "7ab67198d640b26abbb6f4986f1414829a95571d93900c0ebea98e1b6b8e3f06", + "PF-E2014": "9718d91092ca36df191c533a3a7e7559bc6d3252964617294dd648d2b4f081fc", + "PF-E2015": "87fe6f364e055e9005fb5dd420c2297000bfc171148a5ac81e660b2864951433", + "PF-E2016": "17c05596dc90f912218c0592d3243f3f5330083a828d896abc2760ea54d23fb6", + "PF-E2017": "f588cd1b987f90331573f9faccd913d07ccd01434da07de3b0ea7954365c10e0", + "PF-E2018": "f2562b41b8639bb7b3d68199dd18ca91517ac2931862304b9631ecc21ee1ab51", + "PF-E2019": "85aac7b45d2dc36bec00e7e3f0a6656c772603bab8a15918f0c84d814317af28", + "PF-E2020": "f29c8e63d7717094f37fa288da9ccc9c9d5afe0fac8027c300dbc0188ac44b13", + "PF-E2021": "0e4e8a3d48069fca02d0ad72ed468a36f3265d70f70eda2dee01162acc1b93f0", + "PF-E2022": "61c8cd9ea7a63e8c3ae303da9b4004f3a77b90a9ee2c6e1245dd45fa4d435177", + "PF-E2023": "0a3a72379e6d10a44382fecd3c1e871eb258926707362525ec27db5f6a456ff7", + "PF-E2024": "9d9d1d4c1e2a2cf3d5c2bc6ea5fde3ae61aecac28a24b9078726b652186b9896", + "PF-E2025": "0e56b50a4612a96e7bb1c57b10c406f11287ab6c81172533ad9ca15f3372b603", + "PF-E2026": "25efdb79e27561c66b201f530352e7ce5604770de4baf4d0e5771935de7f6fc9", + "PF-E2027": "97d497fb95ae41955206393a4e2ef7b816710f3c10480b93180d6c312459517a", + "PF-E2028": "89b597d48b73067a478336b754a6acd0664f45a42d97f6e40dcb3850920c3022", + "PF-E2029": "122dcb39d7fe0a5df448c1cf5c3f73025ebc4c6965ce18e6386b65a5c2bfe131", + "PF-E2030": "4ab4347203caf6d00258fb58782f2e7b80420dd523cd06df5598af14be996f47", + "PF-E2031": "eaa4dac3780ade5ee62eef9ee9b4ec056999ddf30d308918e5ab32d4013a469d", + "PF-E2032": "3d329fe8079b275e840c39272afb11e4aaa5a52505188b9b48abf4071f09484b", + "PF-E2033": "efbc7a86f3a9da674c796caeff4da7434480197d9c45a2f33459480baa0cbe0d", + "PF-E2034": "ef22f5d432f03a2dc566b1463685bbcca81466c3bba5ea998f659e0435d61997", + "PF-E2035": "a511375c29f85bfedd42fc3f5cf74ae82b71af2c194ea8034427574eb15fe291", + "PF-E2036": "41c444c5c720835aaa53b4142c4b6d34a808fc973521e1ac2d692e1f72cddf71", + "PF-E2037": "ebb86c0878d80dbf8bec308117bef93307a94d744c4938d1ea1f315b38e76ce2", + "PF-E2038": "075d265e09731bb954bd0d672d7d5b96accf55eb6212c21f9d34691377162806", + "PF-E2039": "4ba31bc50ef3982caeb131158bb9662c540e51ef4bfc87df20fd910a6eab6a99", + "PF-E3001": "585dad07e797bbe2cfffa9f45e14dee040be5570cc13f8e46fa4c31e953fc92a", + "PF-E3002": "db089893825afe5ad1d91934c21107fc58451cadf3d71de2539b9c5805549433", + "PF-E3003": "02571beee5163d1596d8a11fe49336dfcf65f86d4fed13254bac6b36023c3c79", + "PF-E3004": "30c92a4a2423ed23782509fdfa0d02682d40af159a89fd3f5ec30e52b9831cea", + "PF-E3005": "b27512de5b1e16f6de9c66b3af380f73cb2d00ff33fea04aae0124b1f86797fc", + "PF-E3006": "d515e41a6f5ca835e7c97ed36fe6e8f7035306caee4f2960a85d32b10cebf2cc", + "PF-E3007": "adc607a7be6f667a101d92f62e94673fcbe703ab350554475cee90d714013446", + "PF-E3008": "0c54e68ff0f24134fdd3c11ba612fd9f4b4aa9deb7aa9bad52097de20f9b21c3", + "PF-E3009": "93e2089d2f6b1166da22d7c535568cbc88054611cec98588e3316ce7e1aa130a", + "PF-E3010": "7ab392e86dd2e2af525f99dcdf4b0131c1ed7e04b46065456eca59b28c2f2f6a", + "PF-E3011": "50d58e7ae776e4e2742ae84d9b30ee4f0012635f63a6bd3925a05415cfb326ed", + "PF-E3012": "3025b79d440418a9a44b90af29fbaaa6271e6b1aa9a753c485672333bc93c8be", + "PF-E3013": "1c61bb5993c55e628d49bc2fcc74ddb70d0fe5ec99241e61d559a5679413f0e9", + "PF-E3014": "6e713393159fa4e055261a4bce2c51acd786bfa8983d99a7c9a41621834e8793", + "PF-E3015": "4fe4e0ce8cb7c74474bc150a3cf30945fbdb61a59d58fcd729abde947c5271ea", + "PF-E3016": "41ea29f6848941aba248ccd8758b5e7c8a3d59d16eb1156111b466308328d0ee", + "PF-E3017": "711540c06238816942a20884b19400e90a570c4522a2e8c5899627fcda185c78", + "PF-E3018": "7693ce91626e624cd7b34f9e1bafd4cb1eecc2870555ed042684bd8820f1894c", + "PF-E3019": "c9d042c5909224e235bc14d58dc5c72e169353f1fd4a33e1a3b37116eb15adb5", + "PF-E3020": "5b0f01cf980da850ff611849d6955308b5dde333e2f0158146c5d1cb6fda6d44", + "PF-E3021": "983e12fe1a725658bfad9d4cd2089c698e8e46883105bbc7c073ba220cc1085e", + "PF-E3022": "4ee5f80af914cb40f95e337d143d79155b26346a29243deaa8ce067c4825245a", + "PF-E3023": "4bd1707430d44d1482f488aad0bdd7e5dff51eb111c7cd0ed13bcd758a551592", + "PF-E3024": "bd7431d9bc2d8fc144c2829c452d3afcec4decd0e7b508ff527d3347069af871", + "PF-E3025": "9881b90b40c2461e95fce3dca594b447fc1e42c3ba777eb56f8cca55c4dd66f6", + "PF-E3026": "240540f1d9868496939346b81d8fa3c720d1fbb2baa1a0a27107cb7ed24db4a1", + "PF-E3027": "776c925cfe85f760df1e2d81de2c353452d0e021d4f73e963b6f3fcfddf21141", + "PF-E3028": "7c20dd3863c65fed5dec63c03a7d9b0934a8f391fc3fa187d1fe2ed620ce6c78", + "PF-E3029": "1be44481457f8bcf76e6676c491daf5a246c457cf00ec8b886453769ba1190f4", + "PF-E3030": "04c36e5e99e078fc3bc6a957245ce75d8c5a8482f873d85240863f0bd8f7cc2e", + "PF-E3031": "4e910f3b499eba5a7a7edb162f8920afde0829772050ff14d3f2434f56b2ec68", + "PF-E3032": "7538d36582dc957756555221c69053ac465a6d5e902b010fd282384b8d21e969", + "PF-E3033": "b8e9d8e06458eb719a636856867c319f60fa9f1fb477c4c3d056e4223a491a40", + "PF-E3034": "24a68838c7ca78e4379e7748584fa0fc95ef691ce12c30b911971d8d0d3b3b5a", + "PF-E3035": "ff9b23c8ec0b11931c80ab757cfdf86f6a5e049844525bfef2a915ebd329c16a", + "PF-E3036": "379e3ba364a2257d4fe7c4ab33b969692a8d2a9124aea32ecb23b8b61be2cd2f", + "PF-E3037": "d24782cc7e4059c7904cec3fcf1277d54dac1d3f0e3883237e1dfcd28b481026", + "PF-E3038": "dea3cd644df59a17e6b1491c9de32bde1bf8cea839697e0d186fa73ad8ae4342", + "PF-E3039": "eeb033eaa1b1b0e1939083665ff51fb2f7bcf955aa72d6b9c95e962303d28973", + "PF-E3040": "57dca44dc50e2114d70a51b47706757a9556e7a3cd2ad8b7e243b5740da6b96a", + "PF-E3041": "36c80fb2a5b1b16722243b9569c598e7e7e87c11de53b7b5dfc69b4ecbde8d55", + "PF-E3042": "1032bd408c44b2fd63032cd1b8f373a59f48247a35555ad61b26612cc8017638", + "PF-E3043": "a293bad272705e6372d64b989d12aaf2095fdad958493845261b725e2aaf9471", + "PF-E3044": "68431710d5accc37798cf8f9afe0979d07818dcc9ccdbf24f1819ac9f09f5bf4", + "PF-E3045": "d686a941d65041bf613b024c84fa88b3fb00638311dd78c72ca7dd84f76e600a", + "PF-E3046": "0d0d7ce8d2a671f1ee6416ec5ed8ad65d165e2528c84d421a0449a9d37dbbd2e", + "PF-E3047": "88d13163942c51a33ebc911f2b1dc0d636c9366ee733842f6ca6934574156100", + "PF-E3048": "48efb37648f440d32f7a637816a3634bea9762cf713614137d2da14f2901d0e6", + "PF-E3049": "cfc66c64550821d23910f6f4c24b484d7842ca14fc37b61841dd79d161ba34e9", + "PF-E3050": "8ed4310529d2c09507a487a80fc0c9ce074d2492895683ffba8c33462c3b92fd", + "PF-E3051": "73a4c7907bfecf50e16e4fc69e0d5c12094bef6d69e578b316c1da06971990c2", + "PF-E3052": "02341847a530a199ac6ea78297f0ddb7f6142573b4e30cee15611c4d172edabb", + "PF-E3053": "05b3cae0f8db6c6363d4de7aff1f7efc99313b1a7a46f4ea3db0d6fd8be515b1", + "PF-E3054": "70e845dd172c9f8e89b8c2c07067685a40ea0015c3dd3125769f43ad56dc8e6f", + "PF-E3055": "f3532d0dcf66c9e5e2de10120568da28e6421b8bab9e25f96a5c1a44e1c15423", + "PF-E3056": "0f65bc68665b101cb594b89f0b192172277b54d84749885f22b4df0313ca5201", + "PF-E3057": "0cf35717f2db3b2ad03512968f22b2e38443ddec2cbeb1d4870908c7ed026358", + "PF-E3058": "8877da23dac5a0512daf5ba443caa52bdebcc51109609dc4fb7bb6577f0210c8", + "PF-E3059": "7b0d7eec835355b530d8c4acab5cd2f285ed25a5dc6ba58e0e6a4d7028ebea70", + "PF-E3060": "faf673d59c3bb1155bd0c697a59f714a8c508aebb0ecf18faf1244f113693610", + "PF-E3061": "56b82b70a64a499049ab49966d091f05ca2847fa4567a90bfd9b5b5446728ac0", + "PF-E3062": "2e3fef0b29a5654fe9aa94dd63e809305867d75e1cec6b7c22fda9ff73fa7e12", + "PF-E3063": "dd827b422b6beed8a362ed4d701f0b332c1313128f4fa6314225bd59762ce40a", + "PF-E3064": "3e55a1aa079d8ef66a670dcfbc98fe25f6dbd313e500ac92e1c573ca8ce45eff", + "PF-E3065": "b1199a376f35682e6045569f411d57715a70ab4bc292536d3ae11e40aec66e73", + "PF-E3066": "888ea9891258cf61257b539f4c837a801fc8c1affcb93caf73baebc7f3939dc6", + "PF-E3067": "4d050afccb8b8bd64256238a4e83c8ae32e4249a66d33d977b88611ec5b18a00", + "PF-E3068": "31b5428ab11778685066ab9085c3dbbc1aa5cc6c034babbca578bfcbb4da9da6", + "PF-E3069": "2c927584dd73c18b9f72388cfe833090b7b18053883278d3ab1ae6aefb86e90c", + "PF-E3070": "89f2bbbdfc1c6b62d275d168f782a3169d74266b90405633cf088a629294b3e4", + "PF-E3071": "1c3b76ed0cafad7c7a49cf6977bf8ddcc226f25d19fdc3601ca04c95a2c3ac36", + "PF-E3072": "f5ab203002eae57f227494228a2c096c8935f45dc43b146355826180ad1eefd3", + "PF-E3073": "db3ed98dcc439d7cac19ac14a4e719ef765706783635a7387a93121606532dbc", + "PF-E3074": "311accab9caa19401417639c92f9b336c7631266b500ae862a5f67c17bb23a66", + "PF-E3075": "1cfb2fa455c10d22fbb230ba062d25fd55027a555cd4fd15d9c98c4b1018657b", + "PF-E3076": "65f199f6133fe6fe03df22d6d33eb2a522616c2676de35d486029a4ce3111bfe", + "PF-E3077": "ed731dd2a1d3b1044e72b12e0a10cfe303cfc359a6a655453ec9487bdd5260d9", + "PF-E3078": "24d4fbfdc26d18fa606d1afeac138ef9546035249958c7d363ede349a4bf6d2d", + "PF-E3079": "ec7cc428c444dced4bed3e25dc4e37278c7ad8a2f659290d11f6ee355b48f0fb", + "PF-E3080": "59e78716bafd85494987e59884ccac02803d82e3482733b14f333dba5bcd9e73", + "PF-E3081": "709456204e38b0e972819db0d9e85ffefdcd20ab67d937c2284fcceb81dcfc82", + "PF-E3082": "fdd85a7923b61e8a61367b9aacccd6b43eab99b291e9c606dfb5d2421bb93292", + "PF-E3083": "947d155627263c6d7417146733d064eccc9fec32e653eaac6a252654e89aa9ad", + "PF-E3084": "666902f8371b1764df2dce2ba69af06cc43206aceef5dac223c85a62561170a2", + "PF-E3085": "e4e5981e4a41c4c6fcba7388bcaad0669758cc1aad095e4be523a588360fe5d4", + "PF-E3086": "eb5c7e9bd4283eea3823a937bd0ae1259e357586b1786c9293022afc3d238347", + "PF-E3087": "90ccb7ee991945e3233b409354e8f7b6cf9ea8439105ccb1469588ca98f03411", + "PF-E3088": "938373f4ceabe600e7a0e403a4f1ef3e90cbf74b522c761e0bea25d26d0a4da8", + "PF-E3089": "4e37fb4a30227e4a2b0162a9792059684b833819a4f51d2daee8dbd439b4cbcf", + "PF-E3090": "9f826e60755d3c5aa7cb956403a81b62f5395dac54f04e019c913476f4992870", + "PF-E3091": "3d56a8c1b46a3b0d16b43e5a6fb2cc0cd581d62a8ababef3931dc92a8691da4a", + "PF-E3092": "557c84b19c5680edcd1ec9807341611cddb8d5d035b221f9dbe5300d9d132827", + "PF-E4001": "f488e6af6b2b4f79cd67174b1e20c64a341f2662890bf94fc0238548bb2ffb32", + "PF-E4002": "9e14403bc1e30a4a59b40f55fa0be4f45d27cf31bea9adc97aa71cf599d39ab0", + "PF-E4003": "a29480e8883ce324fab677201938a847c6c51ac817c9f6be9d2173f2d7e0c530", + "PF-E4004": "2d1f7222de792bf9da7c4117f826e251a24256f7215c58aeeac84a63e6314a47", + "PF-E4005": "682221de055e538dfcbb9cd4428db77767f437ee864dddcbab812252059af3bc", + "PF-E4006": "18776bdf7ecefb78c2f66fb997af5761d56fa62ab65b65548d8636f936ea8d1c", + "PF-E4007": "d60606d10795ab11cf644eeff30f601300f3bc8e31197ab933fa9e24fe4f2193", + "PF-E4008": "7cbac16f5fc9c50c8ae841f067f843ba0162cfd370a491553d456cc7d16514d2", + "PF-E4009": "b2c5ef94ddb284004cf13bd78d30dde603395c5addb757b8a5dad05a9a48a076", + "PF-E4010": "af39b934f1e15c6dcf70a3ddbabf73a2befa7c5790d24df274d4153ffe882dcd", + "PF-E4011": "55750bb97e776607662ecd192af2b15dce424dfb18c3e273cd08b438e68a7c71", + "PF-E4012": "df2a6ab9c7364bd8b01a7ff481d2f17c9d14f16922dca7007c6d77fa319b871b", + "PF-E4013": "0566b5cebf055d8bb3dfac83ab33c0d309f0451badf055e4cea4906d6727b7ca", + "PF-E4014": "7866740c5ff6ff5b7ffd5113b12fb329ac060b0c9170df668b990cd3e6a4054a", + "PF-E4015": "9518640e1cb3181331426ce5c31d1125b2bfe150d95db78bf190eab155861bf2", + "PF-E4016": "552b4d836cf83b773847fdae010b4794bd946cd9931cf00d308482666bf914c3", + "PF-E4017": "1388cd20dddb1f3ad5540082c643a2c03954917e9508bdb65d84d50e1905291c", + "PF-E4018": "ed25566ffaa80d09d3b92d69a01c73e7551bc5a3365aefdc676a0ea7f422dd05", + "PF-E4019": "937b171075ba543e84ed71ff9b7115626169eda2500066479c94baef4fec3232", + "PF-E4020": "9d15066301851d08f2c8d849ef623530a38d54d6e25b425f399ac0da2088307f", + "PF-E4021": "e605234907c183c48a916a70b7db6a33f69aecfa8cd8aeeee1071baae334b61b", + "PF-E4022": "1d372faf58013c48d90a412b0d562e7868fd99d9f4b5cdcbdaba4ca4bc6bcc40", + "PF-E4023": "f68a4b1f9686b9f9532a8036e9bb6924e8dbaabcb908e98d52b2a5b62500ae4f", + "PF-E4024": "966c481aed947817713e3095525e8966395562d828ea7dc779b0ae676032d27f", + "PF-E4025": "187a2208ebf37784688785aae87dc90dd7b1e1ae760f450e7fd434bbb7eb2168", + "PF-E4026": "95816d33bae90b8680cefb34bef1232e2664771b14ccfc22ba29eaa344192c00", + "PF-E4027": "10ef01625abfd0380c0d6b7f4200c544ee954cd3db76f0b5b37340681f64e190", + "PF-E4028": "ad86f34f27b9641be2b8f3a065b7da6702530f88594b49fd977c9db5c0ac3356", + "PF-E4029": "a6124a0e3e1a4c5ff0fa640b5cac8a5bc096637ff9542503b9045c8cdfc499a8", + "PF-E4030": "b5e7647566355817676ee5b02cfe1aeb1ff2628484e9725d13fc07c9a35ca99e", + "PF-E4031": "54375fa2e19043fd9bb941b1ce444169e7797dafff91d58142fcd71a8e41fb41", + "PF-E4032": "c8ab521539784786f2eb3d398efe8ff0f14fbbeb2c40664562a7ea55883f6e9a", + "PF-E4033": "f9da466aff44be8a4227c45596b89320c35b3bf2d672abbb8b47498a51f3b3ce", + "PF-E4034": "36f9a37eafc908fbbe48a89bd3549978008dcdcb8613a765affb4df1c99e25c5", + "PF-E4035": "46fb8fa1739e4203053f5d5e0f22202e5d71f281bbb40620c7e77b6546bd9a95", + "PF-E4036": "4425ff00810f89e55be7ee7eddeb873a25f5f4a37ac6b65ba80f015b497b5133", + "PF-E4037": "c8cdbd9fdc3e3106e2ea79e646b0b4d1124d01d1bd778286349666e590b80af0", + "PF-E4038": "39dfc830adbd1b09db8aee60928439c4dbedc552cc32d6b27b696893b071e162", + "PF-E4039": "47c1a304fa37e4d1557fb6d08e892cd045dddc1553031cb7495f58a7176d41bc", + "PF-E4040": "ff1e347a6b9d2e36d2df9fa67488ebcfbdff768df88f9e65da86db81c41dbc85", + "PF-E5001": "04e2058982eb91b24fa9fcd9b34e87606b9ebe055310db68959330ac4f0ffaa9", + "PF-E5002": "b7ae068582d018dc2c7cb9adb652a8104fc5eb1cc18586d1f85005149087adee", + "PF-E5003": "e4210864adaed289355b23f7ec5d3ea575487bc557b8c7245111227899fafd72", + "PF-E5004": "d3bc99e3f0f94871dddd9547078bb668ddba7fe40bde89dfa8d305216a8d00b4", + "PF-E5005": "204eb55fe807f4736f0aca9c34be460d0763e8c02b93bd831402f7a12c4303c2", + "PF-E5006": "4a5c5ef12e9b969fab905900be479d89ba2281a2f65b41fcbfaa5dc8b9d181af", + "PF-E5007": "10ce4504551b8cb335d1694deed9f2495d796bbeabcbd369527a90a39bd7c872", + "PF-E5008": "665c6b7933dad5d098a83008ae473604ed03e4ec143543ebd1d11ac18212d69d", + "PF-E5009": "07116bf8df21a5148b6ac62df823500b4415de4ff2acf64b43181088257b84c5", + "PF-E5010": "405bfa5289883d26290252f4677cff8a3d1b59453e2fe1ded0dd8c8ea5d63290", + "PF-E5011": "f5d0893cfaf3c6901f95a12ae4dee63e1e97b73b757e80e2a219ebfedf2ba1c0", + "PF-E5012": "e0617aee147c8cd97850ee3c54609a5960710504423217c71504888172b6496c", + "PF-E5013": "6fd31d44cfa20046024611014aa701dfa5cf0f3bde6c4d2a6f181a28fbb98879", + "PF-E5014": "863d618ac9fef42b3de06f295df1a1ad00119abee6dfead7bcee84c445b71bd7", + "PF-E5015": "b915ae75b0a131301a37b99cec950f40841c1371185763ba0ae65a2aefe16bca", + "PF-E5016": "f6d5884fcfee5fddd9c3ca5f81a3dd4375b2a898545dd43bcf180f7b68742cf6", + "PF-E5017": "6f9c3a691ad59bf4e9fc1e98dd2cd477eece44b050e5b0b20b388816241eb6ab", + "PF-E5018": "84268b01b55420bd5e62a35f1d0fdb446e11c928ad344b939524e3e170003d38", + "PF-E5019": "5f11b33a15d19e08d12cfd9873e13923bef3ed78af8c677cacdbad8fc877a1d3", + "PF-E5020": "39ca44687806d7a17dbba6eb7cabef6a33880be8afa256677d56d0d6f6668c6b", + "PF-E5021": "58afbc952cef2bce7cd77a74eb9b5073fe8749bcd37c5c7b830d26c8b0bd4e8c", + "PF-E5022": "6a457ff496001807cb555f5070c6838758095c531ac0f36cf266ff863fd87c76", + "PF-E5023": "5fb07b636df4d93bbd81e67a6632362ba66796e8d26a8f6f8b5d41a4b47a9425", + "PF-E5024": "c8bea2b0778c43595418e16e1c656b66347667d362c0e83ecddfa0b56cd886a3", + "PF-E5025": "2ce9d266a1b40c65fe147697de35c4180903e25708eeb3b594baa12995ed5a53", + "PF-E5026": "0b2666a4475d52908d7392e3bccf732d7e5513f1eb1554757385cc5aeebf5da3", + "PF-E5027": "45fce1e9cba07b431f5430f97fb828b3a9beb540345f5bfe4f9914a0bee6e53f", + "PF-E5028": "9624dfe8451b9ec78df8bdd6cb20f136520135b46baba2898c23c365885dbba5", + "PF-E5029": "f7440d96eb7df08cbef389812a8a78f1a48f5bde6c6fac8bf24fbd61264d8cc7", + "PF-E5030": "9292925cd16913cc6a693697c7636491c455bf798d6504cf518f00afe66bd19e", + "PF-E5031": "e73daf5aed4a5ce67b624a4f1ad8acbebe050b3a422c30d56034992dbb1c6a64", + "PF-E5032": "989222460925cefc468f409537361e9a739a72349e36b63414f2989b3da812a3", + "PF-E5033": "501f91c1408149cbcdea5c8f8b53f7489afb543cb1e411c6d5afffc6136c04af", + "PF-E5034": "976c651cfd3e9f826f2ff26f92abd9d5a943c4942e5ba4a273927c044a2ec0ed", + "PF-E5035": "ea85ccb044c93f4e9329a6f882d33b4b737c33258d787ecf027c5286f1459e90", + "PF-E5036": "6146395b1dea5a398553f2a6960cb20a07fe384ddeebdeb1699ff87a61bf7ab1", + "PF-E5037": "494d9d549e10168477d768e2ed52f7171fcf045a17821a7a69919ac7edc59e7a", + "PF-E5038": "f4c447d252efdc61dbb5f3b74c9b9b58ba4b27be14102fca64a9e7abf530409b", + "PF-E5039": "27fd87deefc6f35aa11148653114a8ad6746a7da52025c8bbd2a9d4e82e827e1", + "PF-E5040": "4e25ecaaa4c2ee6bd69000fe29f16effe048ba0c95279ff03c9c11f466ea359b", + "PF-E5041": "fb8be86ab36e2d281326e6a67adc6cbdf1789deff4e6f93677b8a8d8abf9b02f", + "PF-E5042": "d1cba262c0b3f4de761593f7b2249c15afc212a5dd9a0df8b869ca84544df276", + "PF-E5043": "dfb8dbb703ad12a22bc5b74484ff987e590b342a8672fec78dc7b4053984f407", + "PF-E5044": "cebbe9a4cd473d6061052b4b078649f02b2cf3dc813a22e773fa43c5e154ae3e", + "PF-E5045": "ce94f3f93788b32f392b9a7a6688adbece65e01a48064be2894be9452e6781ce", + "PF-E5046": "d4dd00e326d28d6af215bd61a9cf97315265a37cdbeb07ce99ba2d5cc1d6909a", + "PF-E5047": "93c3ae8727904c6a4411f694508c280f801b8c0994213f7618482784e205fac0", + "PF-E5048": "34167e8b4381fbd6e0568d5cec5e13cce82f87fad7f17e2b2799a239de7b1d54", + "PF-E5049": "324fcec1de2fe836a4936f0117e215267ee54ca841539d9a754391f6fa629a29", + "PF-E5050": "4df3e307482c6d28cec9fd53682643f14df1645497da8f726bdd85baf066122d", + "PF-E5051": "951afeb314989372a68feb444c42acb6048a23da7b7143596fa25a7bdcac3447", + "PF-E5052": "fdfd6a51f253431433848cb43a441927fcb201e5ef3ec5001ee6aa81322b6407", + "PF-E6001": "62ad4d403a565609c34596b1c5d3982b990b137e255b3a83a97d92699ebe67bb", + "PF-E6002": "655927199576b7c06dae674bcfc6f5750c801f1af0564e862894c1e47a211038", + "PF-E6003": "8e9601e1627f343fada36b306aa9ecdd3239161eb3dc6a0716a664dc77e32b1b", + "PF-E6004": "ca9cb31a91aae0b4af0a6e37e137d12ba98146fc50e27768df6711e5e04b711a", + "PF-E6005": "5972b6278ffe2e4287aeec29112f93f92ff4b8016e3e886c200e98d0bb4b0c6f", + "PF-E6006": "200248af4b91de9c4be5391d828a4148fc05d594b5176c0b549548c18444ab5b", + "PF-E6007": "5614e696159ba2e71699eb8a53b3dfffc31bc1d3ec995eabadec32b80e8a6976", + "PF-E6008": "829032604cb717cfb53d832a8f88f24e7c0c833367cbec0e96097cadf8f69830", + "PF-E6009": "65b87ff5f1ff98ad28933218a6c424b5d88a44b2d10fa7cc7eeda0bd7524312b", + "PF-E6010": "b253302f63d44a2e561b0ceabdb6bbf345df839cbedcb9310556936cbb5ef2c2", + "PF-E6011": "bbf9a3ad1d1d60af7e6b2b62649cd4a37f795c033d41b1140a5d7cf09a9f3e41", + "PF-E6012": "969171f1eaf55ad370d752c32723232b84e96f2031f209fe756b715f64752f24", + "PF-E6013": "5ac43627a5ef99857754f9448fcbe24cb7fa3d79f26baaf4b423f0663cb0eb84", + "PF-E6014": "583d103570ceb892ee470a889f26c113745cc283b8f9061cdcbf27cc2d741342", + "PF-E6015": "f6c0e557ca3f1950ebba25e317978b52f0ba3a5a4c4c1edd668687b75e451656", + "PF-E6016": "04e35e80da2d34de9bb5230ead53de73d5728f06e547f75daaf7783b8e8f8ae4", + "PF-E6017": "3779b7d37851d76c9098cec76f3d7b2ec2002046548ad62ad11bfba3bc6d203d", + "PF-E6018": "6aefea9dd569e689b135b1f37a973b6e111dddd557d10a7fd0084d81acccf861", + "PF-E6019": "e94c6ce6de61583c455e625b6c78ef79b453efc6292fa601fa1400ec31bca7b6", + "PF-E6020": "a3c34182a2cd26f73d832c3ac97c1bc812fd9fa992f61019bda5ac50a74fa5b2", + "PF-E6021": "b14a65e21d0417ffd17f8d3ca4fb0417309af0bef4e73d12da91d7e51f8876c7", + "PF-E6022": "d6a05a4d09b426f6ec97751bd631cf690514e288cdf971d912063c8091e7e7ac", + "PF-E6023": "a155c6d5e72aebd0098e9d9ad69e4a20a6018453f1a93a35b8e91c7efeab423b", + "PF-E6024": "9cc312f293cfca01cbf7f6d4431b91b3d57bebae7394f15093ceab7932abfce3", + "PF-E6025": "ea5ad100f8a103eeecac6811e51d5e7616ee2d0e70cbf761a44b26bd3360be62", + "PF-E6026": "dff1f35e05559ac29553db95487021b6cfdf3e706e7dc207f8046e1e4b624462", + "PF-E6027": "cfd2ee75240683c804cccb895a51b679d35bc3276e34d10d0c032e4afa42c346", + "PF-E6028": "c0a3d82ffe92a1de0e5807616372f6133a64c59b25c7d41ce311e2f4b567d871", + "PF-E6029": "2d5438da4f2f94a1209f8c0f28dea07031e1b9f58f66e20c2d902fe59c523588", + "PF-E6030": "ee9c97a183b9db36b5b9e84f87a1331d03c8e7c90361707ff458dc010d6608f3", + "PF-E6031": "e2017709dd3089a5cadca80667d748914888b961932e1d21dc541d08225e1677", + "PF-E6032": "ade97008471b06d9b8243950fb0a2d35a03b4eb3876f1c358678da1170efde47", + "PF-E6033": "6199126cddaba0722cf62336b37c9887b1fd7250b38d4790965b6a444ad9a6f9", + "PF-E6034": "4394afe31b0004546ecf6b1ac1f1f0404faffd240d2efecf62835334b23050c2", + "PF-E6035": "9ad90a8374eb52b526000b4ff52a01d46e74dcce527637edc845d090486b8f0f", + "PF-E6036": "364d57d37af4d528ab3bf77efde83ba0b1b986a4efb3e6749459b69f37f402dc", + "PF-E6037": "3445e26f2cc4757069ccad0743cfee05cdd435267780ad5c6cd32be93fde6c4b", + "PF-E6038": "f1b432d1f37b943f87088e6377cd02f5db308d3ff3421fe4d96d1c6b7c4ea75c", + "PF-E6039": "e5c41a3431ddbf51ec6afbcd4d3dba42eaee3ba8483c74df89a0344cf64275dd", + "PF-E6040": "7893412edc7c7d3247d2ce8778fb0dfc59a8aae9ee40ea37451eff20618f8d65", + "PF-E6041": "ef405600ac0f7abebf36d25d6860f81e995fe1b97a661b3ce0a06b2b49a9861b", + "PF-E6042": "a81947fdb8c44f9576f3eb96a938796f57a069a1602187f3bf8cd6e9b7b1036d", + "PF-E6043": "a2b0e93bb65804205b715cd976b74837344058844887724913584955b1ffb150", + "PF-E6044": "b71984d7df9f1d0b4b9f64f50eb264548ed4a23d9c1eb832233923feea9c456c", + "PF-E6045": "83352ac09287010e7d43a64f802c8d42f26495a4bd528ef3b1fee2a29daafa81", + "PF-E6046": "35a1afc1871d257df1f4c02d18a244913192ca7e962311327270aade49181486", + "PF-E6047": "b2182faca0b5572d59ad9cb3ea5001d11f0116d0e500960d1dee5c158abc577a", + "PF-E6048": "805ce49eb04119d760e68bffbb22bad5b4b75968b243e4794a725700d9e2551c", + "PF-E6049": "98b80f47308ab54f439260d9e01cef201fd53b487f0b2dbc5ad191b32d984ade", + "PF-E6050": "b683d41f27a593560d0738477da76b74de0011f0d79b68bca36c6cd05013fc7f", + "PF-E6051": "2c1d8b51b6fdeebf33928d1c43aa0de96c92552f3e7e3067de1d48d82724a88a", + "PF-E6052": "f2d9b8311dba1285b023c6acc8bffeb990565a8dd8b0bb87d9bafba265ac0a4a", + "PF-E6053": "b97e941cab43e1a060311be74fc3dc45b4a988cf7d74d03bea15b234f50c362f", + "PF-E6054": "02a0e5049125602b6151b55a1cc132747381358b7036740d7bb3bfc497da9b1e", + "PF-E6055": "2136cdaabbb52e4e3cc52d6b1a05d06184b0eaa04ec357105787a6334cbbd007", + "PF-E6056": "b3a1b53a42062c311698a90d9d63d1ce5f18b46c7491b6d595029071db8a916a", + "PF-E6057": "e72f5e5628bdbc03701121156b498787bf6f2f55897184c1217400b5a8668933", + "PF-E6058": "814945420c3e42c79094ce37c0993c588b97cc94edd15b7a49731124c65b8e01", + "PF-E6059": "ddf160edda66996a5223434bb1d888d22a1b05862b4f2e7c6ff9be15ef693b15", + "PF-E6060": "afacc4dedd9eb39ab83a580ec7d2f81881d82f586000d330e473cb947354ba40", + "PF-E6061": "009fcb99a223fe1938d4f22457134091de127ce55b16a53918fc07baaa8228f0", + "PF-E6062": "b5d3dce8878ae83e50c99eeb05b32e3ed3fafb5ae0a02f535fd0992a6ed1dfb0", + "PF-E6063": "2513f9c2e3f7e968d1a9823630fd003033699c01cd7871f06b9031f335f17c46", + "PF-E6064": "97d1eb11d24cad3c2603079b1a85232c7073be677e8df925015856ddc2ddbd6a", + "PF-E6065": "342f7805ca1aa8205634ca956d73c1f2468f3deaec388f9572dfd85d94c43085", + "PF-E6066": "58840efee0a526f9d2a46ace2d847d8f5b0b53bf8ddef017e8e1e76c48ca27f9", + "PF-E6067": "1c89feb7accacad9bceb84f97fcb197fc2b4ae48783182e7d851278c779c9e5a", + "PF-E6068": "e2059672991f969d82e146f7227deab160959baae5c6833efc6d6a5baba69012", + "PF-E6069": "3ba8f6bf1019bc7762a219c3eece52b8b595b0d423d4bdd32ba9922d5cb713c0", + "PF-E6070": "aad05a3d0adc2d6d477ca539d0b6e94f7879bd889927ed9e1912cc223889dafa", + "PF-E6071": "b703c64f091dedd6174c3dfe9f7948afa0396baf64661d69286031a87419a6c1", + "PF-E6072": "e3635393fd9ac3638e3a025dcca91466a8e108afab18c4a0650339cedf56da1d", + "PF-E6073": "f6238ca281cb032b5fcedb9f8ca4f9e01ee96606377d8b79a4b7a5a02808c216", + "PF-E6074": "00937d8d72d30a81287f621132bc7eb01c236435fc71b5bdb27a9f586c0cf1cf", + "PF-E6075": "0f46198c3c4c81b3e92ba41954d614808ad380db34427287bc99a596fecc4c7d", + "PF-E6076": "c8bba3db26b3172028973a7b3754b7efad1c113c955a8626c84d7c624a08e614", + "PF-E6077": "99ebf94157bc99faac148e8786ce77af3857f20dea9d627955abfa6d970e3f4f", + "PF-E6078": "fd6178f44f7cebe4dac1c2db0009e8fdd3cc3611db2d66d4a9f4ee9c25beb336", + "PF-E6079": "bde36a0ba8f97cf5c48a339f93f1ece20e4d6afff2ae7a1884419faa1b230bb0", + "PF-E6080": "e930f5ff5fa26954485cbc0cbef6f7f56d1c66542a34f7e3025cf52b99bff523", + "PF-E6081": "24aa448c9cb20ef226aa3c2081ebee41ed0941f6281e658c1aab39b1fec0733b", + "PF-E6082": "605983784926e135ab5f41456c85c55ea68391d12774d5aa3b72d39e0b0750f8", + "PF-E7001": "233c520405eb6e3dda004c28c313fc77875fd7de8392af94c0ce5bd8367f4717", + "PF-E7002": "26993d470cbd1804937d72c282186c29c5f375059372276d3a9f52d6c0a39878", + "PF-E7003": "20f8958cd0e1dc67bb5dabacf0f7ced1e32a6233b79a2a69d1ca98eaee9bd366", + "PF-E7004": "084f19119896bd908db1d45322e6f8d89e3d01c9a9d76c6d8065c863b387cda2", + "PF-W0000": "7421c978182c16430cc009ca2a7449e607384eefbdc1aaa278fc5337146b3526", + "PF-W1001": "93247da40121bcea58c8c43e7b898685a6f12ebaeed2cbbdeb957a1d023fc34d", + "PF-W1002": "2ada4236c2f1bfdb4d62e734b64e13703a085329ce11a20df09458d8a891f49a", + "PF-W1003": "aa49c991dd37f11f31f5b847bc18c45bcba2e71efec65d0059997438d9ff6dca", + "PF-W1004": "07d3fd39d1388933f426e97cf7453fa3ac79b2fa9e8f87e21fdbe3b72e3a6a6d", + "PF-W1005": "95e14107e2c6bc6f802aa51c03234ea0b89452ae962fbc15b884855e9f3240a4", + "PF-W1006": "86878b51df714ca47451da2ce647b28ada9b0adce7ad288221efa866b32d4733", + "PF-W1007": "c662aa1cce95f062b82ba4d845081457e02951140332be5e0a8878b82a285a94", + "PF-W1008": "858b1448d6448f4e39bfecfefa62b993ef479ecc86bb0d7c6bac5b2aa0481d73", + "PF-W1009": "56c44a87d07cd60e86e02d2072415a0126179a44d9bfc891164b9033d1d207e7", + "PF-W1010": "86255f80abd859283a3a707a4b4bb6bc0dff474aac85bac88ed5c8093670426b", + "PF-W1011": "74d4c7e94f884165fe0b09aeb1786bf920899951eca8797c15da1245434e42e1", + "PF-W1012": "bce98a1335bc788aa77a903f1e2012e1ef8f03903a4146edd3422c3dd6189637", + "PF-W1013": "65d2e4c763c8b47aa081baaa661d9b2b66915a85e118013dc8f9f84e1f35121d", + "PF-W1014": "b3821009d1167627a0771981eefed44231dd222c40364938ac3a101ebceeb7c1", + "PF-W1015": "861f8971389b73de5d823bac5aa6d538356a2df793507130da745953203881e1", + "PF-W1016": "5f036c8234ed86a680f98559e9e706dd15456efe6666ee9617ca2f1e6296715a", + "PF-W1017": "068ef37cee1d1c895e75a1803af48fca2fb36d5fcdcff3fd4c6b5d98bf305fb5", + "PF-W1018": "2bc502b1f786e867a19520bd32ee77d88295e65baa64866ccc131eb4a84c241b", + "PF-W1019": "127c13304e6332f0d86b80c1f8f13660f00dddee122ac306b6c803ddf80be1da", + "PF-W1020": "f4b2c96e9a76f0ecedc59d301f5ddd0bb11ed5ea6a79ede6cd086d7484bda9f3", + "PF-W1021": "31b93326d878800a90830403bd6d5341c6921b2793793f1acc18ea39485a6d08", + "PF-W1022": "250c0b060e425f508e15a1e339423cb32743207b35faa7367b5559d221e2bb00", + "PF-W1023": "05c00b40a088c35f5cad483619bafbc83e91f0899deb53d654d968e598776054", + "PF-W1024": "51aa8638b0834a668cc9fc2b6dcaa4e9145b1cae8abb6fa3f61ca2e2e6df3d67", + "PF-W1025": "95d3664957a886cbe29a52f49466a41769150a71405aa4736b7fd4e900fd7381", + "PF-W1026": "5dac6a6591da8337312b2af19cf0f259edefefe79c82474728971b296614347c", + "PF-W1027": "0ce6b40a0c67d7ed14ad25e63bc3d9d44e0fe10b911221fbc03b392a2f131588", + "PF-W1028": "50d2df17c0d7641efc08621157bd50c38e2c568df5681b54cea2036f8bde3391", + "PF-W1029": "78ab49390a6c18761778a5caf0e6bc9060b31951c86cc74c49b4367e3f3c7ce4", + "PF-W1030": "63a79bd5c6a418137c60f97a538a74f8fd71009b0800a0a2be923b43e8042cf8", + "PF-W1031": "2cf4e6750071dfc6176e3a0aba0b4e84f34952db8bd0ac9370908af914ac8627", + "PF-W1032": "9cac4824ebc0657913e21d476aad66fc431f573c53b13b915bf6e413399e3e55", + "PF-W1033": "e569bf0431ebe863479fb6fed1b6209db2f70d92c94fdabf72191d83f2462c31", + "PF-W1034": "c3555e3429657790e5b99756fb1853df693807793839ece439e01827b85c26eb", + "PF-W1035": "d8442523cd1a9f4f14aa6d07f083aaf5eb105391f387f001ae24a952570ca8c5", + "PF-W1036": "fffdba49adb40c4d16801e7b2e4d55af34dc6c571d01c6058f6b48436b417732", + "PF-W1037": "5318dba34bec0d53c2457d750b944d60879a301188a39459733364d9e7eac383", + "PF-W1038": "0508c42d6ea84adfcc9d553fc189d4d96c61b9e416fad94fbb4f5f2623ec2784", + "PF-W1039": "c10cffe8f581ecd48bb5b2b8975ba487776d1f68c2155191b56d4976c260854f", + "PF-W1040": "2bb166e0b2d0df866c1b1e3dab389319781926bf5d61d870d3450c57c86a04b5", + "PF-W1041": "85dd2db20f4cfe95f374a5b7d1a20924f2f627b0e503a5aa2a00a077ccd239de", + "PF-W1042": "bd9db32a813d9cf5d9d79c4817174fc1e01ec75553e742cd4cc5dc79425c91fe", + "PF-W1043": "625a76246fff5c74368533e2b5516482834f0efbd4a45f91ced7334ab1a44189", + "PF-W1044": "9003820b931b01b3f8bc92eac8fe647cad126d1459c48b510da072c652e65133", + "PF-W1045": "560983a7123ddd1a2c3daefc9ad713a040d43b07cae8ae47069e6f81dcc2a6b9", + "PF-W1046": "f05663823503aafe68873e5fc8d864945b01d5cb8978e14a102038199a1a34b2", + "PF-W1047": "0296cfa2b46d67727d2f9dee18160ac9a7e079cd11b4c7e7bdceaaa5dcace4cc", + "PF-W1048": "d29953f131fa2e4df91dacf0b1a780342e027e9211febc153296ee20fe396667", + "PF-W1049": "b2da9c183f88d308e4715bdd7b62046fb3226faf6c5ee17f5ac7bcca32dccbbf", + "PF-W1050": "f9e54b91f6507ef6d95a1804e247b8ca7b08120a80a453fec11a227530263b11", + "PF-W1051": "5345255b13de28015511f26e324ce92ba4cb56777e3d0537b55581cebc50a006", + "PF-W1052": "39324af6060618f183568526eb29b346c79f055129ec9853c075f3524e2b727e", + "PF-W1053": "d1c27468a68ad70da01bc602afd7a52cf94199c6a640b73375d70caf4b599373", + "PF-W1054": "320e44c381eca970c001925d150513dc17943a9445c6eae334e9a8ff1f952f91", + "PF-W1055": "2b8e3c148b72b5888de56714c3c1258fd26a186d633e63ef06230af7ac753020", + "PF-W1056": "3b38438df0ba0ac764028e5cecdcff712c7557b828f4d10a4dd3505958644bc9", + "PF-W1057": "cf48d4f0ad54259de222c1db7f0f81bc37d96fd9e0bf88dfe1c8d29d82310727", + "PF-W1058": "90f8afacd46169aeabf07f734e67f1b665e58ad7374dffbc9bf35b21714d5ed4", + "PF-W1059": "08d7f32cd223a0c570e0cf2c13a68f9986527e457ecaafe5d3fb401fac726cb9", + "PF-W1060": "ca0f6ba51b1ad6417abd4acb1e7b416719aeae1533fcbf3782a8de9d45d2d2f6", + "PF-W1061": "011c7e28c32d44c26b539e05d57e4b256b9d2381acfcec595e32b59576390fae", + "PF-W1062": "46b53f4f1a68c87bf2e7d508dc078228af9cd8235b6f1a5d00c892d5b3f2afff", + "PF-W1063": "a627a93ebdc270c3f61dd60581a956974441a55d9f54ea9fb2e0291d0826ff33", + "PF-W1064": "a1a289d2ef01c51b75775bd636e90affd8f68190168a340f34728001302e1b06", + "PF-W1065": "95293a6131f3500f529c88e35a4b6875dc2c117afbb30c25b0de8b6c096a9085", + "PF-W1066": "ce3eedfa360b6ec4858b13b28e4017752aaac16846d53fb4b503485de14a0cb3", + "PF-W1067": "1a1168bfcfd2005d9939e289c06a7cff26380f4b0bb2010d42c699749de59e7c", + "PF-W1068": "bdb47827b1d92a83fbbade01e8c2b8c7e26eac6699d09a32a4f5cbb2e6fd55c5", + "PF-W1069": "32ce7ff427cecf36d5e08f348a70fdc83cc55a39d9d511ea0487f582e6ecabda", + "PF-W1070": "8fac83110d1b1b76f005866eb00bf7ea0e094847ef79d47edb11998531ea63f1", + "PF-W1071": "47599b98b6c95d56097656281f2cce2d21118d71d2db0f1359ebbd5d2f3c5b96", + "PF-W1072": "ecb27b1f85da4b882f4cdf7d158d31a2b630d17b39c4bd3408d31a7643aea34f", + "PF-W1073": "da25faf9e5e0d06f93997cbf8dfdcb4172d2de661fe6a1335ed727514d9ea025", + "PF-W1074": "455f83227fe6ded19acf783545e6b959e5c8b5edb0b00ef18ab90f117e4f869f", + "PF-W1075": "bd2eff8895e744170cbd821d30966ca8e9050f073e01fc67fe38e2ba4d3ba909", + "PF-W1076": "b6ded44b0603e7b43a7ae009ad187498c05cca066cc6b0f48061d84b973301ac", + "PF-W1077": "48a891e61786cbee0c049259a699fe12ffe6c7f09d04feb2b7652940654e9cb8", + "PF-W1078": "a8b2c968ffb503de85e81a3e7d9873848179f4c66ac24e83d71b337b6013cd1e", + "PF-W1079": "840f9a5e5ca420b3e394271b921ba27607a0e4538b06d5e1b151b1654af6119f", + "PF-W1080": "acca2adefb4532f03e60e15ee43ea2568286bc05d0ab6e0d5537a00287f7a89a", + "PF-W1081": "17fd525f8ff769383b7f499af22dcbb215180b5fe81d3e94d860ff5225befd85", + "PF-W1082": "d4955f41ae92c063aa4624b289b4beefa6f1e5ce7b3ec15d05ccb6446ac04bf0", + "PF-W1083": "9625ef7e15f462451010a611ba0e5f86517617e793e4d72dc59b478102c8131c", + "PF-W1084": "86fcdda06690b603b7df5aebf784024d938c6c12de5c4a5b45425745c95513c5", + "PF-W1085": "cfcdd6ea0cf9bf22715934e7836cabd54688eca5a0e76c518733a62fef4ddbf7", + "PF-W1086": "d94fade49915c9d45998369bdc31a3ed1b4ae08094ed9cfd4ebda19ba7e0f24e", + "PF-W1087": "09f809e15fc3c7f876feb714fb6e80fd78ae7e62b1147051ffaf0ec1771a101f", + "PF-W1088": "9e8e55fab34e5c09417a4248cd77c805c3e86673694aa917eca1a9a81eeb1904", + "PF-W1089": "bb18286df7edf7cc64ec9fe67346e1c597c86c5133bf4e8840b89fa50f0cff1b", + "PF-W1090": "441e4e371f5186cd535b3295007af1050ec240920c3a3c1125e16e46cd7d70d7", + "PF-W1091": "8156829538596b3a2dc315e8a79d33f65f6a8304a1884210cdcdf34e47787d8c", + "PF-W1092": "f9a2ad4d5462b771eac860cdd29336e6db1aab0f7619fef6d7f31041dea06453", + "PF-W1093": "3b77b0b47f4f9cdcaf811c3404d171f417a47ccc9d4d3d2b5ee40071ab75d924", + "PF-W1094": "c04f0b17db3f9a4fc6228b4895fdf8d78d422d4823e7ddc39340a1ef99ad934a", + "PF-W1095": "88ed0e6b483c3458d57caaa78f295e6e2e0f311b1638ae982f68bb5438d94e43", + "PF-W1096": "3d6e62130f9cca02a3b3cc144c68942bef1434dae675ed6bd7040cb144e22f7f", + "PF-W1097": "a889558560d36b89dc2fc566cdc9c5f9c322f169ac68bbc41bf4208a368bbb0c", + "PF-W1500": "c75a5672704911176a2a4325bc17f79d8d56191b92c87f670a663a32c604a038", + "PF-W1501": "1b3135d61f5cd94b670a85a1037ea4be636a7f9db9532f6bcda08faf314bf1c9", + "PF-W1502": "7414dde57f8560fef4a235df1712edcdd104dabb912301c0b7955cd6180806e2", + "PF-W1503": "d01282d4267e74bee4f2410d627a53659dfb8ef4d3a7da52aa6d2472ca3cdd44", + "PF-W1504": "a47b0c03eca361d8efc488ad9978d80981fa62ece90917d644e652f526965ec2", + "PF-W1505": "787177596255e23d0b59c8aa9892f69d71a1a745c89982b96610389c129f4735", + "PF-W1506": "4a3de9263a6aee53db84e33bdc89120475693bc33f8817897c5e3b0c4f600e70", + "PF-W1507": "6abcc1fbd882466757a9c052cefccec32d0ea79551eafc1b2dd8418a68ecae08", + "PF-W1508": "e6a55746d8cd3e273e1a160f8d40005667d7276f14e43679802b7acea59eb8a5", + "PF-W1509": "14a7dc566b33c9ac37dbaddff8ec88284778798cb6ed2c6b82e734f741e2db64", + "PF-W1510": "2c8994cfc4ca7de7a63f18306b1b25147d9ed0fccb13799fb24e01b5aaae1b1e", + "PF-W1511": "7a7077a3ea2c89a607a74bbba0fa197b193af52a8d2dbbb10c186a97e562e6e0", + "PF-W1512": "621ae32351ea33c51a2f12e668f0314341354fef423a4e02e272d03874080dce", + "PF-W1513": "b09f7956345ce2d4e6b14e424c902aaaffbfb2321d27467dd352cb75efe2b212", + "PF-W1514": "d149dae283204e35bdde9e02154893465e6f4262e610c9ef2457ae3e4dd7e42b", + "PF-W1515": "0302bdcd62c655929f28d5d27e3c724e0e28438203f8f22f011dfae1910a4949", + "PF-W1516": "f539d4116c39db982437cda31d3c36b56dbb82a8a05dc2f7896a356d2fb12af8", + "PF-W1517": "f2c6311163b88497028915a764a25f35d3affddd9c29c8233d33212e9b965393", + "PF-W1518": "eb9a54268ae3b991de36ca03295ab71ab3df79772433632562adb45ae241128d", + "PF-W1519": "0a95fbc03da2cc532c9af8a99e5afdcea426fc00f8ba7ab5673b76b0457212c1", + "PF-W1520": "bb7a8a5164bc0b732c70079b2911e85b8fd5f5f92377ce8b1a45b4679d49c1e9", + "PF-W1521": "44c7cc7abf42bf6934dc591f7cb7bbefc9c226e7404d8e7f15288ab0330e3db1", + "PF-W1522": "ef8bdb005216265ab866cfe24f869b04bc7b76187776f51ee326e3d124799646", + "PF-W1523": "6048f792bbe012075b1f1af01ba2a4a7e92ed31471adaae94a3b4fcdff9294e0", + "PF-W1524": "eb43a104276e90b07fd37ece812f5c1206dabc36943ef2bf56188744ff5ea6cd", + "PF-W1525": "7f05cf12e7274bf5ae4e4164f975fc4185864e3dc9658a128bd8f3413213d06b", + "PF-W1526": "9a7990cadb1fe7eda3d35cdd345836889d5e8a7a28d0279e2c2e3e8d8334b91d", + "PF-W1527": "6f7b920851e88a42f7a414060750870806bbab9209aa93e24d008affbba3360f", + "PF-W1528": "c7b73144ec5143b30f2914ea891277630110c77150aec2b766643e023bd6c15e", + "PF-W1529": "ccc27d2ce0c2216a63bde293f052cf39e913e8135a5d5df3b0ea19b428048912", + "PF-W1530": "095838c70d9f3e88f202c92312b649d717a4749e7b205f90f4b1e2e3f88d736b", + "PF-W1531": "75e41d964c941d0b16e7f1b74fe60aea944a2a24bcdd8f7438bd84263be55705", + "PF-W1532": "e844cd922c91555618673691479c7dc64d280d7621da59b4f2a6f9cfe83205c4", + "PF-W1533": "c244f2332d60b36aee58c5d46a62c73da9cfded5a8c4065821787dadaabaeab6", + "PF-W1534": "6f62f69665b802bf9f80cdeb10e2a720379b4f296b71d3c922b463cf1112c5d8", + "PF-W1535": "cb45ba282f87aae25883dedd8287263de9bfcb60c3ae9a97bbc5f32e872622f6", + "PF-W1536": "e8bc1a3ef7ba64afd0040b0aaf061e8f6cd4548e6613c8c3347523d3273087ff", + "PF-W1537": "7a105a660db12b6be736b258190630ae893cfd16fb21d52281a083d184613bda", + "PF-W1538": "d03767ee33236a7f64c6c37736f59e41966fac39c613100160299752e198512b", + "PF-W1539": "3d733379543ceae1f722106fa53a836485739fc99ae089f80c5f8623aecafe55", + "PF-W1540": "fbe702127d7fa1fcd8239824fd7d4701686f268dab705799965add653111e04c", + "PF-W1541": "84e314020f8b6616e0fff411dfc4e70d80fd72d677d95c201bd82c7ef88362f7", + "PF-W1542": "ab496915d9a08faf2aeb9d74be122ad34dc346822103574f61ddc97e5212f75b", + "PF-W1543": "9cf564aa1eeb4aa7b262ac30529cc1cc1a2de724656ec34e7a6e1d6131aa2e59", + "PF-W1544": "274e7f851b6f4e908b89b9a2a2a08d3c06857b0a17215585fa246b222e0d44a0", + "PF-W1545": "b843a59b8718436b234bd44b53f6e392b08a299104e289b923cc7028a68b329e", + "PF-W1546": "36c3af6f843fb4857509aac9c37f1eb18ecc2c76f0db6dcaa08932f348deca10", + "PF-W1547": "2001b472364a0543b471e49f5d6bde2e2d1645f7129aee65dc7d3bbfa8c052e8", + "PF-W1548": "76fa06b5bb6f1261b8727a0b38ae9fcc1ff1d338831fd1a9eba6df7c023ee3aa", + "PF-W1549": "3e6cadcf3e8c9aba8f4d680e2defed3342fed8e12a734277b5390c8ef658fa4a", + "PF-W1550": "0d73bb5d2a22ee6bc342499b16b7338abddb0d6c98f2237a92157812c4121aef", + "PF-W1551": "97261dabc66a05a5a5e14e4fe7e8865f5704e1f7289304aa45709e976a29fc07", + "PF-W1552": "1f0ecd367a2b16f724e5f17dc950054f06071925c8633dcd291ad37c1fdadcea", + "PF-W2001": "49fda8dee49a14e23193c02639093e2d8e2598279d36d910233de8395d996082", + "PF-W2002": "a0474e31462e4ee84e821c3f791c7be21db29e1e8c0bb67372119bf2547b3955", + "PF-W2003": "1aa350aaabc80de130be586528ebae1045ab9392c91f43d0f2757e5d37b7606d", + "PF-W2004": "03752b434d95a43b58b4586852c5a95bacb5c8159554b1ed9936e0c76b7a2b7c", + "PF-W2005": "6eaf80f389e63432fcbd43526756f2e2931214ddfc6fa035b2cbd50f1b7193ce", + "PF-W2006": "67e17e0e7cfebc2c92e62f98d2360da4e2c61b5572e000e596818bbe33363ed0", + "PF-W2007": "cd375f4dc0dba878b28ca0aff9e333e3b1107dba424ede74f14e6015c2c02b84", + "PF-W2008": "75f3960b09e8b899ed9d4135d5f663cf4795c4e8dce1f475d5ac670a0900a77b", + "PF-W2009": "624d1f21f72d2064394f4fbb29fda30f46f919535f35dacfb392cfdd14173072", + "PF-W3001": "26147be69f0b2246d64b05e05e4732d1a67f6d739a246df32f664d8a038f8e58", + "PF-W3002": "e79e17e4bfc6be42e3dc37eb5a9fea86d025db807b6a8731d9e4920b6dc43095", + "PF-W3003": "65aa628c54d4e6f49df436c0833481fc11091a6897363c189c01e5af9251c629", + "PF-W3004": "b743ede072aa5fdba2ffd8983e7715869046e17339a35c5e9928fa10023dfc5d", + "PF-W3005": "196e9c66ecfef9edb39bd367fc04c7905963b9339632ea3cc15f29e1b9714b5d", + "PF-W3006": "4132e24d31d76bcb7c0c2d57e509ecefd3cb740573f5917cb7b3dfce6818e1e7", + "PF-W3007": "02dac59a7b8bcff7ba97ef2e156f225501ab251eaa3d59a8666b2ab6c4a352c2", + "PF-W3008": "6610ccb2e0562d4e29b77c74e75d7d68ce31b7db1f97378223fad0ddd92be606", + "PF-W3009": "37041000c4e8846db5a1739ac6903ba8e109019baf858eafbcac6daeea2f21b4", + "PF-W3010": "a936d51d7f7f632e707923d2f4285e5dcf9566a9e387bf567c84cb1431281515", + "PF-W3011": "dc777ac59e3fdfd74d312e55397b096f8dc22acbd58c2315fed1a9b8beff947c", + "PF-W3012": "16a75b0fdede020dc9919f2230a0506744695e999e88b44676cdcda5c76a8594", + "PF-W3013": "5fbce67eec11e99de6f9f9dabdb95a63fda667a4d160832e8b7f396927c84582", + "PF-W5001": "0ef938afbfa02f4fede7cac1fee01dc61d46a588ef943096fcd545f359fcefe1", + "PF-W5002": "253a89e2f6b604376930c302d3139a8fbb221d93b86145a90df9a0af50e145d0", + "PF-W5003": "447fc43e819fdd3df7659d9471f9f3d1d25e9b0a19fe923ea3a5da98f2a63985", + "PF-W5004": "3284133adac0ce8e30f8ec0dce132afb53bf4d9d9c8a552cace40bc73968c18b", + "PF-W5005": "8d2b834899049991c5fac10b73ead2d5a68fcb52a556f0e710a304522bea0a5e", + "PF-W5006": "b227a773d40a86f4389759c49a2a3e4474a2ebcbaaec1c92d46ba431213b518c", + "PF-W5007": "7124a2fe3e882861873bf1f9ee02c516f995200822a20f2d01aed08516d1fdbb", + "PF-W5008": "007769d118b3c079d4f5c7a036ef29ebf7ee77b218a35cc1adfb34f4c1291147", + "PF-W5009": "7ff3059904161cab2a3bf1c400db319b89a48f5e36d27fc5fba976f122503d75", + "PF-W5010": "0eeaef26dc71232c3e3e3568e49c4b2b350ae11e3855b51ea623813ca57e9354", + "PF-W5011": "78355a934a2a30492f26e90c24425fa13d289abd687f35337b769b423c66dc48", + "PF-W5012": "b45b744807fd859880761b1c9966f84ec6811f101acb6f80d368106db72aee44" + } +} diff --git a/tests/fixtures/diagnostic_notes/interfaces.json b/tests/fixtures/diagnostic_notes/interfaces.json new file mode 100644 index 0000000..c00503f --- /dev/null +++ b/tests/fixtures/diagnostic_notes/interfaces.json @@ -0,0 +1,41 @@ +{ + "status": "FROZEN: user_message carries a template, never pre-rendered English", + "cases": [ + { + "name": "chart_ema", + "source": "//@version=6\nstrategy(\"EMA 診斷\")\nx = ta.ema(close, 20)\nplot(x)\n", + "ok": true, + "controls": {"PF-W1505": {"before": "warning", "after": "note"}} + }, + { + "name": "visual_only", + "source": "//@version=6\nstrategy(\"Visual\")\nt = table.new(position.top_right, 1, 1)\n", + "ok": true, + "controls": {"PF-W1508": {"before": "warning", "after": "note"}} + }, + { + "name": "display_request", + "source": "//@version=6\nstrategy(\"Display\")\nx = request.financial(\"NASDAQ:AAPL\", \"TOTAL_REVENUE\", \"FQ\")\nplot(x)\n", + "ok": true, + "controls": {"PF-W1528": {"before": "warning", "after": "note"}} + }, + { + "name": "actionable_warning", + "source": "//@version=6\nstrategy(\"Risk\")\nstrategy.risk.max_drawdown(10, strategy.percent_of_equity)\n", + "ok": true, + "controls": {"PF-W1503": {"before": "warning", "after": "warning"}} + }, + { + "name": "error_with_note", + "source": "//@version=6\nstrategy(\"Mixed\")\nx = ta.ema(close, 20)\ny = request.seed(\"x\", \"y\", close)\n", + "ok": false, + "controls": {"PF-W1505": {"before": "warning", "after": "note"}} + }, + { + "name": "unicode_escape_error", + "source": "//@version=6\nstrategy(\"引號 \\\" and braces {}\")\nx = close +\n", + "ok": false, + "controls": {} + } + ] +} diff --git a/tests/fixtures/diagnostic_notes/product.before.json b/tests/fixtures/diagnostic_notes/product.before.json new file mode 100644 index 0000000..5936c09 --- /dev/null +++ b/tests/fixtures/diagnostic_notes/product.before.json @@ -0,0 +1,341 @@ +{ + "interfaces": { + "chart_ema": { + "python": [ + { + "severity": "warning", + "phase": "ANALYZER", + "location": { + "file": "", + "line": 3, + "col": 11, + "end_col": 12 + }, + "message": "ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does.", + "hint": "A covered length-20 TradingView tape first returns a finite EMA at bar 19; standalone PineForge EMA is finite at bar 0. Its established lowering stays in place pending per-call-site population parity.", + "code": "PF-W1505", + "args": {} + }, + { + "severity": "warning", + "phase": "ANALYZER", + "location": { + "file": "", + "line": 4, + "col": 5, + "end_col": 6 + }, + "message": "plot(...) has no effect in PineForge backtests (visual only).", + "hint": null, + "code": "PF-W1508", + "args": { + "name": "plot" + } + } + ], + "envelope": { + "ok": true, + "inputs": [], + "strategyParams": { + "title": "EMA 診斷" + }, + "diagnostics": [ + { + "line": 3, + "col": 11, + "message": "ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does. — A covered length-20 TradingView tape first returns a finite EMA at bar 19; standalone PineForge EMA is finite at bar 0. Its established lowering stays in place pending per-call-site population parity.", + "severity": "warning", + "code": "PF-W1505", + "args": {}, + "endCol": 12 + }, + { + "line": 4, + "col": 5, + "message": "plot(...) has no effect in PineForge backtests (visual only).", + "severity": "warning", + "code": "PF-W1508", + "args": { + "name": "plot" + }, + "endCol": 6 + } + ], + "requests": [] + }, + "cpp_sha256": "57c2321d7762e854036ac9d99221931ac96dd32e618c363e875b3e51f0519d2e" + }, + "visual_only": { + "python": [ + { + "severity": "warning", + "phase": "ANALYZER", + "location": { + "file": "", + "line": 3, + "col": 14, + "end_col": 15 + }, + "message": "table.new(...) has no effect in PineForge backtests (visual only).", + "hint": null, + "code": "PF-W1508", + "args": { + "name": "table.new" + } + } + ], + "envelope": { + "ok": true, + "inputs": [], + "strategyParams": { + "title": "Visual" + }, + "diagnostics": [ + { + "line": 3, + "col": 14, + "message": "table.new(...) has no effect in PineForge backtests (visual only).", + "severity": "warning", + "code": "PF-W1508", + "args": { + "name": "table.new" + }, + "endCol": 15 + } + ], + "requests": [] + }, + "cpp_sha256": "583a732dce24b3d9f3cbf3e93152450207ad482e295bb8daa75a20009756d25f" + }, + "display_request": { + "python": [ + { + "severity": "warning", + "phase": "ANALYZER", + "location": { + "file": "", + "line": 3, + "col": 22, + "end_col": 23 + }, + "message": "request.financial(\"NASDAQ:AAPL\", \"TOTAL_REVENUE\", ...) at line 3: value reaches only display/alert sinks; lowered to na; trades are unaffected.", + "hint": "External fundamentals data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.", + "code": "PF-W1528", + "args": { + "call": "request.financial(\"NASDAQ:AAPL\", \"TOTAL_REVENUE\", ...) at line 3" + } + }, + { + "severity": "warning", + "phase": "ANALYZER", + "location": { + "file": "", + "line": 4, + "col": 5, + "end_col": 6 + }, + "message": "plot(...) has no effect in PineForge backtests (visual only).", + "hint": null, + "code": "PF-W1508", + "args": { + "name": "plot" + } + } + ], + "envelope": { + "ok": true, + "inputs": [], + "strategyParams": { + "title": "Display" + }, + "diagnostics": [ + { + "line": 3, + "col": 22, + "message": "request.financial(\"NASDAQ:AAPL\", \"TOTAL_REVENUE\", ...) at line 3: value reaches only display/alert sinks; lowered to na; trades are unaffected. — External fundamentals data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.", + "severity": "warning", + "code": "PF-W1528", + "args": { + "call": "request.financial(\"NASDAQ:AAPL\", \"TOTAL_REVENUE\", ...) at line 3" + }, + "endCol": 23 + }, + { + "line": 4, + "col": 5, + "message": "plot(...) has no effect in PineForge backtests (visual only).", + "severity": "warning", + "code": "PF-W1508", + "args": { + "name": "plot" + }, + "endCol": 6 + } + ], + "requests": [] + }, + "cpp_sha256": "0255ef55a869a3e3cb24e9a930bcfd045d1d0d544d7aa14df06d40adffe8e40a" + }, + "actionable_warning": { + "python": [ + { + "severity": "warning", + "phase": "ANALYZER", + "location": { + "file": "", + "line": 3, + "col": 27, + "end_col": 28 + }, + "message": "strategy.risk.max_drawdown(...) has partial PineForge runtime support.", + "hint": "Verify risk behavior against PineForge results; unsupported risk edge cases may diverge from TradingView.", + "code": "PF-W1503", + "args": { + "name": "max_drawdown" + } + } + ], + "envelope": { + "ok": true, + "inputs": [], + "strategyParams": { + "title": "Risk" + }, + "diagnostics": [ + { + "line": 3, + "col": 27, + "message": "strategy.risk.max_drawdown(...) has partial PineForge runtime support. — Verify risk behavior against PineForge results; unsupported risk edge cases may diverge from TradingView.", + "severity": "warning", + "code": "PF-W1503", + "args": { + "name": "max_drawdown" + }, + "endCol": 28 + } + ], + "requests": [] + }, + "cpp_sha256": "9a106939527e18a844cdc1a9e5d6d997e46e14979d348a9af10892f5633abc48" + }, + "error_with_note": { + "python": [ + { + "severity": "warning", + "phase": "ANALYZER", + "location": { + "file": "", + "line": 3, + "col": 11, + "end_col": 12 + }, + "message": "ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does.", + "hint": "A covered length-20 TradingView tape first returns a finite EMA at bar 19; standalone PineForge EMA is finite at bar 0. Its established lowering stays in place pending per-call-site population parity.", + "code": "PF-W1505", + "args": {} + }, + { + "severity": "error", + "phase": "ANALYZER", + "location": { + "file": "", + "line": 4, + "col": 17, + "end_col": 18 + }, + "message": "request.seed(...) is not supported.", + "hint": "External seed data feeds not available in PineForge.", + "code": "PF-E1027", + "args": { + "full": "request.seed" + } + } + ], + "envelope": { + "ok": false, + "error": ":3:11: ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does.; :4:17: request.seed(...) is not supported.", + "diagnostics": [ + { + "line": 3, + "col": 11, + "message": "ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does. — A covered length-20 TradingView tape first returns a finite EMA at bar 19; standalone PineForge EMA is finite at bar 0. Its established lowering stays in place pending per-call-site population parity.", + "severity": "warning", + "code": "PF-W1505", + "args": {}, + "endCol": 12 + }, + { + "line": 4, + "col": 17, + "message": "request.seed(...) is not supported. — External seed data feeds not available in PineForge.", + "severity": "error", + "code": "PF-E1027", + "args": { + "full": "request.seed" + }, + "endCol": 18 + } + ] + }, + "cpp_sha256": null + }, + "unicode_escape_error": { + "python": [ + { + "severity": "error", + "phase": "PARSER", + "location": { + "file": "", + "line": 4, + "col": 1, + "end_col": 1 + }, + "message": "Unexpected token EOF_TOKEN('')", + "hint": null, + "code": "PF-E0037", + "args": { + "token_type": "EOF_TOKEN", + "token": "" + } + } + ], + "envelope": { + "ok": false, + "error": ":4:1: Unexpected token EOF_TOKEN('')", + "diagnostics": [ + { + "line": 4, + "col": 1, + "message": "Unexpected token EOF_TOKEN('')", + "severity": "error", + "code": "PF-E0037", + "args": { + "token_type": "EOF_TOKEN", + "token": "" + }, + "endCol": 1 + } + ] + }, + "cpp_sha256": null + } + }, + "wire": { + "chart_ema": "{\"ok\": true, \"cpp\": \"#include \\n#include \\n#if __has_include()\\n#include \\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#ifndef PINEFORGE_HAS_NATIVE_LOWERING_V1\\n#error \\\"generated code requires pineforge-engine native lowering v1 (PINEFORGE_HAS_NATIVE_LOWERING_V1)\\\"\\n#endif\\n\\nusing namespace pineforge;\\n\\n\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n#define _PF_NO_DATA_STOP(function, call, line, english) ::pineforge::pine_no_data_stop(function, call, line, english)\\n#define _PF_OTHER_SYMBOL_STOP(function, symbol, call, line, english) ::pineforge::pine_other_symbol_stop(function, symbol, call, line, english)\\n#define _PF_ARRAY_STOP(reason, method, english) ::pineforge::pine_array_stop(reason, method, std::string(english).c_str())\\n#define _PF_COLLECTION_STOP(reason, object, english) ::pineforge::pine_collection_stop(object, reason, english)\\n#define _PF_NA_STOP(object, english) ::pineforge::pine_na_stop(object, english)\\n#define _PF_LIMIT_STOP(limit, max, english) ::pineforge::pine_limit_stop(limit, max, english)\\n#define _PF_UNSUPPORTED_STOP(reason, line, english) ::pineforge::pine_unsupported_stop(reason, line, english)\\n#define _PF_STRING_STOP(reason, english) ::pineforge::pine_string_stop(reason, english)\\n#define _PF_ENGINE_INVARIANT(english, legacy_type) ::pineforge::pine_engine_invariant(english)\\n#define _PF_INVARIANT_AT(container, index) _pf_invariant_at(container, index)\\n#define _PF_SETTING_FAILURE(strategy, entrypoint, message, reason) (strategy)->_pf_record_setting_failure(entrypoint, message, [] { return reason ? ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::setting_rejected, {{\\\"entrypoint\\\", entrypoint}, {\\\"reason\\\", reason}}) : ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::setting_rejected, {{\\\"entrypoint\\\", entrypoint}}); })\\ntemplate \\ndecltype(auto) _pf_invariant_at(Container& container, Index index) {\\n try { return container.at(index); }\\n catch (const std::out_of_range& error) { ::pineforge::pine_engine_invariant(error.what()); }\\n}\\n#else\\n#define _PF_NO_DATA_STOP(function, call, line, english) pine_runtime_error(std::string(english))\\n#define _PF_OTHER_SYMBOL_STOP(function, symbol, call, line, english) pine_runtime_error(std::string(english))\\n#define _PF_ARRAY_STOP(reason, method, english) pine_runtime_error(english)\\n#define _PF_COLLECTION_STOP(reason, object, english) pine_runtime_error(english)\\n#define _PF_NA_STOP(object, english) throw std::runtime_error(english)\\n#define _PF_LIMIT_STOP(limit, max, english) throw std::length_error(english)\\n#define _PF_UNSUPPORTED_STOP(reason, line, english) pine_runtime_error(std::string(english))\\n#define _PF_STRING_STOP(reason, english) pine_runtime_error(std::string(english))\\n#define _PF_ENGINE_INVARIANT(english, legacy_type) throw legacy_type(english)\\n#define _PF_INVARIANT_AT(container, index) (container).at(index)\\n#define _PF_SETTING_FAILURE(strategy, entrypoint, message, reason) (strategy)->_pf_record_setting_failure(entrypoint, message)\\n#endif\\n\\n// --- syminfo derivation helpers (PineForge G2) ---\\nstatic inline std::string _pf_derive_prefix(const std::string& tickerid) {\\n std::size_t colon = tickerid.find(':');\\n return (colon == std::string::npos) ? tickerid : tickerid.substr(0, colon);\\n}\\n\\nstatic inline std::string _pf_derive_main_tickerid(const std::string& tickerid) {\\n // Strip trailing digits (optionally followed by '!') from the symbol part.\\n // e.g. \\\"CME_MINI:ES1!\\\" -> \\\"CME_MINI:ES\\\", \\\"NYMEX:CL2!\\\" -> \\\"NYMEX:CL\\\"\\n std::string result = tickerid;\\n std::size_t colon = result.find(':');\\n std::size_t start = (colon == std::string::npos) ? 0 : colon + 1;\\n // Find end of base symbol (strip trailing digits + optional '!')\\n std::size_t end = result.size();\\n if (end > start && result[end - 1] == '!') {\\n --end;\\n }\\n while (end > start && std::isdigit((unsigned char)result[end - 1])) {\\n --end;\\n }\\n return result.substr(0, end);\\n}\\n\\nstatic inline std::string _pf_derive_country(const std::string& tickerid) {\\n // Lookup country by exchange prefix (text before ':').\\n std::size_t colon = tickerid.find(':');\\n std::string prefix = (colon == std::string::npos)\\n ? tickerid : tickerid.substr(0, colon);\\n static const std::unordered_map _tbl = {\\n {\\\"AMEX\\\", \\\"US\\\"},\\n {\\\"AQUIS\\\", \\\"GB\\\"},\\n {\\\"ARCA\\\", \\\"US\\\"},\\n {\\\"ASX\\\", \\\"AU\\\"},\\n {\\\"B3\\\", \\\"BR\\\"},\\n {\\\"BMF\\\", \\\"BR\\\"},\\n {\\\"BMFBOVESPA\\\", \\\"BR\\\"},\\n {\\\"BSE\\\", \\\"IN\\\"},\\n {\\\"CBOE\\\", \\\"US\\\"},\\n {\\\"CBOT\\\", \\\"US\\\"},\\n {\\\"CME\\\", \\\"US\\\"},\\n {\\\"CME_MINI\\\", \\\"US\\\"},\\n {\\\"COINBASE\\\", \\\"US\\\"},\\n {\\\"COMEX\\\", \\\"US\\\"},\\n {\\\"HKEX\\\", \\\"HK\\\"},\\n {\\\"JSE\\\", \\\"ZA\\\"},\\n {\\\"KOSPI\\\", \\\"KR\\\"},\\n {\\\"KRX\\\", \\\"KR\\\"},\\n {\\\"LSE\\\", \\\"GB\\\"},\\n {\\\"MOEX\\\", \\\"RU\\\"},\\n {\\\"NASDAQ\\\", \\\"US\\\"},\\n {\\\"NSE\\\", \\\"IN\\\"},\\n {\\\"NYMEX\\\", \\\"US\\\"},\\n {\\\"NYSE\\\", \\\"US\\\"},\\n {\\\"OSE\\\", \\\"JP\\\"},\\n {\\\"OTC\\\", \\\"US\\\"},\\n {\\\"SGX\\\", \\\"SG\\\"},\\n {\\\"SIX\\\", \\\"CH\\\"},\\n {\\\"SSE\\\", \\\"CN\\\"},\\n {\\\"SZSE\\\", \\\"CN\\\"},\\n {\\\"TSE\\\", \\\"JP\\\"},\\n {\\\"TSX\\\", \\\"CA\\\"},\\n {\\\"UPBIT\\\", \\\"KR\\\"},\\n {\\\"VENTURE\\\", \\\"CA\\\"},\\n {\\\"XETRA\\\", \\\"DE\\\"}\\n };\\n auto it = _tbl.find(prefix);\\n return (it != _tbl.end()) ? it->second : na();\\n}\\n// --- end syminfo derivation helpers ---\\n\\nclass GeneratedStrategy : public pineforge::source::PineStrategyHost {\\npublic:\\n ta::EMA _ta_ema_1;\\n std::vector _precalc__ta_ema_1;\\n bool _use_precalc = false;\\n double x = 0.0;\\n bool _ta_initialized_ = false;\\n bool _inputs_initialized_ = false;\\n\\n struct _PFScriptState {\\n decltype(GeneratedStrategy::_ta_ema_1) _pf_value_0;\\n decltype(GeneratedStrategy::x) _pf_value_1;\\n decltype(GeneratedStrategy::_ta_initialized_) _pf_value_2;\\n decltype(GeneratedStrategy::_inputs_initialized_) _pf_value_3;\\n };\\n static_assert(std::is_copy_constructible_v<_PFScriptState>, \\\"generated Pine state must be deep-copy constructible\\\");\\n static_assert(std::is_copy_assignable_v<_PFScriptState>, \\\"generated Pine state must be deep-copy assignable\\\");\\n std::optional<_PFScriptState> _pf_script_state_checkpoint_;\\n\\n void snapshot_script_state() override {\\n _pf_script_state_checkpoint_.emplace(_PFScriptState{\\n _ta_ema_1,\\n x,\\n _ta_initialized_,\\n _inputs_initialized_,\\n });\\n }\\n\\n void restore_script_state() override {\\n if (!_pf_script_state_checkpoint_) return;\\n this->_ta_ema_1 = _pf_script_state_checkpoint_->_pf_value_0;\\n this->x = _pf_script_state_checkpoint_->_pf_value_1;\\n this->_ta_initialized_ = _pf_script_state_checkpoint_->_pf_value_2;\\n this->_inputs_initialized_ = _pf_script_state_checkpoint_->_pf_value_3;\\n }\\n\\n void commit_script_state() override {\\n snapshot_script_state();\\n }\\n\\n explicit GeneratedStrategy() : _ta_ema_1(20) {\\n#if defined(PINEFORGE_HAS_EXPLICIT_PINE_EXECUTION_ADAPTER_V1)\\n pineforge::source::PineStrategyHost::attach_pine_execution_adapter();\\n#elif defined(PINEFORGE_HAS_EXPLICIT_PINE_CAP_V1)\\n pineforge::source::PineStrategyHost::enable_pine_intraday_cap();\\n#endif\\n pineforge::source::PineStrategyConfig cfg{};\\n cfg.initial_capital = 100000.0;\\n cfg.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n cfg.default_qty_value = 100.0;\\n configure_pine_strategy(cfg);\\n }\\n\\n void set_strategy_override(const std::string& key, const std::string& value) {\\n pineforge::source::StrategyOverrides overrides{};\\n if (key == \\\"initial_capital\\\") {\\n overrides.initial_capital = std::stod(value);\\n } else if (key == \\\"commission_value\\\") {\\n overrides.commission_value = std::stod(value);\\n } else if (key == \\\"default_qty_value\\\") {\\n overrides.default_qty_value = std::stod(value);\\n } else if (key == \\\"pyramiding\\\") {\\n overrides.pyramiding = std::stoi(value);\\n } else if (key == \\\"slippage\\\") {\\n overrides.slippage = std::stoi(value);\\n } else if (key == \\\"process_orders_on_close\\\") {\\n overrides.process_orders_on_close = (value == \\\"true\\\" || value == \\\"1\\\");\\n } else if (key == \\\"calc_on_order_fills\\\") {\\n overrides.calc_on_order_fills = (value == \\\"true\\\" || value == \\\"1\\\");\\n } else if (key == \\\"close_entries_rule\\\") {\\n overrides.close_entries_rule = (value == \\\"ANY\\\" || value == \\\"any\\\" || value == \\\"1\\\");\\n } else if (key == \\\"default_qty_type\\\") {\\n if (value == \\\"fixed\\\" || value == \\\"strategy.fixed\\\" || value == \\\"0\\\") overrides.default_qty_type = static_cast(QtyType::FIXED);\\n else if (value == \\\"percent_of_equity\\\" || value == \\\"strategy.percent_of_equity\\\" || value == \\\"1\\\") overrides.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n else if (value == \\\"cash\\\" || value == \\\"strategy.cash\\\" || value == \\\"2\\\") overrides.default_qty_type = static_cast(QtyType::CASH);\\n else return;\\n } else if (key == \\\"commission_type\\\") {\\n if (value == \\\"percent\\\" || value == \\\"strategy.commission.percent\\\" || value == \\\"0\\\") overrides.commission_type = static_cast(CommissionType::PERCENT);\\n else if (value == \\\"cash_per_order\\\" || value == \\\"strategy.commission.cash_per_order\\\" || value == \\\"1\\\") overrides.commission_type = static_cast(CommissionType::CASH_PER_ORDER);\\n else if (value == \\\"cash_per_contract\\\" || value == \\\"strategy.commission.cash_per_contract\\\" || value == \\\"2\\\") overrides.commission_type = static_cast(CommissionType::CASH_PER_CONTRACT);\\n else return;\\n } else {\\n return;\\n }\\n pineforge::source::PineStrategyHost::set_strategy_override(overrides);\\n }\\n bool _pf_setting_failed_ = false;\\n std::string _pf_setting_failure_;\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n ::pineforge::RunFailureInfo _pf_setting_failure_info_{::pineforge::RunFailureCode::none, {}};\\n#ifdef PF_SETTINGS_API_VERSION\\n using _pf_setting_error_base = ::pineforge::checked_settings::LatchedSettingsFailure;\\n#else\\n using _pf_setting_error_base = std::runtime_error;\\n#endif\\n struct _pf_latched_setting_error : _pf_setting_error_base, ::pineforge::RunFailureInfo {\\n _pf_latched_setting_error(const std::string& text, const ::pineforge::RunFailureInfo& info)\\n : _pf_setting_error_base(text), ::pineforge::RunFailureInfo(info) {}\\n };\\n#endif\\n void _pf_record_failure(const char* entrypoint, const char* message) noexcept {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure_unknown(*this, entrypoint); } catch (...) {}\\n#else\\n try { last_error_ = entrypoint; last_error_ += \\\": \\\"; last_error_ += message; } catch (...) {}\\n#endif\\n }\\n void _pf_record_failure(const char* entrypoint, const std::exception& error) noexcept {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure(*this, entrypoint, error); } catch (...) {}\\n#else\\n _pf_record_failure(entrypoint, error.what());\\n#endif\\n }\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n template \\n void _pf_record_setting_failure(const char* entrypoint, const char* message, FailureInfo failure_info) noexcept {\\n#else\\n void _pf_record_setting_failure(const char* entrypoint, const char* message) noexcept {\\n#endif\\n if (!_pf_setting_failed_) {\\n _pf_setting_failed_ = true;\\n try { _pf_setting_failure_ = entrypoint; _pf_setting_failure_ += \\\": \\\"; _pf_setting_failure_ += message; } catch (...) {}\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { _pf_setting_failure_info_ = failure_info(); }\\n catch (...) { _pf_setting_failure_info_ = ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::out_of_memory, {}); }\\n#endif\\n }\\n _pf_refuse_failed_setting(nullptr);\\n }\\n void _pf_require_settings_ok() const {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n if (_pf_setting_failed_) throw _pf_latched_setting_error(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_, _pf_setting_failure_info_);\\n#elif defined(PF_SETTINGS_API_VERSION)\\n if (_pf_setting_failed_) throw ::pineforge::checked_settings::LatchedSettingsFailure(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_);\\n#else\\n if (_pf_setting_failed_) throw std::runtime_error(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_);\\n#endif\\n }\\n bool _pf_refuse_failed_setting(ReportC* out) noexcept {\\n if (!_pf_setting_failed_) return false;\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure(*this, _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_, _pf_setting_failure_info_.run_failure()); } catch (...) {}\\n#else\\n try { last_error_ = _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_; } catch (...) {}\\n#endif\\n if (out) *out = ReportC{};\\n return true;\\n }\\n#ifdef PF_SETTINGS_API_VERSION\\n static pineforge::source::PineStrategyConfig _pf_settings_declared_config() {\\n pineforge::source::PineStrategyConfig cfg{};\\n cfg.initial_capital = 100000.0;\\n cfg.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n cfg.default_qty_value = 100.0;\\n return cfg;\\n }\\n std::vector<::pineforge::checked_settings::Setting> _pf_settings_inputs() const {\\n return {\\n };\\n }\\n std::vector<::pineforge::checked_settings::Setting> _pf_settings_overrides() const {\\n const double _pf_nan = std::numeric_limits::quiet_NaN();\\n const auto _pf_defaults = _pf_settings_declared_config();\\n return {\\n {\\\"initial_capital\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.initial_capital), {}, 0.0},\\n {\\\"commission_value\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.commission_value), {}, 0.0},\\n {\\\"default_qty_value\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.default_qty_value), {}, 0.0},\\n {\\\"pyramiding\\\", \\\"int\\\", ::pineforge::checked_settings::number(_pf_defaults.pyramiding), {}, 0.0},\\n {\\\"slippage\\\", \\\"int\\\", ::pineforge::checked_settings::number(_pf_defaults.slippage), {}, 0.0},\\n {\\\"process_orders_on_close\\\", \\\"bool\\\", ::pineforge::checked_settings::number(_pf_defaults.process_orders_on_close), {}, _pf_nan},\\n {\\\"calc_on_order_fills\\\", \\\"bool\\\", ::pineforge::checked_settings::number(_pf_defaults.calc_on_order_fills), {}, _pf_nan},\\n {\\\"close_entries_rule\\\", \\\"string\\\", _pf_close_entries_rule_word(_pf_defaults.close_entries_rule_any), {\\\"FIFO\\\", \\\"ANY\\\"}, _pf_nan},\\n {\\\"default_qty_type\\\", \\\"string\\\", _pf_default_qty_type_word(_pf_defaults.default_qty_type), {\\\"fixed\\\", \\\"percent_of_equity\\\", \\\"cash\\\"}, _pf_nan},\\n {\\\"commission_type\\\", \\\"string\\\", _pf_commission_type_word(_pf_defaults.commission_type), {\\\"percent\\\", \\\"cash_per_order\\\", \\\"cash_per_contract\\\"}, _pf_nan},\\n };\\n }\\n static std::string _pf_close_entries_rule_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"FIFO\\\";\\n if (_pf_value == 1) return \\\"ANY\\\";\\n return \\\"invalid\\\";\\n }\\n static std::string _pf_default_qty_type_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"fixed\\\";\\n if (_pf_value == 1) return \\\"percent_of_equity\\\";\\n if (_pf_value == 2) return \\\"cash\\\";\\n return \\\"invalid\\\";\\n }\\n static std::string _pf_commission_type_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"percent\\\";\\n if (_pf_value == 1) return \\\"cash_per_order\\\";\\n if (_pf_value == 2) return \\\"cash_per_contract\\\";\\n return \\\"invalid\\\";\\n }\\n void _pf_set_input_checked(const std::string& _pf_key, const std::string& _pf_value) {\\n if (_pf_refuse_failed_setting(nullptr)) throw ::pineforge::checked_settings::Error{PF_SETTINGS_RUN_FAILED, last_error_.c_str()};\\n ::pineforge::checked_settings::require(script_bars_processed() == 0 && stream_phase_ == StreamPhase::IDLE, \\\"settings are frozen after execution begins\\\", PF_SETTINGS_UNSUPPORTED);\\n const auto _pf_inputs = _pf_settings_inputs();\\n const ::pineforge::checked_settings::Setting* _pf_match = nullptr;\\n for (const auto& _pf_input : _pf_inputs) {\\n if (_pf_input.name != _pf_key) continue;\\n ::pineforge::checked_settings::require(_pf_match == nullptr, \\\"ambiguous input key\\\", PF_SETTINGS_UNSUPPORTED);\\n _pf_match = &_pf_input;\\n }\\n ::pineforge::checked_settings::require(_pf_match != nullptr, \\\"unknown input key\\\");\\n const auto _pf_canonical = ::pineforge::checked_settings::validate(*_pf_match, _pf_value);\\n set_input(_pf_key, _pf_canonical);\\n ::pineforge::checked_settings::require(inputs_.count(_pf_key) && inputs_.at(_pf_key) == _pf_canonical, \\\"input was not installed\\\", PF_SETTINGS_UNSUPPORTED);\\n }\\n void _pf_set_override_checked(const std::string& _pf_key, const std::string& _pf_value) {\\n if (_pf_refuse_failed_setting(nullptr)) throw ::pineforge::checked_settings::Error{PF_SETTINGS_RUN_FAILED, last_error_.c_str()};\\n ::pineforge::checked_settings::require(script_bars_processed() == 0 && stream_phase_ == StreamPhase::IDLE, \\\"settings are frozen after execution begins\\\", PF_SETTINGS_UNSUPPORTED);\\n for (const auto& _pf_override : _pf_settings_overrides()) {\\n if (_pf_override.name != _pf_key) continue;\\n auto _pf_alias = _pf_value;\\n if (_pf_key == \\\"close_entries_rule\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"fifo\\\") _pf_alias = \\\"FIFO\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"any\\\") _pf_alias = \\\"ANY\\\";\\n }\\n if (_pf_key == \\\"default_qty_type\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"strategy.fixed\\\") _pf_alias = \\\"fixed\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"strategy.percent_of_equity\\\") _pf_alias = \\\"percent_of_equity\\\";\\n if (_pf_value == \\\"2\\\" || _pf_value == \\\"strategy.cash\\\") _pf_alias = \\\"cash\\\";\\n }\\n if (_pf_key == \\\"commission_type\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"strategy.commission.percent\\\") _pf_alias = \\\"percent\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"strategy.commission.cash_per_order\\\") _pf_alias = \\\"cash_per_order\\\";\\n if (_pf_value == \\\"2\\\" || _pf_value == \\\"strategy.commission.cash_per_contract\\\") _pf_alias = \\\"cash_per_contract\\\";\\n }\\n const auto _pf_canonical = ::pineforge::checked_settings::validate(_pf_override, _pf_alias);\\n set_strategy_override(_pf_key, _pf_canonical);\\n return;\\n }\\n throw ::pineforge::checked_settings::Error{PF_SETTINGS_INVALID_ARGUMENT, \\\"unknown override key\\\"};\\n }\\n std::string _pf_settings_receipt() const {\\n ::pineforge::checked_settings::require(!_pf_setting_failed_, _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_.c_str(), PF_SETTINGS_RUN_FAILED);\\n std::string _pf_document = \\\"{\\\\\\\"version\\\\\\\":1,\\\\\\\"inputs\\\\\\\":[\\\";\\n const auto _pf_inputs = _pf_settings_inputs();\\n _pf_document += \\\"],\\\\\\\"overrides\\\\\\\":[\\\";\\n const auto _pf_overrides = _pf_settings_overrides();\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[0], ::pineforge::checked_settings::number((std::isnan(override_.initial_capital) ? config_.initial_capital : override_.initial_capital)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[1], ::pineforge::checked_settings::number((std::isnan(override_.commission_value) ? config_.commission_value : override_.commission_value)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[2], ::pineforge::checked_settings::number((std::isnan(override_.default_qty_value) ? config_.default_qty_value : override_.default_qty_value)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[3], ::pineforge::checked_settings::number((override_.pyramiding < 0 ? config_.pyramiding : override_.pyramiding)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[4], ::pineforge::checked_settings::number((override_.slippage < 0 ? config_.slippage : override_.slippage)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[5], ::pineforge::checked_settings::number(static_cast((override_.process_orders_on_close < 0 ? config_.process_orders_on_close : override_.process_orders_on_close))));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[6], ::pineforge::checked_settings::number(static_cast((override_.calc_on_order_fills < 0 ? config_.calc_on_order_fills : override_.calc_on_order_fills))));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[7], _pf_close_entries_rule_word((override_.close_entries_rule < 0 ? config_.close_entries_rule_any : override_.close_entries_rule)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[8], _pf_default_qty_type_word((override_.default_qty_type < 0 ? config_.default_qty_type : override_.default_qty_type)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[9], _pf_commission_type_word((override_.commission_type < 0 ? config_.commission_type : override_.commission_type)));\\n return _pf_document + \\\"]}\\\";\\n }\\n#endif\\n\\n#ifndef PINEFORGE_HAS_SCRIPT_RUN_PREPARE_V1\\n#error \\\"Generated lifecycle reset requires a matching PineForge engine; rebuild with script-run preparation support\\\"\\n#endif\\n void prepare_script_run(const Bar* bars, int n, bool allow_precalculation) override {\\n _pf_require_settings_ok();\\n _pf_script_state_checkpoint_.reset();\\n this->_ta_ema_1 = decltype(this->_ta_ema_1)(20);\\n this->_precalc__ta_ema_1 = decltype(this->_precalc__ta_ema_1){};\\n this->_use_precalc = false;\\n this->x = 0.0;\\n this->_ta_initialized_ = false;\\n this->_inputs_initialized_ = false;\\n if (allow_precalculation) precalculate(bars, n);\\n }\\n\\n void on_source_bar(const Bar& bar) override {\\n x = (history_advances_new_bar() ? _ta_ema_1.compute(current_bar_.close) : _ta_ema_1.recompute(current_bar_.close));\\n }\\n\\n void precalculate(const Bar* bars, int n) {\\n _use_precalc = false;\\n if (n <= 0 || bars == nullptr) return;\\n\\n _precalc__ta_ema_1.resize(n);\\n\\n _ta_ema_1 = ta::EMA(20);\\n\\n\\n for (int i = 0; i < n; ++i) {\\n if (_src_series_active_) {\\n const double _pc_o = bars[i].open;\\n const double _pc_h = bars[i].high;\\n const double _pc_l = bars[i].low;\\n const double _pc_c = bars[i].close;\\n const double _pc_v = bars[i].volume;\\n _src_open_.push(_pc_o); _src_high_.push(_pc_h); _src_low_.push(_pc_l);\\n _src_close_.push(_pc_c); _src_volume_.push(_pc_v);\\n _src_hl2_.push((_pc_h + _pc_l) / 2.0);\\n _src_hlc3_.push((_pc_h + _pc_l + _pc_c) / 3.0);\\n _src_ohlc4_.push((_pc_o + _pc_h + _pc_l + _pc_c) / 4.0);\\n _src_hlcc4_.push((_pc_h + _pc_l + _pc_c + _pc_c) / 4.0);\\n }\\n _precalc__ta_ema_1[i] = _ta_ema_1.compute(bars[i].close);\\n }\\n\\n _ta_ema_1 = ta::EMA(20);\\n\\n _use_precalc = true;\\n }\\n\\n\\n};\\n\\nextern \\\"C\\\" {\\n#if defined(PINEFORGE_HAS_RUN_FAILURE_CODES_V1) && defined(PF_SETTINGS_API_VERSION)\\n int strategy_create_checked(const char* params_json, void** out, char* error, size_t error_capacity);\\n#endif\\n void* strategy_create(const char* params_json) {\\n#if defined(PINEFORGE_HAS_RUN_FAILURE_CODES_V1) && defined(PF_SETTINGS_API_VERSION)\\n void* out = nullptr;\\n strategy_create_checked(nullptr, &out, nullptr, 0);\\n return out;\\n#else\\n try { return new GeneratedStrategy(); } catch (...) { return nullptr; }\\n#endif\\n }\\n void run_backtest(void* s, Bar* bars, int n, ReportC* out) {\\n try {\\n auto* strat = static_cast(s);\\n#ifndef PF_SETTINGS_API_VERSION\\n if (strat->_pf_refuse_failed_setting(out)) return;\\n#endif\\n strat->run(bars, n);\\n if (!strat->_pf_refuse_failed_setting(out)) strat->fill_report(out);\\n } catch (const std::exception& _pf_error) {\\n if (out) *out = ReportC{};\\n if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest\\\", _pf_error);\\n } catch (...) {\\n if (out) *out = ReportC{};\\n if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest\\\", \\\"unknown C++ exception\\\");\\n }\\n }\\n static void _pf_run_backtest_full_impl(void* s, Bar* bars, int n,\\n const char* input_tf, const char* script_tf,\\n int bar_magnifier, int magnifier_samples,\\n int magnifier_dist,\\n ReportC* out) {\\n auto* strat = static_cast(s);\\n#ifndef PF_SETTINGS_API_VERSION\\n if (strat->_pf_refuse_failed_setting(out)) return;\\n#endif\\n std::string itf = input_tf ? input_tf : \\\"\\\";\\n std::string stf = script_tf ? script_tf : \\\"\\\";\\n bool needs_full_run = (bar_magnifier != 0)\\n || !itf.empty() || !stf.empty();\\n if (!needs_full_run) {\\n strat->run(bars, n);\\n } else {\\n strat->run(bars, n, itf, stf, bar_magnifier != 0, magnifier_samples,\\n static_cast(magnifier_dist));\\n }\\n if (!strat->_pf_refuse_failed_setting(out)) strat->fill_report(out);\\n }\\n void run_backtest_full(void* s, Bar* bars, int n, const char* input_tf, const char* script_tf,\\n int bar_magnifier, int magnifier_samples, int magnifier_dist, ReportC* out) {\\n try { _pf_run_backtest_full_impl(s, bars, n, input_tf, script_tf, bar_magnifier, magnifier_samples, magnifier_dist, out); }\\n catch (const std::exception& _pf_error) { if (out) *out = ReportC{}; if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest_full\\\", _pf_error); }\\n catch (...) { if (out) *out = ReportC{}; if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest_full\\\", \\\"unknown C++ exception\\\"); }\\n }\\n void strategy_free(void* s) {\\n try { delete static_cast(s); } catch (...) {}\\n }\\n void report_free(ReportC* report) {\\n try { BacktestEngine::free_report(report); } catch (...) {}\\n }\\n void strategy_set_input(void* s, const char* key, const char* value) {\\n if (!s || !key || !value) return;\\n try { static_cast(s)->set_input(key, value); }\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_input\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_input\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n void strategy_set_override(void* s, const char* key, const char* value) {\\n if (!s || !key || !value) return;\\n try { static_cast(s)->set_strategy_override(key, value); }\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n catch (const std::invalid_argument& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), \\\"unparseable_value\\\"); }\\n catch (const std::out_of_range& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), \\\"unparseable_value\\\"); }\\n#endif\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n void strategy_set_magnifier_volume_weighted(void* s, int on) {\\n if (!s) return;\\n try { static_cast(s)->set_magnifier_volume_weighted(on != 0); }\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_magnifier_volume_weighted\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_magnifier_volume_weighted\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n#ifdef PF_SETTINGS_API_VERSION\\n uint32_t strategy_settings_api_version(void) { return PF_SETTINGS_API_VERSION; }\\n int strategy_create_checked(const char* params_json, void** out, char* error, size_t error_capacity) {\\n if (out) *out = nullptr;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(out != nullptr, \\\"strategy output pointer is null\\\");\\n ::pineforge::checked_settings::require(!params_json || !*params_json, \\\"params_json is reserved; use checked setters\\\", PF_SETTINGS_UNSUPPORTED);\\n *out = new GeneratedStrategy();\\n });\\n }\\n int strategy_set_input_checked(void* s, const char* key, const char* value, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && key && value, \\\"null strategy, key or value\\\");\\n static_cast(s)->_pf_set_input_checked(key, value);\\n });\\n }\\n int strategy_set_override_checked(void* s, const char* key, const char* value, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && key && value, \\\"null strategy, key or value\\\");\\n static_cast(s)->_pf_set_override_checked(key, value);\\n });\\n }\\n int strategy_get_effective_settings(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(static_cast(s)->_pf_settings_receipt(), json, capacity, required);\\n });\\n }\\n int run_backtest_full_checked(void* s, Bar* bars, int n, const char* input_tf, const char* script_tf, int bar_magnifier, int magnifier_samples, int magnifier_dist, ReportC* out, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && out && n >= 0 && (n == 0 || bars), \\\"invalid batch arguments\\\");\\n _pf_run_backtest_full_impl(s, bars, n, input_tf, script_tf, bar_magnifier, magnifier_samples, magnifier_dist, out);\\n const auto& _pf_error = static_cast(s)->last_error();\\n ::pineforge::checked_settings::require(_pf_error.empty(), _pf_error.c_str(), PF_SETTINGS_RUN_FAILED);\\n });\\n }\\n#endif\\n#ifdef PF_SETTINGS_API_VERSION\\n#ifdef PF_CAPABILITIES_API_VERSION\\n uint32_t strategy_capabilities_api_version(void) { return PF_CAPABILITIES_API_VERSION; }\\n int strategy_capabilities_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"declarations\\\\\\\":{\\\\\\\"backtest_fill_limits_assumption\\\\\\\":0,\\\\\\\"calc_on_every_history_tick\\\\\\\":false,\\\\\\\"calc_on_every_tick\\\\\\\":false,\\\\\\\"calc_on_order_fills\\\\\\\":false,\\\\\\\"currency\\\\\\\":\\\\\\\"currency.NONE\\\\\\\",\\\\\\\"dynamic_requests\\\\\\\":true,\\\\\\\"fill_orders_on_standard_ohlc\\\\\\\":false,\\\\\\\"process_orders_on_close\\\\\\\":false,\\\\\\\"timeframe\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"timeframe_gaps\\\\\\\":true,\\\\\\\"use_bar_magnifier\\\\\\\":false},\\\\\\\"requests\\\\\\\":[],\\\\\\\"requirements\\\\\\\":{\\\\\\\"auxiliary_security_feeds\\\\\\\":false,\\\\\\\"fx_curve\\\\\\\":false,\\\\\\\"historical_probe_overrides\\\\\\\":false,\\\\\\\"intrabar_persistence\\\\\\\":false,\\\\\\\"native_security_feeds\\\\\\\":false,\\\\\\\"recorded_series\\\\\\\":false},\\\\\\\"unresolved\\\\\\\":[],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n uint32_t strategy_confirmed_bar_api_version(void) { return 1u; }\\n int strategy_confirmed_bar_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"intrabar_persistence\\\\\\\":false,\\\\\\\"orders\\\\\\\":[],\\\\\\\"requests\\\\\\\":[],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n uint32_t strategy_order_shapes_api_version(void) { return 1u; }\\n int strategy_order_shapes_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"calls\\\\\\\":[],\\\\\\\"entry_ids\\\\\\\":{\\\\\\\"long\\\\\\\":0,\\\\\\\"multi_site\\\\\\\":0,\\\\\\\"shared\\\\\\\":0,\\\\\\\"short\\\\\\\":0},\\\\\\\"host_reads\\\\\\\":[\\\\\\\"StreamPhase\\\\\\\",\\\\\\\"_src_close_\\\\\\\",\\\\\\\"_src_high_\\\\\\\",\\\\\\\"_src_hl2_\\\\\\\",\\\\\\\"_src_hlc3_\\\\\\\",\\\\\\\"_src_hlcc4_\\\\\\\",\\\\\\\"_src_low_\\\\\\\",\\\\\\\"_src_ohlc4_\\\\\\\",\\\\\\\"_src_open_\\\\\\\",\\\\\\\"_src_series_active_\\\\\\\",\\\\\\\"_src_volume_\\\\\\\",\\\\\\\"commit_script_state\\\\\\\",\\\\\\\"config_\\\\\\\",\\\\\\\"configure_pine_strategy\\\\\\\",\\\\\\\"current_bar_\\\\\\\",\\\\\\\"fill_report\\\\\\\",\\\\\\\"history_advances_new_bar\\\\\\\",\\\\\\\"inputs_\\\\\\\",\\\\\\\"last_error\\\\\\\",\\\\\\\"last_error_\\\\\\\",\\\\\\\"on_source_bar\\\\\\\",\\\\\\\"override_\\\\\\\",\\\\\\\"prepare_script_run\\\\\\\",\\\\\\\"restore_script_state\\\\\\\",\\\\\\\"run\\\\\\\",\\\\\\\"script_bars_processed\\\\\\\",\\\\\\\"set_input\\\\\\\",\\\\\\\"set_magnifier_volume_weighted\\\\\\\",\\\\\\\"set_strategy_override\\\\\\\",\\\\\\\"snapshot_script_state\\\\\\\",\\\\\\\"stream_phase_\\\\\\\"],\\\\\\\"process_orders_on_close\\\\\\\":false,\\\\\\\"settings\\\\\\\":{\\\\\\\"close_entries_rule\\\\\\\":\\\\\\\"FIFO\\\\\\\",\\\\\\\"commission_type\\\\\\\":\\\\\\\"percent\\\\\\\",\\\\\\\"commission_value\\\\\\\":0.0,\\\\\\\"default_qty_type\\\\\\\":\\\\\\\"percent_of_equity\\\\\\\",\\\\\\\"default_qty_value\\\\\\\":100.0,\\\\\\\"initial_capital\\\\\\\":100000.0,\\\\\\\"margin_long\\\\\\\":100.0,\\\\\\\"margin_short\\\\\\\":100.0,\\\\\\\"pyramiding\\\\\\\":1,\\\\\\\"slippage\\\\\\\":0},\\\\\\\"unmodeled\\\\\\\":[],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n#endif\\n#endif\\n}\\n\", \"inputs\": [], \"strategyParams\": {\"title\": \"EMA \\u8a3a\\u65b7\"}, \"diagnostics\": [{\"line\": 3, \"col\": 11, \"message\": \"ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does. \\u2014 A covered length-20 TradingView tape first returns a finite EMA at bar 19; standalone PineForge EMA is finite at bar 0. Its established lowering stays in place pending per-call-site population parity.\", \"severity\": \"warning\", \"code\": \"PF-W1505\", \"args\": {}, \"endCol\": 12}, {\"line\": 4, \"col\": 5, \"message\": \"plot(...) has no effect in PineForge backtests (visual only).\", \"severity\": \"warning\", \"code\": \"PF-W1508\", \"args\": {\"name\": \"plot\"}, \"endCol\": 6}], \"requests\": []}", + "visual_only": "{\"ok\": true, \"cpp\": \"#include \\n#include \\n#if __has_include()\\n#include \\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#ifndef PINEFORGE_HAS_NATIVE_LOWERING_V1\\n#error \\\"generated code requires pineforge-engine native lowering v1 (PINEFORGE_HAS_NATIVE_LOWERING_V1)\\\"\\n#endif\\n\\nusing namespace pineforge;\\n\\n\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n#define _PF_NO_DATA_STOP(function, call, line, english) ::pineforge::pine_no_data_stop(function, call, line, english)\\n#define _PF_OTHER_SYMBOL_STOP(function, symbol, call, line, english) ::pineforge::pine_other_symbol_stop(function, symbol, call, line, english)\\n#define _PF_ARRAY_STOP(reason, method, english) ::pineforge::pine_array_stop(reason, method, std::string(english).c_str())\\n#define _PF_COLLECTION_STOP(reason, object, english) ::pineforge::pine_collection_stop(object, reason, english)\\n#define _PF_NA_STOP(object, english) ::pineforge::pine_na_stop(object, english)\\n#define _PF_LIMIT_STOP(limit, max, english) ::pineforge::pine_limit_stop(limit, max, english)\\n#define _PF_UNSUPPORTED_STOP(reason, line, english) ::pineforge::pine_unsupported_stop(reason, line, english)\\n#define _PF_STRING_STOP(reason, english) ::pineforge::pine_string_stop(reason, english)\\n#define _PF_ENGINE_INVARIANT(english, legacy_type) ::pineforge::pine_engine_invariant(english)\\n#define _PF_INVARIANT_AT(container, index) _pf_invariant_at(container, index)\\n#define _PF_SETTING_FAILURE(strategy, entrypoint, message, reason) (strategy)->_pf_record_setting_failure(entrypoint, message, [] { return reason ? ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::setting_rejected, {{\\\"entrypoint\\\", entrypoint}, {\\\"reason\\\", reason}}) : ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::setting_rejected, {{\\\"entrypoint\\\", entrypoint}}); })\\ntemplate \\ndecltype(auto) _pf_invariant_at(Container& container, Index index) {\\n try { return container.at(index); }\\n catch (const std::out_of_range& error) { ::pineforge::pine_engine_invariant(error.what()); }\\n}\\n#else\\n#define _PF_NO_DATA_STOP(function, call, line, english) pine_runtime_error(std::string(english))\\n#define _PF_OTHER_SYMBOL_STOP(function, symbol, call, line, english) pine_runtime_error(std::string(english))\\n#define _PF_ARRAY_STOP(reason, method, english) pine_runtime_error(english)\\n#define _PF_COLLECTION_STOP(reason, object, english) pine_runtime_error(english)\\n#define _PF_NA_STOP(object, english) throw std::runtime_error(english)\\n#define _PF_LIMIT_STOP(limit, max, english) throw std::length_error(english)\\n#define _PF_UNSUPPORTED_STOP(reason, line, english) pine_runtime_error(std::string(english))\\n#define _PF_STRING_STOP(reason, english) pine_runtime_error(std::string(english))\\n#define _PF_ENGINE_INVARIANT(english, legacy_type) throw legacy_type(english)\\n#define _PF_INVARIANT_AT(container, index) (container).at(index)\\n#define _PF_SETTING_FAILURE(strategy, entrypoint, message, reason) (strategy)->_pf_record_setting_failure(entrypoint, message)\\n#endif\\n\\n// --- syminfo derivation helpers (PineForge G2) ---\\nstatic inline std::string _pf_derive_prefix(const std::string& tickerid) {\\n std::size_t colon = tickerid.find(':');\\n return (colon == std::string::npos) ? tickerid : tickerid.substr(0, colon);\\n}\\n\\nstatic inline std::string _pf_derive_main_tickerid(const std::string& tickerid) {\\n // Strip trailing digits (optionally followed by '!') from the symbol part.\\n // e.g. \\\"CME_MINI:ES1!\\\" -> \\\"CME_MINI:ES\\\", \\\"NYMEX:CL2!\\\" -> \\\"NYMEX:CL\\\"\\n std::string result = tickerid;\\n std::size_t colon = result.find(':');\\n std::size_t start = (colon == std::string::npos) ? 0 : colon + 1;\\n // Find end of base symbol (strip trailing digits + optional '!')\\n std::size_t end = result.size();\\n if (end > start && result[end - 1] == '!') {\\n --end;\\n }\\n while (end > start && std::isdigit((unsigned char)result[end - 1])) {\\n --end;\\n }\\n return result.substr(0, end);\\n}\\n\\nstatic inline std::string _pf_derive_country(const std::string& tickerid) {\\n // Lookup country by exchange prefix (text before ':').\\n std::size_t colon = tickerid.find(':');\\n std::string prefix = (colon == std::string::npos)\\n ? tickerid : tickerid.substr(0, colon);\\n static const std::unordered_map _tbl = {\\n {\\\"AMEX\\\", \\\"US\\\"},\\n {\\\"AQUIS\\\", \\\"GB\\\"},\\n {\\\"ARCA\\\", \\\"US\\\"},\\n {\\\"ASX\\\", \\\"AU\\\"},\\n {\\\"B3\\\", \\\"BR\\\"},\\n {\\\"BMF\\\", \\\"BR\\\"},\\n {\\\"BMFBOVESPA\\\", \\\"BR\\\"},\\n {\\\"BSE\\\", \\\"IN\\\"},\\n {\\\"CBOE\\\", \\\"US\\\"},\\n {\\\"CBOT\\\", \\\"US\\\"},\\n {\\\"CME\\\", \\\"US\\\"},\\n {\\\"CME_MINI\\\", \\\"US\\\"},\\n {\\\"COINBASE\\\", \\\"US\\\"},\\n {\\\"COMEX\\\", \\\"US\\\"},\\n {\\\"HKEX\\\", \\\"HK\\\"},\\n {\\\"JSE\\\", \\\"ZA\\\"},\\n {\\\"KOSPI\\\", \\\"KR\\\"},\\n {\\\"KRX\\\", \\\"KR\\\"},\\n {\\\"LSE\\\", \\\"GB\\\"},\\n {\\\"MOEX\\\", \\\"RU\\\"},\\n {\\\"NASDAQ\\\", \\\"US\\\"},\\n {\\\"NSE\\\", \\\"IN\\\"},\\n {\\\"NYMEX\\\", \\\"US\\\"},\\n {\\\"NYSE\\\", \\\"US\\\"},\\n {\\\"OSE\\\", \\\"JP\\\"},\\n {\\\"OTC\\\", \\\"US\\\"},\\n {\\\"SGX\\\", \\\"SG\\\"},\\n {\\\"SIX\\\", \\\"CH\\\"},\\n {\\\"SSE\\\", \\\"CN\\\"},\\n {\\\"SZSE\\\", \\\"CN\\\"},\\n {\\\"TSE\\\", \\\"JP\\\"},\\n {\\\"TSX\\\", \\\"CA\\\"},\\n {\\\"UPBIT\\\", \\\"KR\\\"},\\n {\\\"VENTURE\\\", \\\"CA\\\"},\\n {\\\"XETRA\\\", \\\"DE\\\"}\\n };\\n auto it = _tbl.find(prefix);\\n return (it != _tbl.end()) ? it->second : na();\\n}\\n// --- end syminfo derivation helpers ---\\n\\nclass GeneratedStrategy : public pineforge::source::PineStrategyHost {\\npublic:\\n bool _use_precalc = false;\\n double t = 0.0;\\n bool _inputs_initialized_ = false;\\n\\n struct _PFScriptState {\\n decltype(GeneratedStrategy::t) _pf_value_0;\\n decltype(GeneratedStrategy::_inputs_initialized_) _pf_value_1;\\n };\\n static_assert(std::is_copy_constructible_v<_PFScriptState>, \\\"generated Pine state must be deep-copy constructible\\\");\\n static_assert(std::is_copy_assignable_v<_PFScriptState>, \\\"generated Pine state must be deep-copy assignable\\\");\\n std::optional<_PFScriptState> _pf_script_state_checkpoint_;\\n\\n void snapshot_script_state() override {\\n _pf_script_state_checkpoint_.emplace(_PFScriptState{\\n t,\\n _inputs_initialized_,\\n });\\n }\\n\\n void restore_script_state() override {\\n if (!_pf_script_state_checkpoint_) return;\\n this->t = _pf_script_state_checkpoint_->_pf_value_0;\\n this->_inputs_initialized_ = _pf_script_state_checkpoint_->_pf_value_1;\\n }\\n\\n void commit_script_state() override {\\n snapshot_script_state();\\n }\\n\\n explicit GeneratedStrategy() {\\n#if defined(PINEFORGE_HAS_EXPLICIT_PINE_EXECUTION_ADAPTER_V1)\\n pineforge::source::PineStrategyHost::attach_pine_execution_adapter();\\n#elif defined(PINEFORGE_HAS_EXPLICIT_PINE_CAP_V1)\\n pineforge::source::PineStrategyHost::enable_pine_intraday_cap();\\n#endif\\n pineforge::source::PineStrategyConfig cfg{};\\n cfg.initial_capital = 100000.0;\\n cfg.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n cfg.default_qty_value = 100.0;\\n configure_pine_strategy(cfg);\\n }\\n\\n void set_strategy_override(const std::string& key, const std::string& value) {\\n pineforge::source::StrategyOverrides overrides{};\\n if (key == \\\"initial_capital\\\") {\\n overrides.initial_capital = std::stod(value);\\n } else if (key == \\\"commission_value\\\") {\\n overrides.commission_value = std::stod(value);\\n } else if (key == \\\"default_qty_value\\\") {\\n overrides.default_qty_value = std::stod(value);\\n } else if (key == \\\"pyramiding\\\") {\\n overrides.pyramiding = std::stoi(value);\\n } else if (key == \\\"slippage\\\") {\\n overrides.slippage = std::stoi(value);\\n } else if (key == \\\"process_orders_on_close\\\") {\\n overrides.process_orders_on_close = (value == \\\"true\\\" || value == \\\"1\\\");\\n } else if (key == \\\"calc_on_order_fills\\\") {\\n overrides.calc_on_order_fills = (value == \\\"true\\\" || value == \\\"1\\\");\\n } else if (key == \\\"close_entries_rule\\\") {\\n overrides.close_entries_rule = (value == \\\"ANY\\\" || value == \\\"any\\\" || value == \\\"1\\\");\\n } else if (key == \\\"default_qty_type\\\") {\\n if (value == \\\"fixed\\\" || value == \\\"strategy.fixed\\\" || value == \\\"0\\\") overrides.default_qty_type = static_cast(QtyType::FIXED);\\n else if (value == \\\"percent_of_equity\\\" || value == \\\"strategy.percent_of_equity\\\" || value == \\\"1\\\") overrides.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n else if (value == \\\"cash\\\" || value == \\\"strategy.cash\\\" || value == \\\"2\\\") overrides.default_qty_type = static_cast(QtyType::CASH);\\n else return;\\n } else if (key == \\\"commission_type\\\") {\\n if (value == \\\"percent\\\" || value == \\\"strategy.commission.percent\\\" || value == \\\"0\\\") overrides.commission_type = static_cast(CommissionType::PERCENT);\\n else if (value == \\\"cash_per_order\\\" || value == \\\"strategy.commission.cash_per_order\\\" || value == \\\"1\\\") overrides.commission_type = static_cast(CommissionType::CASH_PER_ORDER);\\n else if (value == \\\"cash_per_contract\\\" || value == \\\"strategy.commission.cash_per_contract\\\" || value == \\\"2\\\") overrides.commission_type = static_cast(CommissionType::CASH_PER_CONTRACT);\\n else return;\\n } else {\\n return;\\n }\\n pineforge::source::PineStrategyHost::set_strategy_override(overrides);\\n }\\n bool _pf_setting_failed_ = false;\\n std::string _pf_setting_failure_;\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n ::pineforge::RunFailureInfo _pf_setting_failure_info_{::pineforge::RunFailureCode::none, {}};\\n#ifdef PF_SETTINGS_API_VERSION\\n using _pf_setting_error_base = ::pineforge::checked_settings::LatchedSettingsFailure;\\n#else\\n using _pf_setting_error_base = std::runtime_error;\\n#endif\\n struct _pf_latched_setting_error : _pf_setting_error_base, ::pineforge::RunFailureInfo {\\n _pf_latched_setting_error(const std::string& text, const ::pineforge::RunFailureInfo& info)\\n : _pf_setting_error_base(text), ::pineforge::RunFailureInfo(info) {}\\n };\\n#endif\\n void _pf_record_failure(const char* entrypoint, const char* message) noexcept {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure_unknown(*this, entrypoint); } catch (...) {}\\n#else\\n try { last_error_ = entrypoint; last_error_ += \\\": \\\"; last_error_ += message; } catch (...) {}\\n#endif\\n }\\n void _pf_record_failure(const char* entrypoint, const std::exception& error) noexcept {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure(*this, entrypoint, error); } catch (...) {}\\n#else\\n _pf_record_failure(entrypoint, error.what());\\n#endif\\n }\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n template \\n void _pf_record_setting_failure(const char* entrypoint, const char* message, FailureInfo failure_info) noexcept {\\n#else\\n void _pf_record_setting_failure(const char* entrypoint, const char* message) noexcept {\\n#endif\\n if (!_pf_setting_failed_) {\\n _pf_setting_failed_ = true;\\n try { _pf_setting_failure_ = entrypoint; _pf_setting_failure_ += \\\": \\\"; _pf_setting_failure_ += message; } catch (...) {}\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { _pf_setting_failure_info_ = failure_info(); }\\n catch (...) { _pf_setting_failure_info_ = ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::out_of_memory, {}); }\\n#endif\\n }\\n _pf_refuse_failed_setting(nullptr);\\n }\\n void _pf_require_settings_ok() const {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n if (_pf_setting_failed_) throw _pf_latched_setting_error(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_, _pf_setting_failure_info_);\\n#elif defined(PF_SETTINGS_API_VERSION)\\n if (_pf_setting_failed_) throw ::pineforge::checked_settings::LatchedSettingsFailure(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_);\\n#else\\n if (_pf_setting_failed_) throw std::runtime_error(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_);\\n#endif\\n }\\n bool _pf_refuse_failed_setting(ReportC* out) noexcept {\\n if (!_pf_setting_failed_) return false;\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure(*this, _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_, _pf_setting_failure_info_.run_failure()); } catch (...) {}\\n#else\\n try { last_error_ = _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_; } catch (...) {}\\n#endif\\n if (out) *out = ReportC{};\\n return true;\\n }\\n#ifdef PF_SETTINGS_API_VERSION\\n static pineforge::source::PineStrategyConfig _pf_settings_declared_config() {\\n pineforge::source::PineStrategyConfig cfg{};\\n cfg.initial_capital = 100000.0;\\n cfg.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n cfg.default_qty_value = 100.0;\\n return cfg;\\n }\\n std::vector<::pineforge::checked_settings::Setting> _pf_settings_inputs() const {\\n return {\\n };\\n }\\n std::vector<::pineforge::checked_settings::Setting> _pf_settings_overrides() const {\\n const double _pf_nan = std::numeric_limits::quiet_NaN();\\n const auto _pf_defaults = _pf_settings_declared_config();\\n return {\\n {\\\"initial_capital\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.initial_capital), {}, 0.0},\\n {\\\"commission_value\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.commission_value), {}, 0.0},\\n {\\\"default_qty_value\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.default_qty_value), {}, 0.0},\\n {\\\"pyramiding\\\", \\\"int\\\", ::pineforge::checked_settings::number(_pf_defaults.pyramiding), {}, 0.0},\\n {\\\"slippage\\\", \\\"int\\\", ::pineforge::checked_settings::number(_pf_defaults.slippage), {}, 0.0},\\n {\\\"process_orders_on_close\\\", \\\"bool\\\", ::pineforge::checked_settings::number(_pf_defaults.process_orders_on_close), {}, _pf_nan},\\n {\\\"calc_on_order_fills\\\", \\\"bool\\\", ::pineforge::checked_settings::number(_pf_defaults.calc_on_order_fills), {}, _pf_nan},\\n {\\\"close_entries_rule\\\", \\\"string\\\", _pf_close_entries_rule_word(_pf_defaults.close_entries_rule_any), {\\\"FIFO\\\", \\\"ANY\\\"}, _pf_nan},\\n {\\\"default_qty_type\\\", \\\"string\\\", _pf_default_qty_type_word(_pf_defaults.default_qty_type), {\\\"fixed\\\", \\\"percent_of_equity\\\", \\\"cash\\\"}, _pf_nan},\\n {\\\"commission_type\\\", \\\"string\\\", _pf_commission_type_word(_pf_defaults.commission_type), {\\\"percent\\\", \\\"cash_per_order\\\", \\\"cash_per_contract\\\"}, _pf_nan},\\n };\\n }\\n static std::string _pf_close_entries_rule_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"FIFO\\\";\\n if (_pf_value == 1) return \\\"ANY\\\";\\n return \\\"invalid\\\";\\n }\\n static std::string _pf_default_qty_type_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"fixed\\\";\\n if (_pf_value == 1) return \\\"percent_of_equity\\\";\\n if (_pf_value == 2) return \\\"cash\\\";\\n return \\\"invalid\\\";\\n }\\n static std::string _pf_commission_type_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"percent\\\";\\n if (_pf_value == 1) return \\\"cash_per_order\\\";\\n if (_pf_value == 2) return \\\"cash_per_contract\\\";\\n return \\\"invalid\\\";\\n }\\n void _pf_set_input_checked(const std::string& _pf_key, const std::string& _pf_value) {\\n if (_pf_refuse_failed_setting(nullptr)) throw ::pineforge::checked_settings::Error{PF_SETTINGS_RUN_FAILED, last_error_.c_str()};\\n ::pineforge::checked_settings::require(script_bars_processed() == 0 && stream_phase_ == StreamPhase::IDLE, \\\"settings are frozen after execution begins\\\", PF_SETTINGS_UNSUPPORTED);\\n const auto _pf_inputs = _pf_settings_inputs();\\n const ::pineforge::checked_settings::Setting* _pf_match = nullptr;\\n for (const auto& _pf_input : _pf_inputs) {\\n if (_pf_input.name != _pf_key) continue;\\n ::pineforge::checked_settings::require(_pf_match == nullptr, \\\"ambiguous input key\\\", PF_SETTINGS_UNSUPPORTED);\\n _pf_match = &_pf_input;\\n }\\n ::pineforge::checked_settings::require(_pf_match != nullptr, \\\"unknown input key\\\");\\n const auto _pf_canonical = ::pineforge::checked_settings::validate(*_pf_match, _pf_value);\\n set_input(_pf_key, _pf_canonical);\\n ::pineforge::checked_settings::require(inputs_.count(_pf_key) && inputs_.at(_pf_key) == _pf_canonical, \\\"input was not installed\\\", PF_SETTINGS_UNSUPPORTED);\\n }\\n void _pf_set_override_checked(const std::string& _pf_key, const std::string& _pf_value) {\\n if (_pf_refuse_failed_setting(nullptr)) throw ::pineforge::checked_settings::Error{PF_SETTINGS_RUN_FAILED, last_error_.c_str()};\\n ::pineforge::checked_settings::require(script_bars_processed() == 0 && stream_phase_ == StreamPhase::IDLE, \\\"settings are frozen after execution begins\\\", PF_SETTINGS_UNSUPPORTED);\\n for (const auto& _pf_override : _pf_settings_overrides()) {\\n if (_pf_override.name != _pf_key) continue;\\n auto _pf_alias = _pf_value;\\n if (_pf_key == \\\"close_entries_rule\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"fifo\\\") _pf_alias = \\\"FIFO\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"any\\\") _pf_alias = \\\"ANY\\\";\\n }\\n if (_pf_key == \\\"default_qty_type\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"strategy.fixed\\\") _pf_alias = \\\"fixed\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"strategy.percent_of_equity\\\") _pf_alias = \\\"percent_of_equity\\\";\\n if (_pf_value == \\\"2\\\" || _pf_value == \\\"strategy.cash\\\") _pf_alias = \\\"cash\\\";\\n }\\n if (_pf_key == \\\"commission_type\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"strategy.commission.percent\\\") _pf_alias = \\\"percent\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"strategy.commission.cash_per_order\\\") _pf_alias = \\\"cash_per_order\\\";\\n if (_pf_value == \\\"2\\\" || _pf_value == \\\"strategy.commission.cash_per_contract\\\") _pf_alias = \\\"cash_per_contract\\\";\\n }\\n const auto _pf_canonical = ::pineforge::checked_settings::validate(_pf_override, _pf_alias);\\n set_strategy_override(_pf_key, _pf_canonical);\\n return;\\n }\\n throw ::pineforge::checked_settings::Error{PF_SETTINGS_INVALID_ARGUMENT, \\\"unknown override key\\\"};\\n }\\n std::string _pf_settings_receipt() const {\\n ::pineforge::checked_settings::require(!_pf_setting_failed_, _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_.c_str(), PF_SETTINGS_RUN_FAILED);\\n std::string _pf_document = \\\"{\\\\\\\"version\\\\\\\":1,\\\\\\\"inputs\\\\\\\":[\\\";\\n const auto _pf_inputs = _pf_settings_inputs();\\n _pf_document += \\\"],\\\\\\\"overrides\\\\\\\":[\\\";\\n const auto _pf_overrides = _pf_settings_overrides();\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[0], ::pineforge::checked_settings::number((std::isnan(override_.initial_capital) ? config_.initial_capital : override_.initial_capital)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[1], ::pineforge::checked_settings::number((std::isnan(override_.commission_value) ? config_.commission_value : override_.commission_value)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[2], ::pineforge::checked_settings::number((std::isnan(override_.default_qty_value) ? config_.default_qty_value : override_.default_qty_value)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[3], ::pineforge::checked_settings::number((override_.pyramiding < 0 ? config_.pyramiding : override_.pyramiding)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[4], ::pineforge::checked_settings::number((override_.slippage < 0 ? config_.slippage : override_.slippage)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[5], ::pineforge::checked_settings::number(static_cast((override_.process_orders_on_close < 0 ? config_.process_orders_on_close : override_.process_orders_on_close))));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[6], ::pineforge::checked_settings::number(static_cast((override_.calc_on_order_fills < 0 ? config_.calc_on_order_fills : override_.calc_on_order_fills))));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[7], _pf_close_entries_rule_word((override_.close_entries_rule < 0 ? config_.close_entries_rule_any : override_.close_entries_rule)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[8], _pf_default_qty_type_word((override_.default_qty_type < 0 ? config_.default_qty_type : override_.default_qty_type)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[9], _pf_commission_type_word((override_.commission_type < 0 ? config_.commission_type : override_.commission_type)));\\n return _pf_document + \\\"]}\\\";\\n }\\n#endif\\n\\n#ifndef PINEFORGE_HAS_SCRIPT_RUN_PREPARE_V1\\n#error \\\"Generated lifecycle reset requires a matching PineForge engine; rebuild with script-run preparation support\\\"\\n#endif\\n void prepare_script_run(const Bar* bars, int n, bool allow_precalculation) override {\\n _pf_require_settings_ok();\\n _pf_script_state_checkpoint_.reset();\\n this->_use_precalc = false;\\n this->t = 0.0;\\n this->_inputs_initialized_ = false;\\n (void)bars; (void)n; (void)allow_precalculation;\\n }\\n\\n void on_source_bar(const Bar& bar) override {\\n }\\n\\n\\n};\\n\\nextern \\\"C\\\" {\\n#if defined(PINEFORGE_HAS_RUN_FAILURE_CODES_V1) && defined(PF_SETTINGS_API_VERSION)\\n int strategy_create_checked(const char* params_json, void** out, char* error, size_t error_capacity);\\n#endif\\n void* strategy_create(const char* params_json) {\\n#if defined(PINEFORGE_HAS_RUN_FAILURE_CODES_V1) && defined(PF_SETTINGS_API_VERSION)\\n void* out = nullptr;\\n strategy_create_checked(nullptr, &out, nullptr, 0);\\n return out;\\n#else\\n try { return new GeneratedStrategy(); } catch (...) { return nullptr; }\\n#endif\\n }\\n void run_backtest(void* s, Bar* bars, int n, ReportC* out) {\\n try {\\n auto* strat = static_cast(s);\\n#ifndef PF_SETTINGS_API_VERSION\\n if (strat->_pf_refuse_failed_setting(out)) return;\\n#endif\\n strat->run(bars, n);\\n if (!strat->_pf_refuse_failed_setting(out)) strat->fill_report(out);\\n } catch (const std::exception& _pf_error) {\\n if (out) *out = ReportC{};\\n if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest\\\", _pf_error);\\n } catch (...) {\\n if (out) *out = ReportC{};\\n if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest\\\", \\\"unknown C++ exception\\\");\\n }\\n }\\n static void _pf_run_backtest_full_impl(void* s, Bar* bars, int n,\\n const char* input_tf, const char* script_tf,\\n int bar_magnifier, int magnifier_samples,\\n int magnifier_dist,\\n ReportC* out) {\\n auto* strat = static_cast(s);\\n#ifndef PF_SETTINGS_API_VERSION\\n if (strat->_pf_refuse_failed_setting(out)) return;\\n#endif\\n std::string itf = input_tf ? input_tf : \\\"\\\";\\n std::string stf = script_tf ? script_tf : \\\"\\\";\\n bool needs_full_run = (bar_magnifier != 0)\\n || !itf.empty() || !stf.empty();\\n if (!needs_full_run) {\\n strat->run(bars, n);\\n } else {\\n strat->run(bars, n, itf, stf, bar_magnifier != 0, magnifier_samples,\\n static_cast(magnifier_dist));\\n }\\n if (!strat->_pf_refuse_failed_setting(out)) strat->fill_report(out);\\n }\\n void run_backtest_full(void* s, Bar* bars, int n, const char* input_tf, const char* script_tf,\\n int bar_magnifier, int magnifier_samples, int magnifier_dist, ReportC* out) {\\n try { _pf_run_backtest_full_impl(s, bars, n, input_tf, script_tf, bar_magnifier, magnifier_samples, magnifier_dist, out); }\\n catch (const std::exception& _pf_error) { if (out) *out = ReportC{}; if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest_full\\\", _pf_error); }\\n catch (...) { if (out) *out = ReportC{}; if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest_full\\\", \\\"unknown C++ exception\\\"); }\\n }\\n void strategy_free(void* s) {\\n try { delete static_cast(s); } catch (...) {}\\n }\\n void report_free(ReportC* report) {\\n try { BacktestEngine::free_report(report); } catch (...) {}\\n }\\n void strategy_set_input(void* s, const char* key, const char* value) {\\n if (!s || !key || !value) return;\\n try { static_cast(s)->set_input(key, value); }\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_input\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_input\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n void strategy_set_override(void* s, const char* key, const char* value) {\\n if (!s || !key || !value) return;\\n try { static_cast(s)->set_strategy_override(key, value); }\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n catch (const std::invalid_argument& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), \\\"unparseable_value\\\"); }\\n catch (const std::out_of_range& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), \\\"unparseable_value\\\"); }\\n#endif\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n void strategy_set_magnifier_volume_weighted(void* s, int on) {\\n if (!s) return;\\n try { static_cast(s)->set_magnifier_volume_weighted(on != 0); }\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_magnifier_volume_weighted\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_magnifier_volume_weighted\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n#ifdef PF_SETTINGS_API_VERSION\\n uint32_t strategy_settings_api_version(void) { return PF_SETTINGS_API_VERSION; }\\n int strategy_create_checked(const char* params_json, void** out, char* error, size_t error_capacity) {\\n if (out) *out = nullptr;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(out != nullptr, \\\"strategy output pointer is null\\\");\\n ::pineforge::checked_settings::require(!params_json || !*params_json, \\\"params_json is reserved; use checked setters\\\", PF_SETTINGS_UNSUPPORTED);\\n *out = new GeneratedStrategy();\\n });\\n }\\n int strategy_set_input_checked(void* s, const char* key, const char* value, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && key && value, \\\"null strategy, key or value\\\");\\n static_cast(s)->_pf_set_input_checked(key, value);\\n });\\n }\\n int strategy_set_override_checked(void* s, const char* key, const char* value, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && key && value, \\\"null strategy, key or value\\\");\\n static_cast(s)->_pf_set_override_checked(key, value);\\n });\\n }\\n int strategy_get_effective_settings(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(static_cast(s)->_pf_settings_receipt(), json, capacity, required);\\n });\\n }\\n int run_backtest_full_checked(void* s, Bar* bars, int n, const char* input_tf, const char* script_tf, int bar_magnifier, int magnifier_samples, int magnifier_dist, ReportC* out, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && out && n >= 0 && (n == 0 || bars), \\\"invalid batch arguments\\\");\\n _pf_run_backtest_full_impl(s, bars, n, input_tf, script_tf, bar_magnifier, magnifier_samples, magnifier_dist, out);\\n const auto& _pf_error = static_cast(s)->last_error();\\n ::pineforge::checked_settings::require(_pf_error.empty(), _pf_error.c_str(), PF_SETTINGS_RUN_FAILED);\\n });\\n }\\n#endif\\n#ifdef PF_SETTINGS_API_VERSION\\n#ifdef PF_CAPABILITIES_API_VERSION\\n uint32_t strategy_capabilities_api_version(void) { return PF_CAPABILITIES_API_VERSION; }\\n int strategy_capabilities_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"declarations\\\\\\\":{\\\\\\\"backtest_fill_limits_assumption\\\\\\\":0,\\\\\\\"calc_on_every_history_tick\\\\\\\":false,\\\\\\\"calc_on_every_tick\\\\\\\":false,\\\\\\\"calc_on_order_fills\\\\\\\":false,\\\\\\\"currency\\\\\\\":\\\\\\\"currency.NONE\\\\\\\",\\\\\\\"dynamic_requests\\\\\\\":true,\\\\\\\"fill_orders_on_standard_ohlc\\\\\\\":false,\\\\\\\"process_orders_on_close\\\\\\\":false,\\\\\\\"timeframe\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"timeframe_gaps\\\\\\\":true,\\\\\\\"use_bar_magnifier\\\\\\\":false},\\\\\\\"requests\\\\\\\":[],\\\\\\\"requirements\\\\\\\":{\\\\\\\"auxiliary_security_feeds\\\\\\\":false,\\\\\\\"fx_curve\\\\\\\":false,\\\\\\\"historical_probe_overrides\\\\\\\":false,\\\\\\\"intrabar_persistence\\\\\\\":false,\\\\\\\"native_security_feeds\\\\\\\":false,\\\\\\\"recorded_series\\\\\\\":false},\\\\\\\"unresolved\\\\\\\":[],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n uint32_t strategy_confirmed_bar_api_version(void) { return 1u; }\\n int strategy_confirmed_bar_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"intrabar_persistence\\\\\\\":false,\\\\\\\"orders\\\\\\\":[],\\\\\\\"requests\\\\\\\":[],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n uint32_t strategy_order_shapes_api_version(void) { return 1u; }\\n int strategy_order_shapes_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"calls\\\\\\\":[],\\\\\\\"entry_ids\\\\\\\":{\\\\\\\"long\\\\\\\":0,\\\\\\\"multi_site\\\\\\\":0,\\\\\\\"shared\\\\\\\":0,\\\\\\\"short\\\\\\\":0},\\\\\\\"host_reads\\\\\\\":[\\\\\\\"StreamPhase\\\\\\\",\\\\\\\"commit_script_state\\\\\\\",\\\\\\\"config_\\\\\\\",\\\\\\\"configure_pine_strategy\\\\\\\",\\\\\\\"fill_report\\\\\\\",\\\\\\\"inputs_\\\\\\\",\\\\\\\"last_error\\\\\\\",\\\\\\\"last_error_\\\\\\\",\\\\\\\"on_source_bar\\\\\\\",\\\\\\\"override_\\\\\\\",\\\\\\\"prepare_script_run\\\\\\\",\\\\\\\"restore_script_state\\\\\\\",\\\\\\\"run\\\\\\\",\\\\\\\"script_bars_processed\\\\\\\",\\\\\\\"set_input\\\\\\\",\\\\\\\"set_magnifier_volume_weighted\\\\\\\",\\\\\\\"set_strategy_override\\\\\\\",\\\\\\\"snapshot_script_state\\\\\\\",\\\\\\\"stream_phase_\\\\\\\"],\\\\\\\"process_orders_on_close\\\\\\\":false,\\\\\\\"settings\\\\\\\":{\\\\\\\"close_entries_rule\\\\\\\":\\\\\\\"FIFO\\\\\\\",\\\\\\\"commission_type\\\\\\\":\\\\\\\"percent\\\\\\\",\\\\\\\"commission_value\\\\\\\":0.0,\\\\\\\"default_qty_type\\\\\\\":\\\\\\\"percent_of_equity\\\\\\\",\\\\\\\"default_qty_value\\\\\\\":100.0,\\\\\\\"initial_capital\\\\\\\":100000.0,\\\\\\\"margin_long\\\\\\\":100.0,\\\\\\\"margin_short\\\\\\\":100.0,\\\\\\\"pyramiding\\\\\\\":1,\\\\\\\"slippage\\\\\\\":0},\\\\\\\"unmodeled\\\\\\\":[],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n#endif\\n#endif\\n}\\n\", \"inputs\": [], \"strategyParams\": {\"title\": \"Visual\"}, \"diagnostics\": [{\"line\": 3, \"col\": 14, \"message\": \"table.new(...) has no effect in PineForge backtests (visual only).\", \"severity\": \"warning\", \"code\": \"PF-W1508\", \"args\": {\"name\": \"table.new\"}, \"endCol\": 15}], \"requests\": []}", + "display_request": "{\"ok\": true, \"cpp\": \"#include \\n#include \\n#if __has_include()\\n#include \\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#ifndef PINEFORGE_HAS_NATIVE_LOWERING_V1\\n#error \\\"generated code requires pineforge-engine native lowering v1 (PINEFORGE_HAS_NATIVE_LOWERING_V1)\\\"\\n#endif\\n\\nusing namespace pineforge;\\n\\n\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n#define _PF_NO_DATA_STOP(function, call, line, english) ::pineforge::pine_no_data_stop(function, call, line, english)\\n#define _PF_OTHER_SYMBOL_STOP(function, symbol, call, line, english) ::pineforge::pine_other_symbol_stop(function, symbol, call, line, english)\\n#define _PF_ARRAY_STOP(reason, method, english) ::pineforge::pine_array_stop(reason, method, std::string(english).c_str())\\n#define _PF_COLLECTION_STOP(reason, object, english) ::pineforge::pine_collection_stop(object, reason, english)\\n#define _PF_NA_STOP(object, english) ::pineforge::pine_na_stop(object, english)\\n#define _PF_LIMIT_STOP(limit, max, english) ::pineforge::pine_limit_stop(limit, max, english)\\n#define _PF_UNSUPPORTED_STOP(reason, line, english) ::pineforge::pine_unsupported_stop(reason, line, english)\\n#define _PF_STRING_STOP(reason, english) ::pineforge::pine_string_stop(reason, english)\\n#define _PF_ENGINE_INVARIANT(english, legacy_type) ::pineforge::pine_engine_invariant(english)\\n#define _PF_INVARIANT_AT(container, index) _pf_invariant_at(container, index)\\n#define _PF_SETTING_FAILURE(strategy, entrypoint, message, reason) (strategy)->_pf_record_setting_failure(entrypoint, message, [] { return reason ? ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::setting_rejected, {{\\\"entrypoint\\\", entrypoint}, {\\\"reason\\\", reason}}) : ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::setting_rejected, {{\\\"entrypoint\\\", entrypoint}}); })\\ntemplate \\ndecltype(auto) _pf_invariant_at(Container& container, Index index) {\\n try { return container.at(index); }\\n catch (const std::out_of_range& error) { ::pineforge::pine_engine_invariant(error.what()); }\\n}\\n#else\\n#define _PF_NO_DATA_STOP(function, call, line, english) pine_runtime_error(std::string(english))\\n#define _PF_OTHER_SYMBOL_STOP(function, symbol, call, line, english) pine_runtime_error(std::string(english))\\n#define _PF_ARRAY_STOP(reason, method, english) pine_runtime_error(english)\\n#define _PF_COLLECTION_STOP(reason, object, english) pine_runtime_error(english)\\n#define _PF_NA_STOP(object, english) throw std::runtime_error(english)\\n#define _PF_LIMIT_STOP(limit, max, english) throw std::length_error(english)\\n#define _PF_UNSUPPORTED_STOP(reason, line, english) pine_runtime_error(std::string(english))\\n#define _PF_STRING_STOP(reason, english) pine_runtime_error(std::string(english))\\n#define _PF_ENGINE_INVARIANT(english, legacy_type) throw legacy_type(english)\\n#define _PF_INVARIANT_AT(container, index) (container).at(index)\\n#define _PF_SETTING_FAILURE(strategy, entrypoint, message, reason) (strategy)->_pf_record_setting_failure(entrypoint, message)\\n#endif\\n\\n// --- syminfo derivation helpers (PineForge G2) ---\\nstatic inline std::string _pf_derive_prefix(const std::string& tickerid) {\\n std::size_t colon = tickerid.find(':');\\n return (colon == std::string::npos) ? tickerid : tickerid.substr(0, colon);\\n}\\n\\nstatic inline std::string _pf_derive_main_tickerid(const std::string& tickerid) {\\n // Strip trailing digits (optionally followed by '!') from the symbol part.\\n // e.g. \\\"CME_MINI:ES1!\\\" -> \\\"CME_MINI:ES\\\", \\\"NYMEX:CL2!\\\" -> \\\"NYMEX:CL\\\"\\n std::string result = tickerid;\\n std::size_t colon = result.find(':');\\n std::size_t start = (colon == std::string::npos) ? 0 : colon + 1;\\n // Find end of base symbol (strip trailing digits + optional '!')\\n std::size_t end = result.size();\\n if (end > start && result[end - 1] == '!') {\\n --end;\\n }\\n while (end > start && std::isdigit((unsigned char)result[end - 1])) {\\n --end;\\n }\\n return result.substr(0, end);\\n}\\n\\nstatic inline std::string _pf_derive_country(const std::string& tickerid) {\\n // Lookup country by exchange prefix (text before ':').\\n std::size_t colon = tickerid.find(':');\\n std::string prefix = (colon == std::string::npos)\\n ? tickerid : tickerid.substr(0, colon);\\n static const std::unordered_map _tbl = {\\n {\\\"AMEX\\\", \\\"US\\\"},\\n {\\\"AQUIS\\\", \\\"GB\\\"},\\n {\\\"ARCA\\\", \\\"US\\\"},\\n {\\\"ASX\\\", \\\"AU\\\"},\\n {\\\"B3\\\", \\\"BR\\\"},\\n {\\\"BMF\\\", \\\"BR\\\"},\\n {\\\"BMFBOVESPA\\\", \\\"BR\\\"},\\n {\\\"BSE\\\", \\\"IN\\\"},\\n {\\\"CBOE\\\", \\\"US\\\"},\\n {\\\"CBOT\\\", \\\"US\\\"},\\n {\\\"CME\\\", \\\"US\\\"},\\n {\\\"CME_MINI\\\", \\\"US\\\"},\\n {\\\"COINBASE\\\", \\\"US\\\"},\\n {\\\"COMEX\\\", \\\"US\\\"},\\n {\\\"HKEX\\\", \\\"HK\\\"},\\n {\\\"JSE\\\", \\\"ZA\\\"},\\n {\\\"KOSPI\\\", \\\"KR\\\"},\\n {\\\"KRX\\\", \\\"KR\\\"},\\n {\\\"LSE\\\", \\\"GB\\\"},\\n {\\\"MOEX\\\", \\\"RU\\\"},\\n {\\\"NASDAQ\\\", \\\"US\\\"},\\n {\\\"NSE\\\", \\\"IN\\\"},\\n {\\\"NYMEX\\\", \\\"US\\\"},\\n {\\\"NYSE\\\", \\\"US\\\"},\\n {\\\"OSE\\\", \\\"JP\\\"},\\n {\\\"OTC\\\", \\\"US\\\"},\\n {\\\"SGX\\\", \\\"SG\\\"},\\n {\\\"SIX\\\", \\\"CH\\\"},\\n {\\\"SSE\\\", \\\"CN\\\"},\\n {\\\"SZSE\\\", \\\"CN\\\"},\\n {\\\"TSE\\\", \\\"JP\\\"},\\n {\\\"TSX\\\", \\\"CA\\\"},\\n {\\\"UPBIT\\\", \\\"KR\\\"},\\n {\\\"VENTURE\\\", \\\"CA\\\"},\\n {\\\"XETRA\\\", \\\"DE\\\"}\\n };\\n auto it = _tbl.find(prefix);\\n return (it != _tbl.end()) ? it->second : na();\\n}\\n// --- end syminfo derivation helpers ---\\n\\nclass GeneratedStrategy : public pineforge::source::PineStrategyHost {\\npublic:\\n bool _use_precalc = false;\\n double x = 0.0;\\n bool _inputs_initialized_ = false;\\n\\n struct _PFScriptState {\\n decltype(GeneratedStrategy::x) _pf_value_0;\\n decltype(GeneratedStrategy::_inputs_initialized_) _pf_value_1;\\n };\\n static_assert(std::is_copy_constructible_v<_PFScriptState>, \\\"generated Pine state must be deep-copy constructible\\\");\\n static_assert(std::is_copy_assignable_v<_PFScriptState>, \\\"generated Pine state must be deep-copy assignable\\\");\\n std::optional<_PFScriptState> _pf_script_state_checkpoint_;\\n\\n void snapshot_script_state() override {\\n _pf_script_state_checkpoint_.emplace(_PFScriptState{\\n x,\\n _inputs_initialized_,\\n });\\n }\\n\\n void restore_script_state() override {\\n if (!_pf_script_state_checkpoint_) return;\\n this->x = _pf_script_state_checkpoint_->_pf_value_0;\\n this->_inputs_initialized_ = _pf_script_state_checkpoint_->_pf_value_1;\\n }\\n\\n void commit_script_state() override {\\n snapshot_script_state();\\n }\\n\\n explicit GeneratedStrategy() {\\n#if defined(PINEFORGE_HAS_EXPLICIT_PINE_EXECUTION_ADAPTER_V1)\\n pineforge::source::PineStrategyHost::attach_pine_execution_adapter();\\n#elif defined(PINEFORGE_HAS_EXPLICIT_PINE_CAP_V1)\\n pineforge::source::PineStrategyHost::enable_pine_intraday_cap();\\n#endif\\n pineforge::source::PineStrategyConfig cfg{};\\n cfg.initial_capital = 100000.0;\\n cfg.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n cfg.default_qty_value = 100.0;\\n configure_pine_strategy(cfg);\\n }\\n\\n void set_strategy_override(const std::string& key, const std::string& value) {\\n pineforge::source::StrategyOverrides overrides{};\\n if (key == \\\"initial_capital\\\") {\\n overrides.initial_capital = std::stod(value);\\n } else if (key == \\\"commission_value\\\") {\\n overrides.commission_value = std::stod(value);\\n } else if (key == \\\"default_qty_value\\\") {\\n overrides.default_qty_value = std::stod(value);\\n } else if (key == \\\"pyramiding\\\") {\\n overrides.pyramiding = std::stoi(value);\\n } else if (key == \\\"slippage\\\") {\\n overrides.slippage = std::stoi(value);\\n } else if (key == \\\"process_orders_on_close\\\") {\\n overrides.process_orders_on_close = (value == \\\"true\\\" || value == \\\"1\\\");\\n } else if (key == \\\"calc_on_order_fills\\\") {\\n overrides.calc_on_order_fills = (value == \\\"true\\\" || value == \\\"1\\\");\\n } else if (key == \\\"close_entries_rule\\\") {\\n overrides.close_entries_rule = (value == \\\"ANY\\\" || value == \\\"any\\\" || value == \\\"1\\\");\\n } else if (key == \\\"default_qty_type\\\") {\\n if (value == \\\"fixed\\\" || value == \\\"strategy.fixed\\\" || value == \\\"0\\\") overrides.default_qty_type = static_cast(QtyType::FIXED);\\n else if (value == \\\"percent_of_equity\\\" || value == \\\"strategy.percent_of_equity\\\" || value == \\\"1\\\") overrides.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n else if (value == \\\"cash\\\" || value == \\\"strategy.cash\\\" || value == \\\"2\\\") overrides.default_qty_type = static_cast(QtyType::CASH);\\n else return;\\n } else if (key == \\\"commission_type\\\") {\\n if (value == \\\"percent\\\" || value == \\\"strategy.commission.percent\\\" || value == \\\"0\\\") overrides.commission_type = static_cast(CommissionType::PERCENT);\\n else if (value == \\\"cash_per_order\\\" || value == \\\"strategy.commission.cash_per_order\\\" || value == \\\"1\\\") overrides.commission_type = static_cast(CommissionType::CASH_PER_ORDER);\\n else if (value == \\\"cash_per_contract\\\" || value == \\\"strategy.commission.cash_per_contract\\\" || value == \\\"2\\\") overrides.commission_type = static_cast(CommissionType::CASH_PER_CONTRACT);\\n else return;\\n } else {\\n return;\\n }\\n pineforge::source::PineStrategyHost::set_strategy_override(overrides);\\n }\\n bool _pf_setting_failed_ = false;\\n std::string _pf_setting_failure_;\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n ::pineforge::RunFailureInfo _pf_setting_failure_info_{::pineforge::RunFailureCode::none, {}};\\n#ifdef PF_SETTINGS_API_VERSION\\n using _pf_setting_error_base = ::pineforge::checked_settings::LatchedSettingsFailure;\\n#else\\n using _pf_setting_error_base = std::runtime_error;\\n#endif\\n struct _pf_latched_setting_error : _pf_setting_error_base, ::pineforge::RunFailureInfo {\\n _pf_latched_setting_error(const std::string& text, const ::pineforge::RunFailureInfo& info)\\n : _pf_setting_error_base(text), ::pineforge::RunFailureInfo(info) {}\\n };\\n#endif\\n void _pf_record_failure(const char* entrypoint, const char* message) noexcept {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure_unknown(*this, entrypoint); } catch (...) {}\\n#else\\n try { last_error_ = entrypoint; last_error_ += \\\": \\\"; last_error_ += message; } catch (...) {}\\n#endif\\n }\\n void _pf_record_failure(const char* entrypoint, const std::exception& error) noexcept {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure(*this, entrypoint, error); } catch (...) {}\\n#else\\n _pf_record_failure(entrypoint, error.what());\\n#endif\\n }\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n template \\n void _pf_record_setting_failure(const char* entrypoint, const char* message, FailureInfo failure_info) noexcept {\\n#else\\n void _pf_record_setting_failure(const char* entrypoint, const char* message) noexcept {\\n#endif\\n if (!_pf_setting_failed_) {\\n _pf_setting_failed_ = true;\\n try { _pf_setting_failure_ = entrypoint; _pf_setting_failure_ += \\\": \\\"; _pf_setting_failure_ += message; } catch (...) {}\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { _pf_setting_failure_info_ = failure_info(); }\\n catch (...) { _pf_setting_failure_info_ = ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::out_of_memory, {}); }\\n#endif\\n }\\n _pf_refuse_failed_setting(nullptr);\\n }\\n void _pf_require_settings_ok() const {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n if (_pf_setting_failed_) throw _pf_latched_setting_error(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_, _pf_setting_failure_info_);\\n#elif defined(PF_SETTINGS_API_VERSION)\\n if (_pf_setting_failed_) throw ::pineforge::checked_settings::LatchedSettingsFailure(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_);\\n#else\\n if (_pf_setting_failed_) throw std::runtime_error(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_);\\n#endif\\n }\\n bool _pf_refuse_failed_setting(ReportC* out) noexcept {\\n if (!_pf_setting_failed_) return false;\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure(*this, _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_, _pf_setting_failure_info_.run_failure()); } catch (...) {}\\n#else\\n try { last_error_ = _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_; } catch (...) {}\\n#endif\\n if (out) *out = ReportC{};\\n return true;\\n }\\n#ifdef PF_SETTINGS_API_VERSION\\n static pineforge::source::PineStrategyConfig _pf_settings_declared_config() {\\n pineforge::source::PineStrategyConfig cfg{};\\n cfg.initial_capital = 100000.0;\\n cfg.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n cfg.default_qty_value = 100.0;\\n return cfg;\\n }\\n std::vector<::pineforge::checked_settings::Setting> _pf_settings_inputs() const {\\n return {\\n };\\n }\\n std::vector<::pineforge::checked_settings::Setting> _pf_settings_overrides() const {\\n const double _pf_nan = std::numeric_limits::quiet_NaN();\\n const auto _pf_defaults = _pf_settings_declared_config();\\n return {\\n {\\\"initial_capital\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.initial_capital), {}, 0.0},\\n {\\\"commission_value\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.commission_value), {}, 0.0},\\n {\\\"default_qty_value\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.default_qty_value), {}, 0.0},\\n {\\\"pyramiding\\\", \\\"int\\\", ::pineforge::checked_settings::number(_pf_defaults.pyramiding), {}, 0.0},\\n {\\\"slippage\\\", \\\"int\\\", ::pineforge::checked_settings::number(_pf_defaults.slippage), {}, 0.0},\\n {\\\"process_orders_on_close\\\", \\\"bool\\\", ::pineforge::checked_settings::number(_pf_defaults.process_orders_on_close), {}, _pf_nan},\\n {\\\"calc_on_order_fills\\\", \\\"bool\\\", ::pineforge::checked_settings::number(_pf_defaults.calc_on_order_fills), {}, _pf_nan},\\n {\\\"close_entries_rule\\\", \\\"string\\\", _pf_close_entries_rule_word(_pf_defaults.close_entries_rule_any), {\\\"FIFO\\\", \\\"ANY\\\"}, _pf_nan},\\n {\\\"default_qty_type\\\", \\\"string\\\", _pf_default_qty_type_word(_pf_defaults.default_qty_type), {\\\"fixed\\\", \\\"percent_of_equity\\\", \\\"cash\\\"}, _pf_nan},\\n {\\\"commission_type\\\", \\\"string\\\", _pf_commission_type_word(_pf_defaults.commission_type), {\\\"percent\\\", \\\"cash_per_order\\\", \\\"cash_per_contract\\\"}, _pf_nan},\\n };\\n }\\n static std::string _pf_close_entries_rule_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"FIFO\\\";\\n if (_pf_value == 1) return \\\"ANY\\\";\\n return \\\"invalid\\\";\\n }\\n static std::string _pf_default_qty_type_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"fixed\\\";\\n if (_pf_value == 1) return \\\"percent_of_equity\\\";\\n if (_pf_value == 2) return \\\"cash\\\";\\n return \\\"invalid\\\";\\n }\\n static std::string _pf_commission_type_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"percent\\\";\\n if (_pf_value == 1) return \\\"cash_per_order\\\";\\n if (_pf_value == 2) return \\\"cash_per_contract\\\";\\n return \\\"invalid\\\";\\n }\\n void _pf_set_input_checked(const std::string& _pf_key, const std::string& _pf_value) {\\n if (_pf_refuse_failed_setting(nullptr)) throw ::pineforge::checked_settings::Error{PF_SETTINGS_RUN_FAILED, last_error_.c_str()};\\n ::pineforge::checked_settings::require(script_bars_processed() == 0 && stream_phase_ == StreamPhase::IDLE, \\\"settings are frozen after execution begins\\\", PF_SETTINGS_UNSUPPORTED);\\n const auto _pf_inputs = _pf_settings_inputs();\\n const ::pineforge::checked_settings::Setting* _pf_match = nullptr;\\n for (const auto& _pf_input : _pf_inputs) {\\n if (_pf_input.name != _pf_key) continue;\\n ::pineforge::checked_settings::require(_pf_match == nullptr, \\\"ambiguous input key\\\", PF_SETTINGS_UNSUPPORTED);\\n _pf_match = &_pf_input;\\n }\\n ::pineforge::checked_settings::require(_pf_match != nullptr, \\\"unknown input key\\\");\\n const auto _pf_canonical = ::pineforge::checked_settings::validate(*_pf_match, _pf_value);\\n set_input(_pf_key, _pf_canonical);\\n ::pineforge::checked_settings::require(inputs_.count(_pf_key) && inputs_.at(_pf_key) == _pf_canonical, \\\"input was not installed\\\", PF_SETTINGS_UNSUPPORTED);\\n }\\n void _pf_set_override_checked(const std::string& _pf_key, const std::string& _pf_value) {\\n if (_pf_refuse_failed_setting(nullptr)) throw ::pineforge::checked_settings::Error{PF_SETTINGS_RUN_FAILED, last_error_.c_str()};\\n ::pineforge::checked_settings::require(script_bars_processed() == 0 && stream_phase_ == StreamPhase::IDLE, \\\"settings are frozen after execution begins\\\", PF_SETTINGS_UNSUPPORTED);\\n for (const auto& _pf_override : _pf_settings_overrides()) {\\n if (_pf_override.name != _pf_key) continue;\\n auto _pf_alias = _pf_value;\\n if (_pf_key == \\\"close_entries_rule\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"fifo\\\") _pf_alias = \\\"FIFO\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"any\\\") _pf_alias = \\\"ANY\\\";\\n }\\n if (_pf_key == \\\"default_qty_type\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"strategy.fixed\\\") _pf_alias = \\\"fixed\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"strategy.percent_of_equity\\\") _pf_alias = \\\"percent_of_equity\\\";\\n if (_pf_value == \\\"2\\\" || _pf_value == \\\"strategy.cash\\\") _pf_alias = \\\"cash\\\";\\n }\\n if (_pf_key == \\\"commission_type\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"strategy.commission.percent\\\") _pf_alias = \\\"percent\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"strategy.commission.cash_per_order\\\") _pf_alias = \\\"cash_per_order\\\";\\n if (_pf_value == \\\"2\\\" || _pf_value == \\\"strategy.commission.cash_per_contract\\\") _pf_alias = \\\"cash_per_contract\\\";\\n }\\n const auto _pf_canonical = ::pineforge::checked_settings::validate(_pf_override, _pf_alias);\\n set_strategy_override(_pf_key, _pf_canonical);\\n return;\\n }\\n throw ::pineforge::checked_settings::Error{PF_SETTINGS_INVALID_ARGUMENT, \\\"unknown override key\\\"};\\n }\\n std::string _pf_settings_receipt() const {\\n ::pineforge::checked_settings::require(!_pf_setting_failed_, _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_.c_str(), PF_SETTINGS_RUN_FAILED);\\n std::string _pf_document = \\\"{\\\\\\\"version\\\\\\\":1,\\\\\\\"inputs\\\\\\\":[\\\";\\n const auto _pf_inputs = _pf_settings_inputs();\\n _pf_document += \\\"],\\\\\\\"overrides\\\\\\\":[\\\";\\n const auto _pf_overrides = _pf_settings_overrides();\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[0], ::pineforge::checked_settings::number((std::isnan(override_.initial_capital) ? config_.initial_capital : override_.initial_capital)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[1], ::pineforge::checked_settings::number((std::isnan(override_.commission_value) ? config_.commission_value : override_.commission_value)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[2], ::pineforge::checked_settings::number((std::isnan(override_.default_qty_value) ? config_.default_qty_value : override_.default_qty_value)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[3], ::pineforge::checked_settings::number((override_.pyramiding < 0 ? config_.pyramiding : override_.pyramiding)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[4], ::pineforge::checked_settings::number((override_.slippage < 0 ? config_.slippage : override_.slippage)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[5], ::pineforge::checked_settings::number(static_cast((override_.process_orders_on_close < 0 ? config_.process_orders_on_close : override_.process_orders_on_close))));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[6], ::pineforge::checked_settings::number(static_cast((override_.calc_on_order_fills < 0 ? config_.calc_on_order_fills : override_.calc_on_order_fills))));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[7], _pf_close_entries_rule_word((override_.close_entries_rule < 0 ? config_.close_entries_rule_any : override_.close_entries_rule)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[8], _pf_default_qty_type_word((override_.default_qty_type < 0 ? config_.default_qty_type : override_.default_qty_type)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[9], _pf_commission_type_word((override_.commission_type < 0 ? config_.commission_type : override_.commission_type)));\\n return _pf_document + \\\"]}\\\";\\n }\\n#endif\\n\\n#ifndef PINEFORGE_HAS_SCRIPT_RUN_PREPARE_V1\\n#error \\\"Generated lifecycle reset requires a matching PineForge engine; rebuild with script-run preparation support\\\"\\n#endif\\n void prepare_script_run(const Bar* bars, int n, bool allow_precalculation) override {\\n _pf_require_settings_ok();\\n _pf_script_state_checkpoint_.reset();\\n this->_use_precalc = false;\\n this->x = 0.0;\\n this->_inputs_initialized_ = false;\\n (void)bars; (void)n; (void)allow_precalculation;\\n }\\n\\n void on_source_bar(const Bar& bar) override {\\n x = na();\\n }\\n\\n\\n};\\n\\nextern \\\"C\\\" {\\n#if defined(PINEFORGE_HAS_RUN_FAILURE_CODES_V1) && defined(PF_SETTINGS_API_VERSION)\\n int strategy_create_checked(const char* params_json, void** out, char* error, size_t error_capacity);\\n#endif\\n void* strategy_create(const char* params_json) {\\n#if defined(PINEFORGE_HAS_RUN_FAILURE_CODES_V1) && defined(PF_SETTINGS_API_VERSION)\\n void* out = nullptr;\\n strategy_create_checked(nullptr, &out, nullptr, 0);\\n return out;\\n#else\\n try { return new GeneratedStrategy(); } catch (...) { return nullptr; }\\n#endif\\n }\\n void run_backtest(void* s, Bar* bars, int n, ReportC* out) {\\n try {\\n auto* strat = static_cast(s);\\n#ifndef PF_SETTINGS_API_VERSION\\n if (strat->_pf_refuse_failed_setting(out)) return;\\n#endif\\n strat->run(bars, n);\\n if (!strat->_pf_refuse_failed_setting(out)) strat->fill_report(out);\\n } catch (const std::exception& _pf_error) {\\n if (out) *out = ReportC{};\\n if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest\\\", _pf_error);\\n } catch (...) {\\n if (out) *out = ReportC{};\\n if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest\\\", \\\"unknown C++ exception\\\");\\n }\\n }\\n static void _pf_run_backtest_full_impl(void* s, Bar* bars, int n,\\n const char* input_tf, const char* script_tf,\\n int bar_magnifier, int magnifier_samples,\\n int magnifier_dist,\\n ReportC* out) {\\n auto* strat = static_cast(s);\\n#ifndef PF_SETTINGS_API_VERSION\\n if (strat->_pf_refuse_failed_setting(out)) return;\\n#endif\\n std::string itf = input_tf ? input_tf : \\\"\\\";\\n std::string stf = script_tf ? script_tf : \\\"\\\";\\n bool needs_full_run = (bar_magnifier != 0)\\n || !itf.empty() || !stf.empty();\\n if (!needs_full_run) {\\n strat->run(bars, n);\\n } else {\\n strat->run(bars, n, itf, stf, bar_magnifier != 0, magnifier_samples,\\n static_cast(magnifier_dist));\\n }\\n if (!strat->_pf_refuse_failed_setting(out)) strat->fill_report(out);\\n }\\n void run_backtest_full(void* s, Bar* bars, int n, const char* input_tf, const char* script_tf,\\n int bar_magnifier, int magnifier_samples, int magnifier_dist, ReportC* out) {\\n try { _pf_run_backtest_full_impl(s, bars, n, input_tf, script_tf, bar_magnifier, magnifier_samples, magnifier_dist, out); }\\n catch (const std::exception& _pf_error) { if (out) *out = ReportC{}; if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest_full\\\", _pf_error); }\\n catch (...) { if (out) *out = ReportC{}; if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest_full\\\", \\\"unknown C++ exception\\\"); }\\n }\\n void strategy_free(void* s) {\\n try { delete static_cast(s); } catch (...) {}\\n }\\n void report_free(ReportC* report) {\\n try { BacktestEngine::free_report(report); } catch (...) {}\\n }\\n void strategy_set_input(void* s, const char* key, const char* value) {\\n if (!s || !key || !value) return;\\n try { static_cast(s)->set_input(key, value); }\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_input\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_input\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n void strategy_set_override(void* s, const char* key, const char* value) {\\n if (!s || !key || !value) return;\\n try { static_cast(s)->set_strategy_override(key, value); }\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n catch (const std::invalid_argument& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), \\\"unparseable_value\\\"); }\\n catch (const std::out_of_range& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), \\\"unparseable_value\\\"); }\\n#endif\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n void strategy_set_magnifier_volume_weighted(void* s, int on) {\\n if (!s) return;\\n try { static_cast(s)->set_magnifier_volume_weighted(on != 0); }\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_magnifier_volume_weighted\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_magnifier_volume_weighted\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n#ifdef PF_SETTINGS_API_VERSION\\n uint32_t strategy_settings_api_version(void) { return PF_SETTINGS_API_VERSION; }\\n int strategy_create_checked(const char* params_json, void** out, char* error, size_t error_capacity) {\\n if (out) *out = nullptr;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(out != nullptr, \\\"strategy output pointer is null\\\");\\n ::pineforge::checked_settings::require(!params_json || !*params_json, \\\"params_json is reserved; use checked setters\\\", PF_SETTINGS_UNSUPPORTED);\\n *out = new GeneratedStrategy();\\n });\\n }\\n int strategy_set_input_checked(void* s, const char* key, const char* value, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && key && value, \\\"null strategy, key or value\\\");\\n static_cast(s)->_pf_set_input_checked(key, value);\\n });\\n }\\n int strategy_set_override_checked(void* s, const char* key, const char* value, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && key && value, \\\"null strategy, key or value\\\");\\n static_cast(s)->_pf_set_override_checked(key, value);\\n });\\n }\\n int strategy_get_effective_settings(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(static_cast(s)->_pf_settings_receipt(), json, capacity, required);\\n });\\n }\\n int run_backtest_full_checked(void* s, Bar* bars, int n, const char* input_tf, const char* script_tf, int bar_magnifier, int magnifier_samples, int magnifier_dist, ReportC* out, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && out && n >= 0 && (n == 0 || bars), \\\"invalid batch arguments\\\");\\n _pf_run_backtest_full_impl(s, bars, n, input_tf, script_tf, bar_magnifier, magnifier_samples, magnifier_dist, out);\\n const auto& _pf_error = static_cast(s)->last_error();\\n ::pineforge::checked_settings::require(_pf_error.empty(), _pf_error.c_str(), PF_SETTINGS_RUN_FAILED);\\n });\\n }\\n#endif\\n#ifdef PF_SETTINGS_API_VERSION\\n#ifdef PF_CAPABILITIES_API_VERSION\\n uint32_t strategy_capabilities_api_version(void) { return PF_CAPABILITIES_API_VERSION; }\\n int strategy_capabilities_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"declarations\\\\\\\":{\\\\\\\"backtest_fill_limits_assumption\\\\\\\":0,\\\\\\\"calc_on_every_history_tick\\\\\\\":false,\\\\\\\"calc_on_every_tick\\\\\\\":false,\\\\\\\"calc_on_order_fills\\\\\\\":false,\\\\\\\"currency\\\\\\\":\\\\\\\"currency.NONE\\\\\\\",\\\\\\\"dynamic_requests\\\\\\\":true,\\\\\\\"fill_orders_on_standard_ohlc\\\\\\\":false,\\\\\\\"process_orders_on_close\\\\\\\":false,\\\\\\\"timeframe\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"timeframe_gaps\\\\\\\":true,\\\\\\\"use_bar_magnifier\\\\\\\":false},\\\\\\\"requests\\\\\\\":[],\\\\\\\"requirements\\\\\\\":{\\\\\\\"auxiliary_security_feeds\\\\\\\":false,\\\\\\\"fx_curve\\\\\\\":false,\\\\\\\"historical_probe_overrides\\\\\\\":false,\\\\\\\"intrabar_persistence\\\\\\\":false,\\\\\\\"native_security_feeds\\\\\\\":false,\\\\\\\"recorded_series\\\\\\\":false},\\\\\\\"unresolved\\\\\\\":[],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n uint32_t strategy_confirmed_bar_api_version(void) { return 1u; }\\n int strategy_confirmed_bar_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"intrabar_persistence\\\\\\\":false,\\\\\\\"orders\\\\\\\":[],\\\\\\\"requests\\\\\\\":[],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n uint32_t strategy_order_shapes_api_version(void) { return 1u; }\\n int strategy_order_shapes_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"calls\\\\\\\":[],\\\\\\\"entry_ids\\\\\\\":{\\\\\\\"long\\\\\\\":0,\\\\\\\"multi_site\\\\\\\":0,\\\\\\\"shared\\\\\\\":0,\\\\\\\"short\\\\\\\":0},\\\\\\\"host_reads\\\\\\\":[\\\\\\\"StreamPhase\\\\\\\",\\\\\\\"commit_script_state\\\\\\\",\\\\\\\"config_\\\\\\\",\\\\\\\"configure_pine_strategy\\\\\\\",\\\\\\\"fill_report\\\\\\\",\\\\\\\"inputs_\\\\\\\",\\\\\\\"last_error\\\\\\\",\\\\\\\"last_error_\\\\\\\",\\\\\\\"on_source_bar\\\\\\\",\\\\\\\"override_\\\\\\\",\\\\\\\"prepare_script_run\\\\\\\",\\\\\\\"restore_script_state\\\\\\\",\\\\\\\"run\\\\\\\",\\\\\\\"script_bars_processed\\\\\\\",\\\\\\\"set_input\\\\\\\",\\\\\\\"set_magnifier_volume_weighted\\\\\\\",\\\\\\\"set_strategy_override\\\\\\\",\\\\\\\"snapshot_script_state\\\\\\\",\\\\\\\"stream_phase_\\\\\\\"],\\\\\\\"process_orders_on_close\\\\\\\":false,\\\\\\\"settings\\\\\\\":{\\\\\\\"close_entries_rule\\\\\\\":\\\\\\\"FIFO\\\\\\\",\\\\\\\"commission_type\\\\\\\":\\\\\\\"percent\\\\\\\",\\\\\\\"commission_value\\\\\\\":0.0,\\\\\\\"default_qty_type\\\\\\\":\\\\\\\"percent_of_equity\\\\\\\",\\\\\\\"default_qty_value\\\\\\\":100.0,\\\\\\\"initial_capital\\\\\\\":100000.0,\\\\\\\"margin_long\\\\\\\":100.0,\\\\\\\"margin_short\\\\\\\":100.0,\\\\\\\"pyramiding\\\\\\\":1,\\\\\\\"slippage\\\\\\\":0},\\\\\\\"unmodeled\\\\\\\":[],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n#endif\\n#endif\\n}\\n\", \"inputs\": [], \"strategyParams\": {\"title\": \"Display\"}, \"diagnostics\": [{\"line\": 3, \"col\": 22, \"message\": \"request.financial(\\\"NASDAQ:AAPL\\\", \\\"TOTAL_REVENUE\\\", ...) at line 3: value reaches only display/alert sinks; lowered to na; trades are unaffected. \\u2014 External fundamentals data not available in PineForge. The value it lowers to reaches alerts, plots and tables only.\", \"severity\": \"warning\", \"code\": \"PF-W1528\", \"args\": {\"call\": \"request.financial(\\\"NASDAQ:AAPL\\\", \\\"TOTAL_REVENUE\\\", ...) at line 3\"}, \"endCol\": 23}, {\"line\": 4, \"col\": 5, \"message\": \"plot(...) has no effect in PineForge backtests (visual only).\", \"severity\": \"warning\", \"code\": \"PF-W1508\", \"args\": {\"name\": \"plot\"}, \"endCol\": 6}], \"requests\": []}", + "actionable_warning": "{\"ok\": true, \"cpp\": \"#include \\n#include \\n#if __has_include()\\n#include \\n#endif\\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#include \\n#ifndef PINEFORGE_HAS_NATIVE_LOWERING_V1\\n#error \\\"generated code requires pineforge-engine native lowering v1 (PINEFORGE_HAS_NATIVE_LOWERING_V1)\\\"\\n#endif\\n\\nusing namespace pineforge;\\n\\n\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n#define _PF_NO_DATA_STOP(function, call, line, english) ::pineforge::pine_no_data_stop(function, call, line, english)\\n#define _PF_OTHER_SYMBOL_STOP(function, symbol, call, line, english) ::pineforge::pine_other_symbol_stop(function, symbol, call, line, english)\\n#define _PF_ARRAY_STOP(reason, method, english) ::pineforge::pine_array_stop(reason, method, std::string(english).c_str())\\n#define _PF_COLLECTION_STOP(reason, object, english) ::pineforge::pine_collection_stop(object, reason, english)\\n#define _PF_NA_STOP(object, english) ::pineforge::pine_na_stop(object, english)\\n#define _PF_LIMIT_STOP(limit, max, english) ::pineforge::pine_limit_stop(limit, max, english)\\n#define _PF_UNSUPPORTED_STOP(reason, line, english) ::pineforge::pine_unsupported_stop(reason, line, english)\\n#define _PF_STRING_STOP(reason, english) ::pineforge::pine_string_stop(reason, english)\\n#define _PF_ENGINE_INVARIANT(english, legacy_type) ::pineforge::pine_engine_invariant(english)\\n#define _PF_INVARIANT_AT(container, index) _pf_invariant_at(container, index)\\n#define _PF_SETTING_FAILURE(strategy, entrypoint, message, reason) (strategy)->_pf_record_setting_failure(entrypoint, message, [] { return reason ? ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::setting_rejected, {{\\\"entrypoint\\\", entrypoint}, {\\\"reason\\\", reason}}) : ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::setting_rejected, {{\\\"entrypoint\\\", entrypoint}}); })\\ntemplate \\ndecltype(auto) _pf_invariant_at(Container& container, Index index) {\\n try { return container.at(index); }\\n catch (const std::out_of_range& error) { ::pineforge::pine_engine_invariant(error.what()); }\\n}\\n#else\\n#define _PF_NO_DATA_STOP(function, call, line, english) pine_runtime_error(std::string(english))\\n#define _PF_OTHER_SYMBOL_STOP(function, symbol, call, line, english) pine_runtime_error(std::string(english))\\n#define _PF_ARRAY_STOP(reason, method, english) pine_runtime_error(english)\\n#define _PF_COLLECTION_STOP(reason, object, english) pine_runtime_error(english)\\n#define _PF_NA_STOP(object, english) throw std::runtime_error(english)\\n#define _PF_LIMIT_STOP(limit, max, english) throw std::length_error(english)\\n#define _PF_UNSUPPORTED_STOP(reason, line, english) pine_runtime_error(std::string(english))\\n#define _PF_STRING_STOP(reason, english) pine_runtime_error(std::string(english))\\n#define _PF_ENGINE_INVARIANT(english, legacy_type) throw legacy_type(english)\\n#define _PF_INVARIANT_AT(container, index) (container).at(index)\\n#define _PF_SETTING_FAILURE(strategy, entrypoint, message, reason) (strategy)->_pf_record_setting_failure(entrypoint, message)\\n#endif\\n\\n// --- syminfo derivation helpers (PineForge G2) ---\\nstatic inline std::string _pf_derive_prefix(const std::string& tickerid) {\\n std::size_t colon = tickerid.find(':');\\n return (colon == std::string::npos) ? tickerid : tickerid.substr(0, colon);\\n}\\n\\nstatic inline std::string _pf_derive_main_tickerid(const std::string& tickerid) {\\n // Strip trailing digits (optionally followed by '!') from the symbol part.\\n // e.g. \\\"CME_MINI:ES1!\\\" -> \\\"CME_MINI:ES\\\", \\\"NYMEX:CL2!\\\" -> \\\"NYMEX:CL\\\"\\n std::string result = tickerid;\\n std::size_t colon = result.find(':');\\n std::size_t start = (colon == std::string::npos) ? 0 : colon + 1;\\n // Find end of base symbol (strip trailing digits + optional '!')\\n std::size_t end = result.size();\\n if (end > start && result[end - 1] == '!') {\\n --end;\\n }\\n while (end > start && std::isdigit((unsigned char)result[end - 1])) {\\n --end;\\n }\\n return result.substr(0, end);\\n}\\n\\nstatic inline std::string _pf_derive_country(const std::string& tickerid) {\\n // Lookup country by exchange prefix (text before ':').\\n std::size_t colon = tickerid.find(':');\\n std::string prefix = (colon == std::string::npos)\\n ? tickerid : tickerid.substr(0, colon);\\n static const std::unordered_map _tbl = {\\n {\\\"AMEX\\\", \\\"US\\\"},\\n {\\\"AQUIS\\\", \\\"GB\\\"},\\n {\\\"ARCA\\\", \\\"US\\\"},\\n {\\\"ASX\\\", \\\"AU\\\"},\\n {\\\"B3\\\", \\\"BR\\\"},\\n {\\\"BMF\\\", \\\"BR\\\"},\\n {\\\"BMFBOVESPA\\\", \\\"BR\\\"},\\n {\\\"BSE\\\", \\\"IN\\\"},\\n {\\\"CBOE\\\", \\\"US\\\"},\\n {\\\"CBOT\\\", \\\"US\\\"},\\n {\\\"CME\\\", \\\"US\\\"},\\n {\\\"CME_MINI\\\", \\\"US\\\"},\\n {\\\"COINBASE\\\", \\\"US\\\"},\\n {\\\"COMEX\\\", \\\"US\\\"},\\n {\\\"HKEX\\\", \\\"HK\\\"},\\n {\\\"JSE\\\", \\\"ZA\\\"},\\n {\\\"KOSPI\\\", \\\"KR\\\"},\\n {\\\"KRX\\\", \\\"KR\\\"},\\n {\\\"LSE\\\", \\\"GB\\\"},\\n {\\\"MOEX\\\", \\\"RU\\\"},\\n {\\\"NASDAQ\\\", \\\"US\\\"},\\n {\\\"NSE\\\", \\\"IN\\\"},\\n {\\\"NYMEX\\\", \\\"US\\\"},\\n {\\\"NYSE\\\", \\\"US\\\"},\\n {\\\"OSE\\\", \\\"JP\\\"},\\n {\\\"OTC\\\", \\\"US\\\"},\\n {\\\"SGX\\\", \\\"SG\\\"},\\n {\\\"SIX\\\", \\\"CH\\\"},\\n {\\\"SSE\\\", \\\"CN\\\"},\\n {\\\"SZSE\\\", \\\"CN\\\"},\\n {\\\"TSE\\\", \\\"JP\\\"},\\n {\\\"TSX\\\", \\\"CA\\\"},\\n {\\\"UPBIT\\\", \\\"KR\\\"},\\n {\\\"VENTURE\\\", \\\"CA\\\"},\\n {\\\"XETRA\\\", \\\"DE\\\"}\\n };\\n auto it = _tbl.find(prefix);\\n return (it != _tbl.end()) ? it->second : na();\\n}\\n// --- end syminfo derivation helpers ---\\n\\nclass GeneratedStrategy : public pineforge::source::PineStrategyHost {\\npublic:\\n bool _use_precalc = false;\\n bool _inputs_initialized_ = false;\\n\\n struct _PFScriptState {\\n decltype(GeneratedStrategy::_inputs_initialized_) _pf_value_0;\\n };\\n static_assert(std::is_copy_constructible_v<_PFScriptState>, \\\"generated Pine state must be deep-copy constructible\\\");\\n static_assert(std::is_copy_assignable_v<_PFScriptState>, \\\"generated Pine state must be deep-copy assignable\\\");\\n std::optional<_PFScriptState> _pf_script_state_checkpoint_;\\n\\n void snapshot_script_state() override {\\n _pf_script_state_checkpoint_.emplace(_PFScriptState{\\n _inputs_initialized_,\\n });\\n }\\n\\n void restore_script_state() override {\\n if (!_pf_script_state_checkpoint_) return;\\n this->_inputs_initialized_ = _pf_script_state_checkpoint_->_pf_value_0;\\n }\\n\\n void commit_script_state() override {\\n snapshot_script_state();\\n }\\n\\n explicit GeneratedStrategy() {\\n#if defined(PINEFORGE_HAS_EXPLICIT_PINE_EXECUTION_ADAPTER_V1)\\n pineforge::source::PineStrategyHost::attach_pine_execution_adapter();\\n#elif defined(PINEFORGE_HAS_EXPLICIT_PINE_CAP_V1)\\n pineforge::source::PineStrategyHost::enable_pine_intraday_cap();\\n#endif\\n pineforge::source::PineStrategyConfig cfg{};\\n cfg.initial_capital = 100000.0;\\n cfg.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n cfg.default_qty_value = 100.0;\\n configure_pine_strategy(cfg);\\n }\\n\\n void set_strategy_override(const std::string& key, const std::string& value) {\\n pineforge::source::StrategyOverrides overrides{};\\n if (key == \\\"initial_capital\\\") {\\n overrides.initial_capital = std::stod(value);\\n } else if (key == \\\"commission_value\\\") {\\n overrides.commission_value = std::stod(value);\\n } else if (key == \\\"default_qty_value\\\") {\\n overrides.default_qty_value = std::stod(value);\\n } else if (key == \\\"pyramiding\\\") {\\n overrides.pyramiding = std::stoi(value);\\n } else if (key == \\\"slippage\\\") {\\n overrides.slippage = std::stoi(value);\\n } else if (key == \\\"process_orders_on_close\\\") {\\n overrides.process_orders_on_close = (value == \\\"true\\\" || value == \\\"1\\\");\\n } else if (key == \\\"calc_on_order_fills\\\") {\\n overrides.calc_on_order_fills = (value == \\\"true\\\" || value == \\\"1\\\");\\n } else if (key == \\\"close_entries_rule\\\") {\\n overrides.close_entries_rule = (value == \\\"ANY\\\" || value == \\\"any\\\" || value == \\\"1\\\");\\n } else if (key == \\\"default_qty_type\\\") {\\n if (value == \\\"fixed\\\" || value == \\\"strategy.fixed\\\" || value == \\\"0\\\") overrides.default_qty_type = static_cast(QtyType::FIXED);\\n else if (value == \\\"percent_of_equity\\\" || value == \\\"strategy.percent_of_equity\\\" || value == \\\"1\\\") overrides.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n else if (value == \\\"cash\\\" || value == \\\"strategy.cash\\\" || value == \\\"2\\\") overrides.default_qty_type = static_cast(QtyType::CASH);\\n else return;\\n } else if (key == \\\"commission_type\\\") {\\n if (value == \\\"percent\\\" || value == \\\"strategy.commission.percent\\\" || value == \\\"0\\\") overrides.commission_type = static_cast(CommissionType::PERCENT);\\n else if (value == \\\"cash_per_order\\\" || value == \\\"strategy.commission.cash_per_order\\\" || value == \\\"1\\\") overrides.commission_type = static_cast(CommissionType::CASH_PER_ORDER);\\n else if (value == \\\"cash_per_contract\\\" || value == \\\"strategy.commission.cash_per_contract\\\" || value == \\\"2\\\") overrides.commission_type = static_cast(CommissionType::CASH_PER_CONTRACT);\\n else return;\\n } else {\\n return;\\n }\\n pineforge::source::PineStrategyHost::set_strategy_override(overrides);\\n }\\n bool _pf_setting_failed_ = false;\\n std::string _pf_setting_failure_;\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n ::pineforge::RunFailureInfo _pf_setting_failure_info_{::pineforge::RunFailureCode::none, {}};\\n#ifdef PF_SETTINGS_API_VERSION\\n using _pf_setting_error_base = ::pineforge::checked_settings::LatchedSettingsFailure;\\n#else\\n using _pf_setting_error_base = std::runtime_error;\\n#endif\\n struct _pf_latched_setting_error : _pf_setting_error_base, ::pineforge::RunFailureInfo {\\n _pf_latched_setting_error(const std::string& text, const ::pineforge::RunFailureInfo& info)\\n : _pf_setting_error_base(text), ::pineforge::RunFailureInfo(info) {}\\n };\\n#endif\\n void _pf_record_failure(const char* entrypoint, const char* message) noexcept {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure_unknown(*this, entrypoint); } catch (...) {}\\n#else\\n try { last_error_ = entrypoint; last_error_ += \\\": \\\"; last_error_ += message; } catch (...) {}\\n#endif\\n }\\n void _pf_record_failure(const char* entrypoint, const std::exception& error) noexcept {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure(*this, entrypoint, error); } catch (...) {}\\n#else\\n _pf_record_failure(entrypoint, error.what());\\n#endif\\n }\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n template \\n void _pf_record_setting_failure(const char* entrypoint, const char* message, FailureInfo failure_info) noexcept {\\n#else\\n void _pf_record_setting_failure(const char* entrypoint, const char* message) noexcept {\\n#endif\\n if (!_pf_setting_failed_) {\\n _pf_setting_failed_ = true;\\n try { _pf_setting_failure_ = entrypoint; _pf_setting_failure_ += \\\": \\\"; _pf_setting_failure_ += message; } catch (...) {}\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { _pf_setting_failure_info_ = failure_info(); }\\n catch (...) { _pf_setting_failure_info_ = ::pineforge::RunFailureInfo(::pineforge::RunFailureCode::out_of_memory, {}); }\\n#endif\\n }\\n _pf_refuse_failed_setting(nullptr);\\n }\\n void _pf_require_settings_ok() const {\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n if (_pf_setting_failed_) throw _pf_latched_setting_error(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_, _pf_setting_failure_info_);\\n#elif defined(PF_SETTINGS_API_VERSION)\\n if (_pf_setting_failed_) throw ::pineforge::checked_settings::LatchedSettingsFailure(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_);\\n#else\\n if (_pf_setting_failed_) throw std::runtime_error(_pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_);\\n#endif\\n }\\n bool _pf_refuse_failed_setting(ReportC* out) noexcept {\\n if (!_pf_setting_failed_) return false;\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n try { ::pineforge::note_run_failure(*this, _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_, _pf_setting_failure_info_.run_failure()); } catch (...) {}\\n#else\\n try { last_error_ = _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_; } catch (...) {}\\n#endif\\n if (out) *out = ReportC{};\\n return true;\\n }\\n#ifdef PF_SETTINGS_API_VERSION\\n static pineforge::source::PineStrategyConfig _pf_settings_declared_config() {\\n pineforge::source::PineStrategyConfig cfg{};\\n cfg.initial_capital = 100000.0;\\n cfg.default_qty_type = static_cast(QtyType::PERCENT_OF_EQUITY);\\n cfg.default_qty_value = 100.0;\\n return cfg;\\n }\\n std::vector<::pineforge::checked_settings::Setting> _pf_settings_inputs() const {\\n return {\\n };\\n }\\n std::vector<::pineforge::checked_settings::Setting> _pf_settings_overrides() const {\\n const double _pf_nan = std::numeric_limits::quiet_NaN();\\n const auto _pf_defaults = _pf_settings_declared_config();\\n return {\\n {\\\"initial_capital\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.initial_capital), {}, 0.0},\\n {\\\"commission_value\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.commission_value), {}, 0.0},\\n {\\\"default_qty_value\\\", \\\"float\\\", ::pineforge::checked_settings::number(_pf_defaults.default_qty_value), {}, 0.0},\\n {\\\"pyramiding\\\", \\\"int\\\", ::pineforge::checked_settings::number(_pf_defaults.pyramiding), {}, 0.0},\\n {\\\"slippage\\\", \\\"int\\\", ::pineforge::checked_settings::number(_pf_defaults.slippage), {}, 0.0},\\n {\\\"process_orders_on_close\\\", \\\"bool\\\", ::pineforge::checked_settings::number(_pf_defaults.process_orders_on_close), {}, _pf_nan},\\n {\\\"calc_on_order_fills\\\", \\\"bool\\\", ::pineforge::checked_settings::number(_pf_defaults.calc_on_order_fills), {}, _pf_nan},\\n {\\\"close_entries_rule\\\", \\\"string\\\", _pf_close_entries_rule_word(_pf_defaults.close_entries_rule_any), {\\\"FIFO\\\", \\\"ANY\\\"}, _pf_nan},\\n {\\\"default_qty_type\\\", \\\"string\\\", _pf_default_qty_type_word(_pf_defaults.default_qty_type), {\\\"fixed\\\", \\\"percent_of_equity\\\", \\\"cash\\\"}, _pf_nan},\\n {\\\"commission_type\\\", \\\"string\\\", _pf_commission_type_word(_pf_defaults.commission_type), {\\\"percent\\\", \\\"cash_per_order\\\", \\\"cash_per_contract\\\"}, _pf_nan},\\n };\\n }\\n static std::string _pf_close_entries_rule_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"FIFO\\\";\\n if (_pf_value == 1) return \\\"ANY\\\";\\n return \\\"invalid\\\";\\n }\\n static std::string _pf_default_qty_type_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"fixed\\\";\\n if (_pf_value == 1) return \\\"percent_of_equity\\\";\\n if (_pf_value == 2) return \\\"cash\\\";\\n return \\\"invalid\\\";\\n }\\n static std::string _pf_commission_type_word(int _pf_value) {\\n if (_pf_value == 0) return \\\"percent\\\";\\n if (_pf_value == 1) return \\\"cash_per_order\\\";\\n if (_pf_value == 2) return \\\"cash_per_contract\\\";\\n return \\\"invalid\\\";\\n }\\n void _pf_set_input_checked(const std::string& _pf_key, const std::string& _pf_value) {\\n if (_pf_refuse_failed_setting(nullptr)) throw ::pineforge::checked_settings::Error{PF_SETTINGS_RUN_FAILED, last_error_.c_str()};\\n ::pineforge::checked_settings::require(script_bars_processed() == 0 && stream_phase_ == StreamPhase::IDLE, \\\"settings are frozen after execution begins\\\", PF_SETTINGS_UNSUPPORTED);\\n const auto _pf_inputs = _pf_settings_inputs();\\n const ::pineforge::checked_settings::Setting* _pf_match = nullptr;\\n for (const auto& _pf_input : _pf_inputs) {\\n if (_pf_input.name != _pf_key) continue;\\n ::pineforge::checked_settings::require(_pf_match == nullptr, \\\"ambiguous input key\\\", PF_SETTINGS_UNSUPPORTED);\\n _pf_match = &_pf_input;\\n }\\n ::pineforge::checked_settings::require(_pf_match != nullptr, \\\"unknown input key\\\");\\n const auto _pf_canonical = ::pineforge::checked_settings::validate(*_pf_match, _pf_value);\\n set_input(_pf_key, _pf_canonical);\\n ::pineforge::checked_settings::require(inputs_.count(_pf_key) && inputs_.at(_pf_key) == _pf_canonical, \\\"input was not installed\\\", PF_SETTINGS_UNSUPPORTED);\\n }\\n void _pf_set_override_checked(const std::string& _pf_key, const std::string& _pf_value) {\\n if (_pf_refuse_failed_setting(nullptr)) throw ::pineforge::checked_settings::Error{PF_SETTINGS_RUN_FAILED, last_error_.c_str()};\\n ::pineforge::checked_settings::require(script_bars_processed() == 0 && stream_phase_ == StreamPhase::IDLE, \\\"settings are frozen after execution begins\\\", PF_SETTINGS_UNSUPPORTED);\\n for (const auto& _pf_override : _pf_settings_overrides()) {\\n if (_pf_override.name != _pf_key) continue;\\n auto _pf_alias = _pf_value;\\n if (_pf_key == \\\"close_entries_rule\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"fifo\\\") _pf_alias = \\\"FIFO\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"any\\\") _pf_alias = \\\"ANY\\\";\\n }\\n if (_pf_key == \\\"default_qty_type\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"strategy.fixed\\\") _pf_alias = \\\"fixed\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"strategy.percent_of_equity\\\") _pf_alias = \\\"percent_of_equity\\\";\\n if (_pf_value == \\\"2\\\" || _pf_value == \\\"strategy.cash\\\") _pf_alias = \\\"cash\\\";\\n }\\n if (_pf_key == \\\"commission_type\\\") {\\n if (_pf_value == \\\"0\\\" || _pf_value == \\\"strategy.commission.percent\\\") _pf_alias = \\\"percent\\\";\\n if (_pf_value == \\\"1\\\" || _pf_value == \\\"strategy.commission.cash_per_order\\\") _pf_alias = \\\"cash_per_order\\\";\\n if (_pf_value == \\\"2\\\" || _pf_value == \\\"strategy.commission.cash_per_contract\\\") _pf_alias = \\\"cash_per_contract\\\";\\n }\\n const auto _pf_canonical = ::pineforge::checked_settings::validate(_pf_override, _pf_alias);\\n set_strategy_override(_pf_key, _pf_canonical);\\n return;\\n }\\n throw ::pineforge::checked_settings::Error{PF_SETTINGS_INVALID_ARGUMENT, \\\"unknown override key\\\"};\\n }\\n std::string _pf_settings_receipt() const {\\n ::pineforge::checked_settings::require(!_pf_setting_failed_, _pf_setting_failure_.empty() ? \\\"legacy strategy setter failed\\\" : _pf_setting_failure_.c_str(), PF_SETTINGS_RUN_FAILED);\\n std::string _pf_document = \\\"{\\\\\\\"version\\\\\\\":1,\\\\\\\"inputs\\\\\\\":[\\\";\\n const auto _pf_inputs = _pf_settings_inputs();\\n _pf_document += \\\"],\\\\\\\"overrides\\\\\\\":[\\\";\\n const auto _pf_overrides = _pf_settings_overrides();\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[0], ::pineforge::checked_settings::number((std::isnan(override_.initial_capital) ? config_.initial_capital : override_.initial_capital)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[1], ::pineforge::checked_settings::number((std::isnan(override_.commission_value) ? config_.commission_value : override_.commission_value)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[2], ::pineforge::checked_settings::number((std::isnan(override_.default_qty_value) ? config_.default_qty_value : override_.default_qty_value)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[3], ::pineforge::checked_settings::number((override_.pyramiding < 0 ? config_.pyramiding : override_.pyramiding)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[4], ::pineforge::checked_settings::number((override_.slippage < 0 ? config_.slippage : override_.slippage)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[5], ::pineforge::checked_settings::number(static_cast((override_.process_orders_on_close < 0 ? config_.process_orders_on_close : override_.process_orders_on_close))));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[6], ::pineforge::checked_settings::number(static_cast((override_.calc_on_order_fills < 0 ? config_.calc_on_order_fills : override_.calc_on_order_fills))));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[7], _pf_close_entries_rule_word((override_.close_entries_rule < 0 ? config_.close_entries_rule_any : override_.close_entries_rule)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[8], _pf_default_qty_type_word((override_.default_qty_type < 0 ? config_.default_qty_type : override_.default_qty_type)));\\n _pf_document += ',';\\n _pf_document += ::pineforge::checked_settings::describe(_pf_overrides[9], _pf_commission_type_word((override_.commission_type < 0 ? config_.commission_type : override_.commission_type)));\\n return _pf_document + \\\"]}\\\";\\n }\\n#endif\\n\\n#ifndef PINEFORGE_HAS_SCRIPT_RUN_PREPARE_V1\\n#error \\\"Generated lifecycle reset requires a matching PineForge engine; rebuild with script-run preparation support\\\"\\n#endif\\n void prepare_script_run(const Bar* bars, int n, bool allow_precalculation) override {\\n _pf_require_settings_ok();\\n _pf_script_state_checkpoint_.reset();\\n this->_use_precalc = false;\\n this->_inputs_initialized_ = false;\\n (void)bars; (void)n; (void)allow_precalculation;\\n }\\n\\n void on_source_bar(const Bar& bar) override {\\n set_pine_risk_max_drawdown((double)(10), true);\\n }\\n\\n\\n};\\n\\nextern \\\"C\\\" {\\n#if defined(PINEFORGE_HAS_RUN_FAILURE_CODES_V1) && defined(PF_SETTINGS_API_VERSION)\\n int strategy_create_checked(const char* params_json, void** out, char* error, size_t error_capacity);\\n#endif\\n void* strategy_create(const char* params_json) {\\n#if defined(PINEFORGE_HAS_RUN_FAILURE_CODES_V1) && defined(PF_SETTINGS_API_VERSION)\\n void* out = nullptr;\\n strategy_create_checked(nullptr, &out, nullptr, 0);\\n return out;\\n#else\\n try { return new GeneratedStrategy(); } catch (...) { return nullptr; }\\n#endif\\n }\\n void run_backtest(void* s, Bar* bars, int n, ReportC* out) {\\n try {\\n auto* strat = static_cast(s);\\n#ifndef PF_SETTINGS_API_VERSION\\n if (strat->_pf_refuse_failed_setting(out)) return;\\n#endif\\n strat->run(bars, n);\\n if (!strat->_pf_refuse_failed_setting(out)) strat->fill_report(out);\\n } catch (const std::exception& _pf_error) {\\n if (out) *out = ReportC{};\\n if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest\\\", _pf_error);\\n } catch (...) {\\n if (out) *out = ReportC{};\\n if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest\\\", \\\"unknown C++ exception\\\");\\n }\\n }\\n static void _pf_run_backtest_full_impl(void* s, Bar* bars, int n,\\n const char* input_tf, const char* script_tf,\\n int bar_magnifier, int magnifier_samples,\\n int magnifier_dist,\\n ReportC* out) {\\n auto* strat = static_cast(s);\\n#ifndef PF_SETTINGS_API_VERSION\\n if (strat->_pf_refuse_failed_setting(out)) return;\\n#endif\\n std::string itf = input_tf ? input_tf : \\\"\\\";\\n std::string stf = script_tf ? script_tf : \\\"\\\";\\n bool needs_full_run = (bar_magnifier != 0)\\n || !itf.empty() || !stf.empty();\\n if (!needs_full_run) {\\n strat->run(bars, n);\\n } else {\\n strat->run(bars, n, itf, stf, bar_magnifier != 0, magnifier_samples,\\n static_cast(magnifier_dist));\\n }\\n if (!strat->_pf_refuse_failed_setting(out)) strat->fill_report(out);\\n }\\n void run_backtest_full(void* s, Bar* bars, int n, const char* input_tf, const char* script_tf,\\n int bar_magnifier, int magnifier_samples, int magnifier_dist, ReportC* out) {\\n try { _pf_run_backtest_full_impl(s, bars, n, input_tf, script_tf, bar_magnifier, magnifier_samples, magnifier_dist, out); }\\n catch (const std::exception& _pf_error) { if (out) *out = ReportC{}; if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest_full\\\", _pf_error); }\\n catch (...) { if (out) *out = ReportC{}; if (s) static_cast(s)->_pf_record_failure(\\\"run_backtest_full\\\", \\\"unknown C++ exception\\\"); }\\n }\\n void strategy_free(void* s) {\\n try { delete static_cast(s); } catch (...) {}\\n }\\n void report_free(ReportC* report) {\\n try { BacktestEngine::free_report(report); } catch (...) {}\\n }\\n void strategy_set_input(void* s, const char* key, const char* value) {\\n if (!s || !key || !value) return;\\n try { static_cast(s)->set_input(key, value); }\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_input\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_input\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n void strategy_set_override(void* s, const char* key, const char* value) {\\n if (!s || !key || !value) return;\\n try { static_cast(s)->set_strategy_override(key, value); }\\n#ifdef PINEFORGE_HAS_RUN_FAILURE_CODES_V1\\n catch (const std::invalid_argument& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), \\\"unparseable_value\\\"); }\\n catch (const std::out_of_range& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), \\\"unparseable_value\\\"); }\\n#endif\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_override\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n void strategy_set_magnifier_volume_weighted(void* s, int on) {\\n if (!s) return;\\n try { static_cast(s)->set_magnifier_volume_weighted(on != 0); }\\n catch (const std::exception& _pf_error) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_magnifier_volume_weighted\\\", _pf_error.what(), nullptr); }\\n catch (...) { _PF_SETTING_FAILURE(static_cast(s), \\\"strategy_set_magnifier_volume_weighted\\\", \\\"unknown C++ exception\\\", nullptr); }\\n }\\n#ifdef PF_SETTINGS_API_VERSION\\n uint32_t strategy_settings_api_version(void) { return PF_SETTINGS_API_VERSION; }\\n int strategy_create_checked(const char* params_json, void** out, char* error, size_t error_capacity) {\\n if (out) *out = nullptr;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(out != nullptr, \\\"strategy output pointer is null\\\");\\n ::pineforge::checked_settings::require(!params_json || !*params_json, \\\"params_json is reserved; use checked setters\\\", PF_SETTINGS_UNSUPPORTED);\\n *out = new GeneratedStrategy();\\n });\\n }\\n int strategy_set_input_checked(void* s, const char* key, const char* value, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && key && value, \\\"null strategy, key or value\\\");\\n static_cast(s)->_pf_set_input_checked(key, value);\\n });\\n }\\n int strategy_set_override_checked(void* s, const char* key, const char* value, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && key && value, \\\"null strategy, key or value\\\");\\n static_cast(s)->_pf_set_override_checked(key, value);\\n });\\n }\\n int strategy_get_effective_settings(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(static_cast(s)->_pf_settings_receipt(), json, capacity, required);\\n });\\n }\\n int run_backtest_full_checked(void* s, Bar* bars, int n, const char* input_tf, const char* script_tf, int bar_magnifier, int magnifier_samples, int magnifier_dist, ReportC* out, char* error, size_t error_capacity) {\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s && out && n >= 0 && (n == 0 || bars), \\\"invalid batch arguments\\\");\\n _pf_run_backtest_full_impl(s, bars, n, input_tf, script_tf, bar_magnifier, magnifier_samples, magnifier_dist, out);\\n const auto& _pf_error = static_cast(s)->last_error();\\n ::pineforge::checked_settings::require(_pf_error.empty(), _pf_error.c_str(), PF_SETTINGS_RUN_FAILED);\\n });\\n }\\n#endif\\n#ifdef PF_SETTINGS_API_VERSION\\n#ifdef PF_CAPABILITIES_API_VERSION\\n uint32_t strategy_capabilities_api_version(void) { return PF_CAPABILITIES_API_VERSION; }\\n int strategy_capabilities_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"declarations\\\\\\\":{\\\\\\\"backtest_fill_limits_assumption\\\\\\\":0,\\\\\\\"calc_on_every_history_tick\\\\\\\":false,\\\\\\\"calc_on_every_tick\\\\\\\":false,\\\\\\\"calc_on_order_fills\\\\\\\":false,\\\\\\\"currency\\\\\\\":\\\\\\\"currency.NONE\\\\\\\",\\\\\\\"dynamic_requests\\\\\\\":true,\\\\\\\"fill_orders_on_standard_ohlc\\\\\\\":false,\\\\\\\"process_orders_on_close\\\\\\\":false,\\\\\\\"timeframe\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"timeframe_gaps\\\\\\\":true,\\\\\\\"use_bar_magnifier\\\\\\\":false},\\\\\\\"requests\\\\\\\":[],\\\\\\\"requirements\\\\\\\":{\\\\\\\"auxiliary_security_feeds\\\\\\\":false,\\\\\\\"fx_curve\\\\\\\":false,\\\\\\\"historical_probe_overrides\\\\\\\":false,\\\\\\\"intrabar_persistence\\\\\\\":false,\\\\\\\"native_security_feeds\\\\\\\":false,\\\\\\\"recorded_series\\\\\\\":false},\\\\\\\"unresolved\\\\\\\":[],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n uint32_t strategy_confirmed_bar_api_version(void) { return 1u; }\\n int strategy_confirmed_bar_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"intrabar_persistence\\\\\\\":false,\\\\\\\"orders\\\\\\\":[\\\\\\\"strategy.risk.max_drawdown (unproven order shape)\\\\\\\"],\\\\\\\"requests\\\\\\\":[],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n uint32_t strategy_order_shapes_api_version(void) { return 1u; }\\n int strategy_order_shapes_receipt(void* s, char* json, size_t capacity, size_t* required, char* error, size_t error_capacity) {\\n if (required) *required = 0;\\n return ::pineforge::checked_settings::boundary(error, error_capacity, [&] {\\n ::pineforge::checked_settings::require(s != nullptr, \\\"null strategy\\\");\\n ::pineforge::checked_settings::receipt(\\\"{\\\\\\\"calls\\\\\\\":[],\\\\\\\"entry_ids\\\\\\\":{\\\\\\\"long\\\\\\\":0,\\\\\\\"multi_site\\\\\\\":0,\\\\\\\"shared\\\\\\\":0,\\\\\\\"short\\\\\\\":0},\\\\\\\"host_reads\\\\\\\":[\\\\\\\"StreamPhase\\\\\\\",\\\\\\\"commit_script_state\\\\\\\",\\\\\\\"config_\\\\\\\",\\\\\\\"configure_pine_strategy\\\\\\\",\\\\\\\"fill_report\\\\\\\",\\\\\\\"inputs_\\\\\\\",\\\\\\\"last_error\\\\\\\",\\\\\\\"last_error_\\\\\\\",\\\\\\\"on_source_bar\\\\\\\",\\\\\\\"override_\\\\\\\",\\\\\\\"prepare_script_run\\\\\\\",\\\\\\\"restore_script_state\\\\\\\",\\\\\\\"run\\\\\\\",\\\\\\\"script_bars_processed\\\\\\\",\\\\\\\"set_input\\\\\\\",\\\\\\\"set_magnifier_volume_weighted\\\\\\\",\\\\\\\"set_pine_risk_max_drawdown\\\\\\\",\\\\\\\"set_strategy_override\\\\\\\",\\\\\\\"snapshot_script_state\\\\\\\",\\\\\\\"stream_phase_\\\\\\\"],\\\\\\\"process_orders_on_close\\\\\\\":false,\\\\\\\"settings\\\\\\\":{\\\\\\\"close_entries_rule\\\\\\\":\\\\\\\"FIFO\\\\\\\",\\\\\\\"commission_type\\\\\\\":\\\\\\\"percent\\\\\\\",\\\\\\\"commission_value\\\\\\\":0.0,\\\\\\\"default_qty_type\\\\\\\":\\\\\\\"percent_of_equity\\\\\\\",\\\\\\\"default_qty_value\\\\\\\":100.0,\\\\\\\"initial_capital\\\\\\\":100000.0,\\\\\\\"margin_long\\\\\\\":100.0,\\\\\\\"margin_short\\\\\\\":100.0,\\\\\\\"pyramiding\\\\\\\":1,\\\\\\\"slippage\\\\\\\":0},\\\\\\\"unmodeled\\\\\\\":[\\\\\\\"strategy.risk.max_drawdown\\\\\\\"],\\\\\\\"version\\\\\\\":1}\\\", json, capacity, required);\\n });\\n }\\n#endif\\n#endif\\n}\\n\", \"inputs\": [], \"strategyParams\": {\"title\": \"Risk\"}, \"diagnostics\": [{\"line\": 3, \"col\": 27, \"message\": \"strategy.risk.max_drawdown(...) has partial PineForge runtime support. \\u2014 Verify risk behavior against PineForge results; unsupported risk edge cases may diverge from TradingView.\", \"severity\": \"warning\", \"code\": \"PF-W1503\", \"args\": {\"name\": \"max_drawdown\"}, \"endCol\": 28}], \"requests\": []}", + "error_with_note": "{\"ok\": false, \"error\": \":3:11: ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does.; :4:17: request.seed(...) is not supported.\", \"diagnostics\": [{\"line\": 3, \"col\": 11, \"message\": \"ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does. \\u2014 A covered length-20 TradingView tape first returns a finite EMA at bar 19; standalone PineForge EMA is finite at bar 0. Its established lowering stays in place pending per-call-site population parity.\", \"severity\": \"warning\", \"code\": \"PF-W1505\", \"args\": {}, \"endCol\": 12}, {\"line\": 4, \"col\": 17, \"message\": \"request.seed(...) is not supported. \\u2014 External seed data feeds not available in PineForge.\", \"severity\": \"error\", \"code\": \"PF-E1027\", \"args\": {\"full\": \"request.seed\"}, \"endCol\": 18}]}", + "unicode_escape_error": "{\"ok\": false, \"error\": \":4:1: Unexpected token EOF_TOKEN('')\", \"diagnostics\": [{\"line\": 4, \"col\": 1, \"message\": \"Unexpected token EOF_TOKEN('')\", \"severity\": \"error\", \"code\": \"PF-E0037\", \"args\": {\"token_type\": \"EOF_TOKEN\", \"token\": \"\"}, \"endCol\": 1}]}" + }, + "text": { + "error_with_note": { + "format": "warning[ANALYZER]: ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does.\n --> :3:11\n |\n 3 | x = ta.ema(close, 20)\n | ^\n = hint: A covered length-20 TradingView tape first returns a finite EMA at bar 19; standalone PineForge EMA is finite at bar 0. Its established lowering stays in place pending per-call-site population parity.\n\nerror[ANALYZER]: request.seed(...) is not supported.\n --> :4:17\n |\n 4 | y = request.seed(\"x\", \"y\", close)\n | ^\n = hint: External seed data feeds not available in PineForge.", + "error": ":3:11: ta.ema initial warmup is approximated: PineForge may return a finite value before TradingView does.; :4:17: request.seed(...) is not supported." + }, + "unicode_escape_error": { + "format": "error[PARSER]: Unexpected token EOF_TOKEN('')\n --> :4:1\n |\n 4 | \n | ^", + "error": ":4:1: Unexpected token EOF_TOKEN('')" + } + } +} diff --git a/tests/fixtures/diagnostic_notes/receiver.json b/tests/fixtures/diagnostic_notes/receiver.json new file mode 100644 index 0000000..35634de --- /dev/null +++ b/tests/fixtures/diagnostic_notes/receiver.json @@ -0,0 +1,10 @@ +{ + "scope": "Contract fixtures only; these are not an app E2E receipt.", + "cases": [ + {"code": "PF-FUTURE", "severity": "note", "user_message": "Data is unavailable for {name}.", "args": {"name": "台灣 & ' {x}"}, "expected_severity": "note", "expected_text": "Data is unavailable for 台灣 & ' {x}."}, + {"code": "PF-FUTURE", "severity": "warning", "user_message": "Check the value of {name}.", "args": {"name": "length"}, "expected_severity": "warning", "expected_text": "Check the value of length."}, + {"code": "PF-FUTURE", "severity": "error", "user_message": "The value is invalid.", "args": {}, "expected_severity": "error", "expected_text": "The value is invalid."}, + {"code": "PF-FUTURE", "severity": "future-level", "user_message": "Check {name}.", "args": {"name": "輸入"}, "expected_severity": "warning", "expected_text": "Check 輸入."}, + {"code": "PF-W1508", "severity": "future-level", "user_message": "{name}() does nothing in a backtest.", "args": {"name": "plot"}, "expected_severity": "warning", "expected_text": "plot() does nothing in a backtest."} + ] +} diff --git a/tests/fixtures/diagnostic_notes/warmup_consumer.py b/tests/fixtures/diagnostic_notes/warmup_consumer.py new file mode 100644 index 0000000..6dd4f11 --- /dev/null +++ b/tests/fixtures/diagnostic_notes/warmup_consumer.py @@ -0,0 +1,55 @@ +"""Typed handoff example only; W4 inventory precedes a production sidecar. + +These types describe the accepted facts a consumer must retain. They neither +extract TA sites nor infer startup lengths, convergence, or run adequacy. +""" +from typing import Literal, TypedDict + + +class SourceRange(TypedDict): + line: int + col: int + end_line: int + end_col: int + + +class Length(TypedDict): + kind: Literal["constant", "input", "unknown"] + value: int | None + input_name: str | None + expression: str | None + + +class Site(TypedDict): + call_site_id: str + source_range: SourceRange + code: Literal["PF-W1505"] + length: Length + context: Literal["chart", "same_symbol_request", "other_symbol_request"] + timeframe: str | None + seeding: Literal["first_value", "sma", "unknown"] + startup_unit: Literal["bars_of_evaluation_context_timeframe"] + required_startup_bars: int | None + recursive_adequacy: Literal["unknown"] + has_unbounded_state: bool + + +class CompileSidecar(TypedDict): + version: Literal[1] + source_sha256: str + generated_sha256: str + sites: list[Site] + + +class ResolvedLength(TypedDict): + call_site_id: str + source_range: SourceRange + scope: Literal["run", "trial", "study"] + submitted_value: int | None + searched_range: list[int] | None + + +def same_site(diagnostic: dict, site: Site) -> bool: + """Text is deliberately absent from this fixture's join predicate.""" + return (diagnostic.get("call_site_id") == site["call_site_id"] + and diagnostic.get("source_range") == site["source_range"]) diff --git a/tests/fixtures/diagnostic_notes/warmup_handoff.json b/tests/fixtures/diagnostic_notes/warmup_handoff.json new file mode 100644 index 0000000..41d5c97 --- /dev/null +++ b/tests/fixtures/diagnostic_notes/warmup_handoff.json @@ -0,0 +1,19 @@ +{ + "scope": "Typed consumer handoff only, not emitted sidecar code or measured TA startup requirements; W4 inventory comes first.", + "rules": { + "startup_presentation": "Only known finite shortfall measured in bars of the site's evaluation-context timeframe may trigger PF-W1505 presentation.", + "absence": "Absence of the startup note is not parity or recursive adequacy.", + "binding": "The trusted compile path binds Pine/generated hashes and copies call_site_id plus the exact same source range to the diagnostic and sidecar.", + "input": "Resolve the named input/expression from the submitted run/trial value or the study searched range, never only its default." + }, + "sites": [ + {"call_site_id": "chart-ema", "source_range": {"line": 3, "col": 5, "end_line": 3, "end_col": 22}, "code": "PF-W1505", "length": {"kind": "constant", "value": 20, "input_name": null, "expression": null}, "context": "chart", "timeframe": "15", "seeding": "first_value", "startup_unit": "bars_of_evaluation_context_timeframe", "required_startup_bars": null, "recursive_adequacy": "unknown", "has_unbounded_state": true}, + {"call_site_id": "same-symbol-ema", "source_range": {"line": 5, "col": 42, "end_line": 5, "end_col": 64}, "code": "PF-W1505", "length": {"kind": "input", "value": null, "input_name": "Length", "expression": "lengthInput"}, "context": "same_symbol_request", "timeframe": "D", "seeding": "first_value", "startup_unit": "bars_of_evaluation_context_timeframe", "required_startup_bars": null, "recursive_adequacy": "unknown", "has_unbounded_state": true}, + {"call_site_id": "other-symbol-ema", "source_range": {"line": 7, "col": 48, "end_line": 7, "end_col": 72}, "code": "PF-W1505", "length": {"kind": "unknown", "value": null, "input_name": null, "expression": "dynamicLength"}, "context": "other_symbol_request", "timeframe": "60", "seeding": "sma", "startup_unit": "bars_of_evaluation_context_timeframe", "required_startup_bars": null, "recursive_adequacy": "unknown", "has_unbounded_state": true} + ], + "effective_inputs": [ + {"call_site_id": "same-symbol-ema", "source_range": {"line": 5, "col": 42, "end_line": 5, "end_col": 64}, "scope": "run", "submitted_value": 37, "searched_range": null}, + {"call_site_id": "same-symbol-ema", "source_range": {"line": 5, "col": 42, "end_line": 5, "end_col": 64}, "scope": "trial", "submitted_value": 41, "searched_range": null}, + {"call_site_id": "same-symbol-ema", "source_range": {"line": 5, "col": 42, "end_line": 5, "end_col": 64}, "scope": "study", "submitted_value": null, "searched_range": [10, 100]} + ] +} diff --git a/tests/test_diagnostic_codes.py b/tests/test_diagnostic_codes.py index eefb024..5b517d2 100644 --- a/tests/test_diagnostic_codes.py +++ b/tests/test_diagnostic_codes.py @@ -55,7 +55,12 @@ def test_catalog_entries_are_well_formed(): assert diagnostics_catalog()["schema"] == "pineforge-diagnostics-catalog/v1" for code, entry in CATALOG.items(): assert re.fullmatch(r"PF-[EW][0-9]{4}", code), code - assert entry["severity"] == {"E": "error", "W": "warning"}[code[3]], code + # Stable historical W identities also carry notes, so the letter fixes + # only error versus nonfatal; warning versus note is the declared + # severity, never read off the W (the pin and the explicit migration + # delta keep it). + assert entry["severity"] in {"error", "warning", "note"}, code + assert (entry["severity"] == "error") == (code[3] == "E"), code assert entry["area"], code explanation = entry["explanation"] assert explanation and "\n" not in explanation and len(explanation) <= 300, code diff --git a/tests/test_diagnostic_notes.py b/tests/test_diagnostic_notes.py new file mode 100644 index 0000000..abb0171 --- /dev/null +++ b/tests/test_diagnostic_notes.py @@ -0,0 +1,478 @@ +"""Real Python/browser interfaces for the explicitly bounded NOTE migration.""" + +import json +import copy +import hashlib +import re +from dataclasses import asdict, replace +from pathlib import Path + +import pytest + +from pineforge_codegen import diagnostics_catalog, transpile_full +from pineforge_codegen.errors import CompileError, Level +from pineforge_codegen.errors import Diagnostic, Phase, SourceLocation +from pineforge_codegen.diagnostic_codes import classify, parse_template, render, render_diagnostic + + +FIXTURES = Path(__file__).parent / "fixtures" / "diagnostic_notes" +CASES = json.loads((FIXTURES / "interfaces.json").read_text())["cases"] +DELTA = json.loads((FIXTURES / "delta.json").read_text()) +NOTE_CODES = set(DELTA["severity_changes"]) +BEFORE = json.loads((FIXTURES / "catalog.before.json").read_text())["codes"] +PRODUCT_BEFORE = json.loads((FIXTURES / "product.before.json").read_text()) +# The support checker warns, inside a switch arm, what it refuses elsewhere: +# PF-W1nnn is PF-E1nnn there. Read off the live catalog, so a twin added later +# is covered by the sentence tests below without an edit here. +TWINS = sorted("PF-W" + code[4:] for code in diagnostics_catalog()["codes"] if code.startswith("PF-E1")) + + +def _assert_catalog_delta(catalog): + assert set(catalog) == set(BEFORE) + changed = set() + for code, old in BEFORE.items(): + entry = dict(catalog[code]) + template = entry.pop("user_message") + assert isinstance(template, str) and template.strip() == template + assert template.endswith(".") and "\n" not in template + assert len(template) <= 180 + parts = parse_template(template) + names = {p[0] for p in parts if isinstance(p, tuple)} + assert names <= set(old["args"]), code + assert any(isinstance(p, str) and p.strip(" .") for p in parts), code + if entry["severity"] != old["severity"]: + changed.add(code) + expected = DELTA["severity_changes"][code] + assert (old["severity"], entry["severity"]) == (expected["before"], expected["after"]) + assert template == expected["user_message"] + entry["severity"] = old["severity"] + assert entry == old, code + assert changed == NOTE_CODES + + +def test_exact_catalog_delta_and_legacy_pin(): + catalog = diagnostics_catalog()["codes"] + _assert_catalog_delta(catalog) + legacy = json.loads((FIXTURES / "diagnostic_codes_pin.legacy.json").read_text())["codes"] + current = json.loads((FIXTURES.parent / "diagnostic_codes_pin.json").read_text())["codes"] + assert set(current) == set(legacy) == set(catalog) + assert {code for code in legacy if legacy[code] != current[code]} == NOTE_CODES + for code, entry in BEFORE.items(): + meaning = json.dumps([entry["severity"], entry["message"], entry.get("hint"), + sorted(entry["args"])], ensure_ascii=False) + assert hashlib.sha256(meaning.encode()).hexdigest() == legacy[code] + + +def test_catalog_legacy_bytes_only_have_the_declared_delta(): + path = Path(__file__).resolve().parents[1] / "pineforge_codegen" / "diagnostics_catalog.json" + catalog = diagnostics_catalog()["codes"] + restored = [] + for line in path.read_text().splitlines(keepends=True): + match = re.match(r' "(PF-[EW][0-9]{4})": ', line) + if match: + code = match[1] + field = ', "user_message": ' + json.dumps(catalog[code]["user_message"], ensure_ascii=False) + assert line.count(field) == 1 + line = line.replace(field, "") + if code in NOTE_CODES: + line = line.replace('"severity": "note"', '"severity": "warning"', 1) + restored.append(line) + assert "".join(restored).encode() == (FIXTURES / "catalog.before.json").read_bytes() + + +@pytest.mark.parametrize("mutation", ["message", "hint", "explanation", "args", "severity", "user_message"]) +def test_catalog_delta_rejects_malformed_candidate(mutation): + bad = copy.deepcopy(diagnostics_catalog()["codes"]) + # A genuine warning outside the migration is the positive control's subject. + entry = bad["PF-W1503"] + entry[mutation] = ({"invented": {"kind": "text"}} if mutation == "args" + else "note" if mutation == "severity" + else "An invented {argument}." if mutation == "user_message" + else "changed") + with pytest.raises((AssertionError, KeyError)): + _assert_catalog_delta(bad) + + +@pytest.mark.parametrize("code", sorted(NOTE_CODES)) +def test_stable_note_identity_uses_declared_severity(code): + entry = diagnostics_catalog()["codes"][code] + args = {name: (7 if spec["kind"] == "number" else + spec["values"][0] if spec["kind"] == "vocab" else + "台灣 <>& '\" {not_an_argument}") for name, spec in entry["args"].items()} + message, hint = render_diagnostic(code, args) + # These legacy templates differ only in the argument's name; the existing + # text classifier chooses the lower stable code at the specificity tie. + expected_code = "PF-W1508" if code == "PF-W1509" else code + expected_args = {"name": args["full"]} if code == "PF-W1509" else args + assert classify("note", message, hint) == (expected_code, expected_args) + assert classify("warning", message, hint)[0] != code + assert classify("error", message, hint)[0] != code + d = Diagnostic(Level.NOTE, Phase.ANALYZER, SourceLocation("例.pine", 3, 2, 8), message, hint) + assert d.code == expected_code and d.args == expected_args + assert d.user_message == diagnostics_catalog()["codes"][expected_code]["user_message"] + assert render(d.user_message, expected_args) + + +def test_uncatalogued_note_retains_existing_nonfatal_identity(): + message, hint = "未知 '\" {v}\nmessage", "hint 🐍" + diagnostic = Diagnostic(Level.NOTE, Phase.ANALYZER, SourceLocation("x", 1, 1, 2), message, hint) + assert diagnostic.code == "PF-W0000" + assert diagnostic.level.value == "note" + assert diagnostic.args == {"message": message, "hint": hint} + entry = diagnostics_catalog()["codes"]["PF-W0000"] + assert entry["severity"] == BEFORE["PF-W0000"]["severity"] == "warning" + assert diagnostic.user_message == entry["user_message"] + assert diagnostic.user_message != "{message}" + namespace = {} + path = Path(__file__).resolve().parents[1] / "gate" / "glue.py" + exec(compile(path.read_text(), str(path), "exec"), namespace) + wire = json.loads(json.dumps(namespace["_diagnostic_entries"]([diagnostic])))[0] + assert wire["severity"] == "note" and wire["code"] == "PF-W0000" + assert wire["message"] == message + " — " + hint + assert wire["user_message"] == diagnostic.user_message + + +def test_receiver_compatibility_vectors(): + """Executable contract examples, not an app implementation or app E2E.""" + cases = json.loads((FIXTURES / "receiver.json").read_text())["cases"] + for case in cases: + severity = case["severity"] if case["severity"] in {"error", "warning", "note"} else "warning" + assert severity == case["expected_severity"] + assert render(case["user_message"], case["args"]) == case["expected_text"] + + +def test_typed_warmup_handoff_keeps_identity_range_units_and_inputs(): + import runpy + types = runpy.run_path(str(FIXTURES / "warmup_consumer.py")) + fixture = json.loads((FIXTURES / "warmup_handoff.json").read_text()) + sites = fixture["sites"] + assert {site["context"] for site in sites} == {"chart", "same_symbol_request", "other_symbol_request"} + assert {site["length"]["kind"] for site in sites} == {"constant", "input", "unknown"} + for site in sites: + assert set(site) == types["Site"].__required_keys__ + assert set(site["source_range"]) == types["SourceRange"].__required_keys__ + assert site["startup_unit"] == "bars_of_evaluation_context_timeframe" + assert site["required_startup_bars"] is None # no invented convergence threshold + assert site["recursive_adequacy"] == "unknown" and site["has_unbounded_state"] + diagnostic = {"call_site_id": site["call_site_id"], "source_range": dict(site["source_range"])} + assert types["same_site"](diagnostic, site) + diagnostic["source_range"]["end_col"] += 1 + assert not types["same_site"](diagnostic, site) + assert not types["same_site"]({"message": "This EMA may need more earlier bars to initialize."}, site) + input_site = next(site for site in sites if site["length"]["kind"] == "input") + assert input_site["length"]["input_name"] and input_site["length"]["expression"] + assert input_site["length"]["value"] is None + assert {row["scope"] for row in fixture["effective_inputs"]} == {"run", "trial", "study"} + for row in fixture["effective_inputs"]: + assert set(row) == types["ResolvedLength"].__required_keys__ + assert types["same_site"](row, input_site) + assert row["searched_range"] if row["scope"] == "study" else row["submitted_value"] + + +def _glue(): + namespace = {} + path = Path(__file__).resolve().parents[1] / "gate" / "glue.py" + exec(compile(path.read_text(), str(path), "exec"), namespace) + return namespace["transpile_json"] + + +def test_note_enum_and_catalog_short_sentences(): + assert "NOTE" in Level.__members__, "missing NOTE severity" + assert Level.NOTE.value == "note" + catalog = diagnostics_catalog()["codes"] + assert catalog + for code, entry in catalog.items(): + assert entry.get("user_message"), f"missing user_message: {code}" + + +@pytest.mark.parametrize("case", CASES, ids=lambda case: case["name"]) +def test_real_interfaces_keep_notes_and_short_sentences(case): + source = case["source"] + failure = None + try: + diagnostics = transpile_full(source)["diagnostics"] + ok = True + except CompileError as exc: + diagnostics, ok = exc.diagnostics, False + failure = exc + envelope = json.loads(_glue()(source)) + assert ok == envelope["ok"] == case["ok"] + assert len(diagnostics) == len(envelope["diagnostics"]) + for code, control in case["controls"].items(): + selected = [d for d in diagnostics if d.code == code] + assert selected, f"real product control did not emit {code}" + assert all(d.level.value == control["after"] for d in selected) + if not ok: + assert any(d.level == Level.ERROR for d in diagnostics) + for diagnostic, entry in zip(diagnostics, envelope["diagnostics"]): + assert entry["code"] == diagnostic.code + assert entry["severity"] == diagnostic.level.value + assert entry["args"] == diagnostic.args + assert entry["user_message"] == diagnostic.user_message + assert entry["user_message"] == diagnostics_catalog()["codes"][diagnostic.code]["user_message"] + assert entry["message"] == (diagnostic.message + " — " + diagnostic.hint + if diagnostic.hint else diagnostic.message) + baseline = PRODUCT_BEFORE["interfaces"][case["name"]] + normalized = copy.deepcopy(envelope) + python_rows = [] + for d, row in zip(diagnostics, normalized["diagnostics"]): + row.pop("user_message") + level = "warning" if d.code in NOTE_CODES else d.level.value + row["severity"] = level + python_rows.append({"severity": level, "phase": d.phase.value, + "location": asdict(d.location) if d.location else None, + "message": d.message, "hint": d.hint, "code": d.code, "args": d.args}) + assert python_rows == baseline["python"] + assert json.dumps(normalized) == PRODUCT_BEFORE["wire"][case["name"]] + if failure: + text = PRODUCT_BEFORE["text"][case["name"]] + assert str(failure) == text["error"] + legacy_levels = [replace(d, level=Level.WARNING) if d.code in NOTE_CODES else d for d in diagnostics] + assert CompileError(legacy_levels).format(source) == text["format"] + if any(d.level == Level.NOTE for d in diagnostics): + assert "note[ANALYZER]:" in failure.format(source) + + +# -- Warning twins: the sentence says what the warning does --------------------------- +# +# A problem the support checker finds in a switch arm is accepted with a warning +# (``SupportChecker._err``): PF-W1nnn is PF-E1nnn's template as a warning, and the +# generator creates a twin as a copy of the error's entry. Authoring both with one +# sentence is the easy mistake -- the first authoring copied each error's sentence +# into its twin, and it said PineForge refused a call in a script that had just +# transpiled. Each twin needs a sentence of its own. + +REFUSAL = re.compile(r"\b(?:refus|reject)\w*", re.IGNORECASE) +TRADINGVIEW_REFUSAL = re.compile(r"\bTradingView (?:refus|reject)\w*", re.IGNORECASE) + + +def _asserts_refusal(template): + """Whether a sentence says something is refused. What TradingView refuses is a + fact about TradingView (``a call TradingView rejects``) and may stay.""" + return bool(REFUSAL.search(TRADINGVIEW_REFUSAL.sub("", template))) + + +def _assert_twin_sentence(catalog, twin_code): + error_code = "PF-E" + twin_code[4:] + twin, error = catalog[twin_code], catalog[error_code] + sentence = twin["user_message"] + assert twin["severity"] == "warning", twin_code + assert sentence != error["user_message"], f"{twin_code} copies the sentence of {error_code}" + assert not _asserts_refusal(sentence), (twin_code, sentence) + assert re.search(r"\bwarns?\b", sentence), (twin_code, sentence) + if "inside a switch arm" in twin["explanation"]: + # The catalog's own meaning of the twin: it warns and the arm keeps its lowering. + assert "switch arm" in sentence and "lowering" in sentence, (twin_code, sentence) + else: + # A warning everywhere (bar_index, last_bar_index, timenow): no arm to name. + assert "switch arm" not in sentence, (twin_code, sentence) + + +def test_every_switch_arm_twin_is_covered(): + catalog = diagnostics_catalog()["codes"] + assert len(TWINS) >= 97 and len(set(TWINS)) == len(TWINS) + assert all(code in catalog for code in TWINS) + + +@pytest.mark.parametrize("twin_code", TWINS) +def test_switch_arm_twin_sentence_is_its_own_and_is_not_a_refusal(twin_code): + _assert_twin_sentence(diagnostics_catalog()["codes"], twin_code) + + +def test_no_nonfatal_sentence_claims_a_refusal(): + """A warning or a note means the script transpiled.""" + for code, entry in diagnostics_catalog()["codes"].items(): + if entry["severity"] != "error": + assert not _asserts_refusal(entry["user_message"]), (code, entry["user_message"]) + + +@pytest.mark.parametrize("sentence, refuses", [ + ("PineForge cannot load external seed data feeds, so request.seed is refused.", True), + ("PineForge has no implementation of this ta.* function, so the call is refused instead " + "of compiling to a silent stub.", True), + ("A call whose arguments match none of TradingView''s signatures is refused, " + "as TradingView refuses it.", True), + ("The timeframe string of request.security is not a valid Pine timeframe, " + "so PineForge rejects it.", True), + ("TradingView rejects a method call written straight after a history index, x[k].method().", False), + ("The missing str.repeat count produces an empty string for a call TradingView rejects.", False), + ("PineForge cannot load external seed data feeds, so request.seed cannot return any. " + "In a switch arm PineForge only warns and keeps the arm''s lowering.", False), +]) +def test_refusal_wording_detector(sentence, refuses): + assert _asserts_refusal(sentence) is refuses + + +@pytest.mark.parametrize("twin_code", ["PF-W1003", "PF-W1013", "PF-W1027", "PF-W1090", "PF-W1096"]) +def test_twin_check_rejects_the_sentence_copied_from_the_error(twin_code): + catalog = diagnostics_catalog()["codes"] + catalog[twin_code]["user_message"] = catalog["PF-E" + twin_code[4:]]["user_message"] + with pytest.raises(AssertionError): + _assert_twin_sentence(catalog, twin_code) + + +@pytest.mark.parametrize("twin_code, sentence", [ + # refusal wording behind a correct switch-arm clause + ("PF-W1027", "request.seed is refused. In a switch arm PineForge only warns and keeps the arm''s lowering."), + # neither a warning nor a switch-arm clause + ("PF-W1027", "PineForge cannot load external seed data feeds, so request.seed cannot return any."), + # a switch-arm clause that does not say it only warns + ("PF-W1027", "PineForge has no seed data. In a switch arm PineForge keeps the arm''s lowering."), + # a switch-arm clause on a warning that is not about a switch arm + ("PF-W1067", "PineForge warns that bar_index differs. In a switch arm PineForge only warns " + "and keeps the arm''s lowering."), +]) +def test_twin_check_rejects_other_false_sentences(twin_code, sentence): + catalog = diagnostics_catalog()["codes"] + catalog[twin_code]["user_message"] = sentence + with pytest.raises(AssertionError): + _assert_twin_sentence(catalog, twin_code) + + +HEAD = '//@version=6\nstrategy("T", overlay = true)\n' +TAIL = 'if x > 0\n strategy.entry("L", strategy.long)\n' +# The accepted-arm shapes tests/test_tail_f_rules.py pins at the Python interface. +ARM_SEED = (HEAD + 'k = bar_index % 2\nx = switch k\n' + ' 0 => request.seed("seed_crypto_santiment", "BTC", close)\n' + ' => 1.0\n' + TAIL) +ARM_TEXT_CONSTANT = (HEAD + 'm = close > open ? "L" : "R"\nta_ = switch m\n' + ' "L" => text.align_left\n "R" => text.align_right\n' + 'if barstate.islast\n label.new(bar_index, close, "x", textalign = ta_)\n' + 'x = 1\n' + TAIL) +OUTSIDE_ARM_SEED = HEAD + 'x = request.seed("seed_crypto_santiment", "BTC", close)\n' + TAIL +ARM_CASES = { + "request.seed": (ARM_SEED, "PF-W1027", "request.seed"), + "text constant": (ARM_TEXT_CONSTANT, "PF-W1078", "text.align_left"), +} + + +@pytest.mark.parametrize("name", sorted(ARM_CASES)) +def test_an_accepted_switch_arm_warns_with_a_sentence_that_says_so(name): + source, code, needle = ARM_CASES[name] + catalog = diagnostics_catalog()["codes"] + out = transpile_full(source) # a refusal would raise CompileError + assert out["cpp"] + found = [d for d in out["diagnostics"] if d.code == code] + assert found and any(needle in d.message for d in found), \ + [(d.code, d.message) for d in out["diagnostics"]] + sentence = catalog[code]["user_message"] + assert "switch arm" in sentence and re.search(r"\bwarns?\b", sentence) + assert not _asserts_refusal(sentence) + for d in found: + assert d.level == Level.WARNING + assert d.user_message == sentence + envelope = json.loads(_glue()(source)) + assert envelope["ok"] is True + wire = [e for e in envelope["diagnostics"] if e["code"] == code] + assert len(wire) == len(found) + assert all(e["severity"] == "warning" and e["user_message"] == sentence for e in wire) + # Nothing an accepted script carries says that something was refused. + assert not [e["code"] for e in envelope["diagnostics"] if _asserts_refusal(e["user_message"])] + + +def test_the_same_call_outside_a_switch_arm_keeps_the_error_sentence(): + catalog = diagnostics_catalog()["codes"] + with pytest.raises(CompileError) as refused: + transpile_full(OUTSIDE_ARM_SEED) + errors = [d for d in refused.value.diagnostics if d.code == "PF-E1027"] + assert errors, [(d.code, d.message) for d in refused.value.diagnostics] + assert all(d.level == Level.ERROR for d in errors) + assert errors[0].user_message == catalog["PF-E1027"]["user_message"] + assert errors[0].user_message != catalog["PF-W1027"]["user_message"] + envelope = json.loads(_glue()(OUTSIDE_ARM_SEED)) + assert envelope["ok"] is False + assert any(e["code"] == "PF-E1027" and e["severity"] == "error" for e in envelope["diagnostics"]) + + +ARRAY_HISTORY_IN_REQUEST = ( + '//@version=6\nstrategy("shape", overlay = true, max_lines_count = 500)\n' + "a = array.from(close)\n" + 'r = request.security(syminfo.tickerid, "60", (a[1]).size())\n' + "if r > 0\n" + ' strategy.entry("L", strategy.long)\n') + + +def test_array_history_in_a_request_is_described_as_array_history_not_references(): + """PF-E6062 is the array and matrix history scope check (collection_history.py, + tests/test_array_history.py ``request_security_size``); the history of a + user-defined type or drawing reference in a request is PF-E3043's.""" + catalog = diagnostics_catalog()["codes"] + with pytest.raises(CompileError) as refused: + transpile_full(ARRAY_HISTORY_IN_REQUEST) + found = [d for d in refused.value.diagnostics if d.code == "PF-E6062"] + assert found, [(d.code, d.message) for d in refused.value.diagnostics] + assert all("inside a request.security expression" in d.message for d in found) + sentence = catalog["PF-E6062"]["user_message"] + assert all(d.level == Level.ERROR and d.user_message == sentence for d in found) + assert "array" in sentence and "matrix" in sentence and "request.security" in sentence + assert "user-defined" not in sentence and "drawing" not in sentence + assert sentence != catalog["PF-E3043"]["user_message"] + envelope = json.loads(_glue()(ARRAY_HISTORY_IN_REQUEST)) + assert envelope["ok"] is False + assert {e["user_message"] for e in envelope["diagnostics"] if e["code"] == "PF-E6062"} == {sentence} + + +# -- A call PineForge skips: the sentence names the call and says it does nothing ----- +# +# PF-W1508 (a bare call) and PF-W1509 (the same template, spelled for a namespaced one) +# first said "{name} is not drawn in backtests.". The support checker emits the note for +# alert() and alertcondition() as well as plot() and table.new(), and an alert draws +# nothing on a chart, so the sentence described a drawing that never existed. +# "{name}() does nothing in a backtest." holds for every call the note covers. `name` is +# the call's bare or dotted name and never carries parentheses (the checker spells +# "{name}(...)" itself, SupportChecker._visit_FuncCall), so the template's "()" is the +# only pair a rendered sentence has. + +NO_EFFECT_TEMPLATES = {"PF-W1508": "{name}() does nothing in a backtest.", + "PF-W1509": "{full}() does nothing in a backtest."} +# (script, the name its note carries): the two calls the old sentence was wrong for, and +# plot and table.new, which the note always covered. +NO_EFFECT_CASES = [ + pytest.param(HEAD + 'alert("go", alert.freq_once_per_bar)\n', "alert", id="alert"), + pytest.param(HEAD + 'alertcondition(close > open, "up", "close is above open")\n', + "alertcondition", id="alertcondition"), + pytest.param(HEAD + "plot(close)\n", "plot", id="plot"), + pytest.param(HEAD + "t = table.new(position.top_right, 1, 1)\n", "table.new", id="table_new"), +] + + +@pytest.mark.parametrize("source, name", NO_EFFECT_CASES) +def test_a_skipped_call_note_names_the_call_and_says_it_does_nothing(source, name): + template = NO_EFFECT_TEMPLATES["PF-W1508"] + sentence = f"{name}() does nothing in a backtest." + out = transpile_full(source) + notes = [d for d in out["diagnostics"] if d.code == "PF-W1508"] + assert len(notes) == 1, [(d.code, d.message) for d in out["diagnostics"]] + note = notes[0] + # Identity, level, arguments and the English text are what they were. + assert note.level == Level.NOTE + assert note.args == {"name": name} + assert note.message == f"{name}(...) has no effect in PineForge backtests (visual only)." + assert note.hint is None + # user_message is the raw catalog template; a receiver renders it with args as text. + assert note.user_message == template + assert render(note.user_message, note.args) == sentence + envelope = json.loads(_glue()(source)) + assert envelope["ok"] is True + wire = [e for e in envelope["diagnostics"] if e["code"] == "PF-W1508"] + assert len(wire) == 1 + assert wire[0]["severity"] == "note" + assert wire[0]["args"] == {"name": name} + assert wire[0]["message"] == note.message + assert wire[0]["user_message"] == template + assert render(wire[0]["user_message"], wire[0]["args"]) == sentence + + +def test_the_alias_template_is_the_same_sentence_over_its_own_argument(): + """PF-W1509 is never classified (the text classifier picks PF-W1508 where the two + templates tie), but it is a catalog entry a receiver can be handed.""" + catalog = diagnostics_catalog()["codes"] + for code, argument in (("PF-W1508", "name"), ("PF-W1509", "full")): + entry = catalog[code] + assert entry["severity"] == "note" and list(entry["args"]) == [argument], code + assert entry["user_message"] == NO_EFFECT_TEMPLATES[code], code + assert "drawn" not in entry["user_message"], code + assert render(entry["user_message"], {argument: "table.new"}) == \ + "table.new() does nothing in a backtest." + assert (catalog["PF-W1509"]["user_message"].replace("{full}", "{name}") + == catalog["PF-W1508"]["user_message"]) diff --git a/tests/test_external_requests.py b/tests/test_external_requests.py index 08e8507..cbd3c9a 100644 --- a/tests/test_external_requests.py +++ b/tests/test_external_requests.py @@ -108,7 +108,7 @@ def test_payload_with_side_effects_is_not_inert(): assert "runtime.error" in TradeSlice(program).reason(request) -def test_inert_requests_are_lowered_with_a_warning(): +def test_inert_requests_are_lowered_with_a_note(): result = transpile_full( HEAD + WATCH + 'plot(other)\nplot(shares)\n' + TRADE) warnings = [d.message for d in result["diagnostics"]] diff --git a/tests/test_kc_middle_band.py b/tests/test_kc_middle_band.py index 2320665..b9c332a 100644 --- a/tests/test_kc_middle_band.py +++ b/tests/test_kc_middle_band.py @@ -11,6 +11,7 @@ from __future__ import annotations from pineforge_codegen import transpile, transpile_full +from pineforge_codegen.errors import Level from tests._compile import run_emitted_tu @@ -56,7 +57,8 @@ def test_kc_middle_warms_without_changing_standalone_ema() -> None: assert warm_m == warm_e -def test_standalone_ema_warmup_gap_warns() -> None: +def test_standalone_ema_warmup_gap_is_a_note() -> None: diagnostics = transpile_full(_PINE)["diagnostics"] - assert any("ta.ema initial warmup is approximated" in d.message + assert any(d.code == "PF-W1505" and d.level == Level.NOTE + and "ta.ema initial warmup is approximated" in d.message for d in diagnostics) diff --git a/tests/test_support_checker.py b/tests/test_support_checker.py index 8125153..63d3921 100644 --- a/tests/test_support_checker.py +++ b/tests/test_support_checker.py @@ -726,10 +726,14 @@ def test_ta_stoch_tuple_assignment_rejected(): # Visual-skip warnings (not errors) # --------------------------------------------------------------------------- -def test_plot_emits_warning_not_error(): +def test_plot_emits_note_not_warning_or_error(): src = PRELUDE + "plot(close)\n" assert _errors(src) == [] - assert any("visual only" in d.message for d in _warnings(src)) + assert _warnings(src) == [] + diagnostics = _check(src) + assert [d.code for d in diagnostics] == ["PF-W1508"] + assert all(d.level == Level.NOTE for d in diagnostics) + assert "visual only" in diagnostics[0].message def test_label_geometry_accepted_visual_setter_warns():