oakscriptjs 0.7.2 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/array/index.d.ts.map +1 -1
- package/dist/callsite/index.d.ts +7 -0
- package/dist/callsite/index.d.ts.map +1 -0
- package/dist/color/index.d.ts +4 -4
- package/dist/color/index.d.ts.map +1 -1
- package/dist/index.cjs +348 -257
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +348 -257
- package/dist/runtime/index.cjs +1 -1
- package/dist/runtime/index.mjs +1 -1
- package/dist/runtime/types.d.ts +17 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/script/index.cjs +1954 -1712
- package/dist/script/index.d.ts +167 -18
- package/dist/script/index.d.ts.map +1 -1
- package/dist/script/index.mjs +1954 -1712
- package/dist/strategy/index.d.ts +195 -0
- package/dist/strategy/index.d.ts.map +1 -0
- package/dist/ta/index.d.ts.map +1 -1
- package/dist/types/metadata.d.ts +9 -1
- package/dist/types/metadata.d.ts.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -85,13 +85,47 @@ __export(ta_exports, {
|
|
|
85
85
|
wvad: () => wvad,
|
|
86
86
|
zigzag: () => zigzag
|
|
87
87
|
});
|
|
88
|
+
|
|
89
|
+
// src/compare/index.ts
|
|
90
|
+
var compare_exports = {};
|
|
91
|
+
__export(compare_exports, {
|
|
92
|
+
EPSILON: () => EPSILON,
|
|
93
|
+
eq: () => eq,
|
|
94
|
+
ge: () => ge,
|
|
95
|
+
gt: () => gt,
|
|
96
|
+
le: () => le,
|
|
97
|
+
lt: () => lt,
|
|
98
|
+
ne: () => ne
|
|
99
|
+
});
|
|
100
|
+
var EPSILON = 1e-10;
|
|
101
|
+
var valid = (a, b2) => !Number.isNaN(a) && !Number.isNaN(b2);
|
|
102
|
+
function eq(a, b2) {
|
|
103
|
+
return valid(a, b2) && Math.abs(a - b2) <= EPSILON;
|
|
104
|
+
}
|
|
105
|
+
function ne(a, b2) {
|
|
106
|
+
return valid(a, b2) && Math.abs(a - b2) > EPSILON;
|
|
107
|
+
}
|
|
108
|
+
function lt(a, b2) {
|
|
109
|
+
return valid(a, b2) && b2 - a > EPSILON;
|
|
110
|
+
}
|
|
111
|
+
function le(a, b2) {
|
|
112
|
+
return valid(a, b2) && a - b2 <= EPSILON;
|
|
113
|
+
}
|
|
114
|
+
function gt(a, b2) {
|
|
115
|
+
return valid(a, b2) && a - b2 > EPSILON;
|
|
116
|
+
}
|
|
117
|
+
function ge(a, b2) {
|
|
118
|
+
return valid(a, b2) && b2 - a <= EPSILON;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/ta/index.ts
|
|
88
122
|
function sma(source, length2) {
|
|
89
123
|
const result = [];
|
|
90
124
|
const len = Math.floor(length2);
|
|
91
125
|
const window = [];
|
|
92
126
|
for (let i = 0; i < source.length; i++) {
|
|
93
127
|
const v = source[i];
|
|
94
|
-
if (v !== void 0 && v !== null &&
|
|
128
|
+
if (v !== void 0 && v !== null && Number.isFinite(v)) {
|
|
95
129
|
window.push(v);
|
|
96
130
|
if (window.length > len) window.shift();
|
|
97
131
|
}
|
|
@@ -276,7 +310,7 @@ function tr(handle_na = false, high, low, close) {
|
|
|
276
310
|
const result = [];
|
|
277
311
|
for (let i = 0; i < high.length; i++) {
|
|
278
312
|
if (i === 0) {
|
|
279
|
-
result.push(high[i] - low[i]);
|
|
313
|
+
result.push(handle_na ? high[i] - low[i] : NaN);
|
|
280
314
|
} else {
|
|
281
315
|
const prevClose = close[i - 1];
|
|
282
316
|
if (isNaN(prevClose)) {
|
|
@@ -303,7 +337,7 @@ function atr(length2, high, low, close) {
|
|
|
303
337
|
"ta.atr() requires high, low, and close series. Either pass them explicitly or use createContext({ chart: { high, low, close } }) for implicit data."
|
|
304
338
|
);
|
|
305
339
|
}
|
|
306
|
-
const trueRange = tr(
|
|
340
|
+
const trueRange = tr(true, high, low, close);
|
|
307
341
|
return rma(trueRange, length2);
|
|
308
342
|
}
|
|
309
343
|
function supertrend(factor, atrPeriod, high, low, close, wicks = false) {
|
|
@@ -435,7 +469,7 @@ function lowest(source, length2) {
|
|
|
435
469
|
function cum(source) {
|
|
436
470
|
let sum4 = 0;
|
|
437
471
|
return source.map((v) => {
|
|
438
|
-
if (Number.
|
|
472
|
+
if (!Number.isFinite(v)) return NaN;
|
|
439
473
|
sum4 += v;
|
|
440
474
|
return sum4;
|
|
441
475
|
});
|
|
@@ -453,41 +487,24 @@ function cross(source1, source2) {
|
|
|
453
487
|
}
|
|
454
488
|
return result;
|
|
455
489
|
}
|
|
456
|
-
function
|
|
490
|
+
function monotonic(source, length2, step) {
|
|
457
491
|
const result = [];
|
|
492
|
+
const values2 = [];
|
|
458
493
|
for (let i = 0; i < source.length; i++) {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
isRising = false;
|
|
466
|
-
break;
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
result.push(isRising);
|
|
470
|
-
}
|
|
494
|
+
const v = source[i];
|
|
495
|
+
if (!Number.isNaN(v)) values2.push(v);
|
|
496
|
+
const n = values2.length;
|
|
497
|
+
let ok = n > length2;
|
|
498
|
+
for (let j = 1; ok && j <= length2; j++) ok = step(values2[n - j], values2[n - j - 1]);
|
|
499
|
+
result.push(ok);
|
|
471
500
|
}
|
|
472
501
|
return result;
|
|
473
502
|
}
|
|
503
|
+
function rising(source, length2) {
|
|
504
|
+
return monotonic(source, length2, gt);
|
|
505
|
+
}
|
|
474
506
|
function falling(source, length2) {
|
|
475
|
-
|
|
476
|
-
for (let i = 0; i < source.length; i++) {
|
|
477
|
-
if (i < length2) {
|
|
478
|
-
result.push(false);
|
|
479
|
-
} else {
|
|
480
|
-
let isFalling = true;
|
|
481
|
-
for (let j = 1; j <= length2; j++) {
|
|
482
|
-
if (source[i - j + 1] >= source[i - j]) {
|
|
483
|
-
isFalling = false;
|
|
484
|
-
break;
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
result.push(isFalling);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
return result;
|
|
507
|
+
return monotonic(source, length2, lt);
|
|
491
508
|
}
|
|
492
509
|
function roc(source, length2) {
|
|
493
510
|
const result = [];
|
|
@@ -711,33 +728,16 @@ function correlation(source1, source2, length2) {
|
|
|
711
728
|
function percentrank(source, length2) {
|
|
712
729
|
const result = [];
|
|
713
730
|
for (let i = 0; i < source.length; i++) {
|
|
714
|
-
|
|
731
|
+
const currentValue = source[i];
|
|
732
|
+
if (i < length2 || Number.isNaN(currentValue)) {
|
|
715
733
|
result.push(NaN);
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
let hasNaN = false;
|
|
722
|
-
for (let j = 1; j <= length2; j++) {
|
|
723
|
-
if (isNaN(source[i - j])) {
|
|
724
|
-
hasNaN = true;
|
|
725
|
-
break;
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
if (hasNaN) {
|
|
729
|
-
result.push(NaN);
|
|
730
|
-
} else {
|
|
731
|
-
const currentValue = source[i];
|
|
732
|
-
let countLessOrEqual = 0;
|
|
733
|
-
for (let j = 1; j <= length2; j++) {
|
|
734
|
-
if (source[i - j] <= currentValue) {
|
|
735
|
-
countLessOrEqual++;
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
result.push(countLessOrEqual / length2 * 100);
|
|
739
|
-
}
|
|
734
|
+
continue;
|
|
735
|
+
}
|
|
736
|
+
let countLessOrEqual = 0;
|
|
737
|
+
for (let j = 1; j <= length2; j++) {
|
|
738
|
+
if (le(source[i - j], currentValue)) countLessOrEqual++;
|
|
740
739
|
}
|
|
740
|
+
result.push(countLessOrEqual / length2 * 100);
|
|
741
741
|
}
|
|
742
742
|
return result;
|
|
743
743
|
}
|
|
@@ -780,48 +780,26 @@ function mfi(source, length2, volume) {
|
|
|
780
780
|
"ta.mfi() requires volume series. Either pass it explicitly or use createContext({ chart: { ..., volume } }) for implicit data."
|
|
781
781
|
);
|
|
782
782
|
}
|
|
783
|
-
const
|
|
784
|
-
const
|
|
785
|
-
for (let i = 1; i < source.length; i++) {
|
|
786
|
-
changes.push(source[i] - source[i - 1]);
|
|
787
|
-
}
|
|
788
|
-
const positiveFlow = [];
|
|
789
|
-
const negativeFlow = [];
|
|
783
|
+
const upperFlow = [];
|
|
784
|
+
const lowerFlow = [];
|
|
790
785
|
for (let i = 0; i < source.length; i++) {
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
} else {
|
|
809
|
-
let posSum = 0;
|
|
810
|
-
let negSum = 0;
|
|
811
|
-
for (let j = 0; j < length2; j++) {
|
|
812
|
-
posSum += positiveFlow[i - j];
|
|
813
|
-
negSum += negativeFlow[i - j];
|
|
814
|
-
}
|
|
815
|
-
if (negSum === 0) {
|
|
816
|
-
result.push(100);
|
|
817
|
-
} else {
|
|
818
|
-
const moneyRatio = posSum / negSum;
|
|
819
|
-
const mfiValue = 100 - 100 / (1 + moneyRatio);
|
|
820
|
-
result.push(mfiValue);
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
return result;
|
|
786
|
+
const change3 = i === 0 ? NaN : source[i] - source[i - 1];
|
|
787
|
+
const flow = volume[i] * source[i];
|
|
788
|
+
upperFlow.push(le(change3, 0) ? 0 : flow);
|
|
789
|
+
lowerFlow.push(ge(change3, 0) ? 0 : flow);
|
|
790
|
+
}
|
|
791
|
+
const sumAt = (flow, i) => {
|
|
792
|
+
const values2 = lastValues(flow, i, Math.floor(length2));
|
|
793
|
+
return values2 ? values2.reduce((a, b2) => a + b2, 0) : NaN;
|
|
794
|
+
};
|
|
795
|
+
const upper2 = upperFlow.map((_, i) => sumAt(upperFlow, i));
|
|
796
|
+
const lower2 = lowerFlow.map((_, i) => sumAt(lowerFlow, i));
|
|
797
|
+
return upper2.map((u, i) => {
|
|
798
|
+
const l = lower2[i];
|
|
799
|
+
if (Number.isNaN(u) || Number.isNaN(l)) return NaN;
|
|
800
|
+
if (l === 0) return 100;
|
|
801
|
+
return 100 - 100 / (1 + u / l);
|
|
802
|
+
});
|
|
825
803
|
}
|
|
826
804
|
function hma(source, length2) {
|
|
827
805
|
const halfLength = Math.floor(length2 / 2);
|
|
@@ -985,50 +963,32 @@ function dmi(diLength, adxSmoothing, high, low, close) {
|
|
|
985
963
|
const len = Math.max(high.length, low.length, close.length);
|
|
986
964
|
const plusDM = [];
|
|
987
965
|
const minusDM = [];
|
|
988
|
-
const trueRangeValues = tr(false, high, low, close);
|
|
989
966
|
for (let i = 0; i < len; i++) {
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
const
|
|
1009
|
-
const
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
plusDI.push(0);
|
|
1016
|
-
minusDI.push(0);
|
|
1017
|
-
} else {
|
|
1018
|
-
plusDI.push(smoothedPlusDM[i] / smoothedTR[i] * 100);
|
|
1019
|
-
minusDI.push(smoothedMinusDM[i] / smoothedTR[i] * 100);
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
const dx = [];
|
|
1023
|
-
for (let i = 0; i < len; i++) {
|
|
1024
|
-
const sum4 = plusDI[i] + minusDI[i];
|
|
1025
|
-
if (sum4 === 0) {
|
|
1026
|
-
dx.push(0);
|
|
1027
|
-
} else {
|
|
1028
|
-
dx.push(Math.abs(plusDI[i] - minusDI[i]) / sum4 * 100);
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
const adx = rma(dx, adxSmoothing);
|
|
967
|
+
const up = i === 0 ? NaN : high[i] - high[i - 1];
|
|
968
|
+
const down = i === 0 ? NaN : low[i - 1] - low[i];
|
|
969
|
+
plusDM.push(Number.isNaN(up) ? NaN : gt(up, down) && gt(up, 0) ? up : 0);
|
|
970
|
+
minusDM.push(Number.isNaN(down) ? NaN : gt(down, up) && gt(down, 0) ? down : 0);
|
|
971
|
+
}
|
|
972
|
+
const trur = rma(tr(false, high, low, close), diLength);
|
|
973
|
+
const smoothedPlus = rma(plusDM, diLength);
|
|
974
|
+
const smoothedMinus = rma(minusDM, diLength);
|
|
975
|
+
const directional = (smoothed) => {
|
|
976
|
+
let last2 = NaN;
|
|
977
|
+
return smoothed.map((v, i) => {
|
|
978
|
+
const t2 = trur[i];
|
|
979
|
+
const value = t2 === 0 ? NaN : 100 * v / t2;
|
|
980
|
+
if (!Number.isNaN(value)) last2 = value;
|
|
981
|
+
return last2;
|
|
982
|
+
});
|
|
983
|
+
};
|
|
984
|
+
const plusDI = directional(smoothedPlus);
|
|
985
|
+
const minusDI = directional(smoothedMinus);
|
|
986
|
+
const dx = plusDI.map((plus, i) => {
|
|
987
|
+
const minus = minusDI[i];
|
|
988
|
+
const sum4 = plus + minus;
|
|
989
|
+
return Math.abs(plus - minus) / (eq(sum4, 0) ? 1 : sum4);
|
|
990
|
+
});
|
|
991
|
+
const adx = rma(dx, adxSmoothing).map((v) => 100 * v);
|
|
1032
992
|
return [plusDI, minusDI, adx];
|
|
1033
993
|
}
|
|
1034
994
|
function tsi(source, shortLength, longLength) {
|
|
@@ -1304,63 +1264,36 @@ function mode(source, length2) {
|
|
|
1304
1264
|
return result;
|
|
1305
1265
|
}
|
|
1306
1266
|
function percentile_linear_interpolation(source, length2, percentage) {
|
|
1267
|
+
return sortedWindow(source, length2, (s) => {
|
|
1268
|
+
const pos2 = percentage / 100 * length2 - 0.5;
|
|
1269
|
+
if (pos2 <= 0) return s[0];
|
|
1270
|
+
if (pos2 >= length2 - 1) return s[length2 - 1];
|
|
1271
|
+
const lo = Math.floor(pos2);
|
|
1272
|
+
return s[lo] + (pos2 - lo) * (s[lo + 1] - s[lo]);
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
function sortedWindow(source, length2, fn) {
|
|
1307
1276
|
const result = [];
|
|
1277
|
+
const values2 = [];
|
|
1278
|
+
const bars = [];
|
|
1308
1279
|
for (let i = 0; i < source.length; i++) {
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
const
|
|
1316
|
-
values2.
|
|
1317
|
-
|
|
1318
|
-
if (values2.some((v) => isNaN(v))) {
|
|
1319
|
-
result.push(NaN);
|
|
1320
|
-
continue;
|
|
1321
|
-
}
|
|
1322
|
-
const sorted = [...values2].sort((a, b2) => a - b2);
|
|
1323
|
-
const position = percentage / 100 * (sorted.length - 1);
|
|
1324
|
-
const lowerIndex = Math.floor(position);
|
|
1325
|
-
const upperIndex = Math.ceil(position);
|
|
1326
|
-
if (lowerIndex === upperIndex) {
|
|
1327
|
-
result.push(sorted[lowerIndex]);
|
|
1328
|
-
} else {
|
|
1329
|
-
const fraction = position - lowerIndex;
|
|
1330
|
-
const interpolated = sorted[lowerIndex] + fraction * (sorted[upperIndex] - sorted[lowerIndex]);
|
|
1331
|
-
result.push(interpolated);
|
|
1280
|
+
const v = source[i];
|
|
1281
|
+
let k = 0;
|
|
1282
|
+
while (k < values2.length && !(values2[k] >= v)) k++;
|
|
1283
|
+
values2.splice(k, 0, v);
|
|
1284
|
+
bars.splice(k, 0, i);
|
|
1285
|
+
if (i >= length2) {
|
|
1286
|
+
const old = bars.indexOf(i - length2);
|
|
1287
|
+
values2.splice(old, 1);
|
|
1288
|
+
bars.splice(old, 1);
|
|
1332
1289
|
}
|
|
1290
|
+
result.push(i < length2 - 1 ? NaN : fn(values2));
|
|
1333
1291
|
}
|
|
1334
1292
|
return result;
|
|
1335
1293
|
}
|
|
1336
1294
|
function percentile_nearest_rank(source, length2, percentage) {
|
|
1337
|
-
const
|
|
1338
|
-
|
|
1339
|
-
if (i < length2 - 1) {
|
|
1340
|
-
result.push(NaN);
|
|
1341
|
-
continue;
|
|
1342
|
-
}
|
|
1343
|
-
const values2 = [];
|
|
1344
|
-
for (let j = 0; j < length2; j++) {
|
|
1345
|
-
const value = source[i - j];
|
|
1346
|
-
if (!isNaN(value)) {
|
|
1347
|
-
values2.push(value);
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1350
|
-
if (values2.length === 0) {
|
|
1351
|
-
result.push(NaN);
|
|
1352
|
-
continue;
|
|
1353
|
-
}
|
|
1354
|
-
const sorted = [...values2].sort((a, b2) => a - b2);
|
|
1355
|
-
if (percentage >= 100) {
|
|
1356
|
-
result.push(sorted[sorted.length - 1]);
|
|
1357
|
-
continue;
|
|
1358
|
-
}
|
|
1359
|
-
const rank2 = Math.ceil(percentage / 100 * sorted.length);
|
|
1360
|
-
const index = Math.max(0, rank2 - 1);
|
|
1361
|
-
result.push(sorted[index]);
|
|
1362
|
-
}
|
|
1363
|
-
return result;
|
|
1295
|
+
const rank2 = Math.min(length2, Math.max(1, Math.ceil(percentage / 100 * length2)));
|
|
1296
|
+
return sortedWindow(source, length2, (s) => s[rank2 - 1]);
|
|
1364
1297
|
}
|
|
1365
1298
|
function rci(source, length2) {
|
|
1366
1299
|
const result = [];
|
|
@@ -1855,38 +1788,6 @@ __export(math_exports, {
|
|
|
1855
1788
|
toradians: () => toradians
|
|
1856
1789
|
});
|
|
1857
1790
|
|
|
1858
|
-
// src/compare/index.ts
|
|
1859
|
-
var compare_exports = {};
|
|
1860
|
-
__export(compare_exports, {
|
|
1861
|
-
EPSILON: () => EPSILON,
|
|
1862
|
-
eq: () => eq,
|
|
1863
|
-
ge: () => ge,
|
|
1864
|
-
gt: () => gt,
|
|
1865
|
-
le: () => le,
|
|
1866
|
-
lt: () => lt,
|
|
1867
|
-
ne: () => ne
|
|
1868
|
-
});
|
|
1869
|
-
var EPSILON = 1e-10;
|
|
1870
|
-
var valid = (a, b2) => !Number.isNaN(a) && !Number.isNaN(b2);
|
|
1871
|
-
function eq(a, b2) {
|
|
1872
|
-
return valid(a, b2) && Math.abs(a - b2) <= EPSILON;
|
|
1873
|
-
}
|
|
1874
|
-
function ne(a, b2) {
|
|
1875
|
-
return valid(a, b2) && Math.abs(a - b2) > EPSILON;
|
|
1876
|
-
}
|
|
1877
|
-
function lt(a, b2) {
|
|
1878
|
-
return valid(a, b2) && b2 - a > EPSILON;
|
|
1879
|
-
}
|
|
1880
|
-
function le(a, b2) {
|
|
1881
|
-
return valid(a, b2) && a - b2 <= EPSILON;
|
|
1882
|
-
}
|
|
1883
|
-
function gt(a, b2) {
|
|
1884
|
-
return valid(a, b2) && a - b2 > EPSILON;
|
|
1885
|
-
}
|
|
1886
|
-
function ge(a, b2) {
|
|
1887
|
-
return valid(a, b2) && b2 - a <= EPSILON;
|
|
1888
|
-
}
|
|
1889
|
-
|
|
1890
1791
|
// src/runtime/series.ts
|
|
1891
1792
|
var BarData = class _BarData {
|
|
1892
1793
|
_bars;
|
|
@@ -2110,7 +2011,7 @@ var Series = class _Series {
|
|
|
2110
2011
|
return new _Series(this.dataSource, (bar, i, data) => {
|
|
2111
2012
|
const a = this.extractor(bar, i, data);
|
|
2112
2013
|
const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
|
|
2113
|
-
return
|
|
2014
|
+
return a / b2;
|
|
2114
2015
|
});
|
|
2115
2016
|
}
|
|
2116
2017
|
/**
|
|
@@ -3117,15 +3018,27 @@ function percentile_linear_interpolation2(id, percentage) {
|
|
|
3117
3018
|
if (id.length === 0) {
|
|
3118
3019
|
return NaN;
|
|
3119
3020
|
}
|
|
3120
|
-
const
|
|
3121
|
-
|
|
3021
|
+
const s = sortedNaLast(id);
|
|
3022
|
+
const n = s.length;
|
|
3023
|
+
const pos2 = percentage / 100 * n - 0.5;
|
|
3024
|
+
if (pos2 <= 0) return s[0];
|
|
3025
|
+
if (pos2 >= n - 1) return s[n - 1];
|
|
3026
|
+
const lo = Math.floor(pos2);
|
|
3027
|
+
const f = pos2 - lo;
|
|
3028
|
+
if (f === 0) return s[lo];
|
|
3029
|
+
return Number.isNaN(s[n - 1]) ? NaN : s[lo] + f * (s[lo + 1] - s[lo]);
|
|
3030
|
+
}
|
|
3031
|
+
function sortedNaLast(id) {
|
|
3032
|
+
const numbers = id.filter((v) => !Number.isNaN(v)).sort((a, b2) => a - b2);
|
|
3033
|
+
return [...numbers, ...Array(id.length - numbers.length).fill(NaN)];
|
|
3122
3034
|
}
|
|
3123
3035
|
function percentile_nearest_rank2(id, percentage) {
|
|
3124
3036
|
if (id.length === 0) {
|
|
3125
3037
|
return NaN;
|
|
3126
3038
|
}
|
|
3127
|
-
const
|
|
3128
|
-
|
|
3039
|
+
const s = sortedNaLast(id);
|
|
3040
|
+
const rank2 = Math.min(s.length, Math.max(1, Math.ceil(percentage / 100 * s.length)));
|
|
3041
|
+
return s[rank2 - 1];
|
|
3129
3042
|
}
|
|
3130
3043
|
function percentrank2(id, index) {
|
|
3131
3044
|
if (id.length === 0 || index < 0 || index >= id.length) {
|
|
@@ -3836,11 +3749,13 @@ __export(color_exports, {
|
|
|
3836
3749
|
white: () => white,
|
|
3837
3750
|
yellow: () => yellow
|
|
3838
3751
|
});
|
|
3752
|
+
var channel = (v) => v === null || v === void 0 || Number.isNaN(v) ? 0 : Math.max(0, Math.min(255, Math.trunc(v)));
|
|
3753
|
+
var alphaOf = (transp) => transp === null || Number.isNaN(transp) ? 0 : 1 - Math.max(0, Math.min(100, transp)) / 100;
|
|
3839
3754
|
function rgb(red2, green2, blue2, transp) {
|
|
3840
|
-
const r2 =
|
|
3841
|
-
const g2 =
|
|
3842
|
-
const b2 =
|
|
3843
|
-
const a = transp !== void 0 ?
|
|
3755
|
+
const r2 = channel(red2);
|
|
3756
|
+
const g2 = channel(green2);
|
|
3757
|
+
const b2 = channel(blue2);
|
|
3758
|
+
const a = transp !== void 0 ? alphaOf(transp) : 1;
|
|
3844
3759
|
if (a === 1) {
|
|
3845
3760
|
return `rgb(${r2}, ${g2}, ${b2})`;
|
|
3846
3761
|
}
|
|
@@ -3867,7 +3782,8 @@ function b(clr) {
|
|
|
3867
3782
|
return parseColor(clr).b;
|
|
3868
3783
|
}
|
|
3869
3784
|
function t(clr) {
|
|
3870
|
-
|
|
3785
|
+
const alpha = Math.round((1 - parseColor(clr).t / 100) * 255);
|
|
3786
|
+
return Math.round((1 - alpha / 255) * 100);
|
|
3871
3787
|
}
|
|
3872
3788
|
function parseColor(clr) {
|
|
3873
3789
|
if (typeof clr === "string") {
|
|
@@ -3920,13 +3836,12 @@ function from_gradient(value, bottom_value, top_value, bottom_color, top_color)
|
|
|
3920
3836
|
};
|
|
3921
3837
|
const c1 = rgba(bottom_color);
|
|
3922
3838
|
const c2 = rgba(top_color);
|
|
3923
|
-
const
|
|
3924
|
-
const w2 = c2.a * k;
|
|
3925
|
-
const a = w1 + w2;
|
|
3839
|
+
const a = c1.a * (1 - k) + c2.a * k;
|
|
3926
3840
|
if (a === 0) return transparent;
|
|
3927
|
-
const mix = (x1, x2) => Math.floor((x1 *
|
|
3841
|
+
const mix = (x1, x2) => Math.floor((x1 / 255 * c1.a * (1 - k) + x2 / 255 * c2.a * k) / (a / 255));
|
|
3928
3842
|
const [r2, g2, b2] = [mix(c1.r, c2.r), mix(c1.g, c2.g), mix(c1.b, c2.b)];
|
|
3929
|
-
|
|
3843
|
+
const alpha = Math.floor(a);
|
|
3844
|
+
return alpha === 255 ? `rgb(${r2}, ${g2}, ${b2})` : `rgba(${r2}, ${g2}, ${b2}, ${alpha / 255})`;
|
|
3930
3845
|
}
|
|
3931
3846
|
|
|
3932
3847
|
// src/time/index.ts
|
|
@@ -6134,13 +6049,60 @@ var format_none = 0;
|
|
|
6134
6049
|
var format_bold = 1;
|
|
6135
6050
|
var format_italic = 2;
|
|
6136
6051
|
|
|
6052
|
+
// src/callsite/index.ts
|
|
6053
|
+
var callsite_exports = {};
|
|
6054
|
+
__export(callsite_exports, {
|
|
6055
|
+
barssince: () => barssince2,
|
|
6056
|
+
cross: () => cross2,
|
|
6057
|
+
crossover: () => crossover2,
|
|
6058
|
+
crossunder: () => crossunder2,
|
|
6059
|
+
whenCalled: () => whenCalled
|
|
6060
|
+
});
|
|
6061
|
+
function whenCalled(called, fn, ...sources) {
|
|
6062
|
+
const bars = [];
|
|
6063
|
+
for (let i = 0; i < called.length; i++) if (called[i]) bars.push(i);
|
|
6064
|
+
const result = fn(...sources.map((s) => bars.map((i) => s[i] ?? NaN)));
|
|
6065
|
+
const out = new Array(called.length).fill(NaN);
|
|
6066
|
+
bars.forEach((bar, k) => {
|
|
6067
|
+
out[bar] = result[k];
|
|
6068
|
+
});
|
|
6069
|
+
return out;
|
|
6070
|
+
}
|
|
6071
|
+
function twoSeriesSite(test) {
|
|
6072
|
+
let prevA = NaN;
|
|
6073
|
+
let prevB = NaN;
|
|
6074
|
+
return (a, b2) => {
|
|
6075
|
+
const result = test(a, b2, prevA, prevB);
|
|
6076
|
+
prevA = a;
|
|
6077
|
+
prevB = b2;
|
|
6078
|
+
return result;
|
|
6079
|
+
};
|
|
6080
|
+
}
|
|
6081
|
+
function crossover2() {
|
|
6082
|
+
return twoSeriesSite((a, b2, pa, pb) => a > b2 && pa <= pb);
|
|
6083
|
+
}
|
|
6084
|
+
function crossunder2() {
|
|
6085
|
+
return twoSeriesSite((a, b2, pa, pb) => a < b2 && pa >= pb);
|
|
6086
|
+
}
|
|
6087
|
+
function barssince2() {
|
|
6088
|
+
let count = NaN;
|
|
6089
|
+
return (condition) => {
|
|
6090
|
+
if (condition && !Number.isNaN(condition)) count = 0;
|
|
6091
|
+
else if (!Number.isNaN(count)) count++;
|
|
6092
|
+
return count;
|
|
6093
|
+
};
|
|
6094
|
+
}
|
|
6095
|
+
function cross2() {
|
|
6096
|
+
return twoSeriesSite((a, b2, pa, pb) => a > b2 && pa <= pb || a < b2 && pa >= pb);
|
|
6097
|
+
}
|
|
6098
|
+
|
|
6137
6099
|
// src/ta-series.ts
|
|
6138
6100
|
var ta_series_exports = {};
|
|
6139
6101
|
__export(ta_series_exports, {
|
|
6140
6102
|
accdist: () => accdist2,
|
|
6141
6103
|
alma: () => alma2,
|
|
6142
6104
|
atr: () => atr2,
|
|
6143
|
-
barssince: () =>
|
|
6105
|
+
barssince: () => barssince3,
|
|
6144
6106
|
bb: () => bb2,
|
|
6145
6107
|
bbw: () => bbw2,
|
|
6146
6108
|
cci: () => cci2,
|
|
@@ -6148,9 +6110,9 @@ __export(ta_series_exports, {
|
|
|
6148
6110
|
cmo: () => cmo2,
|
|
6149
6111
|
cog: () => cog2,
|
|
6150
6112
|
correlation: () => correlation2,
|
|
6151
|
-
cross: () =>
|
|
6152
|
-
crossover: () =>
|
|
6153
|
-
crossunder: () =>
|
|
6113
|
+
cross: () => cross3,
|
|
6114
|
+
crossover: () => crossover3,
|
|
6115
|
+
crossunder: () => crossunder3,
|
|
6154
6116
|
cum: () => cum2,
|
|
6155
6117
|
dev: () => dev2,
|
|
6156
6118
|
dmi: () => dmi2,
|
|
@@ -6316,7 +6278,7 @@ function stoch2(source, high, low, length2) {
|
|
|
6316
6278
|
const result = stoch(sourceValues, highValues, lowValues, length2);
|
|
6317
6279
|
return Series.fromArray(bars, result);
|
|
6318
6280
|
}
|
|
6319
|
-
function
|
|
6281
|
+
function crossover3(source1, source2) {
|
|
6320
6282
|
const bars = source1.bars;
|
|
6321
6283
|
const vals1 = source1.toArray();
|
|
6322
6284
|
const vals2 = typeof source2 === "number" ? Array(bars.length).fill(source2) : source2.toArray();
|
|
@@ -6324,7 +6286,7 @@ function crossover2(source1, source2) {
|
|
|
6324
6286
|
const numResult = result.map((b2) => b2 ? 1 : 0);
|
|
6325
6287
|
return Series.fromArray(bars, numResult);
|
|
6326
6288
|
}
|
|
6327
|
-
function
|
|
6289
|
+
function crossunder3(source1, source2) {
|
|
6328
6290
|
const bars = source1.bars;
|
|
6329
6291
|
const vals1 = source1.toArray();
|
|
6330
6292
|
const vals2 = typeof source2 === "number" ? Array(bars.length).fill(source2) : source2.toArray();
|
|
@@ -6332,7 +6294,7 @@ function crossunder2(source1, source2) {
|
|
|
6332
6294
|
const numResult = result.map((b2) => b2 ? 1 : 0);
|
|
6333
6295
|
return Series.fromArray(bars, numResult);
|
|
6334
6296
|
}
|
|
6335
|
-
function
|
|
6297
|
+
function cross3(source1, source2) {
|
|
6336
6298
|
const bars = source1.bars;
|
|
6337
6299
|
const vals1 = source1.toArray();
|
|
6338
6300
|
const vals2 = typeof source2 === "number" ? Array(bars.length).fill(source2) : source2.toArray();
|
|
@@ -6528,7 +6490,7 @@ function pivotlow2(source, leftbars, rightbars) {
|
|
|
6528
6490
|
const result = pivotlow(source.toArray(), leftbars, rightbars);
|
|
6529
6491
|
return Series.fromArray(bars, result);
|
|
6530
6492
|
}
|
|
6531
|
-
function
|
|
6493
|
+
function barssince3(condition) {
|
|
6532
6494
|
const bars = condition.bars;
|
|
6533
6495
|
const boolValues = condition.toArray().map((v) => v === 1);
|
|
6534
6496
|
const result = barssince(boolValues);
|
|
@@ -6651,9 +6613,9 @@ var ta = {
|
|
|
6651
6613
|
atr: atr2,
|
|
6652
6614
|
tr: tr2,
|
|
6653
6615
|
stoch: stoch2,
|
|
6654
|
-
crossover:
|
|
6655
|
-
crossunder:
|
|
6656
|
-
cross:
|
|
6616
|
+
crossover: crossover3,
|
|
6617
|
+
crossunder: crossunder3,
|
|
6618
|
+
cross: cross3,
|
|
6657
6619
|
change: change2,
|
|
6658
6620
|
mom: mom2,
|
|
6659
6621
|
roc: roc2,
|
|
@@ -6680,7 +6642,7 @@ var ta = {
|
|
|
6680
6642
|
hma: hma2,
|
|
6681
6643
|
pivothigh: pivothigh2,
|
|
6682
6644
|
pivotlow: pivotlow2,
|
|
6683
|
-
barssince:
|
|
6645
|
+
barssince: barssince3,
|
|
6684
6646
|
valuewhen: valuewhen2,
|
|
6685
6647
|
dmi: dmi2,
|
|
6686
6648
|
tsi: tsi2,
|
|
@@ -6712,7 +6674,7 @@ var ta = {
|
|
|
6712
6674
|
|
|
6713
6675
|
// src/utils/index.ts
|
|
6714
6676
|
function isNA(value) {
|
|
6715
|
-
return value === null || value === void 0 || Number.isNaN(value) || isDeleted(value);
|
|
6677
|
+
return value === null || value === void 0 || Number.isNaN(value) || value === Infinity || value === -Infinity || isDeleted(value);
|
|
6716
6678
|
}
|
|
6717
6679
|
function nz(value, defaultValue = 0) {
|
|
6718
6680
|
return isNA(value) ? defaultValue : value;
|
|
@@ -6721,7 +6683,7 @@ function fixnan(source) {
|
|
|
6721
6683
|
let last2;
|
|
6722
6684
|
let seen = false;
|
|
6723
6685
|
return source.map((v) => {
|
|
6724
|
-
if (!
|
|
6686
|
+
if (!(v === null || v === void 0 || Number.isNaN(v) || isDeleted(v))) {
|
|
6725
6687
|
last2 = v;
|
|
6726
6688
|
seen = true;
|
|
6727
6689
|
return v;
|
|
@@ -6729,6 +6691,16 @@ function fixnan(source) {
|
|
|
6729
6691
|
return seen ? last2 : v;
|
|
6730
6692
|
});
|
|
6731
6693
|
}
|
|
6694
|
+
function at(source, i, offset = 0) {
|
|
6695
|
+
if (offset < 0) {
|
|
6696
|
+
throw new RangeError(`at(): the offset must be >= 0 (got ${offset}); a negative offset reads a later bar.`);
|
|
6697
|
+
}
|
|
6698
|
+
const j = i - offset;
|
|
6699
|
+
return j >= 0 && j < source.length ? source[j] ?? NaN : NaN;
|
|
6700
|
+
}
|
|
6701
|
+
function div(a, b2) {
|
|
6702
|
+
return a / b2;
|
|
6703
|
+
}
|
|
6732
6704
|
function ohlcFromBars(bars) {
|
|
6733
6705
|
return {
|
|
6734
6706
|
open: bars.map((b2) => b2.open),
|
|
@@ -6749,6 +6721,50 @@ function getLow(ohlc) {
|
|
|
6749
6721
|
function getOpen(ohlc) {
|
|
6750
6722
|
return ohlc.open;
|
|
6751
6723
|
}
|
|
6724
|
+
function getSource(data, source = "close") {
|
|
6725
|
+
const isOHLC = "open" in data && Array.isArray(data.open);
|
|
6726
|
+
if (isOHLC) {
|
|
6727
|
+
const ohlc = data;
|
|
6728
|
+
switch (source) {
|
|
6729
|
+
case "close":
|
|
6730
|
+
return ohlc.close;
|
|
6731
|
+
case "open":
|
|
6732
|
+
return ohlc.open;
|
|
6733
|
+
case "high":
|
|
6734
|
+
return ohlc.high;
|
|
6735
|
+
case "low":
|
|
6736
|
+
return ohlc.low;
|
|
6737
|
+
case "hl2":
|
|
6738
|
+
return ohlc.high.map((h, i) => (h + ohlc.low[i]) / 2);
|
|
6739
|
+
case "hlc3":
|
|
6740
|
+
return ohlc.high.map((h, i) => (h + ohlc.low[i] + ohlc.close[i]) / 3);
|
|
6741
|
+
case "ohlc4":
|
|
6742
|
+
return ohlc.open.map((o, i) => (o + ohlc.high[i] + ohlc.low[i] + ohlc.close[i]) / 4);
|
|
6743
|
+
case "hlcc4":
|
|
6744
|
+
return ohlc.high.map((h, i) => (h + ohlc.low[i] + ohlc.close[i] + ohlc.close[i]) / 4);
|
|
6745
|
+
}
|
|
6746
|
+
} else {
|
|
6747
|
+
const bars = data;
|
|
6748
|
+
switch (source) {
|
|
6749
|
+
case "close":
|
|
6750
|
+
return bars.map((b2) => b2.close);
|
|
6751
|
+
case "open":
|
|
6752
|
+
return bars.map((b2) => b2.open);
|
|
6753
|
+
case "high":
|
|
6754
|
+
return bars.map((b2) => b2.high);
|
|
6755
|
+
case "low":
|
|
6756
|
+
return bars.map((b2) => b2.low);
|
|
6757
|
+
case "hl2":
|
|
6758
|
+
return bars.map((b2) => (b2.high + b2.low) / 2);
|
|
6759
|
+
case "hlc3":
|
|
6760
|
+
return bars.map((b2) => (b2.high + b2.low + b2.close) / 3);
|
|
6761
|
+
case "ohlc4":
|
|
6762
|
+
return bars.map((b2) => (b2.open + b2.high + b2.low + b2.close) / 4);
|
|
6763
|
+
case "hlcc4":
|
|
6764
|
+
return bars.map((b2) => (b2.high + b2.low + b2.close + b2.close) / 4);
|
|
6765
|
+
}
|
|
6766
|
+
}
|
|
6767
|
+
}
|
|
6752
6768
|
function getSourceSeries(bars, source = "close") {
|
|
6753
6769
|
const open = new Series(bars, (bar) => bar.open);
|
|
6754
6770
|
const high = new Series(bars, (bar) => bar.high);
|
|
@@ -7317,7 +7333,7 @@ function hline(price, title, color, linestyle, linewidth) {
|
|
|
7317
7333
|
const options = {
|
|
7318
7334
|
color,
|
|
7319
7335
|
lineWidth: linewidth,
|
|
7320
|
-
lineStyle: getLineStyle(linestyle)
|
|
7336
|
+
lineStyle: getLineStyle(linestyle ?? "dashed")
|
|
7321
7337
|
};
|
|
7322
7338
|
const seriesHandle = context.chart.addSeries("line", options);
|
|
7323
7339
|
const data = context.ohlcv.time.map((time) => ({
|
|
@@ -7548,6 +7564,73 @@ function getSourceData(ohlcv, sourceName) {
|
|
|
7548
7564
|
}
|
|
7549
7565
|
}
|
|
7550
7566
|
|
|
7567
|
+
// src/strategy/index.ts
|
|
7568
|
+
var STRATEGY_CONSTANTS = {
|
|
7569
|
+
long: "long",
|
|
7570
|
+
short: "short",
|
|
7571
|
+
fixed: "fixed",
|
|
7572
|
+
cash: "cash",
|
|
7573
|
+
percent_of_equity: "percent_of_equity",
|
|
7574
|
+
commission: { percent: "percent", cash_per_contract: "cash_per_contract", cash_per_order: "cash_per_order" },
|
|
7575
|
+
direction: { all: "all", long: "long", short: "short" },
|
|
7576
|
+
oca: { none: "none", cancel: "cancel", reduce: "reduce" }
|
|
7577
|
+
};
|
|
7578
|
+
var STRATEGY_DEFAULTS = {
|
|
7579
|
+
pyramiding: 0,
|
|
7580
|
+
calc_on_order_fills: false,
|
|
7581
|
+
calc_on_every_tick: false,
|
|
7582
|
+
backtest_fill_limits_assumption: 0,
|
|
7583
|
+
// v6 values; PineScript v5: fixed / 1 / 1000000 and margins 0
|
|
7584
|
+
default_qty_type: "percent_of_equity",
|
|
7585
|
+
default_qty_value: 100,
|
|
7586
|
+
initial_capital: 1e5,
|
|
7587
|
+
slippage: 0,
|
|
7588
|
+
commission_type: "percent",
|
|
7589
|
+
commission_value: 0,
|
|
7590
|
+
process_orders_on_close: false,
|
|
7591
|
+
close_entries_rule: "FIFO",
|
|
7592
|
+
margin_long: 100,
|
|
7593
|
+
margin_short: 100,
|
|
7594
|
+
calc_bars_count: 0,
|
|
7595
|
+
risk_free_rate: 2,
|
|
7596
|
+
use_bar_magnifier: false,
|
|
7597
|
+
fill_orders_on_standard_ohlc: false
|
|
7598
|
+
};
|
|
7599
|
+
var STRATEGY_NUMBER_VARIABLES = [
|
|
7600
|
+
"position_size",
|
|
7601
|
+
"position_avg_price",
|
|
7602
|
+
"equity",
|
|
7603
|
+
"initial_capital",
|
|
7604
|
+
"netprofit",
|
|
7605
|
+
"netprofit_percent",
|
|
7606
|
+
"openprofit",
|
|
7607
|
+
"openprofit_percent",
|
|
7608
|
+
"grossprofit",
|
|
7609
|
+
"grossprofit_percent",
|
|
7610
|
+
"grossloss",
|
|
7611
|
+
"grossloss_percent",
|
|
7612
|
+
"opentrades",
|
|
7613
|
+
"closedtrades",
|
|
7614
|
+
"wintrades",
|
|
7615
|
+
"losstrades",
|
|
7616
|
+
"eventrades",
|
|
7617
|
+
"avg_trade",
|
|
7618
|
+
"avg_trade_percent",
|
|
7619
|
+
"avg_winning_trade",
|
|
7620
|
+
"avg_winning_trade_percent",
|
|
7621
|
+
"avg_losing_trade",
|
|
7622
|
+
"avg_losing_trade_percent",
|
|
7623
|
+
"max_drawdown",
|
|
7624
|
+
"max_drawdown_percent",
|
|
7625
|
+
"max_runup",
|
|
7626
|
+
"max_runup_percent",
|
|
7627
|
+
"max_contracts_held_all",
|
|
7628
|
+
"max_contracts_held_long",
|
|
7629
|
+
"max_contracts_held_short",
|
|
7630
|
+
"margin_liquidation_price"
|
|
7631
|
+
];
|
|
7632
|
+
var STRATEGY_TEXT_VARIABLES = ["position_entry_name", "account_currency"];
|
|
7633
|
+
|
|
7551
7634
|
// src/runtime/adapters/LightweightChartsAdapter.ts
|
|
7552
7635
|
var LightweightChartsAdapter = class {
|
|
7553
7636
|
chart;
|
|
@@ -7756,7 +7839,7 @@ var SimpleInputAdapter = class {
|
|
|
7756
7839
|
};
|
|
7757
7840
|
|
|
7758
7841
|
// src/index.ts
|
|
7759
|
-
var VERSION = "0.
|
|
7842
|
+
var VERSION = "0.8.1";
|
|
7760
7843
|
var info2 = {
|
|
7761
7844
|
name: "OakScriptJS",
|
|
7762
7845
|
version: VERSION,
|
|
@@ -7781,6 +7864,10 @@ function alertcondition(_condition, _title, _message) {
|
|
|
7781
7864
|
export {
|
|
7782
7865
|
BarData,
|
|
7783
7866
|
LightweightChartsAdapter,
|
|
7867
|
+
STRATEGY_CONSTANTS,
|
|
7868
|
+
STRATEGY_DEFAULTS,
|
|
7869
|
+
STRATEGY_NUMBER_VARIABLES,
|
|
7870
|
+
STRATEGY_TEXT_VARIABLES,
|
|
7784
7871
|
Series,
|
|
7785
7872
|
SimpleInputAdapter,
|
|
7786
7873
|
VERSION,
|
|
@@ -7788,11 +7875,13 @@ export {
|
|
|
7788
7875
|
abs,
|
|
7789
7876
|
alertcondition,
|
|
7790
7877
|
array_exports as array,
|
|
7878
|
+
at,
|
|
7791
7879
|
atr2 as atr,
|
|
7792
7880
|
avg,
|
|
7793
7881
|
bb2 as bb,
|
|
7794
7882
|
box_exports as box,
|
|
7795
7883
|
calculateZigZag,
|
|
7884
|
+
callsite_exports as callsite,
|
|
7796
7885
|
ceil,
|
|
7797
7886
|
change2 as change,
|
|
7798
7887
|
chartpoint_exports as chartPoint,
|
|
@@ -7803,9 +7892,10 @@ export {
|
|
|
7803
7892
|
compare_exports as compare,
|
|
7804
7893
|
cos,
|
|
7805
7894
|
createPlot,
|
|
7806
|
-
|
|
7807
|
-
|
|
7895
|
+
crossover3 as crossover,
|
|
7896
|
+
crossunder3 as crossunder,
|
|
7808
7897
|
cum2 as cum,
|
|
7898
|
+
div,
|
|
7809
7899
|
ema2 as ema,
|
|
7810
7900
|
exp,
|
|
7811
7901
|
fixnan,
|
|
@@ -7815,6 +7905,7 @@ export {
|
|
|
7815
7905
|
getHigh,
|
|
7816
7906
|
getLow,
|
|
7817
7907
|
getOpen,
|
|
7908
|
+
getSource,
|
|
7818
7909
|
getSourceSeries,
|
|
7819
7910
|
hline,
|
|
7820
7911
|
indicator,
|