oakscriptjs 0.8.0 → 0.8.2
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 +1 -0
- package/dist/callsite/index.d.ts.map +1 -1
- package/dist/color/index.d.ts +4 -4
- package/dist/color/index.d.ts.map +1 -1
- package/dist/index.cjs +197 -232
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +197 -232
- package/dist/math/index.d.ts.map +1 -1
- package/dist/runtime/index.cjs +1 -1
- package/dist/runtime/index.mjs +1 -1
- package/dist/runtime/types.d.ts +21 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/script/index.cjs +293 -241
- package/dist/script/index.d.ts +71 -16
- package/dist/script/index.d.ts.map +1 -1
- package/dist/script/index.mjs +293 -241
- package/dist/strategy/index.d.ts.map +1 -1
- package/dist/ta/index.d.ts.map +1 -1
- package/dist/ta/running-sum.d.ts +3 -0
- package/dist/ta/running-sum.d.ts.map +1 -0
- package/dist/types/metadata.d.ts +10 -1
- package/dist/types/metadata.d.ts.map +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/script/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ __export(index_exports, {
|
|
|
26
26
|
alertcondition: () => alertcondition,
|
|
27
27
|
barcolor: () => barcolor,
|
|
28
28
|
barmerge: () => barmerge,
|
|
29
|
+
barstate: () => barstate,
|
|
29
30
|
bgcolor: () => bgcolor,
|
|
30
31
|
box: () => box,
|
|
31
32
|
chart: () => chart,
|
|
@@ -59,6 +60,7 @@ __export(index_exports, {
|
|
|
59
60
|
ohlc4: () => ohlc4,
|
|
60
61
|
open: () => open,
|
|
61
62
|
plot: () => plot,
|
|
63
|
+
plotarrow: () => plotarrow,
|
|
62
64
|
plotchar: () => plotchar,
|
|
63
65
|
plotshape: () => plotshape,
|
|
64
66
|
polyline: () => polyline,
|
|
@@ -338,7 +340,7 @@ var Series = class _Series {
|
|
|
338
340
|
return new _Series(this.dataSource, (bar, i, data) => {
|
|
339
341
|
const a = this.extractor(bar, i, data);
|
|
340
342
|
const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
|
|
341
|
-
return
|
|
343
|
+
return a / b2;
|
|
342
344
|
});
|
|
343
345
|
}
|
|
344
346
|
/**
|
|
@@ -704,26 +706,86 @@ __export(ta_series_exports, {
|
|
|
704
706
|
zigzag: () => zigzag2
|
|
705
707
|
});
|
|
706
708
|
|
|
707
|
-
// src/ta/
|
|
708
|
-
|
|
709
|
-
|
|
709
|
+
// src/ta/running-sum.ts
|
|
710
|
+
var view = new DataView(new ArrayBuffer(8));
|
|
711
|
+
function exponentOf(x) {
|
|
712
|
+
view.setFloat64(0, x);
|
|
713
|
+
const e2 = view.getUint16(0) >> 4 & 2047;
|
|
714
|
+
return e2 === 0 ? -1074 : e2 - 1023;
|
|
715
|
+
}
|
|
716
|
+
function compensationLost(x, c) {
|
|
717
|
+
if (c === 0 || x === 0) return false;
|
|
718
|
+
const ulp = 2 ** (exponentOf(x) - 52);
|
|
719
|
+
const q = c / ulp;
|
|
720
|
+
const mantissa = x / ulp;
|
|
721
|
+
const f = Math.floor(q);
|
|
722
|
+
const d = q - f;
|
|
723
|
+
const applied = d > 0.5 ? f + 1 : d < 0.5 ? f : (mantissa - f) % 2 === 0 ? f : f + 1;
|
|
724
|
+
return Math.abs(applied) < Math.abs(q);
|
|
725
|
+
}
|
|
726
|
+
function isNa(v) {
|
|
727
|
+
return v === void 0 || v === null || !Number.isFinite(v);
|
|
728
|
+
}
|
|
729
|
+
function runningSum(source, length2) {
|
|
710
730
|
const len = Math.floor(length2);
|
|
711
|
-
const
|
|
731
|
+
const out = new Array(source.length).fill(NaN);
|
|
732
|
+
if (!(len >= 1)) return out;
|
|
733
|
+
const values = [];
|
|
734
|
+
const stored = [];
|
|
735
|
+
let s = 0;
|
|
736
|
+
let c = 0;
|
|
737
|
+
let previous = NaN;
|
|
738
|
+
const kahanAdd = (v) => {
|
|
739
|
+
const y = v - c;
|
|
740
|
+
const t2 = s + y;
|
|
741
|
+
c = t2 - s - y;
|
|
742
|
+
s = t2;
|
|
743
|
+
return y;
|
|
744
|
+
};
|
|
712
745
|
for (let i = 0; i < source.length; i++) {
|
|
713
746
|
const v = source[i];
|
|
714
|
-
if (
|
|
715
|
-
|
|
716
|
-
|
|
747
|
+
if (isNa(v)) {
|
|
748
|
+
out[i] = previous;
|
|
749
|
+
continue;
|
|
717
750
|
}
|
|
718
|
-
|
|
719
|
-
|
|
751
|
+
const x = v;
|
|
752
|
+
const c0 = c;
|
|
753
|
+
const n = values.length;
|
|
754
|
+
if (n >= len) kahanAdd(-stored[n - len]);
|
|
755
|
+
values.push(x);
|
|
756
|
+
if (compensationLost(x, c0)) {
|
|
757
|
+
let fresh = 0;
|
|
758
|
+
for (let k = values.length - 1; k >= Math.max(0, values.length - len); k--) fresh += values[k];
|
|
759
|
+
s = fresh;
|
|
760
|
+
c = 0;
|
|
761
|
+
stored.push(x);
|
|
720
762
|
} else {
|
|
721
|
-
|
|
722
|
-
for (const x of window) sum2 += x;
|
|
723
|
-
result.push(sum2 / len);
|
|
763
|
+
stored.push(kahanAdd(x));
|
|
724
764
|
}
|
|
765
|
+
previous = values.length >= len ? s : NaN;
|
|
766
|
+
out[i] = previous;
|
|
725
767
|
}
|
|
726
|
-
return
|
|
768
|
+
return out;
|
|
769
|
+
}
|
|
770
|
+
function runningVariance(source, length2, biased) {
|
|
771
|
+
const len = Math.floor(length2);
|
|
772
|
+
const squares = Array.from({ length: source.length }, (_, i) => {
|
|
773
|
+
const v = source[i];
|
|
774
|
+
return isNa(v) ? NaN : v * v;
|
|
775
|
+
});
|
|
776
|
+
const sums = runningSum(source, len);
|
|
777
|
+
const sumSquares = runningSum(squares, len);
|
|
778
|
+
return sums.map((sum2, i) => {
|
|
779
|
+
const mean = sum2 / len;
|
|
780
|
+
const sq = sumSquares[i];
|
|
781
|
+
return biased ? sq / len - mean * mean : sq / (len - 1) - mean * sum2 / (len - 1);
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// src/ta/index.ts
|
|
786
|
+
function sma(source, length2) {
|
|
787
|
+
const len = Math.floor(length2);
|
|
788
|
+
return runningSum(source, len).map((sum2) => sum2 / len);
|
|
727
789
|
}
|
|
728
790
|
function strictWindowMean(source, length2) {
|
|
729
791
|
const len = Math.floor(length2);
|
|
@@ -743,7 +805,7 @@ function ema(source, length2) {
|
|
|
743
805
|
let initSum = 0;
|
|
744
806
|
for (let i = 0; i < source.length; i++) {
|
|
745
807
|
const val = source[i];
|
|
746
|
-
if (val !== void 0 &&
|
|
808
|
+
if (val !== void 0 && Number.isFinite(val)) {
|
|
747
809
|
initSum += val;
|
|
748
810
|
validCount++;
|
|
749
811
|
if (validCount === len) {
|
|
@@ -761,7 +823,7 @@ function ema(source, length2) {
|
|
|
761
823
|
result.push(emaValue);
|
|
762
824
|
} else {
|
|
763
825
|
const val = source[i];
|
|
764
|
-
if (val !== void 0 &&
|
|
826
|
+
if (val !== void 0 && Number.isFinite(val)) {
|
|
765
827
|
emaValue = (val - emaValue) * multiplier + emaValue;
|
|
766
828
|
result.push(emaValue);
|
|
767
829
|
} else {
|
|
@@ -818,14 +880,7 @@ function bb(series, length2, mult) {
|
|
|
818
880
|
return [basis, upper2, lower2];
|
|
819
881
|
}
|
|
820
882
|
function stdev(source, length2, biased = true) {
|
|
821
|
-
|
|
822
|
-
return source.map((_, i) => {
|
|
823
|
-
const values = lastValues(source, i, len);
|
|
824
|
-
if (!values) return NaN;
|
|
825
|
-
const mean = values.reduce((a, b2) => a + b2, 0) / len;
|
|
826
|
-
const squares = values.reduce((a, b2) => a + (b2 - mean) * (b2 - mean), 0);
|
|
827
|
-
return Math.sqrt(squares / (biased ? len : len - 1));
|
|
828
|
-
});
|
|
883
|
+
return variance(source, length2, biased).map((v) => Number.isNaN(v) ? NaN : v > 0 ? Math.sqrt(v) : 0);
|
|
829
884
|
}
|
|
830
885
|
function lastValues(source, i, length2) {
|
|
831
886
|
const values = [];
|
|
@@ -979,13 +1034,12 @@ function supertrend(factor, atrPeriod, high2, low2, close2, wicks = false) {
|
|
|
979
1034
|
function rma(source, length2) {
|
|
980
1035
|
const result = [];
|
|
981
1036
|
const len = Math.floor(length2);
|
|
982
|
-
const alpha = 1 / len;
|
|
983
1037
|
let firstValidIndex = -1;
|
|
984
1038
|
let validCount = 0;
|
|
985
1039
|
let initSum = 0;
|
|
986
1040
|
for (let i = 0; i < source.length; i++) {
|
|
987
1041
|
const val = source[i];
|
|
988
|
-
if (val !== void 0 &&
|
|
1042
|
+
if (val !== void 0 && Number.isFinite(val)) {
|
|
989
1043
|
initSum += val;
|
|
990
1044
|
validCount++;
|
|
991
1045
|
if (validCount === len) {
|
|
@@ -1003,8 +1057,8 @@ function rma(source, length2) {
|
|
|
1003
1057
|
result.push(rmaValue);
|
|
1004
1058
|
} else {
|
|
1005
1059
|
const val = source[i];
|
|
1006
|
-
if (val !== void 0 &&
|
|
1007
|
-
rmaValue =
|
|
1060
|
+
if (val !== void 0 && Number.isFinite(val)) {
|
|
1061
|
+
rmaValue = (val + (len - 1) * rmaValue) / len;
|
|
1008
1062
|
result.push(rmaValue);
|
|
1009
1063
|
} else {
|
|
1010
1064
|
result.push(NaN);
|
|
@@ -1018,18 +1072,22 @@ function wma(source, length2) {
|
|
|
1018
1072
|
const len = Math.floor(length2);
|
|
1019
1073
|
const filled = [];
|
|
1020
1074
|
let last = NaN;
|
|
1075
|
+
let count = 0;
|
|
1021
1076
|
for (let i = 0; i < source.length; i++) {
|
|
1022
1077
|
const v = source[i];
|
|
1023
|
-
const
|
|
1024
|
-
if (!
|
|
1078
|
+
const isNa2 = v === void 0 || v === null || !Number.isFinite(v);
|
|
1079
|
+
if (!isNa2) {
|
|
1080
|
+
last = v;
|
|
1081
|
+
count++;
|
|
1082
|
+
}
|
|
1025
1083
|
filled.push(last);
|
|
1026
|
-
if (
|
|
1084
|
+
if (isNa2 || count < len) {
|
|
1027
1085
|
result.push(NaN);
|
|
1028
1086
|
continue;
|
|
1029
1087
|
}
|
|
1030
1088
|
let sum2 = 0;
|
|
1031
1089
|
let weightSum = 0;
|
|
1032
|
-
for (let j =
|
|
1090
|
+
for (let j = len - 1; j >= 0; j--) {
|
|
1033
1091
|
const weight = len - j;
|
|
1034
1092
|
sum2 += filled[i - j] * weight;
|
|
1035
1093
|
weightSum += weight;
|
|
@@ -1055,7 +1113,7 @@ function lowest(source, length2) {
|
|
|
1055
1113
|
function cum(source) {
|
|
1056
1114
|
let sum2 = 0;
|
|
1057
1115
|
return source.map((v) => {
|
|
1058
|
-
if (Number.
|
|
1116
|
+
if (!Number.isFinite(v)) return NaN;
|
|
1059
1117
|
sum2 += v;
|
|
1060
1118
|
return sum2;
|
|
1061
1119
|
});
|
|
@@ -1073,41 +1131,24 @@ function cross(source1, source2) {
|
|
|
1073
1131
|
}
|
|
1074
1132
|
return result;
|
|
1075
1133
|
}
|
|
1076
|
-
function
|
|
1134
|
+
function monotonic(source, length2, step) {
|
|
1077
1135
|
const result = [];
|
|
1136
|
+
const values = [];
|
|
1078
1137
|
for (let i = 0; i < source.length; i++) {
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
isRising = false;
|
|
1086
|
-
break;
|
|
1087
|
-
}
|
|
1088
|
-
}
|
|
1089
|
-
result.push(isRising);
|
|
1090
|
-
}
|
|
1138
|
+
const v = source[i];
|
|
1139
|
+
if (!Number.isNaN(v)) values.push(v);
|
|
1140
|
+
const n = values.length;
|
|
1141
|
+
let ok = n > length2;
|
|
1142
|
+
for (let j = 1; ok && j <= length2; j++) ok = step(values[n - j], values[n - j - 1]);
|
|
1143
|
+
result.push(ok);
|
|
1091
1144
|
}
|
|
1092
1145
|
return result;
|
|
1093
1146
|
}
|
|
1147
|
+
function rising(source, length2) {
|
|
1148
|
+
return monotonic(source, length2, gt);
|
|
1149
|
+
}
|
|
1094
1150
|
function falling(source, length2) {
|
|
1095
|
-
|
|
1096
|
-
for (let i = 0; i < source.length; i++) {
|
|
1097
|
-
if (i < length2) {
|
|
1098
|
-
result.push(false);
|
|
1099
|
-
} else {
|
|
1100
|
-
let isFalling = true;
|
|
1101
|
-
for (let j = 1; j <= length2; j++) {
|
|
1102
|
-
if (source[i - j + 1] >= source[i - j]) {
|
|
1103
|
-
isFalling = false;
|
|
1104
|
-
break;
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
|
-
result.push(isFalling);
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
return result;
|
|
1151
|
+
return monotonic(source, length2, lt);
|
|
1111
1152
|
}
|
|
1112
1153
|
function roc(source, length2) {
|
|
1113
1154
|
const result = [];
|
|
@@ -1160,53 +1201,19 @@ function dev(source, length2) {
|
|
|
1160
1201
|
return result;
|
|
1161
1202
|
}
|
|
1162
1203
|
function variance(source, length2, biased = true) {
|
|
1163
|
-
const result = [];
|
|
1164
1204
|
const len = Math.floor(length2);
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
const v = source[i];
|
|
1168
|
-
if (v !== void 0 && v !== null && !Number.isNaN(v)) {
|
|
1169
|
-
window.push(v);
|
|
1170
|
-
if (window.length > len) window.shift();
|
|
1171
|
-
}
|
|
1172
|
-
const divisor = biased ? len : len - 1;
|
|
1173
|
-
if (window.length < len || divisor <= 0) {
|
|
1174
|
-
result.push(NaN);
|
|
1175
|
-
continue;
|
|
1176
|
-
}
|
|
1177
|
-
const mean = window.reduce((a, x) => a + x, 0) / len;
|
|
1178
|
-
let sumSquares = 0;
|
|
1179
|
-
for (const x of window) sumSquares += (x - mean) * (x - mean);
|
|
1180
|
-
result.push(sumSquares / divisor);
|
|
1181
|
-
}
|
|
1182
|
-
return result;
|
|
1205
|
+
if ((biased ? len : len - 1) <= 0) return source.map(() => NaN);
|
|
1206
|
+
return runningVariance(source, len, biased);
|
|
1183
1207
|
}
|
|
1184
1208
|
function median(source, length2) {
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
values.push(source[i - j]);
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
|
-
if (values.length === 0) {
|
|
1197
|
-
result.push(NaN);
|
|
1198
|
-
} else {
|
|
1199
|
-
values.sort((a, b2) => a - b2);
|
|
1200
|
-
const mid = Math.floor(values.length / 2);
|
|
1201
|
-
if (values.length % 2 === 0) {
|
|
1202
|
-
result.push((values[mid - 1] + values[mid]) / 2);
|
|
1203
|
-
} else {
|
|
1204
|
-
result.push(values[mid]);
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
return result;
|
|
1209
|
+
const len = Math.floor(length2);
|
|
1210
|
+
return source.map((_, i) => {
|
|
1211
|
+
const values = lastValues(source, i, len);
|
|
1212
|
+
if (!values) return NaN;
|
|
1213
|
+
values.sort((a, b2) => a - b2);
|
|
1214
|
+
const mid = Math.floor(len / 2);
|
|
1215
|
+
return len % 2 === 0 ? (values[mid - 1] + values[mid]) / 2 : values[mid];
|
|
1216
|
+
});
|
|
1210
1217
|
}
|
|
1211
1218
|
function swma(source) {
|
|
1212
1219
|
const result = [];
|
|
@@ -1331,33 +1338,16 @@ function correlation(source1, source2, length2) {
|
|
|
1331
1338
|
function percentrank(source, length2) {
|
|
1332
1339
|
const result = [];
|
|
1333
1340
|
for (let i = 0; i < source.length; i++) {
|
|
1334
|
-
|
|
1341
|
+
const currentValue = source[i];
|
|
1342
|
+
if (i < length2 || Number.isNaN(currentValue)) {
|
|
1335
1343
|
result.push(NaN);
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
let hasNaN = false;
|
|
1342
|
-
for (let j = 1; j <= length2; j++) {
|
|
1343
|
-
if (isNaN(source[i - j])) {
|
|
1344
|
-
hasNaN = true;
|
|
1345
|
-
break;
|
|
1346
|
-
}
|
|
1347
|
-
}
|
|
1348
|
-
if (hasNaN) {
|
|
1349
|
-
result.push(NaN);
|
|
1350
|
-
} else {
|
|
1351
|
-
const currentValue = source[i];
|
|
1352
|
-
let countLessOrEqual = 0;
|
|
1353
|
-
for (let j = 1; j <= length2; j++) {
|
|
1354
|
-
if (source[i - j] <= currentValue) {
|
|
1355
|
-
countLessOrEqual++;
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
1358
|
-
result.push(countLessOrEqual / length2 * 100);
|
|
1359
|
-
}
|
|
1344
|
+
continue;
|
|
1345
|
+
}
|
|
1346
|
+
let countLessOrEqual = 0;
|
|
1347
|
+
for (let j = 1; j <= length2; j++) {
|
|
1348
|
+
if (le(source[i - j], currentValue)) countLessOrEqual++;
|
|
1360
1349
|
}
|
|
1350
|
+
result.push(countLessOrEqual / length2 * 100);
|
|
1361
1351
|
}
|
|
1362
1352
|
return result;
|
|
1363
1353
|
}
|
|
@@ -1408,12 +1398,8 @@ function mfi(source, length2, volume2) {
|
|
|
1408
1398
|
upperFlow.push(le(change3, 0) ? 0 : flow);
|
|
1409
1399
|
lowerFlow.push(ge(change3, 0) ? 0 : flow);
|
|
1410
1400
|
}
|
|
1411
|
-
const
|
|
1412
|
-
|
|
1413
|
-
return values ? values.reduce((a, b2) => a + b2, 0) : NaN;
|
|
1414
|
-
};
|
|
1415
|
-
const upper2 = upperFlow.map((_, i) => sumAt(upperFlow, i));
|
|
1416
|
-
const lower2 = lowerFlow.map((_, i) => sumAt(lowerFlow, i));
|
|
1401
|
+
const upper2 = runningSum(upperFlow, length2);
|
|
1402
|
+
const lower2 = runningSum(lowerFlow, length2);
|
|
1417
1403
|
return upper2.map((u, i) => {
|
|
1418
1404
|
const l = lower2[i];
|
|
1419
1405
|
if (Number.isNaN(u) || Number.isNaN(l)) return NaN;
|
|
@@ -1884,63 +1870,36 @@ function mode(source, length2) {
|
|
|
1884
1870
|
return result;
|
|
1885
1871
|
}
|
|
1886
1872
|
function percentile_linear_interpolation(source, length2, percentage) {
|
|
1873
|
+
return sortedWindow(source, length2, (s) => {
|
|
1874
|
+
const pos2 = percentage / 100 * length2 - 0.5;
|
|
1875
|
+
if (pos2 <= 0) return s[0];
|
|
1876
|
+
if (pos2 >= length2 - 1) return s[length2 - 1];
|
|
1877
|
+
const lo = Math.floor(pos2);
|
|
1878
|
+
return s[lo] + (pos2 - lo) * (s[lo + 1] - s[lo]);
|
|
1879
|
+
});
|
|
1880
|
+
}
|
|
1881
|
+
function sortedWindow(source, length2, fn) {
|
|
1887
1882
|
const result = [];
|
|
1883
|
+
const values = [];
|
|
1884
|
+
const bars2 = [];
|
|
1888
1885
|
for (let i = 0; i < source.length; i++) {
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
const
|
|
1896
|
-
values.
|
|
1897
|
-
|
|
1898
|
-
if (values.some((v) => isNaN(v))) {
|
|
1899
|
-
result.push(NaN);
|
|
1900
|
-
continue;
|
|
1901
|
-
}
|
|
1902
|
-
const sorted = [...values].sort((a, b2) => a - b2);
|
|
1903
|
-
const position = percentage / 100 * (sorted.length - 1);
|
|
1904
|
-
const lowerIndex = Math.floor(position);
|
|
1905
|
-
const upperIndex = Math.ceil(position);
|
|
1906
|
-
if (lowerIndex === upperIndex) {
|
|
1907
|
-
result.push(sorted[lowerIndex]);
|
|
1908
|
-
} else {
|
|
1909
|
-
const fraction = position - lowerIndex;
|
|
1910
|
-
const interpolated = sorted[lowerIndex] + fraction * (sorted[upperIndex] - sorted[lowerIndex]);
|
|
1911
|
-
result.push(interpolated);
|
|
1886
|
+
const v = source[i];
|
|
1887
|
+
let k = 0;
|
|
1888
|
+
while (k < values.length && !(values[k] >= v)) k++;
|
|
1889
|
+
values.splice(k, 0, v);
|
|
1890
|
+
bars2.splice(k, 0, i);
|
|
1891
|
+
if (i >= length2) {
|
|
1892
|
+
const old = bars2.indexOf(i - length2);
|
|
1893
|
+
values.splice(old, 1);
|
|
1894
|
+
bars2.splice(old, 1);
|
|
1912
1895
|
}
|
|
1896
|
+
result.push(i < length2 - 1 ? NaN : fn(values));
|
|
1913
1897
|
}
|
|
1914
1898
|
return result;
|
|
1915
1899
|
}
|
|
1916
1900
|
function percentile_nearest_rank(source, length2, percentage) {
|
|
1917
|
-
const
|
|
1918
|
-
|
|
1919
|
-
if (i < length2 - 1) {
|
|
1920
|
-
result.push(NaN);
|
|
1921
|
-
continue;
|
|
1922
|
-
}
|
|
1923
|
-
const values = [];
|
|
1924
|
-
for (let j = 0; j < length2; j++) {
|
|
1925
|
-
const value = source[i - j];
|
|
1926
|
-
if (!isNaN(value)) {
|
|
1927
|
-
values.push(value);
|
|
1928
|
-
}
|
|
1929
|
-
}
|
|
1930
|
-
if (values.length === 0) {
|
|
1931
|
-
result.push(NaN);
|
|
1932
|
-
continue;
|
|
1933
|
-
}
|
|
1934
|
-
const sorted = [...values].sort((a, b2) => a - b2);
|
|
1935
|
-
if (percentage >= 100) {
|
|
1936
|
-
result.push(sorted[sorted.length - 1]);
|
|
1937
|
-
continue;
|
|
1938
|
-
}
|
|
1939
|
-
const rank = Math.ceil(percentage / 100 * sorted.length);
|
|
1940
|
-
const index = Math.max(0, rank - 1);
|
|
1941
|
-
result.push(sorted[index]);
|
|
1942
|
-
}
|
|
1943
|
-
return result;
|
|
1901
|
+
const rank = Math.min(length2, Math.max(1, Math.ceil(percentage / 100 * length2)));
|
|
1902
|
+
return sortedWindow(source, length2, (s) => s[rank - 1]);
|
|
1944
1903
|
}
|
|
1945
1904
|
function rci(source, length2) {
|
|
1946
1905
|
const result = [];
|
|
@@ -2806,11 +2765,13 @@ __export(color_exports, {
|
|
|
2806
2765
|
white: () => white,
|
|
2807
2766
|
yellow: () => yellow
|
|
2808
2767
|
});
|
|
2768
|
+
var channel = (v) => v === null || v === void 0 || Number.isNaN(v) ? 0 : Math.max(0, Math.min(255, Math.trunc(v)));
|
|
2769
|
+
var alphaOf = (transp) => transp === null || Number.isNaN(transp) ? 0 : 1 - Math.max(0, Math.min(100, transp)) / 100;
|
|
2809
2770
|
function rgb(red2, green2, blue2, transp) {
|
|
2810
|
-
const r2 =
|
|
2811
|
-
const g2 =
|
|
2812
|
-
const b2 =
|
|
2813
|
-
const a = transp !== void 0 ?
|
|
2771
|
+
const r2 = channel(red2);
|
|
2772
|
+
const g2 = channel(green2);
|
|
2773
|
+
const b2 = channel(blue2);
|
|
2774
|
+
const a = transp !== void 0 ? alphaOf(transp) : 1;
|
|
2814
2775
|
if (a === 1) {
|
|
2815
2776
|
return `rgb(${r2}, ${g2}, ${b2})`;
|
|
2816
2777
|
}
|
|
@@ -2837,7 +2798,8 @@ function b(clr) {
|
|
|
2837
2798
|
return parseColor(clr).b;
|
|
2838
2799
|
}
|
|
2839
2800
|
function t(clr) {
|
|
2840
|
-
|
|
2801
|
+
const alpha = Math.round((1 - parseColor(clr).t / 100) * 255);
|
|
2802
|
+
return Math.round((1 - alpha / 255) * 100);
|
|
2841
2803
|
}
|
|
2842
2804
|
function parseColor(clr) {
|
|
2843
2805
|
if (typeof clr === "string") {
|
|
@@ -2890,13 +2852,12 @@ function from_gradient(value, bottom_value, top_value, bottom_color, top_color)
|
|
|
2890
2852
|
};
|
|
2891
2853
|
const c1 = rgba(bottom_color);
|
|
2892
2854
|
const c2 = rgba(top_color);
|
|
2893
|
-
const
|
|
2894
|
-
const w2 = c2.a * k;
|
|
2895
|
-
const a = w1 + w2;
|
|
2855
|
+
const a = c1.a * (1 - k) + c2.a * k;
|
|
2896
2856
|
if (a === 0) return transparent;
|
|
2897
|
-
const mix = (x1, x2) => Math.floor((x1 *
|
|
2857
|
+
const mix = (x1, x2) => Math.floor((x1 / 255 * c1.a * (1 - k) + x2 / 255 * c2.a * k) / (a / 255));
|
|
2898
2858
|
const [r2, g2, b2] = [mix(c1.r, c2.r), mix(c1.g, c2.g), mix(c1.b, c2.b)];
|
|
2899
|
-
|
|
2859
|
+
const alpha = Math.floor(a);
|
|
2860
|
+
return alpha === 255 ? `rgb(${r2}, ${g2}, ${b2})` : `rgba(${r2}, ${g2}, ${b2}, ${alpha / 255})`;
|
|
2900
2861
|
}
|
|
2901
2862
|
|
|
2902
2863
|
// src/drawing/registry.ts
|
|
@@ -2960,7 +2921,7 @@ function setDrawingLimits(newLimits) {
|
|
|
2960
2921
|
|
|
2961
2922
|
// src/utils/index.ts
|
|
2962
2923
|
function isNA(value) {
|
|
2963
|
-
return value === null || value === void 0 || Number.isNaN(value) || isDeleted(value);
|
|
2924
|
+
return value === null || value === void 0 || Number.isNaN(value) || value === Infinity || value === -Infinity || isDeleted(value);
|
|
2964
2925
|
}
|
|
2965
2926
|
function nz(value, defaultValue = 0) {
|
|
2966
2927
|
return isNA(value) ? defaultValue : value;
|
|
@@ -2969,7 +2930,7 @@ function fixnan(source) {
|
|
|
2969
2930
|
let last;
|
|
2970
2931
|
let seen = false;
|
|
2971
2932
|
return source.map((v) => {
|
|
2972
|
-
if (!
|
|
2933
|
+
if (!(v === null || v === void 0 || Number.isNaN(v) || isDeleted(v))) {
|
|
2973
2934
|
last = v;
|
|
2974
2935
|
seen = true;
|
|
2975
2936
|
return v;
|
|
@@ -3856,23 +3817,7 @@ function avg(...values) {
|
|
|
3856
3817
|
}
|
|
3857
3818
|
function sum(source, length2) {
|
|
3858
3819
|
const sourceArray = source instanceof Series ? source.toArray() : source;
|
|
3859
|
-
const result =
|
|
3860
|
-
const len = Math.floor(length2);
|
|
3861
|
-
const window = [];
|
|
3862
|
-
for (let i = 0; i < sourceArray.length; i++) {
|
|
3863
|
-
const v = sourceArray[i];
|
|
3864
|
-
if (v !== void 0 && v !== null && !Number.isNaN(v)) {
|
|
3865
|
-
window.push(v);
|
|
3866
|
-
if (window.length > len) window.shift();
|
|
3867
|
-
}
|
|
3868
|
-
if (window.length < len) {
|
|
3869
|
-
result.push(NaN);
|
|
3870
|
-
} else {
|
|
3871
|
-
let total = 0;
|
|
3872
|
-
for (const x of window) total += x;
|
|
3873
|
-
result.push(total);
|
|
3874
|
-
}
|
|
3875
|
-
}
|
|
3820
|
+
const result = runningSum(sourceArray, length2);
|
|
3876
3821
|
if (source instanceof Series) {
|
|
3877
3822
|
return Series.fromArray(source.bars, result);
|
|
3878
3823
|
}
|
|
@@ -4548,9 +4493,9 @@ function shortestDigits(x) {
|
|
|
4548
4493
|
function exactDigits(x) {
|
|
4549
4494
|
const abs2 = Math.abs(x);
|
|
4550
4495
|
if (abs2 === 0) return { digits: "", intLen: 0 };
|
|
4551
|
-
const
|
|
4552
|
-
|
|
4553
|
-
const bits =
|
|
4496
|
+
const view2 = new DataView(new ArrayBuffer(8));
|
|
4497
|
+
view2.setFloat64(0, abs2);
|
|
4498
|
+
const bits = view2.getBigUint64(0);
|
|
4554
4499
|
const expBits = Number(bits >> 52n & 0x7ffn);
|
|
4555
4500
|
let mant = bits & 0xfffffffffffffn;
|
|
4556
4501
|
const e2 = expBits === 0 ? -1074 : expBits - 1075;
|
|
@@ -5344,9 +5289,10 @@ var STRATEGY_DEFAULTS = {
|
|
|
5344
5289
|
calc_on_order_fills: false,
|
|
5345
5290
|
calc_on_every_tick: false,
|
|
5346
5291
|
backtest_fill_limits_assumption: 0,
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5292
|
+
// v6 values; PineScript v5: fixed / 1 / 1000000 and margins 0
|
|
5293
|
+
default_qty_type: "percent_of_equity",
|
|
5294
|
+
default_qty_value: 100,
|
|
5295
|
+
initial_capital: 1e5,
|
|
5350
5296
|
slippage: 0,
|
|
5351
5297
|
commission_type: "percent",
|
|
5352
5298
|
commission_value: 0,
|
|
@@ -5420,6 +5366,8 @@ function freshCollector(inputValues) {
|
|
|
5420
5366
|
fillConfig: [],
|
|
5421
5367
|
shapeConfig: [],
|
|
5422
5368
|
markers: [],
|
|
5369
|
+
arrowConfig: [],
|
|
5370
|
+
arrows: [],
|
|
5423
5371
|
barColorConfig: [],
|
|
5424
5372
|
bgcolors: [],
|
|
5425
5373
|
barcolors: [],
|
|
@@ -5457,6 +5405,7 @@ function executeScript(body, barsInput, inputs = {}, chart2 = {}, options = {})
|
|
|
5457
5405
|
hlineConfig: c.hlineConfig,
|
|
5458
5406
|
fillConfig: c.fillConfig,
|
|
5459
5407
|
shapeConfig: c.shapeConfig,
|
|
5408
|
+
arrowConfig: c.arrowConfig,
|
|
5460
5409
|
barColorConfig: c.barColorConfig,
|
|
5461
5410
|
defaultInputs: c.defaultInputs,
|
|
5462
5411
|
alertConfig: c.alertConfig,
|
|
@@ -5466,6 +5415,7 @@ function executeScript(body, barsInput, inputs = {}, chart2 = {}, options = {})
|
|
|
5466
5415
|
plots: c.plots,
|
|
5467
5416
|
fills: c.fills.length ? c.fills : void 0,
|
|
5468
5417
|
markers: c.markers.length ? c.markers : void 0,
|
|
5418
|
+
arrows: c.arrows.length ? c.arrows : void 0,
|
|
5469
5419
|
bgcolors: c.bgcolors.length ? c.bgcolors : void 0,
|
|
5470
5420
|
barcolors: c.barcolors.length ? c.barcolors : void 0,
|
|
5471
5421
|
alerts: c.alerts.length ? c.alerts : void 0
|
|
@@ -5496,6 +5446,15 @@ function declare(c, kind) {
|
|
|
5496
5446
|
}
|
|
5497
5447
|
c.declaration = kind;
|
|
5498
5448
|
}
|
|
5449
|
+
function common(opts) {
|
|
5450
|
+
const out = {};
|
|
5451
|
+
if (opts.group !== void 0) out.group = opts.group;
|
|
5452
|
+
if (opts.inline !== void 0) out.inline = opts.inline;
|
|
5453
|
+
if (opts.tooltip !== void 0) out.tooltip = opts.tooltip;
|
|
5454
|
+
if (opts.confirm !== void 0) out.confirm = opts.confirm;
|
|
5455
|
+
if (opts.display !== void 0) out.display = opts.display;
|
|
5456
|
+
return out;
|
|
5457
|
+
}
|
|
5499
5458
|
function registerInput(config, fallbackId) {
|
|
5500
5459
|
const c = collector();
|
|
5501
5460
|
const id = slugId(config.title, fallbackId, c.inputIds);
|
|
@@ -5506,7 +5465,7 @@ function registerInput(config, fallbackId) {
|
|
|
5506
5465
|
}
|
|
5507
5466
|
function registerNumeric(type, defval, title, opts = {}) {
|
|
5508
5467
|
const v = registerInput(
|
|
5509
|
-
{ type, defval, title, min: opts.minval, max: opts.maxval, step: opts.step },
|
|
5468
|
+
{ type, defval, title, min: opts.minval, max: opts.maxval, step: opts.step, ...common(opts) },
|
|
5510
5469
|
`input_${type}`
|
|
5511
5470
|
);
|
|
5512
5471
|
return typeof v === "number" ? v : defval;
|
|
@@ -5518,31 +5477,37 @@ var input = {
|
|
|
5518
5477
|
float(defval, title, opts = {}) {
|
|
5519
5478
|
return registerNumeric("float", defval, title, opts);
|
|
5520
5479
|
},
|
|
5521
|
-
bool(defval, title) {
|
|
5522
|
-
return registerInput({ type: "bool", defval, title }, "input_bool");
|
|
5480
|
+
bool(defval, title, opts = {}) {
|
|
5481
|
+
return registerInput({ type: "bool", defval, title, ...common(opts) }, "input_bool");
|
|
5523
5482
|
},
|
|
5524
5483
|
string(defval, title, opts = {}) {
|
|
5525
|
-
return registerInput({ type: "string", defval, title, options: opts.options }, "input_string");
|
|
5484
|
+
return registerInput({ type: "string", defval, title, options: opts.options, ...common(opts) }, "input_string");
|
|
5526
5485
|
},
|
|
5527
|
-
color(defval, title) {
|
|
5528
|
-
return registerInput({ type: "color", defval, title }, "input_color");
|
|
5486
|
+
color(defval, title, opts = {}) {
|
|
5487
|
+
return registerInput({ type: "color", defval, title, ...common(opts) }, "input_color");
|
|
5529
5488
|
},
|
|
5530
5489
|
/** Declares a source input and returns it as a Series. */
|
|
5531
|
-
source(defval = "close", title) {
|
|
5532
|
-
const name = registerInput({ type: "source", defval, title }, "input_source");
|
|
5490
|
+
source(defval = "close", title, opts = {}) {
|
|
5491
|
+
const name = registerInput({ type: "source", defval, title, ...common(opts) }, "input_source");
|
|
5533
5492
|
return sourceSeries(name);
|
|
5534
5493
|
},
|
|
5535
5494
|
/** Timeframe string ("60", "1D", "W"). As in PineScript, "" means the chart timeframe. */
|
|
5536
5495
|
timeframe(defval, title, opts = {}) {
|
|
5537
|
-
return registerInput(
|
|
5496
|
+
return registerInput(
|
|
5497
|
+
{ type: "timeframe", defval, title, options: opts.options, ...common(opts) },
|
|
5498
|
+
"input_timeframe"
|
|
5499
|
+
);
|
|
5538
5500
|
},
|
|
5539
5501
|
/** Session string ("0930-1600", "0930-1600:23456"). */
|
|
5540
5502
|
session(defval, title, opts = {}) {
|
|
5541
|
-
return registerInput(
|
|
5503
|
+
return registerInput(
|
|
5504
|
+
{ type: "session", defval, title, options: opts.options, ...common(opts) },
|
|
5505
|
+
"input_session"
|
|
5506
|
+
);
|
|
5542
5507
|
},
|
|
5543
5508
|
/** Date and time as a UNIX time in milliseconds, e.g. `input.time(timestamp('2024-01-01'), 'Start')`. */
|
|
5544
|
-
time(defval, title) {
|
|
5545
|
-
const v = registerInput({ type: "time", defval, title }, "input_time");
|
|
5509
|
+
time(defval, title, opts = {}) {
|
|
5510
|
+
const v = registerInput({ type: "time", defval, title, ...common(opts) }, "input_time");
|
|
5546
5511
|
return typeof v === "number" ? v : defval;
|
|
5547
5512
|
}
|
|
5548
5513
|
};
|
|
@@ -5596,6 +5561,8 @@ var ta2 = {
|
|
|
5596
5561
|
const a = anchor ?? changeOf("1D");
|
|
5597
5562
|
return stdev_mult === void 0 ? vwap2(source, volume, a) : vwapBands(source, volume, a, stdev_mult);
|
|
5598
5563
|
}),
|
|
5564
|
+
/** `ta.mfi(source, length)` with the chart volume (PineScript takes 2 arguments). */
|
|
5565
|
+
mfi: (source, length2) => mfi2(source, length2, volume),
|
|
5599
5566
|
/** `ta.pivothigh(source, leftbars, rightbars)` or `ta.pivothigh(leftbars, rightbars)` (source = high).
|
|
5600
5567
|
* The value appears `rightbars` bars after the pivot bar, as in PineScript. */
|
|
5601
5568
|
pivothigh: (sourceOrLeft, leftOrRight, rightbars) => typeof sourceOrLeft === "number" ? pivothigh2(high, sourceOrLeft, leftOrRight) : pivothigh2(sourceOrLeft, leftOrRight, rightbars),
|
|
@@ -5622,7 +5589,7 @@ var color = {
|
|
|
5622
5589
|
new: new_color,
|
|
5623
5590
|
when: colorWhen
|
|
5624
5591
|
};
|
|
5625
|
-
function
|
|
5592
|
+
function plotImpl(series, title, options = {}) {
|
|
5626
5593
|
const c = collector();
|
|
5627
5594
|
const id = `plot${c.plotConfig.length}`;
|
|
5628
5595
|
const perBar2 = Array.isArray(options.color) ? options.color : void 0;
|
|
@@ -5633,21 +5600,39 @@ function plot(series, title, options = {}) {
|
|
|
5633
5600
|
color: staticColor,
|
|
5634
5601
|
lineWidth: options.linewidth,
|
|
5635
5602
|
style: options.style,
|
|
5603
|
+
linestyle: options.linestyle,
|
|
5636
5604
|
display: options.display,
|
|
5637
|
-
histbase: options.histbase
|
|
5605
|
+
histbase: options.histbase,
|
|
5606
|
+
forceOverlay: options.force_overlay
|
|
5638
5607
|
});
|
|
5639
5608
|
const values = series.toArray();
|
|
5640
5609
|
const b2 = bars();
|
|
5641
5610
|
const data = [];
|
|
5642
5611
|
for (let i = 0; i < b2.length; i++) {
|
|
5643
5612
|
const value = values[i];
|
|
5644
|
-
if (value === void 0 || Number.
|
|
5613
|
+
if (value === void 0 || !Number.isFinite(value)) continue;
|
|
5645
5614
|
data.push(perBar2 ? { time: b2[i].time, value, color: perBar2[i] } : { time: b2[i].time, value });
|
|
5646
5615
|
}
|
|
5647
5616
|
c.plots[id] = data;
|
|
5648
5617
|
return { id, kind: "plot" };
|
|
5649
5618
|
}
|
|
5650
|
-
|
|
5619
|
+
var plot = Object.assign(plotImpl, {
|
|
5620
|
+
style_line: "line",
|
|
5621
|
+
style_linebr: "linebr",
|
|
5622
|
+
style_stepline: "stepline",
|
|
5623
|
+
style_steplinebr: "steplinebr",
|
|
5624
|
+
style_stepline_diamond: "stepline_diamond",
|
|
5625
|
+
style_histogram: "histogram",
|
|
5626
|
+
style_columns: "columns",
|
|
5627
|
+
style_area: "area",
|
|
5628
|
+
style_areabr: "areabr",
|
|
5629
|
+
style_circles: "circles",
|
|
5630
|
+
style_cross: "cross",
|
|
5631
|
+
linestyle_solid: "solid",
|
|
5632
|
+
linestyle_dotted: "dotted",
|
|
5633
|
+
linestyle_dashed: "dashed"
|
|
5634
|
+
});
|
|
5635
|
+
function hlineImpl(price, title, options = {}) {
|
|
5651
5636
|
const c = collector();
|
|
5652
5637
|
const id = `hline${c.hlineConfig.length}`;
|
|
5653
5638
|
c.hlineConfig.push({
|
|
@@ -5655,11 +5640,16 @@ function hline(price, title, options = {}) {
|
|
|
5655
5640
|
price,
|
|
5656
5641
|
title,
|
|
5657
5642
|
color: options.color,
|
|
5658
|
-
linestyle: options.linestyle,
|
|
5643
|
+
linestyle: options.linestyle ?? "dashed",
|
|
5659
5644
|
linewidth: options.linewidth
|
|
5660
5645
|
});
|
|
5661
5646
|
return { id, kind: "hline" };
|
|
5662
5647
|
}
|
|
5648
|
+
var hline = Object.assign(hlineImpl, {
|
|
5649
|
+
style_solid: "solid",
|
|
5650
|
+
style_dotted: "dotted",
|
|
5651
|
+
style_dashed: "dashed"
|
|
5652
|
+
});
|
|
5663
5653
|
function perBarValues(v, n) {
|
|
5664
5654
|
return v instanceof Series ? v.toArray().slice(0, n) : new Array(n).fill(v);
|
|
5665
5655
|
}
|
|
@@ -5731,7 +5721,8 @@ function emitMarkers(kind, condition, title, options) {
|
|
|
5731
5721
|
text: options.text,
|
|
5732
5722
|
textcolor: options.textcolor,
|
|
5733
5723
|
size: options.size,
|
|
5734
|
-
offset: options.offset
|
|
5724
|
+
offset: options.offset,
|
|
5725
|
+
forceOverlay: options.force_overlay
|
|
5735
5726
|
});
|
|
5736
5727
|
const values = condition.toArray();
|
|
5737
5728
|
const b2 = bars();
|
|
@@ -5762,10 +5753,40 @@ function plotshape(condition, title, options = {}) {
|
|
|
5762
5753
|
function plotchar(condition, title, options = {}) {
|
|
5763
5754
|
emitMarkers("char", condition, title, options);
|
|
5764
5755
|
}
|
|
5756
|
+
function plotarrow(series, title, options = {}) {
|
|
5757
|
+
const c = collector();
|
|
5758
|
+
const id = `arrow${c.arrowConfig.length}`;
|
|
5759
|
+
const pick = (col2, fallback, i) => col2 === void 0 ? fallback : typeof col2 === "string" ? col2 : col2[i];
|
|
5760
|
+
const colorup = typeof options.colorup === "string" ? options.colorup : "#00FF00";
|
|
5761
|
+
const colordown = typeof options.colordown === "string" ? options.colordown : "#FF0000";
|
|
5762
|
+
c.arrowConfig.push({
|
|
5763
|
+
id,
|
|
5764
|
+
title,
|
|
5765
|
+
colorup,
|
|
5766
|
+
colordown,
|
|
5767
|
+
minheight: options.minheight ?? 5,
|
|
5768
|
+
maxheight: options.maxheight ?? 100,
|
|
5769
|
+
offset: options.offset,
|
|
5770
|
+
display: options.display,
|
|
5771
|
+
forceOverlay: options.force_overlay
|
|
5772
|
+
});
|
|
5773
|
+
const values = series.toArray();
|
|
5774
|
+
const b2 = bars();
|
|
5775
|
+
const off = options.offset ?? 0;
|
|
5776
|
+
for (let i = 0; i < b2.length; i++) {
|
|
5777
|
+
const v = values[i];
|
|
5778
|
+
if (v === void 0 || Number.isNaN(v) || v === 0) continue;
|
|
5779
|
+
const j = i + off;
|
|
5780
|
+
if (j < 0 || j >= b2.length) continue;
|
|
5781
|
+
const color2 = v > 0 ? pick(options.colorup, "#00FF00", i) : pick(options.colordown, "#FF0000", i);
|
|
5782
|
+
if (color2 === void 0) continue;
|
|
5783
|
+
c.arrows.push({ time: b2[j].time, id, value: v, color: color2 });
|
|
5784
|
+
}
|
|
5785
|
+
}
|
|
5765
5786
|
function emitBarColors(kind, colors, options) {
|
|
5766
5787
|
const c = collector();
|
|
5767
5788
|
const id = `${kind}${c.barColorConfig.filter((x) => x.kind === kind).length}`;
|
|
5768
|
-
c.barColorConfig.push({ id, kind, title: options.title, offset: options.offset });
|
|
5789
|
+
c.barColorConfig.push({ id, kind, title: options.title, offset: options.offset, forceOverlay: options.force_overlay });
|
|
5769
5790
|
const b2 = bars();
|
|
5770
5791
|
const off = options.offset ?? 0;
|
|
5771
5792
|
const target = kind === "bgcolor" ? c.bgcolors : c.barcolors;
|
|
@@ -6163,6 +6184,37 @@ function flag(key) {
|
|
|
6163
6184
|
const values = sessionFlags(ctxBars.bars.map(barTime), bars2, regular)[key];
|
|
6164
6185
|
return Series.fromArray(ctxBars, values.map((v) => v ? 1 : 0));
|
|
6165
6186
|
}
|
|
6187
|
+
function barFlag(test) {
|
|
6188
|
+
const n = ctxBars.bars.length;
|
|
6189
|
+
return Series.fromArray(ctxBars, Array.from({ length: n }, (_, i) => test(i, n) ? 1 : 0));
|
|
6190
|
+
}
|
|
6191
|
+
var lastRealtime = (i, n) => i === n - 1 && chartCtx.realtime === true;
|
|
6192
|
+
var barstate = {
|
|
6193
|
+
get isfirst() {
|
|
6194
|
+
return barFlag((i) => i === 0);
|
|
6195
|
+
},
|
|
6196
|
+
get islast() {
|
|
6197
|
+
return barFlag((i, n) => i === n - 1);
|
|
6198
|
+
},
|
|
6199
|
+
get isconfirmed() {
|
|
6200
|
+
return barFlag((i, n) => i < n - 1 || chartCtx.lastBarConfirmed === true);
|
|
6201
|
+
},
|
|
6202
|
+
get isrealtime() {
|
|
6203
|
+
return barFlag(lastRealtime);
|
|
6204
|
+
},
|
|
6205
|
+
get ishistory() {
|
|
6206
|
+
return barFlag((i, n) => !lastRealtime(i, n));
|
|
6207
|
+
},
|
|
6208
|
+
get isnew() {
|
|
6209
|
+
return barFlag((i, n) => !lastRealtime(i, n) || chartCtx.lastBarNew !== false);
|
|
6210
|
+
},
|
|
6211
|
+
get islastconfirmedhistory() {
|
|
6212
|
+
return barFlag((i, n) => {
|
|
6213
|
+
const lastConfirmed = chartCtx.lastBarConfirmed === true && chartCtx.realtime !== true;
|
|
6214
|
+
return i === (lastConfirmed ? n - 1 : n - 2);
|
|
6215
|
+
});
|
|
6216
|
+
}
|
|
6217
|
+
};
|
|
6166
6218
|
var session = {
|
|
6167
6219
|
regular: "regular",
|
|
6168
6220
|
extended: "extended",
|