@alphacharts/indicators 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -8
- package/dist/{all-DeXJJd7D.js → all-_xzUPrL7.js} +9 -9
- package/dist/{all-DeXJJd7D.js.map → all-_xzUPrL7.js.map} +1 -1
- package/dist/all.js +2 -2
- package/dist/define-XUgQMhSl.js +687 -0
- package/dist/define-XUgQMhSl.js.map +1 -0
- package/dist/index.js +269 -118
- package/dist/index.js.map +1 -1
- package/dist/{registry-CYZuqhXX.js → registry-DdYYyZN_.js} +5 -1
- package/dist/registry-DdYYyZN_.js.map +1 -0
- package/dist/{runner-DBP0M8z3.js → runner-B53M0IsJ.js} +15 -7
- package/dist/runner-B53M0IsJ.js.map +1 -0
- package/dist/studies.js +1 -1
- package/dist/{tv-volume-7hh6ajKt.js → tv-volume-BYSbfrVk.js} +197 -200
- package/dist/tv-volume-BYSbfrVk.js.map +1 -0
- package/dist/types/chart/marker-floor.d.ts +9 -0
- package/dist/types/chart/studies.d.ts +29 -2
- package/dist/types/engine/feed.d.ts +88 -0
- package/dist/types/engine/graph.d.ts +37 -2
- package/dist/types/engine/study.d.ts +9 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/runner.d.ts +11 -2
- package/dist/types/studies/tv-volume.d.ts +1 -0
- package/dist/types/types.d.ts +40 -4
- package/dist/worker.js +2 -2
- package/package.json +8 -5
- package/dist/assets/worker-BrUuzTIJ.js +0 -2
- package/dist/assets/worker-BrUuzTIJ.js.map +0 -1
- package/dist/define-BPvQbaq9.js +0 -472
- package/dist/define-BPvQbaq9.js.map +0 -1
- package/dist/registry-CYZuqhXX.js.map +0 -1
- package/dist/runner-DBP0M8z3.js.map +0 -1
- package/dist/tv-volume-7hh6ajKt.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as
|
|
3
|
-
import { a as
|
|
4
|
-
import { COL_C as
|
|
5
|
-
import { loadKernels as
|
|
1
|
+
import { S as e, _ as t, b as n, g as r, h as i, i as a, m as o, v as s, x as c, y as l } from "./define-XUgQMhSl.js";
|
|
2
|
+
import { a as u, c as d, i as f, l as p, n as m, o as h, r as g, s as _, t as v } from "./runner-B53M0IsJ.js";
|
|
3
|
+
import { a as y, i as b, n as x, r as S, t as C } from "./registry-DdYYyZN_.js";
|
|
4
|
+
import { BarShading as w, COL_C as T, COL_H as E, COL_L as D, COL_O as O, COL_V as k, cssColor as A, parseColor as j } from "@alphacharts/core";
|
|
5
|
+
import { loadKernels as M } from "@alphacharts/wasm";
|
|
6
|
+
//#region src/chart/marker-floor.ts
|
|
7
|
+
var N = (e, t) => e !== void 0 && e === e && !(t && e === 0);
|
|
8
|
+
function P(e, t, n) {
|
|
9
|
+
let r = n.within === void 0 ? 0 : Math.max(0, t - n.within);
|
|
10
|
+
if (n.last !== void 0) {
|
|
11
|
+
let i = 0;
|
|
12
|
+
for (let a = t - 1; a >= r; a--) if (N(e[a], !!n.text) && ++i === n.last) return a;
|
|
13
|
+
}
|
|
14
|
+
return r;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
6
17
|
//#region src/chart/studies.ts
|
|
7
|
-
var
|
|
18
|
+
var F = "alphacharts.studies", I = class {
|
|
8
19
|
host;
|
|
9
20
|
id;
|
|
10
21
|
source;
|
|
@@ -16,6 +27,9 @@ var O = "alphacharts.studies", k = class {
|
|
|
16
27
|
engine;
|
|
17
28
|
outs = [];
|
|
18
29
|
lines = [];
|
|
30
|
+
shades = [];
|
|
31
|
+
feeds = /* @__PURE__ */ new Map();
|
|
32
|
+
sameScale = !0;
|
|
19
33
|
styles = {};
|
|
20
34
|
shown = !0;
|
|
21
35
|
pane = 0;
|
|
@@ -29,8 +43,8 @@ var O = "alphacharts.studies", k = class {
|
|
|
29
43
|
disposed = !1;
|
|
30
44
|
decimals = 2;
|
|
31
45
|
persist = !0;
|
|
32
|
-
constructor(e, t, n, r, i, a, o,
|
|
33
|
-
this.host = e, this.id = t, this.source = i, this.volume = a, this.ownRunner =
|
|
46
|
+
constructor(e, t, n, r, i, a, o, s, c) {
|
|
47
|
+
this.host = e, this.id = t, this.source = i, this.volume = a, this.ownRunner = s, this.onDispose = c, this.def = n, this.params = d(n, r), this.engine = new _(n, this.params), this.checkSource(), o?.styles && (this.styles = { ...o.styles }), o?.visible === !1 && (this.shown = !1), this.createSeries(), this.recompute();
|
|
34
48
|
}
|
|
35
49
|
inputs() {
|
|
36
50
|
return this.params;
|
|
@@ -47,25 +61,32 @@ var O = "alphacharts.studies", k = class {
|
|
|
47
61
|
series() {
|
|
48
62
|
return this.outs.map((e) => e.series);
|
|
49
63
|
}
|
|
50
|
-
setInputs(e) {
|
|
51
|
-
let
|
|
52
|
-
|
|
64
|
+
setInputs(e, t = []) {
|
|
65
|
+
let n = { ...this.params };
|
|
66
|
+
for (let e of t) delete n[e];
|
|
67
|
+
let r = d(this.def, {
|
|
68
|
+
...n,
|
|
53
69
|
...e
|
|
54
|
-
})
|
|
55
|
-
this.
|
|
70
|
+
});
|
|
71
|
+
for (let e of this.def.plots) if (e.kind === "line" && typeof e.offset == "function" && R(e, this.params) !== R(e, r)) throw TypeError(`${e.title}: this input would move its line between the pane and the overlay; add the study again`);
|
|
72
|
+
let i = new _(this.def, r);
|
|
73
|
+
this.params = r;
|
|
74
|
+
for (let e of this.outs) e.plot.kind === "line" && (e.offset = L(e.plot, r));
|
|
75
|
+
this.engine = i, this.retitle(), this.recompute(), this.host.changed();
|
|
56
76
|
}
|
|
57
77
|
setVisible(e) {
|
|
58
78
|
this.shown = e;
|
|
59
79
|
for (let t of this.outs) t.series.applyOptions({ visible: e });
|
|
60
|
-
this.
|
|
80
|
+
for (let t of this.shades) t.prim.setVisible(e);
|
|
81
|
+
this.hasBarColor() && this.host.syncBarColors(this.source), this.host.changed();
|
|
61
82
|
}
|
|
62
83
|
setStyle(e, t) {
|
|
63
|
-
t.color !== void 0 &&
|
|
84
|
+
t.color !== void 0 && j(t.color), this.styles[e] = {
|
|
64
85
|
...this.styles[e],
|
|
65
86
|
...t
|
|
66
87
|
};
|
|
67
88
|
for (let t of this.outs) t.key.split(":")[0] === e && t.series.applyOptions(this.seriesOptions(t.plot, t.key));
|
|
68
|
-
this.host.changed();
|
|
89
|
+
!this.job && this.engine.length > 0 && (this.shades.length > 0 || this.hasBarColor()) && this.syncOverlays(), this.host.changed();
|
|
69
90
|
}
|
|
70
91
|
remove() {
|
|
71
92
|
this.host.removeStudy(this.id);
|
|
@@ -102,8 +123,62 @@ var O = "alphacharts.studies", k = class {
|
|
|
102
123
|
dispose(e) {
|
|
103
124
|
this.drop();
|
|
104
125
|
for (let { series: t, line: n } of this.lines) e.removePriceLine(t, n);
|
|
126
|
+
for (let e of this.shades) e.anchor.detachPrimitive(e.prim);
|
|
105
127
|
for (let t of this.outs) e.removeSeries(t.series);
|
|
106
|
-
this.outs = [], this.lines = [];
|
|
128
|
+
this.outs = [], this.lines = [], this.shades = [];
|
|
129
|
+
}
|
|
130
|
+
setFeed(e, t, r) {
|
|
131
|
+
let i = this.feeds.get(e);
|
|
132
|
+
i || this.feeds.set(e, i = new n()), i.load(t, r, `outside series ${e}`), this.recompute(), this.host.changed();
|
|
133
|
+
}
|
|
134
|
+
feedKeys() {
|
|
135
|
+
return [...this.feeds.keys()];
|
|
136
|
+
}
|
|
137
|
+
pushFeedBar(e, t) {
|
|
138
|
+
let n = this.feeds.get(e);
|
|
139
|
+
if (!n) throw RangeError(`${this.def.id}: no outside series "${e}"; give it with setFeed first`);
|
|
140
|
+
if (n.apply(t, `outside series ${e}`), this.disposed || this.error) return;
|
|
141
|
+
if (this.job) {
|
|
142
|
+
this.structural = !0;
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
let r = this.ownRunner ?? this.host.runner;
|
|
146
|
+
r?.canRun(this.def) ? r.feedBar?.(this.def, e, t) : this.engine.pushFeed(e, t) && (this.tickSync(), this.host.api?.requestRender());
|
|
147
|
+
}
|
|
148
|
+
hasBarColor() {
|
|
149
|
+
return this.def.plots.some((e) => e.kind === "barcolor");
|
|
150
|
+
}
|
|
151
|
+
barColorSource() {
|
|
152
|
+
return this.source;
|
|
153
|
+
}
|
|
154
|
+
barColorAt(e) {
|
|
155
|
+
let t = this.engine, n = 0;
|
|
156
|
+
if (e < 0) return n;
|
|
157
|
+
for (let r of this.def.plots) {
|
|
158
|
+
if (r.kind !== "barcolor") continue;
|
|
159
|
+
let i = t.outputs[this.def.columns.indexOf(r.col)].v[e];
|
|
160
|
+
i === i && i !== 0 && (n = j(this.color(r)));
|
|
161
|
+
}
|
|
162
|
+
return n;
|
|
163
|
+
}
|
|
164
|
+
barColors() {
|
|
165
|
+
let e = this.engine.length, t = new Uint32Array(e);
|
|
166
|
+
for (let n = 0; n < e; n++) t[n] = this.barColorAt(n);
|
|
167
|
+
return {
|
|
168
|
+
time: this.engine.graph.time.v.slice(0, e),
|
|
169
|
+
color: t
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
rowOf(e) {
|
|
173
|
+
let t = this.engine.length;
|
|
174
|
+
return t > 0 && this.engine.graph.time.v[t - 1] === e ? t - 1 : -1;
|
|
175
|
+
}
|
|
176
|
+
lastTime() {
|
|
177
|
+
let e = this.engine.length;
|
|
178
|
+
return e > 0 ? this.engine.graph.time.v[e - 1] : NaN;
|
|
179
|
+
}
|
|
180
|
+
get isShown() {
|
|
181
|
+
return this.shown && !this.error && !this.disposed;
|
|
107
182
|
}
|
|
108
183
|
get ohlc() {
|
|
109
184
|
return this.source.data.shape === "ohlc";
|
|
@@ -115,6 +190,7 @@ var O = "alphacharts.studies", k = class {
|
|
|
115
190
|
if (this.params.source !== void 0 && this.params.source !== "close") throw RangeError(`${this.def.id}: a single-value source has only "close", not "${this.params.source}"`);
|
|
116
191
|
}
|
|
117
192
|
if (e === "ohlcv" && !this.volume) throw TypeError(`${this.def.id} needs volume: pass the volume series as options.volume`);
|
|
193
|
+
if (!this.ohlc && this.def.plots.some((e) => e.kind === "barcolor")) throw TypeError(`${this.def.id} colours bars; the source series holds single values, not candles or bars`);
|
|
118
194
|
}
|
|
119
195
|
watches(e) {
|
|
120
196
|
return e === this.source.data ? "source" : this.volume && e === this.volume.data ? "volume" : null;
|
|
@@ -123,7 +199,7 @@ var O = "alphacharts.studies", k = class {
|
|
|
123
199
|
let e = this.host.chart, t = this.source.data, n = t.store, r = 0;
|
|
124
200
|
for (let e = n.first; e < n.end; e++) t.has(e) && r++;
|
|
125
201
|
let i = new Float64Array(r), a = new Float64Array(r), o = this.ohlc, s = o ? new Float64Array(r) : void 0, c = o ? new Float64Array(r) : void 0, l = o ? new Float64Array(r) : void 0, u = this.volume ? new Float64Array(r) : void 0, d = 0;
|
|
126
|
-
for (let r = n.first; r < n.end; r++) t.has(r) && (i[d] = e.logicalToTime(r), o ? (s[d] = t.get(r,
|
|
202
|
+
for (let r = n.first; r < n.end; r++) t.has(r) && (i[d] = e.logicalToTime(r), o ? (s[d] = t.get(r, O), c[d] = t.get(r, E), l[d] = t.get(r, D), a[d] = t.get(r, T)) : a[d] = t.get(r, k), u && (u[d] = this.volume.data.get(r, k)), d++);
|
|
127
203
|
return {
|
|
128
204
|
time: i,
|
|
129
205
|
close: a,
|
|
@@ -139,15 +215,15 @@ var O = "alphacharts.studies", k = class {
|
|
|
139
215
|
let t = this.source.data, n = NaN;
|
|
140
216
|
return {
|
|
141
217
|
time: this.host.chart.logicalToTime(e),
|
|
142
|
-
open: this.ohlc ? t.get(e,
|
|
143
|
-
high: this.ohlc ? t.get(e,
|
|
144
|
-
low: this.ohlc ? t.get(e,
|
|
145
|
-
close: this.ohlc ? t.get(e,
|
|
146
|
-
volume: this.volume ? this.volume.data.get(e,
|
|
218
|
+
open: this.ohlc ? t.get(e, O) : n,
|
|
219
|
+
high: this.ohlc ? t.get(e, E) : n,
|
|
220
|
+
low: this.ohlc ? t.get(e, D) : n,
|
|
221
|
+
close: this.ohlc ? t.get(e, T) : t.get(e, k),
|
|
222
|
+
volume: this.volume ? this.volume.data.get(e, k) : n
|
|
147
223
|
};
|
|
148
224
|
}
|
|
149
225
|
onChange(e) {
|
|
150
|
-
if (this.disposed || this.error) return;
|
|
226
|
+
if (this.disposed || this.error || e.kind === "color") return;
|
|
151
227
|
let t = this.watches(e.series);
|
|
152
228
|
if (e.series === null || !t) return;
|
|
153
229
|
if (this.job) {
|
|
@@ -172,24 +248,30 @@ var O = "alphacharts.studies", k = class {
|
|
|
172
248
|
this.version++, this.job?.cancel(), this.job = null, this.dirty = !1, this.structural = !1, this.error = null;
|
|
173
249
|
let e = this.bars(), t = this.ownRunner ?? this.host.runner;
|
|
174
250
|
if (!t || !t.canRun(this.def)) {
|
|
251
|
+
for (let [e, t] of this.feeds) this.engine.setFeed(e, t.snapshot(), t);
|
|
175
252
|
this.engine.load(e), this.syncAll(), this.ready_ = Promise.resolve();
|
|
176
253
|
return;
|
|
177
254
|
}
|
|
178
|
-
let n = this.version, r =
|
|
255
|
+
let n = this.version, r = this.feeds.size > 0 ? Object.fromEntries([...this.feeds].map(([e, t]) => [e, {
|
|
256
|
+
align: t.align,
|
|
257
|
+
spanMs: t.spanMs,
|
|
258
|
+
bars: t.snapshot()
|
|
259
|
+
}])) : void 0, i = t.run(this.def, {
|
|
179
260
|
studyId: this.def.id,
|
|
180
261
|
params: this.params,
|
|
181
|
-
bars: e
|
|
262
|
+
bars: e,
|
|
263
|
+
...r && { feeds: r }
|
|
182
264
|
});
|
|
183
|
-
this.job =
|
|
265
|
+
this.job = i, this.ready_ = i.promise.then((e) => {
|
|
184
266
|
n !== this.version || this.disposed || (this.job = null, this.engine.graph.adopt(e.buffers, e.n), this.structural ? this.recompute() : (this.dirty && (this.dirty = !1, this.catchUp()), this.syncAll()));
|
|
185
267
|
}, (e) => {
|
|
186
|
-
if (!(e instanceof
|
|
268
|
+
if (!(e instanceof m || n !== this.version || this.disposed)) throw this.job = null, this.error = e instanceof Error ? e : Error(String(e)), this.error;
|
|
187
269
|
});
|
|
188
270
|
}
|
|
189
271
|
catchUp() {
|
|
190
272
|
let e = this.engine, t = this.bars(), n = t.time.length;
|
|
191
273
|
if (e.length === 0 || n === 0) return this.fullLoad(t);
|
|
192
|
-
let r = e.graph.time.v[e.length - 1], i =
|
|
274
|
+
let r = e.graph.time.v[e.length - 1], i = z(t.time, n, r), a = (e) => ({
|
|
193
275
|
time: t.time[e],
|
|
194
276
|
open: t.open?.[e] ?? NaN,
|
|
195
277
|
high: t.high?.[e] ?? NaN,
|
|
@@ -230,8 +312,8 @@ var O = "alphacharts.studies", k = class {
|
|
|
230
312
|
let t = r ?? e.color;
|
|
231
313
|
return {
|
|
232
314
|
lineColor: t,
|
|
233
|
-
topColor:
|
|
234
|
-
bottomColor:
|
|
315
|
+
topColor: B(t, .28),
|
|
316
|
+
bottomColor: B(t, .02),
|
|
235
317
|
lineWidth: n?.width ?? 1.5
|
|
236
318
|
};
|
|
237
319
|
}
|
|
@@ -240,34 +322,36 @@ var O = "alphacharts.studies", k = class {
|
|
|
240
322
|
}
|
|
241
323
|
createSeries() {
|
|
242
324
|
let e = this.host.chart, t = this.source.options();
|
|
243
|
-
this.def.pane === "overlay" ? (this.pane = t.pane, this.scaleId = t.priceScaleId) : (this.pane = this.host.freePane(), this.scaleId = "right");
|
|
244
|
-
let n = this.def.pane === "overlay"
|
|
245
|
-
|
|
246
|
-
|
|
325
|
+
this.def.pane === "overlay" ? (this.pane = t.pane, this.scaleId = this.def.scale ?? t.priceScaleId) : (this.pane = this.host.freePane(), this.scaleId = this.def.scale ?? "right");
|
|
326
|
+
let n = this.def.pane === "overlay";
|
|
327
|
+
this.sameScale = n && this.scaleId === t.priceScaleId;
|
|
328
|
+
let r = this.def.columns, i = (n, i, a, o, s) => {
|
|
329
|
+
let c = e.addSeries(a, {
|
|
330
|
+
id: `study:${this.id}:${i}`,
|
|
247
331
|
pane: this.pane,
|
|
248
332
|
priceScaleId: this.scaleId,
|
|
249
|
-
title: this.outs.length === 0 ? this.title() :
|
|
250
|
-
lastValueVisible: !
|
|
333
|
+
title: this.outs.length === 0 ? this.title() : n.title,
|
|
334
|
+
lastValueVisible: !this.sameScale,
|
|
251
335
|
priceLineVisible: !1,
|
|
252
336
|
visible: this.shown,
|
|
253
|
-
...this.seriesOptions(
|
|
254
|
-
priceFormat:
|
|
337
|
+
...this.seriesOptions(n, i),
|
|
338
|
+
priceFormat: this.sameScale ? t.priceFormat : {
|
|
255
339
|
type: "price",
|
|
256
340
|
minMove: this.def.minMove ?? 10 ** -this.decimals
|
|
257
341
|
}
|
|
258
342
|
});
|
|
259
343
|
this.outs.push({
|
|
260
|
-
plot:
|
|
261
|
-
key:
|
|
262
|
-
col: r.indexOf(
|
|
263
|
-
series:
|
|
264
|
-
offset:
|
|
344
|
+
plot: n,
|
|
345
|
+
key: i,
|
|
346
|
+
col: r.indexOf(o),
|
|
347
|
+
series: c,
|
|
348
|
+
offset: s,
|
|
265
349
|
lastTime: NaN
|
|
266
350
|
});
|
|
267
351
|
};
|
|
268
352
|
for (let e of this.def.plots) switch (e.kind) {
|
|
269
353
|
case "line":
|
|
270
|
-
|
|
354
|
+
R(e, this.params) || i(e, e.key, "line", e.col, L(e, this.params));
|
|
271
355
|
break;
|
|
272
356
|
case "histogram":
|
|
273
357
|
i(e, e.key, "histogram", e.col, 0);
|
|
@@ -278,6 +362,18 @@ var O = "alphacharts.studies", k = class {
|
|
|
278
362
|
case "band": i(e, `${e.key}:upper`, "line", e.upper, 0), i(e, `${e.key}:lower`, "line", e.lower, 0);
|
|
279
363
|
}
|
|
280
364
|
let a = this.outs[0]?.series;
|
|
365
|
+
for (let e of this.def.plots) {
|
|
366
|
+
if (e.kind !== "bgcolor") continue;
|
|
367
|
+
let t = n ? this.source : a;
|
|
368
|
+
if (!t) throw TypeError(`${this.def.id}: bgcolor shades the study's pane, and a study in its own pane needs a plot to hold it`);
|
|
369
|
+
let i = new w();
|
|
370
|
+
i.setVisible(this.shown), t.attachPrimitive(i), this.shades.push({
|
|
371
|
+
plot: e,
|
|
372
|
+
col: r.indexOf(e.col),
|
|
373
|
+
prim: i,
|
|
374
|
+
anchor: t
|
|
375
|
+
});
|
|
376
|
+
}
|
|
281
377
|
if (a) for (let t of this.def.plots) {
|
|
282
378
|
if (t.kind !== "hline") continue;
|
|
283
379
|
let n = typeof t.value == "function" ? t.value(this.params) : t.value, r = e.createPriceLine(a, {
|
|
@@ -296,32 +392,44 @@ var O = "alphacharts.studies", k = class {
|
|
|
296
392
|
syncAll() {
|
|
297
393
|
let e = this.engine, t = e.length, n = e.graph.time.v;
|
|
298
394
|
for (let r of this.outs) this.writeSeries(r, e.outputs[r.col].v, n, t);
|
|
299
|
-
this.host.api?.requestRender(!0);
|
|
395
|
+
this.syncOverlays(), this.host.api?.requestRender(!0);
|
|
396
|
+
}
|
|
397
|
+
syncOverlays() {
|
|
398
|
+
let e = this.engine, t = e.length, n = e.graph.time.v;
|
|
399
|
+
for (let r of this.shades) {
|
|
400
|
+
let i = e.outputs[r.col].v, a = j(this.color(r.plot)), o = new Uint32Array(t);
|
|
401
|
+
for (let e = 0; e < t; e++) o[e] = i[e] === i[e] && i[e] !== 0 ? a : 0;
|
|
402
|
+
r.prim.set(n.slice(0, t), o);
|
|
403
|
+
}
|
|
404
|
+
this.hasBarColor() && this.host.syncBarColors(this.source);
|
|
300
405
|
}
|
|
301
406
|
writeSeries(e, t, n, r) {
|
|
302
407
|
let i = e.plot.kind === "histogram" && e.plot.colorDown ? {
|
|
303
|
-
up:
|
|
304
|
-
down:
|
|
305
|
-
} : null, a =
|
|
408
|
+
up: j(this.color(e.plot)),
|
|
409
|
+
down: j(e.plot.colorDown)
|
|
410
|
+
} : null, a = e.plot.kind === "line" && e.plot.colorBy ? {
|
|
411
|
+
col: this.engine.outputs[this.def.columns.indexOf(e.plot.colorBy.col)].v,
|
|
412
|
+
color: j(e.plot.colorBy.color)
|
|
413
|
+
} : null, o = 0;
|
|
306
414
|
for (let n = 0; n < r; n++) {
|
|
307
415
|
let i = n + e.offset;
|
|
308
|
-
i >= 0 && i < r && t[n] === t[n] &&
|
|
416
|
+
i >= 0 && i < r && t[n] === t[n] && o++;
|
|
309
417
|
}
|
|
310
|
-
let
|
|
311
|
-
for (let
|
|
312
|
-
let
|
|
313
|
-
|
|
418
|
+
let s = new Float64Array(o), c = new Float64Array(o), l = i || a ? new Uint32Array(o) : void 0, u = 0;
|
|
419
|
+
for (let o = 0; o < r; o++) {
|
|
420
|
+
let d = o + e.offset;
|
|
421
|
+
d < 0 || d >= r || t[o] !== t[o] || (s[u] = n[d], c[u] = t[o], i ? l[u] = t[o] >= 0 ? i.up : i.down : a && (l[u] = a.col[o] === a.col[o] && a.col[o] !== 0 ? a.color : 0), u++);
|
|
314
422
|
}
|
|
315
|
-
let
|
|
316
|
-
for (let e = 0; e <
|
|
317
|
-
this.widen(
|
|
318
|
-
time:
|
|
319
|
-
value:
|
|
320
|
-
...
|
|
321
|
-
}), e.lastTime =
|
|
423
|
+
let d = 0;
|
|
424
|
+
for (let e = 0; e < o; e++) d = Math.max(d, Math.abs(c[e]));
|
|
425
|
+
this.widen(d), e.series.setData({
|
|
426
|
+
time: s,
|
|
427
|
+
value: c,
|
|
428
|
+
...l && { color: l }
|
|
429
|
+
}), e.lastTime = o > 0 ? s[o - 1] : NaN;
|
|
322
430
|
}
|
|
323
431
|
widen(e) {
|
|
324
|
-
if (this.
|
|
432
|
+
if (this.sameScale || this.def.minMove !== void 0 || !(e > 0) || e >= 1) return;
|
|
325
433
|
let t = Math.min(8, 2 - Math.floor(Math.log10(e)));
|
|
326
434
|
if (!(t <= this.decimals)) {
|
|
327
435
|
this.decimals = t;
|
|
@@ -336,64 +444,73 @@ var O = "alphacharts.studies", k = class {
|
|
|
336
444
|
return this.outs.find((e) => e.col === t)?.series;
|
|
337
445
|
}
|
|
338
446
|
tickSync() {
|
|
339
|
-
let e = this.engine, t = e.length, n = e.graph.time.v, r = n[t - 1];
|
|
340
|
-
for (let
|
|
341
|
-
let
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
447
|
+
let e = this.engine, t = e.length, n = e.graph.time.v, r = n[t - 1], i = this.def.columns;
|
|
448
|
+
for (let n of this.shades) {
|
|
449
|
+
let i = e.outputs[n.col].v[t - 1];
|
|
450
|
+
n.prim.setAt(r, i === i && i !== 0 ? j(this.color(n.plot)) : 0);
|
|
451
|
+
}
|
|
452
|
+
this.hasBarColor() && this.host.syncBarColors(this.source, !0);
|
|
453
|
+
for (let a of this.outs) {
|
|
454
|
+
let o = t - 1 - a.offset;
|
|
455
|
+
if (o < 0) continue;
|
|
456
|
+
let s = e.outputs[a.col].v, c = s[o];
|
|
457
|
+
if (c === c) {
|
|
458
|
+
this.widen(Math.abs(c));
|
|
459
|
+
let t = a.plot.kind === "histogram" && a.plot.colorDown, n = a.plot.kind === "line" ? a.plot.colorBy : void 0, s = n ? e.outputs[i.indexOf(n.col)].v[o] : NaN, l = n && s === s && s !== 0 ? n.color : void 0;
|
|
460
|
+
a.series.update({
|
|
348
461
|
time: r,
|
|
349
|
-
value:
|
|
350
|
-
...
|
|
351
|
-
|
|
352
|
-
|
|
462
|
+
value: c,
|
|
463
|
+
...t && { color: c >= 0 ? this.color(a.plot) : t },
|
|
464
|
+
...l && { color: l }
|
|
465
|
+
}), a.lastTime = r;
|
|
466
|
+
} else a.lastTime === r && this.writeSeries(a, s, n, t);
|
|
353
467
|
}
|
|
354
468
|
}
|
|
355
469
|
draw(e, t) {
|
|
356
470
|
if (!this.shown || t.pane !== this.pane) return;
|
|
357
471
|
let n = this.engine, r = n.length;
|
|
358
472
|
if (r === 0) return;
|
|
359
|
-
let i = n.graph.time.v, a = Math.max(0,
|
|
473
|
+
let i = n.graph.time.v, a = Math.max(0, z(i, r, t.xToTime(0)) - 1), o = Math.min(r, z(i, r, t.xToTime(t.width)) + 2);
|
|
360
474
|
if (o <= a) return;
|
|
361
475
|
let s = Math.max(1, Math.floor((o - a) / (t.width * 2))), c = (e) => t.timeToX(i[e]), l = (e) => t.priceToY(e, this.scaleId), u = (e) => n.outputs[this.def.columns.indexOf(e)].v;
|
|
362
476
|
for (let t of this.def.plots) switch (t.kind) {
|
|
363
477
|
case "band":
|
|
364
|
-
|
|
478
|
+
V(e, a, o, s, c, l, u(t.upper), u(t.lower), this.styles[t.key]?.color ?? t.fill, 0);
|
|
365
479
|
break;
|
|
366
480
|
case "fill":
|
|
367
|
-
|
|
481
|
+
V(e, a, o, s, c, l, u(t.a), u(t.b), this.styles[t.key]?.color ?? t.color, 0);
|
|
368
482
|
break;
|
|
369
483
|
case "line":
|
|
370
|
-
|
|
484
|
+
R(t, this.params) && H(e, a, o, s, r, c, l, u(t.col), L(t, this.params), !!t.connect, this.color(t), this.styles[t.key]?.width ?? t.width ?? 1.5);
|
|
371
485
|
break;
|
|
372
486
|
case "markers":
|
|
373
487
|
this.drawMarkers(e, t, a, o, c, l, u(t.col), r);
|
|
374
488
|
break;
|
|
375
|
-
case "zigzag":
|
|
489
|
+
case "zigzag": U(e, a, o, c, l, u(t.price), u(t.back), i, this.color(t), t.width ?? 1.5);
|
|
376
490
|
}
|
|
377
491
|
}
|
|
378
492
|
drawMarkers(e, t, n, r, i, a, o, s) {
|
|
379
|
-
let c = t.
|
|
493
|
+
let c = L(t, this.params), l = this.engine.graph.high.v, u = this.engine.graph.low.v, d = this.color(t);
|
|
380
494
|
e.save(), e.fillStyle = d, e.strokeStyle = d, e.font = "10px system-ui, sans-serif", e.textAlign = "center";
|
|
381
|
-
let f = 0;
|
|
382
|
-
for (let
|
|
383
|
-
let
|
|
384
|
-
if (
|
|
385
|
-
let
|
|
386
|
-
if (
|
|
387
|
-
let p = i(
|
|
388
|
-
m === "value" ? (h = a(
|
|
495
|
+
let f = 0, p = Math.max(n, P(o, s, t));
|
|
496
|
+
for (let n = p; n < r && f < 4e3; n++) {
|
|
497
|
+
let r = o[n];
|
|
498
|
+
if (r !== r || t.text && r === 0) continue;
|
|
499
|
+
let d = n + c;
|
|
500
|
+
if (d < 0 || d >= s) continue;
|
|
501
|
+
let p = i(d), m = t.position === "sign" ? r > 0 ? "below" : "above" : t.position, h, g;
|
|
502
|
+
m === "value" ? (h = a(r), g = 1) : m === "above" ? (h = a(l[d]) - 8, g = -1) : (h = a(u[d]) + 8, g = 1), t.text ? (e.textBaseline = g < 0 ? "bottom" : "top", e.fillText(String(Math.round(r)), p, m === "above" ? h - 2 : h + 2)) : W(e, t.shape, p, h, m === "above" ? -1 : 1), f++;
|
|
389
503
|
}
|
|
390
504
|
e.restore();
|
|
391
505
|
}
|
|
392
506
|
};
|
|
393
|
-
function
|
|
394
|
-
return
|
|
507
|
+
function L(e, t) {
|
|
508
|
+
return typeof e.offset == "function" ? e.offset(t) : e.offset ?? 0;
|
|
509
|
+
}
|
|
510
|
+
function R(e, t) {
|
|
511
|
+
return L(e, t) < 0 || !!e.connect;
|
|
395
512
|
}
|
|
396
|
-
function
|
|
513
|
+
function z(e, t, n) {
|
|
397
514
|
let r = 0, i = t;
|
|
398
515
|
for (; r < i;) {
|
|
399
516
|
let t = r + i >>> 1;
|
|
@@ -401,11 +518,11 @@ function j(e, t, n) {
|
|
|
401
518
|
}
|
|
402
519
|
return r;
|
|
403
520
|
}
|
|
404
|
-
function
|
|
405
|
-
let n =
|
|
406
|
-
return
|
|
521
|
+
function B(e, t) {
|
|
522
|
+
let n = j(e);
|
|
523
|
+
return A((n & 4294967040 | Math.round(t * 255)) >>> 0);
|
|
407
524
|
}
|
|
408
|
-
function
|
|
525
|
+
function V(e, t, n, r, i, a, o, s, c, l) {
|
|
409
526
|
e.save(), e.fillStyle = c;
|
|
410
527
|
let u = [], d = () => {
|
|
411
528
|
if (u.length > 1) {
|
|
@@ -419,7 +536,7 @@ function N(e, t, n, r, i, a, o, s, c, l) {
|
|
|
419
536
|
for (let e = t; e < n; e += r) o[e] === o[e] && s[e] === s[e] ? u.push(e) : d();
|
|
420
537
|
d(), e.restore();
|
|
421
538
|
}
|
|
422
|
-
function
|
|
539
|
+
function H(e, t, n, r, i, a, o, s, c, l, u, d) {
|
|
423
540
|
e.save(), e.strokeStyle = u, e.lineWidth = d, e.beginPath();
|
|
424
541
|
let f = !1;
|
|
425
542
|
for (let u = t; u < n; u += r) {
|
|
@@ -428,7 +545,7 @@ function P(e, t, n, r, i, a, o, s, c, l, u, d) {
|
|
|
428
545
|
}
|
|
429
546
|
e.stroke(), e.restore();
|
|
430
547
|
}
|
|
431
|
-
function
|
|
548
|
+
function U(e, t, n, r, i, a, o, s, c, l) {
|
|
432
549
|
e.save(), e.strokeStyle = c, e.lineWidth = l, e.beginPath();
|
|
433
550
|
let u = !1;
|
|
434
551
|
for (let s = Math.max(0, t - 2e3); s < n; s++) {
|
|
@@ -439,7 +556,7 @@ function F(e, t, n, r, i, a, o, s, c, l) {
|
|
|
439
556
|
}
|
|
440
557
|
e.stroke(), e.restore();
|
|
441
558
|
}
|
|
442
|
-
function
|
|
559
|
+
function W(e, t, n, r, i) {
|
|
443
560
|
switch (e.beginPath(), t) {
|
|
444
561
|
case "square":
|
|
445
562
|
e.rect(n - 4, r - 4, 8, 8), e.fill();
|
|
@@ -461,14 +578,15 @@ function I(e, t, n, r, i) {
|
|
|
461
578
|
default: e.arc(n, r, 3, 0, Math.PI * 2), e.fill();
|
|
462
579
|
}
|
|
463
580
|
}
|
|
464
|
-
var
|
|
581
|
+
var G = class {
|
|
465
582
|
chart;
|
|
466
583
|
runner;
|
|
467
584
|
resolve;
|
|
468
|
-
id =
|
|
585
|
+
id = F;
|
|
469
586
|
api = null;
|
|
470
587
|
studies = /* @__PURE__ */ new Map();
|
|
471
588
|
counter = 0;
|
|
589
|
+
coloured = /* @__PURE__ */ new Set();
|
|
472
590
|
constructor(e, t, n) {
|
|
473
591
|
this.chart = e, this.runner = t, this.resolve = n;
|
|
474
592
|
}
|
|
@@ -476,8 +594,41 @@ var L = class {
|
|
|
476
594
|
this.api = e;
|
|
477
595
|
}
|
|
478
596
|
uninstall() {
|
|
597
|
+
let e = [...this.coloured];
|
|
479
598
|
for (let e of [...this.studies.values()]) e.dispose(this.chart);
|
|
480
|
-
this.studies.clear()
|
|
599
|
+
this.studies.clear();
|
|
600
|
+
for (let t of e) this.syncBarColors(t);
|
|
601
|
+
this.api = null;
|
|
602
|
+
}
|
|
603
|
+
syncBarColors(e, t = !1) {
|
|
604
|
+
let n = [...this.studies.values()].filter((t) => t.barColorSource() === e && t.hasBarColor() && t.isShown), r = e;
|
|
605
|
+
if (n.length === 0) {
|
|
606
|
+
this.coloured.delete(e) && r.clearBarColors();
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
if (this.coloured.add(e), t) {
|
|
610
|
+
let e = n[0].lastTime();
|
|
611
|
+
if (e !== e) return;
|
|
612
|
+
let t = 0;
|
|
613
|
+
for (let r of n) r.lastTime() === e && (t = r.barColorAt(r.rowOf(e)) || t);
|
|
614
|
+
r.setBarColors({
|
|
615
|
+
time: Float64Array.of(e),
|
|
616
|
+
color: Uint32Array.of(t)
|
|
617
|
+
});
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
let i = n[0].barColors(), a = i.time, o = i.color;
|
|
621
|
+
for (let e = 1; e < n.length; e++) {
|
|
622
|
+
let t = n[e].barColors(), r = 0;
|
|
623
|
+
for (let e = 0; e < t.time.length; e++) {
|
|
624
|
+
for (; r < a.length && a[r] < t.time[e];) r++;
|
|
625
|
+
r < a.length && a[r] === t.time[e] && t.color[e] !== 0 && (o[r] = t.color[e]);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
r.setBarColors({
|
|
629
|
+
time: a,
|
|
630
|
+
color: o
|
|
631
|
+
});
|
|
481
632
|
}
|
|
482
633
|
dataChanged(e) {
|
|
483
634
|
for (let t of this.studies.values()) t.onChange(e);
|
|
@@ -505,18 +656,18 @@ var L = class {
|
|
|
505
656
|
if (this.studies.has(a)) throw Error(`alphacharts: a study with id "${a}" already exists`);
|
|
506
657
|
let o = /^s(\d+)$/.exec(a);
|
|
507
658
|
o && (this.counter = Math.max(this.counter, Number(o[1])));
|
|
508
|
-
let s = new
|
|
509
|
-
return s.persist = r.persist !== !1, this.studies.set(a, s), s;
|
|
659
|
+
let s = new I(this, a, e, t, n, r.volume, i, r.runner, r.onDispose);
|
|
660
|
+
return s.persist = r.persist !== !1, this.studies.set(a, s), s.hasBarColor() && this.syncBarColors(n), s;
|
|
510
661
|
}
|
|
511
662
|
removeStudy(e) {
|
|
512
663
|
let t = this.studies.get(e);
|
|
513
|
-
t && (this.studies.delete(e), t.dispose(this.chart), this.changed());
|
|
664
|
+
t && (this.studies.delete(e), t.dispose(this.chart), t.hasBarColor() && this.syncBarColors(t.barColorSource()), this.changed());
|
|
514
665
|
}
|
|
515
666
|
reap() {
|
|
516
667
|
let e = new Set(this.chart.series().map((e) => e.data));
|
|
517
668
|
for (let [t, n] of this.studies) {
|
|
518
669
|
let r = n;
|
|
519
|
-
(!e.has(r.source.data) || r.volume && !e.has(r.volume.data)) && (this.studies.delete(t), n.dispose(this.chart));
|
|
670
|
+
(!e.has(r.source.data) || r.volume && !e.has(r.volume.data)) && (this.studies.delete(t), n.dispose(this.chart), e.has(r.source.data) ? n.hasBarColor() && this.syncBarColors(r.source) : this.coloured.delete(r.source));
|
|
520
671
|
}
|
|
521
672
|
}
|
|
522
673
|
reserveIds(e) {
|
|
@@ -542,7 +693,7 @@ var L = class {
|
|
|
542
693
|
if (r.has(e.id)) throw Error(`alphacharts studies: the layout repeats study id "${e.id}"`);
|
|
543
694
|
if (r.add(e.id), !t.seriesIds.includes(e.source)) throw Error(`alphacharts studies: study "${e.id}" needs series "${e.source}", which the layout does not contain`);
|
|
544
695
|
if (e.volume && !t.seriesIds.includes(e.volume)) throw Error(`alphacharts studies: study "${e.id}" needs volume series "${e.volume}"`);
|
|
545
|
-
|
|
696
|
+
d(this.resolve(e.study), e.inputs);
|
|
546
697
|
}
|
|
547
698
|
}
|
|
548
699
|
fromJSON(e) {
|
|
@@ -569,25 +720,25 @@ var L = class {
|
|
|
569
720
|
for (let e of this.chart.series()) e.options().id.startsWith("study:") && !r.has(e) && this.chart.removeSeries(e);
|
|
570
721
|
}
|
|
571
722
|
};
|
|
572
|
-
function
|
|
573
|
-
let n = e.plugin(
|
|
723
|
+
function K(e, t = {}) {
|
|
724
|
+
let n = e.plugin(F);
|
|
574
725
|
if (n) return n;
|
|
575
|
-
let r = new
|
|
726
|
+
let r = new G(e, t.runner, t.resolve ?? C);
|
|
576
727
|
return e.addPlugin(r), r;
|
|
577
728
|
}
|
|
578
|
-
function
|
|
579
|
-
let a = typeof n == "string" ?
|
|
580
|
-
return
|
|
729
|
+
function q(e, t, n, r = {}, i = {}) {
|
|
730
|
+
let a = typeof n == "string" ? C(n) : n;
|
|
731
|
+
return K(e, i.runner ? { runner: i.runner } : {}).add(a, r, t, i);
|
|
581
732
|
}
|
|
582
733
|
//#endregion
|
|
583
734
|
//#region src/wasm.ts
|
|
584
|
-
async function
|
|
585
|
-
|
|
735
|
+
async function J() {
|
|
736
|
+
s(await M());
|
|
586
737
|
}
|
|
587
|
-
function
|
|
588
|
-
|
|
738
|
+
function Y() {
|
|
739
|
+
s(null);
|
|
589
740
|
}
|
|
590
741
|
//#endregion
|
|
591
|
-
export {
|
|
742
|
+
export { v as CHUNK, m as CancelledError, o as Col, l as FEED_FIELDS, n as Feed, i as Graph, g as InlineRunner, r as Node, F as PLUGIN_ID, t as SOURCE_NAMES, G as StudiesPlugin, I as Study, _ as StudyEngine, f as WorkerRunner, q as addStudy, u as createRunner, a as defineStudy, c as describeJoin, Y as disableWasm, J as enableWasm, C as getStudy, K as installStudies, e as joinFeed, x as listStudies, P as markerFloor, S as registerStudies, b as registerStudy, d as resolveParams, p as runStudy, h as serveWorker, s as setKernels, y as validateDef };
|
|
592
743
|
|
|
593
744
|
//# sourceMappingURL=index.js.map
|