oakscriptjs 0.11.0 → 0.11.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.
- package/dist/cjs/array/index.d.ts +8 -2
- package/dist/cjs/array/index.d.ts.map +1 -1
- package/dist/cjs/array/index.js +2 -1
- package/dist/cjs/array/index.js.map +2 -2
- package/dist/cjs/box/index.js +6 -6
- package/dist/cjs/box/index.js.map +2 -2
- package/dist/cjs/callsite/index.js +1 -1
- package/dist/cjs/callsite/index.js.map +2 -2
- package/dist/cjs/drawing/registry.d.ts +15 -6
- package/dist/cjs/drawing/registry.d.ts.map +1 -1
- package/dist/cjs/drawing/registry.js +16 -2
- package/dist/cjs/drawing/registry.js.map +2 -2
- package/dist/cjs/index.d.ts +3 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/input.d.ts +9 -1
- package/dist/cjs/input.d.ts.map +1 -1
- package/dist/cjs/input.js +16 -0
- package/dist/cjs/input.js.map +2 -2
- package/dist/cjs/label/index.js +3 -3
- package/dist/cjs/label/index.js.map +2 -2
- package/dist/cjs/line/index.d.ts +10 -27
- package/dist/cjs/line/index.d.ts.map +1 -1
- package/dist/cjs/line/index.js +10 -27
- package/dist/cjs/line/index.js.map +2 -2
- package/dist/cjs/linefill/index.d.ts +3 -0
- package/dist/cjs/linefill/index.d.ts.map +1 -1
- package/dist/cjs/linefill/index.js +15 -1
- package/dist/cjs/linefill/index.js.map +3 -3
- package/dist/cjs/runtime/adapters/SimpleInputAdapter.js +1 -1
- package/dist/cjs/runtime/adapters/SimpleInputAdapter.js.map +2 -2
- package/dist/cjs/runtime/index.d.ts +1 -1
- package/dist/cjs/runtime/index.d.ts.map +1 -1
- package/dist/cjs/runtime/index.js +1 -0
- package/dist/cjs/runtime/index.js.map +2 -2
- package/dist/cjs/runtime/inputs.d.ts +9 -0
- package/dist/cjs/runtime/inputs.d.ts.map +1 -1
- package/dist/cjs/runtime/inputs.js +8 -0
- package/dist/cjs/runtime/inputs.js.map +2 -2
- package/dist/cjs/runtime/types.d.ts +1 -1
- package/dist/cjs/runtime/types.d.ts.map +1 -1
- package/dist/cjs/runtime/types.js.map +1 -1
- package/dist/cjs/script/index.d.ts +65 -12
- package/dist/cjs/script/index.d.ts.map +1 -1
- package/dist/cjs/script/index.js +168 -19
- package/dist/cjs/script/index.js.map +3 -3
- package/dist/cjs/security/other.d.ts +92 -0
- package/dist/cjs/security/other.d.ts.map +1 -0
- package/dist/cjs/security/other.js +164 -0
- package/dist/cjs/security/other.js.map +7 -0
- package/dist/cjs/session/bars.d.ts +10 -1
- package/dist/cjs/session/bars.d.ts.map +1 -1
- package/dist/cjs/session/bars.js +16 -2
- package/dist/cjs/session/bars.js.map +2 -2
- package/dist/cjs/session/calendar.d.ts +4 -1
- package/dist/cjs/session/calendar.d.ts.map +1 -1
- package/dist/cjs/session/calendar.js +11 -7
- package/dist/cjs/session/calendar.js.map +2 -2
- package/dist/cjs/session/context.d.ts +2 -1
- package/dist/cjs/session/context.d.ts.map +1 -1
- package/dist/cjs/session/context.js +2 -1
- package/dist/cjs/session/context.js.map +2 -2
- package/dist/cjs/str/floatingdecimal.d.ts +31 -0
- package/dist/cjs/str/floatingdecimal.d.ts.map +1 -0
- package/dist/cjs/str/floatingdecimal.js +298 -0
- package/dist/cjs/str/floatingdecimal.js.map +7 -0
- package/dist/cjs/str/index.d.ts +4 -3
- package/dist/cjs/str/index.d.ts.map +1 -1
- package/dist/cjs/str/index.js +1 -1
- package/dist/cjs/str/index.js.map +2 -2
- package/dist/cjs/str/numberformat.d.ts +6 -4
- package/dist/cjs/str/numberformat.d.ts.map +1 -1
- package/dist/cjs/str/numberformat.js +3 -2
- package/dist/cjs/str/numberformat.js.map +2 -2
- package/dist/cjs/ta/index.d.ts +34 -17
- package/dist/cjs/ta/index.d.ts.map +1 -1
- package/dist/cjs/ta/index.js +132 -116
- package/dist/cjs/ta/index.js.map +2 -2
- package/dist/cjs/ta/limits.d.ts +11 -0
- package/dist/cjs/ta/limits.d.ts.map +1 -1
- package/dist/cjs/ta/limits.js +15 -1
- package/dist/cjs/ta/limits.js.map +2 -2
- package/dist/cjs/ta/running-sum.js +1 -1
- package/dist/cjs/ta/running-sum.js.map +2 -2
- package/dist/cjs/ta-series.d.ts +1 -1
- package/dist/cjs/ta-series.d.ts.map +1 -1
- package/dist/cjs/ta-series.js +1 -1
- package/dist/cjs/ta-series.js.map +2 -2
- package/dist/cjs/table/index.d.ts +3 -1
- package/dist/cjs/table/index.d.ts.map +1 -1
- package/dist/cjs/table/index.js +1 -0
- package/dist/cjs/table/index.js.map +3 -3
- package/dist/cjs/time/session.d.ts +9 -0
- package/dist/cjs/time/session.d.ts.map +1 -1
- package/dist/cjs/time/session.js +42 -14
- package/dist/cjs/time/session.js.map +3 -3
- package/dist/cjs/time/timezone.d.ts +6 -1
- package/dist/cjs/time/timezone.d.ts.map +1 -1
- package/dist/cjs/time/timezone.js +2 -2
- package/dist/cjs/time/timezone.js.map +2 -2
- package/dist/cjs/types/metadata.d.ts +1 -1
- package/dist/cjs/types/metadata.d.ts.map +1 -1
- package/dist/cjs/types/metadata.js.map +1 -1
- package/dist/esm/array/index.d.ts +8 -2
- package/dist/esm/array/index.d.ts.map +1 -1
- package/dist/esm/array/index.js +12 -3
- package/dist/esm/array/index.js.map +1 -1
- package/dist/esm/box/index.js +6 -6
- package/dist/esm/box/index.js.map +1 -1
- package/dist/esm/callsite/index.js +1 -1
- package/dist/esm/callsite/index.js.map +1 -1
- package/dist/esm/drawing/registry.d.ts +15 -6
- package/dist/esm/drawing/registry.d.ts.map +1 -1
- package/dist/esm/drawing/registry.js +30 -7
- package/dist/esm/drawing/registry.js.map +1 -1
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +4 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/input.d.ts +9 -1
- package/dist/esm/input.d.ts.map +1 -1
- package/dist/esm/input.js +16 -0
- package/dist/esm/input.js.map +1 -1
- package/dist/esm/label/index.js +3 -3
- package/dist/esm/label/index.js.map +1 -1
- package/dist/esm/line/index.d.ts +10 -27
- package/dist/esm/line/index.d.ts.map +1 -1
- package/dist/esm/line/index.js +20 -64
- package/dist/esm/line/index.js.map +1 -1
- package/dist/esm/linefill/index.d.ts +3 -0
- package/dist/esm/linefill/index.d.ts.map +1 -1
- package/dist/esm/linefill/index.js +20 -1
- package/dist/esm/linefill/index.js.map +1 -1
- package/dist/esm/runtime/adapters/SimpleInputAdapter.js +1 -1
- package/dist/esm/runtime/adapters/SimpleInputAdapter.js.map +1 -1
- package/dist/esm/runtime/index.d.ts +1 -1
- package/dist/esm/runtime/index.d.ts.map +1 -1
- package/dist/esm/runtime/index.js +1 -1
- package/dist/esm/runtime/index.js.map +1 -1
- package/dist/esm/runtime/inputs.d.ts +9 -0
- package/dist/esm/runtime/inputs.d.ts.map +1 -1
- package/dist/esm/runtime/inputs.js +15 -0
- package/dist/esm/runtime/inputs.js.map +1 -1
- package/dist/esm/runtime/types.d.ts +1 -1
- package/dist/esm/runtime/types.d.ts.map +1 -1
- package/dist/esm/script/index.d.ts +65 -12
- package/dist/esm/script/index.d.ts.map +1 -1
- package/dist/esm/script/index.js +217 -29
- package/dist/esm/script/index.js.map +1 -1
- package/dist/esm/security/other.d.ts +92 -0
- package/dist/esm/security/other.d.ts.map +1 -0
- package/dist/esm/security/other.js +211 -0
- package/dist/esm/security/other.js.map +1 -0
- package/dist/esm/session/bars.d.ts +10 -1
- package/dist/esm/session/bars.d.ts.map +1 -1
- package/dist/esm/session/bars.js +26 -1
- package/dist/esm/session/bars.js.map +1 -1
- package/dist/esm/session/calendar.d.ts +4 -1
- package/dist/esm/session/calendar.d.ts.map +1 -1
- package/dist/esm/session/calendar.js +19 -7
- package/dist/esm/session/calendar.js.map +1 -1
- package/dist/esm/session/context.d.ts +2 -1
- package/dist/esm/session/context.d.ts.map +1 -1
- package/dist/esm/session/context.js +5 -3
- package/dist/esm/session/context.js.map +1 -1
- package/dist/esm/str/floatingdecimal.d.ts +31 -0
- package/dist/esm/str/floatingdecimal.d.ts.map +1 -0
- package/dist/esm/str/floatingdecimal.js +272 -0
- package/dist/esm/str/floatingdecimal.js.map +1 -0
- package/dist/esm/str/index.d.ts +4 -3
- package/dist/esm/str/index.d.ts.map +1 -1
- package/dist/esm/str/index.js +6 -5
- package/dist/esm/str/index.js.map +1 -1
- package/dist/esm/str/numberformat.d.ts +6 -4
- package/dist/esm/str/numberformat.d.ts.map +1 -1
- package/dist/esm/str/numberformat.js +9 -5
- package/dist/esm/str/numberformat.js.map +1 -1
- package/dist/esm/ta/index.d.ts +34 -17
- package/dist/esm/ta/index.d.ts.map +1 -1
- package/dist/esm/ta/index.js +155 -185
- package/dist/esm/ta/index.js.map +1 -1
- package/dist/esm/ta/limits.d.ts +11 -0
- package/dist/esm/ta/limits.d.ts.map +1 -1
- package/dist/esm/ta/limits.js +27 -2
- package/dist/esm/ta/limits.js.map +1 -1
- package/dist/esm/ta/running-sum.js +1 -1
- package/dist/esm/ta/running-sum.js.map +1 -1
- package/dist/esm/ta-series.d.ts +1 -1
- package/dist/esm/ta-series.d.ts.map +1 -1
- package/dist/esm/ta-series.js +2 -1
- package/dist/esm/ta-series.js.map +1 -1
- package/dist/esm/table/index.d.ts +3 -1
- package/dist/esm/table/index.d.ts.map +1 -1
- package/dist/esm/table/index.js +6 -1
- package/dist/esm/table/index.js.map +1 -1
- package/dist/esm/time/session.d.ts +9 -0
- package/dist/esm/time/session.d.ts.map +1 -1
- package/dist/esm/time/session.js +53 -15
- package/dist/esm/time/session.js.map +1 -1
- package/dist/esm/time/timezone.d.ts +6 -1
- package/dist/esm/time/timezone.d.ts.map +1 -1
- package/dist/esm/time/timezone.js +8 -2
- package/dist/esm/time/timezone.js.map +1 -1
- package/dist/esm/types/metadata.d.ts +1 -1
- package/dist/esm/types/metadata.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/array/index.ts +11 -3
- package/src/box/index.ts +6 -6
- package/src/callsite/index.ts +1 -1
- package/src/drawing/registry.ts +30 -7
- package/src/index.ts +11 -1
- package/src/input.ts +18 -1
- package/src/label/index.ts +3 -3
- package/src/line/index.ts +20 -68
- package/src/linefill/index.ts +20 -1
- package/src/runtime/adapters/SimpleInputAdapter.ts +1 -1
- package/src/runtime/index.ts +1 -0
- package/src/runtime/inputs.ts +16 -0
- package/src/runtime/types.ts +1 -1
- package/src/script/index.ts +292 -30
- package/src/security/other.ts +269 -0
- package/src/session/bars.ts +24 -1
- package/src/session/calendar.ts +23 -7
- package/src/session/context.ts +5 -3
- package/src/str/floatingdecimal.ts +268 -0
- package/src/str/index.ts +6 -5
- package/src/str/numberformat.ts +11 -6
- package/src/ta/index.ts +157 -183
- package/src/ta/limits.ts +28 -1
- package/src/ta/running-sum.ts +1 -1
- package/src/ta-series.ts +3 -2
- package/src/table/index.ts +4 -1
- package/src/time/session.ts +58 -16
- package/src/time/timezone.ts +9 -2
- package/src/types/metadata.ts +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/callsite/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Per-call history of ta.* functions called in a conditional block.\n *\n * In PineScript, every ta.* call keeps its own history of the values it receives. A call inside\n * an `if` block receives values only on the bars where the block runs, so its history skips the\n * other bars: `ta.crossover(a, b)` is false on the first bar the block runs, and `ta.sma(x, 3)`\n * averages the last 3 values it received, not the last 3 bars.\n *\n * - {@link whenCalled}: vectorized, when the bars of the calls are known in advance.\n * - {@link crossover} / {@link crossunder} / {@link cross} / {@link barssince}: one stateful call site for bar\n * loops, called only on the bars where the Pine call runs.\n * - {@link lowestByBar} / {@link highestByBar} / {@link lowestbars} / {@link highestbars} / {@link pivothigh} /\n * {@link pivotlow}: `ta.lowest` / `ta.highest` / `ta.lowestbars` / `ta.highestbars` / `ta.pivothigh` /\n * `ta.pivotlow` in a conditional block or a loop, also with a length that changes on each call. They keep the\n * non-na values of their calls; {@link lowest} / {@link highest} are the same sites called with `(value, length)`.\n * - {@link linreg}: `ta.linreg` in a conditional block, whose history is kept by bar (not by call).\n * - {@link sum} / {@link sma}: `math.sum` / `ta.sma` in a `for` / `while` loop, called several times on one bar.\n *\n * Since PineScript v6, `and` / `or` are lazy: the right operand runs only when the left operand does not decide\n * the result. A ta.* call in the right operand of `a or b` runs on the bars where `a` is false, in `a and b` on the\n * bars where `a` is true, so it needs a call site too:\n *\n * ```typescript\n * // Pine: longCond = longUp or (src > sig and ta.barssince(longUp) <= lookback)\n * const since = callsite.whenCalled(longUp.map((u, i) => !u && src[i] > sig[i]), (c) => taCore.barssince(c.map(Boolean)), longUp);\n * // ta.barssince(longUp) only runs where longUp is false: it never sees true and stays na\n * ```\n *\n * ```typescript\n * // Pine: if inRange\n * // buy = ta.crossover(cumRsi, 60)\n * const buy = callsite.whenCalled(inRange, (a) => taCore.crossover(a, a.map(() => 60)), cumRsi);\n *\n * // Same call in a bar loop\n * const buyCross = callsite.crossover();\n * for (let i = 0; i < n; i++) {\n * if (inRange[i]) {\n * const buy = buyCross(cumRsi[i], 60);\n * }\n * }\n * ```\n *\n * @module callsite\n */\n\nimport type { Source } from '../types/index.js';\nimport { linreg as linregSeries } from '../ta/index.js';\nimport { RunningSum, isNa } from '../ta/running-sum.js';\nimport { checkSumLength, checkWindowLength } from '../ta/limits.js';\nimport { seededRandom } from '../math/index.js';\n\n/**\n * Runs `fn` on the bars where `called` is true only, like a ta.* call inside an `if` block.\n * `fn` receives the values of `sources` on those bars, in order; its results are placed back on\n * the same bars. The other bars get na (NaN).\n *\n * @param called - true (or non-zero) on the bars where the call runs\n * @param fn - the calculation, for example `(x) => taCore.sma(x, 3)`\n * @param sources - the arguments of the call, one value per chart bar\n */\nexport function whenCalled<T extends number | boolean>(\n called: ArrayLike<boolean | number>,\n fn: (...values: number[][]) => ArrayLike<T>,\n ...sources: Source[]\n): Array<T | number> {\n const bars: number[] = [];\n for (let i = 0; i < called.length; i++) if (called[i]) bars.push(i);\n const result = fn(...sources.map(s => bars.map(i => s[i] ?? NaN)));\n const out = new Array<T | number>(called.length).fill(NaN);\n bars.forEach((bar, k) => {\n out[bar] = result[k]!;\n });\n return out;\n}\n\n/**\n * A call site that keeps the arguments of the last call where both were not na (na before such a call), as\n * ta.crossover / ta.crossunder / ta.cross.\n */\nfunction twoSeriesSite(test: (a: number, b: number, prevA: number, prevB: number) => boolean) {\n let prevA = NaN;\n let prevB = NaN;\n return (a: number, b: number): boolean => {\n const result = test(a, b, prevA, prevB);\n if (!Number.isNaN(a) && !Number.isNaN(b)) {\n prevA = a;\n prevB = b;\n }\n return result;\n };\n}\n\n/**\n * One `ta.crossover(a, b)` call site: compared with the last call where both arguments were not na; false before\n * such a call.\n */\nexport function crossover(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => a > b && pa <= pb);\n}\n\n/**\n * One `ta.crossunder(a, b)` call site: compared with the last call where both arguments were not na; false before\n * such a call.\n */\nexport function crossunder(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => a < b && pa >= pb);\n}\n\n/**\n * One `ta.barssince(condition)` call site: the number of calls since the condition was true on a call (0 on that\n * call), na before the first true condition. An na condition counts as false.\n */\nexport function barssince(): (condition: boolean | number) => number {\n let count = NaN;\n return (condition) => {\n if (condition && !Number.isNaN(condition)) count = 0;\n else if (!Number.isNaN(count)) count++;\n return count;\n };\n}\n\n/**\n * One `ta.cross(a, b)` call site, rules of `ta.cross`: the site keeps the side of the last call where `a` was\n * strictly above or strictly below `b` (none before such a call; equal values and na arguments do not change it),\n * and is true when the arguments are strictly on the other side. False with an na argument.\n */\nexport function cross(): (a: number, b: number) => boolean {\n let side = 0; // -1: last strictly below, 1: last strictly above, 0: none yet\n return (a, b) => {\n if (Number.isNaN(a) || Number.isNaN(b)) return false;\n const result = (side < 0 && a > b) || (side > 0 && a < b);\n if (a < b) side = -1;\n else if (a > b) side = 1;\n return result;\n };\n}\n\n/** The values a ta.highest / ta.lowest / ta.pivothigh call site keeps: the non-na values of its calls, one per bar. */\nclass KeptCalls {\n readonly values: number[] = [];\n readonly bars: number[] = [];\n\n /** Keeps a non-na value; a later call on the same bar (a loop) replaces the value of that bar. */\n add(barIndex: number, value: number): void {\n if (Number.isNaN(value)) return;\n const last = this.values.length - 1;\n if (last >= 0 && this.bars[last] === barIndex) this.values[last] = value;\n else {\n this.values.push(value);\n this.bars.push(barIndex);\n }\n }\n\n /** Position of the best of the last `count` kept values (the newest one on ties), -1 when there is none. */\n best(count: number, isLowest: boolean): number {\n const last = this.values.length - 1;\n if (last < 0 || !(count >= 1)) return -1;\n let best = last;\n for (let k = last - 1; k >= 0 && k > last - count; k--) {\n if (isLowest ? this.values[k]! < this.values[best]! : this.values[k]! > this.values[best]!) best = k;\n }\n return best;\n }\n}\n\n/** One `ta.lowest` / `ta.highest` / `ta.lowestbars` / `ta.highestbars` call site; rules in {@link lowestByBar}. */\nfunction extremeByBarSite(\n isLowest: boolean,\n offsets: boolean\n): (barIndex: number, value: number, length: number) => number {\n const kept = new KeptCalls();\n const name = (isLowest ? 'lowest' : 'highest') + (offsets ? 'bars' : '');\n return (barIndex, value, length) => {\n checkWindowLength(name, length, barIndex);\n kept.add(barIndex, value);\n const len = Math.trunc(length);\n if (barIndex < len - 1) return NaN;\n const best = kept.best(len, isLowest);\n if (best < 0) return NaN;\n return offsets ? -(barIndex - kept.bars[best]!) : kept.values[best]!;\n };\n}\n\n/** {@link extremeByBarSite} called with `(value, length, barIndex?)`: without a bar index, every call is a new bar. */\nfunction extremeSite(isLowest: boolean): (value: number, length: number, barIndex?: number) => number {\n const site = extremeByBarSite(isLowest, false);\n let calls = 0;\n return (value, length, barIndex) => site(barIndex ?? calls++, value, length);\n}\n\n/**\n * One `ta.lowest(source, length)` call site, called with `(value, length, barIndex?)`: the same site as\n * {@link lowestByBar} (same rules). Pass the bar index when the call does not run on every bar; without it every\n * call counts as one bar, which is right for a call on every bar (for example with a length that changes).\n *\n * @example\n * ```typescript\n * // Pine: lowPrice = ta.lowest(close[1], lookback) // lookback changes per bar\n * const lowPrice = callsite.lowest();\n * const out = closes.map((_, i) => lowPrice(i > 0 ? closes[i - 1]! : NaN, lookback[i]!));\n * ```\n */\nexport function lowest(): (value: number, length: number, barIndex?: number) => number {\n return extremeSite(true);\n}\n\n/**\n * One `ta.highest(source, length)` call site, called with `(value, length, barIndex?)`. Same rules as\n * {@link lowest}.\n */\nexport function highest(): (value: number, length: number, barIndex?: number) => number {\n return extremeSite(false);\n}\n\n/**\n * One `ta.lowest(source, length)` call site in a conditional block or a loop, called with\n * `(barIndex, value, length)` on the bars (and loop turns) where the Pine call runs. The length can change from one\n * call to the next.\n *\n * PineScript rules (measured in `if` blocks, ternaries, user functions and `for` loops, with constant lengths and\n * lengths that change, on sources with and without na):\n * - the call site keeps the non-na values it received, each with its bar; nothing is kept for a bar without a call\n * or for an na value\n * - the result is na while `barIndex < length - 1` (by bar, not by call) and while no value was received\n * - otherwise it is the lowest of the last `length` kept values, or of all of them when there are fewer: the first\n * call after bar `length - 1` gives its own value. A call with an na value also gives this result\n * - in a loop (several calls on one bar), a bar has one kept value: each call replaces the value of the earlier\n * calls of that bar, so a call gives the lowest of its value and the values of the bars before\n *\n * Called on every bar, it equals `ta.lowest`.\n *\n * @example\n * ```typescript\n * // Pine: lo = cond ? ta.lowest(low, 6) : na\n * const site = callsite.lowestByBar();\n * const lo = lows.map((v, i) => (cond[i] ? site(i, v, 6) : NaN));\n * ```\n */\nexport function lowestByBar(): (barIndex: number, value: number, length: number) => number {\n return extremeByBarSite(true, false);\n}\n\n/**\n * One `ta.highest(source, length)` call site in a conditional block or a loop, called with\n * `(barIndex, value, length)`. Same rules as {@link lowestByBar}.\n */\nexport function highestByBar(): (barIndex: number, value: number, length: number) => number {\n return extremeByBarSite(false, false);\n}\n\n/**\n * One `ta.lowestbars(source, length)` call site in a conditional block or a loop, called with\n * `(barIndex, value, length)`: the offset (0 or negative) from this bar to the bar of the lowest of the last `length`\n * kept values, the newest one on equal values. The values are kept as in {@link lowestByBar}; the offset counts\n * bars, not calls, so it can be below `-(length - 1)`.\n *\n * @example\n * ```typescript\n * // Pine: off = cond ? ta.lowestbars(low, 10) : na\n * const site = callsite.lowestbars();\n * const off = lows.map((v, i) => (cond[i] ? site(i, v, 10) : NaN));\n * ```\n */\nexport function lowestbars(): (barIndex: number, value: number, length: number) => number {\n return extremeByBarSite(true, true);\n}\n\n/**\n * One `ta.highestbars(source, length)` call site in a conditional block or a loop, called with\n * `(barIndex, value, length)`. Same rules as {@link lowestbars}.\n */\nexport function highestbars(): (barIndex: number, value: number, length: number) => number {\n return extremeByBarSite(false, true);\n}\n\n/** One `ta.pivothigh` / `ta.pivotlow` call site; rules in {@link pivothigh}. */\nfunction pivotSite(isLowest: boolean): (barIndex: number, value: number, leftbars: number, rightbars: number) => number {\n const kept = new KeptCalls();\n return (barIndex, value, leftbars, rightbars) => {\n kept.add(barIndex, value);\n const left = Math.trunc(leftbars);\n const right = Math.trunc(rightbars);\n if (!(barIndex >= left + right)) return NaN;\n const best = kept.best(left + right + 1, isLowest);\n return best >= 0 && kept.bars[best] === barIndex - right ? kept.values[best]! : NaN;\n };\n}\n\n/**\n * One `ta.pivothigh(source, leftbars, rightbars)` call site in a conditional block, called with\n * `(barIndex, value, leftbars, rightbars)` on the bars where the Pine call runs. The lengths can change from one call\n * to the next (the lengths of the current call are used).\n *\n * PineScript rules (measured in `if` blocks and ternaries, and on sources with na):\n * - the call site keeps the non-na values it received, each with its bar\n * - on a call it takes the last `leftbars + rightbars + 1` kept values (all of them when there are fewer) and finds\n * the highest, the newest one on equal values\n * - there is a pivot only when that value is on the bar `rightbars` BARS back (by bar index, not by call); the\n * result is its value, na otherwise and before bar `leftbars + rightbars`\n *\n * Called on every bar, it equals `ta.pivothigh`.\n *\n * @example\n * ```typescript\n * // Pine: ph = useFilter ? ta.pivothigh(src, 5, 5) : na\n * const site = callsite.pivothigh();\n * const ph = src.map((v, i) => (useFilter[i] ? site(i, v, 5, 5) : NaN));\n * ```\n */\nexport function pivothigh(): (barIndex: number, value: number, leftbars: number, rightbars: number) => number {\n return pivotSite(false);\n}\n\n/**\n * One `ta.pivotlow(source, leftbars, rightbars)` call site in a conditional block, called with\n * `(barIndex, value, leftbars, rightbars)`. Same rules as {@link pivothigh} (the lowest value).\n */\nexport function pivotlow(): (barIndex: number, value: number, leftbars: number, rightbars: number) => number {\n return pivotSite(true);\n}\n\n/**\n * One `ta.linreg(source, length, offset)` call site in a conditional block, called with\n * `(barIndex, value, length, offset)` on the bars where the Pine call runs.\n *\n * PineScript rules (measured): `ta.linreg` keeps the values it receives in a ring of `length + 1` slots indexed by the\n * bar index, filled with 0 at the start and written only on the bars where it is called. The window is read from the\n * ring for the last `length` bars: a bar before the first call counts as 0, and a bar without a call holds the value of\n * the call `length + 1` bars earlier (0 if there was none). The result is na before bar `length - 1`. Called on every\n * bar, it equals `ta.linreg`.\n *\n * @example\n * ```typescript\n * // Pine: if bar_index >= 20\n * // a := ta.linreg(close, 10, 0)\n * const site = callsite.linreg();\n * const a = closes.map((c, i) => (i >= 20 ? site(i, c, 10, 0) : NaN));\n * ```\n */\nexport function linreg(): (barIndex: number, value: number, length: number, offset?: number) => number {\n let ring: number[] = [];\n return (barIndex, value, length, offset = 0) => {\n const len = Math.floor(length);\n if (ring.length !== len + 1) ring = new Array<number>(len + 1).fill(0);\n ring[barIndex % (len + 1)] = value;\n if (barIndex < len - 1) return NaN;\n const window = Array.from({ length: len }, (_, k) => ring[(barIndex - len + 1 + k) % (len + 1)]!);\n return linregSeries(window, len, offset)[len - 1]!;\n };\n}\n\n\n/**\n * One `math.sum` call site in a loop; rules in {@link sum}. With `squares`, it also keeps the running sum of the\n * squared values (for {@link stdev}). Returns `[sum, sumOfSquares]` (NaN when not kept).\n */\nfunction loopSumSite(\n name: string,\n squares: boolean\n): (barIndex: number, value: number, length: number) => [number, number] {\n const running = new RunningSum();\n const runningSq = new RunningSum();\n let lastBar = NaN;\n let pending = false;\n return (barIndex, value, length) => {\n const len = Math.floor(length);\n if (!(len >= 1)) throw new Error(`callsite.${name}: length must be at least 1 (got ${length})`);\n checkSumLength(name === 'sum' ? 'math.sum' : `ta.${name}`, len, barIndex);\n if (barIndex !== lastBar) {\n if (pending) {\n running.commit();\n if (squares) runningSq.commit();\n }\n pending = false;\n lastBar = barIndex;\n }\n if (isNa(value)) {\n pending = false;\n return [running.stepNa(len), squares ? runningSq.stepNa(len) : NaN];\n }\n const x = value;\n const out: [number, number] = [running.step(x, len), squares ? runningSq.step(x * x, len) : NaN];\n pending = true;\n return out;\n };\n}\n\n/**\n * One `math.sum(source, length)` call site inside a `for` / `while` loop, called with `(barIndex, value, length)` on\n * each call.\n *\n * PineScript rules (measured on calls in loops, 1 to 3 calls per bar, and bars without a call):\n * - the call site keeps one history value per bar: the value of its last call on that bar\n * - every call on a bar starts from the state of the earlier bars, so it gives the sum of its value and the last\n * `length - 1` kept values; the last call of the bar is the one kept for the later bars\n * - the length can change from one call to the next (also on the same bar): each call first moves the kept sum to\n * its own length as `math.sum` with a series length does (Kahan steps of the raw values)\n * - a bar without a call is not in the history (as a call in an `if` block)\n * - the sum is the same compensated running sum as `math.sum` (bit for bit)\n *\n * An na value is skipped as in `math.sum` (it returns the sum of the last `length` earlier values); when it is the\n * last call of a bar, the bar is not in the history (not measured).\n *\n * @example\n * ```typescript\n * // Pine: for i = 0 to 2\n * // s = math.sum(close * (1 + 0.01 * i), 7)\n * const site = callsite.sum();\n * for (let b = 0; b < closes.length; b++) {\n * for (let i = 0; i <= 2; i++) {\n * const s = site(b, closes[b]! * (1 + 0.01 * i), 7);\n * }\n * }\n * ```\n */\nexport function sum(): (barIndex: number, value: number, length: number) => number {\n const site = loopSumSite('sum', false);\n return (barIndex, value, length) => site(barIndex, value, length)[0];\n}\n\n/**\n * One `ta.sma(source, length)` call site inside a `for` / `while` loop, called with `(barIndex, value, length)` on\n * each call: {@link sum} divided by the length (same rules).\n *\n * @example\n * ```typescript\n * // Pine: evaluate(ratio) => ta.sma(gann(ratio), n) // called once per ratio in a while loop\n * const site = callsite.sma();\n * for (let b = 0; b < closes.length; b++) {\n * for (const ratio of ratios) {\n * const avg = site(b, gann(b, ratio), n);\n * }\n * }\n * ```\n */\nexport function sma(): (barIndex: number, value: number, length: number) => number {\n const site = loopSumSite('sma', false);\n return (barIndex, value, length) => site(barIndex, value, length)[0] / Math.floor(length);\n}\n\n/**\n * One `ta.stdev(source, length, biased)` call site inside a `for` / `while` loop, called with\n * `(barIndex, value, length, biased?)` on each call: the running sums of the values and of their squares follow the\n * rules of {@link sum}; the result is computed from them as `ta.stdev` (bit for bit).\n *\n * @example\n * ```typescript\n * // Pine: for len in lengths\n * // [mid, up, lo] = ta.bb(close, len, 2)\n * const avgSite = callsite.sma();\n * const devSite = callsite.stdev();\n * for (let b = 0; b < closes.length; b++) {\n * for (const len of lengths) {\n * const mid = avgSite(b, closes[b]!, len);\n * const dev = devSite(b, closes[b]!, len);\n * }\n * }\n * ```\n */\nexport function stdev(): (barIndex: number, value: number, length: number, biased?: boolean) => number {\n const site = loopSumSite('stdev', true);\n return (barIndex, value, length, biased = true) => {\n const len = Math.floor(length);\n const [s, sq] = site(barIndex, value, length);\n const mean = s / len;\n const variance = biased ? sq / len - mean * mean : sq / (len - 1) - (mean * s) / (len - 1);\n if (!biased && len <= 1) return NaN;\n return Number.isNaN(variance) ? NaN : variance > 0 ? Math.sqrt(variance) : 0;\n };\n}\n\n/**\n * One `math.random(min, max, seed)` call site: PineScript keeps one generator per call site, so two call sites\n * with the same seed give the same sequence. Called with `(min?, max?)` once per bar.\n *\n * @example\n * ```typescript\n * // Pine: a = math.random(0, 1, 42), b = math.random(0, 1, 42) // a == b on every bar\n * const a = callsite.random(42);\n * const b = callsite.random(42);\n * ```\n */\nexport function random(seed: number): (min?: number, max?: number) => number {\n return seededRandom(seed);\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8CA,gBAAuC;AACvC,yBAAiC;AACjC,oBAAkD;AAClD,kBAA6B;AAWtB,SAAS,WACd,QACA,OACG,SACgB;AACnB,QAAM,OAAiB,CAAC;AACxB,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,KAAI,OAAO,CAAC,EAAG,MAAK,KAAK,CAAC;AAClE,QAAM,SAAS,GAAG,GAAG,QAAQ,IAAI,OAAK,KAAK,IAAI,OAAK,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC;AACjE,QAAM,MAAM,IAAI,MAAkB,OAAO,MAAM,EAAE,KAAK,GAAG;AACzD,OAAK,QAAQ,CAAC,KAAK,MAAM;AACvB,QAAI,GAAG,IAAI,OAAO,CAAC;AAAA,EACrB,CAAC;AACD,SAAO;AACT;AAMA,SAAS,cAAc,MAAuE;AAC5F,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,SAAO,CAAC,GAAW,MAAuB;AACxC,UAAM,SAAS,KAAK,GAAG,GAAG,OAAO,KAAK;AACtC,QAAI,CAAC,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,GAAG;AACxC,cAAQ;AACR,cAAQ;AAAA,IACV;AACA,WAAO;AAAA,EACT;AACF;AAMO,SAAS,YAA+C;AAC7D,SAAO,cAAc,CAAC,GAAG,GAAG,IAAI,OAAO,IAAI,KAAK,MAAM,EAAE;AAC1D;AAMO,SAAS,aAAgD;AAC9D,SAAO,cAAc,CAAC,GAAG,GAAG,IAAI,OAAO,IAAI,KAAK,MAAM,EAAE;AAC1D;AAMO,SAAS,YAAqD;AACnE,MAAI,QAAQ;AACZ,SAAO,CAAC,cAAc;AACpB,QAAI,aAAa,CAAC,OAAO,MAAM,SAAS,EAAG,SAAQ;AAAA,aAC1C,CAAC,OAAO,MAAM,KAAK,EAAG;AAC/B,WAAO;AAAA,EACT;AACF;AAOO,SAAS,QAA2C;AACzD,MAAI,OAAO;AACX,SAAO,CAAC,GAAG,MAAM;AACf,QAAI,OAAO,MAAM,CAAC,KAAK,OAAO,MAAM,CAAC,EAAG,QAAO;AAC/C,UAAM,SAAU,OAAO,KAAK,IAAI,KAAO,OAAO,KAAK,IAAI;AACvD,QAAI,IAAI,EAAG,QAAO;AAAA,aACT,IAAI,EAAG,QAAO;AACvB,WAAO;AAAA,EACT;AACF;AAGA,MAAM,UAAU;AAAA,EACL,SAAmB,CAAC;AAAA,EACpB,OAAiB,CAAC;AAAA;AAAA,EAG3B,IAAI,UAAkB,OAAqB;AACzC,QAAI,OAAO,MAAM,KAAK,EAAG;AACzB,UAAM,OAAO,KAAK,OAAO,SAAS;AAClC,QAAI,QAAQ,KAAK,KAAK,KAAK,IAAI,MAAM,SAAU,MAAK,OAAO,IAAI,IAAI;AAAA,SAC9D;AACH,WAAK,OAAO,KAAK,KAAK;AACtB,WAAK,KAAK,KAAK,QAAQ;AAAA,IACzB;AAAA,EACF;AAAA;AAAA,EAGA,KAAK,OAAe,UAA2B;AAC7C,UAAM,OAAO,KAAK,OAAO,SAAS;AAClC,QAAI,OAAO,KAAK,EAAE,SAAS,GAAI,QAAO;AACtC,QAAI,OAAO;AACX,aAAS,IAAI,OAAO,GAAG,KAAK,KAAK,IAAI,OAAO,OAAO,KAAK;AACtD,UAAI,WAAW,KAAK,OAAO,CAAC,IAAK,KAAK,OAAO,IAAI,IAAK,KAAK,OAAO,CAAC,IAAK,KAAK,OAAO,IAAI,EAAI,QAAO;AAAA,IACrG;AACA,WAAO;AAAA,EACT;AACF;AAGA,SAAS,iBACP,UACA,SAC6D;AAC7D,QAAM,OAAO,IAAI,UAAU;AAC3B,QAAM,QAAQ,WAAW,WAAW,cAAc,UAAU,SAAS;AACrE,SAAO,CAAC,UAAU,OAAO,WAAW;AAClC,yCAAkB,MAAM,QAAQ,QAAQ;AACxC,SAAK,IAAI,UAAU,KAAK;AACxB,UAAM,MAAM,KAAK,MAAM,MAAM;AAC7B,QAAI,WAAW,MAAM,EAAG,QAAO;AAC/B,UAAM,OAAO,KAAK,KAAK,KAAK,QAAQ;AACpC,QAAI,OAAO,EAAG,QAAO;AACrB,WAAO,UAAU,EAAE,WAAW,KAAK,KAAK,IAAI,KAAM,KAAK,OAAO,IAAI;AAAA,EACpE;AACF;AAGA,SAAS,YAAY,UAAiF;AACpG,QAAM,OAAO,iBAAiB,UAAU,KAAK;AAC7C,MAAI,QAAQ;AACZ,SAAO,CAAC,OAAO,QAAQ,aAAa,KAAK,YAAY,SAAS,OAAO,MAAM;AAC7E;AAcO,SAAS,SAAuE;AACrF,SAAO,YAAY,IAAI;AACzB;AAMO,SAAS,UAAwE;AACtF,SAAO,YAAY,KAAK;AAC1B;AA0BO,SAAS,cAA2E;AACzF,SAAO,iBAAiB,MAAM,KAAK;AACrC;AAMO,SAAS,eAA4E;AAC1F,SAAO,iBAAiB,OAAO,KAAK;AACtC;AAeO,SAAS,aAA0E;AACxF,SAAO,iBAAiB,MAAM,IAAI;AACpC;AAMO,SAAS,cAA2E;AACzF,SAAO,iBAAiB,OAAO,IAAI;AACrC;AAGA,SAAS,UAAU,UAAqG;AACtH,QAAM,OAAO,IAAI,UAAU;AAC3B,SAAO,CAAC,UAAU,OAAO,UAAU,cAAc;AAC/C,SAAK,IAAI,UAAU,KAAK;AACxB,UAAM,OAAO,KAAK,MAAM,QAAQ;AAChC,UAAM,QAAQ,KAAK,MAAM,SAAS;AAClC,QAAI,EAAE,YAAY,OAAO,OAAQ,QAAO;AACxC,UAAM,OAAO,KAAK,KAAK,OAAO,QAAQ,GAAG,QAAQ;AACjD,WAAO,QAAQ,KAAK,KAAK,KAAK,IAAI,MAAM,WAAW,QAAQ,KAAK,OAAO,IAAI,IAAK;AAAA,EAClF;AACF;AAuBO,SAAS,YAA8F;AAC5G,SAAO,UAAU,KAAK;AACxB;AAMO,SAAS,WAA6F;AAC3G,SAAO,UAAU,IAAI;AACvB;AAoBO,SAAS,SAAuF;AACrG,MAAI,OAAiB,CAAC;AACtB,SAAO,CAAC,UAAU,OAAO,QAAQ,SAAS,MAAM;AAC9C,UAAM,MAAM,KAAK,MAAM,MAAM;AAC7B,QAAI,KAAK,WAAW,MAAM,EAAG,QAAO,IAAI,MAAc,MAAM,CAAC,EAAE,KAAK,CAAC;AACrE,SAAK,YAAY,MAAM,EAAE,IAAI;AAC7B,QAAI,WAAW,MAAM,EAAG,QAAO;AAC/B,UAAM,SAAS,MAAM,KAAK,EAAE,QAAQ,IAAI,GAAG,CAAC,GAAG,MAAM,MAAM,WAAW,MAAM,IAAI,MAAM,MAAM,EAAE,CAAE;AAChG,eAAO,UAAAA,QAAa,QAAQ,KAAK,MAAM,EAAE,MAAM,CAAC;AAAA,EAClD;AACF;AAOA,SAAS,YACP,MACA,SACuE;AACvE,QAAM,UAAU,IAAI,8BAAW;AAC/B,QAAM,YAAY,IAAI,8BAAW;AACjC,MAAI,UAAU;AACd,MAAI,UAAU;AACd,SAAO,CAAC,UAAU,OAAO,WAAW;AAClC,UAAM,MAAM,KAAK,MAAM,MAAM;AAC7B,QAAI,EAAE,OAAO,GAAI,OAAM,IAAI,MAAM,YAAY,IAAI,oCAAoC,MAAM,GAAG;AAC9F,
|
|
4
|
+
"sourcesContent": ["/**\n * @fileoverview Per-call history of ta.* functions called in a conditional block.\n *\n * In PineScript, every ta.* call keeps its own history of the values it receives. A call inside\n * an `if` block receives values only on the bars where the block runs, so its history skips the\n * other bars: `ta.crossover(a, b)` is false on the first bar the block runs, and `ta.sma(x, 3)`\n * averages the last 3 values it received, not the last 3 bars.\n *\n * - {@link whenCalled}: vectorized, when the bars of the calls are known in advance.\n * - {@link crossover} / {@link crossunder} / {@link cross} / {@link barssince}: one stateful call site for bar\n * loops, called only on the bars where the Pine call runs.\n * - {@link lowestByBar} / {@link highestByBar} / {@link lowestbars} / {@link highestbars} / {@link pivothigh} /\n * {@link pivotlow}: `ta.lowest` / `ta.highest` / `ta.lowestbars` / `ta.highestbars` / `ta.pivothigh` /\n * `ta.pivotlow` in a conditional block or a loop, also with a length that changes on each call. They keep the\n * non-na values of their calls; {@link lowest} / {@link highest} are the same sites called with `(value, length)`.\n * - {@link linreg}: `ta.linreg` in a conditional block, whose history is kept by bar (not by call).\n * - {@link sum} / {@link sma}: `math.sum` / `ta.sma` in a `for` / `while` loop, called several times on one bar.\n *\n * Since PineScript v6, `and` / `or` are lazy: the right operand runs only when the left operand does not decide\n * the result. A ta.* call in the right operand of `a or b` runs on the bars where `a` is false, in `a and b` on the\n * bars where `a` is true, so it needs a call site too:\n *\n * ```typescript\n * // Pine: longCond = longUp or (src > sig and ta.barssince(longUp) <= lookback)\n * const since = callsite.whenCalled(longUp.map((u, i) => !u && src[i] > sig[i]), (c) => taCore.barssince(c.map(Boolean)), longUp);\n * // ta.barssince(longUp) only runs where longUp is false: it never sees true and stays na\n * ```\n *\n * ```typescript\n * // Pine: if inRange\n * // buy = ta.crossover(cumRsi, 60)\n * const buy = callsite.whenCalled(inRange, (a) => taCore.crossover(a, a.map(() => 60)), cumRsi);\n *\n * // Same call in a bar loop\n * const buyCross = callsite.crossover();\n * for (let i = 0; i < n; i++) {\n * if (inRange[i]) {\n * const buy = buyCross(cumRsi[i], 60);\n * }\n * }\n * ```\n *\n * @module callsite\n */\n\nimport type { Source } from '../types/index.js';\nimport { linreg as linregSeries } from '../ta/index.js';\nimport { RunningSum, isNa } from '../ta/running-sum.js';\nimport { checkSumLength, checkWindowLength } from '../ta/limits.js';\nimport { seededRandom } from '../math/index.js';\n\n/**\n * Runs `fn` on the bars where `called` is true only, like a ta.* call inside an `if` block.\n * `fn` receives the values of `sources` on those bars, in order; its results are placed back on\n * the same bars. The other bars get na (NaN).\n *\n * @param called - true (or non-zero) on the bars where the call runs\n * @param fn - the calculation, for example `(x) => taCore.sma(x, 3)`\n * @param sources - the arguments of the call, one value per chart bar\n */\nexport function whenCalled<T extends number | boolean>(\n called: ArrayLike<boolean | number>,\n fn: (...values: number[][]) => ArrayLike<T>,\n ...sources: Source[]\n): Array<T | number> {\n const bars: number[] = [];\n for (let i = 0; i < called.length; i++) if (called[i]) bars.push(i);\n const result = fn(...sources.map(s => bars.map(i => s[i] ?? NaN)));\n const out = new Array<T | number>(called.length).fill(NaN);\n bars.forEach((bar, k) => {\n out[bar] = result[k]!;\n });\n return out;\n}\n\n/**\n * A call site that keeps the arguments of the last call where both were not na (na before such a call), as\n * ta.crossover / ta.crossunder / ta.cross.\n */\nfunction twoSeriesSite(test: (a: number, b: number, prevA: number, prevB: number) => boolean) {\n let prevA = NaN;\n let prevB = NaN;\n return (a: number, b: number): boolean => {\n const result = test(a, b, prevA, prevB);\n if (!Number.isNaN(a) && !Number.isNaN(b)) {\n prevA = a;\n prevB = b;\n }\n return result;\n };\n}\n\n/**\n * One `ta.crossover(a, b)` call site: compared with the last call where both arguments were not na; false before\n * such a call.\n */\nexport function crossover(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => a > b && pa <= pb);\n}\n\n/**\n * One `ta.crossunder(a, b)` call site: compared with the last call where both arguments were not na; false before\n * such a call.\n */\nexport function crossunder(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => a < b && pa >= pb);\n}\n\n/**\n * One `ta.barssince(condition)` call site: the number of calls since the condition was true on a call (0 on that\n * call), na before the first true condition. An na condition counts as false.\n */\nexport function barssince(): (condition: boolean | number) => number {\n let count = NaN;\n return (condition) => {\n if (condition && !Number.isNaN(condition)) count = 0;\n else if (!Number.isNaN(count)) count++;\n return count;\n };\n}\n\n/**\n * One `ta.cross(a, b)` call site, rules of `ta.cross`: the site keeps the side of the last call where `a` was\n * strictly above or strictly below `b` (none before such a call; equal values and na arguments do not change it),\n * and is true when the arguments are strictly on the other side. False with an na argument.\n */\nexport function cross(): (a: number, b: number) => boolean {\n let side = 0; // -1: last strictly below, 1: last strictly above, 0: none yet\n return (a, b) => {\n if (Number.isNaN(a) || Number.isNaN(b)) return false;\n const result = (side < 0 && a > b) || (side > 0 && a < b);\n if (a < b) side = -1;\n else if (a > b) side = 1;\n return result;\n };\n}\n\n/** The values a ta.highest / ta.lowest / ta.pivothigh call site keeps: the non-na values of its calls, one per bar. */\nclass KeptCalls {\n readonly values: number[] = [];\n readonly bars: number[] = [];\n\n /** Keeps a non-na value; a later call on the same bar (a loop) replaces the value of that bar. */\n add(barIndex: number, value: number): void {\n if (Number.isNaN(value)) return;\n const last = this.values.length - 1;\n if (last >= 0 && this.bars[last] === barIndex) this.values[last] = value;\n else {\n this.values.push(value);\n this.bars.push(barIndex);\n }\n }\n\n /** Position of the best of the last `count` kept values (the newest one on ties), -1 when there is none. */\n best(count: number, isLowest: boolean): number {\n const last = this.values.length - 1;\n if (last < 0 || !(count >= 1)) return -1;\n let best = last;\n for (let k = last - 1; k >= 0 && k > last - count; k--) {\n if (isLowest ? this.values[k]! < this.values[best]! : this.values[k]! > this.values[best]!) best = k;\n }\n return best;\n }\n}\n\n/** One `ta.lowest` / `ta.highest` / `ta.lowestbars` / `ta.highestbars` call site; rules in {@link lowestByBar}. */\nfunction extremeByBarSite(\n isLowest: boolean,\n offsets: boolean\n): (barIndex: number, value: number, length: number) => number {\n const kept = new KeptCalls();\n const name = (isLowest ? 'lowest' : 'highest') + (offsets ? 'bars' : '');\n return (barIndex, value, length) => {\n checkWindowLength(name, length, barIndex);\n kept.add(barIndex, value);\n const len = Math.trunc(length);\n if (barIndex < len - 1) return NaN;\n const best = kept.best(len, isLowest);\n if (best < 0) return NaN;\n return offsets ? -(barIndex - kept.bars[best]!) : kept.values[best]!;\n };\n}\n\n/** {@link extremeByBarSite} called with `(value, length, barIndex?)`: without a bar index, every call is a new bar. */\nfunction extremeSite(isLowest: boolean): (value: number, length: number, barIndex?: number) => number {\n const site = extremeByBarSite(isLowest, false);\n let calls = 0;\n return (value, length, barIndex) => site(barIndex ?? calls++, value, length);\n}\n\n/**\n * One `ta.lowest(source, length)` call site, called with `(value, length, barIndex?)`: the same site as\n * {@link lowestByBar} (same rules). Pass the bar index when the call does not run on every bar; without it every\n * call counts as one bar, which is right for a call on every bar (for example with a length that changes).\n *\n * @example\n * ```typescript\n * // Pine: lowPrice = ta.lowest(close[1], lookback) // lookback changes per bar\n * const lowPrice = callsite.lowest();\n * const out = closes.map((_, i) => lowPrice(i > 0 ? closes[i - 1]! : NaN, lookback[i]!));\n * ```\n */\nexport function lowest(): (value: number, length: number, barIndex?: number) => number {\n return extremeSite(true);\n}\n\n/**\n * One `ta.highest(source, length)` call site, called with `(value, length, barIndex?)`. Same rules as\n * {@link lowest}.\n */\nexport function highest(): (value: number, length: number, barIndex?: number) => number {\n return extremeSite(false);\n}\n\n/**\n * One `ta.lowest(source, length)` call site in a conditional block or a loop, called with\n * `(barIndex, value, length)` on the bars (and loop turns) where the Pine call runs. The length can change from one\n * call to the next.\n *\n * PineScript rules (measured in `if` blocks, ternaries, user functions and `for` loops, with constant lengths and\n * lengths that change, on sources with and without na):\n * - the call site keeps the non-na values it received, each with its bar; nothing is kept for a bar without a call\n * or for an na value\n * - the result is na while `barIndex < length - 1` (by bar, not by call) and while no value was received\n * - otherwise it is the lowest of the last `length` kept values, or of all of them when there are fewer: the first\n * call after bar `length - 1` gives its own value. A call with an na value also gives this result\n * - in a loop (several calls on one bar), a bar has one kept value: each call replaces the value of the earlier\n * calls of that bar, so a call gives the lowest of its value and the values of the bars before\n *\n * Called on every bar, it equals `ta.lowest`.\n *\n * @example\n * ```typescript\n * // Pine: lo = cond ? ta.lowest(low, 6) : na\n * const site = callsite.lowestByBar();\n * const lo = lows.map((v, i) => (cond[i] ? site(i, v, 6) : NaN));\n * ```\n */\nexport function lowestByBar(): (barIndex: number, value: number, length: number) => number {\n return extremeByBarSite(true, false);\n}\n\n/**\n * One `ta.highest(source, length)` call site in a conditional block or a loop, called with\n * `(barIndex, value, length)`. Same rules as {@link lowestByBar}.\n */\nexport function highestByBar(): (barIndex: number, value: number, length: number) => number {\n return extremeByBarSite(false, false);\n}\n\n/**\n * One `ta.lowestbars(source, length)` call site in a conditional block or a loop, called with\n * `(barIndex, value, length)`: the offset (0 or negative) from this bar to the bar of the lowest of the last `length`\n * kept values, the newest one on equal values. The values are kept as in {@link lowestByBar}; the offset counts\n * bars, not calls, so it can be below `-(length - 1)`.\n *\n * @example\n * ```typescript\n * // Pine: off = cond ? ta.lowestbars(low, 10) : na\n * const site = callsite.lowestbars();\n * const off = lows.map((v, i) => (cond[i] ? site(i, v, 10) : NaN));\n * ```\n */\nexport function lowestbars(): (barIndex: number, value: number, length: number) => number {\n return extremeByBarSite(true, true);\n}\n\n/**\n * One `ta.highestbars(source, length)` call site in a conditional block or a loop, called with\n * `(barIndex, value, length)`. Same rules as {@link lowestbars}.\n */\nexport function highestbars(): (barIndex: number, value: number, length: number) => number {\n return extremeByBarSite(false, true);\n}\n\n/** One `ta.pivothigh` / `ta.pivotlow` call site; rules in {@link pivothigh}. */\nfunction pivotSite(isLowest: boolean): (barIndex: number, value: number, leftbars: number, rightbars: number) => number {\n const kept = new KeptCalls();\n return (barIndex, value, leftbars, rightbars) => {\n kept.add(barIndex, value);\n const left = Math.trunc(leftbars);\n const right = Math.trunc(rightbars);\n if (!(barIndex >= left + right)) return NaN;\n const best = kept.best(left + right + 1, isLowest);\n return best >= 0 && kept.bars[best] === barIndex - right ? kept.values[best]! : NaN;\n };\n}\n\n/**\n * One `ta.pivothigh(source, leftbars, rightbars)` call site in a conditional block, called with\n * `(barIndex, value, leftbars, rightbars)` on the bars where the Pine call runs. The lengths can change from one call\n * to the next (the lengths of the current call are used).\n *\n * PineScript rules (measured in `if` blocks and ternaries, and on sources with na):\n * - the call site keeps the non-na values it received, each with its bar\n * - on a call it takes the last `leftbars + rightbars + 1` kept values (all of them when there are fewer) and finds\n * the highest, the newest one on equal values\n * - there is a pivot only when that value is on the bar `rightbars` BARS back (by bar index, not by call); the\n * result is its value, na otherwise and before bar `leftbars + rightbars`\n *\n * Called on every bar, it equals `ta.pivothigh`.\n *\n * @example\n * ```typescript\n * // Pine: ph = useFilter ? ta.pivothigh(src, 5, 5) : na\n * const site = callsite.pivothigh();\n * const ph = src.map((v, i) => (useFilter[i] ? site(i, v, 5, 5) : NaN));\n * ```\n */\nexport function pivothigh(): (barIndex: number, value: number, leftbars: number, rightbars: number) => number {\n return pivotSite(false);\n}\n\n/**\n * One `ta.pivotlow(source, leftbars, rightbars)` call site in a conditional block, called with\n * `(barIndex, value, leftbars, rightbars)`. Same rules as {@link pivothigh} (the lowest value).\n */\nexport function pivotlow(): (barIndex: number, value: number, leftbars: number, rightbars: number) => number {\n return pivotSite(true);\n}\n\n/**\n * One `ta.linreg(source, length, offset)` call site in a conditional block, called with\n * `(barIndex, value, length, offset)` on the bars where the Pine call runs.\n *\n * PineScript rules (measured): `ta.linreg` keeps the values it receives in a ring of `length + 1` slots indexed by the\n * bar index, filled with 0 at the start and written only on the bars where it is called. The window is read from the\n * ring for the last `length` bars: a bar before the first call counts as 0, and a bar without a call holds the value of\n * the call `length + 1` bars earlier (0 if there was none). The result is na before bar `length - 1`. Called on every\n * bar, it equals `ta.linreg`.\n *\n * @example\n * ```typescript\n * // Pine: if bar_index >= 20\n * // a := ta.linreg(close, 10, 0)\n * const site = callsite.linreg();\n * const a = closes.map((c, i) => (i >= 20 ? site(i, c, 10, 0) : NaN));\n * ```\n */\nexport function linreg(): (barIndex: number, value: number, length: number, offset?: number) => number {\n let ring: number[] = [];\n return (barIndex, value, length, offset = 0) => {\n const len = Math.floor(length);\n if (ring.length !== len + 1) ring = new Array<number>(len + 1).fill(0);\n ring[barIndex % (len + 1)] = value;\n if (barIndex < len - 1) return NaN;\n const window = Array.from({ length: len }, (_, k) => ring[(barIndex - len + 1 + k) % (len + 1)]!);\n return linregSeries(window, len, offset)[len - 1]!;\n };\n}\n\n\n/**\n * One `math.sum` call site in a loop; rules in {@link sum}. With `squares`, it also keeps the running sum of the\n * squared values (for {@link stdev}). Returns `[sum, sumOfSquares]` (NaN when not kept).\n */\nfunction loopSumSite(\n name: string,\n squares: boolean\n): (barIndex: number, value: number, length: number) => [number, number] {\n const running = new RunningSum();\n const runningSq = new RunningSum();\n let lastBar = NaN;\n let pending = false;\n return (barIndex, value, length) => {\n const len = Math.floor(length);\n checkSumLength(name === 'sum' ? 'math.sum' : `ta.${name}`, len, barIndex);\n if (!(len >= 1)) throw new Error(`callsite.${name}: length must be at least 1 (got ${length})`);\n if (barIndex !== lastBar) {\n if (pending) {\n running.commit();\n if (squares) runningSq.commit();\n }\n pending = false;\n lastBar = barIndex;\n }\n if (isNa(value)) {\n pending = false;\n return [running.stepNa(len), squares ? runningSq.stepNa(len) : NaN];\n }\n const x = value;\n const out: [number, number] = [running.step(x, len), squares ? runningSq.step(x * x, len) : NaN];\n pending = true;\n return out;\n };\n}\n\n/**\n * One `math.sum(source, length)` call site inside a `for` / `while` loop, called with `(barIndex, value, length)` on\n * each call.\n *\n * PineScript rules (measured on calls in loops, 1 to 3 calls per bar, and bars without a call):\n * - the call site keeps one history value per bar: the value of its last call on that bar\n * - every call on a bar starts from the state of the earlier bars, so it gives the sum of its value and the last\n * `length - 1` kept values; the last call of the bar is the one kept for the later bars\n * - the length can change from one call to the next (also on the same bar): each call first moves the kept sum to\n * its own length as `math.sum` with a series length does (Kahan steps of the raw values)\n * - a bar without a call is not in the history (as a call in an `if` block)\n * - the sum is the same compensated running sum as `math.sum` (bit for bit)\n *\n * An na value is skipped as in `math.sum` (it returns the sum of the last `length` earlier values); when it is the\n * last call of a bar, the bar is not in the history (not measured).\n *\n * @example\n * ```typescript\n * // Pine: for i = 0 to 2\n * // s = math.sum(close * (1 + 0.01 * i), 7)\n * const site = callsite.sum();\n * for (let b = 0; b < closes.length; b++) {\n * for (let i = 0; i <= 2; i++) {\n * const s = site(b, closes[b]! * (1 + 0.01 * i), 7);\n * }\n * }\n * ```\n */\nexport function sum(): (barIndex: number, value: number, length: number) => number {\n const site = loopSumSite('sum', false);\n return (barIndex, value, length) => site(barIndex, value, length)[0];\n}\n\n/**\n * One `ta.sma(source, length)` call site inside a `for` / `while` loop, called with `(barIndex, value, length)` on\n * each call: {@link sum} divided by the length (same rules).\n *\n * @example\n * ```typescript\n * // Pine: evaluate(ratio) => ta.sma(gann(ratio), n) // called once per ratio in a while loop\n * const site = callsite.sma();\n * for (let b = 0; b < closes.length; b++) {\n * for (const ratio of ratios) {\n * const avg = site(b, gann(b, ratio), n);\n * }\n * }\n * ```\n */\nexport function sma(): (barIndex: number, value: number, length: number) => number {\n const site = loopSumSite('sma', false);\n return (barIndex, value, length) => site(barIndex, value, length)[0] / Math.floor(length);\n}\n\n/**\n * One `ta.stdev(source, length, biased)` call site inside a `for` / `while` loop, called with\n * `(barIndex, value, length, biased?)` on each call: the running sums of the values and of their squares follow the\n * rules of {@link sum}; the result is computed from them as `ta.stdev` (bit for bit).\n *\n * @example\n * ```typescript\n * // Pine: for len in lengths\n * // [mid, up, lo] = ta.bb(close, len, 2)\n * const avgSite = callsite.sma();\n * const devSite = callsite.stdev();\n * for (let b = 0; b < closes.length; b++) {\n * for (const len of lengths) {\n * const mid = avgSite(b, closes[b]!, len);\n * const dev = devSite(b, closes[b]!, len);\n * }\n * }\n * ```\n */\nexport function stdev(): (barIndex: number, value: number, length: number, biased?: boolean) => number {\n const site = loopSumSite('stdev', true);\n return (barIndex, value, length, biased = true) => {\n const len = Math.floor(length);\n const [s, sq] = site(barIndex, value, length);\n const mean = s / len;\n const variance = biased ? sq / len - mean * mean : sq / (len - 1) - (mean * s) / (len - 1);\n if (!biased && len <= 1) return NaN;\n return Number.isNaN(variance) ? NaN : variance > 0 ? Math.sqrt(variance) : 0;\n };\n}\n\n/**\n * One `math.random(min, max, seed)` call site: PineScript keeps one generator per call site, so two call sites\n * with the same seed give the same sequence. Called with `(min?, max?)` once per bar.\n *\n * @example\n * ```typescript\n * // Pine: a = math.random(0, 1, 42), b = math.random(0, 1, 42) // a == b on every bar\n * const a = callsite.random(42);\n * const b = callsite.random(42);\n * ```\n */\nexport function random(seed: number): (min?: number, max?: number) => number {\n return seededRandom(seed);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["linregSeries"]
|
|
7
7
|
}
|
|
@@ -36,8 +36,9 @@
|
|
|
36
36
|
* - polylines on the last bar: the `P` carried from the bar before is counted twice (the first creation adds it once
|
|
37
37
|
* more, unless it sets `P` to 0), later creations do not set `P` to 0, and the polylines of the bars before that a
|
|
38
38
|
* cut deletes are added to `P`. Once none is
|
|
39
|
-
* left,
|
|
40
|
-
*
|
|
39
|
+
* left, `P` is at least the number of polylines of the bars before deleted on the last bar (by the count or by
|
|
40
|
+
* the script) and a cut deletes polylines of the last bar: a script that deletes its 100 polylines and creates 200
|
|
41
|
+
* on the last bar keeps them all (#176). Equal to PineScript for the polylines alive at the end on 271 of
|
|
41
42
|
* 281 probe runs; the count inside the bar can differ when the script deletes polylines of the last bar
|
|
42
43
|
*
|
|
43
44
|
* - a bar index (`xloc.bar_index`) more than 10,000 bars before the current bar stops the script (runtime error
|
|
@@ -89,19 +90,27 @@ export interface DrawingVariable<T extends object> {
|
|
|
89
90
|
export declare function varDrawing<T extends object>(initial?: T): DrawingVariable<T>;
|
|
90
91
|
/** Largest distance, in bars, of a bar index before the current bar (PineScript runtime error RE10026 above it). */
|
|
91
92
|
export declare const MAX_DRAWING_BARS_BACK = 10000;
|
|
93
|
+
/** Largest distance, in bars, of a bar index after the last bar of the data (PineScript runtime error RE10020 above it). */
|
|
94
|
+
export declare const MAX_DRAWING_BARS_FORWARD = 500;
|
|
92
95
|
/**
|
|
93
96
|
* Tells the drawing functions which bar is being calculated (`bar_index`), so that a bar index more than 10,000
|
|
94
97
|
* bars back throws as in PineScript; `null` turns the check off. `eachBar` of the script API calls it.
|
|
95
98
|
*
|
|
96
99
|
* The bar also dates the objects held by a `var` variable (protected from the next bar on). `last` says that it is
|
|
97
|
-
* the last bar of the data, which has rules of its own for the maximum count.
|
|
100
|
+
* the last bar of the data, which has rules of its own for the maximum count. `lastIndex` is the bar index of the
|
|
101
|
+
* last bar of the data (PineScript `last_bar_index`): with it, a bar index more than 500 bars after it throws, also
|
|
102
|
+
* on the bars before the last one (RE10020).
|
|
98
103
|
*/
|
|
99
|
-
export declare function setDrawingBar(barIndex: number | null, last?: boolean): void;
|
|
104
|
+
export declare function setDrawingBar(barIndex: number | null, last?: boolean, lastIndex?: number): void;
|
|
100
105
|
/**
|
|
101
|
-
* Throws the PineScript runtime error RE10026 when `x` is a bar index more than 10,000 bars before the current bar
|
|
106
|
+
* Throws the PineScript runtime error RE10026 when `x` is a bar index more than 10,000 bars before the current bar,
|
|
107
|
+
* and RE10020 when it is more than 500 bars after the last bar of the data (when {@link setDrawingBar} knows it).
|
|
102
108
|
* `method` and `variable` are the names of the PineScript message ("line.new", "x1").
|
|
109
|
+
*
|
|
110
|
+
* Returns `x`, truncated when it is a bar index: PineScript's x is an int (a box from 5537.94 starts on bar 5537,
|
|
111
|
+
* #176).
|
|
103
112
|
*/
|
|
104
|
-
export declare function checkBarIndex(method: string, variable: string, x: number, xloc: string | undefined):
|
|
113
|
+
export declare function checkBarIndex(method: string, variable: string, x: number, xloc: string | undefined): number;
|
|
105
114
|
/** Records a new object and deletes the oldest objects of its kind when the count is too high. */
|
|
106
115
|
export declare function register<K extends DrawingKind>(kind: K, obj: DrawingTypes[K]): DrawingTypes[K];
|
|
107
116
|
/** Deletes an object (no effect when it is already deleted). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/drawing/registry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/drawing/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAErF,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvF,UAAU,YAAY;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,+FAA+F;AAC/F,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAIpC,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,UAAU,GAAG,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAkChG;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAOvD;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAKnE;AAgBD,kEAAkE;AAClE,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,MAAM;IAC/C,8FAA8F;IAC9F,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;CACtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAY5E;AAED,oHAAoH;AACpH,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAC3C,4HAA4H;AAC5H,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAwB5C;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,GAAE,OAAe,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAetG;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAiB3G;AAuDD,kGAAkG;AAClG,wBAAgB,QAAQ,CAAC,CAAC,SAAS,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAS9F;AA8BD,gEAAgE;AAChE,wBAAgB,MAAM,CAAC,CAAC,SAAS,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CASjF;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAE/C;AAED,mEAAmE;AACnE,wBAAgB,GAAG,CAAC,CAAC,SAAS,WAAW,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAE1E;AAED,4FAA4F;AAC5F,wBAAgB,aAAa,CAAC,SAAS,GAAE,aAAkB,GAAG,IAAI,CAejE;AAED,uGAAuG;AACvG,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAE/D"}
|
|
@@ -20,6 +20,7 @@ var registry_exports = {};
|
|
|
20
20
|
__export(registry_exports, {
|
|
21
21
|
DEFAULT_MAX_COUNT: () => DEFAULT_MAX_COUNT,
|
|
22
22
|
MAX_DRAWING_BARS_BACK: () => MAX_DRAWING_BARS_BACK,
|
|
23
|
+
MAX_DRAWING_BARS_FORWARD: () => MAX_DRAWING_BARS_FORWARD,
|
|
23
24
|
all: () => all,
|
|
24
25
|
checkBarIndex: () => checkBarIndex,
|
|
25
26
|
holdDrawing: () => holdDrawing,
|
|
@@ -96,12 +97,15 @@ function varDrawing(initial) {
|
|
|
96
97
|
};
|
|
97
98
|
}
|
|
98
99
|
const MAX_DRAWING_BARS_BACK = 1e4;
|
|
100
|
+
const MAX_DRAWING_BARS_FORWARD = 500;
|
|
99
101
|
let currentBar = null;
|
|
102
|
+
let lastBarIndex = null;
|
|
100
103
|
const isAllowanceKind = (kind) => kind === "line" || kind === "label" || kind === "box";
|
|
101
104
|
let lastBar = null;
|
|
102
|
-
function setDrawingBar(barIndex, last = false) {
|
|
105
|
+
function setDrawingBar(barIndex, last = false, lastIndex) {
|
|
103
106
|
if (lastBar && !(last && barIndex === lastBar.bar)) lastBar = null;
|
|
104
107
|
currentBar = barIndex;
|
|
108
|
+
lastBarIndex = barIndex === null ? null : lastIndex ?? (last ? barIndex : null);
|
|
105
109
|
if (barIndex !== null && last && !lastBar) {
|
|
106
110
|
const start = (kind) => pending[kind] >= PENDING_RESET[kind] ? 0 : pending[kind];
|
|
107
111
|
lastBar = {
|
|
@@ -115,12 +119,20 @@ function setDrawingBar(barIndex, last = false) {
|
|
|
115
119
|
}
|
|
116
120
|
}
|
|
117
121
|
function checkBarIndex(method, variable, x, xloc) {
|
|
118
|
-
if (
|
|
122
|
+
if ((xloc ?? "bar_index") !== "bar_index") return x;
|
|
123
|
+
x = Math.trunc(x);
|
|
124
|
+
if (currentBar === null) return x;
|
|
125
|
+
if (lastBarIndex !== null && x - lastBarIndex > MAX_DRAWING_BARS_FORWARD) {
|
|
126
|
+
throw new Error(
|
|
127
|
+
`Error on bar ${currentBar}: Objects positioned using xloc.bar_index cannot be drawn further than ${MAX_DRAWING_BARS_FORWARD} bars into the future.`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
119
130
|
if (currentBar - x > MAX_DRAWING_BARS_BACK) {
|
|
120
131
|
throw new Error(
|
|
121
132
|
`Error on bar ${currentBar}: Bar index value of the \`${variable}\` argument (${x}) in \`${method}()\` is too far from the current bar index. Try using \`time\` instead.`
|
|
122
133
|
);
|
|
123
134
|
}
|
|
135
|
+
return x;
|
|
124
136
|
}
|
|
125
137
|
const COORDINATES = {
|
|
126
138
|
line: ["x1", "y1", "x2", "y2"],
|
|
@@ -186,6 +198,7 @@ function registerLast(bar, kind, obj) {
|
|
|
186
198
|
}
|
|
187
199
|
for (const old of cut) markDeleted(kind, old, true);
|
|
188
200
|
} else {
|
|
201
|
+
if (kind === "polyline" && pending.polyline < bar.oldPolylinesGone) pending.polyline = bar.oldPolylinesGone;
|
|
189
202
|
const cut = cutOldest(kind, list, obj);
|
|
190
203
|
if (kind === "polyline" && cut.length > 0) pending.polyline = bar.oldPolylinesGone;
|
|
191
204
|
for (const old of cut) markDeleted(kind, old, false);
|
|
@@ -215,6 +228,7 @@ function resetDrawings(newLimits = {}) {
|
|
|
215
228
|
heldAt = /* @__PURE__ */ new WeakMap();
|
|
216
229
|
pending = { line: 0, label: 0, box: 0, polyline: 0 };
|
|
217
230
|
currentBar = null;
|
|
231
|
+
lastBarIndex = null;
|
|
218
232
|
lastBar = null;
|
|
219
233
|
limits = {
|
|
220
234
|
line: newLimits.line ?? DEFAULT_MAX_COUNT,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/drawing/registry.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Registry of the live drawing objects (lines, labels, boxes, polylines, linefills, tables), as PineScript\n * keeps them. PineScript rules:\n *\n * - `line.all`, `label.all`, ... list the live objects in creation order (a copy of the list)\n * - `delete` removes an object; the object becomes `na`: its getters return NaN and its setters\n * do nothing. Deleting a line with `line.delete` also deletes the linefills that use it\n * - when a creation brings the count above `max_*_count + 5`, the oldest objects are deleted until\n * `max_*_count` remain (default 50). Copies count as creations. Linefills follow the same rule with\n * `max_lines_count`; lines deleted by this rule do not delete their linefills\n * - the object that was just created is never deleted by this rule\n * - an object that a `var` variable of the drawing type refers to is never deleted by this rule, and it still counts\n * (measured for lines, labels and boxes: with 9 held boxes and a maximum of 50, 9 held + 46 others stay; with 8\n * held lines and a maximum of 5, the 8 and the newest line stay). The protection starts on the bar after the\n * assignment: 12 `var` lines created on the first bar with a maximum of 5 lose the first 6. Only\n * the variable itself protects: an object in a `var` array, in a field of a user type or in a variable that got\n * another object or `na` later is deleted like any other. JavaScript has no `var` declaration to observe, so the\n * script says it: {@link varDrawing} (a variable), or {@link holdDrawing} / {@link releaseDrawing}\n * - linefills have the limit of `max_lines_count` with another rule for the held ones (measured on one script, two\n * long runs): a fill is skipped when a `var` variable holds it or released it less than 5,000 bars ago (the bar\n * of {@link setDrawingBar}); when the count is still above the maximum + 5 after that, the oldest fills are\n * deleted until the maximum remain, the held ones too\n * - the script deletes count (`line.delete`, `label.delete`, ...): each kind has a number `P` of deleted objects. A\n * delete adds 1; a creation first sets `P` to 0 when it is 5 or more (3 or more for polylines)\n * - polylines use `P` on every bar: a creation cuts when the count is above `max_polylines_count + 5 + P`, down to\n * the maximum + `P`, and the polylines of the cut are added to `P`. A script that deletes and creates one polyline\n * per bar therefore sees the cut 0, 1 or 2 bars late\n * - lines, labels and boxes use `P` on the last bar only, with its value at the start of that bar: there the cut is\n * above the maximum + 5 + `P`, down to the maximum + `P` (up to 4 more objects)\n * - the last bar has rules of its own (measured from the count after each creation, on a closed and on an open last\n * bar): a cut deletes the objects of the bars before first, at most those (a line takes its linefills with it);\n * once none is left, a cut deletes objects of the last bar as on any bar. With 10 lines and a maximum of 10, 13\n * lines on the last bar leave these 13: the cut at the 16th line deletes the 10 old ones only. Lines, labels and\n * boxes: equal to PineScript, count after every operation and objects alive at the end, on 72 of 72 runs checked\n * after the rule was written (and 218 of 218 end states before)\n * - polylines on the last bar: the `P` carried from the bar before is counted twice (the first creation adds it once\n * more, unless it sets `P` to 0), later creations do not set `P` to 0, and the polylines of the bars before that a\n * cut deletes are added to `P`. Once none is\n * left, a cut deletes polylines of the last bar and `P` becomes the number of polylines of the bars before deleted\n * on the last bar (by the count or by the script). Equal to PineScript for the polylines alive at the end on 271 of\n * 281 probe runs; the count inside the bar can differ when the script deletes polylines of the last bar\n *\n * - a bar index (`xloc.bar_index`) more than 10,000 bars before the current bar stops the script (runtime error\n * RE10026) in `line.new`, `box.new`, `label.new`, `polyline.new` and the setters of x. The current bar is the one\n * of `eachBar` in a script run; a port with its own bar loop gives it with {@link setDrawingBar}\n *\n * The script API (`executeScript`) resets the registry at the start of every run and applies the\n * `max_*_count` values of `indicator()`. Outside a script run the registry is global to the module.\n *\n * @module drawing/registry\n */\n\nimport type { Box, Label, Line, Linefill, Polyline, Table } from '../types/index.js';\n\nexport type DrawingKind = 'line' | 'label' | 'box' | 'polyline' | 'linefill' | 'table';\n\ninterface DrawingTypes {\n line: Line;\n label: Label;\n box: Box;\n polyline: Polyline;\n linefill: Linefill;\n table: Table;\n}\n\n/** Default `max_lines_count`, `max_labels_count`, `max_boxes_count`, `max_polylines_count`. */\nexport const DEFAULT_MAX_COUNT = 50;\n/** Objects above the maximum that PineScript keeps before it deletes the oldest ones. */\nconst SLACK = 5;\n\nexport type DrawingLimits = Partial<Record<Exclude<DrawingKind, 'linefill' | 'table'>, number>>;\n\nconst live: { [K in DrawingKind]: Array<DrawingTypes[K]> } = {\n line: [],\n label: [],\n box: [],\n polyline: [],\n linefill: [],\n table: [],\n};\nlet limits: Required<DrawingLimits> = {\n line: DEFAULT_MAX_COUNT,\n label: DEFAULT_MAX_COUNT,\n box: DEFAULT_MAX_COUNT,\n polyline: DEFAULT_MAX_COUNT,\n};\nconst deleted = new WeakSet<object>();\n/** Objects held by a `var` variable, with the number of variables that hold them. */\nlet held = new WeakMap<object, number>();\n/** Bar on which the last `var` variable released an object (linefill rule). */\nlet releasedAt = new WeakMap<object, number>();\n/** Bars during which a released linefill is still skipped by the maximum count. */\nconst LINEFILL_RELEASE_BARS = 5000;\n/** Bar on which a `var` variable got an object: the maximum count skips it from the next bar on. */\nlet heldAt = new WeakMap<object, number>();\n/** Kinds with a maximum count of their own. */\ntype CountedKind = 'line' | 'label' | 'box' | 'polyline';\nconst COUNTED_KINDS: readonly CountedKind[] = ['line', 'label', 'box', 'polyline'];\nconst isCounted = (kind: DrawingKind): kind is CountedKind => (COUNTED_KINDS as readonly DrawingKind[]).includes(kind);\n/** `P` of the module notes: objects deleted by the script (for polylines also by the maximum count). */\nlet pending: Record<CountedKind, number> = { line: 0, label: 0, box: 0, polyline: 0 };\n/** A creation sets `P` to 0 from this value on. */\nconst PENDING_RESET: Record<CountedKind, number> = { line: 5, label: 5, box: 5, polyline: 3 };\n\n/**\n * Marks an object as held by a `var` variable (PineScript `var line l = ...` or `l := line.new(...)` on a `var`\n * variable): the maximum count never deletes it, and it still counts. Returns the object.\n */\nexport function holdDrawing<T extends object>(obj: T): T {\n if (!held.has(obj)) {\n if (currentBar === null) heldAt.delete(obj);\n else heldAt.set(obj, currentBar);\n }\n held.set(obj, (held.get(obj) ?? 0) + 1);\n return obj;\n}\n\n/** The `var` variable no longer refers to the object (it got another object or `na`). */\nexport function releaseDrawing(obj: object | null | undefined): void {\n if (!obj) return;\n const count = held.get(obj) ?? 0;\n if (count > 1) held.set(obj, count - 1);\n else if (held.delete(obj) && currentBar !== null) releasedAt.set(obj, currentBar);\n}\n\n/** Held by a `var` variable since a bar before the current one (or outside a bar loop). */\nfunction heldBefore(obj: object): boolean {\n if (!held.has(obj)) return false;\n const bar = heldAt.get(obj);\n return bar === undefined || currentBar === null || bar < currentBar;\n}\n\n/** Linefill rule: held, or released less than 5,000 bars ago. */\nfunction fillProtected(obj: object): boolean {\n if (held.has(obj)) return true;\n const bar = releasedAt.get(obj);\n return bar !== undefined && currentBar !== null && currentBar - bar < LINEFILL_RELEASE_BARS;\n}\n\n/** A `var` variable of a drawing type: see {@link varDrawing}. */\nexport interface DrawingVariable<T extends object> {\n /** The object of the variable; setting it holds the new object and releases the one before */\n value: T | undefined;\n}\n\n/**\n * A PineScript `var` variable of a drawing type (`var line l = na`). The object it refers to is not deleted by the\n * maximum count; assigning another object (or `undefined` for `na`) releases the one before.\n *\n * @example\n * ```typescript\n * // Pine: var line level = na\n * // level := line.new(bar_index, close, bar_index + 1, close)\n * const level = varDrawing<Line>();\n * level.value = line.new(i, close, i + 1, close);\n * ```\n */\nexport function varDrawing<T extends object>(initial?: T): DrawingVariable<T> {\n let current: T | undefined = initial ? holdDrawing(initial) : undefined;\n return {\n get value() {\n return current;\n },\n set value(next: T | undefined) {\n if (next === current) return;\n releaseDrawing(current);\n current = next ? holdDrawing(next) : undefined;\n },\n };\n}\n\n/** Largest distance, in bars, of a bar index before the current bar (PineScript runtime error RE10026 above it). */\nexport const MAX_DRAWING_BARS_BACK = 10000;\nlet currentBar: number | null = null;\n\n/** Kinds whose allowance on the last bar is the `P` they had when the bar started. */\ntype AllowanceKind = 'line' | 'label' | 'box';\nconst isAllowanceKind = (kind: DrawingKind): kind is AllowanceKind => kind === 'line' || kind === 'label' || kind === 'box';\n\n/** State of the last bar (see the module notes). */\ninterface LastBar {\n bar: number;\n /** The objects alive when the bar started (the objects of the bars before) */\n old: Set<object>;\n /** `P` of lines, labels and boxes when the bar started: their allowance for the whole bar */\n allowance: Record<AllowanceKind, number>;\n /** `P` of polylines when the bar started */\n carried: number;\n /** A polyline was created on this bar */\n polyline: boolean;\n /** Polylines of the bars before deleted on this bar (by the count or by the script) */\n oldPolylinesGone: number;\n}\nlet lastBar: LastBar | null = null;\n\n/**\n * Tells the drawing functions which bar is being calculated (`bar_index`), so that a bar index more than 10,000\n * bars back throws as in PineScript; `null` turns the check off. `eachBar` of the script API calls it.\n *\n * The bar also dates the objects held by a `var` variable (protected from the next bar on). `last` says that it is\n * the last bar of the data, which has rules of its own for the maximum count.\n */\nexport function setDrawingBar(barIndex: number | null, last: boolean = false): void {\n if (lastBar && !(last && barIndex === lastBar.bar)) lastBar = null;\n currentBar = barIndex;\n if (barIndex !== null && last && !lastBar) {\n const start = (kind: AllowanceKind): number => (pending[kind] >= PENDING_RESET[kind] ? 0 : pending[kind]);\n lastBar = {\n bar: barIndex,\n old: new Set<object>([...live.line, ...live.label, ...live.box, ...live.polyline]),\n allowance: { line: start('line'), label: start('label'), box: start('box') },\n carried: pending.polyline,\n polyline: false,\n oldPolylinesGone: 0,\n };\n }\n}\n\n/**\n * Throws the PineScript runtime error RE10026 when `x` is a bar index more than 10,000 bars before the current bar.\n * `method` and `variable` are the names of the PineScript message (\"line.new\", \"x1\").\n */\nexport function checkBarIndex(method: string, variable: string, x: number, xloc: string | undefined): void {\n if (currentBar === null || (xloc ?? 'bar_index') !== 'bar_index') return;\n if (currentBar - x > MAX_DRAWING_BARS_BACK) {\n throw new Error(\n `Error on bar ${currentBar}: Bar index value of the \\`${variable}\\` argument (${x}) in \\`${method}()\\` is too far ` +\n 'from the current bar index. Try using `time` instead.'\n );\n }\n}\n\n/** Numeric fields that become NaN when an object is deleted, so that its getters return `na`. */\nconst COORDINATES: { [K in DrawingKind]: Array<keyof DrawingTypes[K]> } = {\n line: ['x1', 'y1', 'x2', 'y2'],\n label: ['x', 'y'],\n box: ['left', 'top', 'right', 'bottom'],\n polyline: [],\n linefill: [],\n table: [],\n};\n\nfunction markDeleted<K extends DrawingKind>(kind: K, obj: DrawingTypes[K], explicit: boolean): void {\n deleted.add(obj);\n for (const field of COORDINATES[kind]) (obj as unknown as Record<string, unknown>)[field as string] = NaN;\n if (kind === 'line' && explicit) {\n for (const fill of live.linefill.filter((f) => f.line1 === obj || f.line2 === obj)) remove('linefill', fill);\n }\n}\n\n/** Objects above the maximum that the rule allows for, besides the 5: `P` of the module notes. */\nfunction allowance(kind: DrawingKind): number {\n if (kind === 'polyline') return pending.polyline;\n return lastBar && isAllowanceKind(kind) ? lastBar.allowance[kind] : 0;\n}\n\n/**\n * The maximum count after the creation of `obj`: removes the objects to delete from `list` (the oldest first; the new\n * object and an object held by a `var` variable are skipped and still count) and returns them.\n */\nfunction cutOldest<K extends DrawingKind>(\n kind: K,\n list: Array<DrawingTypes[K]>,\n obj: DrawingTypes[K],\n only?: (old: object) => boolean\n): Array<DrawingTypes[K]> {\n if (kind === 'table') return []; // tables have no maximum count\n const max = limits[kind === 'linefill' ? 'line' : (kind as keyof DrawingLimits)] + allowance(kind);\n if (list.length <= max + SLACK) return [];\n const kept: Array<DrawingTypes[K]> = [];\n const cut: Array<DrawingTypes[K]> = [];\n let excess = list.length - max;\n for (const old of list) {\n if (excess > 0 && old !== obj && (!only || only(old)) && !(kind === 'linefill' ? fillProtected(old) : heldBefore(old))) {\n excess--;\n cut.push(old);\n } else kept.push(old);\n }\n // linefills: still above the maximum + 5, the oldest go, the held ones too\n if (kind === 'linefill' && kept.length > max + SLACK) cut.push(...kept.splice(0, kept.length - max));\n list.length = 0;\n list.push(...kept);\n return cut;\n}\n\n/** Records a new object and deletes the oldest objects of its kind when the count is too high. */\nexport function register<K extends DrawingKind>(kind: K, obj: DrawingTypes[K]): DrawingTypes[K] {\n const list = live[kind];\n if (lastBar && isCounted(kind)) return registerLast(lastBar, kind, obj);\n if (isCounted(kind) && pending[kind] >= PENDING_RESET[kind]) pending[kind] = 0;\n list.push(obj);\n const cut = cutOldest(kind, list, obj);\n if (kind === 'polyline') pending.polyline += cut.length;\n for (const old of cut) markDeleted(kind, old, false);\n return obj;\n}\n\n/** An object created on the last bar (see the module notes). */\nfunction registerLast<K extends DrawingKind>(bar: LastBar, kind: K, obj: DrawingTypes[K]): DrawingTypes[K] {\n if (kind === 'polyline' && !bar.polyline) {\n bar.polyline = true;\n if (pending.polyline >= PENDING_RESET.polyline) pending.polyline = 0;\n else pending.polyline += bar.carried; // counted twice\n }\n const list = live[kind];\n list.push(obj);\n const isOld = (old: object): boolean => bar.old.has(old);\n if (list.some((old) => old !== obj && isOld(old) && !heldBefore(old))) {\n // the objects of the bars before only; a line takes its linefills with it\n const cut = cutOldest(kind, list, obj, isOld);\n if (kind === 'polyline') {\n pending.polyline += cut.length;\n bar.oldPolylinesGone += cut.length;\n }\n for (const old of cut) markDeleted(kind, old, true);\n } else {\n const cut = cutOldest(kind, list, obj);\n if (kind === 'polyline' && cut.length > 0) pending.polyline = bar.oldPolylinesGone;\n for (const old of cut) markDeleted(kind, old, false);\n }\n return obj;\n}\n\n/** Deletes an object (no effect when it is already deleted). */\nexport function remove<K extends DrawingKind>(kind: K, obj: DrawingTypes[K]): void {\n const list = live[kind];\n const index = list.indexOf(obj);\n if (index !== -1) {\n list.splice(index, 1);\n if (isCounted(kind)) pending[kind]++;\n if (kind === 'polyline' && lastBar?.old.has(obj)) lastBar.oldPolylinesGone++;\n }\n if (!deleted.has(obj)) markDeleted(kind, obj, true);\n}\n\n/** True when the object was deleted (by `delete` or by the maximum count). */\nexport function isDeleted(obj: unknown): boolean {\n return typeof obj === 'object' && obj !== null && deleted.has(obj);\n}\n\n/** The live objects of a kind, in creation order (a new array). */\nexport function all<K extends DrawingKind>(kind: K): Array<DrawingTypes[K]> {\n return [...live[kind]] as Array<DrawingTypes[K]>;\n}\n\n/** Forgets all objects (without deleting them) and sets the maximum counts (default 50). */\nexport function resetDrawings(newLimits: DrawingLimits = {}): void {\n for (const kind of Object.keys(live) as DrawingKind[]) live[kind].length = 0;\n held = new WeakMap();\n releasedAt = new WeakMap();\n heldAt = new WeakMap();\n pending = { line: 0, label: 0, box: 0, polyline: 0 };\n currentBar = null;\n lastBar = null;\n limits = {\n line: newLimits.line ?? DEFAULT_MAX_COUNT,\n label: newLimits.label ?? DEFAULT_MAX_COUNT,\n box: newLimits.box ?? DEFAULT_MAX_COUNT,\n polyline: newLimits.polyline ?? DEFAULT_MAX_COUNT,\n };\n}\n\n/** Changes the maximum counts without forgetting the objects (PineScript `indicator(max_*_count)`). */\nexport function setDrawingLimits(newLimits: DrawingLimits): void {\n limits = { ...limits, ...Object.fromEntries(Object.entries(newLimits).filter(([, v]) => v !== undefined)) };\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["/**\n * Registry of the live drawing objects (lines, labels, boxes, polylines, linefills, tables), as PineScript\n * keeps them. PineScript rules:\n *\n * - `line.all`, `label.all`, ... list the live objects in creation order (a copy of the list)\n * - `delete` removes an object; the object becomes `na`: its getters return NaN and its setters\n * do nothing. Deleting a line with `line.delete` also deletes the linefills that use it\n * - when a creation brings the count above `max_*_count + 5`, the oldest objects are deleted until\n * `max_*_count` remain (default 50). Copies count as creations. Linefills follow the same rule with\n * `max_lines_count`; lines deleted by this rule do not delete their linefills\n * - the object that was just created is never deleted by this rule\n * - an object that a `var` variable of the drawing type refers to is never deleted by this rule, and it still counts\n * (measured for lines, labels and boxes: with 9 held boxes and a maximum of 50, 9 held + 46 others stay; with 8\n * held lines and a maximum of 5, the 8 and the newest line stay). The protection starts on the bar after the\n * assignment: 12 `var` lines created on the first bar with a maximum of 5 lose the first 6. Only\n * the variable itself protects: an object in a `var` array, in a field of a user type or in a variable that got\n * another object or `na` later is deleted like any other. JavaScript has no `var` declaration to observe, so the\n * script says it: {@link varDrawing} (a variable), or {@link holdDrawing} / {@link releaseDrawing}\n * - linefills have the limit of `max_lines_count` with another rule for the held ones (measured on one script, two\n * long runs): a fill is skipped when a `var` variable holds it or released it less than 5,000 bars ago (the bar\n * of {@link setDrawingBar}); when the count is still above the maximum + 5 after that, the oldest fills are\n * deleted until the maximum remain, the held ones too\n * - the script deletes count (`line.delete`, `label.delete`, ...): each kind has a number `P` of deleted objects. A\n * delete adds 1; a creation first sets `P` to 0 when it is 5 or more (3 or more for polylines)\n * - polylines use `P` on every bar: a creation cuts when the count is above `max_polylines_count + 5 + P`, down to\n * the maximum + `P`, and the polylines of the cut are added to `P`. A script that deletes and creates one polyline\n * per bar therefore sees the cut 0, 1 or 2 bars late\n * - lines, labels and boxes use `P` on the last bar only, with its value at the start of that bar: there the cut is\n * above the maximum + 5 + `P`, down to the maximum + `P` (up to 4 more objects)\n * - the last bar has rules of its own (measured from the count after each creation, on a closed and on an open last\n * bar): a cut deletes the objects of the bars before first, at most those (a line takes its linefills with it);\n * once none is left, a cut deletes objects of the last bar as on any bar. With 10 lines and a maximum of 10, 13\n * lines on the last bar leave these 13: the cut at the 16th line deletes the 10 old ones only. Lines, labels and\n * boxes: equal to PineScript, count after every operation and objects alive at the end, on 72 of 72 runs checked\n * after the rule was written (and 218 of 218 end states before)\n * - polylines on the last bar: the `P` carried from the bar before is counted twice (the first creation adds it once\n * more, unless it sets `P` to 0), later creations do not set `P` to 0, and the polylines of the bars before that a\n * cut deletes are added to `P`. Once none is\n * left, `P` is at least the number of polylines of the bars before deleted on the last bar (by the count or by\n * the script) and a cut deletes polylines of the last bar: a script that deletes its 100 polylines and creates 200\n * on the last bar keeps them all (#176). Equal to PineScript for the polylines alive at the end on 271 of\n * 281 probe runs; the count inside the bar can differ when the script deletes polylines of the last bar\n *\n * - a bar index (`xloc.bar_index`) more than 10,000 bars before the current bar stops the script (runtime error\n * RE10026) in `line.new`, `box.new`, `label.new`, `polyline.new` and the setters of x. The current bar is the one\n * of `eachBar` in a script run; a port with its own bar loop gives it with {@link setDrawingBar}\n *\n * The script API (`executeScript`) resets the registry at the start of every run and applies the\n * `max_*_count` values of `indicator()`. Outside a script run the registry is global to the module.\n *\n * @module drawing/registry\n */\n\nimport type { Box, Label, Line, Linefill, Polyline, Table } from '../types/index.js';\n\nexport type DrawingKind = 'line' | 'label' | 'box' | 'polyline' | 'linefill' | 'table';\n\ninterface DrawingTypes {\n line: Line;\n label: Label;\n box: Box;\n polyline: Polyline;\n linefill: Linefill;\n table: Table;\n}\n\n/** Default `max_lines_count`, `max_labels_count`, `max_boxes_count`, `max_polylines_count`. */\nexport const DEFAULT_MAX_COUNT = 50;\n/** Objects above the maximum that PineScript keeps before it deletes the oldest ones. */\nconst SLACK = 5;\n\nexport type DrawingLimits = Partial<Record<Exclude<DrawingKind, 'linefill' | 'table'>, number>>;\n\nconst live: { [K in DrawingKind]: Array<DrawingTypes[K]> } = {\n line: [],\n label: [],\n box: [],\n polyline: [],\n linefill: [],\n table: [],\n};\nlet limits: Required<DrawingLimits> = {\n line: DEFAULT_MAX_COUNT,\n label: DEFAULT_MAX_COUNT,\n box: DEFAULT_MAX_COUNT,\n polyline: DEFAULT_MAX_COUNT,\n};\nconst deleted = new WeakSet<object>();\n/** Objects held by a `var` variable, with the number of variables that hold them. */\nlet held = new WeakMap<object, number>();\n/** Bar on which the last `var` variable released an object (linefill rule). */\nlet releasedAt = new WeakMap<object, number>();\n/** Bars during which a released linefill is still skipped by the maximum count. */\nconst LINEFILL_RELEASE_BARS = 5000;\n/** Bar on which a `var` variable got an object: the maximum count skips it from the next bar on. */\nlet heldAt = new WeakMap<object, number>();\n/** Kinds with a maximum count of their own. */\ntype CountedKind = 'line' | 'label' | 'box' | 'polyline';\nconst COUNTED_KINDS: readonly CountedKind[] = ['line', 'label', 'box', 'polyline'];\nconst isCounted = (kind: DrawingKind): kind is CountedKind => (COUNTED_KINDS as readonly DrawingKind[]).includes(kind);\n/** `P` of the module notes: objects deleted by the script (for polylines also by the maximum count). */\nlet pending: Record<CountedKind, number> = { line: 0, label: 0, box: 0, polyline: 0 };\n/** A creation sets `P` to 0 from this value on. */\nconst PENDING_RESET: Record<CountedKind, number> = { line: 5, label: 5, box: 5, polyline: 3 };\n\n/**\n * Marks an object as held by a `var` variable (PineScript `var line l = ...` or `l := line.new(...)` on a `var`\n * variable): the maximum count never deletes it, and it still counts. Returns the object.\n */\nexport function holdDrawing<T extends object>(obj: T): T {\n if (!held.has(obj)) {\n if (currentBar === null) heldAt.delete(obj);\n else heldAt.set(obj, currentBar);\n }\n held.set(obj, (held.get(obj) ?? 0) + 1);\n return obj;\n}\n\n/** The `var` variable no longer refers to the object (it got another object or `na`). */\nexport function releaseDrawing(obj: object | null | undefined): void {\n if (!obj) return;\n const count = held.get(obj) ?? 0;\n if (count > 1) held.set(obj, count - 1);\n else if (held.delete(obj) && currentBar !== null) releasedAt.set(obj, currentBar);\n}\n\n/** Held by a `var` variable since a bar before the current one (or outside a bar loop). */\nfunction heldBefore(obj: object): boolean {\n if (!held.has(obj)) return false;\n const bar = heldAt.get(obj);\n return bar === undefined || currentBar === null || bar < currentBar;\n}\n\n/** Linefill rule: held, or released less than 5,000 bars ago. */\nfunction fillProtected(obj: object): boolean {\n if (held.has(obj)) return true;\n const bar = releasedAt.get(obj);\n return bar !== undefined && currentBar !== null && currentBar - bar < LINEFILL_RELEASE_BARS;\n}\n\n/** A `var` variable of a drawing type: see {@link varDrawing}. */\nexport interface DrawingVariable<T extends object> {\n /** The object of the variable; setting it holds the new object and releases the one before */\n value: T | undefined;\n}\n\n/**\n * A PineScript `var` variable of a drawing type (`var line l = na`). The object it refers to is not deleted by the\n * maximum count; assigning another object (or `undefined` for `na`) releases the one before.\n *\n * @example\n * ```typescript\n * // Pine: var line level = na\n * // level := line.new(bar_index, close, bar_index + 1, close)\n * const level = varDrawing<Line>();\n * level.value = line.new(i, close, i + 1, close);\n * ```\n */\nexport function varDrawing<T extends object>(initial?: T): DrawingVariable<T> {\n let current: T | undefined = initial ? holdDrawing(initial) : undefined;\n return {\n get value() {\n return current;\n },\n set value(next: T | undefined) {\n if (next === current) return;\n releaseDrawing(current);\n current = next ? holdDrawing(next) : undefined;\n },\n };\n}\n\n/** Largest distance, in bars, of a bar index before the current bar (PineScript runtime error RE10026 above it). */\nexport const MAX_DRAWING_BARS_BACK = 10000;\n/** Largest distance, in bars, of a bar index after the last bar of the data (PineScript runtime error RE10020 above it). */\nexport const MAX_DRAWING_BARS_FORWARD = 500;\nlet currentBar: number | null = null;\nlet lastBarIndex: number | null = null;\n\n/** Kinds whose allowance on the last bar is the `P` they had when the bar started. */\ntype AllowanceKind = 'line' | 'label' | 'box';\nconst isAllowanceKind = (kind: DrawingKind): kind is AllowanceKind => kind === 'line' || kind === 'label' || kind === 'box';\n\n/** State of the last bar (see the module notes). */\ninterface LastBar {\n bar: number;\n /** The objects alive when the bar started (the objects of the bars before) */\n old: Set<object>;\n /** `P` of lines, labels and boxes when the bar started: their allowance for the whole bar */\n allowance: Record<AllowanceKind, number>;\n /** `P` of polylines when the bar started */\n carried: number;\n /** A polyline was created on this bar */\n polyline: boolean;\n /** Polylines of the bars before deleted on this bar (by the count or by the script) */\n oldPolylinesGone: number;\n}\nlet lastBar: LastBar | null = null;\n\n/**\n * Tells the drawing functions which bar is being calculated (`bar_index`), so that a bar index more than 10,000\n * bars back throws as in PineScript; `null` turns the check off. `eachBar` of the script API calls it.\n *\n * The bar also dates the objects held by a `var` variable (protected from the next bar on). `last` says that it is\n * the last bar of the data, which has rules of its own for the maximum count. `lastIndex` is the bar index of the\n * last bar of the data (PineScript `last_bar_index`): with it, a bar index more than 500 bars after it throws, also\n * on the bars before the last one (RE10020).\n */\nexport function setDrawingBar(barIndex: number | null, last: boolean = false, lastIndex?: number): void {\n if (lastBar && !(last && barIndex === lastBar.bar)) lastBar = null;\n currentBar = barIndex;\n lastBarIndex = barIndex === null ? null : (lastIndex ?? (last ? barIndex : null));\n if (barIndex !== null && last && !lastBar) {\n const start = (kind: AllowanceKind): number => (pending[kind] >= PENDING_RESET[kind] ? 0 : pending[kind]);\n lastBar = {\n bar: barIndex,\n old: new Set<object>([...live.line, ...live.label, ...live.box, ...live.polyline]),\n allowance: { line: start('line'), label: start('label'), box: start('box') },\n carried: pending.polyline,\n polyline: false,\n oldPolylinesGone: 0,\n };\n }\n}\n\n/**\n * Throws the PineScript runtime error RE10026 when `x` is a bar index more than 10,000 bars before the current bar,\n * and RE10020 when it is more than 500 bars after the last bar of the data (when {@link setDrawingBar} knows it).\n * `method` and `variable` are the names of the PineScript message (\"line.new\", \"x1\").\n *\n * Returns `x`, truncated when it is a bar index: PineScript's x is an int (a box from 5537.94 starts on bar 5537,\n * #176).\n */\nexport function checkBarIndex(method: string, variable: string, x: number, xloc: string | undefined): number {\n if ((xloc ?? 'bar_index') !== 'bar_index') return x;\n x = Math.trunc(x);\n if (currentBar === null) return x;\n if (lastBarIndex !== null && x - lastBarIndex > MAX_DRAWING_BARS_FORWARD) {\n throw new Error(\n `Error on bar ${currentBar}: Objects positioned using xloc.bar_index cannot be drawn further than ` +\n `${MAX_DRAWING_BARS_FORWARD} bars into the future.`\n );\n }\n if (currentBar - x > MAX_DRAWING_BARS_BACK) {\n throw new Error(\n `Error on bar ${currentBar}: Bar index value of the \\`${variable}\\` argument (${x}) in \\`${method}()\\` is too far ` +\n 'from the current bar index. Try using `time` instead.'\n );\n }\n return x;\n}\n\n/** Numeric fields that become NaN when an object is deleted, so that its getters return `na`. */\nconst COORDINATES: { [K in DrawingKind]: Array<keyof DrawingTypes[K]> } = {\n line: ['x1', 'y1', 'x2', 'y2'],\n label: ['x', 'y'],\n box: ['left', 'top', 'right', 'bottom'],\n polyline: [],\n linefill: [],\n table: [],\n};\n\nfunction markDeleted<K extends DrawingKind>(kind: K, obj: DrawingTypes[K], explicit: boolean): void {\n deleted.add(obj);\n for (const field of COORDINATES[kind]) (obj as unknown as Record<string, unknown>)[field as string] = NaN;\n if (kind === 'line' && explicit) {\n for (const fill of live.linefill.filter((f) => f.line1 === obj || f.line2 === obj)) remove('linefill', fill);\n }\n}\n\n/** Objects above the maximum that the rule allows for, besides the 5: `P` of the module notes. */\nfunction allowance(kind: DrawingKind): number {\n if (kind === 'polyline') return pending.polyline;\n return lastBar && isAllowanceKind(kind) ? lastBar.allowance[kind] : 0;\n}\n\n/**\n * The maximum count after the creation of `obj`: removes the objects to delete from `list` (the oldest first; the new\n * object and an object held by a `var` variable are skipped and still count) and returns them.\n */\nfunction cutOldest<K extends DrawingKind>(\n kind: K,\n list: Array<DrawingTypes[K]>,\n obj: DrawingTypes[K],\n only?: (old: object) => boolean\n): Array<DrawingTypes[K]> {\n if (kind === 'table') return []; // tables have no maximum count\n const max = limits[kind === 'linefill' ? 'line' : (kind as keyof DrawingLimits)] + allowance(kind);\n if (list.length <= max + SLACK) return [];\n const kept: Array<DrawingTypes[K]> = [];\n const cut: Array<DrawingTypes[K]> = [];\n let excess = list.length - max;\n for (const old of list) {\n if (excess > 0 && old !== obj && (!only || only(old)) && !(kind === 'linefill' ? fillProtected(old) : heldBefore(old))) {\n excess--;\n cut.push(old);\n } else kept.push(old);\n }\n // linefills: still above the maximum + 5, the oldest go, the held ones too\n if (kind === 'linefill' && kept.length > max + SLACK) cut.push(...kept.splice(0, kept.length - max));\n list.length = 0;\n list.push(...kept);\n return cut;\n}\n\n/** Records a new object and deletes the oldest objects of its kind when the count is too high. */\nexport function register<K extends DrawingKind>(kind: K, obj: DrawingTypes[K]): DrawingTypes[K] {\n const list = live[kind];\n if (lastBar && isCounted(kind)) return registerLast(lastBar, kind, obj);\n if (isCounted(kind) && pending[kind] >= PENDING_RESET[kind]) pending[kind] = 0;\n list.push(obj);\n const cut = cutOldest(kind, list, obj);\n if (kind === 'polyline') pending.polyline += cut.length;\n for (const old of cut) markDeleted(kind, old, false);\n return obj;\n}\n\n/** An object created on the last bar (see the module notes). */\nfunction registerLast<K extends DrawingKind>(bar: LastBar, kind: K, obj: DrawingTypes[K]): DrawingTypes[K] {\n if (kind === 'polyline' && !bar.polyline) {\n bar.polyline = true;\n if (pending.polyline >= PENDING_RESET.polyline) pending.polyline = 0;\n else pending.polyline += bar.carried; // counted twice\n }\n const list = live[kind];\n list.push(obj);\n const isOld = (old: object): boolean => bar.old.has(old);\n if (list.some((old) => old !== obj && isOld(old) && !heldBefore(old))) {\n // the objects of the bars before only; a line takes its linefills with it\n const cut = cutOldest(kind, list, obj, isOld);\n if (kind === 'polyline') {\n pending.polyline += cut.length;\n bar.oldPolylinesGone += cut.length;\n }\n for (const old of cut) markDeleted(kind, old, true);\n } else {\n // the polylines of the bars before deleted on this bar count before the cut (#176)\n if (kind === 'polyline' && pending.polyline < bar.oldPolylinesGone) pending.polyline = bar.oldPolylinesGone;\n const cut = cutOldest(kind, list, obj);\n if (kind === 'polyline' && cut.length > 0) pending.polyline = bar.oldPolylinesGone;\n for (const old of cut) markDeleted(kind, old, false);\n }\n return obj;\n}\n\n/** Deletes an object (no effect when it is already deleted). */\nexport function remove<K extends DrawingKind>(kind: K, obj: DrawingTypes[K]): void {\n const list = live[kind];\n const index = list.indexOf(obj);\n if (index !== -1) {\n list.splice(index, 1);\n if (isCounted(kind)) pending[kind]++;\n if (kind === 'polyline' && lastBar?.old.has(obj)) lastBar.oldPolylinesGone++;\n }\n if (!deleted.has(obj)) markDeleted(kind, obj, true);\n}\n\n/** True when the object was deleted (by `delete` or by the maximum count). */\nexport function isDeleted(obj: unknown): boolean {\n return typeof obj === 'object' && obj !== null && deleted.has(obj);\n}\n\n/** The live objects of a kind, in creation order (a new array). */\nexport function all<K extends DrawingKind>(kind: K): Array<DrawingTypes[K]> {\n return [...live[kind]] as Array<DrawingTypes[K]>;\n}\n\n/** Forgets all objects (without deleting them) and sets the maximum counts (default 50). */\nexport function resetDrawings(newLimits: DrawingLimits = {}): void {\n for (const kind of Object.keys(live) as DrawingKind[]) live[kind].length = 0;\n held = new WeakMap();\n releasedAt = new WeakMap();\n heldAt = new WeakMap();\n pending = { line: 0, label: 0, box: 0, polyline: 0 };\n currentBar = null;\n lastBarIndex = null;\n lastBar = null;\n limits = {\n line: newLimits.line ?? DEFAULT_MAX_COUNT,\n label: newLimits.label ?? DEFAULT_MAX_COUNT,\n box: newLimits.box ?? DEFAULT_MAX_COUNT,\n polyline: newLimits.polyline ?? DEFAULT_MAX_COUNT,\n };\n}\n\n/** Changes the maximum counts without forgetting the objects (PineScript `indicator(max_*_count)`). */\nexport function setDrawingLimits(newLimits: DrawingLimits): void {\n limits = { ...limits, ...Object.fromEntries(Object.entries(newLimits).filter(([, v]) => v !== undefined)) };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export { chartSessions, periodTime, periodClose, tradingDayTime, chartSessionFla
|
|
|
40
40
|
export { TradingCalendar, type SessionSpec } from './session/calendar.js';
|
|
41
41
|
export { SessionBars, sessionFlags, type SessionFlags } from './session/bars.js';
|
|
42
42
|
export { resample, periodsOf, afterCompletion, mapToChart, heikinAshi, type Resampled } from './security/resample.js';
|
|
43
|
+
export { securityOther, securityOtherValues, securityLowerTf, type OtherSymbolChart, type OtherSymbolOptions, type SymbolCalendar, } from './security/other.js';
|
|
43
44
|
export { Series, BarData } from './runtime/series.js';
|
|
44
45
|
export type { SeriesExtractor } from './runtime/series.js';
|
|
45
46
|
import * as ta from './ta-series.js';
|
|
@@ -55,7 +56,7 @@ export { indicator, type IndicatorMetadataConfig, type InputDefinition, type Ind
|
|
|
55
56
|
export { input, type InputValue, type IntInputOptions, type FloatInputOptions, type SourceInputOptions, type BoolInputOptions, type StringInputOptions, type TimeInputOptions, type SourceType, } from './input.js';
|
|
56
57
|
export { plot as plotHelper, createPlot, type Time, type TimeValuePair, type PlotOptions as PlotHelperOptions, type PlotResult, } from './plot.js';
|
|
57
58
|
export { setContext, clearContext, getContext, registerCalculate, recalculate, plot, hline, clearPlots, } from './runtime/runtime.js';
|
|
58
|
-
export { input_int, input_float, input_bool, input_string, input_source, input_timeframe, input_session, input_time, } from './runtime/inputs.js';
|
|
59
|
+
export { input_int, input_float, input_bool, input_string, input_source, input_timeframe, input_session, input_symbol, input_time, } from './runtime/inputs.js';
|
|
59
60
|
export { isInputActive } from './runtime/input-active.js';
|
|
60
61
|
export type { OakScriptContext, ChartAdapter, InputAdapter, SeriesHandle, SeriesOptions, InputConfig, InputCondition, InputOptions, OhlcvData, PlotConfig, HLineConfig, FillConfig, ArrowConfig, CandleConfig, } from './runtime/types.js';
|
|
61
62
|
export { STRATEGY_CONSTANTS, STRATEGY_DEFAULTS, STRATEGY_NUMBER_VARIABLES, STRATEGY_TEXT_VARIABLES, } from './strategy/index.js';
|
|
@@ -63,7 +64,7 @@ export type * from './strategy/index.js';
|
|
|
63
64
|
export { LightweightChartsAdapter } from './runtime/adapters/LightweightChartsAdapter.js';
|
|
64
65
|
export type { LightweightSeriesDefinitions } from './runtime/adapters/LightweightChartsAdapter.js';
|
|
65
66
|
export { SimpleInputAdapter } from './runtime/adapters/SimpleInputAdapter.js';
|
|
66
|
-
export declare const VERSION = "0.11.
|
|
67
|
+
export declare const VERSION = "0.11.1";
|
|
67
68
|
/**
|
|
68
69
|
* Library information
|
|
69
70
|
*/
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AAGpC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAG3J,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,cAAc,EACd,UAAU,EACV,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,aAAa,EACb,UAAU,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AAGpC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAEhD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAG3J,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,cAAc,EACd,UAAU,EACV,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,aAAa,EACb,UAAU,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEtH,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACpB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,EAAE,EAAE,CAAC;AAGd,YAAY,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,WAAW,EACX,SAAS,EACV,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACnH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAClH,OAAO,EAAE,GAAG,EAAE,QAAQ,IAAI,cAAc,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG9E,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAGzH,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAC,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAC,MAAM,kBAAkB,CAAC;AAGxD,OAAO,EACL,SAAS,EACT,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,KAAK,EACL,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,UAAU,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,IAAI,IAAI,UAAU,EAClB,UAAU,EACV,KAAK,IAAI,EACT,KAAK,aAAa,EAClB,KAAK,WAAW,IAAI,iBAAiB,EACrC,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,IAAI,EACJ,KAAK,EACL,UAAU,GACX,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,SAAS,EACT,WAAW,EACX,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,aAAa,EACb,YAAY,EACZ,UAAU,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,SAAS,EACT,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,GACb,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,mBAAmB,qBAAqB,CAAC;AAEzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,gDAAgD,CAAC;AAC1F,YAAY,EAAE,4BAA4B,EAAE,MAAM,gDAAgD,CAAC;AACnG,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAG9E,eAAO,MAAM,OAAO,WAAW,CAAC;AAEhC;;GAEG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;CAiBhB,CAAC;AAKF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAE5F"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -94,6 +94,7 @@ __export(index_exports, {
|
|
|
94
94
|
input_session: () => import_inputs.input_session,
|
|
95
95
|
input_source: () => import_inputs.input_source,
|
|
96
96
|
input_string: () => import_inputs.input_string,
|
|
97
|
+
input_symbol: () => import_inputs.input_symbol,
|
|
97
98
|
input_time: () => import_inputs.input_time,
|
|
98
99
|
input_timeframe: () => import_inputs.input_timeframe,
|
|
99
100
|
isInputActive: () => import_input_active.isInputActive,
|
|
@@ -128,6 +129,9 @@ __export(index_exports, {
|
|
|
128
129
|
rgb: () => import_color.rgb,
|
|
129
130
|
round: () => import_math.round,
|
|
130
131
|
rsi: () => import_ta_series.rsi,
|
|
132
|
+
securityLowerTf: () => import_other.securityLowerTf,
|
|
133
|
+
securityOther: () => import_other.securityOther,
|
|
134
|
+
securityOtherValues: () => import_other.securityOtherValues,
|
|
131
135
|
sessionFlags: () => import_bars.sessionFlags,
|
|
132
136
|
setContext: () => import_runtime.setContext,
|
|
133
137
|
setDrawingBar: () => import_registry.setDrawingBar,
|
|
@@ -179,6 +183,7 @@ var import_context = require("./session/context.js");
|
|
|
179
183
|
var import_calendar = require("./session/calendar.js");
|
|
180
184
|
var import_bars = require("./session/bars.js");
|
|
181
185
|
var import_resample = require("./security/resample.js");
|
|
186
|
+
var import_other = require("./security/other.js");
|
|
182
187
|
var import_series = require("./runtime/series.js");
|
|
183
188
|
var ta = __toESM(require("./ta-series.js"), 1);
|
|
184
189
|
var import_ta_series = require("./ta-series.js");
|
|
@@ -196,7 +201,7 @@ var import_input_active = require("./runtime/input-active.js");
|
|
|
196
201
|
var import_strategy = require("./strategy/index.js");
|
|
197
202
|
var import_LightweightChartsAdapter = require("./runtime/adapters/LightweightChartsAdapter.js");
|
|
198
203
|
var import_SimpleInputAdapter = require("./runtime/adapters/SimpleInputAdapter.js");
|
|
199
|
-
const VERSION = "0.11.
|
|
204
|
+
const VERSION = "0.11.1";
|
|
200
205
|
const info = {
|
|
201
206
|
name: "OakScriptJS",
|
|
202
207
|
version: VERSION,
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * OakScriptJS - Simplified PineScript-like library for JavaScript\n *\n * This library provides Series-based lazy evaluation and technical analysis functions\n * for building trading indicators. The PineScript-style script API is in `oakscriptjs/script`.\n *\n * Key features:\n * - Series class for lazy evaluation and method chaining\n * - Core TA functions (array-based)\n * - TA-Series wrappers (Series-based)\n *\n * @packageDocumentation\n */\n\n// Export all types\nexport * from './types/index.js';\nexport * from './types/metadata.js';\n\n// Export core namespaces (array-based functions)\nimport * as taCore from './ta/index.js';\nimport * as math from './math/index.js';\nimport * as array from './array/index.js';\nimport * as map from './map/index.js';\nimport * as str from './str/index.js';\nimport * as color from './color/index.js';\nimport * as time from './time/index.js';\nimport * as timeframe from './timeframe/index.js';\nimport * as matrix from './matrix/index.js';\nimport * as line from './line/index.js';\nimport * as box from './box/index.js';\nimport * as label from './label/index.js';\nimport * as linefill from './linefill/index.js';\nimport * as chartPoint from './chartpoint/index.js';\nimport * as polyline from './polyline/index.js';\nimport * as table from './table/index.js';\nimport * as text from './text/index.js';\nimport * as compare from './compare/index.js';\nimport * as callsite from './callsite/index.js';\n\nexport { taCore, math, array, map, str, color, time, timeframe, matrix, line, box, label, linefill, chartPoint, polyline, table, text, compare, callsite };\n\n// Renderable drawings (IndicatorResult labels, lines, boxes, linefills, polylines, tables) and future bar times\nexport { drawingOutputs, type DrawingOutputs } from './drawing/output.js';\nexport { barInterval, barTime } from './drawing/bar-time.js';\n\n// Drawing registry limits (PineScript indicator(max_lines_count / max_labels_count / max_boxes_count / max_polylines_count))\nexport {\n resetDrawings,\n setDrawingLimits,\n setDrawingBar,\n holdDrawing,\n releaseDrawing,\n varDrawing,\n type DrawingLimits,\n type DrawingVariable,\n} from './drawing/registry.js';\n\n// The session of a chart context without a script run: time(tf), time_close(tf), time_tradingday, session.* flags,\n// request.security periods with the session and holidays, and bars after the last bar on the trading calendar\nexport {\n chartSessions,\n periodTime,\n periodClose,\n tradingDayTime,\n chartSessionFlags,\n resampleSession,\n barTimeAfter,\n barsUntil,\n type SessionContext,\n type ChartSessions,\n type SessionResample,\n} from './session/context.js';\nexport { TradingCalendar, type SessionSpec } from './session/calendar.js';\nexport { SessionBars, sessionFlags, type SessionFlags } from './session/bars.js';\n\n// Same-symbol request.security on a higher timeframe (completion and lookahead rules) and ticker.heikinashi\nexport { resample, periodsOf, afterCompletion, mapToChart, heikinAshi, type Resampled } from './security/resample.js';\n\n// Export Series class (self-contained, no context)\nexport { Series, BarData } from './runtime/series.js';\nexport type { SeriesExtractor } from './runtime/series.js';\n\n// Export TA-Series namespace (Series-based wrappers)\nimport * as ta from './ta-series.js';\nexport { ta };\n\n// Export metadata types for indicator return values\nexport type {\n PlotOptions,\n HLineOptions,\n FillOptions,\n InputMetadata,\n PlotMetadata,\n IndicatorMetadata,\n TimeValue,\n PlotData,\n HLineData,\n FillData,\n FillGradient,\n IndicatorResult,\n IndicatorFactory,\n PlotStyle,\n LineStyle,\n PlotDisplay,\n InputType\n} from './types/metadata.js';\n\n// Re-export commonly used functions for convenience\nexport { sma, ema, rsi, macd, bb, stdev, crossover, crossunder, change, tr, atr, cum, vwap } from './ta-series.js';\nexport { abs, ceil, floor, round, max, min, avg, sum, sqrt, pow, exp, log, sin, cos, tan } from './math/index.js';\nexport { rgb, from_hex as color_from_hex, new_color } from './color/index.js';\n\n// Export chart data utilities\nexport { ohlcFromBars, getClose, getHigh, getLow, getOpen, getSource, getSourceSeries, at, div } from './utils/index.js';\n\n// Export libraries (ZigZag, etc.)\nexport * from './lib/index.js';\n\n// Export helper functions for generated indicators (PineScript compatibility)\nexport {isNA as na, nz, fixnan} from './utils/index.js';\n\n// Export indicator infrastructure\nexport {\n indicator,\n type IndicatorMetadataConfig,\n type InputDefinition,\n type IndicatorContext,\n type IndicatorInstance,\n type IndicatorConstructor,\n} from './indicator.js';\n\nexport {\n input,\n type InputValue,\n type IntInputOptions,\n type FloatInputOptions,\n type SourceInputOptions,\n type BoolInputOptions,\n type StringInputOptions,\n type TimeInputOptions,\n type SourceType,\n} from './input.js';\n\nexport {\n plot as plotHelper,\n createPlot,\n type Time,\n type TimeValuePair,\n type PlotOptions as PlotHelperOptions,\n type PlotResult,\n} from './plot.js';\n\n// Runtime exports - global context runtime (setContext, plot, hline) drawing through a ChartAdapter\nexport {\n setContext,\n clearContext,\n getContext,\n registerCalculate,\n recalculate,\n plot,\n hline,\n clearPlots,\n} from './runtime/runtime.js';\n\nexport {\n input_int,\n input_float,\n input_bool,\n input_string,\n input_source,\n input_timeframe,\n input_session,\n input_time,\n} from './runtime/inputs.js';\nexport { isInputActive } from './runtime/input-active.js';\n\nexport type {\n OakScriptContext,\n ChartAdapter,\n InputAdapter,\n SeriesHandle,\n SeriesOptions,\n InputConfig,\n InputCondition,\n InputOptions,\n OhlcvData,\n PlotConfig,\n HLineConfig,\n FillConfig,\n ArrowConfig,\n CandleConfig,\n} from './runtime/types.js';\n\n// Strategy types and constants (the script API forwards strategy.* calls to a host engine)\nexport {\n STRATEGY_CONSTANTS,\n STRATEGY_DEFAULTS,\n STRATEGY_NUMBER_VARIABLES,\n STRATEGY_TEXT_VARIABLES,\n} from './strategy/index.js';\nexport type * from './strategy/index.js';\n\nexport { LightweightChartsAdapter } from './runtime/adapters/LightweightChartsAdapter.js';\nexport type { LightweightSeriesDefinitions } from './runtime/adapters/LightweightChartsAdapter.js';\nexport { SimpleInputAdapter } from './runtime/adapters/SimpleInputAdapter.js';\n\n// Version\nexport const VERSION = '0.11.
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeA,0BAAc,6BAfd;AAgBA,0BAAc,gCAhBd;AAmBA,aAAwB;AACxB,WAAsB;AACtB,YAAuB;AACvB,UAAqB;AACrB,UAAqB;AACrB,YAAuB;AACvB,WAAsB;AACtB,gBAA2B;AAC3B,aAAwB;AACxB,WAAsB;AACtB,UAAqB;AACrB,YAAuB;AACvB,eAA0B;AAC1B,iBAA4B;AAC5B,eAA0B;AAC1B,YAAuB;AACvB,WAAsB;AACtB,cAAyB;AACzB,eAA0B;AAK1B,oBAAoD;AACpD,sBAAqC;AAGrC,sBASO;AAIP,qBAYO;AACP,sBAAkD;AAClD,kBAA6D;AAG7D,sBAA6F;
|
|
4
|
+
"sourcesContent": ["/**\n * OakScriptJS - Simplified PineScript-like library for JavaScript\n *\n * This library provides Series-based lazy evaluation and technical analysis functions\n * for building trading indicators. The PineScript-style script API is in `oakscriptjs/script`.\n *\n * Key features:\n * - Series class for lazy evaluation and method chaining\n * - Core TA functions (array-based)\n * - TA-Series wrappers (Series-based)\n *\n * @packageDocumentation\n */\n\n// Export all types\nexport * from './types/index.js';\nexport * from './types/metadata.js';\n\n// Export core namespaces (array-based functions)\nimport * as taCore from './ta/index.js';\nimport * as math from './math/index.js';\nimport * as array from './array/index.js';\nimport * as map from './map/index.js';\nimport * as str from './str/index.js';\nimport * as color from './color/index.js';\nimport * as time from './time/index.js';\nimport * as timeframe from './timeframe/index.js';\nimport * as matrix from './matrix/index.js';\nimport * as line from './line/index.js';\nimport * as box from './box/index.js';\nimport * as label from './label/index.js';\nimport * as linefill from './linefill/index.js';\nimport * as chartPoint from './chartpoint/index.js';\nimport * as polyline from './polyline/index.js';\nimport * as table from './table/index.js';\nimport * as text from './text/index.js';\nimport * as compare from './compare/index.js';\nimport * as callsite from './callsite/index.js';\n\nexport { taCore, math, array, map, str, color, time, timeframe, matrix, line, box, label, linefill, chartPoint, polyline, table, text, compare, callsite };\n\n// Renderable drawings (IndicatorResult labels, lines, boxes, linefills, polylines, tables) and future bar times\nexport { drawingOutputs, type DrawingOutputs } from './drawing/output.js';\nexport { barInterval, barTime } from './drawing/bar-time.js';\n\n// Drawing registry limits (PineScript indicator(max_lines_count / max_labels_count / max_boxes_count / max_polylines_count))\nexport {\n resetDrawings,\n setDrawingLimits,\n setDrawingBar,\n holdDrawing,\n releaseDrawing,\n varDrawing,\n type DrawingLimits,\n type DrawingVariable,\n} from './drawing/registry.js';\n\n// The session of a chart context without a script run: time(tf), time_close(tf), time_tradingday, session.* flags,\n// request.security periods with the session and holidays, and bars after the last bar on the trading calendar\nexport {\n chartSessions,\n periodTime,\n periodClose,\n tradingDayTime,\n chartSessionFlags,\n resampleSession,\n barTimeAfter,\n barsUntil,\n type SessionContext,\n type ChartSessions,\n type SessionResample,\n} from './session/context.js';\nexport { TradingCalendar, type SessionSpec } from './session/calendar.js';\nexport { SessionBars, sessionFlags, type SessionFlags } from './session/bars.js';\n\n// Same-symbol request.security on a higher timeframe (completion and lookahead rules) and ticker.heikinashi\nexport { resample, periodsOf, afterCompletion, mapToChart, heikinAshi, type Resampled } from './security/resample.js';\n// request.security of another symbol: which bar of the other symbol each chart bar shows (#179)\nexport {\n securityOther,\n securityOtherValues,\n securityLowerTf,\n type OtherSymbolChart,\n type OtherSymbolOptions,\n type SymbolCalendar,\n} from './security/other.js';\n\n// Export Series class (self-contained, no context)\nexport { Series, BarData } from './runtime/series.js';\nexport type { SeriesExtractor } from './runtime/series.js';\n\n// Export TA-Series namespace (Series-based wrappers)\nimport * as ta from './ta-series.js';\nexport { ta };\n\n// Export metadata types for indicator return values\nexport type {\n PlotOptions,\n HLineOptions,\n FillOptions,\n InputMetadata,\n PlotMetadata,\n IndicatorMetadata,\n TimeValue,\n PlotData,\n HLineData,\n FillData,\n FillGradient,\n IndicatorResult,\n IndicatorFactory,\n PlotStyle,\n LineStyle,\n PlotDisplay,\n InputType\n} from './types/metadata.js';\n\n// Re-export commonly used functions for convenience\nexport { sma, ema, rsi, macd, bb, stdev, crossover, crossunder, change, tr, atr, cum, vwap } from './ta-series.js';\nexport { abs, ceil, floor, round, max, min, avg, sum, sqrt, pow, exp, log, sin, cos, tan } from './math/index.js';\nexport { rgb, from_hex as color_from_hex, new_color } from './color/index.js';\n\n// Export chart data utilities\nexport { ohlcFromBars, getClose, getHigh, getLow, getOpen, getSource, getSourceSeries, at, div } from './utils/index.js';\n\n// Export libraries (ZigZag, etc.)\nexport * from './lib/index.js';\n\n// Export helper functions for generated indicators (PineScript compatibility)\nexport {isNA as na, nz, fixnan} from './utils/index.js';\n\n// Export indicator infrastructure\nexport {\n indicator,\n type IndicatorMetadataConfig,\n type InputDefinition,\n type IndicatorContext,\n type IndicatorInstance,\n type IndicatorConstructor,\n} from './indicator.js';\n\nexport {\n input,\n type InputValue,\n type IntInputOptions,\n type FloatInputOptions,\n type SourceInputOptions,\n type BoolInputOptions,\n type StringInputOptions,\n type TimeInputOptions,\n type SourceType,\n} from './input.js';\n\nexport {\n plot as plotHelper,\n createPlot,\n type Time,\n type TimeValuePair,\n type PlotOptions as PlotHelperOptions,\n type PlotResult,\n} from './plot.js';\n\n// Runtime exports - global context runtime (setContext, plot, hline) drawing through a ChartAdapter\nexport {\n setContext,\n clearContext,\n getContext,\n registerCalculate,\n recalculate,\n plot,\n hline,\n clearPlots,\n} from './runtime/runtime.js';\n\nexport {\n input_int,\n input_float,\n input_bool,\n input_string,\n input_source,\n input_timeframe,\n input_session,\n input_symbol,\n input_time,\n} from './runtime/inputs.js';\nexport { isInputActive } from './runtime/input-active.js';\n\nexport type {\n OakScriptContext,\n ChartAdapter,\n InputAdapter,\n SeriesHandle,\n SeriesOptions,\n InputConfig,\n InputCondition,\n InputOptions,\n OhlcvData,\n PlotConfig,\n HLineConfig,\n FillConfig,\n ArrowConfig,\n CandleConfig,\n} from './runtime/types.js';\n\n// Strategy types and constants (the script API forwards strategy.* calls to a host engine)\nexport {\n STRATEGY_CONSTANTS,\n STRATEGY_DEFAULTS,\n STRATEGY_NUMBER_VARIABLES,\n STRATEGY_TEXT_VARIABLES,\n} from './strategy/index.js';\nexport type * from './strategy/index.js';\n\nexport { LightweightChartsAdapter } from './runtime/adapters/LightweightChartsAdapter.js';\nexport type { LightweightSeriesDefinitions } from './runtime/adapters/LightweightChartsAdapter.js';\nexport { SimpleInputAdapter } from './runtime/adapters/SimpleInputAdapter.js';\n\n// Version\nexport const VERSION = '0.11.1';\n\n/**\n * Library information\n */\nexport const info = {\n name: 'OakScriptJS',\n version: VERSION,\n description: 'Simplified PineScript-like library - Series + TA functions',\n features: {\n series: 'Lazy evaluation with Series class',\n ta: 'Technical analysis functions (Series and array-based)',\n script: 'PineScript-style script API (oakscriptjs/script): indicator, strategy, inputs, plots, request.security',\n runtime: 'Global context runtime drawing through a ChartAdapter',\n indicator: 'Indicator function with automatic pane management'\n },\n namespaces: {\n core: ['ta', 'math', 'array', 'map', 'str', 'color', 'time', 'timeframe', 'matrix'],\n drawing: ['line', 'box', 'label', 'linefill', 'chartPoint', 'polyline', 'table', 'text'],\n runtime: ['setContext', 'plot', 'hline', 'input_*'],\n indicator: ['indicator', 'input', 'plotHelper', 'createPlot']\n }\n};\n\n// PineScript compatibility stubs - functions that have no runtime effect\n// These are no-ops so that PineScript-style code runs without modification\n\n/**\n * alertcondition() - Stub for PineScript alert configuration\n * In PineScript, this registers an alert condition. In oakscriptjs, it's a no-op\n * since alert configuration is handled by the host application.\n */\nexport function alertcondition(_condition: unknown, _title?: string, _message?: string): void {\n // No-op: Alert conditions are handled by the host application\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeA,0BAAc,6BAfd;AAgBA,0BAAc,gCAhBd;AAmBA,aAAwB;AACxB,WAAsB;AACtB,YAAuB;AACvB,UAAqB;AACrB,UAAqB;AACrB,YAAuB;AACvB,WAAsB;AACtB,gBAA2B;AAC3B,aAAwB;AACxB,WAAsB;AACtB,UAAqB;AACrB,YAAuB;AACvB,eAA0B;AAC1B,iBAA4B;AAC5B,eAA0B;AAC1B,YAAuB;AACvB,WAAsB;AACtB,cAAyB;AACzB,eAA0B;AAK1B,oBAAoD;AACpD,sBAAqC;AAGrC,sBASO;AAIP,qBAYO;AACP,sBAAkD;AAClD,kBAA6D;AAG7D,sBAA6F;AAE7F,mBAOO;AAGP,oBAAgC;AAIhC,SAAoB;AAyBpB,uBAAkG;AAClG,kBAAgG;AAChG,mBAA2D;AAG3D,mBAAsG;AAGtG,0BAAc,2BA7Hd;AAgIA,IAAAA,gBAAqC;AAGrC,uBAOO;AAEP,mBAUO;AAEP,kBAOO;AAGP,qBASO;AAEP,oBAUO;AACP,0BAA8B;AAoB9B,sBAKO;AAGP,sCAAyC;AAEzC,gCAAmC;AAG5B,MAAM,UAAU;AAKhB,MAAM,OAAO;AAAA,EAClB,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,UAAU;AAAA,IACR,QAAQ;AAAA,IACR,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW;AAAA,EACb;AAAA,EACA,YAAY;AAAA,IACV,MAAM,CAAC,MAAM,QAAQ,SAAS,OAAO,OAAO,SAAS,QAAQ,aAAa,QAAQ;AAAA,IAClF,SAAS,CAAC,QAAQ,OAAO,SAAS,YAAY,cAAc,YAAY,SAAS,MAAM;AAAA,IACvF,SAAS,CAAC,cAAc,QAAQ,SAAS,SAAS;AAAA,IAClD,WAAW,CAAC,aAAa,SAAS,cAAc,YAAY;AAAA,EAC9D;AACF;AAUO,SAAS,eAAe,YAAqB,QAAiB,UAAyB;AAE9F;",
|
|
6
6
|
"names": ["import_utils"]
|
|
7
7
|
}
|
package/dist/cjs/input.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export interface InputValue<T> {
|
|
10
10
|
/** Input type identifier */
|
|
11
|
-
type: 'int' | 'float' | 'source' | 'bool' | 'string' | 'timeframe' | 'session' | 'time';
|
|
11
|
+
type: 'int' | 'float' | 'source' | 'bool' | 'string' | 'timeframe' | 'session' | 'time' | 'symbol';
|
|
12
12
|
/** Default value */
|
|
13
13
|
defaultValue: T;
|
|
14
14
|
/** Current value (initially equals defaultValue) */
|
|
@@ -179,6 +179,14 @@ export declare const input: {
|
|
|
179
179
|
* ```
|
|
180
180
|
*/
|
|
181
181
|
session(defaultValue: string, options?: StringInputOptions): InputValue<string>;
|
|
182
|
+
/**
|
|
183
|
+
* Create a symbol input parameter (PineScript `input.symbol`): a ticker id ("NASDAQ:MSFT") that an application can
|
|
184
|
+
* edit with a symbol picker (#180)
|
|
185
|
+
* @param defaultValue - Default ticker id
|
|
186
|
+
* @param options - Additional options (title, options for dropdown)
|
|
187
|
+
* @returns Input value object
|
|
188
|
+
*/
|
|
189
|
+
symbol(defaultValue: string, options?: StringInputOptions): InputValue<string>;
|
|
182
190
|
/**
|
|
183
191
|
* Create a date/time input parameter (PineScript `input.time`)
|
|
184
192
|
* @param defaultValue - Default UNIX time in milliseconds, e.g. `time.timestamp('2024-01-01')`
|
package/dist/cjs/input.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/input.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,4BAA4B;IAC5B,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/input.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/input.js
CHANGED
|
@@ -172,6 +172,22 @@ const input = {
|
|
|
172
172
|
options: options.options
|
|
173
173
|
};
|
|
174
174
|
},
|
|
175
|
+
/**
|
|
176
|
+
* Create a symbol input parameter (PineScript `input.symbol`): a ticker id ("NASDAQ:MSFT") that an application can
|
|
177
|
+
* edit with a symbol picker (#180)
|
|
178
|
+
* @param defaultValue - Default ticker id
|
|
179
|
+
* @param options - Additional options (title, options for dropdown)
|
|
180
|
+
* @returns Input value object
|
|
181
|
+
*/
|
|
182
|
+
symbol(defaultValue, options = {}) {
|
|
183
|
+
return {
|
|
184
|
+
type: "symbol",
|
|
185
|
+
defaultValue,
|
|
186
|
+
value: defaultValue,
|
|
187
|
+
title: options.title,
|
|
188
|
+
options: options.options
|
|
189
|
+
};
|
|
190
|
+
},
|
|
175
191
|
/**
|
|
176
192
|
* Create a date/time input parameter (PineScript `input.time`)
|
|
177
193
|
* @param defaultValue - Default UNIX time in milliseconds, e.g. `time.timestamp('2024-01-01')`
|