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
package/types/core.d.ts
ADDED
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
export type Bar = {
|
|
2
|
+
time: number;
|
|
3
|
+
open: number;
|
|
4
|
+
high: number;
|
|
5
|
+
low: number;
|
|
6
|
+
close: number;
|
|
7
|
+
volume?: number;
|
|
8
|
+
};
|
|
9
|
+
export type IndicatorLine = {
|
|
10
|
+
name?: string;
|
|
11
|
+
values: Array<number | null>;
|
|
12
|
+
/**
|
|
13
|
+
* #hex / rgb() / CSS name / palette key
|
|
14
|
+
*/
|
|
15
|
+
color?: string;
|
|
16
|
+
};
|
|
17
|
+
export type IndicatorDef = {
|
|
18
|
+
/**
|
|
19
|
+
* overlay on the price pane, or a stacked sub-pane
|
|
20
|
+
*/
|
|
21
|
+
kind?: 'overlay' | 'pane';
|
|
22
|
+
/**
|
|
23
|
+
* defaults; set via `name:p1/p2` tokens
|
|
24
|
+
*/
|
|
25
|
+
params?: Record<string, number>;
|
|
26
|
+
compute: (bars: Bar[], params: Record<string, number>) => (Array<number | null> | {
|
|
27
|
+
lines?: IndicatorLine[];
|
|
28
|
+
histogram?: Array<number | null>;
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* pane only: dashed horizontal levels
|
|
32
|
+
*/
|
|
33
|
+
guides?: number[];
|
|
34
|
+
/**
|
|
35
|
+
* pane only: fixed scale (else autoscale)
|
|
36
|
+
*/
|
|
37
|
+
range?: [number, number];
|
|
38
|
+
/**
|
|
39
|
+
* legend/axis number format
|
|
40
|
+
*/
|
|
41
|
+
fmt?: 'price' | 'fixed1';
|
|
42
|
+
color?: string;
|
|
43
|
+
};
|
|
44
|
+
export type Position = {
|
|
45
|
+
id: string;
|
|
46
|
+
side: 'long' | 'short';
|
|
47
|
+
entry: number;
|
|
48
|
+
stop: number | null;
|
|
49
|
+
target: number | null;
|
|
50
|
+
qty: number | null;
|
|
51
|
+
};
|
|
52
|
+
export type Alert = {
|
|
53
|
+
id: string;
|
|
54
|
+
price: number;
|
|
55
|
+
direction: 'above' | 'below' | 'cross';
|
|
56
|
+
once: boolean;
|
|
57
|
+
};
|
|
58
|
+
export type ChartState = {
|
|
59
|
+
type?: 'candles' | 'line' | 'area' | 'bars' | 'hollow' | 'heikin';
|
|
60
|
+
theme?: 'dark' | 'light';
|
|
61
|
+
log?: boolean;
|
|
62
|
+
stats?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* volume profile overlay (POC + value area)
|
|
65
|
+
*/
|
|
66
|
+
profile?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* smart annotations (spikes/gaps/pivots/divergences)
|
|
69
|
+
*/
|
|
70
|
+
annotations?: boolean;
|
|
71
|
+
label?: string;
|
|
72
|
+
indicators?: string;
|
|
73
|
+
/**
|
|
74
|
+
* visible time window (ms)
|
|
75
|
+
*/
|
|
76
|
+
view?: {
|
|
77
|
+
from: number;
|
|
78
|
+
to: number;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* partial positions to add
|
|
82
|
+
*/
|
|
83
|
+
positions?: Array<Position & {
|
|
84
|
+
id?: string;
|
|
85
|
+
stop?: number;
|
|
86
|
+
target?: number;
|
|
87
|
+
qty?: number;
|
|
88
|
+
}>;
|
|
89
|
+
/**
|
|
90
|
+
* partial alerts to add
|
|
91
|
+
*/
|
|
92
|
+
alerts?: Array<Alert & {
|
|
93
|
+
id?: string;
|
|
94
|
+
once?: boolean;
|
|
95
|
+
}>;
|
|
96
|
+
};
|
|
97
|
+
export type IndicatorEntry = {
|
|
98
|
+
name: string;
|
|
99
|
+
def: IndicatorDef;
|
|
100
|
+
params: Record<string, number>;
|
|
101
|
+
color: string | null;
|
|
102
|
+
key: string;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* A single OHLCV bar. `time` is milliseconds (second-based input is
|
|
106
|
+
* auto-detected and converted).
|
|
107
|
+
* @typedef {object} Bar
|
|
108
|
+
* @property {number} time
|
|
109
|
+
* @property {number} open
|
|
110
|
+
* @property {number} high
|
|
111
|
+
* @property {number} low
|
|
112
|
+
* @property {number} close
|
|
113
|
+
* @property {number} [volume]
|
|
114
|
+
*/
|
|
115
|
+
/**
|
|
116
|
+
* One plotted line of an indicator result.
|
|
117
|
+
* @typedef {object} IndicatorLine
|
|
118
|
+
* @property {string} [name]
|
|
119
|
+
* @property {Array<number|null>} values
|
|
120
|
+
* @property {string} [color] #hex / rgb() / CSS name / palette key
|
|
121
|
+
*/
|
|
122
|
+
/**
|
|
123
|
+
* An indicator definition for {@link registerIndicator}.
|
|
124
|
+
* @typedef {object} IndicatorDef
|
|
125
|
+
* @property {'overlay'|'pane'} [kind] overlay on the price pane, or a stacked sub-pane
|
|
126
|
+
* @property {Record<string, number>} [params] defaults; set via `name:p1/p2` tokens
|
|
127
|
+
* @property {(bars: Bar[], params: Record<string, number>) => (Array<number|null>|{lines?: IndicatorLine[], histogram?: Array<number|null>})} compute
|
|
128
|
+
* @property {number[]} [guides] pane only: dashed horizontal levels
|
|
129
|
+
* @property {[number, number]} [range] pane only: fixed scale (else autoscale)
|
|
130
|
+
* @property {'price'|'fixed1'} [fmt] legend/axis number format
|
|
131
|
+
* @property {string} [color]
|
|
132
|
+
*/
|
|
133
|
+
/**
|
|
134
|
+
* A position/order visualization.
|
|
135
|
+
* @typedef {object} Position
|
|
136
|
+
* @property {string} id
|
|
137
|
+
* @property {'long'|'short'} side
|
|
138
|
+
* @property {number} entry
|
|
139
|
+
* @property {number|null} stop
|
|
140
|
+
* @property {number|null} target
|
|
141
|
+
* @property {number|null} qty
|
|
142
|
+
*/
|
|
143
|
+
/**
|
|
144
|
+
* A price alert (edge-triggered on streamed crossings).
|
|
145
|
+
* @typedef {object} Alert
|
|
146
|
+
* @property {string} id
|
|
147
|
+
* @property {number} price
|
|
148
|
+
* @property {'above'|'below'|'cross'} direction
|
|
149
|
+
* @property {boolean} once
|
|
150
|
+
*/
|
|
151
|
+
/**
|
|
152
|
+
* Serializable chart snapshot (see `getState()` / `setState()`).
|
|
153
|
+
* @typedef {object} ChartState
|
|
154
|
+
* @property {'candles'|'line'|'area'|'bars'|'hollow'|'heikin'} [type]
|
|
155
|
+
* @property {'dark'|'light'} [theme]
|
|
156
|
+
* @property {boolean} [log]
|
|
157
|
+
* @property {boolean} [stats]
|
|
158
|
+
* @property {boolean} [profile] volume profile overlay (POC + value area)
|
|
159
|
+
* @property {boolean} [annotations] smart annotations (spikes/gaps/pivots/divergences)
|
|
160
|
+
* @property {string} [label]
|
|
161
|
+
* @property {string} [indicators]
|
|
162
|
+
* @property {{from: number, to: number}} [view] visible time window (ms)
|
|
163
|
+
* @property {Array<Position & {id?: string, stop?: number, target?: number, qty?: number}>} [positions] partial positions to add
|
|
164
|
+
* @property {Array<Alert & {id?: string, once?: boolean}>} [alerts] partial alerts to add
|
|
165
|
+
*/
|
|
166
|
+
/**
|
|
167
|
+
* A parsed indicator entry (internal token → def binding).
|
|
168
|
+
* @typedef {object} IndicatorEntry
|
|
169
|
+
* @property {string} name
|
|
170
|
+
* @property {IndicatorDef} def
|
|
171
|
+
* @property {Record<string, number>} params
|
|
172
|
+
* @property {string|null} color
|
|
173
|
+
* @property {string} key
|
|
174
|
+
*/
|
|
175
|
+
export declare const clamp: (v: any, lo: any, hi: any) => any;
|
|
176
|
+
export declare const isNum: (v: any) => boolean;
|
|
177
|
+
export declare const pad2: (n: any) => string;
|
|
178
|
+
export declare function numberFmt(p: any): any;
|
|
179
|
+
export declare function fmtCompact(v: any): any;
|
|
180
|
+
export declare function autoPrecision(v: any): 2 | 3 | 5 | 8;
|
|
181
|
+
/** Nice round step (1, 2, 5 × 10^n) covering `range` in ~`target` steps. */
|
|
182
|
+
export declare function niceStep(range: any, target: any): number;
|
|
183
|
+
export declare function hexToRgba(color: any, alpha: any): any;
|
|
184
|
+
export declare function safeColor(s: any): string;
|
|
185
|
+
export declare const FONT_STACK = "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
|
|
186
|
+
export declare const axisFont: (w?: number) => string;
|
|
187
|
+
export declare const pillFont: () => string;
|
|
188
|
+
export declare function roundRectPath(ctx: any, x: any, y: any, w: any, h: any, r: any): void;
|
|
189
|
+
export declare const SEC = 1000;
|
|
190
|
+
export declare const MIN: number;
|
|
191
|
+
export declare const HOUR: number;
|
|
192
|
+
export declare const DAY: number;
|
|
193
|
+
export declare const TIME_STEPS: {
|
|
194
|
+
ms: number;
|
|
195
|
+
label: string;
|
|
196
|
+
}[];
|
|
197
|
+
export declare const hhmm: (t: any) => string;
|
|
198
|
+
export declare const fmtDay: (t: any) => any;
|
|
199
|
+
export declare const fmtMonth: (t: any, withYear: any) => any;
|
|
200
|
+
export declare const fmtYear: (t: any) => any;
|
|
201
|
+
export declare const fmtFull: (t: any) => string;
|
|
202
|
+
export declare const THEMES: {
|
|
203
|
+
dark: {
|
|
204
|
+
bg: string;
|
|
205
|
+
text: string;
|
|
206
|
+
textStrong: string;
|
|
207
|
+
grid: string;
|
|
208
|
+
border: string;
|
|
209
|
+
up: string;
|
|
210
|
+
down: string;
|
|
211
|
+
accent: string;
|
|
212
|
+
crosshair: string;
|
|
213
|
+
crosshairBg: string;
|
|
214
|
+
crosshairText: string;
|
|
215
|
+
pillText: string;
|
|
216
|
+
rsi: string;
|
|
217
|
+
guide: string;
|
|
218
|
+
volAlpha: number;
|
|
219
|
+
overlay: string[];
|
|
220
|
+
};
|
|
221
|
+
light: {
|
|
222
|
+
bg: string;
|
|
223
|
+
text: string;
|
|
224
|
+
textStrong: string;
|
|
225
|
+
grid: string;
|
|
226
|
+
border: string;
|
|
227
|
+
up: string;
|
|
228
|
+
down: string;
|
|
229
|
+
accent: string;
|
|
230
|
+
crosshair: string;
|
|
231
|
+
crosshairBg: string;
|
|
232
|
+
crosshairText: string;
|
|
233
|
+
pillText: string;
|
|
234
|
+
rsi: string;
|
|
235
|
+
guide: string;
|
|
236
|
+
volAlpha: number;
|
|
237
|
+
overlay: string[];
|
|
238
|
+
};
|
|
239
|
+
};
|
|
240
|
+
/**
|
|
241
|
+
* @param {number[]} values
|
|
242
|
+
* @param {number} period
|
|
243
|
+
* @returns {Array<number|null>}
|
|
244
|
+
*/
|
|
245
|
+
export declare function calcSMA(values: number[], period: number): Array<number | null>;
|
|
246
|
+
/**
|
|
247
|
+
* @param {number[]} values
|
|
248
|
+
* @param {number} period
|
|
249
|
+
* @returns {Array<number|null>}
|
|
250
|
+
*/
|
|
251
|
+
export declare function calcEMA(values: number[], period: number): Array<number | null>;
|
|
252
|
+
/** EMA over a series that may contain leading nulls (e.g. MACD line).
|
|
253
|
+
* @param {Array<number|null>} values
|
|
254
|
+
* @param {number} period
|
|
255
|
+
* @returns {Array<number|null>}
|
|
256
|
+
*/
|
|
257
|
+
export declare function calcEMASparse(values: Array<number | null>, period: number): Array<number | null>;
|
|
258
|
+
/**
|
|
259
|
+
* @param {number[]} closes
|
|
260
|
+
* @param {number} period
|
|
261
|
+
* @returns {Array<number|null>}
|
|
262
|
+
*/
|
|
263
|
+
export declare function calcRSI(closes: number[], period: number): Array<number | null>;
|
|
264
|
+
/** Rolling standard deviation (population) over `period`, aligned like SMA. */
|
|
265
|
+
export declare function calcStdDev(values: any, period: any): any[];
|
|
266
|
+
/**
|
|
267
|
+
* Bollinger Bands.
|
|
268
|
+
* @param {number[]} closes
|
|
269
|
+
* @param {number} period
|
|
270
|
+
* @param {number} [mult]
|
|
271
|
+
* @returns {{mid:Array<number|null>, upper:Array<number|null>, lower:Array<number|null>}}
|
|
272
|
+
*/
|
|
273
|
+
export declare function calcBollinger(closes: number[], period: number, mult?: number): {
|
|
274
|
+
mid: Array<number | null>;
|
|
275
|
+
upper: Array<number | null>;
|
|
276
|
+
lower: Array<number | null>;
|
|
277
|
+
};
|
|
278
|
+
/**
|
|
279
|
+
* MACD.
|
|
280
|
+
* @param {number[]} closes
|
|
281
|
+
* @param {number} [fast]
|
|
282
|
+
* @param {number} [slow]
|
|
283
|
+
* @param {number} [signal]
|
|
284
|
+
* @returns {{macd:Array<number|null>, signal:Array<number|null>, hist:Array<number|null>}}
|
|
285
|
+
*/
|
|
286
|
+
export declare function calcMACD(closes: number[], fast?: number, slow?: number, signal?: number): {
|
|
287
|
+
macd: Array<number | null>;
|
|
288
|
+
signal: Array<number | null>;
|
|
289
|
+
hist: Array<number | null>;
|
|
290
|
+
};
|
|
291
|
+
/**
|
|
292
|
+
* Merge older (backfilled) bars in front of `existing`.
|
|
293
|
+
* Dedupes by time (existing bars win); only strictly older bars are prepended.
|
|
294
|
+
* @param {Bar[]} existing
|
|
295
|
+
* @param {Bar[]} older
|
|
296
|
+
* @returns {{bars: Bar[], added: number}} merged array and count prepended.
|
|
297
|
+
*/
|
|
298
|
+
export declare function mergeOlderData(existing: Bar[], older: Bar[]): {
|
|
299
|
+
bars: Bar[];
|
|
300
|
+
added: number;
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Indices of visible bars whose time jump from the previous bar exceeds
|
|
304
|
+
* `threshold × dt` (sessions breaks, weekends, missing data).
|
|
305
|
+
* @param {Bar[]} bars
|
|
306
|
+
* @param {number} i0
|
|
307
|
+
* @param {number} i1
|
|
308
|
+
* @param {number} dtMs
|
|
309
|
+
* @param {number} [threshold]
|
|
310
|
+
* @returns {number[]}
|
|
311
|
+
*/
|
|
312
|
+
export declare function detectGaps(bars: Bar[], i0: number, i1: number, dtMs: number, threshold?: number): number[];
|
|
313
|
+
/**
|
|
314
|
+
* Aggregate a visible bar range into ~1px-wide columns for deep zoom-outs.
|
|
315
|
+
* `xOf(i)` must be non-decreasing in i (index-space x mapping guarantees it).
|
|
316
|
+
* Each column keeps first open / max high / min low / last close / volume sum.
|
|
317
|
+
* @param {Bar[]} bars
|
|
318
|
+
* @param {number} i0
|
|
319
|
+
* @param {number} i1
|
|
320
|
+
* @param {(i: number) => number} xOf
|
|
321
|
+
* @param {number} plotRight plot width in px (column count)
|
|
322
|
+
* @returns {Array<{x: number, i0: number, i1: number, open: number, high: number, low: number, close: number, volume: number}>}
|
|
323
|
+
*/
|
|
324
|
+
export declare function buildColumns(bars: Bar[], i0: number, i1: number, xOf: (i: number) => number, plotRight: number): Array<{
|
|
325
|
+
x: number;
|
|
326
|
+
i0: number;
|
|
327
|
+
i1: number;
|
|
328
|
+
open: number;
|
|
329
|
+
high: number;
|
|
330
|
+
low: number;
|
|
331
|
+
close: number;
|
|
332
|
+
volume: number;
|
|
333
|
+
}>;
|
|
334
|
+
/**
|
|
335
|
+
* Detect notable events over a visible bar window.
|
|
336
|
+
* Volume spikes (> volMult × SMA(volume)), price gaps beyond the previous
|
|
337
|
+
* bar's range (> gapMult × average range), pivot highs/lows (± pivot bars),
|
|
338
|
+
* and RSI divergences (later higher high with weaker RSI, and symmetric lows).
|
|
339
|
+
*
|
|
340
|
+
* @param {Bar[]} bars full dataset (raw)
|
|
341
|
+
* @param {number} i0 first visible index
|
|
342
|
+
* @param {number} i1 last visible index
|
|
343
|
+
* @param {Array<number|null>|null} rsi precomputed RSI series (or null to skip divergences)
|
|
344
|
+
* @param {{pivot?: number, volMult?: number, gapMult?: number, divDist?: number}} [opts]
|
|
345
|
+
* @returns {Array<{type: string, side: 'high'|'low', i: number, note: string}>}
|
|
346
|
+
*/
|
|
347
|
+
export declare function detectAnnotations(bars: Bar[], i0: number, i1: number, rsi: Array<number | null> | null, opts?: {
|
|
348
|
+
pivot?: number;
|
|
349
|
+
volMult?: number;
|
|
350
|
+
gapMult?: number;
|
|
351
|
+
divDist?: number;
|
|
352
|
+
}): Array<{
|
|
353
|
+
type: string;
|
|
354
|
+
side: 'high' | 'low';
|
|
355
|
+
i: number;
|
|
356
|
+
note: string;
|
|
357
|
+
}>;
|
|
358
|
+
/**
|
|
359
|
+
* Map a price to a sonification frequency over the visible scale.
|
|
360
|
+
* Logarithmic scales map through log-space; result clamped to [lo, hi] Hz.
|
|
361
|
+
* @param {number} price
|
|
362
|
+
* @param {{min: number, max: number, useLog?: boolean}} scale
|
|
363
|
+
* @param {number} [freqLo=180]
|
|
364
|
+
* @param {number} [freqHi=880]
|
|
365
|
+
* @returns {number} frequency in Hz
|
|
366
|
+
*/
|
|
367
|
+
export declare function priceToFreq(price: number, scale: {
|
|
368
|
+
min: number;
|
|
369
|
+
max: number;
|
|
370
|
+
useLog?: boolean;
|
|
371
|
+
}, freqLo?: number, freqHi?: number): number;
|
|
372
|
+
/**
|
|
373
|
+
* Volume profile over a visible bar range: volume distributed into price
|
|
374
|
+
* rows, with POC and the value area (greedy expansion around the POC).
|
|
375
|
+
* @param {Bar[]} bars
|
|
376
|
+
* @param {number} i0
|
|
377
|
+
* @param {number} i1
|
|
378
|
+
* @param {{rows?: number, valueAreaPct?: number}} [opts]
|
|
379
|
+
* @returns {null|{
|
|
380
|
+
* rows: Array<{v: number, up: number, dn: number}>, maxV: number, total: number,
|
|
381
|
+
* rowH: number, priceMin: number, priceMax: number,
|
|
382
|
+
* pocIndex: number, valIndex: number, vahIndex: number,
|
|
383
|
+
* poc: number, val: number, vah: number
|
|
384
|
+
* }}
|
|
385
|
+
*/
|
|
386
|
+
export declare function computeVolumeProfile(bars: Bar[], i0: number, i1: number, opts?: {
|
|
387
|
+
rows?: number;
|
|
388
|
+
valueAreaPct?: number;
|
|
389
|
+
}): null | {
|
|
390
|
+
rows: Array<{
|
|
391
|
+
v: number;
|
|
392
|
+
up: number;
|
|
393
|
+
dn: number;
|
|
394
|
+
}>;
|
|
395
|
+
maxV: number;
|
|
396
|
+
total: number;
|
|
397
|
+
rowH: number;
|
|
398
|
+
priceMin: number;
|
|
399
|
+
priceMax: number;
|
|
400
|
+
pocIndex: number;
|
|
401
|
+
valIndex: number;
|
|
402
|
+
vahIndex: number;
|
|
403
|
+
poc: number;
|
|
404
|
+
val: number;
|
|
405
|
+
vah: number;
|
|
406
|
+
};
|
|
407
|
+
/** Supported values for the `type` attribute. */
|
|
408
|
+
export declare const SERIES_TYPES: string[];
|
|
409
|
+
/**
|
|
410
|
+
* Heikin-Ashi transform (smoothed candles; time/volume pass through).
|
|
411
|
+
* @param {Bar[]} bars
|
|
412
|
+
* @returns {Bar[]}
|
|
413
|
+
*/
|
|
414
|
+
export declare function calcHeikinAshi(bars: Bar[]): Bar[];
|
|
415
|
+
/**
|
|
416
|
+
* Normalize an indicator compute() result to
|
|
417
|
+
* `{ lines: [{name, values, color?}], histogram: number[] | null }`.
|
|
418
|
+
*/
|
|
419
|
+
export declare function normalizeIndicatorResult(res: any): {
|
|
420
|
+
lines: any;
|
|
421
|
+
histogram: any;
|
|
422
|
+
};
|
|
423
|
+
/** Built-in indicator definitions (name → def). */
|
|
424
|
+
export declare const BUILTIN_INDICATORS: Map<string, {
|
|
425
|
+
kind: string;
|
|
426
|
+
params: {
|
|
427
|
+
period: number;
|
|
428
|
+
mult?: undefined;
|
|
429
|
+
fast?: undefined;
|
|
430
|
+
slow?: undefined;
|
|
431
|
+
signal?: undefined;
|
|
432
|
+
};
|
|
433
|
+
compute: (bars: any, p: any) => number[];
|
|
434
|
+
range?: undefined;
|
|
435
|
+
color?: undefined;
|
|
436
|
+
guides?: undefined;
|
|
437
|
+
fmt?: undefined;
|
|
438
|
+
} | {
|
|
439
|
+
kind: string;
|
|
440
|
+
params: {
|
|
441
|
+
period: number;
|
|
442
|
+
mult?: undefined;
|
|
443
|
+
fast?: undefined;
|
|
444
|
+
slow?: undefined;
|
|
445
|
+
signal?: undefined;
|
|
446
|
+
};
|
|
447
|
+
compute: (bars: any, p: any) => number[];
|
|
448
|
+
range?: undefined;
|
|
449
|
+
color?: undefined;
|
|
450
|
+
guides?: undefined;
|
|
451
|
+
fmt?: undefined;
|
|
452
|
+
} | {
|
|
453
|
+
kind: string;
|
|
454
|
+
params: {
|
|
455
|
+
period: number;
|
|
456
|
+
mult: number;
|
|
457
|
+
fast?: undefined;
|
|
458
|
+
slow?: undefined;
|
|
459
|
+
signal?: undefined;
|
|
460
|
+
};
|
|
461
|
+
compute: (bars: any, p: any) => {
|
|
462
|
+
lines: {
|
|
463
|
+
name: string;
|
|
464
|
+
values: number[];
|
|
465
|
+
}[];
|
|
466
|
+
};
|
|
467
|
+
range?: undefined;
|
|
468
|
+
color?: undefined;
|
|
469
|
+
guides?: undefined;
|
|
470
|
+
fmt?: undefined;
|
|
471
|
+
} | {
|
|
472
|
+
kind: string;
|
|
473
|
+
params: {
|
|
474
|
+
mult?: undefined;
|
|
475
|
+
period: number;
|
|
476
|
+
fast?: undefined;
|
|
477
|
+
slow?: undefined;
|
|
478
|
+
signal?: undefined;
|
|
479
|
+
};
|
|
480
|
+
guides: number[];
|
|
481
|
+
range: number[];
|
|
482
|
+
fmt: string;
|
|
483
|
+
color: string;
|
|
484
|
+
compute: (bars: any, p: any) => number[];
|
|
485
|
+
} | {
|
|
486
|
+
range?: undefined;
|
|
487
|
+
color?: undefined;
|
|
488
|
+
kind: string;
|
|
489
|
+
params: {
|
|
490
|
+
mult?: undefined;
|
|
491
|
+
period?: undefined;
|
|
492
|
+
fast: number;
|
|
493
|
+
slow: number;
|
|
494
|
+
signal: number;
|
|
495
|
+
};
|
|
496
|
+
guides: number[];
|
|
497
|
+
fmt: string;
|
|
498
|
+
compute: (bars: any, p: any) => {
|
|
499
|
+
lines: {
|
|
500
|
+
name: string;
|
|
501
|
+
values: number[];
|
|
502
|
+
}[];
|
|
503
|
+
histogram: number[];
|
|
504
|
+
};
|
|
505
|
+
}>;
|
|
506
|
+
/**
|
|
507
|
+
* Parse an `indicators` attribute string against a registry.
|
|
508
|
+
* Token: `name[:param[/param…]][@color]`, plus the `volume` keyword.
|
|
509
|
+
* @param {string|null|undefined} str
|
|
510
|
+
* @param {Map<string, IndicatorDef>} registry
|
|
511
|
+
* @returns {{overlays: IndicatorEntry[], panes: IndicatorEntry[], volume: boolean, unknown: string[]}}
|
|
512
|
+
*/
|
|
513
|
+
export declare function parseIndicators(str: string | null | undefined, registry: Map<string, IndicatorDef>): {
|
|
514
|
+
overlays: IndicatorEntry[];
|
|
515
|
+
panes: IndicatorEntry[];
|
|
516
|
+
volume: boolean;
|
|
517
|
+
unknown: string[];
|
|
518
|
+
};
|
|
519
|
+
/**
|
|
520
|
+
* Unrealized P&L of a position at `price`.
|
|
521
|
+
* @param {{side?: 'long'|'short', entry: number, qty?: number}} pos
|
|
522
|
+
* @param {number} price
|
|
523
|
+
* @returns {number}
|
|
524
|
+
*/
|
|
525
|
+
export declare function positionPnl(pos: {
|
|
526
|
+
side?: 'long' | 'short';
|
|
527
|
+
entry: number;
|
|
528
|
+
qty?: number;
|
|
529
|
+
}, price: number): number;
|
|
530
|
+
/**
|
|
531
|
+
* Edge-triggered alert crossing test between two consecutive prices.
|
|
532
|
+
* @param {{price: number, direction?: 'above'|'below'|'cross'}} alert
|
|
533
|
+
* @param {number} prevPrice
|
|
534
|
+
* @param {number} price
|
|
535
|
+
* @returns {boolean}
|
|
536
|
+
*/
|
|
537
|
+
export declare function checkAlertCross(alert: {
|
|
538
|
+
price: number;
|
|
539
|
+
direction?: 'above' | 'below' | 'cross';
|
|
540
|
+
}, prevPrice: number, price: number): boolean;
|
|
541
|
+
/**
|
|
542
|
+
* Statistics over a visible slice of bars.
|
|
543
|
+
* @param {Bar[]} bars
|
|
544
|
+
* @param {number} i0
|
|
545
|
+
* @param {number} i1
|
|
546
|
+
* @param {number} dtMs
|
|
547
|
+
* @returns {null|{n:number, changePct:number, min:number, max:number, maxDDPct:number, annVolPct:number, up:number, dn:number, avgVolume:number}}
|
|
548
|
+
*/
|
|
549
|
+
export declare function computeStats(bars: Bar[], i0: number, i1: number, dtMs: number): null | {
|
|
550
|
+
n: number;
|
|
551
|
+
changePct: number;
|
|
552
|
+
min: number;
|
|
553
|
+
max: number;
|
|
554
|
+
maxDDPct: number;
|
|
555
|
+
annVolPct: number;
|
|
556
|
+
up: number;
|
|
557
|
+
dn: number;
|
|
558
|
+
avgVolume: number;
|
|
559
|
+
};
|
|
560
|
+
/**
|
|
561
|
+
* Encode a chart state (from getState()) as a compact query string.
|
|
562
|
+
* View times are encoded in whole seconds.
|
|
563
|
+
* @param {ChartState|null} state
|
|
564
|
+
* @returns {string}
|
|
565
|
+
*/
|
|
566
|
+
export declare function encodeStateQuery(state: ChartState | null): string;
|
|
567
|
+
/**
|
|
568
|
+
* Decode a query string (from encodeStateQuery) back into a partial state.
|
|
569
|
+
* @param {string} str
|
|
570
|
+
* @returns {ChartState}
|
|
571
|
+
*/
|
|
572
|
+
export declare function decodeStateQuery(str: string): ChartState;
|
package/types/feeds.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export declare const TF_SECONDS: {
|
|
2
|
+
'1m': number;
|
|
3
|
+
'3m': number;
|
|
4
|
+
'5m': number;
|
|
5
|
+
'15m': number;
|
|
6
|
+
'30m': number;
|
|
7
|
+
'1h': number;
|
|
8
|
+
'2h': number;
|
|
9
|
+
'4h': number;
|
|
10
|
+
'6h': number;
|
|
11
|
+
'12h': number;
|
|
12
|
+
'1d': number;
|
|
13
|
+
'3d': number;
|
|
14
|
+
'1w': number;
|
|
15
|
+
};
|
|
16
|
+
/** Seconds for a timeframe id ('15m', '1h', '1D'…); defaults to 1h. */
|
|
17
|
+
export declare function tfToSeconds(tf: any): any;
|
|
18
|
+
export declare const BASE_PRICES: {
|
|
19
|
+
BTC: number;
|
|
20
|
+
ETH: number;
|
|
21
|
+
SOL: number;
|
|
22
|
+
DEMO: number;
|
|
23
|
+
};
|
|
24
|
+
export declare function mulberry32(seed: any): () => number;
|
|
25
|
+
export declare function gauss(rnd: any): number;
|
|
26
|
+
export declare function hashStr(s: any): number;
|
|
27
|
+
/**
|
|
28
|
+
* Deterministic synthetic OHLCV history (random walk with volatility regimes
|
|
29
|
+
* and mild mean reversion). Same key → same series.
|
|
30
|
+
* @param {string} key seed key (symbol, symbol+tf, …)
|
|
31
|
+
* @param {number} sec timeframe in seconds
|
|
32
|
+
* @param {number} n bar count
|
|
33
|
+
* @param {number} [base=100] starting/base price
|
|
34
|
+
*/
|
|
35
|
+
export declare function genSynthetic(key: string, sec: number, n: number, base?: number): any[];
|
|
36
|
+
/**
|
|
37
|
+
* Stateful synthetic live stream: mutates the current bar each tick and
|
|
38
|
+
* rolls over on timeframe boundaries. Bridges from `startPrice` when given.
|
|
39
|
+
* @param {number} sec timeframe in seconds
|
|
40
|
+
* @param {number} [startPrice] bridge continuity from the last known price
|
|
41
|
+
*/
|
|
42
|
+
export declare function makeSynthStream(sec: number, startPrice?: number): () => any;
|
|
43
|
+
/**
|
|
44
|
+
* Fetch klines from Binance's public REST API.
|
|
45
|
+
* @param {string} symbol e.g. 'BTCUSDT'
|
|
46
|
+
* @param {string} tfId interval id ('15m','1h','1d'…)
|
|
47
|
+
* @param {number} [limit=500]
|
|
48
|
+
* @param {number} [endTime] fetch bars older than this (ms) — for backfill
|
|
49
|
+
*/
|
|
50
|
+
export declare function fetchBinanceKlines(symbol: string, tfId: string, limit?: number, endTime?: number): Promise<any>;
|
|
51
|
+
/**
|
|
52
|
+
* Open a Binance kline WebSocket. `onDown(err)` fires on error/close/timeout
|
|
53
|
+
* (after which the socket is dead and the caller should fall back).
|
|
54
|
+
* @returns {{close(): void}}
|
|
55
|
+
*/
|
|
56
|
+
export declare function openBinanceSocket(symbol: any, tfId: any, onBar: any, onDown: any, timeoutMs?: number): {
|
|
57
|
+
close(): void;
|
|
58
|
+
};
|