oakscriptjs 0.10.1 → 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.d.ts.map +1 -1
- package/dist/cjs/box/index.js +7 -1
- package/dist/cjs/box/index.js.map +2 -2
- package/dist/cjs/callsite/index.d.ts +73 -32
- package/dist/cjs/callsite/index.d.ts.map +1 -1
- package/dist/cjs/callsite/index.js +69 -65
- package/dist/cjs/callsite/index.js.map +2 -2
- package/dist/cjs/drawing/registry.d.ts +84 -0
- package/dist/cjs/drawing/registry.d.ts.map +1 -1
- package/dist/cjs/drawing/registry.js +153 -6
- package/dist/cjs/drawing/registry.js.map +2 -2
- package/dist/cjs/index.d.ts +8 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +33 -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.d.ts.map +1 -1
- package/dist/cjs/label/index.js +3 -0
- 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 +11 -22
- 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/math/index.d.ts.map +1 -1
- package/dist/cjs/math/index.js +2 -0
- package/dist/cjs/math/index.js.map +2 -2
- package/dist/cjs/polyline/index.d.ts.map +1 -1
- package/dist/cjs/polyline/index.js +3 -0
- package/dist/cjs/polyline/index.js.map +2 -2
- 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 +91 -21
- package/dist/cjs/script/index.d.ts.map +1 -1
- package/dist/cjs/script/index.js +207 -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 +24 -1
- package/dist/cjs/session/bars.d.ts.map +1 -1
- package/dist/cjs/session/bars.js +56 -7
- package/dist/cjs/session/bars.js.map +3 -3
- package/dist/cjs/session/calendar.d.ts +13 -2
- package/dist/cjs/session/calendar.d.ts.map +1 -1
- package/dist/cjs/session/calendar.js +39 -9
- package/dist/cjs/session/calendar.js.map +2 -2
- package/dist/cjs/session/context.d.ts +76 -0
- package/dist/cjs/session/context.d.ts.map +1 -0
- package/dist/cjs/session/context.js +114 -0
- package/dist/cjs/session/context.js.map +7 -0
- 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 -1
- package/dist/cjs/str/index.d.ts.map +1 -1
- package/dist/cjs/str/index.js +2 -1
- package/dist/cjs/str/index.js.map +2 -2
- package/dist/cjs/str/numberformat.d.ts +7 -3
- package/dist/cjs/str/numberformat.d.ts.map +1 -1
- package/dist/cjs/str/numberformat.js +4 -3
- package/dist/cjs/str/numberformat.js.map +2 -2
- package/dist/cjs/ta/index.d.ts +67 -34
- package/dist/cjs/ta/index.d.ts.map +1 -1
- package/dist/cjs/ta/index.js +202 -145
- package/dist/cjs/ta/index.js.map +2 -2
- package/dist/cjs/ta/limits.d.ts +35 -0
- package/dist/cjs/ta/limits.d.ts.map +1 -0
- package/dist/cjs/ta/limits.js +64 -0
- package/dist/cjs/ta/limits.js.map +7 -0
- package/dist/cjs/ta/running-sum.d.ts +0 -16
- package/dist/cjs/ta/running-sum.d.ts.map +1 -1
- package/dist/cjs/ta/running-sum.js +2 -0
- package/dist/cjs/ta/running-sum.js.map +2 -2
- package/dist/cjs/ta-series.d.ts +8 -8
- package/dist/cjs/ta-series.d.ts.map +1 -1
- package/dist/cjs/ta-series.js +10 -8
- 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/index.d.ts +5 -2
- package/dist/cjs/time/index.d.ts.map +1 -1
- package/dist/cjs/time/index.js +2 -2
- package/dist/cjs/time/index.js.map +2 -2
- package/dist/cjs/time/session.d.ts +26 -1
- package/dist/cjs/time/session.d.ts.map +1 -1
- package/dist/cjs/time/session.js +94 -12
- 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 +28 -4
- 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.d.ts.map +1 -1
- package/dist/esm/box/index.js +8 -2
- package/dist/esm/box/index.js.map +1 -1
- package/dist/esm/callsite/index.d.ts +73 -32
- package/dist/esm/callsite/index.d.ts.map +1 -1
- package/dist/esm/callsite/index.js +143 -106
- package/dist/esm/callsite/index.js.map +1 -1
- package/dist/esm/drawing/registry.d.ts +84 -0
- package/dist/esm/drawing/registry.d.ts.map +1 -1
- package/dist/esm/drawing/registry.js +260 -6
- package/dist/esm/drawing/registry.js.map +1 -1
- package/dist/esm/index.d.ts +8 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +13 -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.d.ts.map +1 -1
- package/dist/esm/label/index.js +4 -1
- 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 +22 -60
- 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/math/index.d.ts.map +1 -1
- package/dist/esm/math/index.js +3 -0
- package/dist/esm/math/index.js.map +1 -1
- package/dist/esm/polyline/index.d.ts.map +1 -1
- package/dist/esm/polyline/index.js +5 -1
- package/dist/esm/polyline/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 +91 -21
- package/dist/esm/script/index.d.ts.map +1 -1
- package/dist/esm/script/index.js +259 -28
- 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 +24 -1
- package/dist/esm/session/bars.d.ts.map +1 -1
- package/dist/esm/session/bars.js +75 -6
- package/dist/esm/session/bars.js.map +1 -1
- package/dist/esm/session/calendar.d.ts +13 -2
- package/dist/esm/session/calendar.d.ts.map +1 -1
- package/dist/esm/session/calendar.js +54 -10
- package/dist/esm/session/calendar.js.map +1 -1
- package/dist/esm/session/context.d.ts +76 -0
- package/dist/esm/session/context.d.ts.map +1 -0
- package/dist/esm/session/context.js +124 -0
- package/dist/esm/session/context.js.map +1 -0
- 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 -1
- package/dist/esm/str/index.d.ts.map +1 -1
- package/dist/esm/str/index.js +9 -2
- package/dist/esm/str/index.js.map +1 -1
- package/dist/esm/str/numberformat.d.ts +7 -3
- package/dist/esm/str/numberformat.d.ts.map +1 -1
- package/dist/esm/str/numberformat.js +11 -5
- package/dist/esm/str/numberformat.js.map +1 -1
- package/dist/esm/ta/index.d.ts +67 -34
- package/dist/esm/ta/index.d.ts.map +1 -1
- package/dist/esm/ta/index.js +284 -240
- package/dist/esm/ta/index.js.map +1 -1
- package/dist/esm/ta/limits.d.ts +35 -0
- package/dist/esm/ta/limits.d.ts.map +1 -0
- package/dist/esm/ta/limits.js +67 -0
- package/dist/esm/ta/limits.js.map +1 -0
- package/dist/esm/ta/running-sum.d.ts +0 -16
- package/dist/esm/ta/running-sum.d.ts.map +1 -1
- package/dist/esm/ta/running-sum.js +2 -0
- package/dist/esm/ta/running-sum.js.map +1 -1
- package/dist/esm/ta-series.d.ts +8 -8
- package/dist/esm/ta-series.d.ts.map +1 -1
- package/dist/esm/ta-series.js +11 -8
- 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/index.d.ts +5 -2
- package/dist/esm/time/index.d.ts.map +1 -1
- package/dist/esm/time/index.js +6 -3
- package/dist/esm/time/index.js.map +1 -1
- package/dist/esm/time/session.d.ts +26 -1
- package/dist/esm/time/session.d.ts.map +1 -1
- package/dist/esm/time/session.js +141 -16
- 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 +28 -4
- 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 +8 -2
- package/src/callsite/index.ts +150 -100
- package/src/drawing/registry.ts +278 -5
- package/src/index.ts +44 -1
- package/src/input.ts +18 -1
- package/src/label/index.ts +4 -1
- package/src/line/index.ts +22 -64
- package/src/linefill/index.ts +20 -1
- package/src/math/index.ts +2 -0
- package/src/polyline/index.ts +3 -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 +355 -34
- package/src/security/other.ts +269 -0
- package/src/session/bars.ts +70 -6
- package/src/session/calendar.ts +60 -10
- package/src/session/context.ts +162 -0
- package/src/str/floatingdecimal.ts +268 -0
- package/src/str/index.ts +8 -2
- package/src/str/numberformat.ts +13 -6
- package/src/ta/index.ts +304 -248
- package/src/ta/limits.ts +74 -0
- package/src/ta/running-sum.ts +2 -0
- package/src/ta-series.ts +19 -16
- package/src/table/index.ts +4 -1
- package/src/time/index.ts +6 -3
- package/src/time/session.ts +137 -15
- package/src/time/timezone.ts +9 -2
- package/src/types/metadata.ts +28 -4
package/dist/cjs/script/index.js
CHANGED
|
@@ -29,6 +29,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
var script_exports = {};
|
|
30
30
|
__export(script_exports, {
|
|
31
31
|
BarData: () => import_series.BarData,
|
|
32
|
+
MissingSymbolDataError: () => MissingSymbolDataError,
|
|
32
33
|
STRATEGY_DEFAULTS: () => import_strategy2.STRATEGY_DEFAULTS,
|
|
33
34
|
Series: () => import_series.Series,
|
|
34
35
|
alertcondition: () => alertcondition,
|
|
@@ -52,6 +53,7 @@ __export(script_exports, {
|
|
|
52
53
|
hlc3: () => hlc3,
|
|
53
54
|
hlcc4: () => hlcc4,
|
|
54
55
|
hline: () => hline,
|
|
56
|
+
holdDrawing: () => import_registry2.holdDrawing,
|
|
55
57
|
hour: () => hour,
|
|
56
58
|
inSession: () => inSession,
|
|
57
59
|
indicator: () => indicator,
|
|
@@ -76,6 +78,7 @@ __export(script_exports, {
|
|
|
76
78
|
plotshape: () => plotshape,
|
|
77
79
|
polyline: () => polyline,
|
|
78
80
|
position: () => import_types.position,
|
|
81
|
+
releaseDrawing: () => import_registry2.releaseDrawing,
|
|
79
82
|
request: () => request,
|
|
80
83
|
second: () => second,
|
|
81
84
|
seriesOf: () => seriesOf,
|
|
@@ -91,7 +94,9 @@ __export(script_exports, {
|
|
|
91
94
|
time_close: () => time_close,
|
|
92
95
|
time_tradingday: () => time_tradingday,
|
|
93
96
|
timeframe: () => timeframe,
|
|
97
|
+
timenow: () => timenow,
|
|
94
98
|
timestamp: () => timestamp,
|
|
99
|
+
varDrawing: () => import_registry2.varDrawing,
|
|
95
100
|
volume: () => volume,
|
|
96
101
|
weekofyear: () => weekofyear,
|
|
97
102
|
year: () => year
|
|
@@ -112,6 +117,7 @@ var chartPointCore = __toESM(require("../chartpoint/index.js"), 1);
|
|
|
112
117
|
var textCore = __toESM(require("../text/index.js"), 1);
|
|
113
118
|
var mathCore = __toESM(require("../math/index.js"), 1);
|
|
114
119
|
var import_registry = require("../drawing/registry.js");
|
|
120
|
+
var import_registry2 = require("../drawing/registry.js");
|
|
115
121
|
var import_output = require("../drawing/output.js");
|
|
116
122
|
var timeframeCore = __toESM(require("../timeframe/index.js"), 1);
|
|
117
123
|
var timeCore = __toESM(require("../time/index.js"), 1);
|
|
@@ -121,6 +127,7 @@ var import_numberformat = require("../str/numberformat.js");
|
|
|
121
127
|
var import_calendar = require("../session/calendar.js");
|
|
122
128
|
var import_bars = require("../session/bars.js");
|
|
123
129
|
var import_resample = require("../security/resample.js");
|
|
130
|
+
var import_other = require("../security/other.js");
|
|
124
131
|
var import_types = require("../types/index.js");
|
|
125
132
|
var import_strategy = require("../strategy/index.js");
|
|
126
133
|
var import_session = require("../time/session.js");
|
|
@@ -175,12 +182,15 @@ let scriptOptions = {};
|
|
|
175
182
|
function executeScript(body, barsInput, inputs = {}, chart2 = {}, options = {}) {
|
|
176
183
|
ctxBars.setAll(barsInput);
|
|
177
184
|
chartCtx = { ...chart2 };
|
|
185
|
+
runNow = chart2.now ?? Date.now();
|
|
178
186
|
scriptOptions = options;
|
|
179
187
|
ctx = freshCollector(inputs);
|
|
180
188
|
(0, import_registry.resetDrawings)();
|
|
181
189
|
mathCore.resetRandom();
|
|
190
|
+
missingSymbols = [];
|
|
182
191
|
try {
|
|
183
192
|
body();
|
|
193
|
+
if (missingSymbols.length) throw new MissingSymbolDataError(missingSymbols);
|
|
184
194
|
const c = ctx;
|
|
185
195
|
return {
|
|
186
196
|
metadata: {
|
|
@@ -304,6 +314,10 @@ const input = {
|
|
|
304
314
|
"input_session"
|
|
305
315
|
);
|
|
306
316
|
},
|
|
317
|
+
/** Ticker id ("NASDAQ:MSFT"), for `request.security` of another symbol (#180). */
|
|
318
|
+
symbol(defval, title, opts = {}) {
|
|
319
|
+
return registerInput({ type: "symbol", defval, title, options: opts.options, ...common(opts) }, "input_symbol");
|
|
320
|
+
},
|
|
307
321
|
/** Date and time as a UNIX time in milliseconds, e.g. `input.time(timestamp('2024-01-01'), 'Start')`. */
|
|
308
322
|
time(defval, title, opts = {}) {
|
|
309
323
|
const v = registerInput({ type: "time", defval, title, ...common(opts) }, "input_time");
|
|
@@ -355,10 +369,12 @@ const ta = {
|
|
|
355
369
|
highestbars: (sourceOrLength, length) => typeof sourceOrLength === "number" ? taSeries.highestbars(high, sourceOrLength) : taSeries.highestbars(sourceOrLength, length),
|
|
356
370
|
/** `ta.lowestbars(source, length)` or `ta.lowestbars(length)` (source = low); offsets are 0 or negative. */
|
|
357
371
|
lowestbars: (sourceOrLength, length) => typeof sourceOrLength === "number" ? taSeries.lowestbars(low, sourceOrLength) : taSeries.lowestbars(sourceOrLength, length),
|
|
358
|
-
/** `ta.vwap(source, anchor?, stdev_mult?)` with the chart volume; the default anchor is a new trading
|
|
359
|
-
*
|
|
372
|
+
/** `ta.vwap(source, anchor?, stdev_mult?)` with the chart volume; the default anchor is a new trading day
|
|
373
|
+
* and the first bar: as in PineScript, the first loaded bars (a day in progress) have a value. On D / W / M
|
|
374
|
+
* charts every bar is a new day (no time zone or session needed); on intraday charts it needs the chart context
|
|
375
|
+
* (timeframe, time zone, session). */
|
|
360
376
|
vwap: ((source, anchor, stdev_mult) => {
|
|
361
|
-
const a = anchor ??
|
|
377
|
+
const a = anchor ?? vwapAnchor();
|
|
362
378
|
return stdev_mult === void 0 ? taSeries.vwap(source, volume, a) : taSeries.vwapBands(source, volume, a, stdev_mult);
|
|
363
379
|
}),
|
|
364
380
|
/** `ta.mfi(source, length)` with the chart volume (PineScript takes 2 arguments). */
|
|
@@ -758,6 +774,7 @@ function eachBar(fn) {
|
|
|
758
774
|
for (idx = 0; idx < b.length; idx++) {
|
|
759
775
|
if (pendingError && pendingError.bar === idx) throw new Error((0, import_series.historyError)(idx, pendingError.barsBack));
|
|
760
776
|
currentBar = idx;
|
|
777
|
+
(0, import_registry.setDrawingBar)(idx, idx === b.length - 1, b.length - 1);
|
|
761
778
|
const r = fn(ctx2);
|
|
762
779
|
out[idx] = typeof r === "number" ? r : typeof r === "boolean" ? r ? 1 : 0 : NaN;
|
|
763
780
|
for (const buffer of buffers.values()) {
|
|
@@ -773,6 +790,7 @@ function eachBar(fn) {
|
|
|
773
790
|
}
|
|
774
791
|
} finally {
|
|
775
792
|
currentBar = -1;
|
|
793
|
+
(0, import_registry.setDrawingBar)(null);
|
|
776
794
|
}
|
|
777
795
|
return import_series.Series.fromArray(ctxBars, out);
|
|
778
796
|
}
|
|
@@ -918,6 +936,17 @@ const strategy = Object.defineProperties(
|
|
|
918
936
|
Object.assign((title, options) => declareStrategy(title, options), strategyMembers),
|
|
919
937
|
variableGetters
|
|
920
938
|
);
|
|
939
|
+
class MissingSymbolDataError extends Error {
|
|
940
|
+
constructor(requests) {
|
|
941
|
+
super(
|
|
942
|
+
`request.security needs the bars of ${requests.map((r) => `${r.symbol} (${r.timeframe})`).join(", ")}: pass them with ChartContext.bars.`
|
|
943
|
+
);
|
|
944
|
+
this.requests = requests;
|
|
945
|
+
this.name = "MissingSymbolDataError";
|
|
946
|
+
}
|
|
947
|
+
requests;
|
|
948
|
+
}
|
|
949
|
+
let missingSymbols = [];
|
|
921
950
|
let chartCtx = {};
|
|
922
951
|
function chartTimeframe() {
|
|
923
952
|
collector();
|
|
@@ -988,6 +1017,14 @@ function symbolProperty(key) {
|
|
|
988
1017
|
}
|
|
989
1018
|
return value;
|
|
990
1019
|
}
|
|
1020
|
+
function chartText(key, name) {
|
|
1021
|
+
collector();
|
|
1022
|
+
const value = chartCtx[key];
|
|
1023
|
+
if (value === void 0) {
|
|
1024
|
+
throw new Error(`${name} is not known: pass it as executeScript(body, bars, inputs, { ${key} }).`);
|
|
1025
|
+
}
|
|
1026
|
+
return value;
|
|
1027
|
+
}
|
|
991
1028
|
function symbolScale() {
|
|
992
1029
|
collector();
|
|
993
1030
|
const { minmove, pricescale } = chartCtx;
|
|
@@ -1024,6 +1061,18 @@ const syminfo = {
|
|
|
1024
1061
|
get session() {
|
|
1025
1062
|
collector();
|
|
1026
1063
|
return chartCtx.sessionType ?? "regular";
|
|
1064
|
+
},
|
|
1065
|
+
get type() {
|
|
1066
|
+
return chartText("symbolType", "syminfo.type");
|
|
1067
|
+
},
|
|
1068
|
+
get currency() {
|
|
1069
|
+
return chartText("currency", "syminfo.currency");
|
|
1070
|
+
},
|
|
1071
|
+
get basecurrency() {
|
|
1072
|
+
return chartText("basecurrency", "syminfo.basecurrency");
|
|
1073
|
+
},
|
|
1074
|
+
get root() {
|
|
1075
|
+
return chartText("root", "syminfo.root");
|
|
1027
1076
|
}
|
|
1028
1077
|
};
|
|
1029
1078
|
function calendar(fn) {
|
|
@@ -1085,7 +1134,7 @@ function sessionBars() {
|
|
|
1085
1134
|
}
|
|
1086
1135
|
return sessionCache;
|
|
1087
1136
|
}
|
|
1088
|
-
function calendarFor(session2, timezone) {
|
|
1137
|
+
function calendarFor(session2, timezone, dayPlacement = false) {
|
|
1089
1138
|
const { bars: bars2 } = sessionBars();
|
|
1090
1139
|
if (!session2 && !timezone) return { bars: bars2, test: false };
|
|
1091
1140
|
const tz = timezone ?? exchangeTimezone();
|
|
@@ -1095,7 +1144,12 @@ function calendarFor(session2, timezone) {
|
|
|
1095
1144
|
return { bars: new import_bars.SessionBars(new import_calendar.TradingCalendar(tz, { session: toSpec(symbol).session }, "symbol"), bars2.chart.period), test: true };
|
|
1096
1145
|
}
|
|
1097
1146
|
const spec = session2 ? { session: session2 } : { session: toSpec(chartCtx.session).session };
|
|
1098
|
-
return {
|
|
1147
|
+
return {
|
|
1148
|
+
bars: new import_bars.SessionBars(new import_calendar.TradingCalendar(tz, spec, session2 ? "pine" : "symbol", dayPlacement), bars2.chart.period),
|
|
1149
|
+
test: true,
|
|
1150
|
+
// a PineScript session string: the rules of time.inSession (runs ending at 0000, days around a clock change)
|
|
1151
|
+
inside: session2 ? (time2) => timeCore.inSession(time2, session2, tz, timeframeCore.in_seconds(bars2.chart.period) * 1e3) : void 0
|
|
1152
|
+
};
|
|
1099
1153
|
}
|
|
1100
1154
|
function perBar(fn) {
|
|
1101
1155
|
const times = ctxBars.bars.map(barTime);
|
|
@@ -1106,27 +1160,73 @@ function callableSeries(series, fn) {
|
|
|
1106
1160
|
Object.assign(fn, series);
|
|
1107
1161
|
return fn;
|
|
1108
1162
|
}
|
|
1163
|
+
function sessionPeriods(timeframeString, session2, timezone) {
|
|
1164
|
+
const tf = timeframeCore.info(timeframeString);
|
|
1165
|
+
const { bars: bars2, test, inside } = calendarFor(session2, timezone, !tf.isintraday);
|
|
1166
|
+
const open2 = (t) => bars2.timeOf(t, timeframeString);
|
|
1167
|
+
const close2 = (t) => bars2.closeOf(t, timeframeString);
|
|
1168
|
+
if (!test) return { open: open2, close: close2 };
|
|
1169
|
+
if (tf.isintraday) {
|
|
1170
|
+
if (session2 !== void 0 && (0, import_session.parsePineSession)(session2) !== null && !bars2.chart.isdwm) {
|
|
1171
|
+
const tz = timezone ?? exchangeTimezone();
|
|
1172
|
+
const barMs = timeframeCore.in_seconds(bars2.chart.period) * 1e3;
|
|
1173
|
+
const ms = timeframeCore.in_seconds(tf.period) * 1e3;
|
|
1174
|
+
const run = (t) => (0, import_session.sessionRun)(t, session2, tz, barMs);
|
|
1175
|
+
const start = (t, r) => r[0] + Math.floor((t - r[0]) / ms) * ms;
|
|
1176
|
+
return {
|
|
1177
|
+
open: (t) => {
|
|
1178
|
+
const r = run(t);
|
|
1179
|
+
return r ? start(t, r) : NaN;
|
|
1180
|
+
},
|
|
1181
|
+
close: (t) => {
|
|
1182
|
+
const r = run(t);
|
|
1183
|
+
return r ? Math.min(start(t, r) + ms, r[1]) : NaN;
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
const isIn = (t) => inside ? inside(t) : bars2.inside(t);
|
|
1188
|
+
return { open: (t) => isIn(t) ? open2(t) : NaN, close: (t) => isIn(t) ? close2(t) : NaN };
|
|
1189
|
+
}
|
|
1190
|
+
if (tf.isdaily && tf.multiplier === 1) {
|
|
1191
|
+
return { open: (t) => bars2.inside(t) ? open2(t) : NaN, close: (t) => bars2.inside(t) ? close2(t) : NaN };
|
|
1192
|
+
}
|
|
1193
|
+
return { open: open2, close: close2 };
|
|
1194
|
+
}
|
|
1109
1195
|
function timeFunction(tf, session2, timezone) {
|
|
1110
1196
|
collector();
|
|
1111
|
-
const {
|
|
1112
|
-
|
|
1113
|
-
return perBar((t) => test && !bars2.inside(t) ? NaN : bars2.timeOf(t, timeframeString));
|
|
1197
|
+
const { open: open2 } = sessionPeriods(tf || chartTimeframe().period, session2, timezone);
|
|
1198
|
+
return perBar((t) => open2(t));
|
|
1114
1199
|
}
|
|
1115
1200
|
function timeCloseFunction(tf, session2, timezone) {
|
|
1116
1201
|
collector();
|
|
1117
|
-
const {
|
|
1118
|
-
|
|
1119
|
-
return perBar((t) => test && !bars2.inside(t) ? NaN : bars2.closeOf(t, timeframeString));
|
|
1202
|
+
const { close: close2 } = sessionPeriods(tf || chartTimeframe().period, session2, timezone);
|
|
1203
|
+
return perBar((t) => close2(t));
|
|
1120
1204
|
}
|
|
1205
|
+
let runNow = NaN;
|
|
1206
|
+
const timenow = new import_series.Series(ctxBars, () => runNow);
|
|
1121
1207
|
const time = callableSeries(new import_series.Series(ctxBars, (b) => barTime(b)), timeFunction);
|
|
1122
1208
|
const time_close = callableSeries(
|
|
1123
1209
|
new import_series.Series(ctxBars, (_b, i) => sessionBars().bars.closeOf(barTime(ctxBars.bars[i]), chartTimeframe().period)),
|
|
1124
1210
|
timeCloseFunction
|
|
1125
1211
|
);
|
|
1126
1212
|
const time_tradingday = new import_series.Series(ctxBars, (b) => sessionBars().bars.tradingDayTime(barTime(b)));
|
|
1127
|
-
function changeOf(tf) {
|
|
1213
|
+
function changeOf(tf, firstBar = false) {
|
|
1214
|
+
const { bars: bars2 } = sessionBars();
|
|
1215
|
+
const changed = (a, b) => !Number.isNaN(a) && !Number.isNaN(b) && a !== b;
|
|
1216
|
+
return perBar((t, i, times) => (i > 0 ? changed(bars2.timeOf(t, tf), bars2.timeOf(times[i - 1], tf)) : firstBar) ? 1 : 0);
|
|
1217
|
+
}
|
|
1218
|
+
function vwapAnchor() {
|
|
1219
|
+
if (chartTimeframe().isdwm) return barFlag(() => true);
|
|
1128
1220
|
const { bars: bars2 } = sessionBars();
|
|
1129
|
-
|
|
1221
|
+
let last = NaN;
|
|
1222
|
+
let previous = NaN;
|
|
1223
|
+
return perBar((t, i) => {
|
|
1224
|
+
const day = bars2.timeOf(t, "1D");
|
|
1225
|
+
const isNew = i === 0 || (Number.isNaN(day) ? Number.isNaN(previous) : day !== last);
|
|
1226
|
+
if (!Number.isNaN(day)) last = day;
|
|
1227
|
+
previous = day;
|
|
1228
|
+
return isNew ? 1 : 0;
|
|
1229
|
+
});
|
|
1130
1230
|
}
|
|
1131
1231
|
function flag(key) {
|
|
1132
1232
|
const { bars: bars2, regular } = sessionBars();
|
|
@@ -1213,17 +1313,17 @@ function valuesOf(value, length) {
|
|
|
1213
1313
|
}
|
|
1214
1314
|
return value.toArray().slice();
|
|
1215
1315
|
}
|
|
1216
|
-
function security(symbol, timeframe2, expression, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off) {
|
|
1316
|
+
function security(symbol, timeframe2, expression, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off, ignore_invalid_symbol = false) {
|
|
1217
1317
|
collector();
|
|
1218
1318
|
const heikin = symbol.startsWith(HEIKIN_ASHI);
|
|
1219
1319
|
const base = heikin ? symbol.slice(HEIKIN_ASHI.length) : symbol;
|
|
1220
|
-
if (base !== "" && base !== chartCtx.tickerid) {
|
|
1221
|
-
throw new Error(`request.security: "${symbol}" is not the chart symbol; other symbols need external data.`);
|
|
1222
|
-
}
|
|
1223
1320
|
const chart2 = chartTimeframe();
|
|
1224
1321
|
const tf = timeframeCore.info(timeframe2 || chart2.period).period;
|
|
1322
|
+
if (base !== "" && base !== chartCtx.tickerid) {
|
|
1323
|
+
return externalSecurity(base, heikin, tf, expression, gaps, lookahead, ignore_invalid_symbol, false);
|
|
1324
|
+
}
|
|
1225
1325
|
if (timeframeCore.in_seconds(tf) < timeframeCore.in_seconds(chart2.period)) {
|
|
1226
|
-
|
|
1326
|
+
return externalSecurity(chartCtx.tickerid ?? "", heikin, tf, expression, gaps, lookahead, ignore_invalid_symbol, true);
|
|
1227
1327
|
}
|
|
1228
1328
|
const chartBars = ctxBars.bars;
|
|
1229
1329
|
const times = chartBars.map(barTime);
|
|
@@ -1243,6 +1343,8 @@ function security(symbol, timeframe2, expression, gaps = barmerge.gaps_off, look
|
|
|
1243
1343
|
const periods = at ? calendar2.calendar.periods(at.date) : [];
|
|
1244
1344
|
return periods.length ? calendar2.timeOf(periods[0][0], tf) : starts[i];
|
|
1245
1345
|
});
|
|
1346
|
+
const tfInfo = timeframeCore.info(tf);
|
|
1347
|
+
(0, import_bars.strayPeriods)(starts, dayPeriods, times, loaded, tfInfo.isdwm ? null : timeframeCore.in_seconds(tf) * 1e3);
|
|
1246
1348
|
const reaches = times.map((t) => loaded.closeOf(t, chart2.period) >= calendar2.periodEnd(t, tf));
|
|
1247
1349
|
({ group, latest } = (0, import_resample.periodsOf)(starts, dayPeriods, reaches));
|
|
1248
1350
|
const unit = chartCtx.timeUnit === "ms" ? 1 : 1e3;
|
|
@@ -1269,7 +1371,85 @@ function security(symbol, timeframe2, expression, gaps = barmerge.gaps_off, look
|
|
|
1269
1371
|
);
|
|
1270
1372
|
return Array.isArray(result) ? mapped : mapped[0];
|
|
1271
1373
|
}
|
|
1272
|
-
|
|
1374
|
+
function runExternal(symbol, heikin, tf, expression, ignoreInvalid, own) {
|
|
1375
|
+
let bars2 = chartCtx.bars?.(symbol, tf);
|
|
1376
|
+
if (bars2 === void 0 && !missingSymbols.some((r) => r.symbol === symbol && r.timeframe === tf)) {
|
|
1377
|
+
missingSymbols.push({ symbol, timeframe: tf });
|
|
1378
|
+
}
|
|
1379
|
+
if (bars2 !== void 0 && bars2.length === 0 && !ignoreInvalid) throw new Error(`Invalid symbol: ${symbol}`);
|
|
1380
|
+
bars2 ??= [];
|
|
1381
|
+
if (heikin) bars2 = (0, import_resample.heikinAshi)(bars2);
|
|
1382
|
+
const given2 = chartCtx.symbolInfo?.(symbol);
|
|
1383
|
+
const info = own ? { ...chartCtx, ...given2 } : given2 ?? {};
|
|
1384
|
+
const chartBars = ctxBars.bars;
|
|
1385
|
+
const savedCtx = chartCtx;
|
|
1386
|
+
let result;
|
|
1387
|
+
let values;
|
|
1388
|
+
ctxBars.setAll(bars2);
|
|
1389
|
+
chartCtx = {
|
|
1390
|
+
...chartCtx,
|
|
1391
|
+
tickerid: symbol,
|
|
1392
|
+
timeframe: tf,
|
|
1393
|
+
timezone: info.timezone,
|
|
1394
|
+
session: info.session,
|
|
1395
|
+
regularSession: info.regularSession,
|
|
1396
|
+
mintick: info.mintick,
|
|
1397
|
+
minmove: info.minmove,
|
|
1398
|
+
pricescale: info.pricescale,
|
|
1399
|
+
pointvalue: info.pointvalue,
|
|
1400
|
+
mincontract: info.mincontract,
|
|
1401
|
+
symbolType: info.symbolType,
|
|
1402
|
+
currency: info.currency,
|
|
1403
|
+
basecurrency: info.basecurrency,
|
|
1404
|
+
root: info.root
|
|
1405
|
+
};
|
|
1406
|
+
try {
|
|
1407
|
+
result = expression();
|
|
1408
|
+
const parts = Array.isArray(result) ? result : [result];
|
|
1409
|
+
values = parts.map((p) => valuesOf(p, bars2.length));
|
|
1410
|
+
} finally {
|
|
1411
|
+
ctxBars.setAll(chartBars);
|
|
1412
|
+
chartCtx = savedCtx;
|
|
1413
|
+
}
|
|
1414
|
+
return { bars: bars2, info, result, values };
|
|
1415
|
+
}
|
|
1416
|
+
function mergeChart() {
|
|
1417
|
+
return {
|
|
1418
|
+
timeframe: chartTimeframe().period,
|
|
1419
|
+
timezone: chartCtx.timezone,
|
|
1420
|
+
session: chartCtx.session,
|
|
1421
|
+
timeUnit: chartCtx.timeUnit,
|
|
1422
|
+
// the realtime rule applies to a last bar that receives live updates
|
|
1423
|
+
lastBarConfirmed: chartCtx.realtime !== true
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
function externalSecurity(symbol, heikin, tf, expression, gaps, lookahead, ignoreInvalid, own) {
|
|
1427
|
+
const { bars: bars2, info, result, values } = runExternal(symbol, heikin, tf, expression, ignoreInvalid, own);
|
|
1428
|
+
const index = (0, import_other.securityOther)(ctxBars.bars, bars2, tf, mergeChart(), {
|
|
1429
|
+
gaps: gaps === barmerge.gaps_on,
|
|
1430
|
+
lookahead: lookahead === barmerge.lookahead_on,
|
|
1431
|
+
other: info
|
|
1432
|
+
});
|
|
1433
|
+
const mapped = values.map((v) => import_series.Series.fromArray(ctxBars, index.map((j) => j < 0 ? NaN : v[j] ?? NaN)));
|
|
1434
|
+
return Array.isArray(result) ? mapped : mapped[0];
|
|
1435
|
+
}
|
|
1436
|
+
function security_lower_tf(symbol, timeframe2, expression, ignore_invalid_symbol = false) {
|
|
1437
|
+
collector();
|
|
1438
|
+
const heikin = symbol.startsWith(HEIKIN_ASHI);
|
|
1439
|
+
const base = heikin ? symbol.slice(HEIKIN_ASHI.length) : symbol;
|
|
1440
|
+
const chart2 = chartTimeframe();
|
|
1441
|
+
const tf = timeframeCore.info(timeframe2 || chart2.period).period;
|
|
1442
|
+
if (timeframeCore.in_seconds(tf) > timeframeCore.in_seconds(chart2.period)) {
|
|
1443
|
+
throw new Error(`request.security_lower_tf: timeframe "${tf}" is higher than the chart timeframe "${chart2.period}".`);
|
|
1444
|
+
}
|
|
1445
|
+
const own = base === "" || base === chartCtx.tickerid;
|
|
1446
|
+
const ticker2 = own ? chartCtx.tickerid ?? "" : base;
|
|
1447
|
+
const { bars: bars2, info, result, values } = runExternal(ticker2, heikin, tf, expression, ignore_invalid_symbol, own);
|
|
1448
|
+
const ranges = (0, import_other.securityLowerTf)(ctxBars.bars, bars2, tf, mergeChart(), { other: info });
|
|
1449
|
+
const mapped = values.map((v) => ranges.map(([from, to]) => v.slice(from, to)));
|
|
1450
|
+
return Array.isArray(result) ? mapped : mapped[0];
|
|
1451
|
+
}
|
|
1452
|
+
const request = { security, security_lower_tf };
|
|
1273
1453
|
const line = {
|
|
1274
1454
|
...lineCore,
|
|
1275
1455
|
get all() {
|
|
@@ -1308,6 +1488,14 @@ const table = {
|
|
|
1308
1488
|
};
|
|
1309
1489
|
const text = { ...textCore };
|
|
1310
1490
|
const chart = {
|
|
1491
|
+
/** Chart foreground colour (PineScript `chart.fg_color`), from the chart context. */
|
|
1492
|
+
get fg_color() {
|
|
1493
|
+
return chartText("foregroundColor", "chart.fg_color");
|
|
1494
|
+
},
|
|
1495
|
+
/** Chart background colour (PineScript `chart.bg_color`), from the chart context. */
|
|
1496
|
+
get bg_color() {
|
|
1497
|
+
return chartText("backgroundColor", "chart.bg_color");
|
|
1498
|
+
},
|
|
1311
1499
|
point: {
|
|
1312
1500
|
...chartPointCore,
|
|
1313
1501
|
now(price) {
|