@lacspace/indicators 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Lacspace
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.cjs ADDED
@@ -0,0 +1,389 @@
1
+ 'use strict';
2
+
3
+ // src/index.ts
4
+ function assertPeriod(period) {
5
+ if (!Number.isInteger(period) || period < 1) {
6
+ throw new RangeError(`period must be a positive integer, got ${period}`);
7
+ }
8
+ }
9
+ var SMA = class {
10
+ constructor(period) {
11
+ this.period = period;
12
+ this.buf = [];
13
+ this.sum = 0;
14
+ /** Latest value, or `null` until `period` samples have been seen. */
15
+ this.value = null;
16
+ assertPeriod(period);
17
+ }
18
+ next(price) {
19
+ this.buf.push(price);
20
+ this.sum += price;
21
+ if (this.buf.length > this.period) this.sum -= this.buf.shift();
22
+ this.value = this.buf.length === this.period ? this.sum / this.period : null;
23
+ return this.value;
24
+ }
25
+ };
26
+ var EMA = class {
27
+ constructor(period) {
28
+ this.period = period;
29
+ this.seed = [];
30
+ this.ema = null;
31
+ this.value = null;
32
+ assertPeriod(period);
33
+ this.k = 2 / (period + 1);
34
+ }
35
+ next(price) {
36
+ if (this.ema === null) {
37
+ this.seed.push(price);
38
+ if (this.seed.length < this.period) return this.value = null;
39
+ this.ema = this.seed.reduce((a, b) => a + b, 0) / this.period;
40
+ } else {
41
+ this.ema = price * this.k + this.ema * (1 - this.k);
42
+ }
43
+ return this.value = this.ema;
44
+ }
45
+ };
46
+ var WMA = class {
47
+ constructor(period) {
48
+ this.period = period;
49
+ this.buf = [];
50
+ this.value = null;
51
+ assertPeriod(period);
52
+ }
53
+ next(price) {
54
+ this.buf.push(price);
55
+ if (this.buf.length > this.period) this.buf.shift();
56
+ if (this.buf.length < this.period) return this.value = null;
57
+ let num = 0;
58
+ let den = 0;
59
+ for (let i = 0; i < this.period; i++) {
60
+ const w = i + 1;
61
+ num += this.buf[i] * w;
62
+ den += w;
63
+ }
64
+ return this.value = num / den;
65
+ }
66
+ };
67
+ var RSI = class {
68
+ constructor(period = 14) {
69
+ this.period = period;
70
+ this.prev = null;
71
+ this.avgGain = 0;
72
+ this.avgLoss = 0;
73
+ this.count = 0;
74
+ this.value = null;
75
+ assertPeriod(period);
76
+ }
77
+ next(price) {
78
+ if (this.prev === null) {
79
+ this.prev = price;
80
+ return this.value = null;
81
+ }
82
+ const change = price - this.prev;
83
+ this.prev = price;
84
+ const gain = change > 0 ? change : 0;
85
+ const loss = change < 0 ? -change : 0;
86
+ this.count++;
87
+ if (this.count <= this.period) {
88
+ this.avgGain += gain;
89
+ this.avgLoss += loss;
90
+ if (this.count < this.period) return this.value = null;
91
+ this.avgGain /= this.period;
92
+ this.avgLoss /= this.period;
93
+ } else {
94
+ this.avgGain = (this.avgGain * (this.period - 1) + gain) / this.period;
95
+ this.avgLoss = (this.avgLoss * (this.period - 1) + loss) / this.period;
96
+ }
97
+ return this.value = this.compute();
98
+ }
99
+ compute() {
100
+ if (this.avgLoss === 0) return 100;
101
+ const rs = this.avgGain / this.avgLoss;
102
+ return 100 - 100 / (1 + rs);
103
+ }
104
+ };
105
+ var MACD = class {
106
+ constructor(fast = 12, slow = 26, signal = 9) {
107
+ this.value = null;
108
+ this.fastEma = new EMA(fast);
109
+ this.slowEma = new EMA(slow);
110
+ this.signalEma = new EMA(signal);
111
+ }
112
+ next(price) {
113
+ const f = this.fastEma.next(price);
114
+ const s = this.slowEma.next(price);
115
+ if (f === null || s === null) return this.value = null;
116
+ const macd2 = f - s;
117
+ const signal = this.signalEma.next(macd2);
118
+ if (signal === null) return this.value = null;
119
+ return this.value = { macd: macd2, signal, histogram: macd2 - signal };
120
+ }
121
+ };
122
+ var BollingerBands = class {
123
+ constructor(period = 20, mult = 2) {
124
+ this.period = period;
125
+ this.mult = mult;
126
+ this.buf = [];
127
+ this.sum = 0;
128
+ this.value = null;
129
+ assertPeriod(period);
130
+ }
131
+ next(price) {
132
+ this.buf.push(price);
133
+ this.sum += price;
134
+ if (this.buf.length > this.period) this.sum -= this.buf.shift();
135
+ if (this.buf.length < this.period) return this.value = null;
136
+ const mean = this.sum / this.period;
137
+ let variance = 0;
138
+ for (const v of this.buf) variance += (v - mean) ** 2;
139
+ const sd = Math.sqrt(variance / this.period);
140
+ const upper = mean + this.mult * sd;
141
+ const lower = mean - this.mult * sd;
142
+ return this.value = {
143
+ middle: mean,
144
+ upper,
145
+ lower,
146
+ bandwidth: mean === 0 ? 0 : (upper - lower) / mean
147
+ };
148
+ }
149
+ };
150
+ var ATR = class {
151
+ constructor(period = 14) {
152
+ this.period = period;
153
+ this.prevClose = null;
154
+ this.atr = null;
155
+ this.seed = [];
156
+ this.value = null;
157
+ assertPeriod(period);
158
+ }
159
+ next(bar) {
160
+ const tr = this.prevClose === null ? bar.high - bar.low : Math.max(
161
+ bar.high - bar.low,
162
+ Math.abs(bar.high - this.prevClose),
163
+ Math.abs(bar.low - this.prevClose)
164
+ );
165
+ this.prevClose = bar.close;
166
+ if (this.atr === null) {
167
+ this.seed.push(tr);
168
+ if (this.seed.length < this.period) return this.value = null;
169
+ this.atr = this.seed.reduce((a, b) => a + b, 0) / this.period;
170
+ return this.value = this.atr;
171
+ }
172
+ this.atr = (this.atr * (this.period - 1) + tr) / this.period;
173
+ return this.value = this.atr;
174
+ }
175
+ };
176
+ var VWAP = class {
177
+ constructor() {
178
+ this.pv = 0;
179
+ this.vol = 0;
180
+ this.value = null;
181
+ }
182
+ next(bar) {
183
+ const typical = (bar.high + bar.low + bar.close) / 3;
184
+ this.pv += typical * bar.volume;
185
+ this.vol += bar.volume;
186
+ return this.value = this.vol === 0 ? null : this.pv / this.vol;
187
+ }
188
+ reset() {
189
+ this.pv = 0;
190
+ this.vol = 0;
191
+ this.value = null;
192
+ }
193
+ };
194
+ var Stochastic = class {
195
+ constructor(period = 14, signal = 3) {
196
+ this.period = period;
197
+ this.signal = signal;
198
+ this.highs = [];
199
+ this.lows = [];
200
+ this.value = null;
201
+ assertPeriod(period);
202
+ this.dSma = new SMA(signal);
203
+ }
204
+ next(bar) {
205
+ this.highs.push(bar.high);
206
+ this.lows.push(bar.low);
207
+ if (this.highs.length > this.period) {
208
+ this.highs.shift();
209
+ this.lows.shift();
210
+ }
211
+ if (this.highs.length < this.period) return this.value = null;
212
+ const hh = Math.max(...this.highs);
213
+ const ll = Math.min(...this.lows);
214
+ const k = hh === ll ? 100 : (bar.close - ll) / (hh - ll) * 100;
215
+ const d = this.dSma.next(k);
216
+ if (d === null) return this.value = null;
217
+ return this.value = { k, d };
218
+ }
219
+ };
220
+ var Supertrend = class {
221
+ constructor(period = 10, mult = 3) {
222
+ this.period = period;
223
+ this.mult = mult;
224
+ this.prevClose = null;
225
+ this.prevFinalUpper = 0;
226
+ this.prevFinalLower = 0;
227
+ this.prevSupertrend = null;
228
+ this.value = null;
229
+ this.atr = new ATR(period);
230
+ }
231
+ next(bar) {
232
+ const atr2 = this.atr.next(bar);
233
+ if (atr2 === null) {
234
+ this.prevClose = bar.close;
235
+ return this.value = null;
236
+ }
237
+ const hl2 = (bar.high + bar.low) / 2;
238
+ const basicUpper = hl2 + this.mult * atr2;
239
+ const basicLower = hl2 - this.mult * atr2;
240
+ const pc = this.prevClose ?? bar.close;
241
+ const first = this.prevSupertrend === null;
242
+ const finalUpper = first || basicUpper < this.prevFinalUpper || pc > this.prevFinalUpper ? basicUpper : this.prevFinalUpper;
243
+ const finalLower = first || basicLower > this.prevFinalLower || pc < this.prevFinalLower ? basicLower : this.prevFinalLower;
244
+ let st;
245
+ let direction;
246
+ if (first) {
247
+ direction = bar.close <= finalUpper ? -1 : 1;
248
+ st = direction === -1 ? finalUpper : finalLower;
249
+ } else if (this.prevSupertrend === this.prevFinalUpper) {
250
+ if (bar.close <= finalUpper) {
251
+ st = finalUpper;
252
+ direction = -1;
253
+ } else {
254
+ st = finalLower;
255
+ direction = 1;
256
+ }
257
+ } else {
258
+ if (bar.close >= finalLower) {
259
+ st = finalLower;
260
+ direction = 1;
261
+ } else {
262
+ st = finalUpper;
263
+ direction = -1;
264
+ }
265
+ }
266
+ this.prevFinalUpper = finalUpper;
267
+ this.prevFinalLower = finalLower;
268
+ this.prevSupertrend = st;
269
+ this.prevClose = bar.close;
270
+ return this.value = { value: st, direction };
271
+ }
272
+ };
273
+ var ADX = class {
274
+ constructor(period = 14) {
275
+ this.period = period;
276
+ this.prevHigh = null;
277
+ this.prevLow = 0;
278
+ this.prevClose = 0;
279
+ this.smTR = 0;
280
+ this.smPDM = 0;
281
+ this.smMDM = 0;
282
+ this.dxs = [];
283
+ this.adx = null;
284
+ this.count = 0;
285
+ this.value = null;
286
+ assertPeriod(period);
287
+ }
288
+ next(bar) {
289
+ if (this.prevHigh === null) {
290
+ this.prevHigh = bar.high;
291
+ this.prevLow = bar.low;
292
+ this.prevClose = bar.close;
293
+ return this.value = null;
294
+ }
295
+ const upMove = bar.high - this.prevHigh;
296
+ const downMove = this.prevLow - bar.low;
297
+ const pdm = upMove > downMove && upMove > 0 ? upMove : 0;
298
+ const mdm = downMove > upMove && downMove > 0 ? downMove : 0;
299
+ const tr = Math.max(
300
+ bar.high - bar.low,
301
+ Math.abs(bar.high - this.prevClose),
302
+ Math.abs(bar.low - this.prevClose)
303
+ );
304
+ this.prevHigh = bar.high;
305
+ this.prevLow = bar.low;
306
+ this.prevClose = bar.close;
307
+ this.count++;
308
+ if (this.count <= this.period) {
309
+ this.smTR += tr;
310
+ this.smPDM += pdm;
311
+ this.smMDM += mdm;
312
+ if (this.count < this.period) return this.value = null;
313
+ } else {
314
+ this.smTR = this.smTR - this.smTR / this.period + tr;
315
+ this.smPDM = this.smPDM - this.smPDM / this.period + pdm;
316
+ this.smMDM = this.smMDM - this.smMDM / this.period + mdm;
317
+ }
318
+ const plusDI = this.smTR === 0 ? 0 : 100 * this.smPDM / this.smTR;
319
+ const minusDI = this.smTR === 0 ? 0 : 100 * this.smMDM / this.smTR;
320
+ const diSum = plusDI + minusDI;
321
+ const dx = diSum === 0 ? 0 : 100 * Math.abs(plusDI - minusDI) / diSum;
322
+ if (this.adx === null) {
323
+ this.dxs.push(dx);
324
+ if (this.dxs.length < this.period) return this.value = null;
325
+ this.adx = this.dxs.reduce((a, b) => a + b, 0) / this.period;
326
+ } else {
327
+ this.adx = (this.adx * (this.period - 1) + dx) / this.period;
328
+ }
329
+ return this.value = { adx: this.adx, plusDI, minusDI };
330
+ }
331
+ };
332
+ function runNumber(ind, values) {
333
+ return values.map((v) => ind.next(v));
334
+ }
335
+ var sma = (values, period) => runNumber(new SMA(period), values);
336
+ var ema = (values, period) => runNumber(new EMA(period), values);
337
+ var wma = (values, period) => runNumber(new WMA(period), values);
338
+ var rsi = (values, period = 14) => runNumber(new RSI(period), values);
339
+ function macd(values, fast = 12, slow = 26, signal = 9) {
340
+ const ind = new MACD(fast, slow, signal);
341
+ return values.map((v) => ind.next(v));
342
+ }
343
+ function bollinger(values, period = 20, mult = 2) {
344
+ const ind = new BollingerBands(period, mult);
345
+ return values.map((v) => ind.next(v));
346
+ }
347
+ function atr(bars, period = 14) {
348
+ const ind = new ATR(period);
349
+ return bars.map((b) => ind.next(b));
350
+ }
351
+ function supertrend(bars, period = 10, mult = 3) {
352
+ const ind = new Supertrend(period, mult);
353
+ return bars.map((b) => ind.next(b));
354
+ }
355
+ function adx(bars, period = 14) {
356
+ const ind = new ADX(period);
357
+ return bars.map((b) => ind.next(b));
358
+ }
359
+ function crossedAbove(prev, curr) {
360
+ return prev.a <= prev.b && curr.a > curr.b;
361
+ }
362
+ function crossedBelow(prev, curr) {
363
+ return prev.a >= prev.b && curr.a < curr.b;
364
+ }
365
+
366
+ exports.ADX = ADX;
367
+ exports.ATR = ATR;
368
+ exports.BollingerBands = BollingerBands;
369
+ exports.EMA = EMA;
370
+ exports.MACD = MACD;
371
+ exports.RSI = RSI;
372
+ exports.SMA = SMA;
373
+ exports.Stochastic = Stochastic;
374
+ exports.Supertrend = Supertrend;
375
+ exports.VWAP = VWAP;
376
+ exports.WMA = WMA;
377
+ exports.adx = adx;
378
+ exports.atr = atr;
379
+ exports.bollinger = bollinger;
380
+ exports.crossedAbove = crossedAbove;
381
+ exports.crossedBelow = crossedBelow;
382
+ exports.ema = ema;
383
+ exports.macd = macd;
384
+ exports.rsi = rsi;
385
+ exports.sma = sma;
386
+ exports.supertrend = supertrend;
387
+ exports.wma = wma;
388
+ //# sourceMappingURL=index.cjs.map
389
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":["macd","atr"],"mappings":";;;AA2BA,SAAS,aAAa,MAAA,EAAsB;AAC1C,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,MAAM,CAAA,IAAK,SAAS,CAAA,EAAG;AAC3C,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,uCAAA,EAA0C,MAAM,CAAA,CAAE,CAAA;AAAA,EACzE;AACF;AAGO,IAAM,MAAN,MAAU;AAAA,EAMf,YAA4B,MAAA,EAAgB;AAAhB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAL5B,IAAA,IAAA,CAAQ,MAAgB,EAAC;AACzB,IAAA,IAAA,CAAQ,GAAA,GAAM,CAAA;AAEd;AAAA,IAAA,IAAA,CAAA,KAAA,GAAuB,IAAA;AAGrB,IAAA,YAAA,CAAa,MAAM,CAAA;AAAA,EACrB;AAAA,EAEA,KAAK,KAAA,EAA8B;AACjC,IAAA,IAAA,CAAK,GAAA,CAAI,KAAK,KAAK,CAAA;AACnB,IAAA,IAAA,CAAK,GAAA,IAAO,KAAA;AACZ,IAAA,IAAI,IAAA,CAAK,IAAI,MAAA,GAAS,IAAA,CAAK,QAAQ,IAAA,CAAK,GAAA,IAAO,IAAA,CAAK,GAAA,CAAI,KAAA,EAAM;AAC9D,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAK,GAAA,CAAI,MAAA,KAAW,KAAK,MAAA,GAAS,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,MAAA,GAAS,IAAA;AACxE,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AACF;AAGO,IAAM,MAAN,MAAU;AAAA,EAMf,YAA4B,MAAA,EAAgB;AAAhB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAJ5B,IAAA,IAAA,CAAQ,OAAiB,EAAC;AAC1B,IAAA,IAAA,CAAQ,GAAA,GAAqB,IAAA;AAC7B,IAAA,IAAA,CAAA,KAAA,GAAuB,IAAA;AAGrB,IAAA,YAAA,CAAa,MAAM,CAAA;AACnB,IAAA,IAAA,CAAK,CAAA,GAAI,KAAK,MAAA,GAAS,CAAA,CAAA;AAAA,EACzB;AAAA,EAEA,KAAK,KAAA,EAA8B;AACjC,IAAA,IAAI,IAAA,CAAK,QAAQ,IAAA,EAAM;AACrB,MAAA,IAAA,CAAK,IAAA,CAAK,KAAK,KAAK,CAAA;AACpB,MAAA,IAAI,KAAK,IAAA,CAAK,MAAA,GAAS,KAAK,MAAA,EAAQ,OAAQ,KAAK,KAAA,GAAQ,IAAA;AACzD,MAAA,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAA,EAAG,CAAC,CAAA,GAAI,IAAA,CAAK,MAAA;AAAA,IACzD,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,MAAM,KAAA,GAAQ,IAAA,CAAK,IAAI,IAAA,CAAK,GAAA,IAAO,IAAI,IAAA,CAAK,CAAA,CAAA;AAAA,IACnD;AACA,IAAA,OAAQ,IAAA,CAAK,QAAQ,IAAA,CAAK,GAAA;AAAA,EAC5B;AACF;AAGO,IAAM,MAAN,MAAU;AAAA,EAIf,YAA4B,MAAA,EAAgB;AAAhB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAH5B,IAAA,IAAA,CAAQ,MAAgB,EAAC;AACzB,IAAA,IAAA,CAAA,KAAA,GAAuB,IAAA;AAGrB,IAAA,YAAA,CAAa,MAAM,CAAA;AAAA,EACrB;AAAA,EAEA,KAAK,KAAA,EAA8B;AACjC,IAAA,IAAA,CAAK,GAAA,CAAI,KAAK,KAAK,CAAA;AACnB,IAAA,IAAI,KAAK,GAAA,CAAI,MAAA,GAAS,KAAK,MAAA,EAAQ,IAAA,CAAK,IAAI,KAAA,EAAM;AAClD,IAAA,IAAI,KAAK,GAAA,CAAI,MAAA,GAAS,KAAK,MAAA,EAAQ,OAAQ,KAAK,KAAA,GAAQ,IAAA;AACxD,IAAA,IAAI,GAAA,GAAM,CAAA;AACV,IAAA,IAAI,GAAA,GAAM,CAAA;AACV,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,MAAA,MAAM,IAAI,CAAA,GAAI,CAAA;AACd,MAAA,GAAA,IAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAK,CAAA;AACtB,MAAA,GAAA,IAAO,CAAA;AAAA,IACT;AACA,IAAA,OAAQ,IAAA,CAAK,QAAQ,GAAA,GAAM,GAAA;AAAA,EAC7B;AACF;AAGO,IAAM,MAAN,MAAU;AAAA,EAOf,WAAA,CAA4B,SAAiB,EAAA,EAAI;AAArB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAN5B,IAAA,IAAA,CAAQ,IAAA,GAAsB,IAAA;AAC9B,IAAA,IAAA,CAAQ,OAAA,GAAU,CAAA;AAClB,IAAA,IAAA,CAAQ,OAAA,GAAU,CAAA;AAClB,IAAA,IAAA,CAAQ,KAAA,GAAQ,CAAA;AAChB,IAAA,IAAA,CAAA,KAAA,GAAuB,IAAA;AAGrB,IAAA,YAAA,CAAa,MAAM,CAAA;AAAA,EACrB;AAAA,EAEA,KAAK,KAAA,EAA8B;AACjC,IAAA,IAAI,IAAA,CAAK,SAAS,IAAA,EAAM;AACtB,MAAA,IAAA,CAAK,IAAA,GAAO,KAAA;AACZ,MAAA,OAAQ,KAAK,KAAA,GAAQ,IAAA;AAAA,IACvB;AACA,IAAA,MAAM,MAAA,GAAS,QAAQ,IAAA,CAAK,IAAA;AAC5B,IAAA,IAAA,CAAK,IAAA,GAAO,KAAA;AACZ,IAAA,MAAM,IAAA,GAAO,MAAA,GAAS,CAAA,GAAI,MAAA,GAAS,CAAA;AACnC,IAAA,MAAM,IAAA,GAAO,MAAA,GAAS,CAAA,GAAI,CAAC,MAAA,GAAS,CAAA;AACpC,IAAA,IAAA,CAAK,KAAA,EAAA;AAEL,IAAA,IAAI,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,MAAA,EAAQ;AAC7B,MAAA,IAAA,CAAK,OAAA,IAAW,IAAA;AAChB,MAAA,IAAA,CAAK,OAAA,IAAW,IAAA;AAChB,MAAA,IAAI,KAAK,KAAA,GAAQ,IAAA,CAAK,MAAA,EAAQ,OAAQ,KAAK,KAAA,GAAQ,IAAA;AACnD,MAAA,IAAA,CAAK,WAAW,IAAA,CAAK,MAAA;AACrB,MAAA,IAAA,CAAK,WAAW,IAAA,CAAK,MAAA;AAAA,IACvB,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,WAAW,IAAA,CAAK,OAAA,IAAW,KAAK,MAAA,GAAS,CAAA,CAAA,GAAK,QAAQ,IAAA,CAAK,MAAA;AAChE,MAAA,IAAA,CAAK,WAAW,IAAA,CAAK,OAAA,IAAW,KAAK,MAAA,GAAS,CAAA,CAAA,GAAK,QAAQ,IAAA,CAAK,MAAA;AAAA,IAClE;AACA,IAAA,OAAQ,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,OAAA,EAAQ;AAAA,EACpC;AAAA,EAEQ,OAAA,GAAkB;AACxB,IAAA,IAAI,IAAA,CAAK,OAAA,KAAY,CAAA,EAAG,OAAO,GAAA;AAC/B,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,OAAA,GAAU,IAAA,CAAK,OAAA;AAC/B,IAAA,OAAO,GAAA,GAAM,OAAO,CAAA,GAAI,EAAA,CAAA;AAAA,EAC1B;AACF;AASO,IAAM,OAAN,MAAW;AAAA,EAMhB,YAAY,IAAA,GAAO,EAAA,EAAI,IAAA,GAAO,EAAA,EAAI,SAAS,CAAA,EAAG;AAF9C,IAAA,IAAA,CAAA,KAAA,GAA0B,IAAA;AAGxB,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,GAAA,CAAI,IAAI,CAAA;AAC3B,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,GAAA,CAAI,IAAI,CAAA;AAC3B,IAAA,IAAA,CAAK,SAAA,GAAY,IAAI,GAAA,CAAI,MAAM,CAAA;AAAA,EACjC;AAAA,EAEA,KAAK,KAAA,EAAiC;AACpC,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA;AACjC,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA;AACjC,IAAA,IAAI,MAAM,IAAA,IAAQ,CAAA,KAAM,IAAA,EAAM,OAAQ,KAAK,KAAA,GAAQ,IAAA;AACnD,IAAA,MAAMA,QAAO,CAAA,GAAI,CAAA;AACjB,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,IAAA,CAAKA,KAAI,CAAA;AACvC,IAAA,IAAI,MAAA,KAAW,IAAA,EAAM,OAAQ,IAAA,CAAK,KAAA,GAAQ,IAAA;AAC1C,IAAA,OAAQ,IAAA,CAAK,QAAQ,EAAE,IAAA,EAAAA,OAAM,MAAA,EAAQ,SAAA,EAAWA,QAAO,MAAA,EAAO;AAAA,EAChE;AACF;AAWO,IAAM,iBAAN,MAAqB;AAAA,EAK1B,WAAA,CACkB,MAAA,GAAS,EAAA,EACT,IAAA,GAAO,CAAA,EACvB;AAFgB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AANlB,IAAA,IAAA,CAAQ,MAAgB,EAAC;AACzB,IAAA,IAAA,CAAQ,GAAA,GAAM,CAAA;AACd,IAAA,IAAA,CAAA,KAAA,GAA+B,IAAA;AAM7B,IAAA,YAAA,CAAa,MAAM,CAAA;AAAA,EACrB;AAAA,EAEA,KAAK,KAAA,EAAsC;AACzC,IAAA,IAAA,CAAK,GAAA,CAAI,KAAK,KAAK,CAAA;AACnB,IAAA,IAAA,CAAK,GAAA,IAAO,KAAA;AACZ,IAAA,IAAI,IAAA,CAAK,IAAI,MAAA,GAAS,IAAA,CAAK,QAAQ,IAAA,CAAK,GAAA,IAAO,IAAA,CAAK,GAAA,CAAI,KAAA,EAAM;AAC9D,IAAA,IAAI,KAAK,GAAA,CAAI,MAAA,GAAS,KAAK,MAAA,EAAQ,OAAQ,KAAK,KAAA,GAAQ,IAAA;AACxD,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,MAAA;AAC7B,IAAA,IAAI,QAAA,GAAW,CAAA;AACf,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,GAAA,EAAK,QAAA,IAAA,CAAa,IAAI,IAAA,KAAS,CAAA;AACpD,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,IAAA,CAAK,QAAA,GAAW,KAAK,MAAM,CAAA;AAC3C,IAAA,MAAM,KAAA,GAAQ,IAAA,GAAO,IAAA,CAAK,IAAA,GAAO,EAAA;AACjC,IAAA,MAAM,KAAA,GAAQ,IAAA,GAAO,IAAA,CAAK,IAAA,GAAO,EAAA;AACjC,IAAA,OAAQ,KAAK,KAAA,GAAQ;AAAA,MACnB,MAAA,EAAQ,IAAA;AAAA,MACR,KAAA;AAAA,MACA,KAAA;AAAA,MACA,SAAA,EAAW,IAAA,KAAS,CAAA,GAAI,CAAA,GAAA,CAAK,QAAQ,KAAA,IAAS;AAAA,KAChD;AAAA,EACF;AACF;AAGO,IAAM,MAAN,MAAU;AAAA,EAMf,WAAA,CAA4B,SAAS,EAAA,EAAI;AAAb,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAL5B,IAAA,IAAA,CAAQ,SAAA,GAA2B,IAAA;AACnC,IAAA,IAAA,CAAQ,GAAA,GAAqB,IAAA;AAC7B,IAAA,IAAA,CAAQ,OAAiB,EAAC;AAC1B,IAAA,IAAA,CAAA,KAAA,GAAuB,IAAA;AAGrB,IAAA,YAAA,CAAa,MAAM,CAAA;AAAA,EACrB;AAAA,EAEA,KAAK,GAAA,EAAyB;AAC5B,IAAA,MAAM,EAAA,GACJ,KAAK,SAAA,KAAc,IAAA,GACf,IAAI,IAAA,GAAO,GAAA,CAAI,MACf,IAAA,CAAK,GAAA;AAAA,MACH,GAAA,CAAI,OAAO,GAAA,CAAI,GAAA;AAAA,MACf,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,IAAA,GAAO,KAAK,SAAS,CAAA;AAAA,MAClC,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAA,GAAM,KAAK,SAAS;AAAA,KACnC;AACN,IAAA,IAAA,CAAK,YAAY,GAAA,CAAI,KAAA;AAErB,IAAA,IAAI,IAAA,CAAK,QAAQ,IAAA,EAAM;AACrB,MAAA,IAAA,CAAK,IAAA,CAAK,KAAK,EAAE,CAAA;AACjB,MAAA,IAAI,KAAK,IAAA,CAAK,MAAA,GAAS,KAAK,MAAA,EAAQ,OAAQ,KAAK,KAAA,GAAQ,IAAA;AACzD,MAAA,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAA,EAAG,CAAC,CAAA,GAAI,IAAA,CAAK,MAAA;AACvD,MAAA,OAAQ,IAAA,CAAK,QAAQ,IAAA,CAAK,GAAA;AAAA,IAC5B;AACA,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,GAAA,IAAO,KAAK,MAAA,GAAS,CAAA,CAAA,GAAK,MAAM,IAAA,CAAK,MAAA;AACtD,IAAA,OAAQ,IAAA,CAAK,QAAQ,IAAA,CAAK,GAAA;AAAA,EAC5B;AACF;AAGO,IAAM,OAAN,MAAW;AAAA,EAAX,WAAA,GAAA;AACL,IAAA,IAAA,CAAQ,EAAA,GAAK,CAAA;AACb,IAAA,IAAA,CAAQ,GAAA,GAAM,CAAA;AACd,IAAA,IAAA,CAAA,KAAA,GAAuB,IAAA;AAAA,EAAA;AAAA,EAEvB,KAAK,GAAA,EAAiF;AACpF,IAAA,MAAM,WAAW,GAAA,CAAI,IAAA,GAAO,GAAA,CAAI,GAAA,GAAM,IAAI,KAAA,IAAS,CAAA;AACnD,IAAA,IAAA,CAAK,EAAA,IAAM,UAAU,GAAA,CAAI,MAAA;AACzB,IAAA,IAAA,CAAK,OAAO,GAAA,CAAI,MAAA;AAChB,IAAA,OAAQ,IAAA,CAAK,QAAQ,IAAA,CAAK,GAAA,KAAQ,IAAI,IAAA,GAAO,IAAA,CAAK,KAAK,IAAA,CAAK,GAAA;AAAA,EAC9D;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,EAAA,GAAK,CAAA;AACV,IAAA,IAAA,CAAK,GAAA,GAAM,CAAA;AACX,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AAAA,EACf;AACF;AAUO,IAAM,aAAN,MAAiB;AAAA,EAMtB,WAAA,CACkB,MAAA,GAAS,EAAA,EACT,MAAA,GAAS,CAAA,EACzB;AAFgB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAPlB,IAAA,IAAA,CAAQ,QAAkB,EAAC;AAC3B,IAAA,IAAA,CAAQ,OAAiB,EAAC;AAE1B,IAAA,IAAA,CAAA,KAAA,GAAgC,IAAA;AAM9B,IAAA,YAAA,CAAa,MAAM,CAAA;AACnB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAI,GAAA,CAAI,MAAM,CAAA;AAAA,EAC5B;AAAA,EAEA,KAAK,GAAA,EAAkC;AACrC,IAAA,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA;AACxB,IAAA,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AACtB,IAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,IAAA,CAAK,MAAA,EAAQ;AACnC,MAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AACjB,MAAA,IAAA,CAAK,KAAK,KAAA,EAAM;AAAA,IAClB;AACA,IAAA,IAAI,KAAK,KAAA,CAAM,MAAA,GAAS,KAAK,MAAA,EAAQ,OAAQ,KAAK,KAAA,GAAQ,IAAA;AAC1D,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,GAAG,KAAK,KAAK,CAAA;AACjC,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,GAAG,KAAK,IAAI,CAAA;AAChC,IAAA,MAAM,CAAA,GAAI,OAAO,EAAA,GAAK,GAAA,GAAA,CAAQ,IAAI,KAAA,GAAQ,EAAA,KAAO,KAAK,EAAA,CAAA,GAAO,GAAA;AAC7D,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAC1B,IAAA,IAAI,CAAA,KAAM,IAAA,EAAM,OAAQ,IAAA,CAAK,KAAA,GAAQ,IAAA;AACrC,IAAA,OAAQ,IAAA,CAAK,KAAA,GAAQ,EAAE,CAAA,EAAG,CAAA,EAAE;AAAA,EAC9B;AACF;AASO,IAAM,aAAN,MAAiB;AAAA,EAQtB,WAAA,CACkB,MAAA,GAAS,EAAA,EACT,IAAA,GAAO,CAAA,EACvB;AAFgB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AARlB,IAAA,IAAA,CAAQ,SAAA,GAA2B,IAAA;AACnC,IAAA,IAAA,CAAQ,cAAA,GAAiB,CAAA;AACzB,IAAA,IAAA,CAAQ,cAAA,GAAiB,CAAA;AACzB,IAAA,IAAA,CAAQ,cAAA,GAAgC,IAAA;AACxC,IAAA,IAAA,CAAA,KAAA,GAAgC,IAAA;AAM9B,IAAA,IAAA,CAAK,GAAA,GAAM,IAAI,GAAA,CAAI,MAAM,CAAA;AAAA,EAC3B;AAAA,EAEA,KAAK,GAAA,EAAkC;AACrC,IAAA,MAAMC,IAAAA,GAAM,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAG,CAAA;AAC7B,IAAA,IAAIA,SAAQ,IAAA,EAAM;AAChB,MAAA,IAAA,CAAK,YAAY,GAAA,CAAI,KAAA;AACrB,MAAA,OAAQ,KAAK,KAAA,GAAQ,IAAA;AAAA,IACvB;AACA,IAAA,MAAM,GAAA,GAAA,CAAO,GAAA,CAAI,IAAA,GAAO,GAAA,CAAI,GAAA,IAAO,CAAA;AACnC,IAAA,MAAM,UAAA,GAAa,GAAA,GAAM,IAAA,CAAK,IAAA,GAAOA,IAAAA;AACrC,IAAA,MAAM,UAAA,GAAa,GAAA,GAAM,IAAA,CAAK,IAAA,GAAOA,IAAAA;AACrC,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,SAAA,IAAa,GAAA,CAAI,KAAA;AAEjC,IAAA,MAAM,KAAA,GAAQ,KAAK,cAAA,KAAmB,IAAA;AACtC,IAAA,MAAM,UAAA,GACJ,SAAS,UAAA,GAAa,IAAA,CAAK,kBAAkB,EAAA,GAAK,IAAA,CAAK,cAAA,GACnD,UAAA,GACA,IAAA,CAAK,cAAA;AACX,IAAA,MAAM,UAAA,GACJ,SAAS,UAAA,GAAa,IAAA,CAAK,kBAAkB,EAAA,GAAK,IAAA,CAAK,cAAA,GACnD,UAAA,GACA,IAAA,CAAK,cAAA;AAEX,IAAA,IAAI,EAAA;AACJ,IAAA,IAAI,SAAA;AACJ,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,SAAA,GAAY,GAAA,CAAI,KAAA,IAAS,UAAA,GAAa,EAAA,GAAK,CAAA;AAC3C,MAAA,EAAA,GAAK,SAAA,KAAc,KAAK,UAAA,GAAa,UAAA;AAAA,IACvC,CAAA,MAAA,IAAW,IAAA,CAAK,cAAA,KAAmB,IAAA,CAAK,cAAA,EAAgB;AACtD,MAAA,IAAI,GAAA,CAAI,SAAS,UAAA,EAAY;AAC3B,QAAA,EAAA,GAAK,UAAA;AACL,QAAA,SAAA,GAAY,EAAA;AAAA,MACd,CAAA,MAAO;AACL,QAAA,EAAA,GAAK,UAAA;AACL,QAAA,SAAA,GAAY,CAAA;AAAA,MACd;AAAA,IACF,CAAA,MAAO;AACL,MAAA,IAAI,GAAA,CAAI,SAAS,UAAA,EAAY;AAC3B,QAAA,EAAA,GAAK,UAAA;AACL,QAAA,SAAA,GAAY,CAAA;AAAA,MACd,CAAA,MAAO;AACL,QAAA,EAAA,GAAK,UAAA;AACL,QAAA,SAAA,GAAY,EAAA;AAAA,MACd;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,cAAA,GAAiB,UAAA;AACtB,IAAA,IAAA,CAAK,cAAA,GAAiB,UAAA;AACtB,IAAA,IAAA,CAAK,cAAA,GAAiB,EAAA;AACtB,IAAA,IAAA,CAAK,YAAY,GAAA,CAAI,KAAA;AACrB,IAAA,OAAQ,IAAA,CAAK,KAAA,GAAQ,EAAE,KAAA,EAAO,IAAI,SAAA,EAAU;AAAA,EAC9C;AACF;AASO,IAAM,MAAN,MAAU;AAAA,EAYf,WAAA,CAA4B,SAAS,EAAA,EAAI;AAAb,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAX5B,IAAA,IAAA,CAAQ,QAAA,GAA0B,IAAA;AAClC,IAAA,IAAA,CAAQ,OAAA,GAAU,CAAA;AAClB,IAAA,IAAA,CAAQ,SAAA,GAAY,CAAA;AACpB,IAAA,IAAA,CAAQ,IAAA,GAAO,CAAA;AACf,IAAA,IAAA,CAAQ,KAAA,GAAQ,CAAA;AAChB,IAAA,IAAA,CAAQ,KAAA,GAAQ,CAAA;AAChB,IAAA,IAAA,CAAQ,MAAgB,EAAC;AACzB,IAAA,IAAA,CAAQ,GAAA,GAAqB,IAAA;AAC7B,IAAA,IAAA,CAAQ,KAAA,GAAQ,CAAA;AAChB,IAAA,IAAA,CAAA,KAAA,GAAyB,IAAA;AAGvB,IAAA,YAAA,CAAa,MAAM,CAAA;AAAA,EACrB;AAAA,EAEA,KAAK,GAAA,EAA2B;AAC9B,IAAA,IAAI,IAAA,CAAK,aAAa,IAAA,EAAM;AAC1B,MAAA,IAAA,CAAK,WAAW,GAAA,CAAI,IAAA;AACpB,MAAA,IAAA,CAAK,UAAU,GAAA,CAAI,GAAA;AACnB,MAAA,IAAA,CAAK,YAAY,GAAA,CAAI,KAAA;AACrB,MAAA,OAAQ,KAAK,KAAA,GAAQ,IAAA;AAAA,IACvB;AACA,IAAA,MAAM,MAAA,GAAS,GAAA,CAAI,IAAA,GAAO,IAAA,CAAK,QAAA;AAC/B,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,OAAA,GAAU,GAAA,CAAI,GAAA;AACpC,IAAA,MAAM,GAAA,GAAM,MAAA,GAAS,QAAA,IAAY,MAAA,GAAS,IAAI,MAAA,GAAS,CAAA;AACvD,IAAA,MAAM,GAAA,GAAM,QAAA,GAAW,MAAA,IAAU,QAAA,GAAW,IAAI,QAAA,GAAW,CAAA;AAC3D,IAAA,MAAM,KAAK,IAAA,CAAK,GAAA;AAAA,MACd,GAAA,CAAI,OAAO,GAAA,CAAI,GAAA;AAAA,MACf,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,IAAA,GAAO,KAAK,SAAS,CAAA;AAAA,MAClC,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAA,GAAM,KAAK,SAAS;AAAA,KACnC;AACA,IAAA,IAAA,CAAK,WAAW,GAAA,CAAI,IAAA;AACpB,IAAA,IAAA,CAAK,UAAU,GAAA,CAAI,GAAA;AACnB,IAAA,IAAA,CAAK,YAAY,GAAA,CAAI,KAAA;AACrB,IAAA,IAAA,CAAK,KAAA,EAAA;AAEL,IAAA,IAAI,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,MAAA,EAAQ;AAC7B,MAAA,IAAA,CAAK,IAAA,IAAQ,EAAA;AACb,MAAA,IAAA,CAAK,KAAA,IAAS,GAAA;AACd,MAAA,IAAA,CAAK,KAAA,IAAS,GAAA;AACd,MAAA,IAAI,KAAK,KAAA,GAAQ,IAAA,CAAK,MAAA,EAAQ,OAAQ,KAAK,KAAA,GAAQ,IAAA;AAAA,IACrD,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,GAAO,KAAK,MAAA,GAAS,EAAA;AAClD,MAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,KAAA,GAAQ,KAAK,MAAA,GAAS,GAAA;AACrD,MAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,KAAA,GAAQ,KAAK,MAAA,GAAS,GAAA;AAAA,IACvD;AAEA,IAAA,MAAM,MAAA,GAAS,KAAK,IAAA,KAAS,CAAA,GAAI,IAAK,GAAA,GAAM,IAAA,CAAK,QAAS,IAAA,CAAK,IAAA;AAC/D,IAAA,MAAM,OAAA,GAAU,KAAK,IAAA,KAAS,CAAA,GAAI,IAAK,GAAA,GAAM,IAAA,CAAK,QAAS,IAAA,CAAK,IAAA;AAChE,IAAA,MAAM,QAAQ,MAAA,GAAS,OAAA;AACvB,IAAA,MAAM,EAAA,GAAK,UAAU,CAAA,GAAI,CAAA,GAAK,MAAM,IAAA,CAAK,GAAA,CAAI,MAAA,GAAS,OAAO,CAAA,GAAK,KAAA;AAElE,IAAA,IAAI,IAAA,CAAK,QAAQ,IAAA,EAAM;AACrB,MAAA,IAAA,CAAK,GAAA,CAAI,KAAK,EAAE,CAAA;AAChB,MAAA,IAAI,KAAK,GAAA,CAAI,MAAA,GAAS,KAAK,MAAA,EAAQ,OAAQ,KAAK,KAAA,GAAQ,IAAA;AACxD,MAAA,IAAA,CAAK,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAA,EAAG,CAAC,CAAA,GAAI,IAAA,CAAK,MAAA;AAAA,IACxD,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,GAAA,IAAO,KAAK,MAAA,GAAS,CAAA,CAAA,GAAK,MAAM,IAAA,CAAK,MAAA;AAAA,IACxD;AACA,IAAA,OAAQ,KAAK,KAAA,GAAQ,EAAE,KAAK,IAAA,CAAK,GAAA,EAAK,QAAQ,OAAA,EAAQ;AAAA,EACxD;AACF;AAOA,SAAS,SAAA,CACP,KACA,MAAA,EACmB;AACnB,EAAA,OAAO,OAAO,GAAA,CAAI,CAAC,MAAM,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA;AACtC;AAEO,IAAM,GAAA,GAAM,CAAC,MAAA,EAAkB,MAAA,KAAmB,UAAU,IAAI,GAAA,CAAI,MAAM,CAAA,EAAG,MAAM;AACnF,IAAM,GAAA,GAAM,CAAC,MAAA,EAAkB,MAAA,KAAmB,UAAU,IAAI,GAAA,CAAI,MAAM,CAAA,EAAG,MAAM;AACnF,IAAM,GAAA,GAAM,CAAC,MAAA,EAAkB,MAAA,KAAmB,UAAU,IAAI,GAAA,CAAI,MAAM,CAAA,EAAG,MAAM;AACnF,IAAM,GAAA,GAAM,CAAC,MAAA,EAAkB,MAAA,GAAS,EAAA,KAAO,UAAU,IAAI,GAAA,CAAI,MAAM,CAAA,EAAG,MAAM;AAEhF,SAAS,KAAK,MAAA,EAAkB,IAAA,GAAO,IAAI,IAAA,GAAO,EAAA,EAAI,SAAS,CAAA,EAAyB;AAC7F,EAAA,MAAM,GAAA,GAAM,IAAI,IAAA,CAAK,IAAA,EAAM,MAAM,MAAM,CAAA;AACvC,EAAA,OAAO,OAAO,GAAA,CAAI,CAAC,MAAM,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA;AACtC;AAEO,SAAS,SAAA,CAAU,MAAA,EAAkB,MAAA,GAAS,EAAA,EAAI,OAAO,CAAA,EAA8B;AAC5F,EAAA,MAAM,GAAA,GAAM,IAAI,cAAA,CAAe,MAAA,EAAQ,IAAI,CAAA;AAC3C,EAAA,OAAO,OAAO,GAAA,CAAI,CAAC,MAAM,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA;AACtC;AAEO,SAAS,GAAA,CAAI,IAAA,EAAa,MAAA,GAAS,EAAA,EAAuB;AAC/D,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,MAAM,CAAA;AAC1B,EAAA,OAAO,KAAK,GAAA,CAAI,CAAC,MAAM,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA;AACpC;AAEO,SAAS,UAAA,CAAW,IAAA,EAAa,MAAA,GAAS,EAAA,EAAI,OAAO,CAAA,EAA+B;AACzF,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,MAAA,EAAQ,IAAI,CAAA;AACvC,EAAA,OAAO,KAAK,GAAA,CAAI,CAAC,MAAM,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA;AACpC;AAEO,SAAS,GAAA,CAAI,IAAA,EAAa,MAAA,GAAS,EAAA,EAAyB;AACjE,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,MAAM,CAAA;AAC1B,EAAA,OAAO,KAAK,GAAA,CAAI,CAAC,MAAM,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA;AACpC;AAOO,SAAS,YAAA,CACd,MACA,IAAA,EACS;AACT,EAAA,OAAO,KAAK,CAAA,IAAK,IAAA,CAAK,CAAA,IAAK,IAAA,CAAK,IAAI,IAAA,CAAK,CAAA;AAC3C;AAGO,SAAS,YAAA,CACd,MACA,IAAA,EACS;AACT,EAAA,OAAO,KAAK,CAAA,IAAK,IAAA,CAAK,CAAA,IAAK,IAAA,CAAK,IAAI,IAAA,CAAK,CAAA;AAC3C","file":"index.cjs","sourcesContent":["/**\n * @lacspace/indicators\n * Streaming technical indicators for stock-market apps.\n *\n * Every indicator is a small class with an incremental `next()` that updates in\n * O(1) (or O(period) for window-based ones) — push one live tick, get the new\n * value, without recomputing the whole series. Perfect for live LTP feeds.\n *\n * Zero dependencies · isomorphic · fully typed.\n */\n\nexport interface Candle {\n open: number;\n high: number;\n low: number;\n close: number;\n volume?: number;\n time?: number;\n}\n\n/** A high/low/close bar — the minimum most range-based indicators need. */\nexport interface HLC {\n high: number;\n low: number;\n close: number;\n}\n\nfunction assertPeriod(period: number): void {\n if (!Number.isInteger(period) || period < 1) {\n throw new RangeError(`period must be a positive integer, got ${period}`);\n }\n}\n\n/** Simple Moving Average. Incremental O(1) using a running window sum. */\nexport class SMA {\n private buf: number[] = [];\n private sum = 0;\n /** Latest value, or `null` until `period` samples have been seen. */\n value: number | null = null;\n\n constructor(public readonly period: number) {\n assertPeriod(period);\n }\n\n next(price: number): number | null {\n this.buf.push(price);\n this.sum += price;\n if (this.buf.length > this.period) this.sum -= this.buf.shift()!;\n this.value = this.buf.length === this.period ? this.sum / this.period : null;\n return this.value;\n }\n}\n\n/** Exponential Moving Average. Seeded with an SMA of the first `period` values. */\nexport class EMA {\n private readonly k: number;\n private seed: number[] = [];\n private ema: number | null = null;\n value: number | null = null;\n\n constructor(public readonly period: number) {\n assertPeriod(period);\n this.k = 2 / (period + 1);\n }\n\n next(price: number): number | null {\n if (this.ema === null) {\n this.seed.push(price);\n if (this.seed.length < this.period) return (this.value = null);\n this.ema = this.seed.reduce((a, b) => a + b, 0) / this.period;\n } else {\n this.ema = price * this.k + this.ema * (1 - this.k);\n }\n return (this.value = this.ema);\n }\n}\n\n/** Weighted Moving Average — recent samples weighted linearly higher. */\nexport class WMA {\n private buf: number[] = [];\n value: number | null = null;\n\n constructor(public readonly period: number) {\n assertPeriod(period);\n }\n\n next(price: number): number | null {\n this.buf.push(price);\n if (this.buf.length > this.period) this.buf.shift();\n if (this.buf.length < this.period) return (this.value = null);\n let num = 0;\n let den = 0;\n for (let i = 0; i < this.period; i++) {\n const w = i + 1;\n num += this.buf[i]! * w;\n den += w;\n }\n return (this.value = num / den);\n }\n}\n\n/** Relative Strength Index (Wilder's smoothing). O(1) per tick. */\nexport class RSI {\n private prev: number | null = null;\n private avgGain = 0;\n private avgLoss = 0;\n private count = 0;\n value: number | null = null;\n\n constructor(public readonly period: number = 14) {\n assertPeriod(period);\n }\n\n next(price: number): number | null {\n if (this.prev === null) {\n this.prev = price;\n return (this.value = null);\n }\n const change = price - this.prev;\n this.prev = price;\n const gain = change > 0 ? change : 0;\n const loss = change < 0 ? -change : 0;\n this.count++;\n\n if (this.count <= this.period) {\n this.avgGain += gain;\n this.avgLoss += loss;\n if (this.count < this.period) return (this.value = null);\n this.avgGain /= this.period;\n this.avgLoss /= this.period;\n } else {\n this.avgGain = (this.avgGain * (this.period - 1) + gain) / this.period;\n this.avgLoss = (this.avgLoss * (this.period - 1) + loss) / this.period;\n }\n return (this.value = this.compute());\n }\n\n private compute(): number {\n if (this.avgLoss === 0) return 100;\n const rs = this.avgGain / this.avgLoss;\n return 100 - 100 / (1 + rs);\n }\n}\n\nexport interface MACDValue {\n macd: number;\n signal: number;\n histogram: number;\n}\n\n/** Moving Average Convergence Divergence. Defaults 12 / 26 / 9. */\nexport class MACD {\n private readonly fastEma: EMA;\n private readonly slowEma: EMA;\n private readonly signalEma: EMA;\n value: MACDValue | null = null;\n\n constructor(fast = 12, slow = 26, signal = 9) {\n this.fastEma = new EMA(fast);\n this.slowEma = new EMA(slow);\n this.signalEma = new EMA(signal);\n }\n\n next(price: number): MACDValue | null {\n const f = this.fastEma.next(price);\n const s = this.slowEma.next(price);\n if (f === null || s === null) return (this.value = null);\n const macd = f - s;\n const signal = this.signalEma.next(macd);\n if (signal === null) return (this.value = null);\n return (this.value = { macd, signal, histogram: macd - signal });\n }\n}\n\nexport interface BollingerValue {\n middle: number;\n upper: number;\n lower: number;\n /** (upper - lower) / middle — normalised band width. */\n bandwidth: number;\n}\n\n/** Bollinger Bands — SMA middle band ± `mult` standard deviations. */\nexport class BollingerBands {\n private buf: number[] = [];\n private sum = 0;\n value: BollingerValue | null = null;\n\n constructor(\n public readonly period = 20,\n public readonly mult = 2,\n ) {\n assertPeriod(period);\n }\n\n next(price: number): BollingerValue | null {\n this.buf.push(price);\n this.sum += price;\n if (this.buf.length > this.period) this.sum -= this.buf.shift()!;\n if (this.buf.length < this.period) return (this.value = null);\n const mean = this.sum / this.period;\n let variance = 0;\n for (const v of this.buf) variance += (v - mean) ** 2;\n const sd = Math.sqrt(variance / this.period);\n const upper = mean + this.mult * sd;\n const lower = mean - this.mult * sd;\n return (this.value = {\n middle: mean,\n upper,\n lower,\n bandwidth: mean === 0 ? 0 : (upper - lower) / mean,\n });\n }\n}\n\n/** Average True Range (Wilder). Feed it high/low/close bars. */\nexport class ATR {\n private prevClose: number | null = null;\n private atr: number | null = null;\n private seed: number[] = [];\n value: number | null = null;\n\n constructor(public readonly period = 14) {\n assertPeriod(period);\n }\n\n next(bar: HLC): number | null {\n const tr =\n this.prevClose === null\n ? bar.high - bar.low\n : Math.max(\n bar.high - bar.low,\n Math.abs(bar.high - this.prevClose),\n Math.abs(bar.low - this.prevClose),\n );\n this.prevClose = bar.close;\n\n if (this.atr === null) {\n this.seed.push(tr);\n if (this.seed.length < this.period) return (this.value = null);\n this.atr = this.seed.reduce((a, b) => a + b, 0) / this.period;\n return (this.value = this.atr);\n }\n this.atr = (this.atr * (this.period - 1) + tr) / this.period;\n return (this.value = this.atr);\n }\n}\n\n/** Volume-Weighted Average Price. Cumulative — call `reset()` per session. */\nexport class VWAP {\n private pv = 0;\n private vol = 0;\n value: number | null = null;\n\n next(bar: Required<Pick<Candle, \"high\" | \"low\" | \"close\" | \"volume\">>): number | null {\n const typical = (bar.high + bar.low + bar.close) / 3;\n this.pv += typical * bar.volume;\n this.vol += bar.volume;\n return (this.value = this.vol === 0 ? null : this.pv / this.vol);\n }\n\n reset(): void {\n this.pv = 0;\n this.vol = 0;\n this.value = null;\n }\n}\n\nexport interface StochasticValue {\n /** %K — position of close within the recent high/low range (0–100). */\n k: number;\n /** %D — SMA of %K. */\n d: number;\n}\n\n/** Stochastic Oscillator (%K / %D). */\nexport class Stochastic {\n private highs: number[] = [];\n private lows: number[] = [];\n private readonly dSma: SMA;\n value: StochasticValue | null = null;\n\n constructor(\n public readonly period = 14,\n public readonly signal = 3,\n ) {\n assertPeriod(period);\n this.dSma = new SMA(signal);\n }\n\n next(bar: HLC): StochasticValue | null {\n this.highs.push(bar.high);\n this.lows.push(bar.low);\n if (this.highs.length > this.period) {\n this.highs.shift();\n this.lows.shift();\n }\n if (this.highs.length < this.period) return (this.value = null);\n const hh = Math.max(...this.highs);\n const ll = Math.min(...this.lows);\n const k = hh === ll ? 100 : ((bar.close - ll) / (hh - ll)) * 100;\n const d = this.dSma.next(k);\n if (d === null) return (this.value = null);\n return (this.value = { k, d });\n }\n}\n\nexport interface SupertrendValue {\n value: number;\n /** 1 = uptrend (price above band), -1 = downtrend. */\n direction: 1 | -1;\n}\n\n/** Supertrend — ATR-based trend follower. Defaults period 10, multiplier 3. */\nexport class Supertrend {\n private readonly atr: ATR;\n private prevClose: number | null = null;\n private prevFinalUpper = 0;\n private prevFinalLower = 0;\n private prevSupertrend: number | null = null;\n value: SupertrendValue | null = null;\n\n constructor(\n public readonly period = 10,\n public readonly mult = 3,\n ) {\n this.atr = new ATR(period);\n }\n\n next(bar: HLC): SupertrendValue | null {\n const atr = this.atr.next(bar);\n if (atr === null) {\n this.prevClose = bar.close;\n return (this.value = null);\n }\n const hl2 = (bar.high + bar.low) / 2;\n const basicUpper = hl2 + this.mult * atr;\n const basicLower = hl2 - this.mult * atr;\n const pc = this.prevClose ?? bar.close;\n\n const first = this.prevSupertrend === null;\n const finalUpper =\n first || basicUpper < this.prevFinalUpper || pc > this.prevFinalUpper\n ? basicUpper\n : this.prevFinalUpper;\n const finalLower =\n first || basicLower > this.prevFinalLower || pc < this.prevFinalLower\n ? basicLower\n : this.prevFinalLower;\n\n let st: number;\n let direction: 1 | -1;\n if (first) {\n direction = bar.close <= finalUpper ? -1 : 1;\n st = direction === -1 ? finalUpper : finalLower;\n } else if (this.prevSupertrend === this.prevFinalUpper) {\n if (bar.close <= finalUpper) {\n st = finalUpper;\n direction = -1;\n } else {\n st = finalLower;\n direction = 1;\n }\n } else {\n if (bar.close >= finalLower) {\n st = finalLower;\n direction = 1;\n } else {\n st = finalUpper;\n direction = -1;\n }\n }\n\n this.prevFinalUpper = finalUpper;\n this.prevFinalLower = finalLower;\n this.prevSupertrend = st;\n this.prevClose = bar.close;\n return (this.value = { value: st, direction });\n }\n}\n\nexport interface ADXValue {\n adx: number;\n plusDI: number;\n minusDI: number;\n}\n\n/** Average Directional Index with +DI / -DI (Wilder). */\nexport class ADX {\n private prevHigh: number | null = null;\n private prevLow = 0;\n private prevClose = 0;\n private smTR = 0;\n private smPDM = 0;\n private smMDM = 0;\n private dxs: number[] = [];\n private adx: number | null = null;\n private count = 0;\n value: ADXValue | null = null;\n\n constructor(public readonly period = 14) {\n assertPeriod(period);\n }\n\n next(bar: HLC): ADXValue | null {\n if (this.prevHigh === null) {\n this.prevHigh = bar.high;\n this.prevLow = bar.low;\n this.prevClose = bar.close;\n return (this.value = null);\n }\n const upMove = bar.high - this.prevHigh;\n const downMove = this.prevLow - bar.low;\n const pdm = upMove > downMove && upMove > 0 ? upMove : 0;\n const mdm = downMove > upMove && downMove > 0 ? downMove : 0;\n const tr = Math.max(\n bar.high - bar.low,\n Math.abs(bar.high - this.prevClose),\n Math.abs(bar.low - this.prevClose),\n );\n this.prevHigh = bar.high;\n this.prevLow = bar.low;\n this.prevClose = bar.close;\n this.count++;\n\n if (this.count <= this.period) {\n this.smTR += tr;\n this.smPDM += pdm;\n this.smMDM += mdm;\n if (this.count < this.period) return (this.value = null);\n } else {\n this.smTR = this.smTR - this.smTR / this.period + tr;\n this.smPDM = this.smPDM - this.smPDM / this.period + pdm;\n this.smMDM = this.smMDM - this.smMDM / this.period + mdm;\n }\n\n const plusDI = this.smTR === 0 ? 0 : (100 * this.smPDM) / this.smTR;\n const minusDI = this.smTR === 0 ? 0 : (100 * this.smMDM) / this.smTR;\n const diSum = plusDI + minusDI;\n const dx = diSum === 0 ? 0 : (100 * Math.abs(plusDI - minusDI)) / diSum;\n\n if (this.adx === null) {\n this.dxs.push(dx);\n if (this.dxs.length < this.period) return (this.value = null);\n this.adx = this.dxs.reduce((a, b) => a + b, 0) / this.period;\n } else {\n this.adx = (this.adx * (this.period - 1) + dx) / this.period;\n }\n return (this.value = { adx: this.adx, plusDI, minusDI });\n }\n}\n\n/* ------------------------------------------------------------------ *\n * Batch helpers — run an indicator over an existing array in one call.\n * Each returns an array aligned to the input (nulls during warm-up).\n * ------------------------------------------------------------------ */\n\nfunction runNumber<T extends { next(v: number): number | null }>(\n ind: T,\n values: number[],\n): (number | null)[] {\n return values.map((v) => ind.next(v));\n}\n\nexport const sma = (values: number[], period: number) => runNumber(new SMA(period), values);\nexport const ema = (values: number[], period: number) => runNumber(new EMA(period), values);\nexport const wma = (values: number[], period: number) => runNumber(new WMA(period), values);\nexport const rsi = (values: number[], period = 14) => runNumber(new RSI(period), values);\n\nexport function macd(values: number[], fast = 12, slow = 26, signal = 9): (MACDValue | null)[] {\n const ind = new MACD(fast, slow, signal);\n return values.map((v) => ind.next(v));\n}\n\nexport function bollinger(values: number[], period = 20, mult = 2): (BollingerValue | null)[] {\n const ind = new BollingerBands(period, mult);\n return values.map((v) => ind.next(v));\n}\n\nexport function atr(bars: HLC[], period = 14): (number | null)[] {\n const ind = new ATR(period);\n return bars.map((b) => ind.next(b));\n}\n\nexport function supertrend(bars: HLC[], period = 10, mult = 3): (SupertrendValue | null)[] {\n const ind = new Supertrend(period, mult);\n return bars.map((b) => ind.next(b));\n}\n\nexport function adx(bars: HLC[], period = 14): (ADXValue | null)[] {\n const ind = new ADX(period);\n return bars.map((b) => ind.next(b));\n}\n\n/* ------------------------------------------------------------------ *\n * Crossover helpers — the backbone of most signal logic.\n * ------------------------------------------------------------------ */\n\n/** True when series A crossed from at-or-below B to strictly above B. */\nexport function crossedAbove(\n prev: { a: number; b: number },\n curr: { a: number; b: number },\n): boolean {\n return prev.a <= prev.b && curr.a > curr.b;\n}\n\n/** True when series A crossed from at-or-above B to strictly below B. */\nexport function crossedBelow(\n prev: { a: number; b: number },\n curr: { a: number; b: number },\n): boolean {\n return prev.a >= prev.b && curr.a < curr.b;\n}\n"]}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * @lacspace/indicators
3
+ * Streaming technical indicators for stock-market apps.
4
+ *
5
+ * Every indicator is a small class with an incremental `next()` that updates in
6
+ * O(1) (or O(period) for window-based ones) — push one live tick, get the new
7
+ * value, without recomputing the whole series. Perfect for live LTP feeds.
8
+ *
9
+ * Zero dependencies · isomorphic · fully typed.
10
+ */
11
+ interface Candle {
12
+ open: number;
13
+ high: number;
14
+ low: number;
15
+ close: number;
16
+ volume?: number;
17
+ time?: number;
18
+ }
19
+ /** A high/low/close bar — the minimum most range-based indicators need. */
20
+ interface HLC {
21
+ high: number;
22
+ low: number;
23
+ close: number;
24
+ }
25
+ /** Simple Moving Average. Incremental O(1) using a running window sum. */
26
+ declare class SMA {
27
+ readonly period: number;
28
+ private buf;
29
+ private sum;
30
+ /** Latest value, or `null` until `period` samples have been seen. */
31
+ value: number | null;
32
+ constructor(period: number);
33
+ next(price: number): number | null;
34
+ }
35
+ /** Exponential Moving Average. Seeded with an SMA of the first `period` values. */
36
+ declare class EMA {
37
+ readonly period: number;
38
+ private readonly k;
39
+ private seed;
40
+ private ema;
41
+ value: number | null;
42
+ constructor(period: number);
43
+ next(price: number): number | null;
44
+ }
45
+ /** Weighted Moving Average — recent samples weighted linearly higher. */
46
+ declare class WMA {
47
+ readonly period: number;
48
+ private buf;
49
+ value: number | null;
50
+ constructor(period: number);
51
+ next(price: number): number | null;
52
+ }
53
+ /** Relative Strength Index (Wilder's smoothing). O(1) per tick. */
54
+ declare class RSI {
55
+ readonly period: number;
56
+ private prev;
57
+ private avgGain;
58
+ private avgLoss;
59
+ private count;
60
+ value: number | null;
61
+ constructor(period?: number);
62
+ next(price: number): number | null;
63
+ private compute;
64
+ }
65
+ interface MACDValue {
66
+ macd: number;
67
+ signal: number;
68
+ histogram: number;
69
+ }
70
+ /** Moving Average Convergence Divergence. Defaults 12 / 26 / 9. */
71
+ declare class MACD {
72
+ private readonly fastEma;
73
+ private readonly slowEma;
74
+ private readonly signalEma;
75
+ value: MACDValue | null;
76
+ constructor(fast?: number, slow?: number, signal?: number);
77
+ next(price: number): MACDValue | null;
78
+ }
79
+ interface BollingerValue {
80
+ middle: number;
81
+ upper: number;
82
+ lower: number;
83
+ /** (upper - lower) / middle — normalised band width. */
84
+ bandwidth: number;
85
+ }
86
+ /** Bollinger Bands — SMA middle band ± `mult` standard deviations. */
87
+ declare class BollingerBands {
88
+ readonly period: number;
89
+ readonly mult: number;
90
+ private buf;
91
+ private sum;
92
+ value: BollingerValue | null;
93
+ constructor(period?: number, mult?: number);
94
+ next(price: number): BollingerValue | null;
95
+ }
96
+ /** Average True Range (Wilder). Feed it high/low/close bars. */
97
+ declare class ATR {
98
+ readonly period: number;
99
+ private prevClose;
100
+ private atr;
101
+ private seed;
102
+ value: number | null;
103
+ constructor(period?: number);
104
+ next(bar: HLC): number | null;
105
+ }
106
+ /** Volume-Weighted Average Price. Cumulative — call `reset()` per session. */
107
+ declare class VWAP {
108
+ private pv;
109
+ private vol;
110
+ value: number | null;
111
+ next(bar: Required<Pick<Candle, "high" | "low" | "close" | "volume">>): number | null;
112
+ reset(): void;
113
+ }
114
+ interface StochasticValue {
115
+ /** %K — position of close within the recent high/low range (0–100). */
116
+ k: number;
117
+ /** %D — SMA of %K. */
118
+ d: number;
119
+ }
120
+ /** Stochastic Oscillator (%K / %D). */
121
+ declare class Stochastic {
122
+ readonly period: number;
123
+ readonly signal: number;
124
+ private highs;
125
+ private lows;
126
+ private readonly dSma;
127
+ value: StochasticValue | null;
128
+ constructor(period?: number, signal?: number);
129
+ next(bar: HLC): StochasticValue | null;
130
+ }
131
+ interface SupertrendValue {
132
+ value: number;
133
+ /** 1 = uptrend (price above band), -1 = downtrend. */
134
+ direction: 1 | -1;
135
+ }
136
+ /** Supertrend — ATR-based trend follower. Defaults period 10, multiplier 3. */
137
+ declare class Supertrend {
138
+ readonly period: number;
139
+ readonly mult: number;
140
+ private readonly atr;
141
+ private prevClose;
142
+ private prevFinalUpper;
143
+ private prevFinalLower;
144
+ private prevSupertrend;
145
+ value: SupertrendValue | null;
146
+ constructor(period?: number, mult?: number);
147
+ next(bar: HLC): SupertrendValue | null;
148
+ }
149
+ interface ADXValue {
150
+ adx: number;
151
+ plusDI: number;
152
+ minusDI: number;
153
+ }
154
+ /** Average Directional Index with +DI / -DI (Wilder). */
155
+ declare class ADX {
156
+ readonly period: number;
157
+ private prevHigh;
158
+ private prevLow;
159
+ private prevClose;
160
+ private smTR;
161
+ private smPDM;
162
+ private smMDM;
163
+ private dxs;
164
+ private adx;
165
+ private count;
166
+ value: ADXValue | null;
167
+ constructor(period?: number);
168
+ next(bar: HLC): ADXValue | null;
169
+ }
170
+ declare const sma: (values: number[], period: number) => (number | null)[];
171
+ declare const ema: (values: number[], period: number) => (number | null)[];
172
+ declare const wma: (values: number[], period: number) => (number | null)[];
173
+ declare const rsi: (values: number[], period?: number) => (number | null)[];
174
+ declare function macd(values: number[], fast?: number, slow?: number, signal?: number): (MACDValue | null)[];
175
+ declare function bollinger(values: number[], period?: number, mult?: number): (BollingerValue | null)[];
176
+ declare function atr(bars: HLC[], period?: number): (number | null)[];
177
+ declare function supertrend(bars: HLC[], period?: number, mult?: number): (SupertrendValue | null)[];
178
+ declare function adx(bars: HLC[], period?: number): (ADXValue | null)[];
179
+ /** True when series A crossed from at-or-below B to strictly above B. */
180
+ declare function crossedAbove(prev: {
181
+ a: number;
182
+ b: number;
183
+ }, curr: {
184
+ a: number;
185
+ b: number;
186
+ }): boolean;
187
+ /** True when series A crossed from at-or-above B to strictly below B. */
188
+ declare function crossedBelow(prev: {
189
+ a: number;
190
+ b: number;
191
+ }, curr: {
192
+ a: number;
193
+ b: number;
194
+ }): boolean;
195
+
196
+ export { ADX, type ADXValue, ATR, BollingerBands, type BollingerValue, type Candle, EMA, type HLC, MACD, type MACDValue, RSI, SMA, Stochastic, type StochasticValue, Supertrend, type SupertrendValue, VWAP, WMA, adx, atr, bollinger, crossedAbove, crossedBelow, ema, macd, rsi, sma, supertrend, wma };
@@ -0,0 +1,196 @@
1
+ /**
2
+ * @lacspace/indicators
3
+ * Streaming technical indicators for stock-market apps.
4
+ *
5
+ * Every indicator is a small class with an incremental `next()` that updates in
6
+ * O(1) (or O(period) for window-based ones) — push one live tick, get the new
7
+ * value, without recomputing the whole series. Perfect for live LTP feeds.
8
+ *
9
+ * Zero dependencies · isomorphic · fully typed.
10
+ */
11
+ interface Candle {
12
+ open: number;
13
+ high: number;
14
+ low: number;
15
+ close: number;
16
+ volume?: number;
17
+ time?: number;
18
+ }
19
+ /** A high/low/close bar — the minimum most range-based indicators need. */
20
+ interface HLC {
21
+ high: number;
22
+ low: number;
23
+ close: number;
24
+ }
25
+ /** Simple Moving Average. Incremental O(1) using a running window sum. */
26
+ declare class SMA {
27
+ readonly period: number;
28
+ private buf;
29
+ private sum;
30
+ /** Latest value, or `null` until `period` samples have been seen. */
31
+ value: number | null;
32
+ constructor(period: number);
33
+ next(price: number): number | null;
34
+ }
35
+ /** Exponential Moving Average. Seeded with an SMA of the first `period` values. */
36
+ declare class EMA {
37
+ readonly period: number;
38
+ private readonly k;
39
+ private seed;
40
+ private ema;
41
+ value: number | null;
42
+ constructor(period: number);
43
+ next(price: number): number | null;
44
+ }
45
+ /** Weighted Moving Average — recent samples weighted linearly higher. */
46
+ declare class WMA {
47
+ readonly period: number;
48
+ private buf;
49
+ value: number | null;
50
+ constructor(period: number);
51
+ next(price: number): number | null;
52
+ }
53
+ /** Relative Strength Index (Wilder's smoothing). O(1) per tick. */
54
+ declare class RSI {
55
+ readonly period: number;
56
+ private prev;
57
+ private avgGain;
58
+ private avgLoss;
59
+ private count;
60
+ value: number | null;
61
+ constructor(period?: number);
62
+ next(price: number): number | null;
63
+ private compute;
64
+ }
65
+ interface MACDValue {
66
+ macd: number;
67
+ signal: number;
68
+ histogram: number;
69
+ }
70
+ /** Moving Average Convergence Divergence. Defaults 12 / 26 / 9. */
71
+ declare class MACD {
72
+ private readonly fastEma;
73
+ private readonly slowEma;
74
+ private readonly signalEma;
75
+ value: MACDValue | null;
76
+ constructor(fast?: number, slow?: number, signal?: number);
77
+ next(price: number): MACDValue | null;
78
+ }
79
+ interface BollingerValue {
80
+ middle: number;
81
+ upper: number;
82
+ lower: number;
83
+ /** (upper - lower) / middle — normalised band width. */
84
+ bandwidth: number;
85
+ }
86
+ /** Bollinger Bands — SMA middle band ± `mult` standard deviations. */
87
+ declare class BollingerBands {
88
+ readonly period: number;
89
+ readonly mult: number;
90
+ private buf;
91
+ private sum;
92
+ value: BollingerValue | null;
93
+ constructor(period?: number, mult?: number);
94
+ next(price: number): BollingerValue | null;
95
+ }
96
+ /** Average True Range (Wilder). Feed it high/low/close bars. */
97
+ declare class ATR {
98
+ readonly period: number;
99
+ private prevClose;
100
+ private atr;
101
+ private seed;
102
+ value: number | null;
103
+ constructor(period?: number);
104
+ next(bar: HLC): number | null;
105
+ }
106
+ /** Volume-Weighted Average Price. Cumulative — call `reset()` per session. */
107
+ declare class VWAP {
108
+ private pv;
109
+ private vol;
110
+ value: number | null;
111
+ next(bar: Required<Pick<Candle, "high" | "low" | "close" | "volume">>): number | null;
112
+ reset(): void;
113
+ }
114
+ interface StochasticValue {
115
+ /** %K — position of close within the recent high/low range (0–100). */
116
+ k: number;
117
+ /** %D — SMA of %K. */
118
+ d: number;
119
+ }
120
+ /** Stochastic Oscillator (%K / %D). */
121
+ declare class Stochastic {
122
+ readonly period: number;
123
+ readonly signal: number;
124
+ private highs;
125
+ private lows;
126
+ private readonly dSma;
127
+ value: StochasticValue | null;
128
+ constructor(period?: number, signal?: number);
129
+ next(bar: HLC): StochasticValue | null;
130
+ }
131
+ interface SupertrendValue {
132
+ value: number;
133
+ /** 1 = uptrend (price above band), -1 = downtrend. */
134
+ direction: 1 | -1;
135
+ }
136
+ /** Supertrend — ATR-based trend follower. Defaults period 10, multiplier 3. */
137
+ declare class Supertrend {
138
+ readonly period: number;
139
+ readonly mult: number;
140
+ private readonly atr;
141
+ private prevClose;
142
+ private prevFinalUpper;
143
+ private prevFinalLower;
144
+ private prevSupertrend;
145
+ value: SupertrendValue | null;
146
+ constructor(period?: number, mult?: number);
147
+ next(bar: HLC): SupertrendValue | null;
148
+ }
149
+ interface ADXValue {
150
+ adx: number;
151
+ plusDI: number;
152
+ minusDI: number;
153
+ }
154
+ /** Average Directional Index with +DI / -DI (Wilder). */
155
+ declare class ADX {
156
+ readonly period: number;
157
+ private prevHigh;
158
+ private prevLow;
159
+ private prevClose;
160
+ private smTR;
161
+ private smPDM;
162
+ private smMDM;
163
+ private dxs;
164
+ private adx;
165
+ private count;
166
+ value: ADXValue | null;
167
+ constructor(period?: number);
168
+ next(bar: HLC): ADXValue | null;
169
+ }
170
+ declare const sma: (values: number[], period: number) => (number | null)[];
171
+ declare const ema: (values: number[], period: number) => (number | null)[];
172
+ declare const wma: (values: number[], period: number) => (number | null)[];
173
+ declare const rsi: (values: number[], period?: number) => (number | null)[];
174
+ declare function macd(values: number[], fast?: number, slow?: number, signal?: number): (MACDValue | null)[];
175
+ declare function bollinger(values: number[], period?: number, mult?: number): (BollingerValue | null)[];
176
+ declare function atr(bars: HLC[], period?: number): (number | null)[];
177
+ declare function supertrend(bars: HLC[], period?: number, mult?: number): (SupertrendValue | null)[];
178
+ declare function adx(bars: HLC[], period?: number): (ADXValue | null)[];
179
+ /** True when series A crossed from at-or-below B to strictly above B. */
180
+ declare function crossedAbove(prev: {
181
+ a: number;
182
+ b: number;
183
+ }, curr: {
184
+ a: number;
185
+ b: number;
186
+ }): boolean;
187
+ /** True when series A crossed from at-or-above B to strictly below B. */
188
+ declare function crossedBelow(prev: {
189
+ a: number;
190
+ b: number;
191
+ }, curr: {
192
+ a: number;
193
+ b: number;
194
+ }): boolean;
195
+
196
+ export { ADX, type ADXValue, ATR, BollingerBands, type BollingerValue, type Candle, EMA, type HLC, MACD, type MACDValue, RSI, SMA, Stochastic, type StochasticValue, Supertrend, type SupertrendValue, VWAP, WMA, adx, atr, bollinger, crossedAbove, crossedBelow, ema, macd, rsi, sma, supertrend, wma };
package/dist/index.js ADDED
@@ -0,0 +1,366 @@
1
+ // src/index.ts
2
+ function assertPeriod(period) {
3
+ if (!Number.isInteger(period) || period < 1) {
4
+ throw new RangeError(`period must be a positive integer, got ${period}`);
5
+ }
6
+ }
7
+ var SMA = class {
8
+ constructor(period) {
9
+ this.period = period;
10
+ this.buf = [];
11
+ this.sum = 0;
12
+ /** Latest value, or `null` until `period` samples have been seen. */
13
+ this.value = null;
14
+ assertPeriod(period);
15
+ }
16
+ next(price) {
17
+ this.buf.push(price);
18
+ this.sum += price;
19
+ if (this.buf.length > this.period) this.sum -= this.buf.shift();
20
+ this.value = this.buf.length === this.period ? this.sum / this.period : null;
21
+ return this.value;
22
+ }
23
+ };
24
+ var EMA = class {
25
+ constructor(period) {
26
+ this.period = period;
27
+ this.seed = [];
28
+ this.ema = null;
29
+ this.value = null;
30
+ assertPeriod(period);
31
+ this.k = 2 / (period + 1);
32
+ }
33
+ next(price) {
34
+ if (this.ema === null) {
35
+ this.seed.push(price);
36
+ if (this.seed.length < this.period) return this.value = null;
37
+ this.ema = this.seed.reduce((a, b) => a + b, 0) / this.period;
38
+ } else {
39
+ this.ema = price * this.k + this.ema * (1 - this.k);
40
+ }
41
+ return this.value = this.ema;
42
+ }
43
+ };
44
+ var WMA = class {
45
+ constructor(period) {
46
+ this.period = period;
47
+ this.buf = [];
48
+ this.value = null;
49
+ assertPeriod(period);
50
+ }
51
+ next(price) {
52
+ this.buf.push(price);
53
+ if (this.buf.length > this.period) this.buf.shift();
54
+ if (this.buf.length < this.period) return this.value = null;
55
+ let num = 0;
56
+ let den = 0;
57
+ for (let i = 0; i < this.period; i++) {
58
+ const w = i + 1;
59
+ num += this.buf[i] * w;
60
+ den += w;
61
+ }
62
+ return this.value = num / den;
63
+ }
64
+ };
65
+ var RSI = class {
66
+ constructor(period = 14) {
67
+ this.period = period;
68
+ this.prev = null;
69
+ this.avgGain = 0;
70
+ this.avgLoss = 0;
71
+ this.count = 0;
72
+ this.value = null;
73
+ assertPeriod(period);
74
+ }
75
+ next(price) {
76
+ if (this.prev === null) {
77
+ this.prev = price;
78
+ return this.value = null;
79
+ }
80
+ const change = price - this.prev;
81
+ this.prev = price;
82
+ const gain = change > 0 ? change : 0;
83
+ const loss = change < 0 ? -change : 0;
84
+ this.count++;
85
+ if (this.count <= this.period) {
86
+ this.avgGain += gain;
87
+ this.avgLoss += loss;
88
+ if (this.count < this.period) return this.value = null;
89
+ this.avgGain /= this.period;
90
+ this.avgLoss /= this.period;
91
+ } else {
92
+ this.avgGain = (this.avgGain * (this.period - 1) + gain) / this.period;
93
+ this.avgLoss = (this.avgLoss * (this.period - 1) + loss) / this.period;
94
+ }
95
+ return this.value = this.compute();
96
+ }
97
+ compute() {
98
+ if (this.avgLoss === 0) return 100;
99
+ const rs = this.avgGain / this.avgLoss;
100
+ return 100 - 100 / (1 + rs);
101
+ }
102
+ };
103
+ var MACD = class {
104
+ constructor(fast = 12, slow = 26, signal = 9) {
105
+ this.value = null;
106
+ this.fastEma = new EMA(fast);
107
+ this.slowEma = new EMA(slow);
108
+ this.signalEma = new EMA(signal);
109
+ }
110
+ next(price) {
111
+ const f = this.fastEma.next(price);
112
+ const s = this.slowEma.next(price);
113
+ if (f === null || s === null) return this.value = null;
114
+ const macd2 = f - s;
115
+ const signal = this.signalEma.next(macd2);
116
+ if (signal === null) return this.value = null;
117
+ return this.value = { macd: macd2, signal, histogram: macd2 - signal };
118
+ }
119
+ };
120
+ var BollingerBands = class {
121
+ constructor(period = 20, mult = 2) {
122
+ this.period = period;
123
+ this.mult = mult;
124
+ this.buf = [];
125
+ this.sum = 0;
126
+ this.value = null;
127
+ assertPeriod(period);
128
+ }
129
+ next(price) {
130
+ this.buf.push(price);
131
+ this.sum += price;
132
+ if (this.buf.length > this.period) this.sum -= this.buf.shift();
133
+ if (this.buf.length < this.period) return this.value = null;
134
+ const mean = this.sum / this.period;
135
+ let variance = 0;
136
+ for (const v of this.buf) variance += (v - mean) ** 2;
137
+ const sd = Math.sqrt(variance / this.period);
138
+ const upper = mean + this.mult * sd;
139
+ const lower = mean - this.mult * sd;
140
+ return this.value = {
141
+ middle: mean,
142
+ upper,
143
+ lower,
144
+ bandwidth: mean === 0 ? 0 : (upper - lower) / mean
145
+ };
146
+ }
147
+ };
148
+ var ATR = class {
149
+ constructor(period = 14) {
150
+ this.period = period;
151
+ this.prevClose = null;
152
+ this.atr = null;
153
+ this.seed = [];
154
+ this.value = null;
155
+ assertPeriod(period);
156
+ }
157
+ next(bar) {
158
+ const tr = this.prevClose === null ? bar.high - bar.low : Math.max(
159
+ bar.high - bar.low,
160
+ Math.abs(bar.high - this.prevClose),
161
+ Math.abs(bar.low - this.prevClose)
162
+ );
163
+ this.prevClose = bar.close;
164
+ if (this.atr === null) {
165
+ this.seed.push(tr);
166
+ if (this.seed.length < this.period) return this.value = null;
167
+ this.atr = this.seed.reduce((a, b) => a + b, 0) / this.period;
168
+ return this.value = this.atr;
169
+ }
170
+ this.atr = (this.atr * (this.period - 1) + tr) / this.period;
171
+ return this.value = this.atr;
172
+ }
173
+ };
174
+ var VWAP = class {
175
+ constructor() {
176
+ this.pv = 0;
177
+ this.vol = 0;
178
+ this.value = null;
179
+ }
180
+ next(bar) {
181
+ const typical = (bar.high + bar.low + bar.close) / 3;
182
+ this.pv += typical * bar.volume;
183
+ this.vol += bar.volume;
184
+ return this.value = this.vol === 0 ? null : this.pv / this.vol;
185
+ }
186
+ reset() {
187
+ this.pv = 0;
188
+ this.vol = 0;
189
+ this.value = null;
190
+ }
191
+ };
192
+ var Stochastic = class {
193
+ constructor(period = 14, signal = 3) {
194
+ this.period = period;
195
+ this.signal = signal;
196
+ this.highs = [];
197
+ this.lows = [];
198
+ this.value = null;
199
+ assertPeriod(period);
200
+ this.dSma = new SMA(signal);
201
+ }
202
+ next(bar) {
203
+ this.highs.push(bar.high);
204
+ this.lows.push(bar.low);
205
+ if (this.highs.length > this.period) {
206
+ this.highs.shift();
207
+ this.lows.shift();
208
+ }
209
+ if (this.highs.length < this.period) return this.value = null;
210
+ const hh = Math.max(...this.highs);
211
+ const ll = Math.min(...this.lows);
212
+ const k = hh === ll ? 100 : (bar.close - ll) / (hh - ll) * 100;
213
+ const d = this.dSma.next(k);
214
+ if (d === null) return this.value = null;
215
+ return this.value = { k, d };
216
+ }
217
+ };
218
+ var Supertrend = class {
219
+ constructor(period = 10, mult = 3) {
220
+ this.period = period;
221
+ this.mult = mult;
222
+ this.prevClose = null;
223
+ this.prevFinalUpper = 0;
224
+ this.prevFinalLower = 0;
225
+ this.prevSupertrend = null;
226
+ this.value = null;
227
+ this.atr = new ATR(period);
228
+ }
229
+ next(bar) {
230
+ const atr2 = this.atr.next(bar);
231
+ if (atr2 === null) {
232
+ this.prevClose = bar.close;
233
+ return this.value = null;
234
+ }
235
+ const hl2 = (bar.high + bar.low) / 2;
236
+ const basicUpper = hl2 + this.mult * atr2;
237
+ const basicLower = hl2 - this.mult * atr2;
238
+ const pc = this.prevClose ?? bar.close;
239
+ const first = this.prevSupertrend === null;
240
+ const finalUpper = first || basicUpper < this.prevFinalUpper || pc > this.prevFinalUpper ? basicUpper : this.prevFinalUpper;
241
+ const finalLower = first || basicLower > this.prevFinalLower || pc < this.prevFinalLower ? basicLower : this.prevFinalLower;
242
+ let st;
243
+ let direction;
244
+ if (first) {
245
+ direction = bar.close <= finalUpper ? -1 : 1;
246
+ st = direction === -1 ? finalUpper : finalLower;
247
+ } else if (this.prevSupertrend === this.prevFinalUpper) {
248
+ if (bar.close <= finalUpper) {
249
+ st = finalUpper;
250
+ direction = -1;
251
+ } else {
252
+ st = finalLower;
253
+ direction = 1;
254
+ }
255
+ } else {
256
+ if (bar.close >= finalLower) {
257
+ st = finalLower;
258
+ direction = 1;
259
+ } else {
260
+ st = finalUpper;
261
+ direction = -1;
262
+ }
263
+ }
264
+ this.prevFinalUpper = finalUpper;
265
+ this.prevFinalLower = finalLower;
266
+ this.prevSupertrend = st;
267
+ this.prevClose = bar.close;
268
+ return this.value = { value: st, direction };
269
+ }
270
+ };
271
+ var ADX = class {
272
+ constructor(period = 14) {
273
+ this.period = period;
274
+ this.prevHigh = null;
275
+ this.prevLow = 0;
276
+ this.prevClose = 0;
277
+ this.smTR = 0;
278
+ this.smPDM = 0;
279
+ this.smMDM = 0;
280
+ this.dxs = [];
281
+ this.adx = null;
282
+ this.count = 0;
283
+ this.value = null;
284
+ assertPeriod(period);
285
+ }
286
+ next(bar) {
287
+ if (this.prevHigh === null) {
288
+ this.prevHigh = bar.high;
289
+ this.prevLow = bar.low;
290
+ this.prevClose = bar.close;
291
+ return this.value = null;
292
+ }
293
+ const upMove = bar.high - this.prevHigh;
294
+ const downMove = this.prevLow - bar.low;
295
+ const pdm = upMove > downMove && upMove > 0 ? upMove : 0;
296
+ const mdm = downMove > upMove && downMove > 0 ? downMove : 0;
297
+ const tr = Math.max(
298
+ bar.high - bar.low,
299
+ Math.abs(bar.high - this.prevClose),
300
+ Math.abs(bar.low - this.prevClose)
301
+ );
302
+ this.prevHigh = bar.high;
303
+ this.prevLow = bar.low;
304
+ this.prevClose = bar.close;
305
+ this.count++;
306
+ if (this.count <= this.period) {
307
+ this.smTR += tr;
308
+ this.smPDM += pdm;
309
+ this.smMDM += mdm;
310
+ if (this.count < this.period) return this.value = null;
311
+ } else {
312
+ this.smTR = this.smTR - this.smTR / this.period + tr;
313
+ this.smPDM = this.smPDM - this.smPDM / this.period + pdm;
314
+ this.smMDM = this.smMDM - this.smMDM / this.period + mdm;
315
+ }
316
+ const plusDI = this.smTR === 0 ? 0 : 100 * this.smPDM / this.smTR;
317
+ const minusDI = this.smTR === 0 ? 0 : 100 * this.smMDM / this.smTR;
318
+ const diSum = plusDI + minusDI;
319
+ const dx = diSum === 0 ? 0 : 100 * Math.abs(plusDI - minusDI) / diSum;
320
+ if (this.adx === null) {
321
+ this.dxs.push(dx);
322
+ if (this.dxs.length < this.period) return this.value = null;
323
+ this.adx = this.dxs.reduce((a, b) => a + b, 0) / this.period;
324
+ } else {
325
+ this.adx = (this.adx * (this.period - 1) + dx) / this.period;
326
+ }
327
+ return this.value = { adx: this.adx, plusDI, minusDI };
328
+ }
329
+ };
330
+ function runNumber(ind, values) {
331
+ return values.map((v) => ind.next(v));
332
+ }
333
+ var sma = (values, period) => runNumber(new SMA(period), values);
334
+ var ema = (values, period) => runNumber(new EMA(period), values);
335
+ var wma = (values, period) => runNumber(new WMA(period), values);
336
+ var rsi = (values, period = 14) => runNumber(new RSI(period), values);
337
+ function macd(values, fast = 12, slow = 26, signal = 9) {
338
+ const ind = new MACD(fast, slow, signal);
339
+ return values.map((v) => ind.next(v));
340
+ }
341
+ function bollinger(values, period = 20, mult = 2) {
342
+ const ind = new BollingerBands(period, mult);
343
+ return values.map((v) => ind.next(v));
344
+ }
345
+ function atr(bars, period = 14) {
346
+ const ind = new ATR(period);
347
+ return bars.map((b) => ind.next(b));
348
+ }
349
+ function supertrend(bars, period = 10, mult = 3) {
350
+ const ind = new Supertrend(period, mult);
351
+ return bars.map((b) => ind.next(b));
352
+ }
353
+ function adx(bars, period = 14) {
354
+ const ind = new ADX(period);
355
+ return bars.map((b) => ind.next(b));
356
+ }
357
+ function crossedAbove(prev, curr) {
358
+ return prev.a <= prev.b && curr.a > curr.b;
359
+ }
360
+ function crossedBelow(prev, curr) {
361
+ return prev.a >= prev.b && curr.a < curr.b;
362
+ }
363
+
364
+ export { ADX, ATR, BollingerBands, EMA, MACD, RSI, SMA, Stochastic, Supertrend, VWAP, WMA, adx, atr, bollinger, crossedAbove, crossedBelow, ema, macd, rsi, sma, supertrend, wma };
365
+ //# sourceMappingURL=index.js.map
366
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":["macd","atr"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @lacspace/indicators\n * Streaming technical indicators for stock-market apps.\n *\n * Every indicator is a small class with an incremental `next()` that updates in\n * O(1) (or O(period) for window-based ones) — push one live tick, get the new\n * value, without recomputing the whole series. Perfect for live LTP feeds.\n *\n * Zero dependencies · isomorphic · fully typed.\n */\n\nexport interface Candle {\n open: number;\n high: number;\n low: number;\n close: number;\n volume?: number;\n time?: number;\n}\n\n/** A high/low/close bar — the minimum most range-based indicators need. */\nexport interface HLC {\n high: number;\n low: number;\n close: number;\n}\n\nfunction assertPeriod(period: number): void {\n if (!Number.isInteger(period) || period < 1) {\n throw new RangeError(`period must be a positive integer, got ${period}`);\n }\n}\n\n/** Simple Moving Average. Incremental O(1) using a running window sum. */\nexport class SMA {\n private buf: number[] = [];\n private sum = 0;\n /** Latest value, or `null` until `period` samples have been seen. */\n value: number | null = null;\n\n constructor(public readonly period: number) {\n assertPeriod(period);\n }\n\n next(price: number): number | null {\n this.buf.push(price);\n this.sum += price;\n if (this.buf.length > this.period) this.sum -= this.buf.shift()!;\n this.value = this.buf.length === this.period ? this.sum / this.period : null;\n return this.value;\n }\n}\n\n/** Exponential Moving Average. Seeded with an SMA of the first `period` values. */\nexport class EMA {\n private readonly k: number;\n private seed: number[] = [];\n private ema: number | null = null;\n value: number | null = null;\n\n constructor(public readonly period: number) {\n assertPeriod(period);\n this.k = 2 / (period + 1);\n }\n\n next(price: number): number | null {\n if (this.ema === null) {\n this.seed.push(price);\n if (this.seed.length < this.period) return (this.value = null);\n this.ema = this.seed.reduce((a, b) => a + b, 0) / this.period;\n } else {\n this.ema = price * this.k + this.ema * (1 - this.k);\n }\n return (this.value = this.ema);\n }\n}\n\n/** Weighted Moving Average — recent samples weighted linearly higher. */\nexport class WMA {\n private buf: number[] = [];\n value: number | null = null;\n\n constructor(public readonly period: number) {\n assertPeriod(period);\n }\n\n next(price: number): number | null {\n this.buf.push(price);\n if (this.buf.length > this.period) this.buf.shift();\n if (this.buf.length < this.period) return (this.value = null);\n let num = 0;\n let den = 0;\n for (let i = 0; i < this.period; i++) {\n const w = i + 1;\n num += this.buf[i]! * w;\n den += w;\n }\n return (this.value = num / den);\n }\n}\n\n/** Relative Strength Index (Wilder's smoothing). O(1) per tick. */\nexport class RSI {\n private prev: number | null = null;\n private avgGain = 0;\n private avgLoss = 0;\n private count = 0;\n value: number | null = null;\n\n constructor(public readonly period: number = 14) {\n assertPeriod(period);\n }\n\n next(price: number): number | null {\n if (this.prev === null) {\n this.prev = price;\n return (this.value = null);\n }\n const change = price - this.prev;\n this.prev = price;\n const gain = change > 0 ? change : 0;\n const loss = change < 0 ? -change : 0;\n this.count++;\n\n if (this.count <= this.period) {\n this.avgGain += gain;\n this.avgLoss += loss;\n if (this.count < this.period) return (this.value = null);\n this.avgGain /= this.period;\n this.avgLoss /= this.period;\n } else {\n this.avgGain = (this.avgGain * (this.period - 1) + gain) / this.period;\n this.avgLoss = (this.avgLoss * (this.period - 1) + loss) / this.period;\n }\n return (this.value = this.compute());\n }\n\n private compute(): number {\n if (this.avgLoss === 0) return 100;\n const rs = this.avgGain / this.avgLoss;\n return 100 - 100 / (1 + rs);\n }\n}\n\nexport interface MACDValue {\n macd: number;\n signal: number;\n histogram: number;\n}\n\n/** Moving Average Convergence Divergence. Defaults 12 / 26 / 9. */\nexport class MACD {\n private readonly fastEma: EMA;\n private readonly slowEma: EMA;\n private readonly signalEma: EMA;\n value: MACDValue | null = null;\n\n constructor(fast = 12, slow = 26, signal = 9) {\n this.fastEma = new EMA(fast);\n this.slowEma = new EMA(slow);\n this.signalEma = new EMA(signal);\n }\n\n next(price: number): MACDValue | null {\n const f = this.fastEma.next(price);\n const s = this.slowEma.next(price);\n if (f === null || s === null) return (this.value = null);\n const macd = f - s;\n const signal = this.signalEma.next(macd);\n if (signal === null) return (this.value = null);\n return (this.value = { macd, signal, histogram: macd - signal });\n }\n}\n\nexport interface BollingerValue {\n middle: number;\n upper: number;\n lower: number;\n /** (upper - lower) / middle — normalised band width. */\n bandwidth: number;\n}\n\n/** Bollinger Bands — SMA middle band ± `mult` standard deviations. */\nexport class BollingerBands {\n private buf: number[] = [];\n private sum = 0;\n value: BollingerValue | null = null;\n\n constructor(\n public readonly period = 20,\n public readonly mult = 2,\n ) {\n assertPeriod(period);\n }\n\n next(price: number): BollingerValue | null {\n this.buf.push(price);\n this.sum += price;\n if (this.buf.length > this.period) this.sum -= this.buf.shift()!;\n if (this.buf.length < this.period) return (this.value = null);\n const mean = this.sum / this.period;\n let variance = 0;\n for (const v of this.buf) variance += (v - mean) ** 2;\n const sd = Math.sqrt(variance / this.period);\n const upper = mean + this.mult * sd;\n const lower = mean - this.mult * sd;\n return (this.value = {\n middle: mean,\n upper,\n lower,\n bandwidth: mean === 0 ? 0 : (upper - lower) / mean,\n });\n }\n}\n\n/** Average True Range (Wilder). Feed it high/low/close bars. */\nexport class ATR {\n private prevClose: number | null = null;\n private atr: number | null = null;\n private seed: number[] = [];\n value: number | null = null;\n\n constructor(public readonly period = 14) {\n assertPeriod(period);\n }\n\n next(bar: HLC): number | null {\n const tr =\n this.prevClose === null\n ? bar.high - bar.low\n : Math.max(\n bar.high - bar.low,\n Math.abs(bar.high - this.prevClose),\n Math.abs(bar.low - this.prevClose),\n );\n this.prevClose = bar.close;\n\n if (this.atr === null) {\n this.seed.push(tr);\n if (this.seed.length < this.period) return (this.value = null);\n this.atr = this.seed.reduce((a, b) => a + b, 0) / this.period;\n return (this.value = this.atr);\n }\n this.atr = (this.atr * (this.period - 1) + tr) / this.period;\n return (this.value = this.atr);\n }\n}\n\n/** Volume-Weighted Average Price. Cumulative — call `reset()` per session. */\nexport class VWAP {\n private pv = 0;\n private vol = 0;\n value: number | null = null;\n\n next(bar: Required<Pick<Candle, \"high\" | \"low\" | \"close\" | \"volume\">>): number | null {\n const typical = (bar.high + bar.low + bar.close) / 3;\n this.pv += typical * bar.volume;\n this.vol += bar.volume;\n return (this.value = this.vol === 0 ? null : this.pv / this.vol);\n }\n\n reset(): void {\n this.pv = 0;\n this.vol = 0;\n this.value = null;\n }\n}\n\nexport interface StochasticValue {\n /** %K — position of close within the recent high/low range (0–100). */\n k: number;\n /** %D — SMA of %K. */\n d: number;\n}\n\n/** Stochastic Oscillator (%K / %D). */\nexport class Stochastic {\n private highs: number[] = [];\n private lows: number[] = [];\n private readonly dSma: SMA;\n value: StochasticValue | null = null;\n\n constructor(\n public readonly period = 14,\n public readonly signal = 3,\n ) {\n assertPeriod(period);\n this.dSma = new SMA(signal);\n }\n\n next(bar: HLC): StochasticValue | null {\n this.highs.push(bar.high);\n this.lows.push(bar.low);\n if (this.highs.length > this.period) {\n this.highs.shift();\n this.lows.shift();\n }\n if (this.highs.length < this.period) return (this.value = null);\n const hh = Math.max(...this.highs);\n const ll = Math.min(...this.lows);\n const k = hh === ll ? 100 : ((bar.close - ll) / (hh - ll)) * 100;\n const d = this.dSma.next(k);\n if (d === null) return (this.value = null);\n return (this.value = { k, d });\n }\n}\n\nexport interface SupertrendValue {\n value: number;\n /** 1 = uptrend (price above band), -1 = downtrend. */\n direction: 1 | -1;\n}\n\n/** Supertrend — ATR-based trend follower. Defaults period 10, multiplier 3. */\nexport class Supertrend {\n private readonly atr: ATR;\n private prevClose: number | null = null;\n private prevFinalUpper = 0;\n private prevFinalLower = 0;\n private prevSupertrend: number | null = null;\n value: SupertrendValue | null = null;\n\n constructor(\n public readonly period = 10,\n public readonly mult = 3,\n ) {\n this.atr = new ATR(period);\n }\n\n next(bar: HLC): SupertrendValue | null {\n const atr = this.atr.next(bar);\n if (atr === null) {\n this.prevClose = bar.close;\n return (this.value = null);\n }\n const hl2 = (bar.high + bar.low) / 2;\n const basicUpper = hl2 + this.mult * atr;\n const basicLower = hl2 - this.mult * atr;\n const pc = this.prevClose ?? bar.close;\n\n const first = this.prevSupertrend === null;\n const finalUpper =\n first || basicUpper < this.prevFinalUpper || pc > this.prevFinalUpper\n ? basicUpper\n : this.prevFinalUpper;\n const finalLower =\n first || basicLower > this.prevFinalLower || pc < this.prevFinalLower\n ? basicLower\n : this.prevFinalLower;\n\n let st: number;\n let direction: 1 | -1;\n if (first) {\n direction = bar.close <= finalUpper ? -1 : 1;\n st = direction === -1 ? finalUpper : finalLower;\n } else if (this.prevSupertrend === this.prevFinalUpper) {\n if (bar.close <= finalUpper) {\n st = finalUpper;\n direction = -1;\n } else {\n st = finalLower;\n direction = 1;\n }\n } else {\n if (bar.close >= finalLower) {\n st = finalLower;\n direction = 1;\n } else {\n st = finalUpper;\n direction = -1;\n }\n }\n\n this.prevFinalUpper = finalUpper;\n this.prevFinalLower = finalLower;\n this.prevSupertrend = st;\n this.prevClose = bar.close;\n return (this.value = { value: st, direction });\n }\n}\n\nexport interface ADXValue {\n adx: number;\n plusDI: number;\n minusDI: number;\n}\n\n/** Average Directional Index with +DI / -DI (Wilder). */\nexport class ADX {\n private prevHigh: number | null = null;\n private prevLow = 0;\n private prevClose = 0;\n private smTR = 0;\n private smPDM = 0;\n private smMDM = 0;\n private dxs: number[] = [];\n private adx: number | null = null;\n private count = 0;\n value: ADXValue | null = null;\n\n constructor(public readonly period = 14) {\n assertPeriod(period);\n }\n\n next(bar: HLC): ADXValue | null {\n if (this.prevHigh === null) {\n this.prevHigh = bar.high;\n this.prevLow = bar.low;\n this.prevClose = bar.close;\n return (this.value = null);\n }\n const upMove = bar.high - this.prevHigh;\n const downMove = this.prevLow - bar.low;\n const pdm = upMove > downMove && upMove > 0 ? upMove : 0;\n const mdm = downMove > upMove && downMove > 0 ? downMove : 0;\n const tr = Math.max(\n bar.high - bar.low,\n Math.abs(bar.high - this.prevClose),\n Math.abs(bar.low - this.prevClose),\n );\n this.prevHigh = bar.high;\n this.prevLow = bar.low;\n this.prevClose = bar.close;\n this.count++;\n\n if (this.count <= this.period) {\n this.smTR += tr;\n this.smPDM += pdm;\n this.smMDM += mdm;\n if (this.count < this.period) return (this.value = null);\n } else {\n this.smTR = this.smTR - this.smTR / this.period + tr;\n this.smPDM = this.smPDM - this.smPDM / this.period + pdm;\n this.smMDM = this.smMDM - this.smMDM / this.period + mdm;\n }\n\n const plusDI = this.smTR === 0 ? 0 : (100 * this.smPDM) / this.smTR;\n const minusDI = this.smTR === 0 ? 0 : (100 * this.smMDM) / this.smTR;\n const diSum = plusDI + minusDI;\n const dx = diSum === 0 ? 0 : (100 * Math.abs(plusDI - minusDI)) / diSum;\n\n if (this.adx === null) {\n this.dxs.push(dx);\n if (this.dxs.length < this.period) return (this.value = null);\n this.adx = this.dxs.reduce((a, b) => a + b, 0) / this.period;\n } else {\n this.adx = (this.adx * (this.period - 1) + dx) / this.period;\n }\n return (this.value = { adx: this.adx, plusDI, minusDI });\n }\n}\n\n/* ------------------------------------------------------------------ *\n * Batch helpers — run an indicator over an existing array in one call.\n * Each returns an array aligned to the input (nulls during warm-up).\n * ------------------------------------------------------------------ */\n\nfunction runNumber<T extends { next(v: number): number | null }>(\n ind: T,\n values: number[],\n): (number | null)[] {\n return values.map((v) => ind.next(v));\n}\n\nexport const sma = (values: number[], period: number) => runNumber(new SMA(period), values);\nexport const ema = (values: number[], period: number) => runNumber(new EMA(period), values);\nexport const wma = (values: number[], period: number) => runNumber(new WMA(period), values);\nexport const rsi = (values: number[], period = 14) => runNumber(new RSI(period), values);\n\nexport function macd(values: number[], fast = 12, slow = 26, signal = 9): (MACDValue | null)[] {\n const ind = new MACD(fast, slow, signal);\n return values.map((v) => ind.next(v));\n}\n\nexport function bollinger(values: number[], period = 20, mult = 2): (BollingerValue | null)[] {\n const ind = new BollingerBands(period, mult);\n return values.map((v) => ind.next(v));\n}\n\nexport function atr(bars: HLC[], period = 14): (number | null)[] {\n const ind = new ATR(period);\n return bars.map((b) => ind.next(b));\n}\n\nexport function supertrend(bars: HLC[], period = 10, mult = 3): (SupertrendValue | null)[] {\n const ind = new Supertrend(period, mult);\n return bars.map((b) => ind.next(b));\n}\n\nexport function adx(bars: HLC[], period = 14): (ADXValue | null)[] {\n const ind = new ADX(period);\n return bars.map((b) => ind.next(b));\n}\n\n/* ------------------------------------------------------------------ *\n * Crossover helpers — the backbone of most signal logic.\n * ------------------------------------------------------------------ */\n\n/** True when series A crossed from at-or-below B to strictly above B. */\nexport function crossedAbove(\n prev: { a: number; b: number },\n curr: { a: number; b: number },\n): boolean {\n return prev.a <= prev.b && curr.a > curr.b;\n}\n\n/** True when series A crossed from at-or-above B to strictly below B. */\nexport function crossedBelow(\n prev: { a: number; b: number },\n curr: { a: number; b: number },\n): boolean {\n return prev.a >= prev.b && curr.a < curr.b;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@lacspace/indicators",
3
+ "version": "1.0.0",
4
+ "description": "Streaming technical indicators (RSI, MACD, EMA, Bollinger, ATR, Supertrend, ADX, VWAP) with O(1) incremental updates for live price feeds. Zero-dependency.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "sideEffects": false,
25
+ "scripts": {
26
+ "build": "tsup",
27
+ "prepublishOnly": "npm run build"
28
+ },
29
+ "keywords": [
30
+ "technical-indicators",
31
+ "trading",
32
+ "stock-market",
33
+ "rsi",
34
+ "macd",
35
+ "ema",
36
+ "bollinger-bands",
37
+ "supertrend",
38
+ "vwap",
39
+ "atr",
40
+ "adx",
41
+ "streaming",
42
+ "typescript"
43
+ ],
44
+ "author": "Lacspace <contact@lacspace.com>",
45
+ "license": "MIT",
46
+ "homepage": "https://lacspace.com/packages",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/lacspace/npm-packages.git",
50
+ "directory": "indicators"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/lacspace/npm-packages/issues"
54
+ },
55
+ "engines": {
56
+ "node": ">=18"
57
+ }
58
+ }