oakscriptjs 0.9.5 → 0.9.6
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/cjs/array/index.d.ts +84 -27
- package/dist/cjs/array/index.d.ts.map +1 -1
- package/dist/cjs/array/index.js +235 -78
- package/dist/cjs/array/index.js.map +3 -3
- package/dist/cjs/callsite/index.d.ts +81 -2
- package/dist/cjs/callsite/index.d.ts.map +1 -1
- package/dist/cjs/callsite/index.js +62 -1
- package/dist/cjs/callsite/index.js.map +2 -2
- package/dist/cjs/color/index.d.ts +7 -3
- package/dist/cjs/color/index.d.ts.map +1 -1
- package/dist/cjs/color/index.js +6 -1
- package/dist/cjs/color/index.js.map +2 -2
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/label/index.d.ts.map +1 -1
- package/dist/cjs/label/index.js +2 -1
- package/dist/cjs/label/index.js.map +2 -2
- package/dist/cjs/linefill/index.d.ts.map +1 -1
- package/dist/cjs/linefill/index.js +1 -0
- package/dist/cjs/linefill/index.js.map +2 -2
- package/dist/cjs/math/index.d.ts +76 -21
- package/dist/cjs/math/index.d.ts.map +1 -1
- package/dist/cjs/math/index.js +155 -41
- package/dist/cjs/math/index.js.map +3 -3
- package/dist/cjs/matrix/index.d.ts.map +1 -1
- package/dist/cjs/matrix/index.js +42 -36
- package/dist/cjs/matrix/index.js.map +2 -2
- package/dist/cjs/runtime/series.d.ts +9 -0
- package/dist/cjs/runtime/series.d.ts.map +1 -1
- package/dist/cjs/runtime/series.js +16 -2
- package/dist/cjs/runtime/series.js.map +2 -2
- package/dist/cjs/script/index.d.ts +15 -31
- package/dist/cjs/script/index.d.ts.map +1 -1
- package/dist/cjs/script/index.js +32 -0
- package/dist/cjs/script/index.js.map +2 -2
- package/dist/cjs/session/calendar.d.ts.map +1 -1
- package/dist/cjs/session/calendar.js +15 -2
- package/dist/cjs/session/calendar.js.map +2 -2
- package/dist/cjs/str/index.d.ts +50 -38
- package/dist/cjs/str/index.d.ts.map +1 -1
- package/dist/cjs/str/index.js +43 -15
- package/dist/cjs/str/index.js.map +2 -2
- package/dist/cjs/str/messageformat.d.ts +2 -1
- package/dist/cjs/str/messageformat.d.ts.map +1 -1
- package/dist/cjs/str/messageformat.js +4 -1
- package/dist/cjs/str/messageformat.js.map +2 -2
- package/dist/cjs/str/numberformat.d.ts +4 -0
- package/dist/cjs/str/numberformat.d.ts.map +1 -1
- package/dist/cjs/str/numberformat.js +26 -4
- package/dist/cjs/str/numberformat.js.map +3 -3
- package/dist/cjs/ta/index.d.ts +86 -43
- package/dist/cjs/ta/index.d.ts.map +1 -1
- package/dist/cjs/ta/index.js +173 -267
- package/dist/cjs/ta/index.js.map +3 -3
- package/dist/cjs/ta/running-sum.d.ts +54 -2
- package/dist/cjs/ta/running-sum.d.ts.map +1 -1
- package/dist/cjs/ta/running-sum.js +132 -52
- package/dist/cjs/ta/running-sum.js.map +2 -2
- package/dist/cjs/ta-series.d.ts +4 -4
- package/dist/cjs/ta-series.d.ts.map +1 -1
- package/dist/cjs/ta-series.js +4 -3
- package/dist/cjs/ta-series.js.map +2 -2
- package/dist/cjs/time/datestring.d.ts +1 -0
- package/dist/cjs/time/datestring.d.ts.map +1 -1
- package/dist/cjs/time/datestring.js +7 -0
- package/dist/cjs/time/datestring.js.map +2 -2
- package/dist/cjs/time/index.d.ts.map +1 -1
- package/dist/cjs/time/index.js +2 -1
- package/dist/cjs/time/index.js.map +2 -2
- package/dist/cjs/time/session.d.ts +28 -9
- package/dist/cjs/time/session.d.ts.map +1 -1
- package/dist/cjs/time/session.js +74 -28
- package/dist/cjs/time/session.js.map +2 -2
- package/dist/cjs/time/timezone.d.ts +5 -0
- package/dist/cjs/time/timezone.d.ts.map +1 -1
- package/dist/cjs/time/timezone.js +15 -1
- package/dist/cjs/time/timezone.js.map +2 -2
- package/dist/esm/array/index.d.ts +84 -27
- package/dist/esm/array/index.d.ts.map +1 -1
- package/dist/esm/array/index.js +373 -111
- package/dist/esm/array/index.js.map +1 -1
- package/dist/esm/callsite/index.d.ts +81 -2
- package/dist/esm/callsite/index.d.ts.map +1 -1
- package/dist/esm/callsite/index.js +145 -3
- package/dist/esm/callsite/index.js.map +1 -1
- package/dist/esm/color/index.d.ts +7 -3
- package/dist/esm/color/index.d.ts.map +1 -1
- package/dist/esm/color/index.js +15 -3
- package/dist/esm/color/index.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/label/index.d.ts.map +1 -1
- package/dist/esm/label/index.js +2 -1
- package/dist/esm/label/index.js.map +1 -1
- package/dist/esm/linefill/index.d.ts.map +1 -1
- package/dist/esm/linefill/index.js +3 -0
- package/dist/esm/linefill/index.js.map +1 -1
- package/dist/esm/math/index.d.ts +76 -21
- package/dist/esm/math/index.d.ts.map +1 -1
- package/dist/esm/math/index.js +227 -61
- package/dist/esm/math/index.js.map +1 -1
- package/dist/esm/matrix/index.d.ts.map +1 -1
- package/dist/esm/matrix/index.js +57 -43
- package/dist/esm/matrix/index.js.map +1 -1
- package/dist/esm/runtime/series.d.ts +9 -0
- package/dist/esm/runtime/series.d.ts.map +1 -1
- package/dist/esm/runtime/series.js +18 -1
- package/dist/esm/runtime/series.js.map +1 -1
- package/dist/esm/script/index.d.ts +15 -31
- package/dist/esm/script/index.d.ts.map +1 -1
- package/dist/esm/script/index.js +44 -1
- package/dist/esm/script/index.js.map +1 -1
- package/dist/esm/session/calendar.d.ts.map +1 -1
- package/dist/esm/session/calendar.js +22 -2
- package/dist/esm/session/calendar.js.map +1 -1
- package/dist/esm/str/index.d.ts +50 -38
- package/dist/esm/str/index.d.ts.map +1 -1
- package/dist/esm/str/index.js +103 -52
- package/dist/esm/str/index.js.map +1 -1
- package/dist/esm/str/messageformat.d.ts +2 -1
- package/dist/esm/str/messageformat.d.ts.map +1 -1
- package/dist/esm/str/messageformat.js +7 -2
- package/dist/esm/str/messageformat.js.map +1 -1
- package/dist/esm/str/numberformat.d.ts +4 -0
- package/dist/esm/str/numberformat.d.ts.map +1 -1
- package/dist/esm/str/numberformat.js +38 -4
- package/dist/esm/str/numberformat.js.map +1 -1
- package/dist/esm/ta/index.d.ts +86 -43
- package/dist/esm/ta/index.d.ts.map +1 -1
- package/dist/esm/ta/index.js +296 -348
- package/dist/esm/ta/index.js.map +1 -1
- package/dist/esm/ta/running-sum.d.ts +54 -2
- package/dist/esm/ta/running-sum.d.ts.map +1 -1
- package/dist/esm/ta/running-sum.js +166 -71
- package/dist/esm/ta/running-sum.js.map +1 -1
- package/dist/esm/ta-series.d.ts +4 -4
- package/dist/esm/ta-series.d.ts.map +1 -1
- package/dist/esm/ta-series.js +5 -4
- package/dist/esm/ta-series.js.map +1 -1
- package/dist/esm/time/datestring.d.ts +1 -0
- package/dist/esm/time/datestring.d.ts.map +1 -1
- package/dist/esm/time/datestring.js +12 -0
- package/dist/esm/time/datestring.js.map +1 -1
- package/dist/esm/time/index.d.ts.map +1 -1
- package/dist/esm/time/index.js +3 -1
- package/dist/esm/time/index.js.map +1 -1
- package/dist/esm/time/session.d.ts +28 -9
- package/dist/esm/time/session.d.ts.map +1 -1
- package/dist/esm/time/session.js +113 -42
- package/dist/esm/time/session.js.map +1 -1
- package/dist/esm/time/timezone.d.ts +5 -0
- package/dist/esm/time/timezone.d.ts.map +1 -1
- package/dist/esm/time/timezone.js +21 -1
- package/dist/esm/time/timezone.js.map +1 -1
- package/package.json +1 -1
- package/src/array/index.ts +352 -127
- package/src/callsite/index.ts +147 -3
- package/src/color/index.ts +15 -5
- package/src/index.ts +1 -1
- package/src/label/index.ts +2 -1
- package/src/linefill/index.ts +2 -0
- package/src/math/index.ts +256 -74
- package/src/matrix/index.ts +52 -52
- package/src/runtime/series.ts +22 -1
- package/src/script/index.ts +53 -1
- package/src/session/calendar.ts +22 -2
- package/src/str/index.ts +95 -51
- package/src/str/messageformat.ts +7 -2
- package/src/str/numberformat.ts +39 -4
- package/src/ta/index.ts +306 -386
- package/src/ta/running-sum.ts +187 -74
- package/src/ta-series.ts +8 -7
- package/src/time/datestring.ts +10 -0
- package/src/time/index.ts +3 -1
- package/src/time/session.ts +97 -47
- package/src/time/timezone.ts +21 -1
package/dist/cjs/ta/index.js
CHANGED
|
@@ -92,18 +92,13 @@ module.exports = __toCommonJS(ta_exports);
|
|
|
92
92
|
var import_compare = require("../compare/index.js");
|
|
93
93
|
var import_running_sum = require("./running-sum.js");
|
|
94
94
|
function sma(source, length) {
|
|
95
|
+
if (typeof length !== "number") {
|
|
96
|
+
const sums = (0, import_running_sum.runningSumSeries)(source, length, "ta.sma");
|
|
97
|
+
return sums.map((sum, i) => sum / Math.floor(length[i]));
|
|
98
|
+
}
|
|
95
99
|
const len = Math.floor(length);
|
|
96
100
|
return (0, import_running_sum.runningSum)(source, len).map((sum) => sum / len);
|
|
97
101
|
}
|
|
98
|
-
function strictWindowMean(source, length) {
|
|
99
|
-
const len = Math.floor(length);
|
|
100
|
-
return Array.from({ length: source.length }, (_, i) => {
|
|
101
|
-
if (i < len - 1) return NaN;
|
|
102
|
-
let sum = 0;
|
|
103
|
-
for (let j = 0; j < len; j++) sum += source[i - j];
|
|
104
|
-
return sum / len;
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
102
|
function ema(source, length) {
|
|
108
103
|
const result = [];
|
|
109
104
|
const len = Math.floor(length);
|
|
@@ -185,7 +180,7 @@ function bb(series, length, mult) {
|
|
|
185
180
|
return [basis, upper, lower];
|
|
186
181
|
}
|
|
187
182
|
function stdev(source, length, biased = true) {
|
|
188
|
-
return
|
|
183
|
+
return varianceOf(source, length, biased, "ta.stdev").map((v) => Number.isNaN(v) ? NaN : v > 0 ? Math.sqrt(v) : 0);
|
|
189
184
|
}
|
|
190
185
|
function lastValues(source, i, length) {
|
|
191
186
|
const values = [];
|
|
@@ -365,20 +360,15 @@ function rma(source, length) {
|
|
|
365
360
|
const len = Math.floor(length);
|
|
366
361
|
let firstValidIndex = -1;
|
|
367
362
|
let validCount = 0;
|
|
368
|
-
let initSum = 0;
|
|
369
363
|
for (let i = 0; i < source.length; i++) {
|
|
370
364
|
const val = source[i];
|
|
371
|
-
if (val !== void 0 && Number.isFinite(val)) {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
if (validCount === len) {
|
|
375
|
-
firstValidIndex = i;
|
|
376
|
-
break;
|
|
377
|
-
}
|
|
365
|
+
if (val !== void 0 && Number.isFinite(val) && ++validCount === len) {
|
|
366
|
+
firstValidIndex = i;
|
|
367
|
+
break;
|
|
378
368
|
}
|
|
379
369
|
}
|
|
380
|
-
let rmaValue = validCount > 0 ? initSum / validCount : NaN;
|
|
381
370
|
const rmaInitialized = firstValidIndex >= 0;
|
|
371
|
+
let rmaValue = rmaInitialized ? (0, import_running_sum.runningSum)(source.slice(0, firstValidIndex + 1), len)[firstValidIndex] / len : NaN;
|
|
382
372
|
for (let i = 0; i < source.length; i++) {
|
|
383
373
|
if (!rmaInitialized || i < firstValidIndex) {
|
|
384
374
|
result.push(NaN);
|
|
@@ -396,6 +386,10 @@ function rma(source, length) {
|
|
|
396
386
|
}
|
|
397
387
|
return result;
|
|
398
388
|
}
|
|
389
|
+
function wmaAdd(a, b) {
|
|
390
|
+
const sum = a + b;
|
|
391
|
+
return Math.abs(sum) <= 1e-10 * Math.max(1, Math.abs(a) + Math.abs(b)) ? 0 : sum;
|
|
392
|
+
}
|
|
399
393
|
function wma(source, length) {
|
|
400
394
|
const result = [];
|
|
401
395
|
const len = Math.floor(length);
|
|
@@ -418,7 +412,7 @@ function wma(source, length) {
|
|
|
418
412
|
let weightSum = 0;
|
|
419
413
|
for (let j = len - 1; j >= 0; j--) {
|
|
420
414
|
const weight = len - j;
|
|
421
|
-
sum
|
|
415
|
+
sum = wmaAdd(sum, filled[i - j] * weight);
|
|
422
416
|
weightSum += weight;
|
|
423
417
|
}
|
|
424
418
|
result.push(sum / weightSum);
|
|
@@ -440,18 +434,29 @@ function cum(source) {
|
|
|
440
434
|
});
|
|
441
435
|
}
|
|
442
436
|
function cross(source1, source2) {
|
|
443
|
-
|
|
437
|
+
const result = [];
|
|
438
|
+
let side = 0;
|
|
439
|
+
for (let i = 0; i < source1.length; i++) {
|
|
440
|
+
const a = source1[i];
|
|
441
|
+
const b = source2[i];
|
|
442
|
+
if (Number.isNaN(a) || Number.isNaN(b)) {
|
|
443
|
+
result.push(false);
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
result.push(side < 0 && a > b || side > 0 && a < b);
|
|
447
|
+
if (a < b) side = -1;
|
|
448
|
+
else if (a > b) side = 1;
|
|
449
|
+
}
|
|
450
|
+
return result;
|
|
444
451
|
}
|
|
445
452
|
function monotonic(source, length, step) {
|
|
446
453
|
const result = [];
|
|
447
|
-
|
|
454
|
+
let count = 0;
|
|
448
455
|
for (let i = 0; i < source.length; i++) {
|
|
449
456
|
const v = source[i];
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
for (let j = 1; ok && j <= length; j++) ok = step(values[n - j], values[n - j - 1]);
|
|
454
|
-
result.push(ok);
|
|
457
|
+
const prev = i > 0 ? source[i - 1] : NaN;
|
|
458
|
+
if (!Number.isNaN(v) && !Number.isNaN(prev)) count = step(v, prev) ? count + 1 : 0;
|
|
459
|
+
result.push(count >= length);
|
|
455
460
|
}
|
|
456
461
|
return result;
|
|
457
462
|
}
|
|
@@ -494,24 +499,22 @@ function mom(source, length) {
|
|
|
494
499
|
return result;
|
|
495
500
|
}
|
|
496
501
|
function dev(source, length) {
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
for (let j = 0; j < length; j++) {
|
|
505
|
-
if (!isNaN(source[i - j])) {
|
|
506
|
-
sum += Math.abs(source[i - j] - meanValues[i]);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
result.push(sum / length);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
return result;
|
|
502
|
+
const len = Math.floor(length);
|
|
503
|
+
return sma(source, len).map((mean, i) => {
|
|
504
|
+
if (i < len - 1 || Number.isNaN(mean)) return NaN;
|
|
505
|
+
let sum = 0;
|
|
506
|
+
for (let k = 0; k < len; k++) sum += Math.abs(source[i - k] - mean);
|
|
507
|
+
return sum / len;
|
|
508
|
+
});
|
|
513
509
|
}
|
|
514
510
|
function variance(source, length, biased = true) {
|
|
511
|
+
return varianceOf(source, length, biased, "ta.variance");
|
|
512
|
+
}
|
|
513
|
+
function varianceOf(source, length, biased, name) {
|
|
514
|
+
if (typeof length !== "number") {
|
|
515
|
+
const result = (0, import_running_sum.runningVarianceSeries)(source, length, biased, name);
|
|
516
|
+
return biased ? result : result.map((v, i) => Math.floor(length[i]) > 1 ? v : NaN);
|
|
517
|
+
}
|
|
515
518
|
const len = Math.floor(length);
|
|
516
519
|
if ((biased ? len : len - 1) <= 0) return source.map(() => NaN);
|
|
517
520
|
return (0, import_running_sum.runningVariance)(source, len, biased);
|
|
@@ -547,20 +550,10 @@ function median(source, length) {
|
|
|
547
550
|
return out;
|
|
548
551
|
}
|
|
549
552
|
function swma(source) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
} else {
|
|
555
|
-
if (isNaN(source[i]) || isNaN(source[i - 1]) || isNaN(source[i - 2]) || isNaN(source[i - 3])) {
|
|
556
|
-
result.push(NaN);
|
|
557
|
-
} else {
|
|
558
|
-
const value = source[i - 3] * (1 / 6) + source[i - 2] * (2 / 6) + source[i - 1] * (2 / 6) + source[i] * (1 / 6);
|
|
559
|
-
result.push(value);
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
return result;
|
|
553
|
+
return Array.from(
|
|
554
|
+
{ length: source.length },
|
|
555
|
+
(_, i) => i < 3 ? NaN : (source[i] + 2 * source[i - 1] + 2 * source[i - 2] + source[i - 3]) / 6
|
|
556
|
+
);
|
|
564
557
|
}
|
|
565
558
|
function vwma(source, length, volume) {
|
|
566
559
|
if (!volume) {
|
|
@@ -606,68 +599,39 @@ function linreg(source, length, offset = 0) {
|
|
|
606
599
|
let sumXY = 0;
|
|
607
600
|
let sumX2 = 0;
|
|
608
601
|
for (let j = 0; j < len; j++) {
|
|
609
|
-
const
|
|
602
|
+
const x = j + 1;
|
|
610
603
|
const y = source[i - (len - 1 - j)];
|
|
611
|
-
sumX +=
|
|
604
|
+
sumX += x;
|
|
612
605
|
sumY += y;
|
|
613
|
-
sumXY +=
|
|
614
|
-
sumX2 +=
|
|
606
|
+
sumXY += x * y;
|
|
607
|
+
sumX2 += x * x;
|
|
615
608
|
}
|
|
616
609
|
const slope = (len * sumXY - sumX * sumY) / (len * sumX2 - sumX * sumX);
|
|
617
|
-
const intercept =
|
|
618
|
-
|
|
619
|
-
result.push(intercept + slope * x);
|
|
610
|
+
const intercept = sumY / len - slope * sumX / len + slope;
|
|
611
|
+
result.push(intercept + slope * (len - 1 - offset));
|
|
620
612
|
}
|
|
621
613
|
}
|
|
622
614
|
}
|
|
623
615
|
return result;
|
|
624
616
|
}
|
|
625
617
|
function correlation(source1, source2, length) {
|
|
626
|
-
const
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
if (m === 0) {
|
|
646
|
-
result.push(NaN);
|
|
647
|
-
continue;
|
|
648
|
-
}
|
|
649
|
-
let sum1 = 0;
|
|
650
|
-
let sum2 = 0;
|
|
651
|
-
for (let k = 0; k < m; k++) {
|
|
652
|
-
sum1 += a[k];
|
|
653
|
-
sum2 += b[k];
|
|
654
|
-
}
|
|
655
|
-
const mean1 = sum1 / m;
|
|
656
|
-
const mean2 = sum2 / m;
|
|
657
|
-
let numerator = 0;
|
|
658
|
-
let sum1Sq = 0;
|
|
659
|
-
let sum2Sq = 0;
|
|
660
|
-
for (let k = 0; k < m; k++) {
|
|
661
|
-
const dev1 = a[k] - mean1;
|
|
662
|
-
const dev2 = b[k] - mean2;
|
|
663
|
-
numerator += dev1 * dev2;
|
|
664
|
-
sum1Sq += dev1 * dev1;
|
|
665
|
-
sum2Sq += dev2 * dev2;
|
|
666
|
-
}
|
|
667
|
-
const denominator = Math.sqrt(sum1Sq * sum2Sq);
|
|
668
|
-
result.push(denominator === 0 ? NaN : numerator / denominator);
|
|
669
|
-
}
|
|
670
|
-
return result;
|
|
618
|
+
const product = Array.from({ length: source1.length }, (_, i) => {
|
|
619
|
+
const v1 = source1[i];
|
|
620
|
+
const v2 = source2[i];
|
|
621
|
+
return v1 === null || v1 === void 0 || v2 === null || v2 === void 0 ? NaN : v1 * v2;
|
|
622
|
+
});
|
|
623
|
+
const meanXY = sma(product, length);
|
|
624
|
+
const meanX = sma(source1, length);
|
|
625
|
+
const meanY = sma(source2, length);
|
|
626
|
+
const varX = variance(source1, length);
|
|
627
|
+
const varY = variance(source2, length);
|
|
628
|
+
return meanXY.map((mxy, i) => {
|
|
629
|
+
const cov = mxy - meanX[i] * meanY[i];
|
|
630
|
+
if (Number.isNaN(cov)) return NaN;
|
|
631
|
+
if (Math.abs(cov) <= 1e-10) return 0;
|
|
632
|
+
const denominator = Math.sqrt(varX[i] * varY[i]);
|
|
633
|
+
return denominator === 0 ? NaN : cov / denominator;
|
|
634
|
+
});
|
|
671
635
|
}
|
|
672
636
|
function percentrank(source, length) {
|
|
673
637
|
const result = [];
|
|
@@ -686,37 +650,27 @@ function percentrank(source, length) {
|
|
|
686
650
|
return result;
|
|
687
651
|
}
|
|
688
652
|
function cci(source, length) {
|
|
689
|
-
const result = [];
|
|
690
653
|
const smaValues = sma(source, length);
|
|
691
654
|
const devValues = dev(source, length);
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
result.push(cci2);
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
return result;
|
|
655
|
+
let last = 0;
|
|
656
|
+
return smaValues.map((mean, i) => {
|
|
657
|
+
const d = devValues[i];
|
|
658
|
+
if (Number.isNaN(mean) || Number.isNaN(d)) return NaN;
|
|
659
|
+
if (!(0, import_compare.eq)(d, 0)) last = (source[i] - mean) / (0.015 * d);
|
|
660
|
+
return last;
|
|
661
|
+
});
|
|
703
662
|
}
|
|
704
663
|
function stoch(source, high, low, length) {
|
|
705
664
|
const result = [];
|
|
706
665
|
const lowestValues = lowest(low, length);
|
|
707
666
|
const highestValues = highest(high, length);
|
|
667
|
+
let previous = NaN;
|
|
708
668
|
for (let i = 0; i < source.length; i++) {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
result.push(NaN);
|
|
715
|
-
} else {
|
|
716
|
-
const stochValue = 100 * (source[i] - lowestValues[i]) / range2;
|
|
717
|
-
result.push(stochValue);
|
|
718
|
-
}
|
|
719
|
-
}
|
|
669
|
+
const value = source[i];
|
|
670
|
+
const lo = lowestValues[i];
|
|
671
|
+
const range2 = highestValues[i] - lo;
|
|
672
|
+
if (!Number.isNaN(value) && !Number.isNaN(range2) && range2 !== 0) previous = 100 * (value - lo) / range2;
|
|
673
|
+
result.push(previous);
|
|
720
674
|
}
|
|
721
675
|
return result;
|
|
722
676
|
}
|
|
@@ -736,11 +690,14 @@ function mfi(source, length, volume) {
|
|
|
736
690
|
}
|
|
737
691
|
const upper = (0, import_running_sum.runningSum)(upperFlow, length);
|
|
738
692
|
const lower = (0, import_running_sum.runningSum)(lowerFlow, length);
|
|
739
|
-
|
|
740
|
-
|
|
693
|
+
const zero = (x) => Math.abs(x) <= 1e-10 ? 0 : x;
|
|
694
|
+
return upper.map((sumUp, i) => {
|
|
695
|
+
const u = zero(sumUp);
|
|
696
|
+
const l = zero(lower[i]);
|
|
741
697
|
if (Number.isNaN(u) || Number.isNaN(l)) return NaN;
|
|
742
698
|
if (l === 0) return 100;
|
|
743
|
-
|
|
699
|
+
const ratio = 1 + u / l;
|
|
700
|
+
return ratio === 0 ? NaN : 100 - 100 / ratio;
|
|
744
701
|
});
|
|
745
702
|
}
|
|
746
703
|
function hma(source, length) {
|
|
@@ -945,15 +902,10 @@ function tsi(source, shortLength, longLength) {
|
|
|
945
902
|
const smoothedMomentum = ema(ema(momentum, longLength), shortLength);
|
|
946
903
|
const absMomentum = momentum.map(Math.abs);
|
|
947
904
|
const smoothedAbsMomentum = ema(ema(absMomentum, longLength), shortLength);
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
} else {
|
|
953
|
-
result.push(smoothedMomentum[i] / smoothedAbsMomentum[i] * 100);
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
return result;
|
|
905
|
+
return smoothedMomentum.map((m, i) => {
|
|
906
|
+
const d = smoothedAbsMomentum[i];
|
|
907
|
+
return d === 0 ? NaN : m / d;
|
|
908
|
+
});
|
|
957
909
|
}
|
|
958
910
|
function cmo(source, length) {
|
|
959
911
|
const up = [];
|
|
@@ -1007,27 +959,13 @@ function bbw(source, length, mult) {
|
|
|
1007
959
|
return result;
|
|
1008
960
|
}
|
|
1009
961
|
function wpr(high, low, close, length = 14) {
|
|
1010
|
-
const
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
let lowestLow = low[i - length + 1];
|
|
1018
|
-
for (let j = i - length + 2; j <= i; j++) {
|
|
1019
|
-
if (high[j] > highestHigh) highestHigh = high[j];
|
|
1020
|
-
if (low[j] < lowestLow) lowestLow = low[j];
|
|
1021
|
-
}
|
|
1022
|
-
const range2 = highestHigh - lowestLow;
|
|
1023
|
-
if (range2 === 0) {
|
|
1024
|
-
result.push(NaN);
|
|
1025
|
-
} else {
|
|
1026
|
-
const wprValue = (highestHigh - close[i]) / range2 * -100;
|
|
1027
|
-
result.push(wprValue);
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
return result;
|
|
962
|
+
const highs = highest(high, length);
|
|
963
|
+
const lows = lowest(low, length);
|
|
964
|
+
return Array.from({ length: close.length }, (_, i) => {
|
|
965
|
+
const hmax = highs[i];
|
|
966
|
+
const range2 = hmax - lows[i];
|
|
967
|
+
return range2 === 0 ? NaN : 100 * (close[i] - hmax) / range2;
|
|
968
|
+
});
|
|
1031
969
|
}
|
|
1032
970
|
function vwap(source, volume, anchor, stdev_mult) {
|
|
1033
971
|
if (source.length !== volume.length) {
|
|
@@ -1036,18 +974,17 @@ function vwap(source, volume, anchor, stdev_mult) {
|
|
|
1036
974
|
const mid = [];
|
|
1037
975
|
const upper = [];
|
|
1038
976
|
const lower = [];
|
|
1039
|
-
let sumPV =
|
|
1040
|
-
let sumV =
|
|
1041
|
-
let sumPPV =
|
|
977
|
+
let sumPV = NaN;
|
|
978
|
+
let sumV = NaN;
|
|
979
|
+
let sumPPV = NaN;
|
|
1042
980
|
for (let i = 0; i < source.length; i++) {
|
|
1043
|
-
if (anchor && anchor[i]) {
|
|
1044
|
-
sumPV = 0;
|
|
1045
|
-
sumV = 0;
|
|
1046
|
-
sumPPV = 0;
|
|
1047
|
-
}
|
|
1048
981
|
const s = source[i];
|
|
1049
982
|
const v = volume[i];
|
|
1050
|
-
if (
|
|
983
|
+
if (anchor ? anchor[i] : i === 0) {
|
|
984
|
+
sumPV = s * v;
|
|
985
|
+
sumV = v;
|
|
986
|
+
sumPPV = s * s * v;
|
|
987
|
+
} else {
|
|
1051
988
|
sumPV += s * v;
|
|
1052
989
|
sumV += v;
|
|
1053
990
|
sumPPV += s * s * v;
|
|
@@ -1096,8 +1033,7 @@ function kcw(source, length = 20, mult = 2, useTrueRange = true, high, low, clos
|
|
|
1096
1033
|
if (isNaN(basis[i]) || basis[i] === 0) {
|
|
1097
1034
|
result.push(NaN);
|
|
1098
1035
|
} else {
|
|
1099
|
-
|
|
1100
|
-
result.push(width);
|
|
1036
|
+
result.push((upper[i] - lower[i]) / basis[i]);
|
|
1101
1037
|
}
|
|
1102
1038
|
}
|
|
1103
1039
|
return result;
|
|
@@ -1129,47 +1065,26 @@ function min(source) {
|
|
|
1129
1065
|
});
|
|
1130
1066
|
}
|
|
1131
1067
|
function cog(source, length = 10) {
|
|
1132
|
-
const
|
|
1133
|
-
|
|
1134
|
-
if (i <
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
let denominator = 0;
|
|
1140
|
-
for (let j = 0; j < length; j++) {
|
|
1141
|
-
const weight = j + 1;
|
|
1142
|
-
const price = source[i - length + 1 + j];
|
|
1143
|
-
numerator += weight * price;
|
|
1144
|
-
denominator += price;
|
|
1145
|
-
}
|
|
1146
|
-
if (denominator === 0) {
|
|
1147
|
-
result.push(NaN);
|
|
1148
|
-
} else {
|
|
1149
|
-
const cog2 = -1 * (numerator / denominator) + (length + 1) / 2;
|
|
1150
|
-
result.push(cog2);
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
return result;
|
|
1068
|
+
const len = Math.floor(length);
|
|
1069
|
+
return (0, import_running_sum.runningSum)(source, len).map((sum, i) => {
|
|
1070
|
+
if (i < len - 1 || Number.isNaN(sum) || sum === 0) return NaN;
|
|
1071
|
+
let num = 0;
|
|
1072
|
+
for (let k = 0; k < len; k++) num += source[i - k] * (k + 1);
|
|
1073
|
+
return -num / sum;
|
|
1074
|
+
});
|
|
1154
1075
|
}
|
|
1155
1076
|
function mode(source, length) {
|
|
1156
1077
|
const result = [];
|
|
1078
|
+
const len = Math.floor(length);
|
|
1079
|
+
const seen = [];
|
|
1157
1080
|
for (let i = 0; i < source.length; i++) {
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
}
|
|
1162
|
-
const values = [];
|
|
1163
|
-
for (let j = 0; j < length; j++) {
|
|
1164
|
-
const value = source[i - j];
|
|
1165
|
-
if (!isNaN(value)) {
|
|
1166
|
-
values.push(value);
|
|
1167
|
-
}
|
|
1168
|
-
}
|
|
1169
|
-
if (values.length === 0) {
|
|
1081
|
+
const v = source[i];
|
|
1082
|
+
if (!Number.isNaN(v)) seen.push(v);
|
|
1083
|
+
if (seen.length < len) {
|
|
1170
1084
|
result.push(NaN);
|
|
1171
1085
|
continue;
|
|
1172
1086
|
}
|
|
1087
|
+
const values = seen.slice(seen.length - len);
|
|
1173
1088
|
const frequencyMap = /* @__PURE__ */ new Map();
|
|
1174
1089
|
for (const value of values) {
|
|
1175
1090
|
frequencyMap.set(value, (frequencyMap.get(value) || 0) + 1);
|
|
@@ -1223,64 +1138,54 @@ function percentile_nearest_rank(source, length, percentage) {
|
|
|
1223
1138
|
return sortedWindow(source, length, (s) => s[rank - 1]);
|
|
1224
1139
|
}
|
|
1225
1140
|
function rci(source, length) {
|
|
1141
|
+
const len = Math.floor(length);
|
|
1226
1142
|
const result = [];
|
|
1143
|
+
const ring = new Array(len + 1).fill(0);
|
|
1227
1144
|
for (let i = 0; i < source.length; i++) {
|
|
1228
|
-
|
|
1229
|
-
|
|
1145
|
+
const v = source[i];
|
|
1146
|
+
if (Number.isNaN(v)) {
|
|
1147
|
+
result.push(i > 0 ? result[i - 1] : NaN);
|
|
1230
1148
|
continue;
|
|
1231
1149
|
}
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
values.push(source[i - length + 1 + j]);
|
|
1235
|
-
}
|
|
1236
|
-
if (values.some((v) => isNaN(v))) {
|
|
1150
|
+
ring[i % (len + 1)] = v;
|
|
1151
|
+
if (i < len) {
|
|
1237
1152
|
result.push(NaN);
|
|
1238
1153
|
continue;
|
|
1239
1154
|
}
|
|
1240
|
-
const
|
|
1241
|
-
const
|
|
1242
|
-
const ranks = new Array(
|
|
1243
|
-
let
|
|
1244
|
-
|
|
1245
|
-
let
|
|
1246
|
-
while (
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
}
|
|
1262
|
-
const
|
|
1263
|
-
const
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
}
|
|
1270
|
-
if (tieCount > 1) {
|
|
1271
|
-
tieCorrection += (tieCount * tieCount * tieCount - tieCount) / 12;
|
|
1272
|
-
}
|
|
1273
|
-
j += tieCount;
|
|
1274
|
-
}
|
|
1275
|
-
const A = base - tieCorrection;
|
|
1276
|
-
const B = base;
|
|
1277
|
-
let rho;
|
|
1278
|
-
if (A === 0 || B === 0) {
|
|
1279
|
-
rho = 0;
|
|
1280
|
-
} else {
|
|
1281
|
-
rho = (A + B - sumSquaredDiff) / (2 * Math.sqrt(A * B));
|
|
1155
|
+
const values = Array.from({ length: len }, (_, j) => ring[(i - j) % (len + 1)]);
|
|
1156
|
+
const order = values.map((_, j) => j).sort((a, b) => values[a] - values[b]);
|
|
1157
|
+
const ranks = new Array(len);
|
|
1158
|
+
for (let g = 0; g < len; ) {
|
|
1159
|
+
const anchor = values[order[g]];
|
|
1160
|
+
let end = g + 1;
|
|
1161
|
+
while (end < len && values[order[end]] - anchor < 1e-10) end++;
|
|
1162
|
+
const avgRank = len - 1 - (g + g + (end - g) - 1) / 2;
|
|
1163
|
+
for (let k = g; k < end; k++) ranks[order[k]] = avgRank;
|
|
1164
|
+
g = end;
|
|
1165
|
+
}
|
|
1166
|
+
let sumX = 0;
|
|
1167
|
+
let sumY = 0;
|
|
1168
|
+
let sumX2 = 0;
|
|
1169
|
+
let sumY2 = 0;
|
|
1170
|
+
for (let k = 0; k < len; k++) {
|
|
1171
|
+
const y = ranks[k];
|
|
1172
|
+
sumX += k;
|
|
1173
|
+
sumY += y;
|
|
1174
|
+
sumX2 += k * k;
|
|
1175
|
+
sumY2 += y * y;
|
|
1176
|
+
}
|
|
1177
|
+
const meanX = sumX / len;
|
|
1178
|
+
const meanY = sumY / len;
|
|
1179
|
+
const varX = sumX2 / len - meanX * meanX;
|
|
1180
|
+
const varY = sumY2 / len - meanY * meanY;
|
|
1181
|
+
if (!(varX > 0) || !(varY > 0)) {
|
|
1182
|
+
result.push(NaN);
|
|
1183
|
+
continue;
|
|
1282
1184
|
}
|
|
1283
|
-
|
|
1185
|
+
let cov = 0;
|
|
1186
|
+
for (let k = 0; k < len; k++) cov += (k - meanX) * (ranks[k] - meanY);
|
|
1187
|
+
cov /= len;
|
|
1188
|
+
result.push(100 * cov / (Math.sqrt(varX) * Math.sqrt(varY)));
|
|
1284
1189
|
}
|
|
1285
1190
|
return result;
|
|
1286
1191
|
}
|
|
@@ -1627,13 +1532,14 @@ function pvt(close, volume) {
|
|
|
1627
1532
|
);
|
|
1628
1533
|
}
|
|
1629
1534
|
function accdist(high, low, close, volume) {
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1535
|
+
let ad = 0;
|
|
1536
|
+
return close.map((c, i) => {
|
|
1537
|
+
const h = high[i];
|
|
1538
|
+
const l = low[i];
|
|
1539
|
+
const mfv = (c - l - (h - c)) / (h - l) * volume[i];
|
|
1540
|
+
if (Number.isFinite(mfv)) ad += mfv;
|
|
1541
|
+
return ad;
|
|
1542
|
+
});
|
|
1637
1543
|
}
|
|
1638
1544
|
function iii(high, low, close, volume) {
|
|
1639
1545
|
return close.map((c, i) => {
|