oakscriptjs 0.9.3 → 0.9.4
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/callsite/index.d.ts +20 -0
- package/dist/cjs/callsite/index.d.ts.map +1 -1
- package/dist/cjs/callsite/index.js +13 -0
- package/dist/cjs/callsite/index.js.map +3 -3
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/callsite/index.d.ts +20 -0
- package/dist/esm/callsite/index.d.ts.map +1 -1
- package/dist/esm/callsite/index.js +33 -0
- package/dist/esm/callsite/index.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/package.json +1 -1
- package/src/callsite/index.ts +33 -0
- package/src/index.ts +1 -1
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* loops, called only on the bars where the Pine call runs.
|
|
12
12
|
* - {@link lowest} / {@link highest}: `ta.lowest` / `ta.highest` with a series length (a different length on each
|
|
13
13
|
* call), which PineScript computes with a state kept between calls.
|
|
14
|
+
* - {@link linreg}: `ta.linreg` in a conditional block, whose window is kept by bar (not by call).
|
|
14
15
|
*
|
|
15
16
|
* Since PineScript v6, `and` / `or` are lazy: the right operand runs only when the left operand does not decide
|
|
16
17
|
* 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
|
|
@@ -85,4 +86,23 @@ export declare function lowest(): (value: number, length: number) => number;
|
|
|
85
86
|
* `(value, length)`. Same rules as {@link lowest}.
|
|
86
87
|
*/
|
|
87
88
|
export declare function highest(): (value: number, length: number) => number;
|
|
89
|
+
/**
|
|
90
|
+
* One `ta.linreg(source, length, offset)` call site in a conditional block, called with
|
|
91
|
+
* `(barIndex, value, length, offset)` on the bars where the Pine call runs.
|
|
92
|
+
*
|
|
93
|
+
* PineScript rules (measured): `ta.linreg` keeps the values it receives in a ring of `length + 1` slots indexed by the
|
|
94
|
+
* bar index, filled with 0 at the start and written only on the bars where it is called. The window is read from the
|
|
95
|
+
* 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
|
|
96
|
+
* the call `length + 1` bars earlier (0 if there was none). The result is na before bar `length - 1`. Called on every
|
|
97
|
+
* bar, it equals `ta.linreg`.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* // Pine: if bar_index >= 20
|
|
102
|
+
* // a := ta.linreg(close, 10, 0)
|
|
103
|
+
* const site = callsite.linreg();
|
|
104
|
+
* const a = closes.map((c, i) => (i >= 20 ? site(i, c, 10, 0) : NaN));
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare function linreg(): (barIndex: number, value: number, length: number, offset?: number) => number;
|
|
88
108
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/callsite/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/callsite/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,OAAO,EACnD,MAAM,EAAE,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC,EACnC,EAAE,EAAE,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAC3C,GAAG,OAAO,EAAE,MAAM,EAAE,GACnB,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CASnB;AAcD,yFAAyF;AACzF,wBAAgB,SAAS,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAE7D;AAED,0FAA0F;AAC1F,wBAAgB,UAAU,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAE9D;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,KAAK,MAAM,CAOnE;AAED,qFAAqF;AACrF,wBAAgB,KAAK,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAEzD;AA2CD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAElE;AAED;;;GAGG;AACH,wBAAgB,OAAO,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAEnE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAUrG"}
|
|
@@ -23,10 +23,12 @@ __export(callsite_exports, {
|
|
|
23
23
|
crossover: () => crossover,
|
|
24
24
|
crossunder: () => crossunder,
|
|
25
25
|
highest: () => highest,
|
|
26
|
+
linreg: () => linreg,
|
|
26
27
|
lowest: () => lowest,
|
|
27
28
|
whenCalled: () => whenCalled
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(callsite_exports);
|
|
31
|
+
var import_ta = require("../ta/index.js");
|
|
30
32
|
function whenCalled(called, fn, ...sources) {
|
|
31
33
|
const bars = [];
|
|
32
34
|
for (let i = 0; i < called.length; i++) if (called[i]) bars.push(i);
|
|
@@ -109,4 +111,15 @@ function lowest() {
|
|
|
109
111
|
function highest() {
|
|
110
112
|
return extremeSite(false);
|
|
111
113
|
}
|
|
114
|
+
function linreg() {
|
|
115
|
+
let ring = [];
|
|
116
|
+
return (barIndex, value, length, offset = 0) => {
|
|
117
|
+
const len = Math.floor(length);
|
|
118
|
+
if (ring.length !== len + 1) ring = new Array(len + 1).fill(0);
|
|
119
|
+
ring[barIndex % (len + 1)] = value;
|
|
120
|
+
if (barIndex < len - 1) return NaN;
|
|
121
|
+
const window = Array.from({ length: len }, (_, k) => ring[(barIndex - len + 1 + k) % (len + 1)]);
|
|
122
|
+
return (0, import_ta.linreg)(window, len, offset)[len - 1];
|
|
123
|
+
};
|
|
124
|
+
}
|
|
112
125
|
//# sourceMappingURL=index.js.map
|
|
@@ -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 lowest} / {@link highest}: `ta.lowest` / `ta.highest` with a series length (a different length on each\n * call), which PineScript computes with a state kept between calls.\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';\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/** A call site that keeps the two previous arguments (na before the first call). */\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 prevA = a;\n prevB = b;\n return result;\n };\n}\n\n/** One `ta.crossover(a, b)` call site: false on its first call, as its history is na. */\nexport function crossover(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => a > b && pa <= pb);\n}\n\n/** One `ta.crossunder(a, b)` call site: false on its first call, as its history is na. */\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/** One `ta.cross(a, b)` call site: false on its first call, as its history is na. */\nexport function cross(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => (a > b && pa <= pb) || (a < b && pa >= pb));\n}\n\n/** One `ta.lowest` / `ta.highest` call site with a series length; rules in {@link lowest}. */\nfunction extremeSite(isLowest: boolean): (value: number, length: number) => number {\n const better = isLowest ? (a: number, b: number) => a < b : (a: number, b: number) => a > b;\n const values: number[] = [];\n let extreme = NaN;\n let extremeAt = -1;\n let prevLength = NaN;\n const keep = (v: number, at: number) => {\n extreme = v;\n extremeAt = at;\n };\n const rescan = (i: number, length: number) => {\n extreme = NaN;\n for (let b = i; b > i - length && b >= 0; b--) {\n const v = values[b]!;\n if (!Number.isNaN(v) && (Number.isNaN(extreme) || !better(extreme, v))) keep(v, b);\n }\n };\n return (value, length) => {\n const i = values.length;\n values.push(value);\n if (Number.isNaN(value)) {\n extreme = NaN;\n prevLength = length;\n return NaN;\n }\n if (length > prevLength) {\n const from = Math.max(0, i - length + 1);\n const to = Math.max(0, i - prevLength + 1);\n if (values.slice(from, to).some(Number.isNaN)) keep(value, i);\n else {\n for (let b = from; b < to; b++) if (Number.isNaN(extreme) || better(values[b]!, extreme)) keep(values[b]!, b);\n if (Number.isNaN(extreme) || better(value, extreme)) keep(value, i);\n }\n } else if (length < prevLength || Number.isNaN(extreme) || i - extremeAt >= length) rescan(i, length);\n else if (better(value, extreme)) keep(value, i);\n prevLength = length;\n return i < length - 1 ? NaN : extreme;\n };\n}\n\n/**\n * One `ta.lowest(source, length)` call site with a series length (a different length on each call), called with\n * `(value, length)`.\n *\n * PineScript rules (measured with a length that changes on each bar):\n * - the extreme is kept with its bar; a new value that passes it replaces it; when the kept extreme is `length`\n * calls old, the last `length` values are scanned again (na skipped, the oldest wins a tie)\n * - a length smaller than on the previous call: the last `length` values are scanned again\n * - a length larger than on the previous call: the values that enter the window at its old end are compared with the\n * extreme; when one of them is na, the extreme restarts from the current value (the values in between are not read)\n * - an na value gives na and resets the extreme; na before call `length - 1`\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) => number {\n return extremeSite(true);\n}\n\n/**\n * One `ta.highest(source, length)` call site with a series length (a different length on each call), called with\n * `(value, length)`. Same rules as {@link lowest}.\n */\nexport function highest(): (value: number, length: number) => number {\n return extremeSite(false);\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
6
|
-
"names": []
|
|
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 lowest} / {@link highest}: `ta.lowest` / `ta.highest` with a series length (a different length on each\n * call), which PineScript computes with a state kept between calls.\n * - {@link linreg}: `ta.linreg` in a conditional block, whose window is kept by bar (not by call).\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';\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/** A call site that keeps the two previous arguments (na before the first call). */\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 prevA = a;\n prevB = b;\n return result;\n };\n}\n\n/** One `ta.crossover(a, b)` call site: false on its first call, as its history is na. */\nexport function crossover(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => a > b && pa <= pb);\n}\n\n/** One `ta.crossunder(a, b)` call site: false on its first call, as its history is na. */\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/** One `ta.cross(a, b)` call site: false on its first call, as its history is na. */\nexport function cross(): (a: number, b: number) => boolean {\n return twoSeriesSite((a, b, pa, pb) => (a > b && pa <= pb) || (a < b && pa >= pb));\n}\n\n/** One `ta.lowest` / `ta.highest` call site with a series length; rules in {@link lowest}. */\nfunction extremeSite(isLowest: boolean): (value: number, length: number) => number {\n const better = isLowest ? (a: number, b: number) => a < b : (a: number, b: number) => a > b;\n const values: number[] = [];\n let extreme = NaN;\n let extremeAt = -1;\n let prevLength = NaN;\n const keep = (v: number, at: number) => {\n extreme = v;\n extremeAt = at;\n };\n const rescan = (i: number, length: number) => {\n extreme = NaN;\n for (let b = i; b > i - length && b >= 0; b--) {\n const v = values[b]!;\n if (!Number.isNaN(v) && (Number.isNaN(extreme) || !better(extreme, v))) keep(v, b);\n }\n };\n return (value, length) => {\n const i = values.length;\n values.push(value);\n if (Number.isNaN(value)) {\n extreme = NaN;\n prevLength = length;\n return NaN;\n }\n if (length > prevLength) {\n const from = Math.max(0, i - length + 1);\n const to = Math.max(0, i - prevLength + 1);\n if (values.slice(from, to).some(Number.isNaN)) keep(value, i);\n else {\n for (let b = from; b < to; b++) if (Number.isNaN(extreme) || better(values[b]!, extreme)) keep(values[b]!, b);\n if (Number.isNaN(extreme) || better(value, extreme)) keep(value, i);\n }\n } else if (length < prevLength || Number.isNaN(extreme) || i - extremeAt >= length) rescan(i, length);\n else if (better(value, extreme)) keep(value, i);\n prevLength = length;\n return i < length - 1 ? NaN : extreme;\n };\n}\n\n/**\n * One `ta.lowest(source, length)` call site with a series length (a different length on each call), called with\n * `(value, length)`.\n *\n * PineScript rules (measured with a length that changes on each bar):\n * - the extreme is kept with its bar; a new value that passes it replaces it; when the kept extreme is `length`\n * calls old, the last `length` values are scanned again (na skipped, the oldest wins a tie)\n * - a length smaller than on the previous call: the last `length` values are scanned again\n * - a length larger than on the previous call: the values that enter the window at its old end are compared with the\n * extreme; when one of them is na, the extreme restarts from the current value (the values in between are not read)\n * - an na value gives na and resets the extreme; na before call `length - 1`\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) => number {\n return extremeSite(true);\n}\n\n/**\n * One `ta.highest(source, length)` call site with a series length (a different length on each call), called with\n * `(value, length)`. Same rules as {@link lowest}.\n */\nexport function highest(): (value: number, length: number) => number {\n return extremeSite(false);\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"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["linregSeries"]
|
|
7
7
|
}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ export type * from './strategy/index.js';
|
|
|
54
54
|
export { LightweightChartsAdapter } from './runtime/adapters/LightweightChartsAdapter.js';
|
|
55
55
|
export type { LightweightSeriesDefinitions } from './runtime/adapters/LightweightChartsAdapter.js';
|
|
56
56
|
export { SimpleInputAdapter } from './runtime/adapters/SimpleInputAdapter.js';
|
|
57
|
-
export declare const VERSION = "0.9.
|
|
57
|
+
export declare const VERSION = "0.9.4";
|
|
58
58
|
/**
|
|
59
59
|
* Library information
|
|
60
60
|
*/
|
package/dist/cjs/index.js
CHANGED
|
@@ -160,7 +160,7 @@ var import_inputs = require("./runtime/inputs.js");
|
|
|
160
160
|
var import_strategy = require("./strategy/index.js");
|
|
161
161
|
var import_LightweightChartsAdapter = require("./runtime/adapters/LightweightChartsAdapter.js");
|
|
162
162
|
var import_SimpleInputAdapter = require("./runtime/adapters/SimpleInputAdapter.js");
|
|
163
|
-
const VERSION = "0.9.
|
|
163
|
+
const VERSION = "0.9.4";
|
|
164
164
|
const info = {
|
|
165
165
|
name: "OakScriptJS",
|
|
166
166
|
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 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, text, compare, callsite };\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';\n\nexport type {\n OakScriptContext,\n ChartAdapter,\n InputAdapter,\n SeriesHandle,\n SeriesOptions,\n InputConfig,\n InputOptions,\n OhlcvData,\n PlotConfig,\n HLineConfig,\n FillConfig,\n ArrowConfig,\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.9.
|
|
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 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, text, compare, callsite };\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';\n\nexport type {\n OakScriptContext,\n ChartAdapter,\n InputAdapter,\n SeriesHandle,\n SeriesOptions,\n InputConfig,\n InputOptions,\n OhlcvData,\n PlotConfig,\n HLineConfig,\n FillConfig,\n ArrowConfig,\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.9.4';\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', '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
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;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,WAAsB;AACtB,cAAyB;AACzB,eAA0B;AAK1B,oBAAgC;AAIhC,SAAoB;AAyBpB,uBAAkG;AAClG,kBAAgG;AAChG,mBAA2D;AAG3D,mBAAsG;AAGtG,0BAAc,2BA9Ed;AAiFA,IAAAA,gBAAqC;AAGrC,uBAOO;AAEP,mBAUO;AAEP,kBAOO;AAGP,qBASO;AAEP,oBASO;AAkBP,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,MAAM;AAAA,IAC9E,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
|
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* loops, called only on the bars where the Pine call runs.
|
|
12
12
|
* - {@link lowest} / {@link highest}: `ta.lowest` / `ta.highest` with a series length (a different length on each
|
|
13
13
|
* call), which PineScript computes with a state kept between calls.
|
|
14
|
+
* - {@link linreg}: `ta.linreg` in a conditional block, whose window is kept by bar (not by call).
|
|
14
15
|
*
|
|
15
16
|
* Since PineScript v6, `and` / `or` are lazy: the right operand runs only when the left operand does not decide
|
|
16
17
|
* 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
|
|
@@ -85,4 +86,23 @@ export declare function lowest(): (value: number, length: number) => number;
|
|
|
85
86
|
* `(value, length)`. Same rules as {@link lowest}.
|
|
86
87
|
*/
|
|
87
88
|
export declare function highest(): (value: number, length: number) => number;
|
|
89
|
+
/**
|
|
90
|
+
* One `ta.linreg(source, length, offset)` call site in a conditional block, called with
|
|
91
|
+
* `(barIndex, value, length, offset)` on the bars where the Pine call runs.
|
|
92
|
+
*
|
|
93
|
+
* PineScript rules (measured): `ta.linreg` keeps the values it receives in a ring of `length + 1` slots indexed by the
|
|
94
|
+
* bar index, filled with 0 at the start and written only on the bars where it is called. The window is read from the
|
|
95
|
+
* 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
|
|
96
|
+
* the call `length + 1` bars earlier (0 if there was none). The result is na before bar `length - 1`. Called on every
|
|
97
|
+
* bar, it equals `ta.linreg`.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* // Pine: if bar_index >= 20
|
|
102
|
+
* // a := ta.linreg(close, 10, 0)
|
|
103
|
+
* const site = callsite.linreg();
|
|
104
|
+
* const a = closes.map((c, i) => (i >= 20 ? site(i, c, 10, 0) : NaN));
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare function linreg(): (barIndex: number, value: number, length: number, offset?: number) => number;
|
|
88
108
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/callsite/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/callsite/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,OAAO,EACnD,MAAM,EAAE,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC,EACnC,EAAE,EAAE,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAC3C,GAAG,OAAO,EAAE,MAAM,EAAE,GACnB,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CASnB;AAcD,yFAAyF;AACzF,wBAAgB,SAAS,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAE7D;AAED,0FAA0F;AAC1F,wBAAgB,UAAU,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAE9D;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,KAAK,MAAM,CAOnE;AAED,qFAAqF;AACrF,wBAAgB,KAAK,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAEzD;AA2CD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAElE;AAED;;;GAGG;AACH,wBAAgB,OAAO,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAEnE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAUrG"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* loops, called only on the bars where the Pine call runs.
|
|
12
12
|
* - {@link lowest} / {@link highest}: `ta.lowest` / `ta.highest` with a series length (a different length on each
|
|
13
13
|
* call), which PineScript computes with a state kept between calls.
|
|
14
|
+
* - {@link linreg}: `ta.linreg` in a conditional block, whose window is kept by bar (not by call).
|
|
14
15
|
*
|
|
15
16
|
* Since PineScript v6, `and` / `or` are lazy: the right operand runs only when the left operand does not decide
|
|
16
17
|
* 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
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
*
|
|
39
40
|
* @module callsite
|
|
40
41
|
*/
|
|
42
|
+
import { linreg as linregSeries } from '../ta/index.js';
|
|
41
43
|
/**
|
|
42
44
|
* Runs `fn` on the bars where `called` is true only, like a ta.* call inside an `if` block.
|
|
43
45
|
* `fn` receives the values of `sources` on those bars, in order; its results are placed back on
|
|
@@ -173,4 +175,35 @@ export function lowest() {
|
|
|
173
175
|
export function highest() {
|
|
174
176
|
return extremeSite(false);
|
|
175
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* One `ta.linreg(source, length, offset)` call site in a conditional block, called with
|
|
180
|
+
* `(barIndex, value, length, offset)` on the bars where the Pine call runs.
|
|
181
|
+
*
|
|
182
|
+
* PineScript rules (measured): `ta.linreg` keeps the values it receives in a ring of `length + 1` slots indexed by the
|
|
183
|
+
* bar index, filled with 0 at the start and written only on the bars where it is called. The window is read from the
|
|
184
|
+
* 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
|
|
185
|
+
* the call `length + 1` bars earlier (0 if there was none). The result is na before bar `length - 1`. Called on every
|
|
186
|
+
* bar, it equals `ta.linreg`.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```typescript
|
|
190
|
+
* // Pine: if bar_index >= 20
|
|
191
|
+
* // a := ta.linreg(close, 10, 0)
|
|
192
|
+
* const site = callsite.linreg();
|
|
193
|
+
* const a = closes.map((c, i) => (i >= 20 ? site(i, c, 10, 0) : NaN));
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
export function linreg() {
|
|
197
|
+
let ring = [];
|
|
198
|
+
return (barIndex, value, length, offset = 0) => {
|
|
199
|
+
const len = Math.floor(length);
|
|
200
|
+
if (ring.length !== len + 1)
|
|
201
|
+
ring = new Array(len + 1).fill(0);
|
|
202
|
+
ring[barIndex % (len + 1)] = value;
|
|
203
|
+
if (barIndex < len - 1)
|
|
204
|
+
return NaN;
|
|
205
|
+
const window = Array.from({ length: len }, (_, k) => ring[(barIndex - len + 1 + k) % (len + 1)]);
|
|
206
|
+
return linregSeries(window, len, offset)[len - 1];
|
|
207
|
+
};
|
|
208
|
+
}
|
|
176
209
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/callsite/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/callsite/index.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ export type * from './strategy/index.js';
|
|
|
54
54
|
export { LightweightChartsAdapter } from './runtime/adapters/LightweightChartsAdapter.js';
|
|
55
55
|
export type { LightweightSeriesDefinitions } from './runtime/adapters/LightweightChartsAdapter.js';
|
|
56
56
|
export { SimpleInputAdapter } from './runtime/adapters/SimpleInputAdapter.js';
|
|
57
|
-
export declare const VERSION = "0.9.
|
|
57
|
+
export declare const VERSION = "0.9.4";
|
|
58
58
|
/**
|
|
59
59
|
* Library information
|
|
60
60
|
*/
|
package/dist/esm/index.js
CHANGED
|
@@ -61,7 +61,7 @@ export { STRATEGY_CONSTANTS, STRATEGY_DEFAULTS, STRATEGY_NUMBER_VARIABLES, STRAT
|
|
|
61
61
|
export { LightweightChartsAdapter } from './runtime/adapters/LightweightChartsAdapter.js';
|
|
62
62
|
export { SimpleInputAdapter } from './runtime/adapters/SimpleInputAdapter.js';
|
|
63
63
|
// Version
|
|
64
|
-
export const VERSION = '0.9.
|
|
64
|
+
export const VERSION = '0.9.4';
|
|
65
65
|
/**
|
|
66
66
|
* Library information
|
|
67
67
|
*/
|
package/package.json
CHANGED
package/src/callsite/index.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* loops, called only on the bars where the Pine call runs.
|
|
12
12
|
* - {@link lowest} / {@link highest}: `ta.lowest` / `ta.highest` with a series length (a different length on each
|
|
13
13
|
* call), which PineScript computes with a state kept between calls.
|
|
14
|
+
* - {@link linreg}: `ta.linreg` in a conditional block, whose window is kept by bar (not by call).
|
|
14
15
|
*
|
|
15
16
|
* Since PineScript v6, `and` / `or` are lazy: the right operand runs only when the left operand does not decide
|
|
16
17
|
* 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
|
|
@@ -40,6 +41,7 @@
|
|
|
40
41
|
*/
|
|
41
42
|
|
|
42
43
|
import type { Source } from '../types/index.js';
|
|
44
|
+
import { linreg as linregSeries } from '../ta/index.js';
|
|
43
45
|
|
|
44
46
|
/**
|
|
45
47
|
* Runs `fn` on the bars where `called` is true only, like a ta.* call inside an `if` block.
|
|
@@ -176,3 +178,34 @@ export function lowest(): (value: number, length: number) => number {
|
|
|
176
178
|
export function highest(): (value: number, length: number) => number {
|
|
177
179
|
return extremeSite(false);
|
|
178
180
|
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* One `ta.linreg(source, length, offset)` call site in a conditional block, called with
|
|
184
|
+
* `(barIndex, value, length, offset)` on the bars where the Pine call runs.
|
|
185
|
+
*
|
|
186
|
+
* PineScript rules (measured): `ta.linreg` keeps the values it receives in a ring of `length + 1` slots indexed by the
|
|
187
|
+
* bar index, filled with 0 at the start and written only on the bars where it is called. The window is read from the
|
|
188
|
+
* 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
|
|
189
|
+
* the call `length + 1` bars earlier (0 if there was none). The result is na before bar `length - 1`. Called on every
|
|
190
|
+
* bar, it equals `ta.linreg`.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```typescript
|
|
194
|
+
* // Pine: if bar_index >= 20
|
|
195
|
+
* // a := ta.linreg(close, 10, 0)
|
|
196
|
+
* const site = callsite.linreg();
|
|
197
|
+
* const a = closes.map((c, i) => (i >= 20 ? site(i, c, 10, 0) : NaN));
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
export function linreg(): (barIndex: number, value: number, length: number, offset?: number) => number {
|
|
201
|
+
let ring: number[] = [];
|
|
202
|
+
return (barIndex, value, length, offset = 0) => {
|
|
203
|
+
const len = Math.floor(length);
|
|
204
|
+
if (ring.length !== len + 1) ring = new Array<number>(len + 1).fill(0);
|
|
205
|
+
ring[barIndex % (len + 1)] = value;
|
|
206
|
+
if (barIndex < len - 1) return NaN;
|
|
207
|
+
const window = Array.from({ length: len }, (_, k) => ring[(barIndex - len + 1 + k) % (len + 1)]!);
|
|
208
|
+
return linregSeries(window, len, offset)[len - 1]!;
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
package/src/index.ts
CHANGED
|
@@ -164,7 +164,7 @@ export type { LightweightSeriesDefinitions } from './runtime/adapters/Lightweigh
|
|
|
164
164
|
export { SimpleInputAdapter } from './runtime/adapters/SimpleInputAdapter.js';
|
|
165
165
|
|
|
166
166
|
// Version
|
|
167
|
-
export const VERSION = '0.9.
|
|
167
|
+
export const VERSION = '0.9.4';
|
|
168
168
|
|
|
169
169
|
/**
|
|
170
170
|
* Library information
|