@luxalgo/vela 0.8.2 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DataProvider-COGDs9Xg.d.cts → DataProvider-Bw58CjYy.d.cts} +1 -1
- package/dist/{DataProvider-DpOWZD8F.d.ts → DataProvider-Byo8pEv0.d.ts} +1 -1
- package/dist/{chunk-DPAA3SRT.js → chunk-ALTGHKIM.js} +836 -32
- package/dist/{chunk-27UTYE7T.js → chunk-AUOB7A5Y.js} +49 -7
- package/dist/{chunk-HKNO24GD.js → chunk-I2U4NZD2.js} +56 -1
- package/dist/{chunk-R2JMNIHY.js → chunk-MOJ4T26N.js} +341 -169
- package/dist/{chunk-T3DZIR5Y.js → chunk-UNUVPQFW.js} +2214 -886
- package/dist/{chunk-NLDTVFOI.js → chunk-WY5H4S4I.js} +129 -10
- package/dist/{contributions-Cgm9RJYP.d.cts → contributions-BY3zSYiZ.d.ts} +98 -7
- package/dist/{contributions-bWgwyiVi.d.ts → contributions-DOm40g5-.d.cts} +98 -7
- package/dist/index.cjs +3066 -893
- package/dist/index.d.cts +36 -22
- package/dist/index.d.ts +36 -22
- package/dist/index.js +5 -5
- package/dist/{options-NAUHiQEC.d.ts → options-CSXbjMM5.d.cts} +129 -4
- package/dist/{options-NAUHiQEC.d.cts → options-CSXbjMM5.d.ts} +129 -4
- package/dist/{plugin-CqxWoDKS.d.ts → plugin-BDxUhGO3.d.ts} +4 -4
- package/dist/{plugin-CjjzZX2F.d.cts → plugin-CiQVyETg.d.cts} +4 -4
- package/dist/plugin.cjs +573 -17
- package/dist/plugin.d.cts +5 -5
- package/dist/plugin.d.ts +5 -5
- package/dist/plugin.js +3 -3
- package/dist/providers/binance.d.cts +2 -2
- package/dist/providers/binance.d.ts +2 -2
- package/dist/providers/coinbase.d.cts +2 -2
- package/dist/providers/coinbase.d.ts +2 -2
- package/dist/providers/hyperliquid.d.cts +2 -2
- package/dist/providers/hyperliquid.d.ts +2 -2
- package/dist/{side-panel-wMNfgyZb.d.cts → side-panel-_2UK1gSm.d.cts} +45 -3
- package/dist/{side-panel-wMNfgyZb.d.ts → side-panel-_2UK1gSm.d.ts} +45 -3
- package/dist/{statusline-model-Dih6FGWP.d.ts → statusline-model-C9tYXuux.d.ts} +19 -4
- package/dist/{statusline-model-Dpfpq54A.d.cts → statusline-model-DUBX6Fib.d.cts} +19 -4
- package/dist/ui.cjs +224 -14
- package/dist/ui.d.cts +119 -87
- package/dist/ui.d.ts +119 -87
- package/dist/ui.js +3 -3
- package/dist/vela.global.js +3073 -900
- package/dist/vela.global.min.js +158 -54
- package/dist/widget.cjs +3640 -1119
- package/dist/widget.d.cts +24 -10
- package/dist/widget.d.ts +24 -10
- package/dist/widget.js +7 -7
- package/dist/workspace.cjs +3639 -1119
- package/dist/workspace.d.cts +61 -20
- package/dist/workspace.d.ts +61 -20
- package/dist/workspace.js +6 -6
- package/package.json +1 -1
- /package/dist/{chunk-JU4CWEBF.js → chunk-W5YPYZ2P.js} +0 -0
package/dist/plugin.cjs
CHANGED
|
@@ -223,6 +223,23 @@ function resolveEngines(overrides) {
|
|
|
223
223
|
return { ...Object.fromEntries(defaultEngines), ...overrides };
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
+
// src/widget/context-menu-model.ts
|
|
227
|
+
var CONTEXT_MENU_BUILTIN_ORDER = {
|
|
228
|
+
body: { "reset-view": -30, "remove-drawings": -20, "remove-indicators": -10, settings: 1e3 },
|
|
229
|
+
"price-axis": {
|
|
230
|
+
auto: -80,
|
|
231
|
+
invert: -70,
|
|
232
|
+
"scale:regular": -60,
|
|
233
|
+
"scale:percent": -50,
|
|
234
|
+
"scale:indexed": -40,
|
|
235
|
+
"scale:log": -30,
|
|
236
|
+
labels: -20,
|
|
237
|
+
levels: -10,
|
|
238
|
+
settings: 1e3
|
|
239
|
+
},
|
|
240
|
+
"time-axis": { timezone: -10, settings: 1e3 }
|
|
241
|
+
};
|
|
242
|
+
|
|
226
243
|
// src/core/icons.ts
|
|
227
244
|
var registry4 = /* @__PURE__ */ new Map();
|
|
228
245
|
function registerIcon(id, svg) {
|
|
@@ -436,6 +453,28 @@ function defaultText(value = "") {
|
|
|
436
453
|
return { value, size: "normal", hAlign: "left", vAlign: "top" };
|
|
437
454
|
}
|
|
438
455
|
|
|
456
|
+
// src/core/drawings/visibility.ts
|
|
457
|
+
var MIN = 6e4;
|
|
458
|
+
var HOUR = 60 * MIN;
|
|
459
|
+
var DAY = 24 * HOUR;
|
|
460
|
+
var TIMEFRAME_BANDS = [
|
|
461
|
+
{ key: "s", label: "Sec", fromMs: 0 },
|
|
462
|
+
{ key: "1", label: "1m", fromMs: MIN },
|
|
463
|
+
{ key: "5", label: "5m", fromMs: 5 * MIN },
|
|
464
|
+
{ key: "15", label: "15m", fromMs: 15 * MIN },
|
|
465
|
+
{ key: "60", label: "1H", fromMs: HOUR },
|
|
466
|
+
{ key: "240", label: "4H", fromMs: 4 * HOUR },
|
|
467
|
+
{ key: "D", label: "D", fromMs: DAY },
|
|
468
|
+
{ key: "W", label: "W", fromMs: 7 * DAY },
|
|
469
|
+
{ key: "M", label: "M", fromMs: 28 * DAY }
|
|
470
|
+
];
|
|
471
|
+
var BAND_KEYS = new Set(TIMEFRAME_BANDS.map((b) => b.key));
|
|
472
|
+
function sanitizeShowOn(v) {
|
|
473
|
+
if (!Array.isArray(v)) return void 0;
|
|
474
|
+
const wanted = new Set(v.filter((k) => typeof k === "string" && BAND_KEYS.has(k)));
|
|
475
|
+
return TIMEFRAME_BANDS.map((b) => b.key).filter((k) => wanted.has(k));
|
|
476
|
+
}
|
|
477
|
+
|
|
439
478
|
// src/core/drawings/Drawing.ts
|
|
440
479
|
var _Drawing = class _Drawing {
|
|
441
480
|
// Public so the registry can construct concrete subclasses; `abstract` still
|
|
@@ -452,6 +491,7 @@ var _Drawing = class _Drawing {
|
|
|
452
491
|
this.locked = init.locked ?? false;
|
|
453
492
|
this.visible = init.visible ?? true;
|
|
454
493
|
this.zIndex = init.zIndex ?? 0;
|
|
494
|
+
this.showOn = sanitizeShowOn(init.showOn);
|
|
455
495
|
this.createdAt = init.createdAt ?? Date.now();
|
|
456
496
|
if (init.props) this.readProps(init.props);
|
|
457
497
|
}
|
|
@@ -538,7 +578,10 @@ var _Drawing = class _Drawing {
|
|
|
538
578
|
visible: this.visible,
|
|
539
579
|
zIndex: this.zIndex,
|
|
540
580
|
createdAt: this.createdAt,
|
|
541
|
-
props: this.writeProps()
|
|
581
|
+
props: this.writeProps(),
|
|
582
|
+
// Always present (undefined = every timeframe) so an edit can lift a limit; JSON
|
|
583
|
+
// drops the undefined value, so unlimited drawings save as before.
|
|
584
|
+
showOn: this.showOn ? [...this.showOn] : void 0
|
|
542
585
|
};
|
|
543
586
|
}
|
|
544
587
|
/** Per-type extras to serialize into `props` (override in subclasses). */
|
|
@@ -673,9 +716,16 @@ var TrendLine = class extends Drawing {
|
|
|
673
716
|
if (y1 == null || y2 == null) return null;
|
|
674
717
|
return [proj.xOf(a.time), y1, proj.xOf(b.time), y2];
|
|
675
718
|
}
|
|
719
|
+
/** Which ends run on past the anchors. */
|
|
720
|
+
extension() {
|
|
721
|
+
const { extendLeft: l, extendRight: r } = this.style;
|
|
722
|
+
return l && r ? "both" : l ? "left" : r ? "right" : "none";
|
|
723
|
+
}
|
|
676
724
|
hitTest(px, py, proj, tol) {
|
|
677
725
|
const p = this.pixels(proj);
|
|
678
|
-
|
|
726
|
+
if (!p) return false;
|
|
727
|
+
const [x1, y1, x2, y2] = extendRay(p[0], p[1], p[2], p[3], this.extension(), proj.width, proj.height);
|
|
728
|
+
return distToSegment(px, py, x1, y1, x2, y2) <= tol;
|
|
679
729
|
}
|
|
680
730
|
handlePoints(proj) {
|
|
681
731
|
const p = this.pixels(proj);
|
|
@@ -702,6 +752,8 @@ var TrendLine = class extends Drawing {
|
|
|
702
752
|
fields: [
|
|
703
753
|
...LINE_FIELDS,
|
|
704
754
|
{ path: "style.arrowRight", label: "Arrow", kind: "boolean", group: "line" },
|
|
755
|
+
{ path: "style.extendLeft", label: "Extend left", kind: "boolean", group: "line" },
|
|
756
|
+
{ path: "style.extendRight", label: "Extend right", kind: "boolean", group: "line" },
|
|
705
757
|
...TEXT_FIELDS
|
|
706
758
|
]
|
|
707
759
|
};
|
|
@@ -3161,6 +3213,14 @@ var FibRatios = class extends Drawing {
|
|
|
3161
3213
|
|
|
3162
3214
|
// src/core/drawings/types/FibLevels.ts
|
|
3163
3215
|
var FibLevels = class extends FibRatios {
|
|
3216
|
+
// `declare`d: the base constructor reads saved props before these could be initialized.
|
|
3217
|
+
constructor(init) {
|
|
3218
|
+
super(init);
|
|
3219
|
+
if (this.showRatios === void 0) this.showRatios = true;
|
|
3220
|
+
if (this.showPrices === void 0) this.showPrices = true;
|
|
3221
|
+
if (this.labelSide === void 0) this.labelSide = "left";
|
|
3222
|
+
if (this.background === void 0) this.background = true;
|
|
3223
|
+
}
|
|
3164
3224
|
/** Price of a level for the two anchor prices; subclasses override to change which anchor ratio 0 sits on. */
|
|
3165
3225
|
levelPrice(ratio, p1, p2) {
|
|
3166
3226
|
return p1 + ratio * (p2 - p1);
|
|
@@ -3172,8 +3232,8 @@ var FibLevels = class extends FibRatios {
|
|
|
3172
3232
|
if (!a || !b) return null;
|
|
3173
3233
|
const xa = proj.xOf(a.time);
|
|
3174
3234
|
const xb = proj.xOf(b.time);
|
|
3175
|
-
const x1 = Math.min(xa, xb);
|
|
3176
|
-
const x2 = Math.max(xa, xb);
|
|
3235
|
+
const x1 = this.style.extendLeft ? 0 : Math.min(xa, xb);
|
|
3236
|
+
const x2 = this.style.extendRight ? proj.width : Math.max(xa, xb);
|
|
3177
3237
|
const out = [];
|
|
3178
3238
|
for (const lv of this.levels) {
|
|
3179
3239
|
if (!lv.enabled) continue;
|
|
@@ -3187,6 +3247,7 @@ var FibLevels = class extends FibRatios {
|
|
|
3187
3247
|
entryLines(proj) {
|
|
3188
3248
|
const lines = this.levelLines(proj);
|
|
3189
3249
|
if (!lines) return null;
|
|
3250
|
+
const right = this.labelSide === "right";
|
|
3190
3251
|
return lines.map((l) => ({
|
|
3191
3252
|
color: l.color,
|
|
3192
3253
|
label: l.label,
|
|
@@ -3194,16 +3255,24 @@ var FibLevels = class extends FibRatios {
|
|
|
3194
3255
|
y1: l.y,
|
|
3195
3256
|
x2: l.x2,
|
|
3196
3257
|
y2: l.y,
|
|
3197
|
-
numberText:
|
|
3198
|
-
numberX: l.x1 + 4,
|
|
3258
|
+
numberText: this.levelText(l.ratio, l.price),
|
|
3259
|
+
numberX: right ? l.x2 - 4 : l.x1 + 4,
|
|
3199
3260
|
numberY: l.y - 7,
|
|
3200
|
-
numberAlign: "left",
|
|
3261
|
+
numberAlign: right ? "right" : "left",
|
|
3201
3262
|
labelX: (l.x1 + l.x2) / 2,
|
|
3202
3263
|
labelY: l.y - 7
|
|
3203
3264
|
}));
|
|
3204
3265
|
}
|
|
3266
|
+
/** The text beside a level: its ratio, its price, both, or nothing. */
|
|
3267
|
+
levelText(ratio, price) {
|
|
3268
|
+
const p = price.toFixed(2);
|
|
3269
|
+
if (this.showRatios && this.showPrices) return `${ratio} (${p})`;
|
|
3270
|
+
if (this.showRatios) return String(ratio);
|
|
3271
|
+
return this.showPrices ? p : "";
|
|
3272
|
+
}
|
|
3205
3273
|
fillBands(proj) {
|
|
3206
|
-
|
|
3274
|
+
if (!this.background) return [];
|
|
3275
|
+
const lines = this.levelLines(proj)?.sort((p, q) => p.ratio - q.ratio);
|
|
3207
3276
|
if (!lines) return [];
|
|
3208
3277
|
const bands = [];
|
|
3209
3278
|
for (let i = 1; i < lines.length; i += 1) {
|
|
@@ -3221,6 +3290,26 @@ var FibLevels = class extends FibRatios {
|
|
|
3221
3290
|
if (prices.length === 0) return null;
|
|
3222
3291
|
return { min: Math.min(...prices), max: Math.max(...prices) };
|
|
3223
3292
|
}
|
|
3293
|
+
schema() {
|
|
3294
|
+
const base = super.schema();
|
|
3295
|
+
return {
|
|
3296
|
+
fields: [
|
|
3297
|
+
...base.fields,
|
|
3298
|
+
{ path: "style.extendLeft", label: "Extend left", kind: "boolean", group: "line" },
|
|
3299
|
+
{ path: "style.extendRight", label: "Extend right", kind: "boolean", group: "line" }
|
|
3300
|
+
]
|
|
3301
|
+
};
|
|
3302
|
+
}
|
|
3303
|
+
writeProps() {
|
|
3304
|
+
return { ...super.writeProps(), showRatios: this.showRatios, showPrices: this.showPrices, labelSide: this.labelSide, background: this.background };
|
|
3305
|
+
}
|
|
3306
|
+
readProps(props) {
|
|
3307
|
+
super.readProps(props);
|
|
3308
|
+
if (typeof props.showRatios === "boolean") this.showRatios = props.showRatios;
|
|
3309
|
+
if (typeof props.showPrices === "boolean") this.showPrices = props.showPrices;
|
|
3310
|
+
if (props.labelSide === "left" || props.labelSide === "right") this.labelSide = props.labelSide;
|
|
3311
|
+
if (typeof props.background === "boolean") this.background = props.background;
|
|
3312
|
+
}
|
|
3224
3313
|
};
|
|
3225
3314
|
|
|
3226
3315
|
// src/core/drawings/levelPalette.ts
|
|
@@ -3266,14 +3355,31 @@ var RATIO_COLORS = [
|
|
|
3266
3355
|
[0.75, LEVEL_BLUE],
|
|
3267
3356
|
[0.786, LEVEL_BLUE],
|
|
3268
3357
|
[1, LEVEL_ANCHOR],
|
|
3358
|
+
[0.705, LEVEL_AMBER],
|
|
3359
|
+
[0.886, LEVEL_PURPLE],
|
|
3269
3360
|
[1.272, LEVEL_BLUE],
|
|
3270
3361
|
[1.382, LEVEL_ORANGE],
|
|
3362
|
+
[1.414, LEVEL_AQUA],
|
|
3271
3363
|
[1.618, LEVEL_RED],
|
|
3272
3364
|
[2, LEVEL_ANCHOR],
|
|
3365
|
+
[2.272, LEVEL_VIOLET],
|
|
3273
3366
|
[2.382, LEVEL_ORANGE],
|
|
3367
|
+
[2.414, LEVEL_PINK],
|
|
3274
3368
|
[2.618, LEVEL_ORANGE],
|
|
3275
3369
|
[3, LEVEL_ANCHOR],
|
|
3370
|
+
[3.272, LEVEL_CORAL],
|
|
3371
|
+
[3.618, LEVEL_PURPLE],
|
|
3276
3372
|
[4.236, LEVEL_GREEN],
|
|
3373
|
+
[4.618, LEVEL_PINK],
|
|
3374
|
+
// Beyond the swing's end (targets): blues, deepening with distance.
|
|
3375
|
+
[-0.27, LEVEL_CYAN],
|
|
3376
|
+
[-0.272, LEVEL_CYAN],
|
|
3377
|
+
[-0.62, LEVEL_BLUE],
|
|
3378
|
+
[-0.618, LEVEL_BLUE],
|
|
3379
|
+
[-1, LEVEL_AQUA],
|
|
3380
|
+
[-1.5, LEVEL_VIOLET],
|
|
3381
|
+
[-2, LEVEL_PURPLE],
|
|
3382
|
+
[-2.5, LEVEL_PINK],
|
|
3277
3383
|
[6.854, LEVEL_TEAL],
|
|
3278
3384
|
[11.09, LEVEL_BLUE]
|
|
3279
3385
|
];
|
|
@@ -3300,8 +3406,36 @@ function cycleLevels(count, enabledCount = count) {
|
|
|
3300
3406
|
}));
|
|
3301
3407
|
}
|
|
3302
3408
|
|
|
3409
|
+
// src/core/drawings/fibPresets.ts
|
|
3410
|
+
var LADDER = [0, 0.236, 0.382, 0.5, 0.618, 0.705, 0.786, 0.886, 1, 1.272, 1.414, 1.618, 2, 2.272, 2.414, 2.618, 3, 3.272, 3.618, 4.236, 4.618, -0.272, -0.618, -1];
|
|
3411
|
+
var OTE_LADDER = [0, 0.236, 0.382, 0.5, 0.62, 0.705, 0.79, 0.886, 1, 1.272, 1.414, 1.618, 2, 2.618, 3, 3.618, 4.236, 4.618, -0.27, -0.62, -1, -1.5, -2, -2.5];
|
|
3412
|
+
function ladder(ratios, on, colors = {}) {
|
|
3413
|
+
return fibLevels(ratios.map((ratio) => ({ ratio, enabled: on.includes(ratio), color: colors[String(ratio)] })));
|
|
3414
|
+
}
|
|
3415
|
+
var FIB_PRESETS = [
|
|
3416
|
+
{
|
|
3417
|
+
key: "classic",
|
|
3418
|
+
label: "Classic",
|
|
3419
|
+
reverse: false,
|
|
3420
|
+
levels: ladder(LADDER, [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1])
|
|
3421
|
+
},
|
|
3422
|
+
{
|
|
3423
|
+
key: "extension",
|
|
3424
|
+
label: "Extension",
|
|
3425
|
+
reverse: true,
|
|
3426
|
+
levels: ladder(LADDER, [0, 1, 1.272, 1.414, 1.618, 2, 2.618, 3.618, 4.236])
|
|
3427
|
+
},
|
|
3428
|
+
{
|
|
3429
|
+
key: "ote",
|
|
3430
|
+
label: "OTE",
|
|
3431
|
+
reverse: false,
|
|
3432
|
+
// The entry zone reads as one band.
|
|
3433
|
+
levels: ladder(OTE_LADDER, [0, 0.5, 0.62, 0.705, 0.79, 1, -0.27, -0.62], { "0.62": LEVEL_AMBER, "0.79": LEVEL_AMBER })
|
|
3434
|
+
}
|
|
3435
|
+
];
|
|
3436
|
+
|
|
3303
3437
|
// src/core/drawings/types/FibRetracement.ts
|
|
3304
|
-
var LEVELS =
|
|
3438
|
+
var LEVELS = FIB_PRESETS[0].levels;
|
|
3305
3439
|
var FibRetracement = class extends FibLevels {
|
|
3306
3440
|
constructor(init) {
|
|
3307
3441
|
super(init);
|
|
@@ -3324,7 +3458,11 @@ var FibRetracement = class extends FibLevels {
|
|
|
3324
3458
|
};
|
|
3325
3459
|
|
|
3326
3460
|
// src/core/drawings/types/FibExtension.ts
|
|
3327
|
-
var LEVELS2 =
|
|
3461
|
+
var LEVELS2 = ladder(
|
|
3462
|
+
[0, 0.236, 0.382, 0.5, 0.618, 0.786, 1, 1.272, 1.414, 1.618, 2, 2.272, 2.414, 2.618, 3, 3.272, 3.618, 4.236, 4.618],
|
|
3463
|
+
[0, 0.382, 0.618, 1, 1.272, 1.618, 2.618],
|
|
3464
|
+
{ "2.618": LEVEL_PURPLE }
|
|
3465
|
+
);
|
|
3328
3466
|
var FibExtension = class extends FibLevels {
|
|
3329
3467
|
constructor() {
|
|
3330
3468
|
super(...arguments);
|
|
@@ -4902,20 +5040,20 @@ function signed(n) {
|
|
|
4902
5040
|
}
|
|
4903
5041
|
function formatDuration(ms) {
|
|
4904
5042
|
const m = Math.abs(ms);
|
|
4905
|
-
const
|
|
5043
|
+
const DAY2 = 864e5;
|
|
4906
5044
|
const HR = 36e5;
|
|
4907
|
-
const
|
|
4908
|
-
if (m >=
|
|
4909
|
-
const d = Math.floor(m /
|
|
4910
|
-
const h = Math.round(m %
|
|
5045
|
+
const MIN2 = 6e4;
|
|
5046
|
+
if (m >= DAY2) {
|
|
5047
|
+
const d = Math.floor(m / DAY2);
|
|
5048
|
+
const h = Math.round(m % DAY2 / HR);
|
|
4911
5049
|
return h ? `${d}d ${h}h` : `${d}d`;
|
|
4912
5050
|
}
|
|
4913
5051
|
if (m >= HR) {
|
|
4914
5052
|
const h = Math.floor(m / HR);
|
|
4915
|
-
const mn = Math.round(m % HR /
|
|
5053
|
+
const mn = Math.round(m % HR / MIN2);
|
|
4916
5054
|
return mn ? `${h}h ${mn}m` : `${h}h`;
|
|
4917
5055
|
}
|
|
4918
|
-
if (m >=
|
|
5056
|
+
if (m >= MIN2) return `${Math.round(m / MIN2)}m`;
|
|
4919
5057
|
return `${Math.round(m / 1e3)}s`;
|
|
4920
5058
|
}
|
|
4921
5059
|
var MeasureBox = class extends Drawing {
|
|
@@ -5478,6 +5616,393 @@ var Magnifier = class extends Drawing {
|
|
|
5478
5616
|
}
|
|
5479
5617
|
};
|
|
5480
5618
|
|
|
5619
|
+
// src/core/drawings/priceAction.ts
|
|
5620
|
+
var GAP_REACH = 3;
|
|
5621
|
+
function nearestBarIndex(bars, time) {
|
|
5622
|
+
if (bars.length === 0) return -1;
|
|
5623
|
+
let lo = 0;
|
|
5624
|
+
let hi = bars.length - 1;
|
|
5625
|
+
while (lo < hi) {
|
|
5626
|
+
const mid = lo + hi >> 1;
|
|
5627
|
+
if (bars[mid].time < time) lo = mid + 1;
|
|
5628
|
+
else hi = mid;
|
|
5629
|
+
}
|
|
5630
|
+
if (lo > 0 && Math.abs(bars[lo - 1].time - time) <= Math.abs(bars[lo].time - time)) return lo - 1;
|
|
5631
|
+
return lo;
|
|
5632
|
+
}
|
|
5633
|
+
function gapAt(bars, i) {
|
|
5634
|
+
const prev = bars[i - 1];
|
|
5635
|
+
const next = bars[i + 1];
|
|
5636
|
+
if (!prev || !next || !bars[i]) return null;
|
|
5637
|
+
if (next.low > prev.high) return { bull: true, top: next.low, bottom: prev.high };
|
|
5638
|
+
if (next.high < prev.low) return { bull: false, top: prev.low, bottom: next.high };
|
|
5639
|
+
return null;
|
|
5640
|
+
}
|
|
5641
|
+
function nearestGap(bars, i) {
|
|
5642
|
+
for (let k = 0; k <= GAP_REACH; k += 1) {
|
|
5643
|
+
for (const j of k === 0 ? [i] : [i - k, i + k]) {
|
|
5644
|
+
const g = gapAt(bars, j);
|
|
5645
|
+
if (g) return { index: j, ...g };
|
|
5646
|
+
}
|
|
5647
|
+
}
|
|
5648
|
+
return null;
|
|
5649
|
+
}
|
|
5650
|
+
function gapState(bars, i) {
|
|
5651
|
+
const g = nearestGap(bars, i);
|
|
5652
|
+
if (!g) return null;
|
|
5653
|
+
const { index, bull, top, bottom } = g;
|
|
5654
|
+
const mid = (top + bottom) / 2;
|
|
5655
|
+
let tested = null;
|
|
5656
|
+
let half = null;
|
|
5657
|
+
let filled = null;
|
|
5658
|
+
let inverted = null;
|
|
5659
|
+
for (let j = index + 2; j < bars.length && inverted === null; j += 1) {
|
|
5660
|
+
const b = bars[j];
|
|
5661
|
+
const reach = bull ? b.low : b.high;
|
|
5662
|
+
const into = (v) => bull ? reach <= v : reach >= v;
|
|
5663
|
+
if (tested === null && into(bull ? top : bottom)) tested = j;
|
|
5664
|
+
if (half === null && into(mid)) half = j;
|
|
5665
|
+
if (filled === null && into(bull ? bottom : top)) filled = j;
|
|
5666
|
+
if (filled !== null && (bull ? b.close < bottom : b.close > top)) inverted = j;
|
|
5667
|
+
}
|
|
5668
|
+
return { index, bull, top, bottom, mid, tested, half, filled, inverted };
|
|
5669
|
+
}
|
|
5670
|
+
function blockState(bars, i, range) {
|
|
5671
|
+
const c = bars[i];
|
|
5672
|
+
if (!c) return null;
|
|
5673
|
+
const bull = c.close < c.open;
|
|
5674
|
+
const top = range === "body" ? Math.max(c.open, c.close) : c.high;
|
|
5675
|
+
const bottom = range === "body" ? Math.min(c.open, c.close) : c.low;
|
|
5676
|
+
const mid = (top + bottom) / 2;
|
|
5677
|
+
let left = false;
|
|
5678
|
+
let tested = null;
|
|
5679
|
+
let half = null;
|
|
5680
|
+
let broken = null;
|
|
5681
|
+
let leftAfterBreak = false;
|
|
5682
|
+
let retest = null;
|
|
5683
|
+
for (let j = i + 1; j < bars.length && retest === null; j += 1) {
|
|
5684
|
+
const b = bars[j];
|
|
5685
|
+
if (broken === null) {
|
|
5686
|
+
if (!left) left = bull ? b.low > top : b.high < bottom;
|
|
5687
|
+
else {
|
|
5688
|
+
if (tested === null && (bull ? b.low <= top : b.high >= bottom)) tested = j;
|
|
5689
|
+
if (half === null && (bull ? b.low <= mid : b.high >= mid)) half = j;
|
|
5690
|
+
}
|
|
5691
|
+
if (bull ? b.close < bottom : b.close > top) broken = j;
|
|
5692
|
+
} else if (!leftAfterBreak) leftAfterBreak = bull ? b.high < bottom : b.low > top;
|
|
5693
|
+
else if (bull ? b.high >= bottom : b.low <= top) retest = j;
|
|
5694
|
+
}
|
|
5695
|
+
return { index: i, bull, top, bottom, mid, tested, half, broken, retest };
|
|
5696
|
+
}
|
|
5697
|
+
function liquidityState(bars, i, side) {
|
|
5698
|
+
const c = bars[i];
|
|
5699
|
+
if (!c) return null;
|
|
5700
|
+
const high = side === "high";
|
|
5701
|
+
const price = high ? c.high : c.low;
|
|
5702
|
+
let swept = null;
|
|
5703
|
+
let broken = null;
|
|
5704
|
+
for (let j = i + 1; j < bars.length && broken === null; j += 1) {
|
|
5705
|
+
const b = bars[j];
|
|
5706
|
+
if (high ? b.close > price : b.close < price) broken = j;
|
|
5707
|
+
else if (swept === null && (high ? b.high > price : b.low < price)) swept = j;
|
|
5708
|
+
}
|
|
5709
|
+
return { index: i, high, price, swept, broken };
|
|
5710
|
+
}
|
|
5711
|
+
|
|
5712
|
+
// src/core/drawings/types/PriceActionZone.ts
|
|
5713
|
+
var candlesSeen = /* @__PURE__ */ new WeakMap();
|
|
5714
|
+
var PriceActionTool = class extends Drawing {
|
|
5715
|
+
anchorSchema() {
|
|
5716
|
+
return { min: 1, max: 1, slots: [{ role: "candle", free: "x" }] };
|
|
5717
|
+
}
|
|
5718
|
+
/** The chart's candles, and the one nearest the anchor. */
|
|
5719
|
+
candles(proj) {
|
|
5720
|
+
const a = this.anchors[0];
|
|
5721
|
+
if (!a) return null;
|
|
5722
|
+
let bars = candlesSeen.get(proj);
|
|
5723
|
+
if (!bars) {
|
|
5724
|
+
bars = proj.barsInRange?.(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY) ?? [];
|
|
5725
|
+
candlesSeen.set(proj, bars);
|
|
5726
|
+
}
|
|
5727
|
+
return bars.length > 0 ? { bars, at: nearestBarIndex(bars, a.time) } : null;
|
|
5728
|
+
}
|
|
5729
|
+
/** Half a candle's width at bar `i`, in pixels. */
|
|
5730
|
+
halfBar(proj, bars, i) {
|
|
5731
|
+
const a = bars[Math.max(0, i - 1)];
|
|
5732
|
+
const b = bars[Math.min(bars.length - 1, Math.max(1, i))];
|
|
5733
|
+
if (!a || !b || a === b) return 3;
|
|
5734
|
+
return Math.max(1, Math.abs(proj.xOf(b.time) - proj.xOf(a.time)) / 2);
|
|
5735
|
+
}
|
|
5736
|
+
/** Pixel x for the right edge of a zone that stops at bar `end`, or runs on to the chart's edge. */
|
|
5737
|
+
rightEdge(proj, bars, end) {
|
|
5738
|
+
if (end === null) return Math.max(proj.width, proj.xOf(bars[bars.length - 1].time));
|
|
5739
|
+
return proj.xOf(bars[end].time) + this.halfBar(proj, bars, end);
|
|
5740
|
+
}
|
|
5741
|
+
/** The anchor itself, for a tool with nothing on the candles to hang its handle on. */
|
|
5742
|
+
anchorHandle(proj) {
|
|
5743
|
+
const a = this.anchors[0];
|
|
5744
|
+
const y = a ? proj.yOf(a.price, this.paneId) : null;
|
|
5745
|
+
return a && y != null ? [[proj.xOf(a.time), y]] : [];
|
|
5746
|
+
}
|
|
5747
|
+
hitHandle(px, py, proj, tol) {
|
|
5748
|
+
return handleAt(px, py, this.handlePoints(proj), tol + 3);
|
|
5749
|
+
}
|
|
5750
|
+
priceRange() {
|
|
5751
|
+
return null;
|
|
5752
|
+
}
|
|
5753
|
+
};
|
|
5754
|
+
var PriceActionZone = class extends PriceActionTool {
|
|
5755
|
+
/** The zone's pixel layout, or null when the candles don't form one. */
|
|
5756
|
+
zone(proj) {
|
|
5757
|
+
const c = this.candles(proj);
|
|
5758
|
+
const f = c && this.formation(c.bars, c.at);
|
|
5759
|
+
if (!c || !f) return null;
|
|
5760
|
+
const yt = proj.yOf(f.top, this.paneId);
|
|
5761
|
+
const yb = proj.yOf(f.bottom, this.paneId);
|
|
5762
|
+
if (yt == null || yb == null) return null;
|
|
5763
|
+
const { bars } = c;
|
|
5764
|
+
const s = this.settings();
|
|
5765
|
+
const left = (i) => proj.xOf(bars[i].time) - this.halfBar(proj, bars, i);
|
|
5766
|
+
const yTop = Math.min(yt, yb);
|
|
5767
|
+
const yBottom = Math.max(yt, yb);
|
|
5768
|
+
const midY = proj.yOf(f.mid, this.paneId) ?? (yTop + yBottom) / 2;
|
|
5769
|
+
const flip = f.flip && { x1: left(f.flip.from), x2: this.rightEdge(proj, bars, f.flip.to), fill: f.bull ? s.downColor : s.upColor };
|
|
5770
|
+
const edge = s.extend === "tested" ? f.bull ? f.top : f.bottom : s.extend === "half" ? f.mid : f.bull ? f.bottom : f.top;
|
|
5771
|
+
const edgeY = proj.yOf(edge, this.paneId);
|
|
5772
|
+
return {
|
|
5773
|
+
x1: left(f.start),
|
|
5774
|
+
x2: this.rightEdge(proj, bars, f.end),
|
|
5775
|
+
yTop,
|
|
5776
|
+
yBottom,
|
|
5777
|
+
fill: f.bull ? s.upColor : s.downColor,
|
|
5778
|
+
border: s.border,
|
|
5779
|
+
midY: s.midline ? midY : null,
|
|
5780
|
+
faded: f.end !== null && s.fade && !flip,
|
|
5781
|
+
marker: f.end !== null && !flip && edgeY != null ? { x: proj.xOf(bars[f.end].time), y: edgeY } : null,
|
|
5782
|
+
flip,
|
|
5783
|
+
handle: [proj.xOf(bars[f.index].time), midY]
|
|
5784
|
+
};
|
|
5785
|
+
}
|
|
5786
|
+
hitTest(px, py, proj, tol) {
|
|
5787
|
+
const z = this.zone(proj);
|
|
5788
|
+
if (!z) {
|
|
5789
|
+
const a = this.anchors[0];
|
|
5790
|
+
return a != null && Math.abs(px - proj.xOf(a.time)) <= tol;
|
|
5791
|
+
}
|
|
5792
|
+
const inY = py >= z.yTop - tol && py <= z.yBottom + tol;
|
|
5793
|
+
if (inY && px >= z.x1 - tol && px <= z.x2 + tol) return true;
|
|
5794
|
+
return z.flip != null && inY && px >= z.flip.x1 - tol && px <= z.flip.x2 + tol;
|
|
5795
|
+
}
|
|
5796
|
+
handlePoints(proj) {
|
|
5797
|
+
const z = this.zone(proj);
|
|
5798
|
+
return z ? [z.handle] : this.anchorHandle(proj);
|
|
5799
|
+
}
|
|
5800
|
+
bounds(proj) {
|
|
5801
|
+
const z = this.zone(proj);
|
|
5802
|
+
if (!z) return null;
|
|
5803
|
+
const right = Math.min(proj.width, z.flip ? z.flip.x2 : z.x2);
|
|
5804
|
+
return { x: z.x1, y: z.yTop, w: Math.max(1, right - z.x1), h: Math.max(1, z.yBottom - z.yTop) };
|
|
5805
|
+
}
|
|
5806
|
+
};
|
|
5807
|
+
|
|
5808
|
+
// src/core/drawings/types/FairValueGap.ts
|
|
5809
|
+
var EXTEND_OPTIONS = [
|
|
5810
|
+
{ value: "tested", label: "Until tested" },
|
|
5811
|
+
{ value: "half", label: "Until 50%" },
|
|
5812
|
+
{ value: "filled", label: "Until filled" },
|
|
5813
|
+
{ value: "always", label: "Always" }
|
|
5814
|
+
];
|
|
5815
|
+
function defaults2() {
|
|
5816
|
+
return { extend: "filled", upColor: `${BULLISH}33`, downColor: `${BEARISH}33`, midline: true, border: false, fade: true, inverse: false };
|
|
5817
|
+
}
|
|
5818
|
+
var FairValueGap = class extends PriceActionZone {
|
|
5819
|
+
constructor(init) {
|
|
5820
|
+
super(init);
|
|
5821
|
+
this.type = "fairvaluegap";
|
|
5822
|
+
if (!this.gap) this.gap = defaults2();
|
|
5823
|
+
}
|
|
5824
|
+
settings() {
|
|
5825
|
+
return this.gap;
|
|
5826
|
+
}
|
|
5827
|
+
formation(bars, at) {
|
|
5828
|
+
const s = gapState(bars, at);
|
|
5829
|
+
if (!s) return null;
|
|
5830
|
+
const { extend, inverse } = this.gap;
|
|
5831
|
+
const flip = inverse && extend === "filled" && s.inverted !== null ? { from: s.inverted, to: null } : null;
|
|
5832
|
+
return { ...s, start: s.index - 1, end: extend === "always" ? null : s[extend], flip };
|
|
5833
|
+
}
|
|
5834
|
+
schema() {
|
|
5835
|
+
return {
|
|
5836
|
+
fields: [
|
|
5837
|
+
{ path: "gap.extend", label: "Extend right", kind: "select", options: EXTEND_OPTIONS, group: "behavior" },
|
|
5838
|
+
{ path: "gap.upColor", label: "Bullish", kind: "color", group: "fill" },
|
|
5839
|
+
{ path: "gap.downColor", label: "Bearish", kind: "color", group: "fill" },
|
|
5840
|
+
{ path: "gap.midline", label: "Midline", kind: "boolean", group: "line" },
|
|
5841
|
+
{ path: "gap.border", label: "Border", kind: "boolean", group: "line" },
|
|
5842
|
+
{ path: "gap.fade", label: "Fade at end", kind: "boolean", group: "behavior", when: { path: "gap.extend", in: ["tested", "half", "filled"] } },
|
|
5843
|
+
{ path: "gap.inverse", label: "Flip on close", kind: "boolean", group: "behavior", when: { path: "gap.extend", in: ["filled"] } }
|
|
5844
|
+
]
|
|
5845
|
+
};
|
|
5846
|
+
}
|
|
5847
|
+
writeProps() {
|
|
5848
|
+
return { ...this.gap };
|
|
5849
|
+
}
|
|
5850
|
+
readProps(props) {
|
|
5851
|
+
const d = defaults2();
|
|
5852
|
+
const p = props;
|
|
5853
|
+
this.gap = {
|
|
5854
|
+
extend: EXTEND_OPTIONS.some((o) => o.value === p.extend) ? p.extend : d.extend,
|
|
5855
|
+
upColor: typeof p.upColor === "string" ? p.upColor : d.upColor,
|
|
5856
|
+
downColor: typeof p.downColor === "string" ? p.downColor : d.downColor,
|
|
5857
|
+
midline: typeof p.midline === "boolean" ? p.midline : d.midline,
|
|
5858
|
+
border: typeof p.border === "boolean" ? p.border : d.border,
|
|
5859
|
+
fade: typeof p.fade === "boolean" ? p.fade : d.fade,
|
|
5860
|
+
inverse: typeof p.inverse === "boolean" ? p.inverse : d.inverse
|
|
5861
|
+
};
|
|
5862
|
+
}
|
|
5863
|
+
};
|
|
5864
|
+
|
|
5865
|
+
// src/core/drawings/types/OrderBlock.ts
|
|
5866
|
+
var RANGE_OPTIONS = [
|
|
5867
|
+
{ value: "body", label: "Body" },
|
|
5868
|
+
{ value: "wick", label: "Full range" }
|
|
5869
|
+
];
|
|
5870
|
+
var EXTEND_OPTIONS2 = [
|
|
5871
|
+
{ value: "tested", label: "Until tested" },
|
|
5872
|
+
{ value: "half", label: "Until 50%" },
|
|
5873
|
+
{ value: "broken", label: "Until broken" },
|
|
5874
|
+
{ value: "always", label: "Always" }
|
|
5875
|
+
];
|
|
5876
|
+
function defaults3() {
|
|
5877
|
+
return { range: "body", extend: "broken", upColor: `${BULLISH}29`, downColor: `${BEARISH}29`, midline: true, border: true, fade: true, breaker: true };
|
|
5878
|
+
}
|
|
5879
|
+
var OrderBlock = class extends PriceActionZone {
|
|
5880
|
+
constructor(init) {
|
|
5881
|
+
super(init);
|
|
5882
|
+
this.type = "orderblock";
|
|
5883
|
+
if (!this.block) this.block = defaults3();
|
|
5884
|
+
}
|
|
5885
|
+
settings() {
|
|
5886
|
+
return this.block;
|
|
5887
|
+
}
|
|
5888
|
+
formation(bars, at) {
|
|
5889
|
+
const s = blockState(bars, at, this.block.range);
|
|
5890
|
+
if (!s) return null;
|
|
5891
|
+
const { extend, breaker } = this.block;
|
|
5892
|
+
const flip = breaker && extend === "broken" && s.broken !== null ? { from: s.broken, to: s.retest } : null;
|
|
5893
|
+
return { ...s, start: s.index, end: extend === "always" ? null : s[extend], flip };
|
|
5894
|
+
}
|
|
5895
|
+
schema() {
|
|
5896
|
+
return {
|
|
5897
|
+
fields: [
|
|
5898
|
+
{ path: "block.range", label: "Zone", kind: "select", options: RANGE_OPTIONS, group: "behavior" },
|
|
5899
|
+
{ path: "block.extend", label: "Extend right", kind: "select", options: EXTEND_OPTIONS2, group: "behavior" },
|
|
5900
|
+
{ path: "block.upColor", label: "Bullish", kind: "color", group: "fill" },
|
|
5901
|
+
{ path: "block.downColor", label: "Bearish", kind: "color", group: "fill" },
|
|
5902
|
+
{ path: "block.midline", label: "Midline", kind: "boolean", group: "line" },
|
|
5903
|
+
{ path: "block.border", label: "Border", kind: "boolean", group: "line" },
|
|
5904
|
+
{ path: "block.fade", label: "Fade at end", kind: "boolean", group: "behavior", when: { path: "block.extend", in: ["tested", "half", "broken"] } },
|
|
5905
|
+
{ path: "block.breaker", label: "Breaker", kind: "boolean", group: "behavior", when: { path: "block.extend", in: ["broken"] } }
|
|
5906
|
+
]
|
|
5907
|
+
};
|
|
5908
|
+
}
|
|
5909
|
+
writeProps() {
|
|
5910
|
+
return { ...this.block };
|
|
5911
|
+
}
|
|
5912
|
+
readProps(props) {
|
|
5913
|
+
const d = defaults3();
|
|
5914
|
+
const p = props;
|
|
5915
|
+
this.block = {
|
|
5916
|
+
range: p.range === "body" || p.range === "wick" ? p.range : d.range,
|
|
5917
|
+
extend: EXTEND_OPTIONS2.some((o) => o.value === p.extend) ? p.extend : d.extend,
|
|
5918
|
+
upColor: typeof p.upColor === "string" ? p.upColor : d.upColor,
|
|
5919
|
+
downColor: typeof p.downColor === "string" ? p.downColor : d.downColor,
|
|
5920
|
+
midline: typeof p.midline === "boolean" ? p.midline : d.midline,
|
|
5921
|
+
border: typeof p.border === "boolean" ? p.border : d.border,
|
|
5922
|
+
fade: typeof p.fade === "boolean" ? p.fade : d.fade,
|
|
5923
|
+
breaker: typeof p.breaker === "boolean" ? p.breaker : d.breaker
|
|
5924
|
+
};
|
|
5925
|
+
}
|
|
5926
|
+
};
|
|
5927
|
+
|
|
5928
|
+
// src/core/drawings/types/Liquidity.ts
|
|
5929
|
+
var EXTEND_OPTIONS3 = [
|
|
5930
|
+
{ value: "swept", label: "Until swept" },
|
|
5931
|
+
{ value: "broken", label: "Until broken" },
|
|
5932
|
+
{ value: "always", label: "Always" }
|
|
5933
|
+
];
|
|
5934
|
+
function defaults4() {
|
|
5935
|
+
return { extend: "swept", markSweep: true };
|
|
5936
|
+
}
|
|
5937
|
+
var Liquidity = class extends PriceActionTool {
|
|
5938
|
+
constructor(init) {
|
|
5939
|
+
super(init);
|
|
5940
|
+
this.type = "liquidity";
|
|
5941
|
+
if (!this.liq) this.liq = defaults4();
|
|
5942
|
+
}
|
|
5943
|
+
anchorSchema() {
|
|
5944
|
+
return { min: 1, max: 1, slots: [{ role: "candle", free: "both" }] };
|
|
5945
|
+
}
|
|
5946
|
+
state(proj) {
|
|
5947
|
+
const c = this.candles(proj);
|
|
5948
|
+
const a = this.anchors[0];
|
|
5949
|
+
if (!c || !a) return null;
|
|
5950
|
+
const bar = c.bars[c.at];
|
|
5951
|
+
return liquidityState(c.bars, c.at, a.price >= (bar.high + bar.low) / 2 ? "high" : "low");
|
|
5952
|
+
}
|
|
5953
|
+
line(proj) {
|
|
5954
|
+
const c = this.candles(proj);
|
|
5955
|
+
const s = this.state(proj);
|
|
5956
|
+
if (!c || !s) return null;
|
|
5957
|
+
const y = proj.yOf(s.price, this.paneId);
|
|
5958
|
+
if (y == null) return null;
|
|
5959
|
+
const { bars } = c;
|
|
5960
|
+
const { extend, markSweep } = this.liq;
|
|
5961
|
+
const end = extend === "always" ? null : extend === "broken" ? s.broken : s.swept ?? s.broken;
|
|
5962
|
+
const x1 = proj.xOf(bars[s.index].time);
|
|
5963
|
+
let sweep = null;
|
|
5964
|
+
if (markSweep && s.swept !== null && (end === null || s.swept <= end)) {
|
|
5965
|
+
const b = bars[s.swept];
|
|
5966
|
+
const wick = proj.yOf(s.high ? b.high : b.low, this.paneId);
|
|
5967
|
+
if (wick != null) sweep = { x: proj.xOf(b.time), y: wick + (s.high ? -9 : 9) };
|
|
5968
|
+
}
|
|
5969
|
+
return { x1, x2: this.rightEdge(proj, bars, end), y, sweep, handle: [x1, y] };
|
|
5970
|
+
}
|
|
5971
|
+
hitTest(px, py, proj, tol) {
|
|
5972
|
+
const l = this.line(proj);
|
|
5973
|
+
return l != null && px >= l.x1 - tol && px <= l.x2 + tol && Math.abs(py - l.y) <= tol;
|
|
5974
|
+
}
|
|
5975
|
+
handlePoints(proj) {
|
|
5976
|
+
const l = this.line(proj);
|
|
5977
|
+
return l ? [l.handle] : this.anchorHandle(proj);
|
|
5978
|
+
}
|
|
5979
|
+
bounds(proj) {
|
|
5980
|
+
const l = this.line(proj);
|
|
5981
|
+
if (!l) return null;
|
|
5982
|
+
return { x: l.x1, y: l.y - 4, w: Math.max(1, Math.min(proj.width, l.x2) - l.x1), h: 8 };
|
|
5983
|
+
}
|
|
5984
|
+
schema() {
|
|
5985
|
+
return {
|
|
5986
|
+
fields: [
|
|
5987
|
+
...LINE_FIELDS,
|
|
5988
|
+
{ path: "liq.extend", label: "Extend right", kind: "select", options: EXTEND_OPTIONS3, group: "behavior" },
|
|
5989
|
+
{ path: "liq.markSweep", label: "Mark sweep", kind: "boolean", group: "behavior" }
|
|
5990
|
+
]
|
|
5991
|
+
};
|
|
5992
|
+
}
|
|
5993
|
+
writeProps() {
|
|
5994
|
+
return { ...this.liq };
|
|
5995
|
+
}
|
|
5996
|
+
readProps(props) {
|
|
5997
|
+
const d = defaults4();
|
|
5998
|
+
const p = props;
|
|
5999
|
+
this.liq = {
|
|
6000
|
+
extend: EXTEND_OPTIONS3.some((o) => o.value === p.extend) ? p.extend : d.extend,
|
|
6001
|
+
markSweep: typeof p.markSweep === "boolean" ? p.markSweep : d.markSweep
|
|
6002
|
+
};
|
|
6003
|
+
}
|
|
6004
|
+
};
|
|
6005
|
+
|
|
5481
6006
|
// src/core/drawings/registry.ts
|
|
5482
6007
|
var REGISTRY2 = /* @__PURE__ */ new Map();
|
|
5483
6008
|
function registerDrawingType(meta) {
|
|
@@ -6147,6 +6672,36 @@ registerDrawingType({
|
|
|
6147
6672
|
defaultStyle: { lineColor: BULLISH, lineWidth: 1, lineStyle: "solid" },
|
|
6148
6673
|
create: (init) => new FixedRangeVolumeProfile(init)
|
|
6149
6674
|
});
|
|
6675
|
+
var FVG_ICON = svg24('<path d="M6 15v6M12 3v18M18 2v6"/><rect x="3.5" y="9.5" width="17" height="5" rx="1" fill="currentColor" fill-opacity="0.28" stroke-width="1.4"/>');
|
|
6676
|
+
var ORDER_BLOCK_ICON = svg24('<rect x="4" y="7.5" width="5" height="8" rx="1"/><path d="M6.5 4v3.5M6.5 15.5V19"/><rect x="9" y="7.5" width="11.5" height="8" rx="1" fill="currentColor" fill-opacity="0.22" stroke-width="1.4"/>');
|
|
6677
|
+
var LIQUIDITY_ICON = svg24('<path d="M3 8h12" stroke-dasharray="2.5 2.5"/><path d="m16.5 4.5 4 4m0-4-4 4"/><path d="M3.5 20 8 13.5l4 3.5 5-8"/>');
|
|
6678
|
+
registerDrawingType({
|
|
6679
|
+
type: "fairvaluegap",
|
|
6680
|
+
group: "priceaction",
|
|
6681
|
+
label: "Fair Value Gap",
|
|
6682
|
+
icon: FVG_ICON,
|
|
6683
|
+
defaultStyle: { lineColor: BULLISH, lineWidth: 1, lineStyle: "solid" },
|
|
6684
|
+
placementHint: "Click the middle candle of a gap",
|
|
6685
|
+
create: (init) => new FairValueGap(init)
|
|
6686
|
+
});
|
|
6687
|
+
registerDrawingType({
|
|
6688
|
+
type: "orderblock",
|
|
6689
|
+
group: "priceaction",
|
|
6690
|
+
label: "Order Block",
|
|
6691
|
+
icon: ORDER_BLOCK_ICON,
|
|
6692
|
+
defaultStyle: { lineColor: BULLISH, lineWidth: 1, lineStyle: "solid" },
|
|
6693
|
+
placementHint: "Click the candle that forms the block",
|
|
6694
|
+
create: (init) => new OrderBlock(init)
|
|
6695
|
+
});
|
|
6696
|
+
registerDrawingType({
|
|
6697
|
+
type: "liquidity",
|
|
6698
|
+
group: "priceaction",
|
|
6699
|
+
label: "Liquidity",
|
|
6700
|
+
icon: LIQUIDITY_ICON,
|
|
6701
|
+
defaultStyle: { lineColor: WARNING, lineWidth: 1, lineStyle: "solid" },
|
|
6702
|
+
placementHint: "Click near a candle's high or low",
|
|
6703
|
+
create: (init) => new Liquidity(init)
|
|
6704
|
+
});
|
|
6150
6705
|
|
|
6151
6706
|
// src/core/model/inputs.ts
|
|
6152
6707
|
function inputVisible(when, values) {
|
|
@@ -6184,6 +6739,7 @@ exports.BEARISH = BEARISH;
|
|
|
6184
6739
|
exports.BULLISH = BULLISH;
|
|
6185
6740
|
exports.CATEGORICAL = CATEGORICAL;
|
|
6186
6741
|
exports.CHIP_PLATE = CHIP_PLATE;
|
|
6742
|
+
exports.CONTEXT_MENU_BUILTIN_ORDER = CONTEXT_MENU_BUILTIN_ORDER;
|
|
6187
6743
|
exports.CROSSHAIR = CROSSHAIR;
|
|
6188
6744
|
exports.DEFAULT_PANEL_MAX_WIDTH = DEFAULT_PANEL_MAX_WIDTH;
|
|
6189
6745
|
exports.DEFAULT_PANEL_MIN_WIDTH = DEFAULT_PANEL_MIN_WIDTH;
|