oakscriptjs 0.1.6 → 0.2.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/dist/index.mjs CHANGED
@@ -5,7 +5,6 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/types/index.ts
8
- var na = null;
9
8
  var xloc = {
10
9
  /** X-coordinates are bar indices */
11
10
  bar_index: "bar_index",
@@ -80,34 +79,51 @@ __export(ta_exports, {
80
79
  });
81
80
  function sma(source, length2) {
82
81
  const result = [];
82
+ const len = Math.floor(length2);
83
83
  for (let i = 0; i < source.length; i++) {
84
- if (i < length2 - 1) {
84
+ if (i < len - 1) {
85
85
  result.push(NaN);
86
86
  } else {
87
87
  let sum4 = 0;
88
- for (let j = 0; j < length2; j++) {
88
+ for (let j = 0; j < len; j++) {
89
89
  sum4 += source[i - j];
90
90
  }
91
- result.push(sum4 / length2);
91
+ result.push(sum4 / len);
92
92
  }
93
93
  }
94
94
  return result;
95
95
  }
96
96
  function ema(source, length2) {
97
97
  const result = [];
98
- const multiplier = 2 / (length2 + 1);
99
- let ema3 = 0;
100
- for (let i = 0; i < Math.min(length2, source.length); i++) {
101
- ema3 += source[i];
98
+ const len = Math.floor(length2);
99
+ const multiplier = 2 / (len + 1);
100
+ let firstValidIndex = -1;
101
+ let validCount = 0;
102
+ let initSum = 0;
103
+ for (let i = 0; i < source.length; i++) {
104
+ const val = source[i];
105
+ if (val !== void 0 && !isNaN(val)) {
106
+ initSum += val;
107
+ validCount++;
108
+ if (validCount === len) {
109
+ firstValidIndex = i;
110
+ break;
111
+ }
112
+ }
102
113
  }
103
- ema3 = ema3 / Math.min(length2, source.length);
114
+ let emaValue = validCount > 0 ? initSum / validCount : NaN;
115
+ let emaInitialized = firstValidIndex >= 0;
104
116
  for (let i = 0; i < source.length; i++) {
105
- if (i === 0) {
106
- result.push(source[i]);
107
- ema3 = source[i];
117
+ if (!emaInitialized || i < firstValidIndex) {
118
+ result.push(NaN);
119
+ } else if (i === firstValidIndex) {
120
+ result.push(emaValue);
108
121
  } else {
109
- ema3 = (source[i] - ema3) * multiplier + ema3;
110
- result.push(ema3);
122
+ const val = source[i];
123
+ if (val !== void 0 && !isNaN(val)) {
124
+ emaValue = (val - emaValue) * multiplier + emaValue;
125
+ }
126
+ result.push(emaValue);
111
127
  }
112
128
  }
113
129
  return result;
@@ -160,17 +176,18 @@ function bb(series, length2, mult2) {
160
176
  }
161
177
  function stdev(source, length2) {
162
178
  const result = [];
163
- const avg4 = sma(source, length2);
179
+ const len = Math.floor(length2);
180
+ const avg4 = sma(source, len);
164
181
  for (let i = 0; i < source.length; i++) {
165
- if (i < length2 - 1) {
182
+ if (i < len - 1) {
166
183
  result.push(NaN);
167
184
  } else {
168
185
  let sumSquares = 0;
169
- for (let j = 0; j < length2; j++) {
186
+ for (let j = 0; j < len; j++) {
170
187
  const diff2 = source[i - j] - avg4[i];
171
188
  sumSquares += diff2 * diff2;
172
189
  }
173
- result.push(Math.sqrt(sumSquares / length2));
190
+ result.push(Math.sqrt(sumSquares / len));
174
191
  }
175
192
  }
176
193
  return result;
@@ -299,17 +316,34 @@ function supertrend(factor, atrPeriod, high, low, close, wicks = false) {
299
316
  }
300
317
  function rma(source, length2) {
301
318
  const result = [];
302
- const alpha = 1 / length2;
303
- let rmaValue = 0;
304
- for (let i = 0; i < Math.min(length2, source.length); i++) {
305
- rmaValue += source[i];
319
+ const len = Math.floor(length2);
320
+ const alpha = 1 / len;
321
+ let firstValidIndex = -1;
322
+ let validCount = 0;
323
+ let initSum = 0;
324
+ for (let i = 0; i < source.length; i++) {
325
+ const val = source[i];
326
+ if (val !== void 0 && !isNaN(val)) {
327
+ initSum += val;
328
+ validCount++;
329
+ if (validCount === len) {
330
+ firstValidIndex = i;
331
+ break;
332
+ }
333
+ }
306
334
  }
307
- rmaValue = rmaValue / Math.min(length2, source.length);
335
+ let rmaValue = validCount > 0 ? initSum / validCount : NaN;
336
+ let rmaInitialized = firstValidIndex >= 0;
308
337
  for (let i = 0; i < source.length; i++) {
309
- if (i === 0) {
338
+ if (!rmaInitialized || i < firstValidIndex) {
339
+ result.push(NaN);
340
+ } else if (i === firstValidIndex) {
310
341
  result.push(rmaValue);
311
342
  } else {
312
- rmaValue = alpha * source[i] + (1 - alpha) * rmaValue;
343
+ const val = source[i];
344
+ if (val !== void 0 && !isNaN(val)) {
345
+ rmaValue = alpha * val + (1 - alpha) * rmaValue;
346
+ }
313
347
  result.push(rmaValue);
314
348
  }
315
349
  }
@@ -317,14 +351,15 @@ function rma(source, length2) {
317
351
  }
318
352
  function wma(source, length2) {
319
353
  const result = [];
354
+ const len = Math.floor(length2);
320
355
  for (let i = 0; i < source.length; i++) {
321
- if (i < length2 - 1) {
356
+ if (i < len - 1) {
322
357
  result.push(NaN);
323
358
  } else {
324
359
  let sum4 = 0;
325
360
  let weightSum = 0;
326
- for (let j = 0; j < length2; j++) {
327
- const weight = length2 - j;
361
+ for (let j = 0; j < len; j++) {
362
+ const weight = len - j;
328
363
  sum4 += source[i - j] * weight;
329
364
  weightSum += weight;
330
365
  }
@@ -564,12 +599,13 @@ function vwma(source, length2, volume) {
564
599
  }
565
600
  function linreg(source, length2, offset = 0) {
566
601
  const result = [];
602
+ const len = Math.floor(length2);
567
603
  for (let i = 0; i < source.length; i++) {
568
- if (i < length2 - 1) {
604
+ if (i < len - 1) {
569
605
  result.push(NaN);
570
606
  } else {
571
607
  let hasNaN = false;
572
- for (let j = 0; j < length2; j++) {
608
+ for (let j = 0; j < len; j++) {
573
609
  if (isNaN(source[i - j])) {
574
610
  hasNaN = true;
575
611
  break;
@@ -582,17 +618,17 @@ function linreg(source, length2, offset = 0) {
582
618
  let sumY = 0;
583
619
  let sumXY = 0;
584
620
  let sumX2 = 0;
585
- for (let j = 0; j < length2; j++) {
621
+ for (let j = 0; j < len; j++) {
586
622
  const x2 = j;
587
- const y = source[i - (length2 - 1 - j)];
623
+ const y = source[i - (len - 1 - j)];
588
624
  sumX += x2;
589
625
  sumY += y;
590
626
  sumXY += x2 * y;
591
627
  sumX2 += x2 * x2;
592
628
  }
593
- const slope = (length2 * sumXY - sumX * sumY) / (length2 * sumX2 - sumX * sumX);
594
- const intercept = (sumY - slope * sumX) / length2;
595
- const x = length2 - 1 - offset;
629
+ const slope = (len * sumXY - sumX * sumY) / (len * sumX2 - sumX * sumX);
630
+ const intercept = (sumY - slope * sumX) / len;
631
+ const x = len - 1 - offset;
596
632
  result.push(intercept + slope * x);
597
633
  }
598
634
  }
@@ -681,8 +717,8 @@ function cci(source, length2) {
681
717
  if (isNaN(smaValues[i]) || isNaN(devValues[i]) || devValues[i] === 0) {
682
718
  result.push(NaN);
683
719
  } else {
684
- const cci2 = (source[i] - smaValues[i]) / (0.015 * devValues[i]);
685
- result.push(cci2);
720
+ const cci3 = (source[i] - smaValues[i]) / (0.015 * devValues[i]);
721
+ result.push(cci3);
686
722
  }
687
723
  }
688
724
  return result;
@@ -1143,9 +1179,9 @@ function vwap(source, volume) {
1143
1179
  }
1144
1180
  return result;
1145
1181
  }
1146
- function alma(source, length2 = 9, offset = 0.85, sigma = 6) {
1182
+ function alma(source, length2 = 9, offset = 0.85, sigma = 6, floor2 = false) {
1147
1183
  const result = [];
1148
- const m = Math.floor(offset * (length2 - 1));
1184
+ const m = floor2 ? Math.floor(offset * (length2 - 1)) : offset * (length2 - 1);
1149
1185
  const s = length2 / sigma;
1150
1186
  const weights = [];
1151
1187
  let weightSum = 0;
@@ -2147,6 +2183,38 @@ var Series = class _Series {
2147
2183
  });
2148
2184
  }
2149
2185
  // ============================================
2186
+ // Conditional Selection
2187
+ // ============================================
2188
+ /**
2189
+ * Bar-by-bar conditional selection (ternary operator for Series)
2190
+ * Uses this Series as the condition (truthy = nonzero, falsy = zero/NaN)
2191
+ *
2192
+ * @param trueValue - Value or Series to use when condition is truthy
2193
+ * @param falseValue - Value or Series to use when condition is falsy
2194
+ * @returns New Series with bar-by-bar selected values
2195
+ *
2196
+ * @example
2197
+ * ```typescript
2198
+ * // PineScript: result = condition ? trueVal : falseVal
2199
+ * const result = condition.iff(trueVal, falseVal);
2200
+ *
2201
+ * // Example: RSI formula uses ternary for edge cases
2202
+ * // rsi = down == 0 ? 100 : up == 0 ? 0 : formula
2203
+ * const rsi = down.eq(0).iff(100, up.eq(0).iff(0, formula));
2204
+ * ```
2205
+ */
2206
+ iff(trueValue, falseValue) {
2207
+ return new _Series(this.dataSource, (bar, i, data) => {
2208
+ const condition = this.extractor(bar, i, data);
2209
+ const isTruthy = condition !== 0 && !Number.isNaN(condition);
2210
+ if (isTruthy) {
2211
+ return typeof trueValue === "number" ? trueValue : trueValue.extractor(bar, i, data);
2212
+ } else {
2213
+ return typeof falseValue === "number" ? falseValue : falseValue.extractor(bar, i, data);
2214
+ }
2215
+ });
2216
+ }
2217
+ // ============================================
2150
2218
  // Offset/History
2151
2219
  // ============================================
2152
2220
  /**
@@ -3044,6 +3112,7 @@ __export(str_exports, {
3044
3112
  lower: () => lower,
3045
3113
  match: () => match,
3046
3114
  pos: () => pos,
3115
+ repeat: () => repeat,
3047
3116
  replace: () => replace,
3048
3117
  replace_all: () => replace_all,
3049
3118
  split: () => split,
@@ -3129,6 +3198,13 @@ function trimRight(str) {
3129
3198
  function match(source, regex) {
3130
3199
  return new RegExp(regex).test(source);
3131
3200
  }
3201
+ function repeat(source, count, separator = "") {
3202
+ if (source == null)
3203
+ return null;
3204
+ if (count <= 0)
3205
+ return "";
3206
+ return Array(count).fill(source).join(separator);
3207
+ }
3132
3208
  function format_time(time, format2) {
3133
3209
  const date = new Date(time);
3134
3210
  const monthNames = [
@@ -5072,6 +5148,7 @@ __export(ta_series_exports, {
5072
5148
  alma: () => alma2,
5073
5149
  atr: () => atr2,
5074
5150
  bb: () => bb2,
5151
+ cci: () => cci2,
5075
5152
  change: () => change2,
5076
5153
  cross: () => cross2,
5077
5154
  crossover: () => crossover2,
@@ -5089,8 +5166,10 @@ __export(ta_series_exports, {
5089
5166
  rma: () => rma2,
5090
5167
  roc: () => roc2,
5091
5168
  rsi: () => rsi2,
5169
+ sar: () => sar2,
5092
5170
  sma: () => sma2,
5093
5171
  stdev: () => stdev3,
5172
+ stoch: () => stoch2,
5094
5173
  supertrend: () => supertrend2,
5095
5174
  ta: () => ta,
5096
5175
  tr: () => tr2,
@@ -5160,11 +5239,19 @@ function atr2(bars, length2) {
5160
5239
  const result = atr(length2, high, low, close);
5161
5240
  return Series.fromArray(bars, result);
5162
5241
  }
5163
- function tr2(bars) {
5242
+ function tr2(bars, handle_na = false) {
5164
5243
  const high = bars.map((b2) => b2.high);
5165
5244
  const low = bars.map((b2) => b2.low);
5166
5245
  const close = bars.map((b2) => b2.close);
5167
- const result = tr(false, high, low, close);
5246
+ const result = tr(handle_na, high, low, close);
5247
+ return Series.fromArray(bars, result);
5248
+ }
5249
+ function stoch2(source, high, low, length2) {
5250
+ const bars = source.bars;
5251
+ const sourceValues = source.toArray();
5252
+ const highValues = high.toArray();
5253
+ const lowValues = low.toArray();
5254
+ const result = stoch(sourceValues, highValues, lowValues, length2);
5168
5255
  return Series.fromArray(bars, result);
5169
5256
  }
5170
5257
  function crossover2(source1, source2) {
@@ -5291,10 +5378,10 @@ function linreg2(source, length2, offset = 0) {
5291
5378
  const result = linreg(sourceValues, length2, offset);
5292
5379
  return Series.fromArray(bars, result);
5293
5380
  }
5294
- function alma2(source, length2 = 9, offset = 0.85, sigma = 6) {
5381
+ function alma2(source, length2 = 9, offset = 0.85, sigma = 6, floor2 = false) {
5295
5382
  const bars = source.bars;
5296
5383
  const sourceValues = source.toArray();
5297
- const result = alma(sourceValues, length2, offset, sigma);
5384
+ const result = alma(sourceValues, length2, offset, sigma, floor2);
5298
5385
  return Series.fromArray(bars, result);
5299
5386
  }
5300
5387
  function zigzag2(bars, deviation = 5, depth = 10, backstep = 3) {
@@ -5314,6 +5401,19 @@ function zigzag2(bars, deviation = 5, depth = 10, backstep = 3) {
5314
5401
  Series.fromArray(bars, pivotVals.map((b2) => b2 ? 1 : 0))
5315
5402
  ];
5316
5403
  }
5404
+ function cci2(source, length2) {
5405
+ const bars = source.bars;
5406
+ const sourceValues = source.toArray();
5407
+ const result = cci(sourceValues, length2);
5408
+ return Series.fromArray(bars, result);
5409
+ }
5410
+ function sar2(bars, start = 0.02, inc = 0.02, max5 = 0.2) {
5411
+ const high = bars.map((b2) => b2.high);
5412
+ const low = bars.map((b2) => b2.low);
5413
+ const close = bars.map((b2) => b2.close);
5414
+ const result = sar(start, inc, max5, high, low, close);
5415
+ return Series.fromArray(bars, result);
5416
+ }
5317
5417
  var ta = {
5318
5418
  sma: sma2,
5319
5419
  ema: ema2,
@@ -5326,6 +5426,7 @@ var ta = {
5326
5426
  stdev: stdev3,
5327
5427
  atr: atr2,
5328
5428
  tr: tr2,
5429
+ stoch: stoch2,
5329
5430
  crossover: crossover2,
5330
5431
  crossunder: crossunder2,
5331
5432
  cross: cross2,
@@ -5342,10 +5443,18 @@ var ta = {
5342
5443
  ichimoku: ichimoku2,
5343
5444
  linreg: linreg2,
5344
5445
  alma: alma2,
5345
- zigzag: zigzag2
5446
+ zigzag: zigzag2,
5447
+ cci: cci2,
5448
+ sar: sar2
5346
5449
  };
5347
5450
 
5348
5451
  // src/utils/index.ts
5452
+ function isNA(value) {
5453
+ return value === null || value === void 0 || Number.isNaN(value);
5454
+ }
5455
+ function nz(value, defaultValue = 0) {
5456
+ return isNA(value) ? defaultValue : value;
5457
+ }
5349
5458
  function ohlcFromBars(bars) {
5350
5459
  return {
5351
5460
  open: bars.map((b2) => b2.open),
@@ -5366,6 +5475,229 @@ function getLow(ohlc) {
5366
5475
  function getOpen(ohlc) {
5367
5476
  return ohlc.open;
5368
5477
  }
5478
+ function getSourceSeries(bars, source = "close") {
5479
+ const open = new Series(bars, (bar) => bar.open);
5480
+ const high = new Series(bars, (bar) => bar.high);
5481
+ const low = new Series(bars, (bar) => bar.low);
5482
+ const close = new Series(bars, (bar) => bar.close);
5483
+ switch (source) {
5484
+ case "open":
5485
+ return open;
5486
+ case "high":
5487
+ return high;
5488
+ case "low":
5489
+ return low;
5490
+ case "close":
5491
+ return close;
5492
+ case "hl2":
5493
+ return high.add(low).div(2);
5494
+ case "hlc3":
5495
+ return high.add(low).add(close).div(3);
5496
+ case "ohlc4":
5497
+ return open.add(high).add(low).add(close).div(4);
5498
+ case "hlcc4":
5499
+ return high.add(low).add(close).add(close).div(4);
5500
+ default:
5501
+ return close;
5502
+ }
5503
+ }
5504
+
5505
+ // src/lib/zigzag/zigzag.ts
5506
+ var defaultSettings = {
5507
+ devThreshold: 5,
5508
+ depth: 10,
5509
+ lineColor: "#2962FF",
5510
+ extendLast: true,
5511
+ displayReversalPrice: true,
5512
+ displayCumulativeVolume: true,
5513
+ displayReversalPriceChange: true,
5514
+ differencePriceMode: "Absolute",
5515
+ allowZigZagOnOneBar: true
5516
+ };
5517
+ var ZigZag = class {
5518
+ settings;
5519
+ pivots = [];
5520
+ sumVol = 0;
5521
+ highBuffer = [];
5522
+ lowBuffer = [];
5523
+ timeBuffer = [];
5524
+ barCount = 0;
5525
+ constructor(settings) {
5526
+ this.settings = { ...defaultSettings, ...settings };
5527
+ }
5528
+ /**
5529
+ * Process a single bar, detecting pivots.
5530
+ * Must be called sequentially for each bar.
5531
+ * @returns true if a new pivot was detected or updated
5532
+ */
5533
+ update(bar, barIndex) {
5534
+ this.highBuffer.push(bar.high);
5535
+ this.lowBuffer.push(bar.low);
5536
+ this.timeBuffer.push(bar.time);
5537
+ this.barCount++;
5538
+ const depth = Math.max(2, Math.floor(this.settings.depth / 2));
5539
+ this.sumVol += bar.volume ?? 0;
5540
+ if (this.barCount < depth * 2 + 1)
5541
+ return false;
5542
+ let somethingChanged = this.tryFindPivot(true, depth, barIndex);
5543
+ somethingChanged = this.tryFindPivot(
5544
+ false,
5545
+ depth,
5546
+ barIndex,
5547
+ this.settings.allowZigZagOnOneBar || !somethingChanged
5548
+ ) || somethingChanged;
5549
+ return somethingChanged;
5550
+ }
5551
+ /**
5552
+ * Get the last confirmed pivot
5553
+ */
5554
+ lastPivot() {
5555
+ if (this.pivots.length === 0)
5556
+ return null;
5557
+ const last2 = this.pivots[this.pivots.length - 1];
5558
+ return last2 !== void 0 ? last2 : null;
5559
+ }
5560
+ /**
5561
+ * Get extension line to current bar (if extendLast enabled)
5562
+ */
5563
+ getExtension(currentBar, barIndex) {
5564
+ if (!this.settings.extendLast)
5565
+ return null;
5566
+ const last2 = this.lastPivot();
5567
+ if (!last2)
5568
+ return null;
5569
+ const isHigh = !last2.isHigh;
5570
+ const price = isHigh ? currentBar.high : currentBar.low;
5571
+ return {
5572
+ isHigh,
5573
+ volume: this.sumVol,
5574
+ start: last2.end,
5575
+ end: { time: currentBar.time, barIndex, price }
5576
+ };
5577
+ }
5578
+ // ============ Private Methods ============
5579
+ tryFindPivot(isHigh, depth, currentBarIndex, registerPivot = true) {
5580
+ const point = this.findPivotPoint(isHigh, depth, currentBarIndex);
5581
+ if (!point || !registerPivot)
5582
+ return false;
5583
+ return this.newPivotPointFound(isHigh, point);
5584
+ }
5585
+ /**
5586
+ * Check if a bar from `depth` bars back is a pivot point.
5587
+ * A pivot high has prices below it on both sides.
5588
+ * A pivot low has prices above it on both sides.
5589
+ */
5590
+ findPivotPoint(isHigh, depth, currentBarIndex) {
5591
+ const buffer = isHigh ? this.highBuffer : this.lowBuffer;
5592
+ const pivotBufferIdx = buffer.length - 1 - depth;
5593
+ if (pivotBufferIdx < depth)
5594
+ return null;
5595
+ const pivotPrice = buffer[pivotBufferIdx];
5596
+ if (pivotPrice === void 0)
5597
+ return null;
5598
+ for (let i = pivotBufferIdx + 1; i < buffer.length; i++) {
5599
+ const price = buffer[i];
5600
+ if (price === void 0)
5601
+ return null;
5602
+ if (isHigh) {
5603
+ if (price > pivotPrice)
5604
+ return null;
5605
+ } else {
5606
+ if (price < pivotPrice)
5607
+ return null;
5608
+ }
5609
+ }
5610
+ for (let i = pivotBufferIdx - depth; i < pivotBufferIdx; i++) {
5611
+ const price = buffer[i];
5612
+ if (price === void 0)
5613
+ return null;
5614
+ if (isHigh) {
5615
+ if (price >= pivotPrice)
5616
+ return null;
5617
+ } else {
5618
+ if (price <= pivotPrice)
5619
+ return null;
5620
+ }
5621
+ }
5622
+ const pivotBarIndex = currentBarIndex - depth;
5623
+ const pivotTime = this.timeBuffer[pivotBufferIdx];
5624
+ if (pivotTime === void 0)
5625
+ return null;
5626
+ return {
5627
+ time: pivotTime,
5628
+ barIndex: pivotBarIndex,
5629
+ price: pivotPrice
5630
+ };
5631
+ }
5632
+ /**
5633
+ * Calculate percentage deviation from base price to new price
5634
+ */
5635
+ calcDev(basePrice, price) {
5636
+ return 100 * (price - basePrice) / Math.abs(basePrice);
5637
+ }
5638
+ /**
5639
+ * Handle a newly detected pivot point.
5640
+ * Either updates existing pivot (if same direction) or adds new pivot (if direction changed).
5641
+ */
5642
+ newPivotPointFound(isHigh, point) {
5643
+ const last2 = this.lastPivot();
5644
+ if (!last2) {
5645
+ this.pivots.push({
5646
+ isHigh,
5647
+ volume: this.sumVol,
5648
+ start: point,
5649
+ end: point
5650
+ });
5651
+ this.sumVol = 0;
5652
+ return true;
5653
+ }
5654
+ if (last2.isHigh === isHigh) {
5655
+ const isMoreExtreme = isHigh ? point.price > last2.end.price : point.price < last2.end.price;
5656
+ if (isMoreExtreme) {
5657
+ last2.end = point;
5658
+ last2.volume += this.sumVol;
5659
+ this.sumVol = 0;
5660
+ return true;
5661
+ }
5662
+ } else {
5663
+ const dev2 = this.calcDev(last2.end.price, point.price);
5664
+ const threshold = this.settings.devThreshold;
5665
+ const meetsThreshold = last2.isHigh ? dev2 <= -threshold : dev2 >= threshold;
5666
+ if (meetsThreshold) {
5667
+ this.pivots.push({
5668
+ isHigh,
5669
+ volume: this.sumVol,
5670
+ start: last2.end,
5671
+ end: point
5672
+ });
5673
+ this.sumVol = 0;
5674
+ return true;
5675
+ }
5676
+ }
5677
+ return false;
5678
+ }
5679
+ };
5680
+ function calculateZigZag(bars, settings) {
5681
+ if (bars.length === 0) {
5682
+ return { pivots: [], extension: null };
5683
+ }
5684
+ const zz = new ZigZag(settings);
5685
+ for (let i = 0; i < bars.length; i++) {
5686
+ const bar = bars[i];
5687
+ if (bar !== void 0) {
5688
+ zz.update(bar, i);
5689
+ }
5690
+ }
5691
+ const lastBar = bars[bars.length - 1];
5692
+ if (lastBar === void 0) {
5693
+ return { pivots: zz.pivots, extension: null };
5694
+ }
5695
+ const extension = zz.getExtension(lastBar, bars.length - 1);
5696
+ return {
5697
+ pivots: zz.pivots,
5698
+ extension
5699
+ };
5700
+ }
5369
5701
 
5370
5702
  // src/indicator.ts
5371
5703
  function indicator(metadata, setup) {
@@ -5485,7 +5817,7 @@ var input = {
5485
5817
  defaultValue,
5486
5818
  value: defaultValue,
5487
5819
  title: options.title,
5488
- options: ["open", "high", "low", "close", "hl2", "hlc3", "ohlc4"]
5820
+ options: ["open", "high", "low", "close", "hl2", "hlc3", "ohlc4", "hlcc4"]
5489
5821
  };
5490
5822
  },
5491
5823
  /**
@@ -6081,18 +6413,23 @@ var info = {
6081
6413
  indicator: ["indicator", "input", "plotHelper", "createPlot"]
6082
6414
  }
6083
6415
  };
6416
+ function alertcondition(_condition, _title, _message) {
6417
+ }
6084
6418
  export {
6085
6419
  BarData,
6086
6420
  LightweightChartsAdapter,
6087
6421
  Series,
6088
6422
  SimpleInputAdapter,
6089
6423
  VERSION,
6424
+ ZigZag,
6090
6425
  abs,
6426
+ alertcondition,
6091
6427
  array_exports as array,
6092
6428
  atr2 as atr,
6093
6429
  avg,
6094
6430
  bb2 as bb,
6095
6431
  box_exports as box,
6432
+ calculateZigZag,
6096
6433
  ceil,
6097
6434
  change2 as change,
6098
6435
  chartpoint_exports as chartPoint,
@@ -6113,6 +6450,7 @@ export {
6113
6450
  getHigh,
6114
6451
  getLow,
6115
6452
  getOpen,
6453
+ getSourceSeries,
6116
6454
  hline,
6117
6455
  indicator,
6118
6456
  info,
@@ -6131,8 +6469,9 @@ export {
6131
6469
  matrix_exports as matrix,
6132
6470
  max2 as max,
6133
6471
  min2 as min,
6134
- na,
6472
+ isNA as na,
6135
6473
  new_color2 as new_color,
6474
+ nz,
6136
6475
  ohlcFromBars,
6137
6476
  plot2 as plot,
6138
6477
  plot as plotHelper,
@@ -6156,5 +6495,6 @@ export {
6156
6495
  time_exports as time,
6157
6496
  tr2 as tr,
6158
6497
  vwap2 as vwap,
6159
- xloc
6498
+ xloc,
6499
+ defaultSettings as zigZagDefaults
6160
6500
  };
package/dist/input.d.ts CHANGED
@@ -30,7 +30,7 @@ export interface StringInputOptions {
30
30
  title?: string;
31
31
  options?: string[];
32
32
  }
33
- export type SourceType = 'open' | 'high' | 'low' | 'close' | 'hl2' | 'hlc3' | 'ohlc4';
33
+ export type SourceType = 'open' | 'high' | 'low' | 'close' | 'hl2' | 'hlc3' | 'ohlc4' | 'hlcc4';
34
34
  export declare const input: {
35
35
  int(defaultValue: number, options?: IntInputOptions): InputValue<number>;
36
36
  float(defaultValue: number, options?: FloatInputOptions): InputValue<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU,CAAC,CAAC;IAE3B,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IAErD,YAAY,EAAE,CAAC,CAAC;IAEhB,KAAK,EAAE,CAAC,CAAC;IAET,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAKD,MAAM,WAAW,eAAe;IAE9B,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,iBAAiB;IAEhC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,kBAAkB;IAEjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,gBAAgB;IAE/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,kBAAkB;IAEjC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAKD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAKtF,eAAO,MAAM,KAAK;sBAaE,MAAM,YAAW,eAAe,GAAQ,UAAU,CAAC,MAAM,CAAC;wBAwBxD,MAAM,YAAW,iBAAiB,GAAQ,UAAU,CAAC,MAAM,CAAC;0BAwB3D,UAAU,YAAqB,kBAAkB,GAAQ,UAAU,CAAC,UAAU,CAAC;uBAsBjF,OAAO,YAAW,gBAAgB,GAAQ,UAAU,CAAC,OAAO,CAAC;yBAqB3D,MAAM,YAAW,kBAAkB,GAAQ,UAAU,CAAC,MAAM,CAAC;CASnF,CAAC"}
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU,CAAC,CAAC;IAE3B,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IAErD,YAAY,EAAE,CAAC,CAAC;IAEhB,KAAK,EAAE,CAAC,CAAC;IAET,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAKD,MAAM,WAAW,eAAe;IAE9B,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,iBAAiB;IAEhC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,kBAAkB;IAEjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,gBAAgB;IAE/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,kBAAkB;IAEjC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAKD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAKhG,eAAO,MAAM,KAAK;sBAaE,MAAM,YAAW,eAAe,GAAQ,UAAU,CAAC,MAAM,CAAC;wBAwBxD,MAAM,YAAW,iBAAiB,GAAQ,UAAU,CAAC,MAAM,CAAC;0BAwB3D,UAAU,YAAqB,kBAAkB,GAAQ,UAAU,CAAC,UAAU,CAAC;uBAsBjF,OAAO,YAAW,gBAAgB,GAAQ,UAAU,CAAC,OAAO,CAAC;yBAqB3D,MAAM,YAAW,kBAAkB,GAAQ,UAAU,CAAC,MAAM,CAAC;CASnF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './zigzag';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/index.ts"],"names":[],"mappings":"AAOA,cAAc,UAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { ZigZag, calculateZigZag, defaultSettings as zigZagDefaults, type ZigZagSettings, type ZigZagPoint, type ZigZagPivot, type ZigZagResult, } from './zigzag';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/zigzag/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,MAAM,EACN,eAAe,EACf,eAAe,IAAI,cAAc,EACjC,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,YAAY,GAClB,MAAM,UAAU,CAAC"}