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.cjs
CHANGED
|
@@ -22,6 +22,10 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
BarData: () => BarData,
|
|
24
24
|
LightweightChartsAdapter: () => LightweightChartsAdapter,
|
|
25
|
+
STRATEGY_CONSTANTS: () => STRATEGY_CONSTANTS,
|
|
26
|
+
STRATEGY_DEFAULTS: () => STRATEGY_DEFAULTS,
|
|
27
|
+
STRATEGY_NUMBER_VARIABLES: () => STRATEGY_NUMBER_VARIABLES,
|
|
28
|
+
STRATEGY_TEXT_VARIABLES: () => STRATEGY_TEXT_VARIABLES,
|
|
25
29
|
Series: () => Series,
|
|
26
30
|
SimpleInputAdapter: () => SimpleInputAdapter,
|
|
27
31
|
VERSION: () => VERSION,
|
|
@@ -29,11 +33,13 @@ __export(index_exports, {
|
|
|
29
33
|
abs: () => abs,
|
|
30
34
|
alertcondition: () => alertcondition,
|
|
31
35
|
array: () => array_exports,
|
|
36
|
+
at: () => at,
|
|
32
37
|
atr: () => atr2,
|
|
33
38
|
avg: () => avg,
|
|
34
39
|
bb: () => bb2,
|
|
35
40
|
box: () => box_exports,
|
|
36
41
|
calculateZigZag: () => calculateZigZag,
|
|
42
|
+
callsite: () => callsite_exports,
|
|
37
43
|
ceil: () => ceil,
|
|
38
44
|
change: () => change2,
|
|
39
45
|
chartPoint: () => chartpoint_exports,
|
|
@@ -44,9 +50,10 @@ __export(index_exports, {
|
|
|
44
50
|
compare: () => compare_exports,
|
|
45
51
|
cos: () => cos,
|
|
46
52
|
createPlot: () => createPlot,
|
|
47
|
-
crossover: () =>
|
|
48
|
-
crossunder: () =>
|
|
53
|
+
crossover: () => crossover3,
|
|
54
|
+
crossunder: () => crossunder3,
|
|
49
55
|
cum: () => cum2,
|
|
56
|
+
div: () => div,
|
|
50
57
|
ema: () => ema2,
|
|
51
58
|
exp: () => exp,
|
|
52
59
|
fixnan: () => fixnan,
|
|
@@ -56,6 +63,7 @@ __export(index_exports, {
|
|
|
56
63
|
getHigh: () => getHigh,
|
|
57
64
|
getLow: () => getLow,
|
|
58
65
|
getOpen: () => getOpen,
|
|
66
|
+
getSource: () => getSource,
|
|
59
67
|
getSourceSeries: () => getSourceSeries,
|
|
60
68
|
hline: () => hline,
|
|
61
69
|
indicator: () => indicator,
|
|
@@ -193,13 +201,47 @@ __export(ta_exports, {
|
|
|
193
201
|
wvad: () => wvad,
|
|
194
202
|
zigzag: () => zigzag
|
|
195
203
|
});
|
|
204
|
+
|
|
205
|
+
// src/compare/index.ts
|
|
206
|
+
var compare_exports = {};
|
|
207
|
+
__export(compare_exports, {
|
|
208
|
+
EPSILON: () => EPSILON,
|
|
209
|
+
eq: () => eq,
|
|
210
|
+
ge: () => ge,
|
|
211
|
+
gt: () => gt,
|
|
212
|
+
le: () => le,
|
|
213
|
+
lt: () => lt,
|
|
214
|
+
ne: () => ne
|
|
215
|
+
});
|
|
216
|
+
var EPSILON = 1e-10;
|
|
217
|
+
var valid = (a, b2) => !Number.isNaN(a) && !Number.isNaN(b2);
|
|
218
|
+
function eq(a, b2) {
|
|
219
|
+
return valid(a, b2) && Math.abs(a - b2) <= EPSILON;
|
|
220
|
+
}
|
|
221
|
+
function ne(a, b2) {
|
|
222
|
+
return valid(a, b2) && Math.abs(a - b2) > EPSILON;
|
|
223
|
+
}
|
|
224
|
+
function lt(a, b2) {
|
|
225
|
+
return valid(a, b2) && b2 - a > EPSILON;
|
|
226
|
+
}
|
|
227
|
+
function le(a, b2) {
|
|
228
|
+
return valid(a, b2) && a - b2 <= EPSILON;
|
|
229
|
+
}
|
|
230
|
+
function gt(a, b2) {
|
|
231
|
+
return valid(a, b2) && a - b2 > EPSILON;
|
|
232
|
+
}
|
|
233
|
+
function ge(a, b2) {
|
|
234
|
+
return valid(a, b2) && b2 - a <= EPSILON;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/ta/index.ts
|
|
196
238
|
function sma(source, length2) {
|
|
197
239
|
const result = [];
|
|
198
240
|
const len = Math.floor(length2);
|
|
199
241
|
const window = [];
|
|
200
242
|
for (let i = 0; i < source.length; i++) {
|
|
201
243
|
const v = source[i];
|
|
202
|
-
if (v !== void 0 && v !== null &&
|
|
244
|
+
if (v !== void 0 && v !== null && Number.isFinite(v)) {
|
|
203
245
|
window.push(v);
|
|
204
246
|
if (window.length > len) window.shift();
|
|
205
247
|
}
|
|
@@ -384,7 +426,7 @@ function tr(handle_na = false, high, low, close) {
|
|
|
384
426
|
const result = [];
|
|
385
427
|
for (let i = 0; i < high.length; i++) {
|
|
386
428
|
if (i === 0) {
|
|
387
|
-
result.push(high[i] - low[i]);
|
|
429
|
+
result.push(handle_na ? high[i] - low[i] : NaN);
|
|
388
430
|
} else {
|
|
389
431
|
const prevClose = close[i - 1];
|
|
390
432
|
if (isNaN(prevClose)) {
|
|
@@ -411,7 +453,7 @@ function atr(length2, high, low, close) {
|
|
|
411
453
|
"ta.atr() requires high, low, and close series. Either pass them explicitly or use createContext({ chart: { high, low, close } }) for implicit data."
|
|
412
454
|
);
|
|
413
455
|
}
|
|
414
|
-
const trueRange = tr(
|
|
456
|
+
const trueRange = tr(true, high, low, close);
|
|
415
457
|
return rma(trueRange, length2);
|
|
416
458
|
}
|
|
417
459
|
function supertrend(factor, atrPeriod, high, low, close, wicks = false) {
|
|
@@ -543,7 +585,7 @@ function lowest(source, length2) {
|
|
|
543
585
|
function cum(source) {
|
|
544
586
|
let sum4 = 0;
|
|
545
587
|
return source.map((v) => {
|
|
546
|
-
if (Number.
|
|
588
|
+
if (!Number.isFinite(v)) return NaN;
|
|
547
589
|
sum4 += v;
|
|
548
590
|
return sum4;
|
|
549
591
|
});
|
|
@@ -561,41 +603,24 @@ function cross(source1, source2) {
|
|
|
561
603
|
}
|
|
562
604
|
return result;
|
|
563
605
|
}
|
|
564
|
-
function
|
|
606
|
+
function monotonic(source, length2, step) {
|
|
565
607
|
const result = [];
|
|
608
|
+
const values2 = [];
|
|
566
609
|
for (let i = 0; i < source.length; i++) {
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
isRising = false;
|
|
574
|
-
break;
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
result.push(isRising);
|
|
578
|
-
}
|
|
610
|
+
const v = source[i];
|
|
611
|
+
if (!Number.isNaN(v)) values2.push(v);
|
|
612
|
+
const n = values2.length;
|
|
613
|
+
let ok = n > length2;
|
|
614
|
+
for (let j = 1; ok && j <= length2; j++) ok = step(values2[n - j], values2[n - j - 1]);
|
|
615
|
+
result.push(ok);
|
|
579
616
|
}
|
|
580
617
|
return result;
|
|
581
618
|
}
|
|
619
|
+
function rising(source, length2) {
|
|
620
|
+
return monotonic(source, length2, gt);
|
|
621
|
+
}
|
|
582
622
|
function falling(source, length2) {
|
|
583
|
-
|
|
584
|
-
for (let i = 0; i < source.length; i++) {
|
|
585
|
-
if (i < length2) {
|
|
586
|
-
result.push(false);
|
|
587
|
-
} else {
|
|
588
|
-
let isFalling = true;
|
|
589
|
-
for (let j = 1; j <= length2; j++) {
|
|
590
|
-
if (source[i - j + 1] >= source[i - j]) {
|
|
591
|
-
isFalling = false;
|
|
592
|
-
break;
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
result.push(isFalling);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
return result;
|
|
623
|
+
return monotonic(source, length2, lt);
|
|
599
624
|
}
|
|
600
625
|
function roc(source, length2) {
|
|
601
626
|
const result = [];
|
|
@@ -819,33 +844,16 @@ function correlation(source1, source2, length2) {
|
|
|
819
844
|
function percentrank(source, length2) {
|
|
820
845
|
const result = [];
|
|
821
846
|
for (let i = 0; i < source.length; i++) {
|
|
822
|
-
|
|
847
|
+
const currentValue = source[i];
|
|
848
|
+
if (i < length2 || Number.isNaN(currentValue)) {
|
|
823
849
|
result.push(NaN);
|
|
824
|
-
|
|
825
|
-
if (isNaN(source[i])) {
|
|
826
|
-
result.push(NaN);
|
|
827
|
-
continue;
|
|
828
|
-
}
|
|
829
|
-
let hasNaN = false;
|
|
830
|
-
for (let j = 1; j <= length2; j++) {
|
|
831
|
-
if (isNaN(source[i - j])) {
|
|
832
|
-
hasNaN = true;
|
|
833
|
-
break;
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
if (hasNaN) {
|
|
837
|
-
result.push(NaN);
|
|
838
|
-
} else {
|
|
839
|
-
const currentValue = source[i];
|
|
840
|
-
let countLessOrEqual = 0;
|
|
841
|
-
for (let j = 1; j <= length2; j++) {
|
|
842
|
-
if (source[i - j] <= currentValue) {
|
|
843
|
-
countLessOrEqual++;
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
result.push(countLessOrEqual / length2 * 100);
|
|
847
|
-
}
|
|
850
|
+
continue;
|
|
848
851
|
}
|
|
852
|
+
let countLessOrEqual = 0;
|
|
853
|
+
for (let j = 1; j <= length2; j++) {
|
|
854
|
+
if (le(source[i - j], currentValue)) countLessOrEqual++;
|
|
855
|
+
}
|
|
856
|
+
result.push(countLessOrEqual / length2 * 100);
|
|
849
857
|
}
|
|
850
858
|
return result;
|
|
851
859
|
}
|
|
@@ -888,48 +896,26 @@ function mfi(source, length2, volume) {
|
|
|
888
896
|
"ta.mfi() requires volume series. Either pass it explicitly or use createContext({ chart: { ..., volume } }) for implicit data."
|
|
889
897
|
);
|
|
890
898
|
}
|
|
891
|
-
const
|
|
892
|
-
const
|
|
893
|
-
for (let i = 1; i < source.length; i++) {
|
|
894
|
-
changes.push(source[i] - source[i - 1]);
|
|
895
|
-
}
|
|
896
|
-
const positiveFlow = [];
|
|
897
|
-
const negativeFlow = [];
|
|
899
|
+
const upperFlow = [];
|
|
900
|
+
const lowerFlow = [];
|
|
898
901
|
for (let i = 0; i < source.length; i++) {
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
} else {
|
|
917
|
-
let posSum = 0;
|
|
918
|
-
let negSum = 0;
|
|
919
|
-
for (let j = 0; j < length2; j++) {
|
|
920
|
-
posSum += positiveFlow[i - j];
|
|
921
|
-
negSum += negativeFlow[i - j];
|
|
922
|
-
}
|
|
923
|
-
if (negSum === 0) {
|
|
924
|
-
result.push(100);
|
|
925
|
-
} else {
|
|
926
|
-
const moneyRatio = posSum / negSum;
|
|
927
|
-
const mfiValue = 100 - 100 / (1 + moneyRatio);
|
|
928
|
-
result.push(mfiValue);
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
return result;
|
|
902
|
+
const change3 = i === 0 ? NaN : source[i] - source[i - 1];
|
|
903
|
+
const flow = volume[i] * source[i];
|
|
904
|
+
upperFlow.push(le(change3, 0) ? 0 : flow);
|
|
905
|
+
lowerFlow.push(ge(change3, 0) ? 0 : flow);
|
|
906
|
+
}
|
|
907
|
+
const sumAt = (flow, i) => {
|
|
908
|
+
const values2 = lastValues(flow, i, Math.floor(length2));
|
|
909
|
+
return values2 ? values2.reduce((a, b2) => a + b2, 0) : NaN;
|
|
910
|
+
};
|
|
911
|
+
const upper2 = upperFlow.map((_, i) => sumAt(upperFlow, i));
|
|
912
|
+
const lower2 = lowerFlow.map((_, i) => sumAt(lowerFlow, i));
|
|
913
|
+
return upper2.map((u, i) => {
|
|
914
|
+
const l = lower2[i];
|
|
915
|
+
if (Number.isNaN(u) || Number.isNaN(l)) return NaN;
|
|
916
|
+
if (l === 0) return 100;
|
|
917
|
+
return 100 - 100 / (1 + u / l);
|
|
918
|
+
});
|
|
933
919
|
}
|
|
934
920
|
function hma(source, length2) {
|
|
935
921
|
const halfLength = Math.floor(length2 / 2);
|
|
@@ -1093,50 +1079,32 @@ function dmi(diLength, adxSmoothing, high, low, close) {
|
|
|
1093
1079
|
const len = Math.max(high.length, low.length, close.length);
|
|
1094
1080
|
const plusDM = [];
|
|
1095
1081
|
const minusDM = [];
|
|
1096
|
-
const trueRangeValues = tr(false, high, low, close);
|
|
1097
|
-
for (let i = 0; i < len; i++) {
|
|
1098
|
-
if (i === 0) {
|
|
1099
|
-
plusDM.push(0);
|
|
1100
|
-
minusDM.push(0);
|
|
1101
|
-
} else {
|
|
1102
|
-
const upMove = high[i] - high[i - 1];
|
|
1103
|
-
const downMove = low[i - 1] - low[i];
|
|
1104
|
-
let plusDMVal = 0;
|
|
1105
|
-
let minusDMVal = 0;
|
|
1106
|
-
if (upMove > downMove && upMove > 0) {
|
|
1107
|
-
plusDMVal = upMove;
|
|
1108
|
-
}
|
|
1109
|
-
if (downMove > upMove && downMove > 0) {
|
|
1110
|
-
minusDMVal = downMove;
|
|
1111
|
-
}
|
|
1112
|
-
plusDM.push(plusDMVal);
|
|
1113
|
-
minusDM.push(minusDMVal);
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
const smoothedPlusDM = rma(plusDM, diLength);
|
|
1117
|
-
const smoothedMinusDM = rma(minusDM, diLength);
|
|
1118
|
-
const smoothedTR = rma(trueRangeValues, diLength);
|
|
1119
|
-
const plusDI = [];
|
|
1120
|
-
const minusDI = [];
|
|
1121
|
-
for (let i = 0; i < len; i++) {
|
|
1122
|
-
if (smoothedTR[i] === 0) {
|
|
1123
|
-
plusDI.push(0);
|
|
1124
|
-
minusDI.push(0);
|
|
1125
|
-
} else {
|
|
1126
|
-
plusDI.push(smoothedPlusDM[i] / smoothedTR[i] * 100);
|
|
1127
|
-
minusDI.push(smoothedMinusDM[i] / smoothedTR[i] * 100);
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
const dx = [];
|
|
1131
1082
|
for (let i = 0; i < len; i++) {
|
|
1132
|
-
const
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
const
|
|
1083
|
+
const up = i === 0 ? NaN : high[i] - high[i - 1];
|
|
1084
|
+
const down = i === 0 ? NaN : low[i - 1] - low[i];
|
|
1085
|
+
plusDM.push(Number.isNaN(up) ? NaN : gt(up, down) && gt(up, 0) ? up : 0);
|
|
1086
|
+
minusDM.push(Number.isNaN(down) ? NaN : gt(down, up) && gt(down, 0) ? down : 0);
|
|
1087
|
+
}
|
|
1088
|
+
const trur = rma(tr(false, high, low, close), diLength);
|
|
1089
|
+
const smoothedPlus = rma(plusDM, diLength);
|
|
1090
|
+
const smoothedMinus = rma(minusDM, diLength);
|
|
1091
|
+
const directional = (smoothed) => {
|
|
1092
|
+
let last2 = NaN;
|
|
1093
|
+
return smoothed.map((v, i) => {
|
|
1094
|
+
const t2 = trur[i];
|
|
1095
|
+
const value = t2 === 0 ? NaN : 100 * v / t2;
|
|
1096
|
+
if (!Number.isNaN(value)) last2 = value;
|
|
1097
|
+
return last2;
|
|
1098
|
+
});
|
|
1099
|
+
};
|
|
1100
|
+
const plusDI = directional(smoothedPlus);
|
|
1101
|
+
const minusDI = directional(smoothedMinus);
|
|
1102
|
+
const dx = plusDI.map((plus, i) => {
|
|
1103
|
+
const minus = minusDI[i];
|
|
1104
|
+
const sum4 = plus + minus;
|
|
1105
|
+
return Math.abs(plus - minus) / (eq(sum4, 0) ? 1 : sum4);
|
|
1106
|
+
});
|
|
1107
|
+
const adx = rma(dx, adxSmoothing).map((v) => 100 * v);
|
|
1140
1108
|
return [plusDI, minusDI, adx];
|
|
1141
1109
|
}
|
|
1142
1110
|
function tsi(source, shortLength, longLength) {
|
|
@@ -1412,63 +1380,36 @@ function mode(source, length2) {
|
|
|
1412
1380
|
return result;
|
|
1413
1381
|
}
|
|
1414
1382
|
function percentile_linear_interpolation(source, length2, percentage) {
|
|
1383
|
+
return sortedWindow(source, length2, (s) => {
|
|
1384
|
+
const pos2 = percentage / 100 * length2 - 0.5;
|
|
1385
|
+
if (pos2 <= 0) return s[0];
|
|
1386
|
+
if (pos2 >= length2 - 1) return s[length2 - 1];
|
|
1387
|
+
const lo = Math.floor(pos2);
|
|
1388
|
+
return s[lo] + (pos2 - lo) * (s[lo + 1] - s[lo]);
|
|
1389
|
+
});
|
|
1390
|
+
}
|
|
1391
|
+
function sortedWindow(source, length2, fn) {
|
|
1415
1392
|
const result = [];
|
|
1393
|
+
const values2 = [];
|
|
1394
|
+
const bars = [];
|
|
1416
1395
|
for (let i = 0; i < source.length; i++) {
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
const
|
|
1424
|
-
values2.
|
|
1425
|
-
|
|
1426
|
-
if (values2.some((v) => isNaN(v))) {
|
|
1427
|
-
result.push(NaN);
|
|
1428
|
-
continue;
|
|
1429
|
-
}
|
|
1430
|
-
const sorted = [...values2].sort((a, b2) => a - b2);
|
|
1431
|
-
const position = percentage / 100 * (sorted.length - 1);
|
|
1432
|
-
const lowerIndex = Math.floor(position);
|
|
1433
|
-
const upperIndex = Math.ceil(position);
|
|
1434
|
-
if (lowerIndex === upperIndex) {
|
|
1435
|
-
result.push(sorted[lowerIndex]);
|
|
1436
|
-
} else {
|
|
1437
|
-
const fraction = position - lowerIndex;
|
|
1438
|
-
const interpolated = sorted[lowerIndex] + fraction * (sorted[upperIndex] - sorted[lowerIndex]);
|
|
1439
|
-
result.push(interpolated);
|
|
1396
|
+
const v = source[i];
|
|
1397
|
+
let k = 0;
|
|
1398
|
+
while (k < values2.length && !(values2[k] >= v)) k++;
|
|
1399
|
+
values2.splice(k, 0, v);
|
|
1400
|
+
bars.splice(k, 0, i);
|
|
1401
|
+
if (i >= length2) {
|
|
1402
|
+
const old = bars.indexOf(i - length2);
|
|
1403
|
+
values2.splice(old, 1);
|
|
1404
|
+
bars.splice(old, 1);
|
|
1440
1405
|
}
|
|
1406
|
+
result.push(i < length2 - 1 ? NaN : fn(values2));
|
|
1441
1407
|
}
|
|
1442
1408
|
return result;
|
|
1443
1409
|
}
|
|
1444
1410
|
function percentile_nearest_rank(source, length2, percentage) {
|
|
1445
|
-
const
|
|
1446
|
-
|
|
1447
|
-
if (i < length2 - 1) {
|
|
1448
|
-
result.push(NaN);
|
|
1449
|
-
continue;
|
|
1450
|
-
}
|
|
1451
|
-
const values2 = [];
|
|
1452
|
-
for (let j = 0; j < length2; j++) {
|
|
1453
|
-
const value = source[i - j];
|
|
1454
|
-
if (!isNaN(value)) {
|
|
1455
|
-
values2.push(value);
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
if (values2.length === 0) {
|
|
1459
|
-
result.push(NaN);
|
|
1460
|
-
continue;
|
|
1461
|
-
}
|
|
1462
|
-
const sorted = [...values2].sort((a, b2) => a - b2);
|
|
1463
|
-
if (percentage >= 100) {
|
|
1464
|
-
result.push(sorted[sorted.length - 1]);
|
|
1465
|
-
continue;
|
|
1466
|
-
}
|
|
1467
|
-
const rank2 = Math.ceil(percentage / 100 * sorted.length);
|
|
1468
|
-
const index = Math.max(0, rank2 - 1);
|
|
1469
|
-
result.push(sorted[index]);
|
|
1470
|
-
}
|
|
1471
|
-
return result;
|
|
1411
|
+
const rank2 = Math.min(length2, Math.max(1, Math.ceil(percentage / 100 * length2)));
|
|
1412
|
+
return sortedWindow(source, length2, (s) => s[rank2 - 1]);
|
|
1472
1413
|
}
|
|
1473
1414
|
function rci(source, length2) {
|
|
1474
1415
|
const result = [];
|
|
@@ -1963,38 +1904,6 @@ __export(math_exports, {
|
|
|
1963
1904
|
toradians: () => toradians
|
|
1964
1905
|
});
|
|
1965
1906
|
|
|
1966
|
-
// src/compare/index.ts
|
|
1967
|
-
var compare_exports = {};
|
|
1968
|
-
__export(compare_exports, {
|
|
1969
|
-
EPSILON: () => EPSILON,
|
|
1970
|
-
eq: () => eq,
|
|
1971
|
-
ge: () => ge,
|
|
1972
|
-
gt: () => gt,
|
|
1973
|
-
le: () => le,
|
|
1974
|
-
lt: () => lt,
|
|
1975
|
-
ne: () => ne
|
|
1976
|
-
});
|
|
1977
|
-
var EPSILON = 1e-10;
|
|
1978
|
-
var valid = (a, b2) => !Number.isNaN(a) && !Number.isNaN(b2);
|
|
1979
|
-
function eq(a, b2) {
|
|
1980
|
-
return valid(a, b2) && Math.abs(a - b2) <= EPSILON;
|
|
1981
|
-
}
|
|
1982
|
-
function ne(a, b2) {
|
|
1983
|
-
return valid(a, b2) && Math.abs(a - b2) > EPSILON;
|
|
1984
|
-
}
|
|
1985
|
-
function lt(a, b2) {
|
|
1986
|
-
return valid(a, b2) && b2 - a > EPSILON;
|
|
1987
|
-
}
|
|
1988
|
-
function le(a, b2) {
|
|
1989
|
-
return valid(a, b2) && a - b2 <= EPSILON;
|
|
1990
|
-
}
|
|
1991
|
-
function gt(a, b2) {
|
|
1992
|
-
return valid(a, b2) && a - b2 > EPSILON;
|
|
1993
|
-
}
|
|
1994
|
-
function ge(a, b2) {
|
|
1995
|
-
return valid(a, b2) && b2 - a <= EPSILON;
|
|
1996
|
-
}
|
|
1997
|
-
|
|
1998
1907
|
// src/runtime/series.ts
|
|
1999
1908
|
var BarData = class _BarData {
|
|
2000
1909
|
_bars;
|
|
@@ -2218,7 +2127,7 @@ var Series = class _Series {
|
|
|
2218
2127
|
return new _Series(this.dataSource, (bar, i, data) => {
|
|
2219
2128
|
const a = this.extractor(bar, i, data);
|
|
2220
2129
|
const b2 = typeof other === "number" ? other : other.extractor(bar, i, data);
|
|
2221
|
-
return
|
|
2130
|
+
return a / b2;
|
|
2222
2131
|
});
|
|
2223
2132
|
}
|
|
2224
2133
|
/**
|
|
@@ -3225,15 +3134,27 @@ function percentile_linear_interpolation2(id, percentage) {
|
|
|
3225
3134
|
if (id.length === 0) {
|
|
3226
3135
|
return NaN;
|
|
3227
3136
|
}
|
|
3228
|
-
const
|
|
3229
|
-
|
|
3137
|
+
const s = sortedNaLast(id);
|
|
3138
|
+
const n = s.length;
|
|
3139
|
+
const pos2 = percentage / 100 * n - 0.5;
|
|
3140
|
+
if (pos2 <= 0) return s[0];
|
|
3141
|
+
if (pos2 >= n - 1) return s[n - 1];
|
|
3142
|
+
const lo = Math.floor(pos2);
|
|
3143
|
+
const f = pos2 - lo;
|
|
3144
|
+
if (f === 0) return s[lo];
|
|
3145
|
+
return Number.isNaN(s[n - 1]) ? NaN : s[lo] + f * (s[lo + 1] - s[lo]);
|
|
3146
|
+
}
|
|
3147
|
+
function sortedNaLast(id) {
|
|
3148
|
+
const numbers = id.filter((v) => !Number.isNaN(v)).sort((a, b2) => a - b2);
|
|
3149
|
+
return [...numbers, ...Array(id.length - numbers.length).fill(NaN)];
|
|
3230
3150
|
}
|
|
3231
3151
|
function percentile_nearest_rank2(id, percentage) {
|
|
3232
3152
|
if (id.length === 0) {
|
|
3233
3153
|
return NaN;
|
|
3234
3154
|
}
|
|
3235
|
-
const
|
|
3236
|
-
|
|
3155
|
+
const s = sortedNaLast(id);
|
|
3156
|
+
const rank2 = Math.min(s.length, Math.max(1, Math.ceil(percentage / 100 * s.length)));
|
|
3157
|
+
return s[rank2 - 1];
|
|
3237
3158
|
}
|
|
3238
3159
|
function percentrank2(id, index) {
|
|
3239
3160
|
if (id.length === 0 || index < 0 || index >= id.length) {
|
|
@@ -3944,11 +3865,13 @@ __export(color_exports, {
|
|
|
3944
3865
|
white: () => white,
|
|
3945
3866
|
yellow: () => yellow
|
|
3946
3867
|
});
|
|
3868
|
+
var channel = (v) => v === null || v === void 0 || Number.isNaN(v) ? 0 : Math.max(0, Math.min(255, Math.trunc(v)));
|
|
3869
|
+
var alphaOf = (transp) => transp === null || Number.isNaN(transp) ? 0 : 1 - Math.max(0, Math.min(100, transp)) / 100;
|
|
3947
3870
|
function rgb(red2, green2, blue2, transp) {
|
|
3948
|
-
const r2 =
|
|
3949
|
-
const g2 =
|
|
3950
|
-
const b2 =
|
|
3951
|
-
const a = transp !== void 0 ?
|
|
3871
|
+
const r2 = channel(red2);
|
|
3872
|
+
const g2 = channel(green2);
|
|
3873
|
+
const b2 = channel(blue2);
|
|
3874
|
+
const a = transp !== void 0 ? alphaOf(transp) : 1;
|
|
3952
3875
|
if (a === 1) {
|
|
3953
3876
|
return `rgb(${r2}, ${g2}, ${b2})`;
|
|
3954
3877
|
}
|
|
@@ -3975,7 +3898,8 @@ function b(clr) {
|
|
|
3975
3898
|
return parseColor(clr).b;
|
|
3976
3899
|
}
|
|
3977
3900
|
function t(clr) {
|
|
3978
|
-
|
|
3901
|
+
const alpha = Math.round((1 - parseColor(clr).t / 100) * 255);
|
|
3902
|
+
return Math.round((1 - alpha / 255) * 100);
|
|
3979
3903
|
}
|
|
3980
3904
|
function parseColor(clr) {
|
|
3981
3905
|
if (typeof clr === "string") {
|
|
@@ -4028,13 +3952,12 @@ function from_gradient(value, bottom_value, top_value, bottom_color, top_color)
|
|
|
4028
3952
|
};
|
|
4029
3953
|
const c1 = rgba(bottom_color);
|
|
4030
3954
|
const c2 = rgba(top_color);
|
|
4031
|
-
const
|
|
4032
|
-
const w2 = c2.a * k;
|
|
4033
|
-
const a = w1 + w2;
|
|
3955
|
+
const a = c1.a * (1 - k) + c2.a * k;
|
|
4034
3956
|
if (a === 0) return transparent;
|
|
4035
|
-
const mix = (x1, x2) => Math.floor((x1 *
|
|
3957
|
+
const mix = (x1, x2) => Math.floor((x1 / 255 * c1.a * (1 - k) + x2 / 255 * c2.a * k) / (a / 255));
|
|
4036
3958
|
const [r2, g2, b2] = [mix(c1.r, c2.r), mix(c1.g, c2.g), mix(c1.b, c2.b)];
|
|
4037
|
-
|
|
3959
|
+
const alpha = Math.floor(a);
|
|
3960
|
+
return alpha === 255 ? `rgb(${r2}, ${g2}, ${b2})` : `rgba(${r2}, ${g2}, ${b2}, ${alpha / 255})`;
|
|
4038
3961
|
}
|
|
4039
3962
|
|
|
4040
3963
|
// src/time/index.ts
|
|
@@ -6242,13 +6165,60 @@ var format_none = 0;
|
|
|
6242
6165
|
var format_bold = 1;
|
|
6243
6166
|
var format_italic = 2;
|
|
6244
6167
|
|
|
6168
|
+
// src/callsite/index.ts
|
|
6169
|
+
var callsite_exports = {};
|
|
6170
|
+
__export(callsite_exports, {
|
|
6171
|
+
barssince: () => barssince2,
|
|
6172
|
+
cross: () => cross2,
|
|
6173
|
+
crossover: () => crossover2,
|
|
6174
|
+
crossunder: () => crossunder2,
|
|
6175
|
+
whenCalled: () => whenCalled
|
|
6176
|
+
});
|
|
6177
|
+
function whenCalled(called, fn, ...sources) {
|
|
6178
|
+
const bars = [];
|
|
6179
|
+
for (let i = 0; i < called.length; i++) if (called[i]) bars.push(i);
|
|
6180
|
+
const result = fn(...sources.map((s) => bars.map((i) => s[i] ?? NaN)));
|
|
6181
|
+
const out = new Array(called.length).fill(NaN);
|
|
6182
|
+
bars.forEach((bar, k) => {
|
|
6183
|
+
out[bar] = result[k];
|
|
6184
|
+
});
|
|
6185
|
+
return out;
|
|
6186
|
+
}
|
|
6187
|
+
function twoSeriesSite(test) {
|
|
6188
|
+
let prevA = NaN;
|
|
6189
|
+
let prevB = NaN;
|
|
6190
|
+
return (a, b2) => {
|
|
6191
|
+
const result = test(a, b2, prevA, prevB);
|
|
6192
|
+
prevA = a;
|
|
6193
|
+
prevB = b2;
|
|
6194
|
+
return result;
|
|
6195
|
+
};
|
|
6196
|
+
}
|
|
6197
|
+
function crossover2() {
|
|
6198
|
+
return twoSeriesSite((a, b2, pa, pb) => a > b2 && pa <= pb);
|
|
6199
|
+
}
|
|
6200
|
+
function crossunder2() {
|
|
6201
|
+
return twoSeriesSite((a, b2, pa, pb) => a < b2 && pa >= pb);
|
|
6202
|
+
}
|
|
6203
|
+
function barssince2() {
|
|
6204
|
+
let count = NaN;
|
|
6205
|
+
return (condition) => {
|
|
6206
|
+
if (condition && !Number.isNaN(condition)) count = 0;
|
|
6207
|
+
else if (!Number.isNaN(count)) count++;
|
|
6208
|
+
return count;
|
|
6209
|
+
};
|
|
6210
|
+
}
|
|
6211
|
+
function cross2() {
|
|
6212
|
+
return twoSeriesSite((a, b2, pa, pb) => a > b2 && pa <= pb || a < b2 && pa >= pb);
|
|
6213
|
+
}
|
|
6214
|
+
|
|
6245
6215
|
// src/ta-series.ts
|
|
6246
6216
|
var ta_series_exports = {};
|
|
6247
6217
|
__export(ta_series_exports, {
|
|
6248
6218
|
accdist: () => accdist2,
|
|
6249
6219
|
alma: () => alma2,
|
|
6250
6220
|
atr: () => atr2,
|
|
6251
|
-
barssince: () =>
|
|
6221
|
+
barssince: () => barssince3,
|
|
6252
6222
|
bb: () => bb2,
|
|
6253
6223
|
bbw: () => bbw2,
|
|
6254
6224
|
cci: () => cci2,
|
|
@@ -6256,9 +6226,9 @@ __export(ta_series_exports, {
|
|
|
6256
6226
|
cmo: () => cmo2,
|
|
6257
6227
|
cog: () => cog2,
|
|
6258
6228
|
correlation: () => correlation2,
|
|
6259
|
-
cross: () =>
|
|
6260
|
-
crossover: () =>
|
|
6261
|
-
crossunder: () =>
|
|
6229
|
+
cross: () => cross3,
|
|
6230
|
+
crossover: () => crossover3,
|
|
6231
|
+
crossunder: () => crossunder3,
|
|
6262
6232
|
cum: () => cum2,
|
|
6263
6233
|
dev: () => dev2,
|
|
6264
6234
|
dmi: () => dmi2,
|
|
@@ -6424,7 +6394,7 @@ function stoch2(source, high, low, length2) {
|
|
|
6424
6394
|
const result = stoch(sourceValues, highValues, lowValues, length2);
|
|
6425
6395
|
return Series.fromArray(bars, result);
|
|
6426
6396
|
}
|
|
6427
|
-
function
|
|
6397
|
+
function crossover3(source1, source2) {
|
|
6428
6398
|
const bars = source1.bars;
|
|
6429
6399
|
const vals1 = source1.toArray();
|
|
6430
6400
|
const vals2 = typeof source2 === "number" ? Array(bars.length).fill(source2) : source2.toArray();
|
|
@@ -6432,7 +6402,7 @@ function crossover2(source1, source2) {
|
|
|
6432
6402
|
const numResult = result.map((b2) => b2 ? 1 : 0);
|
|
6433
6403
|
return Series.fromArray(bars, numResult);
|
|
6434
6404
|
}
|
|
6435
|
-
function
|
|
6405
|
+
function crossunder3(source1, source2) {
|
|
6436
6406
|
const bars = source1.bars;
|
|
6437
6407
|
const vals1 = source1.toArray();
|
|
6438
6408
|
const vals2 = typeof source2 === "number" ? Array(bars.length).fill(source2) : source2.toArray();
|
|
@@ -6440,7 +6410,7 @@ function crossunder2(source1, source2) {
|
|
|
6440
6410
|
const numResult = result.map((b2) => b2 ? 1 : 0);
|
|
6441
6411
|
return Series.fromArray(bars, numResult);
|
|
6442
6412
|
}
|
|
6443
|
-
function
|
|
6413
|
+
function cross3(source1, source2) {
|
|
6444
6414
|
const bars = source1.bars;
|
|
6445
6415
|
const vals1 = source1.toArray();
|
|
6446
6416
|
const vals2 = typeof source2 === "number" ? Array(bars.length).fill(source2) : source2.toArray();
|
|
@@ -6636,7 +6606,7 @@ function pivotlow2(source, leftbars, rightbars) {
|
|
|
6636
6606
|
const result = pivotlow(source.toArray(), leftbars, rightbars);
|
|
6637
6607
|
return Series.fromArray(bars, result);
|
|
6638
6608
|
}
|
|
6639
|
-
function
|
|
6609
|
+
function barssince3(condition) {
|
|
6640
6610
|
const bars = condition.bars;
|
|
6641
6611
|
const boolValues = condition.toArray().map((v) => v === 1);
|
|
6642
6612
|
const result = barssince(boolValues);
|
|
@@ -6759,9 +6729,9 @@ var ta = {
|
|
|
6759
6729
|
atr: atr2,
|
|
6760
6730
|
tr: tr2,
|
|
6761
6731
|
stoch: stoch2,
|
|
6762
|
-
crossover:
|
|
6763
|
-
crossunder:
|
|
6764
|
-
cross:
|
|
6732
|
+
crossover: crossover3,
|
|
6733
|
+
crossunder: crossunder3,
|
|
6734
|
+
cross: cross3,
|
|
6765
6735
|
change: change2,
|
|
6766
6736
|
mom: mom2,
|
|
6767
6737
|
roc: roc2,
|
|
@@ -6788,7 +6758,7 @@ var ta = {
|
|
|
6788
6758
|
hma: hma2,
|
|
6789
6759
|
pivothigh: pivothigh2,
|
|
6790
6760
|
pivotlow: pivotlow2,
|
|
6791
|
-
barssince:
|
|
6761
|
+
barssince: barssince3,
|
|
6792
6762
|
valuewhen: valuewhen2,
|
|
6793
6763
|
dmi: dmi2,
|
|
6794
6764
|
tsi: tsi2,
|
|
@@ -6820,7 +6790,7 @@ var ta = {
|
|
|
6820
6790
|
|
|
6821
6791
|
// src/utils/index.ts
|
|
6822
6792
|
function isNA(value) {
|
|
6823
|
-
return value === null || value === void 0 || Number.isNaN(value) || isDeleted(value);
|
|
6793
|
+
return value === null || value === void 0 || Number.isNaN(value) || value === Infinity || value === -Infinity || isDeleted(value);
|
|
6824
6794
|
}
|
|
6825
6795
|
function nz(value, defaultValue = 0) {
|
|
6826
6796
|
return isNA(value) ? defaultValue : value;
|
|
@@ -6829,7 +6799,7 @@ function fixnan(source) {
|
|
|
6829
6799
|
let last2;
|
|
6830
6800
|
let seen = false;
|
|
6831
6801
|
return source.map((v) => {
|
|
6832
|
-
if (!
|
|
6802
|
+
if (!(v === null || v === void 0 || Number.isNaN(v) || isDeleted(v))) {
|
|
6833
6803
|
last2 = v;
|
|
6834
6804
|
seen = true;
|
|
6835
6805
|
return v;
|
|
@@ -6837,6 +6807,16 @@ function fixnan(source) {
|
|
|
6837
6807
|
return seen ? last2 : v;
|
|
6838
6808
|
});
|
|
6839
6809
|
}
|
|
6810
|
+
function at(source, i, offset = 0) {
|
|
6811
|
+
if (offset < 0) {
|
|
6812
|
+
throw new RangeError(`at(): the offset must be >= 0 (got ${offset}); a negative offset reads a later bar.`);
|
|
6813
|
+
}
|
|
6814
|
+
const j = i - offset;
|
|
6815
|
+
return j >= 0 && j < source.length ? source[j] ?? NaN : NaN;
|
|
6816
|
+
}
|
|
6817
|
+
function div(a, b2) {
|
|
6818
|
+
return a / b2;
|
|
6819
|
+
}
|
|
6840
6820
|
function ohlcFromBars(bars) {
|
|
6841
6821
|
return {
|
|
6842
6822
|
open: bars.map((b2) => b2.open),
|
|
@@ -6857,6 +6837,50 @@ function getLow(ohlc) {
|
|
|
6857
6837
|
function getOpen(ohlc) {
|
|
6858
6838
|
return ohlc.open;
|
|
6859
6839
|
}
|
|
6840
|
+
function getSource(data, source = "close") {
|
|
6841
|
+
const isOHLC = "open" in data && Array.isArray(data.open);
|
|
6842
|
+
if (isOHLC) {
|
|
6843
|
+
const ohlc = data;
|
|
6844
|
+
switch (source) {
|
|
6845
|
+
case "close":
|
|
6846
|
+
return ohlc.close;
|
|
6847
|
+
case "open":
|
|
6848
|
+
return ohlc.open;
|
|
6849
|
+
case "high":
|
|
6850
|
+
return ohlc.high;
|
|
6851
|
+
case "low":
|
|
6852
|
+
return ohlc.low;
|
|
6853
|
+
case "hl2":
|
|
6854
|
+
return ohlc.high.map((h, i) => (h + ohlc.low[i]) / 2);
|
|
6855
|
+
case "hlc3":
|
|
6856
|
+
return ohlc.high.map((h, i) => (h + ohlc.low[i] + ohlc.close[i]) / 3);
|
|
6857
|
+
case "ohlc4":
|
|
6858
|
+
return ohlc.open.map((o, i) => (o + ohlc.high[i] + ohlc.low[i] + ohlc.close[i]) / 4);
|
|
6859
|
+
case "hlcc4":
|
|
6860
|
+
return ohlc.high.map((h, i) => (h + ohlc.low[i] + ohlc.close[i] + ohlc.close[i]) / 4);
|
|
6861
|
+
}
|
|
6862
|
+
} else {
|
|
6863
|
+
const bars = data;
|
|
6864
|
+
switch (source) {
|
|
6865
|
+
case "close":
|
|
6866
|
+
return bars.map((b2) => b2.close);
|
|
6867
|
+
case "open":
|
|
6868
|
+
return bars.map((b2) => b2.open);
|
|
6869
|
+
case "high":
|
|
6870
|
+
return bars.map((b2) => b2.high);
|
|
6871
|
+
case "low":
|
|
6872
|
+
return bars.map((b2) => b2.low);
|
|
6873
|
+
case "hl2":
|
|
6874
|
+
return bars.map((b2) => (b2.high + b2.low) / 2);
|
|
6875
|
+
case "hlc3":
|
|
6876
|
+
return bars.map((b2) => (b2.high + b2.low + b2.close) / 3);
|
|
6877
|
+
case "ohlc4":
|
|
6878
|
+
return bars.map((b2) => (b2.open + b2.high + b2.low + b2.close) / 4);
|
|
6879
|
+
case "hlcc4":
|
|
6880
|
+
return bars.map((b2) => (b2.high + b2.low + b2.close + b2.close) / 4);
|
|
6881
|
+
}
|
|
6882
|
+
}
|
|
6883
|
+
}
|
|
6860
6884
|
function getSourceSeries(bars, source = "close") {
|
|
6861
6885
|
const open = new Series(bars, (bar) => bar.open);
|
|
6862
6886
|
const high = new Series(bars, (bar) => bar.high);
|
|
@@ -7425,7 +7449,7 @@ function hline(price, title, color, linestyle, linewidth) {
|
|
|
7425
7449
|
const options = {
|
|
7426
7450
|
color,
|
|
7427
7451
|
lineWidth: linewidth,
|
|
7428
|
-
lineStyle: getLineStyle(linestyle)
|
|
7452
|
+
lineStyle: getLineStyle(linestyle ?? "dashed")
|
|
7429
7453
|
};
|
|
7430
7454
|
const seriesHandle = context.chart.addSeries("line", options);
|
|
7431
7455
|
const data = context.ohlcv.time.map((time) => ({
|
|
@@ -7656,6 +7680,73 @@ function getSourceData(ohlcv, sourceName) {
|
|
|
7656
7680
|
}
|
|
7657
7681
|
}
|
|
7658
7682
|
|
|
7683
|
+
// src/strategy/index.ts
|
|
7684
|
+
var STRATEGY_CONSTANTS = {
|
|
7685
|
+
long: "long",
|
|
7686
|
+
short: "short",
|
|
7687
|
+
fixed: "fixed",
|
|
7688
|
+
cash: "cash",
|
|
7689
|
+
percent_of_equity: "percent_of_equity",
|
|
7690
|
+
commission: { percent: "percent", cash_per_contract: "cash_per_contract", cash_per_order: "cash_per_order" },
|
|
7691
|
+
direction: { all: "all", long: "long", short: "short" },
|
|
7692
|
+
oca: { none: "none", cancel: "cancel", reduce: "reduce" }
|
|
7693
|
+
};
|
|
7694
|
+
var STRATEGY_DEFAULTS = {
|
|
7695
|
+
pyramiding: 0,
|
|
7696
|
+
calc_on_order_fills: false,
|
|
7697
|
+
calc_on_every_tick: false,
|
|
7698
|
+
backtest_fill_limits_assumption: 0,
|
|
7699
|
+
// v6 values; PineScript v5: fixed / 1 / 1000000 and margins 0
|
|
7700
|
+
default_qty_type: "percent_of_equity",
|
|
7701
|
+
default_qty_value: 100,
|
|
7702
|
+
initial_capital: 1e5,
|
|
7703
|
+
slippage: 0,
|
|
7704
|
+
commission_type: "percent",
|
|
7705
|
+
commission_value: 0,
|
|
7706
|
+
process_orders_on_close: false,
|
|
7707
|
+
close_entries_rule: "FIFO",
|
|
7708
|
+
margin_long: 100,
|
|
7709
|
+
margin_short: 100,
|
|
7710
|
+
calc_bars_count: 0,
|
|
7711
|
+
risk_free_rate: 2,
|
|
7712
|
+
use_bar_magnifier: false,
|
|
7713
|
+
fill_orders_on_standard_ohlc: false
|
|
7714
|
+
};
|
|
7715
|
+
var STRATEGY_NUMBER_VARIABLES = [
|
|
7716
|
+
"position_size",
|
|
7717
|
+
"position_avg_price",
|
|
7718
|
+
"equity",
|
|
7719
|
+
"initial_capital",
|
|
7720
|
+
"netprofit",
|
|
7721
|
+
"netprofit_percent",
|
|
7722
|
+
"openprofit",
|
|
7723
|
+
"openprofit_percent",
|
|
7724
|
+
"grossprofit",
|
|
7725
|
+
"grossprofit_percent",
|
|
7726
|
+
"grossloss",
|
|
7727
|
+
"grossloss_percent",
|
|
7728
|
+
"opentrades",
|
|
7729
|
+
"closedtrades",
|
|
7730
|
+
"wintrades",
|
|
7731
|
+
"losstrades",
|
|
7732
|
+
"eventrades",
|
|
7733
|
+
"avg_trade",
|
|
7734
|
+
"avg_trade_percent",
|
|
7735
|
+
"avg_winning_trade",
|
|
7736
|
+
"avg_winning_trade_percent",
|
|
7737
|
+
"avg_losing_trade",
|
|
7738
|
+
"avg_losing_trade_percent",
|
|
7739
|
+
"max_drawdown",
|
|
7740
|
+
"max_drawdown_percent",
|
|
7741
|
+
"max_runup",
|
|
7742
|
+
"max_runup_percent",
|
|
7743
|
+
"max_contracts_held_all",
|
|
7744
|
+
"max_contracts_held_long",
|
|
7745
|
+
"max_contracts_held_short",
|
|
7746
|
+
"margin_liquidation_price"
|
|
7747
|
+
];
|
|
7748
|
+
var STRATEGY_TEXT_VARIABLES = ["position_entry_name", "account_currency"];
|
|
7749
|
+
|
|
7659
7750
|
// src/runtime/adapters/LightweightChartsAdapter.ts
|
|
7660
7751
|
var LightweightChartsAdapter = class {
|
|
7661
7752
|
chart;
|
|
@@ -7864,7 +7955,7 @@ var SimpleInputAdapter = class {
|
|
|
7864
7955
|
};
|
|
7865
7956
|
|
|
7866
7957
|
// src/index.ts
|
|
7867
|
-
var VERSION = "0.
|
|
7958
|
+
var VERSION = "0.8.1";
|
|
7868
7959
|
var info2 = {
|
|
7869
7960
|
name: "OakScriptJS",
|
|
7870
7961
|
version: VERSION,
|