wickchart 0.3.0
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 +404 -0
- package/package.json +57 -0
- package/src/core.js +1055 -0
- package/src/feeds.js +192 -0
- package/src/hab-chart.js +2621 -0
- package/src/hab-feed.js +255 -0
- package/types/core.d.ts +572 -0
- package/types/feeds.d.ts +58 -0
- package/types/hab-chart.d.ts +377 -0
- package/types/hab-feed.d.ts +27 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
declare const HTMLElementBase: {
|
|
2
|
+
new (): {};
|
|
3
|
+
};
|
|
4
|
+
declare class HabChart extends HTMLElementBase {
|
|
5
|
+
_canvas: any;
|
|
6
|
+
_ctx: any;
|
|
7
|
+
_legend: any;
|
|
8
|
+
_hud: any;
|
|
9
|
+
_poss: any;
|
|
10
|
+
_statsRow: any;
|
|
11
|
+
_nodata: any;
|
|
12
|
+
_data: any[];
|
|
13
|
+
_version: number;
|
|
14
|
+
_view: {
|
|
15
|
+
rightIndex: number;
|
|
16
|
+
spacing: number;
|
|
17
|
+
};
|
|
18
|
+
_auto: boolean;
|
|
19
|
+
_needsFit: boolean;
|
|
20
|
+
_hover: {
|
|
21
|
+
index: any;
|
|
22
|
+
x: number;
|
|
23
|
+
y: number;
|
|
24
|
+
} | {
|
|
25
|
+
index: number;
|
|
26
|
+
x: number;
|
|
27
|
+
y: number;
|
|
28
|
+
};
|
|
29
|
+
_dt: number;
|
|
30
|
+
_ly: {
|
|
31
|
+
W: any;
|
|
32
|
+
H: any;
|
|
33
|
+
priceW: number;
|
|
34
|
+
timeH: number;
|
|
35
|
+
plotRight: number;
|
|
36
|
+
plotBottom: number;
|
|
37
|
+
main: {
|
|
38
|
+
y0: number;
|
|
39
|
+
y1: number;
|
|
40
|
+
h: number;
|
|
41
|
+
};
|
|
42
|
+
panes: {
|
|
43
|
+
entry: any;
|
|
44
|
+
y0: number;
|
|
45
|
+
y1: number;
|
|
46
|
+
h: number;
|
|
47
|
+
}[];
|
|
48
|
+
};
|
|
49
|
+
_cache: {
|
|
50
|
+
v: number;
|
|
51
|
+
map: {};
|
|
52
|
+
};
|
|
53
|
+
_pal: {
|
|
54
|
+
overlay: any;
|
|
55
|
+
volAlpha: number;
|
|
56
|
+
};
|
|
57
|
+
_palKey: string;
|
|
58
|
+
_legendKey: string;
|
|
59
|
+
_raf: number;
|
|
60
|
+
_connected: boolean;
|
|
61
|
+
_theme: string;
|
|
62
|
+
_type: string;
|
|
63
|
+
_log: boolean;
|
|
64
|
+
_precision: any;
|
|
65
|
+
_label: string;
|
|
66
|
+
_stats: boolean;
|
|
67
|
+
_statsKey: string;
|
|
68
|
+
_profile: boolean;
|
|
69
|
+
_profileKey: string;
|
|
70
|
+
_profileRes: {
|
|
71
|
+
rows: Array<{
|
|
72
|
+
v: number;
|
|
73
|
+
up: number;
|
|
74
|
+
dn: number;
|
|
75
|
+
}>;
|
|
76
|
+
maxV: number;
|
|
77
|
+
total: number;
|
|
78
|
+
rowH: number;
|
|
79
|
+
priceMin: number;
|
|
80
|
+
priceMax: number;
|
|
81
|
+
pocIndex: number;
|
|
82
|
+
valIndex: number;
|
|
83
|
+
vahIndex: number;
|
|
84
|
+
poc: number;
|
|
85
|
+
val: number;
|
|
86
|
+
vah: number;
|
|
87
|
+
};
|
|
88
|
+
_annotations: boolean;
|
|
89
|
+
_annoKey: string;
|
|
90
|
+
_annoList: {
|
|
91
|
+
type: string;
|
|
92
|
+
side: 'high' | 'low';
|
|
93
|
+
i: number;
|
|
94
|
+
note: string;
|
|
95
|
+
}[];
|
|
96
|
+
_coviewName: any;
|
|
97
|
+
_coviewCh: BroadcastChannel;
|
|
98
|
+
_coviewPeer: string;
|
|
99
|
+
_coviewLast: number;
|
|
100
|
+
_ghost: {
|
|
101
|
+
index: number;
|
|
102
|
+
yFrac: any;
|
|
103
|
+
at: number;
|
|
104
|
+
};
|
|
105
|
+
_ghostTimer: number;
|
|
106
|
+
_sonify: boolean;
|
|
107
|
+
_actx: any;
|
|
108
|
+
_lastToneIdx: number;
|
|
109
|
+
_playToken: number;
|
|
110
|
+
_measure: {
|
|
111
|
+
iA: any;
|
|
112
|
+
pA: number;
|
|
113
|
+
iB: any;
|
|
114
|
+
pB: number;
|
|
115
|
+
done: boolean;
|
|
116
|
+
};
|
|
117
|
+
_measuring: boolean;
|
|
118
|
+
_ind: {
|
|
119
|
+
overlays: any[];
|
|
120
|
+
panes: any[];
|
|
121
|
+
volume: boolean;
|
|
122
|
+
};
|
|
123
|
+
_pointers: Map<any, any>;
|
|
124
|
+
_pan: {
|
|
125
|
+
x: number;
|
|
126
|
+
rightIndex: number;
|
|
127
|
+
moved: boolean;
|
|
128
|
+
};
|
|
129
|
+
_pinch: {
|
|
130
|
+
dist: number;
|
|
131
|
+
spacing: number;
|
|
132
|
+
idxAtMid: number;
|
|
133
|
+
midX: number;
|
|
134
|
+
};
|
|
135
|
+
_loadingMore: boolean;
|
|
136
|
+
_noMore: boolean;
|
|
137
|
+
_positions: any[];
|
|
138
|
+
_alerts: any[];
|
|
139
|
+
_seq: number;
|
|
140
|
+
_onResize: () => void;
|
|
141
|
+
_onPointerDown: (e: any) => void;
|
|
142
|
+
_onPointerMove: (e: any) => void;
|
|
143
|
+
_onPointerUp: (e: any) => void;
|
|
144
|
+
_onPointerLeave: () => void;
|
|
145
|
+
_onWheel: (e: any) => void;
|
|
146
|
+
_onDbl: () => void;
|
|
147
|
+
_onKey: (e: any) => void;
|
|
148
|
+
tabIndex: number;
|
|
149
|
+
_ro: any;
|
|
150
|
+
_posVersion: any;
|
|
151
|
+
_pendingRange: {
|
|
152
|
+
from: number;
|
|
153
|
+
to: number;
|
|
154
|
+
};
|
|
155
|
+
_W: any;
|
|
156
|
+
_H: any;
|
|
157
|
+
_dpr: any;
|
|
158
|
+
_lastScale: {
|
|
159
|
+
min: number;
|
|
160
|
+
max: number;
|
|
161
|
+
useLog: boolean;
|
|
162
|
+
rawMin: number;
|
|
163
|
+
rawHi: number;
|
|
164
|
+
};
|
|
165
|
+
static get observedAttributes(): string[];
|
|
166
|
+
constructor();
|
|
167
|
+
connectedCallback(): void;
|
|
168
|
+
disconnectedCallback(): void;
|
|
169
|
+
attributeChangedCallback(name: any, _old: any, val: any): void;
|
|
170
|
+
static _registryMap: any;
|
|
171
|
+
/** Lazily-built registry, seeded with the built-in indicators. */
|
|
172
|
+
static _registry(): any;
|
|
173
|
+
/**
|
|
174
|
+
* Register a custom indicator.
|
|
175
|
+
*
|
|
176
|
+
* HabChart.registerIndicator('vwap', {
|
|
177
|
+
* kind: 'overlay', // or 'pane'
|
|
178
|
+
* params: { period: 20 }, // defaults; settable via name:period
|
|
179
|
+
* compute(bars, params) { // bars: normalized {time,o,h,l,c,v}
|
|
180
|
+
* return smaOfCloses; // single series…
|
|
181
|
+
* // …or { lines: [{name, values}], histogram } for multi-line/panes
|
|
182
|
+
* },
|
|
183
|
+
* guides: [30, 70], // pane only: dashed guide levels
|
|
184
|
+
* range: [0, 100], // pane only: fixed scale
|
|
185
|
+
* fmt: 'price' | 'fixed1', // legend/axis number format
|
|
186
|
+
* });
|
|
187
|
+
* chart.indicators = 'vwap:20';
|
|
188
|
+
*/
|
|
189
|
+
/** @param {import('./core.js').IndicatorDef} def */
|
|
190
|
+
static registerIndicator(name: any, def: import('./core.js').IndicatorDef): void;
|
|
191
|
+
/** The custom element class (also exported implicitly for users). */
|
|
192
|
+
static get elementName(): string;
|
|
193
|
+
get data(): any[];
|
|
194
|
+
/**
|
|
195
|
+
* Replace the dataset.
|
|
196
|
+
* @param {Array<import('./core.js').Bar>} bars
|
|
197
|
+
*/
|
|
198
|
+
setData(bars: Array<import('./core.js').Bar>): void;
|
|
199
|
+
/**
|
|
200
|
+
* Stream a bar: replaces the last bar when `time` matches, appends when
|
|
201
|
+
* newer, inserts/backfills when older.
|
|
202
|
+
* @param {import('./core.js').Bar} bar
|
|
203
|
+
*/
|
|
204
|
+
update(bar: import('./core.js').Bar): void;
|
|
205
|
+
clearData(): void;
|
|
206
|
+
/**
|
|
207
|
+
* Fetch older history when the view approaches the left edge.
|
|
208
|
+
* The host app assigns `chart.onloadmore = async (fromTime) => bars`.
|
|
209
|
+
* Bars strictly older than the current first bar are prepended and the
|
|
210
|
+
* view stays anchored. Return [] / null to signal "no more data".
|
|
211
|
+
* @type {null|((fromTime: number) => Promise<Array<import('./core.js').Bar>>|Array<import('./core.js').Bar>)}
|
|
212
|
+
*/
|
|
213
|
+
onloadmore: null | ((fromTime: number) => Promise<Array<import('./core.js').Bar>> | Array<import('./core.js').Bar>);
|
|
214
|
+
_maybeLoadMore(iLeft: any): void;
|
|
215
|
+
/** Reset zoom to the default view (last ~150 bars). */
|
|
216
|
+
fit(): void;
|
|
217
|
+
/** Visible time window. @returns {{from:number,to:number}|null} */
|
|
218
|
+
/** @returns {{from: number, to: number}|null} visible time window (ms) */
|
|
219
|
+
getVisibleRange(): {
|
|
220
|
+
from: number;
|
|
221
|
+
to: number;
|
|
222
|
+
} | null;
|
|
223
|
+
/** Set visible time window ({from, to} in ms). */
|
|
224
|
+
/** @param {{from: number, to: number}} range times in ms */
|
|
225
|
+
setVisibleRange(range: {
|
|
226
|
+
from: number;
|
|
227
|
+
to: number;
|
|
228
|
+
}): void;
|
|
229
|
+
/** Current canvas as a PNG data URL. */
|
|
230
|
+
exportPNG(): any;
|
|
231
|
+
/**
|
|
232
|
+
* Serializable snapshot of the chart's configuration and view.
|
|
233
|
+
* Feed it to setState() (or encodeStateQuery for shareable URLs).
|
|
234
|
+
*/
|
|
235
|
+
/** @returns {import('./core.js').ChartState} */
|
|
236
|
+
getState(): import('./core.js').ChartState;
|
|
237
|
+
/**
|
|
238
|
+
* Apply a state snapshot (from getState()). If a view range is included
|
|
239
|
+
* and data is not loaded yet, it is applied after the next setData().
|
|
240
|
+
* @param {import('./core.js').ChartState} state
|
|
241
|
+
*/
|
|
242
|
+
setState(state: import('./core.js').ChartState): void;
|
|
243
|
+
/**
|
|
244
|
+
* Visualize a position / order.
|
|
245
|
+
* @param {{id?: string, side?: 'long'|'short', entry: number,
|
|
246
|
+
* stop?: number, target?: number, qty?: number}} pos
|
|
247
|
+
* @returns {string|null} the position id
|
|
248
|
+
*/
|
|
249
|
+
addPosition(pos: {
|
|
250
|
+
id?: string;
|
|
251
|
+
side?: 'long' | 'short';
|
|
252
|
+
entry: number;
|
|
253
|
+
stop?: number;
|
|
254
|
+
target?: number;
|
|
255
|
+
qty?: number;
|
|
256
|
+
}): string | null;
|
|
257
|
+
removePosition(id: any): void;
|
|
258
|
+
clearPositions(): void;
|
|
259
|
+
/**
|
|
260
|
+
* Price alert. Fires `hab:alert` ({id, price, bar}) on an edge crossing
|
|
261
|
+
* during streaming updates.
|
|
262
|
+
* @param {{id?: string, price: number, direction?: 'above'|'below'|'cross',
|
|
263
|
+
* once?: boolean}} alert
|
|
264
|
+
* @returns {string|null} the alert id
|
|
265
|
+
*/
|
|
266
|
+
addAlert(alert: {
|
|
267
|
+
id?: string;
|
|
268
|
+
price: number;
|
|
269
|
+
direction?: 'above' | 'below' | 'cross';
|
|
270
|
+
once?: boolean;
|
|
271
|
+
}): string | null;
|
|
272
|
+
removeAlert(id: any): void;
|
|
273
|
+
clearAlerts(): void;
|
|
274
|
+
/** Check alerts against an incoming bar (prev close → new close). */
|
|
275
|
+
_checkAlerts(prevClose: any, bar: any): void;
|
|
276
|
+
get theme(): string;
|
|
277
|
+
set theme(v: string);
|
|
278
|
+
get type(): string;
|
|
279
|
+
set type(v: string);
|
|
280
|
+
get label(): string;
|
|
281
|
+
set label(v: string);
|
|
282
|
+
get indicators(): any;
|
|
283
|
+
set indicators(v: any);
|
|
284
|
+
static _MAX_SP: number;
|
|
285
|
+
/**
|
|
286
|
+
* Lowest allowed px/bar: either 0.35, or whatever fits the entire
|
|
287
|
+
* dataset on screen — so any history can be zoomed out fully.
|
|
288
|
+
*/
|
|
289
|
+
_minSpacing(): number;
|
|
290
|
+
static _timeToMs(t: any): any;
|
|
291
|
+
static _normBar(b: any): {
|
|
292
|
+
time: any;
|
|
293
|
+
open: any;
|
|
294
|
+
high: any;
|
|
295
|
+
low: any;
|
|
296
|
+
close: any;
|
|
297
|
+
volume: any;
|
|
298
|
+
};
|
|
299
|
+
static _indexForTime(d: any, time: any): number;
|
|
300
|
+
_autoAttr(): boolean;
|
|
301
|
+
_computeDt(): void;
|
|
302
|
+
_updateAria(): void;
|
|
303
|
+
_invalidate(): void;
|
|
304
|
+
_prec(v: any): any;
|
|
305
|
+
_palette(): {
|
|
306
|
+
overlay: any;
|
|
307
|
+
volAlpha: any;
|
|
308
|
+
};
|
|
309
|
+
/**
|
|
310
|
+
* Bars used for drawing/reading OHLC: raw data, or the Heikin-Ashi
|
|
311
|
+
* transform for `type="heikin"` (cached per data version).
|
|
312
|
+
*/
|
|
313
|
+
_renderBars(): any;
|
|
314
|
+
/** RSI(14) over raw closes, cached per data version (annotation input). */
|
|
315
|
+
_cachedRSI14(): any;
|
|
316
|
+
/** Compute (and cache per data version) an indicator entry's series. */
|
|
317
|
+
_indicatorSeries(entry: any): any;
|
|
318
|
+
/** Resolve a line color: #hex / rgb() / CSS name / palette key ('rsi', 'up', …) / cycle.
|
|
319
|
+
* Untrusted values (URL/attribute-sourced) are validated — never interpolated raw. */
|
|
320
|
+
_lineColor(entry: any, line: any, pal: any, cycleIdx: any): any;
|
|
321
|
+
_ensureCanvas(): boolean;
|
|
322
|
+
_rightMargin(): number;
|
|
323
|
+
_applyFit(): void;
|
|
324
|
+
_clampView(): void;
|
|
325
|
+
_atRight(): boolean;
|
|
326
|
+
_xFor(i: any): number;
|
|
327
|
+
_indexForX(x: any): number;
|
|
328
|
+
_mainScale(i0: any, i1: any, cols: any): {
|
|
329
|
+
min: number;
|
|
330
|
+
max: number;
|
|
331
|
+
useLog: boolean;
|
|
332
|
+
rawMin: number;
|
|
333
|
+
rawHi: number;
|
|
334
|
+
};
|
|
335
|
+
_priceTicks(scale: any, height: any): any[];
|
|
336
|
+
/**
|
|
337
|
+
* Time-axis ticks. `sampleIdx` (optional, ascending indices) restricts
|
|
338
|
+
* the walk to those bars — used at deep zoom where bars are aggregated
|
|
339
|
+
* into pixel columns (keeps this O(screen) instead of O(visible bars)).
|
|
340
|
+
*/
|
|
341
|
+
_timeTicks(i0: any, i1: any, sampleIdx: any): any[];
|
|
342
|
+
_render(): void;
|
|
343
|
+
_pill(x: any, y: any, text: any, bg: any, fg: any, align: string, widthOverride: any): void;
|
|
344
|
+
_updateLegend(): void;
|
|
345
|
+
/** Position P&L chips (top-right HTML overlay). */
|
|
346
|
+
_updateHud(): void;
|
|
347
|
+
_localPoint(e: any): {
|
|
348
|
+
x: number;
|
|
349
|
+
y: number;
|
|
350
|
+
};
|
|
351
|
+
_pointerDown(e: any): void;
|
|
352
|
+
_pointerMove(e: any): void;
|
|
353
|
+
_pointerUp(e: any): void;
|
|
354
|
+
_yToPrice(y: any): number;
|
|
355
|
+
_wheel(e: any): void;
|
|
356
|
+
_keydown(e: any): void;
|
|
357
|
+
/** Lazily-created shared AudioContext (enable within a user gesture). */
|
|
358
|
+
_audio(): any;
|
|
359
|
+
/** Short sine blip; `when` schedules against AudioContext time. */
|
|
360
|
+
_tone(freq: any, dur?: number, when?: number): void;
|
|
361
|
+
/** One tone for a bar's close, pitched by its position on the y-scale. */
|
|
362
|
+
_sonifyBar(i: any): void;
|
|
363
|
+
/** One tone per crosshair bar change (dedupes y-only moves). */
|
|
364
|
+
_maybeSonify(idx: any): void;
|
|
365
|
+
/**
|
|
366
|
+
* Play the visible range as a pitch sweep (~4s), riding the crosshair —
|
|
367
|
+
* the audible equivalent of running your eye along the price line.
|
|
368
|
+
*/
|
|
369
|
+
playRange(): void;
|
|
370
|
+
_emitCrosshair(hover: any): void;
|
|
371
|
+
/** Join/leave the co-view channel named by the `co-view` attribute. */
|
|
372
|
+
_setupCoView(): void;
|
|
373
|
+
_coviewSend(msg: any): void;
|
|
374
|
+
_onCoMessage(m: any): void;
|
|
375
|
+
_emitRange(): void;
|
|
376
|
+
}
|
|
377
|
+
export default HabChart;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import './hab-chart.js';
|
|
2
|
+
declare const HTMLElementBase: {
|
|
3
|
+
new (): {};
|
|
4
|
+
};
|
|
5
|
+
declare class HabFeed extends HTMLElementBase {
|
|
6
|
+
_gen: number;
|
|
7
|
+
_closers: any[];
|
|
8
|
+
_timer: number;
|
|
9
|
+
_observer: any;
|
|
10
|
+
static get observedAttributes(): string[];
|
|
11
|
+
constructor();
|
|
12
|
+
connectedCallback(): void;
|
|
13
|
+
disconnectedCallback(): void;
|
|
14
|
+
attributeChangedCallback(name: any, oldVal: any, newVal: any): void;
|
|
15
|
+
_scheduleRestart(): void;
|
|
16
|
+
_teardown(): void;
|
|
17
|
+
_setStatus(status: any, detail: any): void;
|
|
18
|
+
/** Resolve the target chart (by `for` id, else the first <hab-chart>). */
|
|
19
|
+
_resolveChart(): Element;
|
|
20
|
+
_restart(): void;
|
|
21
|
+
_synthetic(gen: any, chart: any, key: any, tfId: any, limit: any, live: any, status?: string): void;
|
|
22
|
+
_binance(gen: any, chart: any, sym: any, tfId: any, limit: any, live: any): Promise<void>;
|
|
23
|
+
_pollBinance(gen: any, chart: any, sym: any, tfId: any): void;
|
|
24
|
+
_degrade(gen: any, chart: any, sym: any, tfId: any, limit: any, live: any, err: any): void;
|
|
25
|
+
_rest(gen: any, chart: any, url: any, limit: any, live: any): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export default HabFeed;
|