oakscriptjs 0.13.2 → 0.14.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/AGENTS.md +6 -1
- package/README.md +1 -1
- package/bin/oakscript.mjs +5 -0
- package/dist/cjs/check/checks.d.ts +78 -0
- package/dist/cjs/check/checks.d.ts.map +1 -0
- package/dist/cjs/check/checks.js +109 -0
- package/dist/cjs/check/checks.js.map +7 -0
- package/dist/cjs/check/format.d.ts +26 -0
- package/dist/cjs/check/format.d.ts.map +1 -0
- package/dist/cjs/check/format.js +106 -0
- package/dist/cjs/check/format.js.map +7 -0
- package/dist/cjs/check/harness.d.ts +94 -0
- package/dist/cjs/check/harness.d.ts.map +1 -0
- package/dist/cjs/check/harness.js +302 -0
- package/dist/cjs/check/harness.js.map +7 -0
- package/dist/cjs/check/index.d.ts +253 -0
- package/dist/cjs/check/index.d.ts.map +1 -0
- package/dist/cjs/check/index.js +466 -0
- package/dist/cjs/check/index.js.map +7 -0
- package/dist/cjs/check/node.d.ts +53 -0
- package/dist/cjs/check/node.d.ts.map +1 -0
- package/dist/cjs/check/node.js +318 -0
- package/dist/cjs/check/node.js.map +7 -0
- package/dist/cjs/check/spec.d.ts +44 -0
- package/dist/cjs/check/spec.d.ts.map +1 -0
- package/dist/cjs/check/spec.js +199 -0
- package/dist/cjs/check/spec.js.map +7 -0
- 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/cjs/runtime/series.d.ts +6 -0
- package/dist/cjs/runtime/series.d.ts.map +1 -1
- package/dist/cjs/runtime/series.js +15 -0
- package/dist/cjs/runtime/series.js.map +2 -2
- package/dist/cjs/script/constants.d.ts +200 -0
- package/dist/cjs/script/constants.d.ts.map +1 -0
- package/dist/cjs/script/constants.js +217 -0
- package/dist/cjs/script/constants.js.map +7 -0
- package/dist/cjs/script/drawing-args.d.ts +25 -0
- package/dist/cjs/script/drawing-args.d.ts.map +1 -0
- package/dist/cjs/script/drawing-args.js +203 -0
- package/dist/cjs/script/drawing-args.js.map +7 -0
- package/dist/cjs/script/globals.d.ts +127 -0
- package/dist/cjs/script/globals.d.ts.map +1 -0
- package/dist/cjs/script/globals.js +17 -0
- package/dist/cjs/script/globals.js.map +7 -0
- package/dist/cjs/script/index.d.ts +504 -166
- package/dist/cjs/script/index.d.ts.map +1 -1
- package/dist/cjs/script/index.js +236 -96
- package/dist/cjs/script/index.js.map +3 -3
- package/dist/esm/check/checks.d.ts +78 -0
- package/dist/esm/check/checks.d.ts.map +1 -0
- package/dist/esm/check/checks.js +95 -0
- package/dist/esm/check/checks.js.map +1 -0
- package/dist/esm/check/format.d.ts +26 -0
- package/dist/esm/check/format.d.ts.map +1 -0
- package/dist/esm/check/format.js +105 -0
- package/dist/esm/check/format.js.map +1 -0
- package/dist/esm/check/harness.d.ts +94 -0
- package/dist/esm/check/harness.d.ts.map +1 -0
- package/dist/esm/check/harness.js +317 -0
- package/dist/esm/check/harness.js.map +1 -0
- package/dist/esm/check/index.d.ts +253 -0
- package/dist/esm/check/index.d.ts.map +1 -0
- package/dist/esm/check/index.js +470 -0
- package/dist/esm/check/index.js.map +1 -0
- package/dist/esm/check/node.d.ts +53 -0
- package/dist/esm/check/node.d.ts.map +1 -0
- package/dist/esm/check/node.js +347 -0
- package/dist/esm/check/node.js.map +1 -0
- package/dist/esm/check/spec.d.ts +44 -0
- package/dist/esm/check/spec.d.ts.map +1 -0
- package/dist/esm/check/spec.js +198 -0
- package/dist/esm/check/spec.js.map +1 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/runtime/series.d.ts +6 -0
- package/dist/esm/runtime/series.d.ts.map +1 -1
- package/dist/esm/runtime/series.js +14 -0
- package/dist/esm/runtime/series.js.map +1 -1
- package/dist/esm/script/constants.d.ts +200 -0
- package/dist/esm/script/constants.d.ts.map +1 -0
- package/dist/esm/script/constants.js +151 -0
- package/dist/esm/script/constants.js.map +1 -0
- package/dist/esm/script/drawing-args.d.ts +25 -0
- package/dist/esm/script/drawing-args.d.ts.map +1 -0
- package/dist/esm/script/drawing-args.js +171 -0
- package/dist/esm/script/drawing-args.js.map +1 -0
- package/dist/esm/script/globals.d.ts +127 -0
- package/dist/esm/script/globals.d.ts.map +1 -0
- package/dist/esm/script/globals.js +28 -0
- package/dist/esm/script/globals.js.map +1 -0
- package/dist/esm/script/index.d.ts +504 -166
- package/dist/esm/script/index.d.ts.map +1 -1
- package/dist/esm/script/index.js +256 -83
- package/dist/esm/script/index.js.map +1 -1
- package/package.json +31 -1
- package/skills/oakscript/SKILL.md +62 -26
- package/skills/oakscript/examples/ma-cross.js +2 -2
- package/skills/oakscript/examples/mtf-trend-filter.js +3 -3
- package/skills/oakscript/reference/check.md +150 -0
- package/skills/oakscript/reference/errors.md +31 -7
- package/skills/oakscript/reference/pine-differences.md +17 -16
- package/skills/oakscript/reference/plotting.md +25 -19
- package/skills/oakscript/reference/script-structure.md +34 -17
- package/skills/oakscript/reference/timeframes-symbols.md +5 -1
- package/skills/oakscript/spec.schema.json +199 -0
- package/src/check/checks.ts +175 -0
- package/src/check/format.ts +117 -0
- package/src/check/harness.ts +372 -0
- package/src/check/index.ts +708 -0
- package/src/check/node.ts +368 -0
- package/src/check/spec.ts +200 -0
- package/src/index.ts +1 -1
- package/src/runtime/series.ts +19 -0
- package/src/script/constants.ts +169 -0
- package/src/script/drawing-args.ts +179 -0
- package/src/script/globals.ts +129 -0
- package/src/script/index.ts +462 -81
package/dist/cjs/script/index.js
CHANGED
|
@@ -35,8 +35,10 @@ __export(script_exports, {
|
|
|
35
35
|
STRATEGY_DEFAULTS: () => import_strategy2.STRATEGY_DEFAULTS,
|
|
36
36
|
Series: () => import_series.Series,
|
|
37
37
|
StrategyRecorder: () => StrategyRecorder,
|
|
38
|
+
adjustment: () => adjustment,
|
|
38
39
|
alert: () => alert,
|
|
39
40
|
alertcondition: () => alertcondition,
|
|
41
|
+
bar_index: () => bar_index,
|
|
40
42
|
barcolor: () => barcolor,
|
|
41
43
|
barmerge: () => barmerge,
|
|
42
44
|
barstate: () => barstate,
|
|
@@ -46,13 +48,18 @@ __export(script_exports, {
|
|
|
46
48
|
close: () => close,
|
|
47
49
|
color: () => color,
|
|
48
50
|
compare: () => compare,
|
|
51
|
+
currency: () => currency,
|
|
49
52
|
dayofmonth: () => dayofmonth,
|
|
50
53
|
dayofweek: () => dayofweek,
|
|
54
|
+
display: () => display,
|
|
51
55
|
eachBar: () => eachBar,
|
|
52
56
|
executeIntrabar: () => executeIntrabar,
|
|
53
57
|
executeScript: () => executeScript,
|
|
58
|
+
extend: () => extend,
|
|
54
59
|
fill: () => fill,
|
|
55
60
|
fixnan: () => fixnan,
|
|
61
|
+
font: () => font,
|
|
62
|
+
format: () => format,
|
|
56
63
|
high: () => high,
|
|
57
64
|
hl2: () => hl2,
|
|
58
65
|
hlc3: () => hlc3,
|
|
@@ -65,8 +72,10 @@ __export(script_exports, {
|
|
|
65
72
|
input: () => input,
|
|
66
73
|
isInputActive: () => import_input_active.isInputActive,
|
|
67
74
|
label: () => label,
|
|
75
|
+
last_bar_index: () => last_bar_index,
|
|
68
76
|
line: () => line,
|
|
69
77
|
linefill: () => linefill,
|
|
78
|
+
location: () => location,
|
|
70
79
|
low: () => low,
|
|
71
80
|
math: () => math,
|
|
72
81
|
minute: () => minute,
|
|
@@ -75,6 +84,7 @@ __export(script_exports, {
|
|
|
75
84
|
nz: () => import_utils.nz,
|
|
76
85
|
ohlc4: () => ohlc4,
|
|
77
86
|
open: () => open,
|
|
87
|
+
order: () => order,
|
|
78
88
|
plot: () => plot,
|
|
79
89
|
plotarrow: () => plotarrow,
|
|
80
90
|
plotbar: () => plotbar,
|
|
@@ -85,9 +95,12 @@ __export(script_exports, {
|
|
|
85
95
|
position: () => import_types.position,
|
|
86
96
|
releaseDrawing: () => import_registry2.releaseDrawing,
|
|
87
97
|
request: () => request,
|
|
98
|
+
scale: () => scale,
|
|
88
99
|
second: () => second,
|
|
89
100
|
seriesOf: () => seriesOf,
|
|
90
101
|
session: () => session,
|
|
102
|
+
shape: () => shape,
|
|
103
|
+
size: () => size,
|
|
91
104
|
str: () => str,
|
|
92
105
|
strategy: () => strategy,
|
|
93
106
|
syminfo: () => syminfo,
|
|
@@ -105,11 +118,15 @@ __export(script_exports, {
|
|
|
105
118
|
varip: () => varip,
|
|
106
119
|
volume: () => volume,
|
|
107
120
|
weekofyear: () => weekofyear,
|
|
108
|
-
|
|
121
|
+
xloc: () => xloc,
|
|
122
|
+
year: () => year,
|
|
123
|
+
yloc: () => yloc
|
|
109
124
|
});
|
|
110
125
|
module.exports = __toCommonJS(script_exports);
|
|
111
126
|
var import_series = require("../runtime/series.js");
|
|
112
127
|
var taSeries = __toESM(require("../ta-series.js"), 1);
|
|
128
|
+
var pineConstants = __toESM(require("./constants.js"), 1);
|
|
129
|
+
var import_drawing_args = require("./drawing-args.js");
|
|
113
130
|
var colorCore = __toESM(require("../color/index.js"), 1);
|
|
114
131
|
var import_parse = require("../color/parse.js");
|
|
115
132
|
var import_utils = require("../utils/index.js");
|
|
@@ -154,7 +171,7 @@ function collector() {
|
|
|
154
171
|
function freshCollector(inputValues) {
|
|
155
172
|
return {
|
|
156
173
|
title: "Untitled",
|
|
157
|
-
overlay:
|
|
174
|
+
overlay: false,
|
|
158
175
|
inputValues,
|
|
159
176
|
inputConfig: [],
|
|
160
177
|
inputIds: /* @__PURE__ */ new Set(),
|
|
@@ -253,7 +270,8 @@ function executeScript(body, barsInput, inputs = {}, chart2 = {}, options = {})
|
|
|
253
270
|
shortTitle: c.shortTitle,
|
|
254
271
|
overlay: c.overlay,
|
|
255
272
|
precision: c.precision,
|
|
256
|
-
format: c.format
|
|
273
|
+
format: c.format,
|
|
274
|
+
...c.scale ? { scale: c.scale } : {}
|
|
257
275
|
},
|
|
258
276
|
inputConfig: c.inputConfig,
|
|
259
277
|
plotConfig: c.plotConfig,
|
|
@@ -343,9 +361,10 @@ function indicator(title, options = {}) {
|
|
|
343
361
|
declare(c, "indicator");
|
|
344
362
|
c.title = title;
|
|
345
363
|
c.shortTitle = options.shorttitle;
|
|
346
|
-
c.overlay = options.overlay ??
|
|
364
|
+
c.overlay = options.overlay ?? false;
|
|
347
365
|
c.precision = options.precision;
|
|
348
366
|
c.format = options.format;
|
|
367
|
+
c.scale = options.scale;
|
|
349
368
|
(0, import_registry.setDrawingLimits)({
|
|
350
369
|
line: options.max_lines_count,
|
|
351
370
|
label: options.max_labels_count,
|
|
@@ -384,60 +403,113 @@ function registerNumeric(type, defval, title, opts = {}) {
|
|
|
384
403
|
);
|
|
385
404
|
return typeof v === "number" ? v : defval;
|
|
386
405
|
}
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
406
|
+
const COMMON_INPUT_KEYS = ["tooltip", "inline", "group", "confirm", "display", "active"];
|
|
407
|
+
const INPUT_KEYS = {
|
|
408
|
+
int: ["defval", "title", "minval", "maxval", "step", ...COMMON_INPUT_KEYS],
|
|
409
|
+
float: ["defval", "title", "minval", "maxval", "step", ...COMMON_INPUT_KEYS],
|
|
410
|
+
price: ["defval", "title", ...COMMON_INPUT_KEYS],
|
|
411
|
+
bool: ["defval", "title", ...COMMON_INPUT_KEYS],
|
|
412
|
+
string: ["defval", "title", "options", ...COMMON_INPUT_KEYS],
|
|
413
|
+
text_area: ["defval", "title", ...COMMON_INPUT_KEYS],
|
|
414
|
+
color: ["defval", "title", ...COMMON_INPUT_KEYS],
|
|
415
|
+
source: ["defval", "title", ...COMMON_INPUT_KEYS],
|
|
416
|
+
timeframe: ["defval", "title", "options", ...COMMON_INPUT_KEYS],
|
|
417
|
+
session: ["defval", "title", "options", ...COMMON_INPUT_KEYS],
|
|
418
|
+
symbol: ["defval", "title", "options", ...COMMON_INPUT_KEYS],
|
|
419
|
+
time: ["defval", "title", ...COMMON_INPUT_KEYS]
|
|
420
|
+
};
|
|
421
|
+
function inputArgs(kind, defvalOrArgs, titleOrArgs, opts) {
|
|
422
|
+
const name = `input.${kind}`;
|
|
423
|
+
const keys = INPUT_KEYS[kind];
|
|
424
|
+
let named = {};
|
|
425
|
+
let defval = defvalOrArgs;
|
|
426
|
+
let title = titleOrArgs;
|
|
427
|
+
if ((0, import_drawing_args.isPlainObject)(defvalOrArgs)) {
|
|
428
|
+
named = { ...defvalOrArgs };
|
|
429
|
+
defval = named.defval;
|
|
430
|
+
title = void 0;
|
|
431
|
+
} else if ((0, import_drawing_args.isPlainObject)(titleOrArgs)) {
|
|
432
|
+
named = { ...titleOrArgs };
|
|
433
|
+
title = void 0;
|
|
434
|
+
}
|
|
435
|
+
if (opts !== void 0) {
|
|
436
|
+
if (!(0, import_drawing_args.isPlainObject)(opts)) throw new TypeError(`${name}(): the options are an object, e.g. { tooltip: "..." }.`);
|
|
437
|
+
named = { ...named, ...opts };
|
|
438
|
+
}
|
|
439
|
+
for (const key of Object.keys(named)) if (!keys.includes(key)) throw (0, import_drawing_args.unknownArgument)(name, key, keys);
|
|
440
|
+
if (title !== void 0 && typeof title !== "string") {
|
|
441
|
+
throw new TypeError(`${name}(): the title is a string, got ${typeof title}.`);
|
|
442
|
+
}
|
|
443
|
+
const { defval: namedDefval, title: namedTitle, ...rest } = named;
|
|
444
|
+
return {
|
|
445
|
+
defval: defval ?? namedDefval,
|
|
446
|
+
title: title ?? namedTitle,
|
|
447
|
+
opts: rest
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
const input = strictNamespace("input", {
|
|
451
|
+
int(defval, title, opts) {
|
|
452
|
+
const a = inputArgs("int", defval, title, opts);
|
|
453
|
+
return Math.round(registerNumeric("int", a.defval, a.title, a.opts));
|
|
390
454
|
},
|
|
391
|
-
float(defval, title, opts
|
|
392
|
-
|
|
455
|
+
float(defval, title, opts) {
|
|
456
|
+
const a = inputArgs("float", defval, title, opts);
|
|
457
|
+
return registerNumeric("float", a.defval, a.title, a.opts);
|
|
393
458
|
},
|
|
394
|
-
bool(defval, title, opts
|
|
395
|
-
|
|
459
|
+
bool(defval, title, opts) {
|
|
460
|
+
const a = inputArgs("bool", defval, title, opts);
|
|
461
|
+
return registerInput({ type: "bool", defval: a.defval, title: a.title, ...common(a.opts) }, "input_bool");
|
|
396
462
|
},
|
|
397
|
-
string(defval, title, opts
|
|
398
|
-
|
|
463
|
+
string(defval, title, opts) {
|
|
464
|
+
const a = inputArgs("string", defval, title, opts);
|
|
465
|
+
return registerInput({ type: "string", defval: a.defval, title: a.title, options: a.opts.options, ...common(a.opts) }, "input_string");
|
|
399
466
|
},
|
|
400
|
-
/** Multi-line text (
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
return registerInput({ type: "text_area", defval, title, ...common(opts) }, "input_text_area");
|
|
467
|
+
/** Multi-line text (lines separated by a newline), e.g. a list a script parses (#184). */
|
|
468
|
+
text_area(defval, title, opts) {
|
|
469
|
+
const a = inputArgs("text_area", defval, title, opts);
|
|
470
|
+
return registerInput({ type: "text_area", defval: a.defval, title: a.title, ...common(a.opts) }, "input_text_area");
|
|
404
471
|
},
|
|
405
472
|
/**
|
|
406
473
|
* Declares a colour input. As in PineScript, the default keeps an alpha of 2 decimals: an input default
|
|
407
474
|
* `color.new(c, 90)` has the alpha byte 26 (25 in the script). A value given by the host is not changed.
|
|
408
475
|
*/
|
|
409
|
-
color(defval, title, opts
|
|
410
|
-
|
|
476
|
+
color(defval, title, opts) {
|
|
477
|
+
const a = inputArgs("color", defval, title, opts);
|
|
478
|
+
return registerInput({ type: "color", defval: (0, import_parse.inputColorDefault)(a.defval), title: a.title, ...common(a.opts) }, "input_color");
|
|
411
479
|
},
|
|
412
480
|
/** Declares a source input and returns it as a Series. */
|
|
413
|
-
source(defval = "close", title, opts
|
|
414
|
-
const
|
|
481
|
+
source(defval = "close", title, opts) {
|
|
482
|
+
const a = inputArgs("source", defval, title, opts);
|
|
483
|
+
const name = registerInput({ type: "source", defval: sourceName(a.defval ?? "close"), title: a.title, ...common(a.opts) }, "input_source");
|
|
415
484
|
return sourceSeries(name);
|
|
416
485
|
},
|
|
417
486
|
/** Timeframe string ("60", "1D", "W"). As in PineScript, "" means the chart timeframe. */
|
|
418
|
-
timeframe(defval, title, opts
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
"input_timeframe"
|
|
422
|
-
);
|
|
487
|
+
timeframe(defval, title, opts) {
|
|
488
|
+
const a = inputArgs("timeframe", defval, title, opts);
|
|
489
|
+
return registerInput({ type: "timeframe", defval: a.defval, title: a.title, options: a.opts.options, ...common(a.opts) }, "input_timeframe");
|
|
423
490
|
},
|
|
424
491
|
/** Session string ("0930-1600", "0930-1600:23456"). */
|
|
425
|
-
session(defval, title, opts
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
"input_session"
|
|
429
|
-
);
|
|
492
|
+
session(defval, title, opts) {
|
|
493
|
+
const a = inputArgs("session", defval, title, opts);
|
|
494
|
+
return registerInput({ type: "session", defval: a.defval, title: a.title, options: a.opts.options, ...common(a.opts) }, "input_session");
|
|
430
495
|
},
|
|
431
496
|
/** Ticker id ("NASDAQ:MSFT"), for `request.security` of another symbol (#180). */
|
|
432
|
-
symbol(defval, title, opts
|
|
433
|
-
|
|
497
|
+
symbol(defval, title, opts) {
|
|
498
|
+
const a = inputArgs("symbol", defval, title, opts);
|
|
499
|
+
return registerInput({ type: "symbol", defval: a.defval, title: a.title, options: a.opts.options, ...common(a.opts) }, "input_symbol");
|
|
500
|
+
},
|
|
501
|
+
/** PineScript `input.price`: a price level, a float input (the host shows it as a number). */
|
|
502
|
+
price(defval, title, opts) {
|
|
503
|
+
const a = inputArgs("price", defval, title, opts);
|
|
504
|
+
return registerNumeric("float", a.defval, a.title, a.opts);
|
|
434
505
|
},
|
|
435
506
|
/** Date and time as a UNIX time in milliseconds, e.g. `input.time(timestamp('2024-01-01'), 'Start')`. */
|
|
436
|
-
time(defval, title, opts
|
|
437
|
-
const
|
|
438
|
-
|
|
507
|
+
time(defval, title, opts) {
|
|
508
|
+
const a = inputArgs("time", defval, title, opts);
|
|
509
|
+
const v = registerInput({ type: "time", defval: a.defval, title: a.title, ...common(a.opts) }, "input_time");
|
|
510
|
+
return typeof v === "number" ? v : a.defval;
|
|
439
511
|
}
|
|
440
|
-
};
|
|
512
|
+
});
|
|
441
513
|
const open = import_series.Series.fromBars(ctxBars, "open");
|
|
442
514
|
const high = import_series.Series.fromBars(ctxBars, "high");
|
|
443
515
|
const low = import_series.Series.fromBars(ctxBars, "low");
|
|
@@ -447,8 +519,20 @@ const hl2 = new import_series.Series(ctxBars, (b) => (b.high + b.low) / 2);
|
|
|
447
519
|
const hlc3 = new import_series.Series(ctxBars, (b) => (b.high + b.low + b.close) / 3);
|
|
448
520
|
const ohlc4 = new import_series.Series(ctxBars, (b) => (b.open + b.high + b.low + b.close) / 4);
|
|
449
521
|
const hlcc4 = new import_series.Series(ctxBars, (b) => (b.high + b.low + b.close + b.close) / 4);
|
|
522
|
+
const bar_index = new import_series.Series(ctxBars, (_b, i) => i);
|
|
523
|
+
bar_index.fullHistory = true;
|
|
524
|
+
const last_bar_index = new import_series.Series(ctxBars, (_b, _i, data) => data.length - 1);
|
|
525
|
+
last_bar_index.fullHistory = true;
|
|
450
526
|
for (const s of [hl2, hlc3, ohlc4, hlcc4]) s.fullHistory = true;
|
|
451
527
|
const SOURCES = { open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4 };
|
|
528
|
+
function sourceName(defval) {
|
|
529
|
+
if (typeof defval === "string") return defval;
|
|
530
|
+
const name = Object.keys(SOURCES).find((k) => SOURCES[k] === defval);
|
|
531
|
+
if (!name) {
|
|
532
|
+
throw new Error("input.source(): the default must be a built-in source (open, high, low, close, volume, hl2, hlc3, ohlc4, hlcc4).");
|
|
533
|
+
}
|
|
534
|
+
return name;
|
|
535
|
+
}
|
|
452
536
|
function sourceSeries(name) {
|
|
453
537
|
const builtin = SOURCES[name];
|
|
454
538
|
if (builtin) return builtin;
|
|
@@ -469,7 +553,58 @@ function barsSeries(compute) {
|
|
|
469
553
|
return values[i] ?? NaN;
|
|
470
554
|
});
|
|
471
555
|
}
|
|
472
|
-
|
|
556
|
+
function editDistance(a, b) {
|
|
557
|
+
const row = Array.from({ length: b.length + 1 }, (_, j) => j);
|
|
558
|
+
for (let i = 1; i <= a.length; i++) {
|
|
559
|
+
let diag = row[0];
|
|
560
|
+
row[0] = i;
|
|
561
|
+
for (let j = 1; j <= b.length; j++) {
|
|
562
|
+
const up = row[j];
|
|
563
|
+
row[j] = Math.min(up + 1, row[j - 1] + 1, diag + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
564
|
+
diag = up;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return row[b.length];
|
|
568
|
+
}
|
|
569
|
+
const PROBED_NAMES = /* @__PURE__ */ new Set(["then", "toJSON", "asymmetricMatch", "nodeType", "tagName", "inspect", "default"]);
|
|
570
|
+
function strictNamespace(name, members) {
|
|
571
|
+
return new Proxy(members, {
|
|
572
|
+
get(target, prop, receiver) {
|
|
573
|
+
if (typeof prop === "symbol" || prop in target || PROBED_NAMES.has(prop) || /^[_$@]/.test(prop)) {
|
|
574
|
+
return Reflect.get(target, prop, receiver);
|
|
575
|
+
}
|
|
576
|
+
const keys = Object.keys(target);
|
|
577
|
+
const lower = prop.toLowerCase();
|
|
578
|
+
const ranked = keys.map((k) => ({ k, d: editDistance(lower, k.toLowerCase()) })).filter(({ k, d }) => {
|
|
579
|
+
const key = k.toLowerCase();
|
|
580
|
+
return d <= Math.max(1, Math.floor(prop.length / 3)) || key.includes(lower) || key.length >= 3 && lower.includes(key);
|
|
581
|
+
}).sort((x, y) => x.d - y.d).slice(0, 3).map(({ k }) => `${name}.${k}`);
|
|
582
|
+
throw new TypeError(
|
|
583
|
+
`${name}.${prop} does not exist.` + (ranked.length ? ` Did you mean ${ranked.join(", ")}?` : "") + " See docs/inventory.md for the supported functions."
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
function outsideBarLoops(members) {
|
|
589
|
+
const out = {};
|
|
590
|
+
for (const [key, value] of Object.entries(members)) {
|
|
591
|
+
if (typeof value !== "function") {
|
|
592
|
+
out[key] = value;
|
|
593
|
+
continue;
|
|
594
|
+
}
|
|
595
|
+
const fn = value;
|
|
596
|
+
out[key] = function(...args) {
|
|
597
|
+
if (currentBar >= 0) {
|
|
598
|
+
throw new Error(
|
|
599
|
+
`ta.${key}() was called inside eachBar(): a ta.* call computes the whole Series at once. Compute it before the loop (const x = ta.${key}(...)) and read the bar's value with c.get(x). For a Pine ta.* call inside an if block or a for loop, use the callsite.* call sites.`
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
return fn.apply(this, args);
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
return out;
|
|
606
|
+
}
|
|
607
|
+
const ta = strictNamespace("ta", outsideBarLoops({
|
|
473
608
|
...taSeries,
|
|
474
609
|
tr: (handleNa = false) => taSeries.tr(bars(), handleNa),
|
|
475
610
|
atr: (length) => taSeries.atr(bars(), length),
|
|
@@ -496,6 +631,8 @@ const ta = {
|
|
|
496
631
|
const a = anchor ?? vwapAnchor();
|
|
497
632
|
return stdev_mult === void 0 ? taSeries.vwap(source, volume, a) : taSeries.vwapBands(source, volume, a, stdev_mult);
|
|
498
633
|
}),
|
|
634
|
+
/** `ta.vwma(source, length)` with the chart volume, as PineScript; a third argument gives another volume. */
|
|
635
|
+
vwma: (source, length, vol) => taSeries.vwma(source, length, vol ?? volume),
|
|
499
636
|
/** `ta.mfi(source, length)` with the chart volume (PineScript takes 2 arguments). */
|
|
500
637
|
mfi: (source, length) => taSeries.mfi(source, length, volume),
|
|
501
638
|
/** `ta.pivothigh(source, leftbars, rightbars)` or `ta.pivothigh(leftbars, rightbars)` (source = high).
|
|
@@ -512,7 +649,7 @@ const ta = {
|
|
|
512
649
|
iii: barsSeries(taSeries.iii),
|
|
513
650
|
wad: barsSeries(taSeries.wad),
|
|
514
651
|
wvad: barsSeries(taSeries.wvad)
|
|
515
|
-
};
|
|
652
|
+
}));
|
|
516
653
|
function fixnan(source) {
|
|
517
654
|
if (source instanceof import_series.Series) return import_series.Series.fromArray(ctxBars, (0, import_utils.fixnan)(source.toArray()));
|
|
518
655
|
return withPalette((0, import_utils.fixnan)(source), colorPalettes.get(source));
|
|
@@ -530,11 +667,11 @@ function colorWhen(cond, colorTrue, colorFalse) {
|
|
|
530
667
|
const palette = [colorTrue, ...colorFalse !== void 0 && colorFalse !== colorTrue ? [colorFalse] : []];
|
|
531
668
|
return withPalette(colors, palette);
|
|
532
669
|
}
|
|
533
|
-
const color = {
|
|
670
|
+
const color = strictNamespace("color", {
|
|
534
671
|
...colorCore,
|
|
535
672
|
new: colorCore.new_color,
|
|
536
673
|
when: colorWhen
|
|
537
|
-
};
|
|
674
|
+
});
|
|
538
675
|
const DEFAULT_OUTPUT_TITLES = {
|
|
539
676
|
plot: "Plot",
|
|
540
677
|
hline: "Level",
|
|
@@ -571,10 +708,12 @@ function plotImpl(series, title = DEFAULT_OUTPUT_TITLES.plot, options = {}) {
|
|
|
571
708
|
const values = series.toArray();
|
|
572
709
|
const b = bars();
|
|
573
710
|
const data = [];
|
|
574
|
-
|
|
711
|
+
const off = Math.trunc(options.offset ?? 0);
|
|
712
|
+
for (let j = Math.max(0, off); j < b.length && j - off < b.length; j++) {
|
|
713
|
+
const i = j - off;
|
|
575
714
|
const value = values[i];
|
|
576
715
|
if (value === void 0 || !Number.isFinite(value)) continue;
|
|
577
|
-
data.push(perBar2 ? { time: b[
|
|
716
|
+
data.push(perBar2 ? { time: b[j].time, value, color: perBar2[i] } : { time: b[j].time, value });
|
|
578
717
|
}
|
|
579
718
|
c.plots[id] = data;
|
|
580
719
|
return { id, kind: "plot" };
|
|
@@ -702,8 +841,8 @@ const MARKER_SHAPES = {
|
|
|
702
841
|
square: "square",
|
|
703
842
|
diamond: "diamond"
|
|
704
843
|
};
|
|
705
|
-
function markerPosition(
|
|
706
|
-
switch (
|
|
844
|
+
function markerPosition(location2, shape2) {
|
|
845
|
+
switch (location2) {
|
|
707
846
|
case "abovebar":
|
|
708
847
|
return "aboveBar";
|
|
709
848
|
case "belowbar":
|
|
@@ -713,7 +852,7 @@ function markerPosition(location, shape) {
|
|
|
713
852
|
case "bottom":
|
|
714
853
|
return "bottom";
|
|
715
854
|
case "absolute":
|
|
716
|
-
return
|
|
855
|
+
return shape2 === "labeldown" ? "atPriceTop" : shape2 === "labelup" ? "atPriceBottom" : "atPriceMiddle";
|
|
717
856
|
}
|
|
718
857
|
}
|
|
719
858
|
const MARKER_COLOR = "#2962FF";
|
|
@@ -733,14 +872,14 @@ function emitMarkers(kind, condition, title, options) {
|
|
|
733
872
|
title ??= DEFAULT_OUTPUT_TITLES[kind];
|
|
734
873
|
const style = kind === "shape" ? options.style ?? "xcross" : "char";
|
|
735
874
|
const char = kind === "char" ? options.char ?? "*" : void 0;
|
|
736
|
-
const
|
|
875
|
+
const location2 = options.location ?? "abovebar";
|
|
737
876
|
c.shapeConfig.push({
|
|
738
877
|
id,
|
|
739
878
|
kind,
|
|
740
879
|
title,
|
|
741
880
|
style: kind === "shape" ? style : void 0,
|
|
742
881
|
char,
|
|
743
|
-
location,
|
|
882
|
+
location: location2,
|
|
744
883
|
color: options.color,
|
|
745
884
|
text: options.text,
|
|
746
885
|
textcolor: options.textcolor,
|
|
@@ -752,7 +891,7 @@ function emitMarkers(kind, condition, title, options) {
|
|
|
752
891
|
c.outputs.push({ kind, id, title });
|
|
753
892
|
const shapeStyle = kind === "shape" ? style : void 0;
|
|
754
893
|
const template = {
|
|
755
|
-
position: markerPosition(
|
|
894
|
+
position: markerPosition(location2, shapeStyle),
|
|
756
895
|
shape: shapeStyle ? MARKER_SHAPES[shapeStyle] : "circle",
|
|
757
896
|
color: options.color ?? MARKER_COLOR,
|
|
758
897
|
id
|
|
@@ -773,7 +912,7 @@ function emitMarkers(kind, condition, title, options) {
|
|
|
773
912
|
const j = i + off;
|
|
774
913
|
if (j < 0 || j >= b.length) continue;
|
|
775
914
|
const time2 = b[j].time;
|
|
776
|
-
c.markers.push(
|
|
915
|
+
c.markers.push(location2 === "absolute" ? { time: time2, ...template, price: v } : { time: time2, ...template });
|
|
777
916
|
}
|
|
778
917
|
}
|
|
779
918
|
function plotshape(condition, title, options = {}) {
|
|
@@ -1337,8 +1476,8 @@ function symbolScale() {
|
|
|
1337
1476
|
collector();
|
|
1338
1477
|
const { minmove, pricescale } = chartCtx;
|
|
1339
1478
|
if (minmove !== void 0 && pricescale !== void 0) return [minmove, pricescale];
|
|
1340
|
-
const [move,
|
|
1341
|
-
return [minmove ?? move,
|
|
1479
|
+
const [move, scale2] = (0, import_numberformat.tickScale)(symbolProperty("mintick"), pricescale);
|
|
1480
|
+
return [minmove ?? move, scale2];
|
|
1342
1481
|
}
|
|
1343
1482
|
const syminfo = {
|
|
1344
1483
|
get mintick() {
|
|
@@ -1396,7 +1535,7 @@ const year = calendar(timeCore.year);
|
|
|
1396
1535
|
const month = calendar(timeCore.month);
|
|
1397
1536
|
const weekofyear = calendar(timeCore.weekofyear);
|
|
1398
1537
|
const dayofmonth = calendar(timeCore.dayofmonth);
|
|
1399
|
-
const dayofweek = calendar(timeCore.dayofweek);
|
|
1538
|
+
const dayofweek = Object.assign(calendar(timeCore.dayofweek), pineConstants.daysOfWeek);
|
|
1400
1539
|
const hour = calendar(timeCore.hour);
|
|
1401
1540
|
const minute = calendar(timeCore.minute);
|
|
1402
1541
|
const second = calendar(timeCore.second);
|
|
@@ -1412,17 +1551,17 @@ function timestamp(first, ...rest) {
|
|
|
1412
1551
|
function inSession(time2, session2, timezone) {
|
|
1413
1552
|
return timeCore.inSession(time2, session2, timezone ?? exchangeTimezone());
|
|
1414
1553
|
}
|
|
1415
|
-
const str = {
|
|
1554
|
+
const str = strictNamespace("str", {
|
|
1416
1555
|
...strCore,
|
|
1417
1556
|
// format.mintick uses the chart symbol's tick and price scale (syminfo.mintick, syminfo.pricescale)
|
|
1418
|
-
tostring: ((value,
|
|
1419
|
-
format_time(time2,
|
|
1420
|
-
return strCore.format_time(time2,
|
|
1557
|
+
tostring: ((value, format2, mintick, pricescale) => format2 === "mintick" && mintick === void 0 ? strCore.tostring(value, format2, syminfo.mintick, pricescale ?? syminfo.pricescale) : strCore.tostring(value, format2, mintick, pricescale)),
|
|
1558
|
+
format_time(time2, format2 = "yyyy-MM-dd'T'HH:mm:ssZ", timezone) {
|
|
1559
|
+
return strCore.format_time(time2, format2, timezone ?? exchangeTimezone());
|
|
1421
1560
|
},
|
|
1422
1561
|
format(pattern, ...args) {
|
|
1423
1562
|
return (0, import_messageformat.formatMessage)(pattern, args, exchangeTimezone);
|
|
1424
1563
|
}
|
|
1425
|
-
};
|
|
1564
|
+
});
|
|
1426
1565
|
function barTime(bar) {
|
|
1427
1566
|
return bar.time * (chartCtx.timeUnit === "ms" ? 1 : 1e3);
|
|
1428
1567
|
}
|
|
@@ -1734,44 +1873,45 @@ function security_lower_tf(symbol, timeframe2, expression, ignore_invalid_symbol
|
|
|
1734
1873
|
const mapped = values.map((v) => ranges.map(([from, to]) => v.slice(from, to)));
|
|
1735
1874
|
return Array.isArray(result) ? mapped : mapped[0];
|
|
1736
1875
|
}
|
|
1737
|
-
const
|
|
1738
|
-
const
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
}
|
|
1743
|
-
};
|
|
1744
|
-
const label = {
|
|
1745
|
-
...labelCore,
|
|
1746
|
-
get all() {
|
|
1747
|
-
return labelCore.all();
|
|
1876
|
+
const SECURITY_PARAMETERS = ["symbol", "timeframe", "expression", "gaps", "lookahead", "ignore_invalid_symbol", "currency", "calc_bars_count"];
|
|
1877
|
+
const SECURITY_LOWER_TF_PARAMETERS = ["symbol", "timeframe", "expression", "ignore_invalid_symbol", "currency", "ignore_invalid_timeframe", "calc_bars_count"];
|
|
1878
|
+
function unsupportedSecurityArgs(name, currency2, calcBarsCount) {
|
|
1879
|
+
if (currency2 !== void 0 && currency2 !== "" && currency2 !== "NONE") {
|
|
1880
|
+
throw new Error(`${name}(): the currency argument (conversion of the values) is not supported.`);
|
|
1748
1881
|
}
|
|
1749
|
-
};
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
}
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
}
|
|
1762
|
-
const
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
const
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1882
|
+
if (calcBarsCount !== void 0) throw new Error(`${name}(): the calc_bars_count argument is not supported.`);
|
|
1883
|
+
}
|
|
1884
|
+
function securityCall(...args) {
|
|
1885
|
+
const a = (0, import_drawing_args.namedArguments)("request.security", SECURITY_PARAMETERS, args);
|
|
1886
|
+
unsupportedSecurityArgs("request.security", a[6], a[7]);
|
|
1887
|
+
return security(a[0], a[1], a[2], a[3], a[4], a[5]);
|
|
1888
|
+
}
|
|
1889
|
+
function securityLowerTfCall(...args) {
|
|
1890
|
+
const a = (0, import_drawing_args.namedArguments)("request.security_lower_tf", SECURITY_LOWER_TF_PARAMETERS, args);
|
|
1891
|
+
unsupportedSecurityArgs("request.security_lower_tf", a[4], a[6]);
|
|
1892
|
+
if (a[5] !== void 0 && a[5] !== false) throw new Error("request.security_lower_tf(): the ignore_invalid_timeframe argument is not supported.");
|
|
1893
|
+
return security_lower_tf(a[0], a[1], a[2], a[3]);
|
|
1894
|
+
}
|
|
1895
|
+
const request = strictNamespace("request", { security: securityCall, security_lower_tf: securityLowerTfCall });
|
|
1896
|
+
const loopBar = () => currentBar;
|
|
1897
|
+
function drawings(name, members, all) {
|
|
1898
|
+
const out = (0, import_drawing_args.drawingNamespace)(name, members, loopBar);
|
|
1899
|
+
return Object.defineProperty(out, "all", { get: all, enumerable: true });
|
|
1900
|
+
}
|
|
1901
|
+
const lineNs = drawings("line", { ...lineCore, ...pineConstants.lineStyles }, () => lineCore.all());
|
|
1902
|
+
const line = lineNs;
|
|
1903
|
+
const labelNs = drawings("label", { ...labelCore, ...pineConstants.labelStyles }, () => labelCore.all());
|
|
1904
|
+
const label = labelNs;
|
|
1905
|
+
const boxNs = drawings("box", { ...boxCore }, () => boxCore.all());
|
|
1906
|
+
const box = boxNs;
|
|
1907
|
+
const linefillNs = drawings("linefill", { ...linefillCore }, () => linefillCore.all());
|
|
1908
|
+
const linefill = linefillNs;
|
|
1909
|
+
const polylineNs = drawings("polyline", { ...polylineCore }, () => polylineCore.all());
|
|
1910
|
+
const polyline = polylineNs;
|
|
1911
|
+
const tableNs = drawings("table", { ...tableCore }, () => tableCore.all());
|
|
1912
|
+
const table = tableNs;
|
|
1774
1913
|
const text = { ...textCore };
|
|
1914
|
+
const { shape, location, size, xloc, yloc, extend, display, format, font, scale, order, currency, adjustment } = pineConstants;
|
|
1775
1915
|
const chart = {
|
|
1776
1916
|
/** Chart foreground colour (PineScript `chart.fg_color`), from the chart context. */
|
|
1777
1917
|
get fg_color() {
|
|
@@ -1836,11 +1976,11 @@ const alert = Object.assign(alertImpl, {
|
|
|
1836
1976
|
const { saveRandom: _saveRandom, restoreRandom: _restoreRandom, ...mathScript } = mathCore;
|
|
1837
1977
|
void _saveRandom;
|
|
1838
1978
|
void _restoreRandom;
|
|
1839
|
-
const math = {
|
|
1979
|
+
const math = strictNamespace("math", {
|
|
1840
1980
|
...mathScript,
|
|
1841
1981
|
round_to_mintick: ((number, mintick) => {
|
|
1842
1982
|
const tick = mintick ?? syminfo.mintick;
|
|
1843
1983
|
return number instanceof import_series.Series ? mathCore.round_to_mintick(number, tick) : mathCore.round_to_mintick(number, tick);
|
|
1844
1984
|
})
|
|
1845
|
-
};
|
|
1985
|
+
});
|
|
1846
1986
|
//# sourceMappingURL=index.js.map
|