@luxalgo/vela 0.5.4 → 0.6.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/{DataProvider-DgS2UyMc.d.cts → DataProvider-BNKtYU5V.d.cts} +22 -3
- package/dist/{DataProvider-Cqc_BaJ9.d.ts → DataProvider-gJjN_0eh.d.ts} +22 -3
- package/dist/{chunk-D6WM5IUE.js → chunk-4MQEG67Z.js} +77 -18
- package/dist/{chunk-JBQUY2RI.js → chunk-6LZJRO2S.js} +48 -18
- package/dist/{contributions-DuIxJWeH.d.ts → contributions-D64UA74H.d.cts} +9 -2
- package/dist/{contributions-4Nh1jbvb.d.cts → contributions-lPAgo9Cu.d.ts} +9 -2
- package/dist/{history-FsmvCIo4.d.ts → history-CVoFDJ2D.d.ts} +21 -3
- package/dist/{history-HofqYEh2.d.cts → history-fSMXVLt1.d.cts} +21 -3
- package/dist/index.cjs +77 -18
- package/dist/index.d.cts +14 -6
- package/dist/index.d.ts +14 -6
- package/dist/index.js +1 -1
- package/dist/{options-BlQ00Fju.d.cts → options-BqGeFHtp.d.cts} +15 -1
- package/dist/{options-BlQ00Fju.d.ts → options-BqGeFHtp.d.ts} +15 -1
- package/dist/{plugin-DJR6z3e0.d.cts → plugin-D5ni4WEJ.d.cts} +3 -3
- package/dist/{plugin-N_EaXN4-.d.ts → plugin-o5HJH46Z.d.ts} +3 -3
- package/dist/plugin.d.cts +4 -4
- package/dist/plugin.d.ts +4 -4
- 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/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/vela.global.js +77 -18
- package/dist/vela.global.min.js +29 -29
- package/dist/widget.cjs +175 -40
- package/dist/widget.d.cts +23 -15
- package/dist/widget.d.ts +23 -15
- package/dist/widget.js +56 -10
- package/dist/workspace.cjs +172 -36
- package/dist/workspace.d.cts +20 -5
- package/dist/workspace.d.ts +20 -5
- package/dist/workspace.js +52 -5
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MarketConfig, O as OHLCV, U as Unsubscribe } from './options-
|
|
1
|
+
import { M as MarketConfig, O as OHLCV, U as Unsubscribe } from './options-BqGeFHtp.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Symbol metadata an engine may need (e.g. Pine `syminfo.*`). Free-form beyond
|
|
@@ -26,6 +26,12 @@ interface BarRange {
|
|
|
26
26
|
to?: number;
|
|
27
27
|
/** Max bars. */
|
|
28
28
|
limit?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Trading session to serve (`'regular'` | `'extended'`) — rides every request on
|
|
31
|
+
* markets that have sessions; absent = the provider's default. A provider without
|
|
32
|
+
* a session concept ignores it.
|
|
33
|
+
*/
|
|
34
|
+
session?: string;
|
|
29
35
|
}
|
|
30
36
|
interface MarketDataFeed {
|
|
31
37
|
/** Load the initial history (from a provider or the offline `data` array). */
|
|
@@ -64,6 +70,15 @@ interface SymbolDescriptor {
|
|
|
64
70
|
description?: string;
|
|
65
71
|
/** Instrument class, free-form (e.g. `crypto`, `futures`, `stock`). */
|
|
66
72
|
type?: string;
|
|
73
|
+
/**
|
|
74
|
+
* The instrument's LISTING-venue prefix (`NASDAQ`, `NYSE`, `AMEX`) — a property of the
|
|
75
|
+
* SYMBOL, not of the provider: AAPL is Nasdaq-listed and IBM NYSE-listed even when one
|
|
76
|
+
* provider supplies both tapes. When declared, it is what pickers/legends display, what
|
|
77
|
+
* `PREFIX:TICKER` strings resolve against (TradingView parity: `NYSE:AAPL` is NOT
|
|
78
|
+
* found), and what the canonical committed/persisted form carries. Absent on venues
|
|
79
|
+
* where the provider IS the identity (crypto, fx) — the provider name prefixes those.
|
|
80
|
+
*/
|
|
81
|
+
prefix?: string;
|
|
67
82
|
/** Owning provider name — annotated by the registry aggregation (badges in pickers). */
|
|
68
83
|
provider?: string;
|
|
69
84
|
}
|
|
@@ -119,9 +134,13 @@ interface DataProvider {
|
|
|
119
134
|
/**
|
|
120
135
|
* Open a true live stream for `ticker`/`timeframe`. Each call to `onBar` delivers
|
|
121
136
|
* the forming candle (or a freshly-closed one). Returns an unsubscribe fn. Absent
|
|
122
|
-
* ⇒ the feed polls `getBars` for ticks instead.
|
|
137
|
+
* ⇒ the feed polls `getBars` for ticks instead. `opts.session` names the trading
|
|
138
|
+
* session the chart is showing (see {@link BarRange.session}) — a provider whose
|
|
139
|
+
* live source cannot filter by session may fall back to polling internally.
|
|
123
140
|
*/
|
|
124
|
-
subscribe?(ticker: string, timeframe: string, onBar: (bar: OHLCV) => void
|
|
141
|
+
subscribe?(ticker: string, timeframe: string, onBar: (bar: OHLCV) => void, opts?: {
|
|
142
|
+
session?: string;
|
|
143
|
+
}): Unsubscribe;
|
|
125
144
|
/** Apply runtime config (e.g. API keys). Absent ⇒ no configuration needed. */
|
|
126
145
|
configure?(config: unknown): void;
|
|
127
146
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MarketConfig, O as OHLCV, U as Unsubscribe } from './options-
|
|
1
|
+
import { M as MarketConfig, O as OHLCV, U as Unsubscribe } from './options-BqGeFHtp.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Symbol metadata an engine may need (e.g. Pine `syminfo.*`). Free-form beyond
|
|
@@ -26,6 +26,12 @@ interface BarRange {
|
|
|
26
26
|
to?: number;
|
|
27
27
|
/** Max bars. */
|
|
28
28
|
limit?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Trading session to serve (`'regular'` | `'extended'`) — rides every request on
|
|
31
|
+
* markets that have sessions; absent = the provider's default. A provider without
|
|
32
|
+
* a session concept ignores it.
|
|
33
|
+
*/
|
|
34
|
+
session?: string;
|
|
29
35
|
}
|
|
30
36
|
interface MarketDataFeed {
|
|
31
37
|
/** Load the initial history (from a provider or the offline `data` array). */
|
|
@@ -64,6 +70,15 @@ interface SymbolDescriptor {
|
|
|
64
70
|
description?: string;
|
|
65
71
|
/** Instrument class, free-form (e.g. `crypto`, `futures`, `stock`). */
|
|
66
72
|
type?: string;
|
|
73
|
+
/**
|
|
74
|
+
* The instrument's LISTING-venue prefix (`NASDAQ`, `NYSE`, `AMEX`) — a property of the
|
|
75
|
+
* SYMBOL, not of the provider: AAPL is Nasdaq-listed and IBM NYSE-listed even when one
|
|
76
|
+
* provider supplies both tapes. When declared, it is what pickers/legends display, what
|
|
77
|
+
* `PREFIX:TICKER` strings resolve against (TradingView parity: `NYSE:AAPL` is NOT
|
|
78
|
+
* found), and what the canonical committed/persisted form carries. Absent on venues
|
|
79
|
+
* where the provider IS the identity (crypto, fx) — the provider name prefixes those.
|
|
80
|
+
*/
|
|
81
|
+
prefix?: string;
|
|
67
82
|
/** Owning provider name — annotated by the registry aggregation (badges in pickers). */
|
|
68
83
|
provider?: string;
|
|
69
84
|
}
|
|
@@ -119,9 +134,13 @@ interface DataProvider {
|
|
|
119
134
|
/**
|
|
120
135
|
* Open a true live stream for `ticker`/`timeframe`. Each call to `onBar` delivers
|
|
121
136
|
* the forming candle (or a freshly-closed one). Returns an unsubscribe fn. Absent
|
|
122
|
-
* ⇒ the feed polls `getBars` for ticks instead.
|
|
137
|
+
* ⇒ the feed polls `getBars` for ticks instead. `opts.session` names the trading
|
|
138
|
+
* session the chart is showing (see {@link BarRange.session}) — a provider whose
|
|
139
|
+
* live source cannot filter by session may fall back to polling internally.
|
|
123
140
|
*/
|
|
124
|
-
subscribe?(ticker: string, timeframe: string, onBar: (bar: OHLCV) => void
|
|
141
|
+
subscribe?(ticker: string, timeframe: string, onBar: (bar: OHLCV) => void, opts?: {
|
|
142
|
+
session?: string;
|
|
143
|
+
}): Unsubscribe;
|
|
125
144
|
/** Apply runtime config (e.g. API keys). Absent ⇒ no configuration needed. */
|
|
126
145
|
configure?(config: unknown): void;
|
|
127
146
|
/**
|
|
@@ -575,8 +575,8 @@ var RendererControl = class {
|
|
|
575
575
|
};
|
|
576
576
|
|
|
577
577
|
// src/data/BarStore.ts
|
|
578
|
-
function seriesKey(provider, symbol, timeframe) {
|
|
579
|
-
return `${provider}|${symbol}|${timeframe}`;
|
|
578
|
+
function seriesKey(provider, symbol, timeframe, session) {
|
|
579
|
+
return `${provider}|${symbol}|${timeframe}${session && session !== "regular" ? `|${session}` : ""}`;
|
|
580
580
|
}
|
|
581
581
|
function symbolOf(key) {
|
|
582
582
|
return key.split("|")[1] ?? "";
|
|
@@ -685,7 +685,7 @@ var ProviderRegistry = class {
|
|
|
685
685
|
/** Register (or replace) a provider; returns a promise that settles when its index is built. */
|
|
686
686
|
register(rawName, provider) {
|
|
687
687
|
const name = normName(rawName);
|
|
688
|
-
const entry = { name, provider, index: null, descriptors: [], settled: false, settle: Promise.resolve() };
|
|
688
|
+
const entry = { name, provider, index: null, prefixIndex: null, byTicker: null, descriptors: [], settled: false, settle: Promise.resolve() };
|
|
689
689
|
this.entries.set(name, entry);
|
|
690
690
|
entry.settle = this.buildIndex(entry);
|
|
691
691
|
queueMicrotask(() => this.notify(false));
|
|
@@ -698,6 +698,9 @@ var ProviderRegistry = class {
|
|
|
698
698
|
const symbols = await entry.provider.listSymbols();
|
|
699
699
|
entry.descriptors = symbols;
|
|
700
700
|
entry.index = new Set(symbols.map((s) => normTicker(s.ticker)));
|
|
701
|
+
entry.byTicker = new Map(symbols.map((s) => [normTicker(s.ticker), s]));
|
|
702
|
+
entry.prefixIndex = /* @__PURE__ */ new Map();
|
|
703
|
+
for (const s of symbols) if (s.prefix) entry.prefixIndex.set(`${normName(s.prefix)}:${normTicker(s.ticker)}`, s);
|
|
701
704
|
}
|
|
702
705
|
} catch {
|
|
703
706
|
entry.index = null;
|
|
@@ -733,14 +736,25 @@ var ProviderRegistry = class {
|
|
|
733
736
|
}
|
|
734
737
|
/**
|
|
735
738
|
* Resolve a symbol to `{ provider, ticker }`, or null when nothing can serve it
|
|
736
|
-
* yet. Explicit prefix → that provider (must be registered)
|
|
737
|
-
*
|
|
738
|
-
*
|
|
739
|
-
*
|
|
739
|
+
* yet. Explicit prefix → that provider (must be registered), else a provider whose
|
|
740
|
+
* index declares that LISTING prefix for that ticker (`NASDAQ:AAPL` routes to the
|
|
741
|
+
* provider serving Nasdaq-listed AAPL — TradingView-strict, so `NYSE:AAPL` resolves
|
|
742
|
+
* to nothing rather than auto-correcting). Bare → first indexed provider
|
|
743
|
+
* (registration order, `opts.default` first) that contains the ticker;
|
|
744
|
+
* `opts.lenient` additionally allows a sole registered provider before its index
|
|
745
|
+
* exists.
|
|
740
746
|
*/
|
|
741
747
|
resolve(raw, opts = {}) {
|
|
742
748
|
const { provider, ticker } = this.parse(raw);
|
|
743
|
-
if (provider)
|
|
749
|
+
if (provider) {
|
|
750
|
+
if (this.entries.has(provider)) return { provider, ticker };
|
|
751
|
+
const key = `${provider}:${normTicker(ticker)}`;
|
|
752
|
+
for (const name of this.candidateOrder(opts.default)) {
|
|
753
|
+
const d = this.entries.get(name).prefixIndex?.get(key);
|
|
754
|
+
if (d) return { provider: name, ticker: d.ticker };
|
|
755
|
+
}
|
|
756
|
+
return null;
|
|
757
|
+
}
|
|
744
758
|
const norm = normTicker(ticker);
|
|
745
759
|
for (const name of this.candidateOrder(opts.default)) {
|
|
746
760
|
if (this.entries.get(name).index?.has(norm)) return { provider: name, ticker };
|
|
@@ -806,6 +820,22 @@ var ProviderRegistry = class {
|
|
|
806
820
|
}
|
|
807
821
|
return names;
|
|
808
822
|
}
|
|
823
|
+
/**
|
|
824
|
+
* The DISPLAY prefix for a resolved symbol — the descriptor's LISTING prefix when the
|
|
825
|
+
* data declares one, else the provider name. This is the single seam every label
|
|
826
|
+
* (legend chip, committed/persisted `PREFIX:TICKER` strings) derives from, which is
|
|
827
|
+
* what makes a non-canonical spelling impossible to display: the form always comes
|
|
828
|
+
* from the data, never from what was typed.
|
|
829
|
+
*/
|
|
830
|
+
displayPrefixOf(resolved) {
|
|
831
|
+
const d = this.entries.get(resolved.provider)?.byTicker?.get(normTicker(resolved.ticker));
|
|
832
|
+
return d?.prefix ?? resolved.provider;
|
|
833
|
+
}
|
|
834
|
+
/** The canonical `PREFIX:TICKER` string for a resolved symbol (descriptor spellings). */
|
|
835
|
+
canonicalSymbol(resolved) {
|
|
836
|
+
const d = this.entries.get(resolved.provider)?.byTicker?.get(normTicker(resolved.ticker));
|
|
837
|
+
return `${d?.prefix ?? resolved.provider}:${d?.ticker ?? resolved.ticker}`;
|
|
838
|
+
}
|
|
809
839
|
/** Indexed symbols for one provider (or all, concatenated) — for autocomplete. */
|
|
810
840
|
symbolsOf(rawName) {
|
|
811
841
|
if (rawName != null) return this.entries.get(normName(rawName))?.descriptors ?? [];
|
|
@@ -829,9 +859,9 @@ var ProviderRegistry = class {
|
|
|
829
859
|
};
|
|
830
860
|
|
|
831
861
|
// src/data/CachingDataFeed.ts
|
|
832
|
-
function cacheKey(symbol, timeframe) {
|
|
862
|
+
function cacheKey(symbol, timeframe, session) {
|
|
833
863
|
const { provider, ticker } = parseSymbol(symbol);
|
|
834
|
-
return seriesKey(provider ?? "", ticker, timeframe);
|
|
864
|
+
return seriesKey(provider ?? "", ticker, timeframe, session);
|
|
835
865
|
}
|
|
836
866
|
var PAGE_BARS = 1e4;
|
|
837
867
|
var SINGLE_FETCH_BARS = PAGE_BARS + 1;
|
|
@@ -843,7 +873,7 @@ var CachingDataFeed = class {
|
|
|
843
873
|
async load(cfg) {
|
|
844
874
|
if (cfg.data && cfg.data.length > 0) return this.inner.load(cfg);
|
|
845
875
|
const symbol = cfg.symbol ?? "TEST";
|
|
846
|
-
const key = cacheKey(symbol, cfg.timeframe ?? "60");
|
|
876
|
+
const key = cacheKey(symbol, cfg.timeframe ?? "60", cfg.session);
|
|
847
877
|
this.store.retainSymbol(symbol);
|
|
848
878
|
const cached = this.store.get(key);
|
|
849
879
|
const n = cfg.bars ?? 500;
|
|
@@ -872,7 +902,7 @@ var CachingDataFeed = class {
|
|
|
872
902
|
*/
|
|
873
903
|
async loadRange(cfg, range) {
|
|
874
904
|
if (!this.inner.loadRange) return this.inner.load(cfg);
|
|
875
|
-
const key = cacheKey(cfg.symbol ?? "TEST", cfg.timeframe ?? "60");
|
|
905
|
+
const key = cacheKey(cfg.symbol ?? "TEST", cfg.timeframe ?? "60", cfg.session);
|
|
876
906
|
let cached = this.store.get(key);
|
|
877
907
|
let newest = cached?.[cached.length - 1];
|
|
878
908
|
if (range.to != null && newest && range.to < newest.time) {
|
|
@@ -1030,6 +1060,20 @@ var MultiProviderFeed = class {
|
|
|
1030
1060
|
resolveSymbol(raw) {
|
|
1031
1061
|
return this.registry.resolve(raw, { default: this.primaryProvider });
|
|
1032
1062
|
}
|
|
1063
|
+
/**
|
|
1064
|
+
* The DISPLAY prefix for `raw` — the descriptor's LISTING prefix when the data
|
|
1065
|
+
* declares one (`NASDAQ` for AAPL), else the resolved provider name. Null while
|
|
1066
|
+
* nothing resolves the symbol.
|
|
1067
|
+
*/
|
|
1068
|
+
displayPrefix(raw) {
|
|
1069
|
+
const resolved = this.resolveSymbol(raw);
|
|
1070
|
+
return resolved ? this.registry.displayPrefixOf(resolved) : null;
|
|
1071
|
+
}
|
|
1072
|
+
/** The canonical `PREFIX:TICKER` form of `raw`, or null while unresolvable. */
|
|
1073
|
+
canonicalSymbol(raw) {
|
|
1074
|
+
const resolved = this.resolveSymbol(raw);
|
|
1075
|
+
return resolved ? this.registry.canonicalSymbol(resolved) : null;
|
|
1076
|
+
}
|
|
1033
1077
|
/** The registered provider INSTANCE under `name` (undefined if unknown). */
|
|
1034
1078
|
providerInstance(name) {
|
|
1035
1079
|
return this.registry.get(name);
|
|
@@ -1165,13 +1209,13 @@ var RegistryFetchFeed = class {
|
|
|
1165
1209
|
const { provider: name, ticker } = parseSymbol(cfg.symbol ?? "");
|
|
1166
1210
|
const provider = this.registry.get(name ?? "");
|
|
1167
1211
|
if (!provider) return Promise.resolve([]);
|
|
1168
|
-
return safeBars(provider, ticker, cfg.timeframe ?? "60", { limit: cfg.bars ?? 500 });
|
|
1212
|
+
return safeBars(provider, ticker, cfg.timeframe ?? "60", { limit: cfg.bars ?? 500, session: cfg.session });
|
|
1169
1213
|
}
|
|
1170
1214
|
loadRange(cfg, range) {
|
|
1171
1215
|
const { provider: name, ticker } = parseSymbol(cfg.symbol ?? "");
|
|
1172
1216
|
const provider = this.registry.get(name ?? "");
|
|
1173
1217
|
if (!provider) return Promise.resolve([]);
|
|
1174
|
-
return safeBars(provider, ticker, cfg.timeframe ?? "60", range);
|
|
1218
|
+
return safeBars(provider, ticker, cfg.timeframe ?? "60", { ...range, session: cfg.session });
|
|
1175
1219
|
}
|
|
1176
1220
|
subscribe(cfg, onBar) {
|
|
1177
1221
|
const { provider: name, ticker } = parseSymbol(cfg.symbol ?? "");
|
|
@@ -1179,13 +1223,13 @@ var RegistryFetchFeed = class {
|
|
|
1179
1223
|
if (!provider) return () => {
|
|
1180
1224
|
};
|
|
1181
1225
|
const tf = cfg.timeframe ?? "60";
|
|
1182
|
-
if (provider.subscribe) return provider.subscribe(ticker, tf, onBar);
|
|
1226
|
+
if (provider.subscribe) return provider.subscribe(ticker, tf, onBar, cfg.session ? { session: cfg.session } : void 0);
|
|
1183
1227
|
let stopped = false;
|
|
1184
1228
|
let timer = null;
|
|
1185
1229
|
const poll = async () => {
|
|
1186
1230
|
if (stopped) return;
|
|
1187
1231
|
try {
|
|
1188
|
-
const bars = await provider.getBars(ticker, tf, { limit: 2 });
|
|
1232
|
+
const bars = await provider.getBars(ticker, tf, { limit: 2, session: cfg.session });
|
|
1189
1233
|
if (stopped) return;
|
|
1190
1234
|
for (const b of bars) onBar(b);
|
|
1191
1235
|
} catch {
|
|
@@ -1235,6 +1279,17 @@ var DataControl = class {
|
|
|
1235
1279
|
resolve(symbol) {
|
|
1236
1280
|
return this.registry?.resolveSymbol(symbol) ?? null;
|
|
1237
1281
|
}
|
|
1282
|
+
/**
|
|
1283
|
+
* The DISPLAY prefix for `symbol` — the listing venue its descriptor declares
|
|
1284
|
+
* (`NASDAQ` for AAPL) or the resolved provider name. Null while unresolvable.
|
|
1285
|
+
*/
|
|
1286
|
+
displayPrefix(symbol) {
|
|
1287
|
+
return this.registry?.displayPrefix(symbol) ?? null;
|
|
1288
|
+
}
|
|
1289
|
+
/** The canonical `PREFIX:TICKER` form of `symbol`, or null while unresolvable. */
|
|
1290
|
+
canonicalSymbol(symbol) {
|
|
1291
|
+
return this.registry?.canonicalSymbol(symbol) ?? null;
|
|
1292
|
+
}
|
|
1238
1293
|
/**
|
|
1239
1294
|
* The registered provider INSTANCE under `name` — the seam for EXTENDED provider
|
|
1240
1295
|
* surfaces: a provider may implement interfaces beyond the `DataProvider` port
|
|
@@ -18903,7 +18958,7 @@ var EngineOrchestrator = class _EngineOrchestrator {
|
|
|
18903
18958
|
* an in-flight `setMarket` immediately (the config mutates before the load). */
|
|
18904
18959
|
marketSnapshot() {
|
|
18905
18960
|
const m = this.config.market;
|
|
18906
|
-
return { symbol: m.symbol, provider: parseSymbol(m.symbol ?? "").provider ?? void 0, timeframe: m.timeframe, bars: m.bars, offline: m.data !== void 0 };
|
|
18961
|
+
return { symbol: m.symbol, provider: parseSymbol(m.symbol ?? "").provider ?? void 0, timeframe: m.timeframe, bars: m.bars, session: m.session, offline: m.data !== void 0 };
|
|
18907
18962
|
}
|
|
18908
18963
|
/**
|
|
18909
18964
|
* Switch the chart's market IN PLACE — no destroy/recreate. The renderer stays
|
|
@@ -18922,7 +18977,9 @@ var EngineOrchestrator = class _EngineOrchestrator {
|
|
|
18922
18977
|
*/
|
|
18923
18978
|
async setMarket(next) {
|
|
18924
18979
|
const m = this.config.market;
|
|
18925
|
-
const identityChanged = next.symbol !== void 0 && next.symbol !== m.symbol || next.timeframe !== void 0 && next.timeframe !== m.timeframe ||
|
|
18980
|
+
const identityChanged = next.symbol !== void 0 && next.symbol !== m.symbol || next.timeframe !== void 0 && next.timeframe !== m.timeframe || // A session switch changes WHICH bars exist (RTH vs ETH) — a full reload,
|
|
18981
|
+
// exactly like a timeframe change; the cache keys the sessions apart.
|
|
18982
|
+
next.session !== void 0 && next.session !== m.session || next.data !== void 0;
|
|
18926
18983
|
const depthChanged = next.bars !== void 0 && next.bars !== m.bars;
|
|
18927
18984
|
const depthOnly = depthChanged && !identityChanged && this.rawBars.length > 0 && !m.data?.length && ((next.bars ?? 0) <= this.rawBars.length || typeof this.feed.loadRange === "function");
|
|
18928
18985
|
if (!identityChanged && !depthChanged) {
|
|
@@ -18944,6 +19001,7 @@ var EngineOrchestrator = class _EngineOrchestrator {
|
|
|
18944
19001
|
if (next.symbol !== void 0) m.symbol = next.symbol;
|
|
18945
19002
|
if (next.timeframe !== void 0) m.timeframe = next.timeframe;
|
|
18946
19003
|
if (next.bars !== void 0) m.bars = next.bars;
|
|
19004
|
+
if (next.session !== void 0) m.session = next.session;
|
|
18947
19005
|
if (next.data !== void 0) m.data = next.data;
|
|
18948
19006
|
else if (next.symbol !== void 0) delete m.data;
|
|
18949
19007
|
m.visibleRange = next.visibleRange;
|
|
@@ -20314,6 +20372,7 @@ var Vela = class {
|
|
|
20314
20372
|
symbol: options.symbol,
|
|
20315
20373
|
timeframe: options.timeframe,
|
|
20316
20374
|
bars: options.bars,
|
|
20375
|
+
session: options.session,
|
|
20317
20376
|
visibleRange: options.visibleRange,
|
|
20318
20377
|
data: options.data
|
|
20319
20378
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, TIMEZONES, normalizeTimezone, tzMenuLabel } from './chunk-
|
|
1
|
+
import { parseSymbol, priceStyleIds, BUILTIN_PRICE_STYLES, tzButtonLabel, TIMEZONES, normalizeTimezone, tzMenuLabel } from './chunk-4MQEG67Z.js';
|
|
2
2
|
import { chartType, widgetActions, SidePanel, sidePanels, DEFAULT_PANEL_ORDER, getDrawingType } from './chunk-ZNL2X6U2.js';
|
|
3
3
|
import { Tooltip, Menu, Dialog, Drawer } from './chunk-QWIEKZRE.js';
|
|
4
4
|
import { iconMarkup, registerIcon, injectStyles, iconEl, SESSION_PRE, SESSION_POST, SESSION_OFF, icon, categoricalColor } from './chunk-EMS6PO2T.js';
|
|
@@ -1468,10 +1468,12 @@ var CSS5 = `
|
|
|
1468
1468
|
color: var(--vela-fg-muted);
|
|
1469
1469
|
font-size: 11px;
|
|
1470
1470
|
font-weight: 600;
|
|
1471
|
-
cursor:
|
|
1472
|
-
opacity: 0.55;
|
|
1471
|
+
cursor: pointer;
|
|
1473
1472
|
}
|
|
1474
|
-
.vela-bb-session-btn
|
|
1473
|
+
.vela-bb-session-btn:disabled { cursor: not-allowed; opacity: 0.55; }
|
|
1474
|
+
.vela-bb-session-btn:not(:disabled):hover { background: var(--vela-hover); color: var(--vela-fg-bright); }
|
|
1475
|
+
.vela-bb-session-btn.is-active { color: var(--vela-fg); background: var(--vela-surface-elev); }
|
|
1476
|
+
.vela-bb-session-btn.is-active:disabled { opacity: 0.8; }
|
|
1475
1477
|
.vela-bb-settings {
|
|
1476
1478
|
all: unset;
|
|
1477
1479
|
display: inline-flex;
|
|
@@ -1491,6 +1493,8 @@ var Bottombar = class {
|
|
|
1491
1493
|
constructor(host, opts) {
|
|
1492
1494
|
this.settingsTip = null;
|
|
1493
1495
|
this.rangeButtons = /* @__PURE__ */ new Map();
|
|
1496
|
+
this.sessionButtons = /* @__PURE__ */ new Map();
|
|
1497
|
+
this.sessionEl = null;
|
|
1494
1498
|
this.timer = null;
|
|
1495
1499
|
this.timezone = opts.timezone;
|
|
1496
1500
|
const doc = host.ownerDocument;
|
|
@@ -1520,12 +1524,19 @@ var Bottombar = class {
|
|
|
1520
1524
|
this.tzButton.append(this.clockEl, this.tzLabelEl);
|
|
1521
1525
|
const session = doc.createElement("span");
|
|
1522
1526
|
session.className = "vela-bb-session";
|
|
1527
|
+
this.sessionEl = session;
|
|
1523
1528
|
session.title = "Session \u2014 stocks & ETFs only";
|
|
1524
|
-
for (const [
|
|
1529
|
+
for (const [key, label] of [["regular", "RTH"], ["extended", "ETH"]]) {
|
|
1525
1530
|
const b = doc.createElement("button");
|
|
1526
|
-
b.className = "vela-bb-session-btn" + (
|
|
1531
|
+
b.className = "vela-bb-session-btn" + (key === "regular" ? " is-active" : "");
|
|
1527
1532
|
b.textContent = label;
|
|
1528
1533
|
b.disabled = true;
|
|
1534
|
+
b.addEventListener("click", () => {
|
|
1535
|
+
if (b.disabled) return;
|
|
1536
|
+
this.setSession({ session: key, enabled: true });
|
|
1537
|
+
opts.onSession?.(key);
|
|
1538
|
+
});
|
|
1539
|
+
this.sessionButtons.set(key, b);
|
|
1529
1540
|
session.appendChild(b);
|
|
1530
1541
|
}
|
|
1531
1542
|
const settingsBtn = doc.createElement("button");
|
|
@@ -1563,6 +1574,19 @@ var Bottombar = class {
|
|
|
1563
1574
|
else delete b.dataset.active;
|
|
1564
1575
|
}
|
|
1565
1576
|
}
|
|
1577
|
+
/**
|
|
1578
|
+
* Reflect the ACTIVE chart's session posture. `enabled: false` (a continuous
|
|
1579
|
+
* market, or metadata not landed yet) shows the disabled RTH-active stub — the
|
|
1580
|
+
* pre-session-model look, byte-for-byte. Enabled, the chips become clickable and
|
|
1581
|
+
* the active one tracks the chart's current session.
|
|
1582
|
+
*/
|
|
1583
|
+
setSession(state) {
|
|
1584
|
+
if (this.sessionEl) this.sessionEl.title = state.enabled ? "Session \u2014 regular (RTH) vs extended (ETH) hours" : "Session \u2014 stocks & ETFs only";
|
|
1585
|
+
for (const [key, b] of this.sessionButtons) {
|
|
1586
|
+
b.disabled = !state.enabled;
|
|
1587
|
+
b.classList.toggle("is-active", state.enabled ? key === state.session : key === "regular");
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1566
1590
|
destroy() {
|
|
1567
1591
|
if (this.timer !== null) clearInterval(this.timer);
|
|
1568
1592
|
this.tzMenu.destroy();
|
|
@@ -1605,10 +1629,11 @@ function parseQuery(raw, venues) {
|
|
|
1605
1629
|
function onlyOne(matches) {
|
|
1606
1630
|
return matches.length === 1 ? matches[0] : null;
|
|
1607
1631
|
}
|
|
1632
|
+
var venueOf = (s) => s.prefix ?? s.provider;
|
|
1608
1633
|
function filterSymbols(list, query, limit = 100) {
|
|
1609
|
-
const venues = [...new Set(list.
|
|
1634
|
+
const venues = [...new Set(list.flatMap((s) => [venueOf(s)?.toLowerCase(), s.provider?.toLowerCase()]).filter((p) => !!p))];
|
|
1610
1635
|
const { scope, term } = parseQuery(query, venues);
|
|
1611
|
-
const pool = scope ? list.filter((s) => s.provider?.toLowerCase() === scope) : list;
|
|
1636
|
+
const pool = scope ? list.filter((s) => venueOf(s)?.toLowerCase() === scope || s.provider?.toLowerCase() === scope) : list;
|
|
1612
1637
|
const q = term.toUpperCase();
|
|
1613
1638
|
if (!q) {
|
|
1614
1639
|
if (scope) return [...pool].sort((a, b) => a.ticker.localeCompare(b.ticker)).slice(0, limit);
|
|
@@ -1627,7 +1652,7 @@ function filterSymbols(list, query, limit = 100) {
|
|
|
1627
1652
|
if (t.startsWith(q)) prefix.push(s);
|
|
1628
1653
|
else if (t.includes(q)) substr.push(s);
|
|
1629
1654
|
else if ((s.description ?? "").toUpperCase().includes(q)) desc.push(s);
|
|
1630
|
-
else if (!scope && s.provider?.toLowerCase().includes(qLower)) venue.push(s);
|
|
1655
|
+
else if (!scope && (venueOf(s)?.toLowerCase().includes(qLower) || s.provider?.toLowerCase().includes(qLower))) venue.push(s);
|
|
1631
1656
|
if (prefix.length >= limit) break;
|
|
1632
1657
|
}
|
|
1633
1658
|
return [...prefix, ...substr, ...desc, ...venue].slice(0, limit);
|
|
@@ -1779,14 +1804,14 @@ var SymbolPicker = class {
|
|
|
1779
1804
|
else if (e.key === "ArrowUp") this.moveHighlight(-1);
|
|
1780
1805
|
else if (e.key === "Enter") {
|
|
1781
1806
|
const pick = this.rows[this.highlighted];
|
|
1782
|
-
if (pick) this.select(pick.ticker, pick.provider, opts.onSelect);
|
|
1807
|
+
if (pick) this.select(pick.ticker, pick.prefix ?? pick.provider, opts.onSelect);
|
|
1783
1808
|
return;
|
|
1784
1809
|
} else return;
|
|
1785
1810
|
e.preventDefault();
|
|
1786
1811
|
});
|
|
1787
1812
|
this.list.addEventListener("click", (e) => {
|
|
1788
1813
|
const row = e.target.closest(".vela-sp-row");
|
|
1789
|
-
if (row?.dataset.ticker) this.select(row.dataset.ticker, row.dataset.
|
|
1814
|
+
if (row?.dataset.ticker) this.select(row.dataset.ticker, row.dataset.venue, opts.onSelect);
|
|
1790
1815
|
});
|
|
1791
1816
|
}
|
|
1792
1817
|
/** Wire where symbols come from (re-called on every widget rebuild). */
|
|
@@ -1803,9 +1828,9 @@ var SymbolPicker = class {
|
|
|
1803
1828
|
destroy() {
|
|
1804
1829
|
this.dialog.destroy();
|
|
1805
1830
|
}
|
|
1806
|
-
select(ticker,
|
|
1831
|
+
select(ticker, venue, onSelect) {
|
|
1807
1832
|
this.close();
|
|
1808
|
-
onSelect(
|
|
1833
|
+
onSelect(venue ? `${venue}:${ticker}` : ticker);
|
|
1809
1834
|
}
|
|
1810
1835
|
moveHighlight(delta) {
|
|
1811
1836
|
if (!this.rows.length) return;
|
|
@@ -1838,7 +1863,8 @@ var SymbolPicker = class {
|
|
|
1838
1863
|
const row = doc.createElement("div");
|
|
1839
1864
|
row.className = "vela-sp-row";
|
|
1840
1865
|
row.dataset.ticker = s.ticker;
|
|
1841
|
-
|
|
1866
|
+
const venue = s.prefix ?? s.provider;
|
|
1867
|
+
if (venue) row.dataset.venue = venue;
|
|
1842
1868
|
const av = tickerIconEl(doc, baseOf(s), s.ticker, "vela-sp-avatar");
|
|
1843
1869
|
const main = doc.createElement("span");
|
|
1844
1870
|
main.className = "vela-sp-main";
|
|
@@ -1850,11 +1876,11 @@ var SymbolPicker = class {
|
|
|
1850
1876
|
d.textContent = s.description ?? (s.type ?? "");
|
|
1851
1877
|
main.append(t, d);
|
|
1852
1878
|
row.append(av, main);
|
|
1853
|
-
if (
|
|
1879
|
+
if (venue) {
|
|
1854
1880
|
const badge = doc.createElement("span");
|
|
1855
1881
|
badge.className = "vela-sp-badge";
|
|
1856
|
-
badge.dataset.p = s.provider;
|
|
1857
|
-
badge.textContent =
|
|
1882
|
+
badge.dataset.p = s.provider ?? venue;
|
|
1883
|
+
badge.textContent = venue;
|
|
1858
1884
|
row.appendChild(badge);
|
|
1859
1885
|
}
|
|
1860
1886
|
this.list.appendChild(row);
|
|
@@ -4264,6 +4290,7 @@ function sanitizeCell(raw) {
|
|
|
4264
4290
|
if (typeof c.timeframe === "string") out.timeframe = c.timeframe;
|
|
4265
4291
|
if (typeof c.priceStyle === "string") out.priceStyle = c.priceStyle;
|
|
4266
4292
|
if (typeof c.bars === "number" && Number.isFinite(c.bars) && c.bars > 0) out.bars = c.bars;
|
|
4293
|
+
if (c.session === "regular" || c.session === "extended") out.session = c.session;
|
|
4267
4294
|
if (typeof c.watermark === "boolean") out.watermark = c.watermark;
|
|
4268
4295
|
if (typeof c.indicatorTitles === "boolean") out.indicatorTitles = c.indicatorTitles;
|
|
4269
4296
|
if (typeof c.indicatorValues === "boolean") out.indicatorValues = c.indicatorValues;
|
|
@@ -4373,6 +4400,9 @@ function indicatorLedger(i) {
|
|
|
4373
4400
|
};
|
|
4374
4401
|
}
|
|
4375
4402
|
|
|
4403
|
+
// src/core/options.ts
|
|
4404
|
+
var normalizeSession = (v) => v === "regular" || v === "extended" ? v : void 0;
|
|
4405
|
+
|
|
4376
4406
|
// src/widget/layout-mode.ts
|
|
4377
4407
|
var MOBILE_BREAKPOINT_PX = 640;
|
|
4378
4408
|
var COARSE_BREAKPOINT_PX = 920;
|
|
@@ -5739,4 +5769,4 @@ var Toast = class {
|
|
|
5739
5769
|
}
|
|
5740
5770
|
};
|
|
5741
5771
|
|
|
5742
|
-
export { Bottombar, ChartContextMenu, DataWindow, DrawingPill, DrawingsDrawer, Glider, IndicatorPicker, LayoutModeController, MobileBar, MoreDrawer, ObjectTree, PAN_FAST, PanelDock, PriceScaleDrawer, RANGE_PRESETS, ShortcutsHelp, Statusline, SymbolPicker, TimeframeDrawer, TimeframeQuick, TimezoneDrawer, Toast, Topbar, Watermark, WidgetHistory, ZOOM_IN, ZOOM_OUT, dataWindowSections, decimalsFor, decodeState, encodeState, filterSymbols, fmtChange, fmtPrice, indicatorLedger, legacyWidgetState, loadPersisted, localStorageAdapter, parsePersisted, parseTimeframe, prefixedSymbol, priceStyleIcon, priceStyleLabel, resolveIndicators, sanitizeState, savePersisted, statuslineInkOf, timeframeLabel, timeframeMs, toolShortcutHints };
|
|
5772
|
+
export { Bottombar, ChartContextMenu, DataWindow, DrawingPill, DrawingsDrawer, Glider, IndicatorPicker, LayoutModeController, MobileBar, MoreDrawer, ObjectTree, PAN_FAST, PanelDock, PriceScaleDrawer, RANGE_PRESETS, ShortcutsHelp, Statusline, SymbolPicker, TimeframeDrawer, TimeframeQuick, TimezoneDrawer, Toast, Topbar, Watermark, WidgetHistory, ZOOM_IN, ZOOM_OUT, dataWindowSections, decimalsFor, decodeState, encodeState, filterSymbols, fmtChange, fmtPrice, indicatorLedger, legacyWidgetState, loadPersisted, localStorageAdapter, normalizeSession, parsePersisted, parseTimeframe, prefixedSymbol, priceStyleIcon, priceStyleLabel, resolveIndicators, sanitizeState, savePersisted, statuslineInkOf, timeframeLabel, timeframeMs, toolShortcutHints };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-
|
|
1
|
+
import { t as Millis, ad as InputSchema, ac as IndicatorMeta, P as PriceStyle, O as OHLCV, m as InputValue, k as IndicatorModel, j as MoveTarget, az as SeriesSpec, aa as Fill, B as Background, ar as PriceLine, a0 as DrawingLine, Y as DrawingBox, $ as DrawingLabel, a4 as DrawingPolyline, a1 as DrawingLinefill, a6 as DrawingTable, g as IndicatorStatus, a as VisibleRange, c as VelaTheme, S as SerializedDrawing, v as DrawingTypeKey, u as SnapMode, a2 as DrawingMode, I as IChartRenderer, R as RendererCapabilities, o as LegendActionView, U as Unsubscribe, C as CrosshairEvent, A as AxisLongPressEvent, r as DataWindowReadout, n as SymbolPickerFn, aL as PaneInfo, a9 as DrawingsOption, D as Drawing, b as VelaOptions, x as AddIndicatorOptions, an as MarketSwitch, am as MarketSnapshot, V as VisibleRangePreset, T as ThemeName } from './options-BqGeFHtp.cjs';
|
|
2
|
+
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-BNKtYU5V.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A strategy's broker state at ONE bar — the flat summary a host reads while a script
|
|
@@ -344,6 +344,13 @@ declare class DataControl {
|
|
|
344
344
|
providers(): ProviderInfo[];
|
|
345
345
|
/** Resolve a symbol string to `{ provider, ticker }`, or null if nothing serves it. */
|
|
346
346
|
resolve(symbol: string): Resolved | null;
|
|
347
|
+
/**
|
|
348
|
+
* The DISPLAY prefix for `symbol` — the listing venue its descriptor declares
|
|
349
|
+
* (`NASDAQ` for AAPL) or the resolved provider name. Null while unresolvable.
|
|
350
|
+
*/
|
|
351
|
+
displayPrefix(symbol: string): string | null;
|
|
352
|
+
/** The canonical `PREFIX:TICKER` form of `symbol`, or null while unresolvable. */
|
|
353
|
+
canonicalSymbol(symbol: string): string | null;
|
|
347
354
|
/**
|
|
348
355
|
* The registered provider INSTANCE under `name` — the seam for EXTENDED provider
|
|
349
356
|
* surfaces: a provider may implement interfaces beyond the `DataProvider` port
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-
|
|
1
|
+
import { t as Millis, ad as InputSchema, ac as IndicatorMeta, P as PriceStyle, O as OHLCV, m as InputValue, k as IndicatorModel, j as MoveTarget, az as SeriesSpec, aa as Fill, B as Background, ar as PriceLine, a0 as DrawingLine, Y as DrawingBox, $ as DrawingLabel, a4 as DrawingPolyline, a1 as DrawingLinefill, a6 as DrawingTable, g as IndicatorStatus, a as VisibleRange, c as VelaTheme, S as SerializedDrawing, v as DrawingTypeKey, u as SnapMode, a2 as DrawingMode, I as IChartRenderer, R as RendererCapabilities, o as LegendActionView, U as Unsubscribe, C as CrosshairEvent, A as AxisLongPressEvent, r as DataWindowReadout, n as SymbolPickerFn, aL as PaneInfo, a9 as DrawingsOption, D as Drawing, b as VelaOptions, x as AddIndicatorOptions, an as MarketSwitch, am as MarketSnapshot, V as VisibleRangePreset, T as ThemeName } from './options-BqGeFHtp.js';
|
|
2
|
+
import { S as SymbolInfo, B as BarRange, M as MarketDataFeed, D as DataProvider, P as ProviderInfo, a as SymbolDescriptor, b as ProviderCapabilities } from './DataProvider-gJjN_0eh.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* A strategy's broker state at ONE bar — the flat summary a host reads while a script
|
|
@@ -344,6 +344,13 @@ declare class DataControl {
|
|
|
344
344
|
providers(): ProviderInfo[];
|
|
345
345
|
/** Resolve a symbol string to `{ provider, ticker }`, or null if nothing serves it. */
|
|
346
346
|
resolve(symbol: string): Resolved | null;
|
|
347
|
+
/**
|
|
348
|
+
* The DISPLAY prefix for `symbol` — the listing venue its descriptor declares
|
|
349
|
+
* (`NASDAQ` for AAPL) or the resolved provider name. Null while unresolvable.
|
|
350
|
+
*/
|
|
351
|
+
displayPrefix(symbol: string): string | null;
|
|
352
|
+
/** The canonical `PREFIX:TICKER` form of `symbol`, or null while unresolvable. */
|
|
353
|
+
canonicalSymbol(symbol: string): string | null;
|
|
347
354
|
/**
|
|
348
355
|
* The registered provider INSTANCE under `name` — the seam for EXTENDED provider
|
|
349
356
|
* surfaces: a provider may implement interfaces beyond the `DataProvider` port
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { V as VisibleRangePreset } from './options-
|
|
2
|
-
import { D as DataProvider } from './DataProvider-
|
|
3
|
-
import { S as ScriptingEngine, V as Vela } from './contributions-
|
|
1
|
+
import { V as VisibleRangePreset } from './options-BqGeFHtp.js';
|
|
2
|
+
import { D as DataProvider } from './DataProvider-gJjN_0eh.js';
|
|
3
|
+
import { S as ScriptingEngine, V as Vela } from './contributions-lPAgo9Cu.js';
|
|
4
4
|
|
|
5
5
|
interface RangePreset {
|
|
6
6
|
/** Button label. */
|
|
@@ -27,6 +27,8 @@ interface BottombarOptions {
|
|
|
27
27
|
timezone: string;
|
|
28
28
|
onRange: (preset: RangePreset) => void;
|
|
29
29
|
onTimezone: (zone: string) => void;
|
|
30
|
+
/** RTH/ETH toggled by the user. Fires only while the toggle is ENABLED (see {@link Bottombar.setSession}). */
|
|
31
|
+
onSession?: (session: 'regular' | 'extended') => void;
|
|
30
32
|
onSettingsClick?: () => void;
|
|
31
33
|
}
|
|
32
34
|
declare class Bottombar {
|
|
@@ -37,12 +39,24 @@ declare class Bottombar {
|
|
|
37
39
|
private readonly tzMenu;
|
|
38
40
|
private readonly settingsTip;
|
|
39
41
|
private readonly rangeButtons;
|
|
42
|
+
private readonly sessionButtons;
|
|
43
|
+
private sessionEl;
|
|
40
44
|
private timezone;
|
|
41
45
|
private timer;
|
|
42
46
|
constructor(host: HTMLElement, opts: BottombarOptions);
|
|
43
47
|
setTimezone(zone: string): void;
|
|
44
48
|
/** Highlight (or clear with null) the active range chip — cleared on manual tf changes. */
|
|
45
49
|
setActiveRange(id: string | null): void;
|
|
50
|
+
/**
|
|
51
|
+
* Reflect the ACTIVE chart's session posture. `enabled: false` (a continuous
|
|
52
|
+
* market, or metadata not landed yet) shows the disabled RTH-active stub — the
|
|
53
|
+
* pre-session-model look, byte-for-byte. Enabled, the chips become clickable and
|
|
54
|
+
* the active one tracks the chart's current session.
|
|
55
|
+
*/
|
|
56
|
+
setSession(state: {
|
|
57
|
+
session: 'regular' | 'extended';
|
|
58
|
+
enabled: boolean;
|
|
59
|
+
}): void;
|
|
46
60
|
destroy(): void;
|
|
47
61
|
private tzItems;
|
|
48
62
|
private tick;
|
|
@@ -130,6 +144,8 @@ interface CellState {
|
|
|
130
144
|
timeframe?: string;
|
|
131
145
|
priceStyle?: string;
|
|
132
146
|
bars?: number;
|
|
147
|
+
/** Trading session shown (`'extended'` persisted; absent = regular, the default). */
|
|
148
|
+
session?: string;
|
|
133
149
|
/** Symbol watermark visibility — a per-chart display pref. */
|
|
134
150
|
watermark?: boolean;
|
|
135
151
|
/** Indicator titles (the in-chart legend rows) visibility — a per-chart display pref. */
|
|
@@ -212,6 +228,8 @@ interface PersistedState {
|
|
|
212
228
|
priceStyle?: string;
|
|
213
229
|
timezone?: string;
|
|
214
230
|
bars?: string;
|
|
231
|
+
/** Trading session (`regular` | `extended`) — URL param `session`. */
|
|
232
|
+
session?: string;
|
|
215
233
|
watermark?: string;
|
|
216
234
|
/** Comma-joined favorite drawing-tool types. */
|
|
217
235
|
favorites?: string;
|