openpinescript 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +332 -2
  3. package/dist/cli.mjs +108691 -0
  4. package/dist/index.cjs +108670 -0
  5. package/dist/index.mjs +108624 -0
  6. package/dist/types/index.d.ts +31 -0
  7. package/dist/types/parser/v1/generated/PineV1Lexer.d.ts +66 -0
  8. package/dist/types/parser/v1/generated/PineV1Parser.d.ts +555 -0
  9. package/dist/types/parser/v1/generated/PineV1ParserVisitor.d.ts +318 -0
  10. package/dist/types/parser/v1/index.d.ts +39 -0
  11. package/dist/types/parser/v2/generated/PineV2Lexer.d.ts +67 -0
  12. package/dist/types/parser/v2/generated/PineV2Parser.d.ts +568 -0
  13. package/dist/types/parser/v2/generated/PineV2ParserVisitor.d.ts +325 -0
  14. package/dist/types/parser/v2/index.d.ts +2 -0
  15. package/dist/types/parser/v3/generated/PineV3Lexer.d.ts +67 -0
  16. package/dist/types/parser/v3/generated/PineV3Parser.d.ts +568 -0
  17. package/dist/types/parser/v3/generated/PineV3ParserVisitor.d.ts +325 -0
  18. package/dist/types/parser/v3/index.d.ts +2 -0
  19. package/dist/types/parser/v4/generated/PineV4Lexer.d.ts +86 -0
  20. package/dist/types/parser/v4/generated/PineV4Parser.d.ts +673 -0
  21. package/dist/types/parser/v4/generated/PineV4ParserVisitor.d.ts +367 -0
  22. package/dist/types/parser/v4/index.d.ts +2 -0
  23. package/dist/types/parser/v5/generated/PineV5Lexer.d.ts +95 -0
  24. package/dist/types/parser/v5/generated/PineV5Parser.d.ts +964 -0
  25. package/dist/types/parser/v5/generated/PineV5ParserVisitor.d.ts +521 -0
  26. package/dist/types/parser/v5/index.d.ts +2 -0
  27. package/dist/types/parser/v6/generated/PineV6Lexer.d.ts +98 -0
  28. package/dist/types/parser/v6/generated/PineV6Parser.d.ts +984 -0
  29. package/dist/types/parser/v6/generated/PineV6ParserVisitor.d.ts +528 -0
  30. package/dist/types/parser/v6/index.d.ts +2 -0
  31. package/dist/types/runtime/v1/Series.d.ts +61 -0
  32. package/dist/types/runtime/v1/broker/Broker.d.ts +325 -0
  33. package/dist/types/runtime/v1/broker/index.d.ts +158 -0
  34. package/dist/types/runtime/v1/broker/val.d.ts +28 -0
  35. package/dist/types/runtime/v1/constDefault.d.ts +11 -0
  36. package/dist/types/runtime/v1/context.d.ts +1705 -0
  37. package/dist/types/runtime/v1/footprint.d.ts +32 -0
  38. package/dist/types/runtime/v1/index.d.ts +7 -0
  39. package/dist/types/runtime/v1/language-spec.d.ts +12 -0
  40. package/dist/types/runtime/v1/openTrades.d.ts +12 -0
  41. package/dist/types/runtime/v1/palette.d.ts +18 -0
  42. package/dist/types/runtime/v1/session.d.ts +482 -0
  43. package/dist/types/runtime/v1/sessions.d.ts +31 -0
  44. package/dist/types/runtime/v1/stateClone.d.ts +19 -0
  45. package/dist/types/runtime/v1/stdlib/alerts.d.ts +31 -0
  46. package/dist/types/runtime/v1/stdlib/arrays.d.ts +133 -0
  47. package/dist/types/runtime/v1/stdlib/barmerge.d.ts +27 -0
  48. package/dist/types/runtime/v1/stdlib/barstate.d.ts +79 -0
  49. package/dist/types/runtime/v1/stdlib/cast.d.ts +81 -0
  50. package/dist/types/runtime/v1/stdlib/chart.d.ts +283 -0
  51. package/dist/types/runtime/v1/stdlib/color.d.ts +51 -0
  52. package/dist/types/runtime/v1/stdlib/core.d.ts +162 -0
  53. package/dist/types/runtime/v1/stdlib/dataset.d.ts +36 -0
  54. package/dist/types/runtime/v1/stdlib/display.d.ts +50 -0
  55. package/dist/types/runtime/v1/stdlib/drawings.d.ts +407 -0
  56. package/dist/types/runtime/v1/stdlib/errors.d.ts +21 -0
  57. package/dist/types/runtime/v1/stdlib/font.d.ts +20 -0
  58. package/dist/types/runtime/v1/stdlib/footprint.d.ts +76 -0
  59. package/dist/types/runtime/v1/stdlib/format.d.ts +57 -0
  60. package/dist/types/runtime/v1/stdlib/index.d.ts +71 -0
  61. package/dist/types/runtime/v1/stdlib/input.d.ts +14 -0
  62. package/dist/types/runtime/v1/stdlib/inputs.d.ts +60 -0
  63. package/dist/types/runtime/v1/stdlib/late_members.d.ts +97 -0
  64. package/dist/types/runtime/v1/stdlib/logging.d.ts +31 -0
  65. package/dist/types/runtime/v1/stdlib/maps.d.ts +55 -0
  66. package/dist/types/runtime/v1/stdlib/math.d.ts +71 -0
  67. package/dist/types/runtime/v1/stdlib/matrix.d.ts +201 -0
  68. package/dist/types/runtime/v1/stdlib/metadata.d.ts +14 -0
  69. package/dist/types/runtime/v1/stdlib/mtf.d.ts +15 -0
  70. package/dist/types/runtime/v1/stdlib/renames.d.ts +117 -0
  71. package/dist/types/runtime/v1/stdlib/renames5.d.ts +113 -0
  72. package/dist/types/runtime/v1/stdlib/renames6.d.ts +81 -0
  73. package/dist/types/runtime/v1/stdlib/request.d.ts +207 -0
  74. package/dist/types/runtime/v1/stdlib/scale.d.ts +19 -0
  75. package/dist/types/runtime/v1/stdlib/session.d.ts +113 -0
  76. package/dist/types/runtime/v1/stdlib/sort_field.d.ts +12 -0
  77. package/dist/types/runtime/v1/stdlib/sources.d.ts +24 -0
  78. package/dist/types/runtime/v1/stdlib/str.d.ts +117 -0
  79. package/dist/types/runtime/v1/stdlib/strategy.d.ts +314 -0
  80. package/dist/types/runtime/v1/stdlib/syminfo.d.ts +209 -0
  81. package/dist/types/runtime/v1/stdlib/ta.d.ts +409 -0
  82. package/dist/types/runtime/v1/stdlib/time.d.ts +158 -0
  83. package/dist/types/runtime/v1/stdlib/trades.d.ts +108 -0
  84. package/dist/types/runtime/v1/stdlib/ui.d.ts +196 -0
  85. package/dist/types/runtime/v1/stdlib/v6_members.d.ts +68 -0
  86. package/dist/types/runtime/v1/timeframes.d.ts +139 -0
  87. package/dist/types/runtime/v1/zones.d.ts +30 -0
  88. package/dist/types/transpiler/common/index.d.ts +51 -0
  89. package/dist/types/transpiler/common/libraries.d.ts +29 -0
  90. package/dist/types/transpiler/common/parseErrors.d.ts +38 -0
  91. package/dist/types/transpiler/common/passes/ScopeAnalysis.d.ts +158 -0
  92. package/dist/types/transpiler/common/passes/TypeRules.d.ts +26 -0
  93. package/dist/types/transpiler/common/profiles/index.d.ts +96 -0
  94. package/dist/types/transpiler/common/version.d.ts +40 -0
  95. package/dist/types/transpiler/v1/ToJsVisitor.d.ts +720 -0
  96. package/dist/types/transpiler/v2/ToJsVisitor.d.ts +72 -0
  97. package/dist/types/transpiler/v3/ToJsVisitor.d.ts +87 -0
  98. package/dist/types/transpiler/v4/ToJsVisitor.d.ts +263 -0
  99. package/dist/types/transpiler/v5/ToJsVisitor.d.ts +1101 -0
  100. package/dist/types/transpiler/v6/ToJsVisitor.d.ts +237 -0
  101. package/dist/types/transpiler/v6/rules.d.ts +94 -0
  102. package/dist/types/utils/v2/common.d.ts +4 -0
  103. package/package.json +92 -4
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Non-price data requests — `request.financial`, `.dividends`, `.splits`,
3
+ * `.earnings`, `.quandl`. v5.
4
+ *
5
+ * `request.security` is NOT here: it is v5's spelling of `security()`, aliased
6
+ * to the same implementation in ./renames5.ts, because the two are one function
7
+ * under two names.
8
+ *
9
+ * ── Where the data comes from ───────────────────────────────────────────────
10
+ *
11
+ * Nowhere this engine can reach. Every function below asks TradingView for a
12
+ * series it does not compute — a company's quarterly revenue, a dividend
13
+ * record, a Nasdaq Data Link table — and there is no such source here.
14
+ *
15
+ * So the HOST supplies it, exactly as it supplies higher-timeframe candles for
16
+ * `security()`: `Context.provideRequestData(kind, key, samples)`. An
17
+ * unsupplied request is REFUSED rather than answered with `na`.
18
+ *
19
+ * That refusal is the whole point of this file. These names were absent
20
+ * before, and `request` is a namespace that DOES exist (it has `security` in
21
+ * it), so `request.financial(…)` read as `undefined` and the script ran to
22
+ * completion with a silently empty series. The emitter's namespace check
23
+ * deliberately does not assert registry completeness — failing an incomplete
24
+ * stdlib as a user error would be worse — so nothing else could catch it.
25
+ *
26
+ * ── Why the values are sparse ───────────────────────────────────────────────
27
+ *
28
+ * None of these is a per-bar series. A dividend happens on one day and the
29
+ * value stands until the next one; a quarterly figure is published once and
30
+ * stands for the quarter. So a request is stored as timestamped SAMPLES and
31
+ * read as a step function: the most recent sample at or before the current bar,
32
+ * and `na` before the first one.
33
+ */
34
+ import { Context } from "../context.js";
35
+ /**
36
+ * The key a request is stored under.
37
+ *
38
+ * Built from every argument that selects a different SERIES, so two requests
39
+ * that differ in any of them cannot read each other's data.
40
+ */
41
+ export declare function requestKey(parts: readonly any[]): string;
42
+ /**
43
+ * `request.financial(symbol, financial_id, period, gaps)`.
44
+ * @returns {series float} The reported figure, held until the next report.
45
+ */
46
+ export declare const request: {
47
+ financial: (ctx: Context, symbol: any, financial_id: any, period: any, gaps?: any, ignore_invalid_symbol?: any, currency?: any) => number;
48
+ /** `request.dividends(ticker, field, …)` — field defaults to gross dividends. */
49
+ dividends: (ctx: Context, ticker: any, field?: any, ..._rest: any[]) => number;
50
+ splits: (ctx: Context, ticker: any, field?: any, ..._rest: any[]) => number;
51
+ earnings: (ctx: Context, ticker: any, field?: any, ..._rest: any[]) => number;
52
+ /**
53
+ * `request.security_lower_tf(symbol, timeframe, expression,
54
+ * ignore_invalid_symbol, currency, ignore_invalid_timeframe,
55
+ * calc_bars_count)` — Sept 2023.
56
+ *
57
+ * Evaluates `expression` on EVERY intrabar of the chart bar and returns them
58
+ * all, as an array — or, when the expression is a tuple, as a tuple of arrays.
59
+ * That is what makes it different from `request.security`, which returns one
60
+ * value: a chart bar contains many lower-timeframe bars, and this hands back
61
+ * all of them so a script can sum, count or measure within the bar.
62
+ *
63
+ * The intrabars of a chart bar are the lower-timeframe bars that open
64
+ * inside it, from its open to its close. The expression is evaluated on
65
+ * every lower-timeframe bar in order, in one sub-context per call site, so
66
+ * a `ta.*` call inside it warms up on the lower timeframe's own history.
67
+ *
68
+ * ── With no intrabar data, the answer is EMPTY, not approximate ─────────────
69
+ *
70
+ * This engine is fed one series of OHLCV bars. It has no finer data and cannot
71
+ * fetch any, so unless a host supplies the lower timeframe there are no
72
+ * intrabars to report — and an empty array says exactly that. The alternative,
73
+ * returning the chart bar as its own single intrabar, would make
74
+ * `array.size(...)` report 1 where TradingView reports 12, and every average
75
+ * computed from it would be quietly wrong rather than visibly absent.
76
+ *
77
+ * `security` answers `na` in the same situation for the same reason, and asks
78
+ * the session layer for the data the same way.
79
+ *
80
+ * ── The three arguments ─────────────────────────────────────────────────────
81
+ *
82
+ * ignore_invalid_timeframe: "Determines the behavior of the function when
83
+ * the chart's timeframe is smaller than the timeframe used in the function
84
+ * call. If false, the script will halt and throw a runtime error. If true,
85
+ * the function will return na and execution will continue."
86
+ *
87
+ * ignore_invalid_symbol: "If false, the script will halt and throw a runtime
88
+ * error [when the symbol is not found]. If true, the function will return
89
+ * na and execution will continue." This engine cannot tell a symbol that
90
+ * does not exist from data the host has not supplied, and the second is
91
+ * not an error: the request is recorded for the host and the answer is the
92
+ * empty one above, whichever way the argument is set. It is accepted so it
93
+ * is not reported as dropped.
94
+ *
95
+ * calc_bars_count: accepted, with no observable effect: TradingView's log
96
+ * (conformance/v5/parity/harness_security_cbc) shows a call with
97
+ * calc_bars_count = 200 equal to the call without it on every bar.
98
+ */
99
+ security_lower_tf: (ctx: Context, symbol: any, timeframe: any, expression: () => any, ignore_invalid_symbol?: any, currency?: any, ignore_invalid_timeframe?: any, calc_bars_count?: any) => any;
100
+ /**
101
+ * `request.quandl(ticker, gaps, index)` — Nasdaq Data Link.
102
+ *
103
+ * TradingView removed this in 2023 and it remains in the v5 reference as
104
+ * deprecated. Kept so a published script still compiles, and refused at run
105
+ * time like the rest unless the host supplies the table.
106
+ */
107
+ quandl: (ctx: Context, ticker: any, _gaps: any, index?: any) => number;
108
+ /**
109
+ * `request.currency_rate(from, to)` — the daily conversion rate.
110
+ *
111
+ * "Provides a daily rate that can be used to convert a value expressed in
112
+ * the `from` currency to another in the `to` currency."
113
+ *
114
+ * Identical currencies convert at 1 without needing any data, which is not
115
+ * a special case so much as the definition — and it is the common one, since
116
+ * `request.currency_rate(syminfo.currency, strategy.account_currency)` is
117
+ * how a strategy asks whether conversion is needed at all.
118
+ *
119
+ * Anything else is host-supplied like the rest of this namespace: an
120
+ * exchange rate is a fact about the world on a date, and guessing one would
121
+ * misstate every position size computed from it.
122
+ */
123
+ currency_rate: (ctx: Context, from: any, to: any) => number;
124
+ /**
125
+ * `request.economic(country_code, field, gaps)` — a macroeconomic series.
126
+ *
127
+ * "GDPQQ", "UNRATE", "CPIYY" and the rest, keyed by country. Host-supplied
128
+ * like every other member of this namespace: there is no data here to fetch
129
+ * it from, and inventing a plausible unemployment rate would be worse than
130
+ * refusing to.
131
+ */
132
+ economic: (ctx: Context, country_code: any, field: any, _gaps?: any) => number;
133
+ /**
134
+ * `request.seed(source, symbol, expression, …)` — September 2023.
135
+ *
136
+ * "Requests data from a user-maintained GitHub repository and returns it as
137
+ * a series."
138
+ *
139
+ * The repository is `source` and the file is `symbol`. Nothing about it is
140
+ * reachable from here, so it resolves through the same host-supplied table
141
+ * as the rest — which is the honest shape for a function whose entire job
142
+ * is to fetch something this engine cannot reach.
143
+ */
144
+ seed: (ctx: Context, source: any, symbol: any, _expression?: any, ..._rest: any[]) => number;
145
+ };
146
+ /** Which dividend figure `request.dividends` returns. */
147
+ export declare const dividends: {
148
+ gross: string;
149
+ net: string;
150
+ /**
151
+ * The NEXT dividend: "na if the data is not available". This engine has
152
+ * no corporate calendar, so it always is.
153
+ * @getter
154
+ */
155
+ future_amount: (_ctx: Context) => number;
156
+ /** @getter */
157
+ future_ex_date: (_ctx: Context) => number;
158
+ /** @getter */
159
+ future_pay_date: (_ctx: Context) => number;
160
+ };
161
+ /** Which half of the split ratio `request.splits` returns. */
162
+ export declare const splits: {
163
+ numerator: string;
164
+ denominator: string;
165
+ };
166
+ /** Which earnings figure `request.earnings` returns. */
167
+ export declare const earnings: {
168
+ actual: string;
169
+ estimate: string;
170
+ standardized: string;
171
+ /** The NEXT report, `na` without a corporate calendar. @getter */
172
+ future_time: (_ctx: Context) => number;
173
+ /** @getter */
174
+ future_eps: (_ctx: Context) => number;
175
+ /** @getter */
176
+ future_revenue: (_ctx: Context) => number;
177
+ /** @getter */
178
+ future_period_end_time: (_ctx: Context) => number;
179
+ };
180
+ /**
181
+ * Whether a futures ticker id's history is back-adjusted, and whether its
182
+ * daily close is the settlement price — `ticker.new` / `ticker.modify`
183
+ * arguments (v5, 2024). Carried like `adjustment`: one price series runs here.
184
+ */
185
+ export declare const backadjustment: {
186
+ inherit: string;
187
+ on: string;
188
+ off: string;
189
+ };
190
+ export declare const settlement_as_close: {
191
+ inherit: string;
192
+ on: string;
193
+ off: string;
194
+ };
195
+ /**
196
+ * Which corporate actions a ticker id's prices are adjusted for.
197
+ *
198
+ * Passed to `ticker.new` / `ticker.modify`. This engine runs one price series —
199
+ * the bars it was handed — so the adjustment cannot change any number here; it
200
+ * is carried so that a script naming it compiles and runs, and so a host that
201
+ * does keep adjusted and unadjusted feeds can read it off the ticker id.
202
+ */
203
+ export declare const adjustment: {
204
+ none: string;
205
+ splits: string;
206
+ dividends: string;
207
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * scale.* — which price scale a study/strategy is drawn against.
3
+ *
4
+ * Passed to the `scale` argument of study()/strategy():
5
+ *
6
+ * strategy("Pre Meditated", scale=scale.right, overlay=true)
7
+ *
8
+ * Purely declarative: it affects chart presentation, not any computed series.
9
+ * The values are carried through to the script's declared metadata so a host
10
+ * renderer can honour them; the engine itself only needs them to EXIST, because
11
+ * a missing constant is a hard "opsv2_scale is not defined" at runtime.
12
+ */
13
+ export declare const __IS_NAMESPACE__ = true;
14
+ /** Draw against the right-hand price scale (the default for overlays). */
15
+ export declare const right = "scale.right";
16
+ /** Draw against the left-hand price scale. */
17
+ export declare const left = "scale.left";
18
+ /** Do not attach to a price scale — the script provides its own range. */
19
+ export declare const none = "scale.none";
@@ -0,0 +1,113 @@
1
+ /**
2
+ * `session.*` — which trading session a bar belongs to, and where in it.
3
+ *
4
+ * Two constants and six per-bar booleans, quoted from the manual's Sessions
5
+ * page:
6
+ *
7
+ * session.regular "Represents the regular trading session."
8
+ * session.extended "Represents the extended trading session."
9
+ *
10
+ * session.ismarket "Is true when the bar belongs to regular trading
11
+ * hours. On '1D' and above timeframes, this variable
12
+ * is always true."
13
+ * session.ispremarket "Is true when the bar belongs to the extended
14
+ * session preceding regular trading hours."
15
+ * session.ispostmarket "Is true when the bar belongs to the extended
16
+ * session following regular trading hours."
17
+ * session.isfirstbar "Is true if the current bar is the first bar of the
18
+ * day's session, and false otherwise."
19
+ * session.islastbar "Is true if the current bar is the last bar of the
20
+ * day's session, and false otherwise."
21
+ * session.isfirstbar_regular "Is true on the first regular session bar of
22
+ * the day, false otherwise."
23
+ * session.islastbar_regular "Is true on the last regular session bar of the
24
+ * day, false otherwise."
25
+ *
26
+ * ── What this engine can and cannot know ────────────────────────────────────
27
+ *
28
+ * A session is a property of the EXCHANGE, and this engine is handed bars and
29
+ * nothing else — no symbol metadata, no session hours, no holiday calendar. So
30
+ * the extended-hours questions cannot be answered from the data, and the answer
31
+ * given is the one that matches the data actually supplied:
32
+ *
33
+ * ismarket always true
34
+ * ispremarket always false
35
+ * ispostmarket always false
36
+ *
37
+ * which is EXACTLY right for a regular-hours dataset — the ordinary OHLCV feed
38
+ * — and wrong for one that includes extended bars. It is stated here rather
39
+ * than hidden because a script gating entries on `not session.ispremarket`
40
+ * would take every bar under this engine and skip some on TradingView.
41
+ *
42
+ * Because of that, `isfirstbar_regular` and `islastbar_regular` are the same
43
+ * facts as `isfirstbar` and `islastbar`: with no extended bars in the dataset,
44
+ * the first bar of the day IS the first regular bar. They are separate entries
45
+ * anyway, so the day a host supplies extended bars there is one place to fix.
46
+ *
47
+ * ── Day boundaries ──────────────────────────────────────────────────────────
48
+ *
49
+ * `opensDay` in ../sessions.ts owns where a day starts, and its header states
50
+ * the convention. It is shared with `ta.vwap`, which restarts its accumulation
51
+ * on the same boundary — the two must not drift apart.
52
+ *
53
+ * v5-only: the registry split in ./index.ts keeps the namespace out of the
54
+ * v1–v4 views.
55
+ */
56
+ import { Context } from "../context.js";
57
+ export declare const session: {
58
+ /** The regular trading session. */
59
+ regular: string;
60
+ /** The extended trading session. */
61
+ extended: string;
62
+ /**
63
+ * True when the bar belongs to regular trading hours.
64
+ * @getter
65
+ */
66
+ ismarket: (_ctx: Context) => boolean;
67
+ /**
68
+ * True when the bar belongs to the extended session BEFORE regular hours.
69
+ * @getter
70
+ */
71
+ ispremarket: (_ctx: Context) => boolean;
72
+ /**
73
+ * True when the bar belongs to the extended session AFTER regular hours.
74
+ * @getter
75
+ */
76
+ ispostmarket: (_ctx: Context) => boolean;
77
+ /**
78
+ * True on the first bar of the day's session.
79
+ * @getter
80
+ */
81
+ isfirstbar: (ctx: Context) => boolean;
82
+ /**
83
+ * True on the first REGULAR-session bar of the day.
84
+ * @getter
85
+ */
86
+ isfirstbar_regular: (ctx: Context) => boolean;
87
+ /**
88
+ * True on the last bar of the day's session.
89
+ *
90
+ * ── Answerable on daily and above; not answerable intraday ──────────────
91
+ *
92
+ * On "1D" and higher, one bar IS one session, so every bar is its session's
93
+ * last — that is a fact about the timeframe, not a guess, and it is what
94
+ * this returns.
95
+ *
96
+ * Intraday it is unanswerable here. The last bar of a day is the bar whose
97
+ * SUCCESSOR opens a new one, and the successor has not arrived: this engine
98
+ * is fed one bar at a time, and looking ahead is exactly the thing it must
99
+ * not do. So intraday gets `false`, always.
100
+ *
101
+ * That is a stated gap rather than an approximation. A script closing
102
+ * positions on `session.islastbar` will simply never fire intraday under
103
+ * this engine, which is visible, instead of firing on the wrong bar, which
104
+ * is not.
105
+ * @getter
106
+ */
107
+ islastbar: (ctx: Context) => boolean;
108
+ /**
109
+ * True on the last REGULAR-session bar of the day. See `islastbar`.
110
+ * @getter
111
+ */
112
+ islastbar_regular: (ctx: Context) => boolean;
113
+ };
@@ -0,0 +1,12 @@
1
+ import type { Context } from "../context.js";
2
+ /** Is `x` an instance of a user-defined type? Such objects carry `__type`. */
3
+ export declare function isObject(x: any): boolean;
4
+ /** The value a UDT element sorts by, or the element itself when it is not one. */
5
+ export declare function sortKey(item: any, sortField: any): any;
6
+ /** Ascending comparison of two keys: strings by code point, numbers numerically. */
7
+ export declare function compareKeys(a: any, b: any): number;
8
+ /**
9
+ * Whether this call sorts by field. Only at v6 — at v5 a UDT array was never
10
+ * sortable here, and turning it into one would change what v5 does.
11
+ */
12
+ export declare function byField(ctx: Context | undefined, items: any[]): boolean;
@@ -0,0 +1,24 @@
1
+ import { Context } from "../context.js";
2
+ /**
3
+ * Derived price sources. Pine spells these as bare globals that recompute each
4
+ * bar, so they are getters rather than values.
5
+ */
6
+ /** (high + low) / 2 @getter */
7
+ export declare function hl2(ctx: Context): number;
8
+ /** (high + low + close) / 3 @getter */
9
+ export declare function hlc3(ctx: Context): number;
10
+ /** (open + high + low + close) / 4 @getter */
11
+ export declare function ohlc4(ctx: Context): number;
12
+ /**
13
+ * `hlcc4` — (high + low + close + close) / 4.
14
+ *
15
+ * Added alongside `last_bar_index` and `last_bar_time` in the same v5 release:
16
+ * "New built-in source variable: hlcc4 - A shortcut for (high + low + close +
17
+ * close)/4. It averages the high and low values with the double-weighted
18
+ * close." Gated to v5 with the rest of that batch.
19
+ *
20
+ * Source: https://www.tradingview.com/pine-script-docs/v5/release-notes/
21
+ * @getter
22
+ * @returns {series float} The double-weighted close average.
23
+ */
24
+ export declare function hlcc4(ctx: Context): number;
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Pine Script strings — the `str.*` namespace.
3
+ *
4
+ * v5 moved string handling into its own namespace: `tostring(x)` became
5
+ * `str.tostring(value, format)` and `tonumber(x)` became `str.tonumber(string)`
6
+ * (docs/common/VERSIONS.md §4a). The rest of the namespace —
7
+ * `str.format`, `str.length`, `str.split` and friends — has no v1–v4 spelling
8
+ * at all and exists only here.
9
+ *
10
+ * v5-only, which this file does NOT enforce: the registry split in ./index.ts
11
+ * keeps the whole namespace out of the v1–v4 views, so a v4 script naming
12
+ * `str.length` is refused there rather than by a check in every function.
13
+ *
14
+ * ── The number FORMAT is the load-bearing part ──────────────────────────────
15
+ *
16
+ * `str.tostring(value, format)` is how the golden-data harnesses get numbers
17
+ * out of TradingView (see scripts/common/make-log-harness.ts): every column is emitted
18
+ * as `str.tostring(v, "#.##########")`. If this formatter disagrees with
19
+ * TradingView's, every golden comparison is measuring the formatter rather than
20
+ * the indicator — so the digit rules below are implemented literally from
21
+ * Pine's format-string grammar rather than approximated with toFixed.
22
+ *
23
+ * '#' an OPTIONAL digit — printed only when non-zero material remains
24
+ * '0' a REQUIRED digit — always printed, padded if necessary
25
+ *
26
+ * so "#.##" is up to two decimals with trailing zeros trimmed, "0.00" is
27
+ * exactly two, and "#" is an integer. That trimming is why the harnesses can
28
+ * ask for ten decimals without every row carrying ten characters of padding.
29
+ */
30
+ import { Context } from "../context.js";
31
+ export declare const str: {
32
+ /**
33
+ * `str.tostring(value, format)` — v5's spelling of v1–v4's `tostring(x)`.
34
+ *
35
+ * The second argument is new in this spelling. The v1–v4 flat `tostring`
36
+ * keeps its own one-argument implementation in ./core.ts — `str.tostring`
37
+ * is a rename for DIAGNOSTIC purposes only, and ./index.ts is careful not
38
+ * to let the rename table overwrite this entry with it.
39
+ *
40
+ * ── The format is EITHER a format string or a `format.*` constant ────────
41
+ *
42
+ * "use str.tostring(myValue, format.mintick) to first round the number to
43
+ * tick precision and then return its string representation."
44
+ *
45
+ * `format.mintick` needs the instrument's tick size, which is why this is
46
+ * the one `str.*` member that takes a Context. The other `format.*`
47
+ * constants describe how a value appears on the PRICE AXIS and in the Data
48
+ * Window — neither of which exists here — so they are recognised and then
49
+ * render the value plainly, rather than being fed to the number-format
50
+ * parser, where "format.volume" would be read as a mask with no digit
51
+ * placeholders and produce an empty string.
52
+ */
53
+ tostring: (ctx: Context, value: any, format?: any) => string;
54
+ /** `str.tonumber(string)` — na (NaN) when the string is not a number. */
55
+ tonumber: (string: any) => number;
56
+ /** `str.format(formatString, arg0, arg1, …)`. */
57
+ format: (formatString: any, ...args: any[]) => string;
58
+ length: (string: any) => number;
59
+ contains: (source: any, str: any) => boolean;
60
+ startswith: (source: any, str: any) => boolean;
61
+ endswith: (source: any, str: any) => boolean;
62
+ /** Index of the first occurrence, or na — Pine returns na, not -1. */
63
+ pos: (source: any, str: any) => number;
64
+ /**
65
+ * `str.substring(source, begin_pos, end_pos)`.
66
+ *
67
+ * `end_pos` is EXCLUSIVE and optional; omitting it runs to the end.
68
+ */
69
+ substring: (source: any, begin_pos: any, end_pos?: any) => string;
70
+ replace_all: (source: any, target: any, replacement: any) => string;
71
+ /**
72
+ * `str.replace(source, target, replacement, occurrence)` — ONE occurrence.
73
+ *
74
+ * The sibling of `replace_all`, and the difference is the fourth argument:
75
+ * `occurrence` is a zero-based index selecting WHICH match to replace, and
76
+ * defaults to 0 — the first. An index past the last match leaves the string
77
+ * alone, which is the same answer as "there was nothing to replace".
78
+ */
79
+ replace: (source: any, target: any, replacement: any, occurrence?: any) => string;
80
+ /** `str.trim(string)` — leading and trailing whitespace removed. */
81
+ trim: (string: any) => string;
82
+ /**
83
+ * `str.format_time(time, format, timezone)` — October 2022.
84
+ *
85
+ * "Converts a timestamp to a formatted string using the specified format
86
+ * and time zone."
87
+ *
88
+ * The format is a Java `SimpleDateFormat` pattern, which is what
89
+ * TradingView's own examples pass — "yyyy-MM-dd", "HH:mm:ss",
90
+ * "yyyy-MM-dd'T'HH:mm:ss". The subset implemented is the one those patterns
91
+ * use, and an unrecognised letter run is left as written rather than
92
+ * silently dropped: a pattern this engine does not understand should be
93
+ * visible in the output, not invisible.
94
+ *
95
+ * Quoted runs are literal — `'T'` is the letter T and not a year field —
96
+ * because a date-time pattern without that rule cannot express ISO 8601,
97
+ * which is the commonest thing anyone formats.
98
+ */
99
+ format_time: (ctx: Context, time: any, format?: any, timezone?: any) => string;
100
+ upper: (source: any) => string;
101
+ lower: (source: any) => string;
102
+ /** `str.split(string, separator)` — returns a Pine array of strings. */
103
+ split: (string: any, separator: any) => string[];
104
+ /** `str.repeat(string, repeat, separator)`. */
105
+ repeat: (string: any, repeat: any, separator?: any) => string;
106
+ /**
107
+ * `str.match(source, regex)` — the first match, or an empty string.
108
+ *
109
+ * Pine documents this as a RE2 regular expression. JavaScript's engine is
110
+ * not RE2, and the two disagree on backreferences and lookaround, which RE2
111
+ * does not support at all. Patterns that stay inside the common subset
112
+ * behave identically; anything relying on a JavaScript-only construct will
113
+ * work here and fail on TradingView, which is the safe direction for a
114
+ * feature no harness exercises.
115
+ */
116
+ match: (source: any, regex: any) => string;
117
+ };