backtest-kit 9.8.4 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -1
- package/build/index.cjs +669 -177
- package/build/index.mjs +666 -178
- package/package.json +1 -1
- package/types.d.ts +481 -1
package/build/index.mjs
CHANGED
|
@@ -942,7 +942,7 @@ async function writeFileAtomic(file, data, options = {}) {
|
|
|
942
942
|
|
|
943
943
|
var _a$3;
|
|
944
944
|
/** Logger service injected as DI singleton */
|
|
945
|
-
const LOGGER_SERVICE$
|
|
945
|
+
const LOGGER_SERVICE$9 = new LoggerService();
|
|
946
946
|
/** Symbol key for the singleshot waitForInit function on PersistBase instances. */
|
|
947
947
|
const BASE_WAIT_FOR_INIT_SYMBOL = Symbol("wait-for-init");
|
|
948
948
|
// Calculate step in milliseconds for candle close time validation
|
|
@@ -1065,7 +1065,7 @@ const BASE_WAIT_FOR_INIT_FN_METHOD_NAME = "PersistBase.waitForInitFn";
|
|
|
1065
1065
|
const BASE_UNLINK_RETRY_COUNT = 5;
|
|
1066
1066
|
const BASE_UNLINK_RETRY_DELAY = 1000;
|
|
1067
1067
|
const BASE_WAIT_FOR_INIT_FN = async (self) => {
|
|
1068
|
-
LOGGER_SERVICE$
|
|
1068
|
+
LOGGER_SERVICE$9.debug(BASE_WAIT_FOR_INIT_FN_METHOD_NAME, {
|
|
1069
1069
|
entityName: self.entityName,
|
|
1070
1070
|
directory: self._directory,
|
|
1071
1071
|
});
|
|
@@ -1123,7 +1123,7 @@ class PersistBase {
|
|
|
1123
1123
|
this.entityName = entityName;
|
|
1124
1124
|
this.baseDir = baseDir;
|
|
1125
1125
|
this[_a$3] = singleshot(async () => await BASE_WAIT_FOR_INIT_FN(this));
|
|
1126
|
-
LOGGER_SERVICE$
|
|
1126
|
+
LOGGER_SERVICE$9.debug(PERSIST_BASE_METHOD_NAME_CTOR, {
|
|
1127
1127
|
entityName: this.entityName,
|
|
1128
1128
|
baseDir,
|
|
1129
1129
|
});
|
|
@@ -1139,14 +1139,14 @@ class PersistBase {
|
|
|
1139
1139
|
return join(this.baseDir, this.entityName, `${entityId}.json`);
|
|
1140
1140
|
}
|
|
1141
1141
|
async waitForInit(initial) {
|
|
1142
|
-
LOGGER_SERVICE$
|
|
1142
|
+
LOGGER_SERVICE$9.debug(PERSIST_BASE_METHOD_NAME_WAIT_FOR_INIT, {
|
|
1143
1143
|
entityName: this.entityName,
|
|
1144
1144
|
initial,
|
|
1145
1145
|
});
|
|
1146
1146
|
await this[BASE_WAIT_FOR_INIT_SYMBOL]();
|
|
1147
1147
|
}
|
|
1148
1148
|
async readValue(entityId) {
|
|
1149
|
-
LOGGER_SERVICE$
|
|
1149
|
+
LOGGER_SERVICE$9.debug(PERSIST_BASE_METHOD_NAME_READ_VALUE, {
|
|
1150
1150
|
entityName: this.entityName,
|
|
1151
1151
|
entityId,
|
|
1152
1152
|
});
|
|
@@ -1163,7 +1163,7 @@ class PersistBase {
|
|
|
1163
1163
|
}
|
|
1164
1164
|
}
|
|
1165
1165
|
async hasValue(entityId) {
|
|
1166
|
-
LOGGER_SERVICE$
|
|
1166
|
+
LOGGER_SERVICE$9.debug(PERSIST_BASE_METHOD_NAME_HAS_VALUE, {
|
|
1167
1167
|
entityName: this.entityName,
|
|
1168
1168
|
entityId,
|
|
1169
1169
|
});
|
|
@@ -1180,7 +1180,7 @@ class PersistBase {
|
|
|
1180
1180
|
}
|
|
1181
1181
|
}
|
|
1182
1182
|
async writeValue(entityId, entity) {
|
|
1183
|
-
LOGGER_SERVICE$
|
|
1183
|
+
LOGGER_SERVICE$9.debug(PERSIST_BASE_METHOD_NAME_WRITE_VALUE, {
|
|
1184
1184
|
entityName: this.entityName,
|
|
1185
1185
|
entityId,
|
|
1186
1186
|
});
|
|
@@ -1202,7 +1202,7 @@ class PersistBase {
|
|
|
1202
1202
|
* @throws Error if reading fails
|
|
1203
1203
|
*/
|
|
1204
1204
|
async *keys() {
|
|
1205
|
-
LOGGER_SERVICE$
|
|
1205
|
+
LOGGER_SERVICE$9.debug(PERSIST_BASE_METHOD_NAME_KEYS, {
|
|
1206
1206
|
entityName: this.entityName,
|
|
1207
1207
|
});
|
|
1208
1208
|
try {
|
|
@@ -1347,7 +1347,7 @@ class PersistSignalUtils {
|
|
|
1347
1347
|
* @returns Promise resolving to signal or null if none persisted
|
|
1348
1348
|
*/
|
|
1349
1349
|
this.readSignalData = async (symbol, strategyName, exchangeName) => {
|
|
1350
|
-
LOGGER_SERVICE$
|
|
1350
|
+
LOGGER_SERVICE$9.info(PERSIST_SIGNAL_UTILS_METHOD_NAME_READ_DATA);
|
|
1351
1351
|
const key = `${symbol}:${strategyName}:${exchangeName}`;
|
|
1352
1352
|
const isInitial = !this.getStorage.has(key);
|
|
1353
1353
|
const instance = this.getStorage(symbol, strategyName, exchangeName);
|
|
@@ -1365,7 +1365,7 @@ class PersistSignalUtils {
|
|
|
1365
1365
|
* @returns Promise that resolves when write is complete
|
|
1366
1366
|
*/
|
|
1367
1367
|
this.writeSignalData = async (signalRow, symbol, strategyName, exchangeName) => {
|
|
1368
|
-
LOGGER_SERVICE$
|
|
1368
|
+
LOGGER_SERVICE$9.info(PERSIST_SIGNAL_UTILS_METHOD_NAME_WRITE_DATA);
|
|
1369
1369
|
const key = `${symbol}:${strategyName}:${exchangeName}`;
|
|
1370
1370
|
const isInitial = !this.getStorage.has(key);
|
|
1371
1371
|
const instance = this.getStorage(symbol, strategyName, exchangeName);
|
|
@@ -1380,7 +1380,7 @@ class PersistSignalUtils {
|
|
|
1380
1380
|
* @param Ctor - Custom IPersistSignalInstance constructor
|
|
1381
1381
|
*/
|
|
1382
1382
|
usePersistSignalAdapter(Ctor) {
|
|
1383
|
-
LOGGER_SERVICE$
|
|
1383
|
+
LOGGER_SERVICE$9.info(PERSIST_SIGNAL_UTILS_METHOD_NAME_USE_PERSIST_SIGNAL_ADAPTER);
|
|
1384
1384
|
this.PersistSignalInstanceCtor = Ctor;
|
|
1385
1385
|
this.getStorage.clear();
|
|
1386
1386
|
}
|
|
@@ -1389,21 +1389,21 @@ class PersistSignalUtils {
|
|
|
1389
1389
|
* Call when process.cwd() changes between strategy iterations.
|
|
1390
1390
|
*/
|
|
1391
1391
|
clear() {
|
|
1392
|
-
LOGGER_SERVICE$
|
|
1392
|
+
LOGGER_SERVICE$9.log(PERSIST_SIGNAL_UTILS_METHOD_NAME_CLEAR);
|
|
1393
1393
|
this.getStorage.clear();
|
|
1394
1394
|
}
|
|
1395
1395
|
/**
|
|
1396
1396
|
* Switches to the default file-based PersistSignalInstance.
|
|
1397
1397
|
*/
|
|
1398
1398
|
useJson() {
|
|
1399
|
-
LOGGER_SERVICE$
|
|
1399
|
+
LOGGER_SERVICE$9.log(PERSIST_SIGNAL_UTILS_METHOD_NAME_USE_JSON);
|
|
1400
1400
|
this.usePersistSignalAdapter(PersistSignalInstance);
|
|
1401
1401
|
}
|
|
1402
1402
|
/**
|
|
1403
1403
|
* Switches to PersistSignalDummyInstance (all operations are no-ops).
|
|
1404
1404
|
*/
|
|
1405
1405
|
useDummy() {
|
|
1406
|
-
LOGGER_SERVICE$
|
|
1406
|
+
LOGGER_SERVICE$9.log(PERSIST_SIGNAL_UTILS_METHOD_NAME_USE_DUMMY);
|
|
1407
1407
|
this.usePersistSignalAdapter(PersistSignalDummyInstance);
|
|
1408
1408
|
}
|
|
1409
1409
|
}
|
|
@@ -1543,7 +1543,7 @@ class PersistRiskUtils {
|
|
|
1543
1543
|
* @returns Promise resolving to position entries (empty array if none)
|
|
1544
1544
|
*/
|
|
1545
1545
|
this.readPositionData = async (riskName, exchangeName, when) => {
|
|
1546
|
-
LOGGER_SERVICE$
|
|
1546
|
+
LOGGER_SERVICE$9.info(PERSIST_RISK_UTILS_METHOD_NAME_READ_DATA);
|
|
1547
1547
|
const key = `${riskName}:${exchangeName}`;
|
|
1548
1548
|
const isInitial = !this.getRiskStorage.has(key);
|
|
1549
1549
|
const instance = this.getRiskStorage(riskName, exchangeName);
|
|
@@ -1561,7 +1561,7 @@ class PersistRiskUtils {
|
|
|
1561
1561
|
* @returns Promise that resolves when write is complete
|
|
1562
1562
|
*/
|
|
1563
1563
|
this.writePositionData = async (riskRow, riskName, exchangeName, when) => {
|
|
1564
|
-
LOGGER_SERVICE$
|
|
1564
|
+
LOGGER_SERVICE$9.info(PERSIST_RISK_UTILS_METHOD_NAME_WRITE_DATA);
|
|
1565
1565
|
const key = `${riskName}:${exchangeName}`;
|
|
1566
1566
|
const isInitial = !this.getRiskStorage.has(key);
|
|
1567
1567
|
const instance = this.getRiskStorage(riskName, exchangeName);
|
|
@@ -1576,7 +1576,7 @@ class PersistRiskUtils {
|
|
|
1576
1576
|
* @param Ctor - Custom IPersistRiskInstance constructor
|
|
1577
1577
|
*/
|
|
1578
1578
|
usePersistRiskAdapter(Ctor) {
|
|
1579
|
-
LOGGER_SERVICE$
|
|
1579
|
+
LOGGER_SERVICE$9.info(PERSIST_RISK_UTILS_METHOD_NAME_USE_PERSIST_RISK_ADAPTER);
|
|
1580
1580
|
this.PersistRiskInstanceCtor = Ctor;
|
|
1581
1581
|
this.getRiskStorage.clear();
|
|
1582
1582
|
}
|
|
@@ -1585,21 +1585,21 @@ class PersistRiskUtils {
|
|
|
1585
1585
|
* Call when process.cwd() changes between strategy iterations.
|
|
1586
1586
|
*/
|
|
1587
1587
|
clear() {
|
|
1588
|
-
LOGGER_SERVICE$
|
|
1588
|
+
LOGGER_SERVICE$9.log(PERSIST_RISK_UTILS_METHOD_NAME_CLEAR);
|
|
1589
1589
|
this.getRiskStorage.clear();
|
|
1590
1590
|
}
|
|
1591
1591
|
/**
|
|
1592
1592
|
* Switches to the default file-based PersistRiskInstance.
|
|
1593
1593
|
*/
|
|
1594
1594
|
useJson() {
|
|
1595
|
-
LOGGER_SERVICE$
|
|
1595
|
+
LOGGER_SERVICE$9.log(PERSIST_RISK_UTILS_METHOD_NAME_USE_JSON);
|
|
1596
1596
|
this.usePersistRiskAdapter(PersistRiskInstance);
|
|
1597
1597
|
}
|
|
1598
1598
|
/**
|
|
1599
1599
|
* Switches to PersistRiskDummyInstance (all operations are no-ops).
|
|
1600
1600
|
*/
|
|
1601
1601
|
useDummy() {
|
|
1602
|
-
LOGGER_SERVICE$
|
|
1602
|
+
LOGGER_SERVICE$9.log(PERSIST_RISK_UTILS_METHOD_NAME_USE_DUMMY);
|
|
1603
1603
|
this.usePersistRiskAdapter(PersistRiskDummyInstance);
|
|
1604
1604
|
}
|
|
1605
1605
|
}
|
|
@@ -1738,7 +1738,7 @@ class PersistScheduleUtils {
|
|
|
1738
1738
|
* @returns Promise resolving to scheduled signal or null if none persisted
|
|
1739
1739
|
*/
|
|
1740
1740
|
this.readScheduleData = async (symbol, strategyName, exchangeName) => {
|
|
1741
|
-
LOGGER_SERVICE$
|
|
1741
|
+
LOGGER_SERVICE$9.info(PERSIST_SCHEDULE_UTILS_METHOD_NAME_READ_DATA);
|
|
1742
1742
|
const key = `${symbol}:${strategyName}:${exchangeName}`;
|
|
1743
1743
|
const isInitial = !this.getScheduleStorage.has(key);
|
|
1744
1744
|
const instance = this.getScheduleStorage(symbol, strategyName, exchangeName);
|
|
@@ -1756,7 +1756,7 @@ class PersistScheduleUtils {
|
|
|
1756
1756
|
* @returns Promise that resolves when write is complete
|
|
1757
1757
|
*/
|
|
1758
1758
|
this.writeScheduleData = async (scheduledSignalRow, symbol, strategyName, exchangeName) => {
|
|
1759
|
-
LOGGER_SERVICE$
|
|
1759
|
+
LOGGER_SERVICE$9.info(PERSIST_SCHEDULE_UTILS_METHOD_NAME_WRITE_DATA);
|
|
1760
1760
|
const key = `${symbol}:${strategyName}:${exchangeName}`;
|
|
1761
1761
|
const isInitial = !this.getScheduleStorage.has(key);
|
|
1762
1762
|
const instance = this.getScheduleStorage(symbol, strategyName, exchangeName);
|
|
@@ -1771,7 +1771,7 @@ class PersistScheduleUtils {
|
|
|
1771
1771
|
* @param Ctor - Custom IPersistScheduleInstance constructor
|
|
1772
1772
|
*/
|
|
1773
1773
|
usePersistScheduleAdapter(Ctor) {
|
|
1774
|
-
LOGGER_SERVICE$
|
|
1774
|
+
LOGGER_SERVICE$9.info(PERSIST_SCHEDULE_UTILS_METHOD_NAME_USE_PERSIST_SCHEDULE_ADAPTER);
|
|
1775
1775
|
this.PersistScheduleInstanceCtor = Ctor;
|
|
1776
1776
|
this.getScheduleStorage.clear();
|
|
1777
1777
|
}
|
|
@@ -1780,21 +1780,21 @@ class PersistScheduleUtils {
|
|
|
1780
1780
|
* Call when process.cwd() changes between strategy iterations.
|
|
1781
1781
|
*/
|
|
1782
1782
|
clear() {
|
|
1783
|
-
LOGGER_SERVICE$
|
|
1783
|
+
LOGGER_SERVICE$9.log(PERSIST_SCHEDULE_UTILS_METHOD_NAME_CLEAR);
|
|
1784
1784
|
this.getScheduleStorage.clear();
|
|
1785
1785
|
}
|
|
1786
1786
|
/**
|
|
1787
1787
|
* Switches to the default file-based PersistScheduleInstance.
|
|
1788
1788
|
*/
|
|
1789
1789
|
useJson() {
|
|
1790
|
-
LOGGER_SERVICE$
|
|
1790
|
+
LOGGER_SERVICE$9.log(PERSIST_SCHEDULE_UTILS_METHOD_NAME_USE_JSON);
|
|
1791
1791
|
this.usePersistScheduleAdapter(PersistScheduleInstance);
|
|
1792
1792
|
}
|
|
1793
1793
|
/**
|
|
1794
1794
|
* Switches to PersistScheduleDummyInstance (all operations are no-ops).
|
|
1795
1795
|
*/
|
|
1796
1796
|
useDummy() {
|
|
1797
|
-
LOGGER_SERVICE$
|
|
1797
|
+
LOGGER_SERVICE$9.log(PERSIST_SCHEDULE_UTILS_METHOD_NAME_USE_DUMMY);
|
|
1798
1798
|
this.usePersistScheduleAdapter(PersistScheduleDummyInstance);
|
|
1799
1799
|
}
|
|
1800
1800
|
}
|
|
@@ -1939,7 +1939,7 @@ class PersistPartialUtils {
|
|
|
1939
1939
|
* @returns Promise resolving to partial data record (empty object if none)
|
|
1940
1940
|
*/
|
|
1941
1941
|
this.readPartialData = async (symbol, strategyName, signalId, exchangeName, when) => {
|
|
1942
|
-
LOGGER_SERVICE$
|
|
1942
|
+
LOGGER_SERVICE$9.info(PERSIST_PARTIAL_UTILS_METHOD_NAME_READ_DATA);
|
|
1943
1943
|
const key = `${symbol}:${strategyName}:${exchangeName}`;
|
|
1944
1944
|
const isInitial = !this.getPartialStorage.has(key);
|
|
1945
1945
|
const instance = this.getPartialStorage(symbol, strategyName, exchangeName);
|
|
@@ -1959,7 +1959,7 @@ class PersistPartialUtils {
|
|
|
1959
1959
|
* @returns Promise that resolves when write is complete
|
|
1960
1960
|
*/
|
|
1961
1961
|
this.writePartialData = async (partialData, symbol, strategyName, signalId, exchangeName, when) => {
|
|
1962
|
-
LOGGER_SERVICE$
|
|
1962
|
+
LOGGER_SERVICE$9.info(PERSIST_PARTIAL_UTILS_METHOD_NAME_WRITE_DATA);
|
|
1963
1963
|
const key = `${symbol}:${strategyName}:${exchangeName}`;
|
|
1964
1964
|
const isInitial = !this.getPartialStorage.has(key);
|
|
1965
1965
|
const instance = this.getPartialStorage(symbol, strategyName, exchangeName);
|
|
@@ -1974,7 +1974,7 @@ class PersistPartialUtils {
|
|
|
1974
1974
|
* @param Ctor - Custom IPersistPartialInstance constructor
|
|
1975
1975
|
*/
|
|
1976
1976
|
usePersistPartialAdapter(Ctor) {
|
|
1977
|
-
LOGGER_SERVICE$
|
|
1977
|
+
LOGGER_SERVICE$9.info(PERSIST_PARTIAL_UTILS_METHOD_NAME_USE_PERSIST_PARTIAL_ADAPTER);
|
|
1978
1978
|
this.PersistPartialInstanceCtor = Ctor;
|
|
1979
1979
|
this.getPartialStorage.clear();
|
|
1980
1980
|
}
|
|
@@ -1983,21 +1983,21 @@ class PersistPartialUtils {
|
|
|
1983
1983
|
* Call when process.cwd() changes between strategy iterations.
|
|
1984
1984
|
*/
|
|
1985
1985
|
clear() {
|
|
1986
|
-
LOGGER_SERVICE$
|
|
1986
|
+
LOGGER_SERVICE$9.log(PERSIST_PARTIAL_UTILS_METHOD_NAME_CLEAR);
|
|
1987
1987
|
this.getPartialStorage.clear();
|
|
1988
1988
|
}
|
|
1989
1989
|
/**
|
|
1990
1990
|
* Switches to the default file-based PersistPartialInstance.
|
|
1991
1991
|
*/
|
|
1992
1992
|
useJson() {
|
|
1993
|
-
LOGGER_SERVICE$
|
|
1993
|
+
LOGGER_SERVICE$9.log(PERSIST_PARTIAL_UTILS_METHOD_NAME_USE_JSON);
|
|
1994
1994
|
this.usePersistPartialAdapter(PersistPartialInstance);
|
|
1995
1995
|
}
|
|
1996
1996
|
/**
|
|
1997
1997
|
* Switches to PersistPartialDummyInstance (all operations are no-ops).
|
|
1998
1998
|
*/
|
|
1999
1999
|
useDummy() {
|
|
2000
|
-
LOGGER_SERVICE$
|
|
2000
|
+
LOGGER_SERVICE$9.log(PERSIST_PARTIAL_UTILS_METHOD_NAME_USE_DUMMY);
|
|
2001
2001
|
this.usePersistPartialAdapter(PersistPartialDummyInstance);
|
|
2002
2002
|
}
|
|
2003
2003
|
}
|
|
@@ -2162,7 +2162,7 @@ class PersistBreakevenUtils {
|
|
|
2162
2162
|
* @returns Promise resolving to breakeven data record (empty object if none)
|
|
2163
2163
|
*/
|
|
2164
2164
|
this.readBreakevenData = async (symbol, strategyName, signalId, exchangeName, when) => {
|
|
2165
|
-
LOGGER_SERVICE$
|
|
2165
|
+
LOGGER_SERVICE$9.info(PERSIST_BREAKEVEN_UTILS_METHOD_NAME_READ_DATA);
|
|
2166
2166
|
const key = `${symbol}:${strategyName}:${exchangeName}`;
|
|
2167
2167
|
const isInitial = !this.getBreakevenStorage.has(key);
|
|
2168
2168
|
const instance = this.getBreakevenStorage(symbol, strategyName, exchangeName);
|
|
@@ -2182,7 +2182,7 @@ class PersistBreakevenUtils {
|
|
|
2182
2182
|
* @returns Promise that resolves when write is complete
|
|
2183
2183
|
*/
|
|
2184
2184
|
this.writeBreakevenData = async (breakevenData, symbol, strategyName, signalId, exchangeName, when) => {
|
|
2185
|
-
LOGGER_SERVICE$
|
|
2185
|
+
LOGGER_SERVICE$9.info(PERSIST_BREAKEVEN_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2186
2186
|
const key = `${symbol}:${strategyName}:${exchangeName}`;
|
|
2187
2187
|
const isInitial = !this.getBreakevenStorage.has(key);
|
|
2188
2188
|
const instance = this.getBreakevenStorage(symbol, strategyName, exchangeName);
|
|
@@ -2197,7 +2197,7 @@ class PersistBreakevenUtils {
|
|
|
2197
2197
|
* @param Ctor - Custom IPersistBreakevenInstance constructor
|
|
2198
2198
|
*/
|
|
2199
2199
|
usePersistBreakevenAdapter(Ctor) {
|
|
2200
|
-
LOGGER_SERVICE$
|
|
2200
|
+
LOGGER_SERVICE$9.info(PERSIST_BREAKEVEN_UTILS_METHOD_NAME_USE_PERSIST_BREAKEVEN_ADAPTER);
|
|
2201
2201
|
this.PersistBreakevenInstanceCtor = Ctor;
|
|
2202
2202
|
this.getBreakevenStorage.clear();
|
|
2203
2203
|
}
|
|
@@ -2206,21 +2206,21 @@ class PersistBreakevenUtils {
|
|
|
2206
2206
|
* Call when process.cwd() changes between strategy iterations.
|
|
2207
2207
|
*/
|
|
2208
2208
|
clear() {
|
|
2209
|
-
LOGGER_SERVICE$
|
|
2209
|
+
LOGGER_SERVICE$9.log(PERSIST_BREAKEVEN_UTILS_METHOD_NAME_CLEAR);
|
|
2210
2210
|
this.getBreakevenStorage.clear();
|
|
2211
2211
|
}
|
|
2212
2212
|
/**
|
|
2213
2213
|
* Switches to the default file-based PersistBreakevenInstance.
|
|
2214
2214
|
*/
|
|
2215
2215
|
useJson() {
|
|
2216
|
-
LOGGER_SERVICE$
|
|
2216
|
+
LOGGER_SERVICE$9.log(PERSIST_BREAKEVEN_UTILS_METHOD_NAME_USE_JSON);
|
|
2217
2217
|
this.usePersistBreakevenAdapter(PersistBreakevenInstance);
|
|
2218
2218
|
}
|
|
2219
2219
|
/**
|
|
2220
2220
|
* Switches to PersistBreakevenDummyInstance (all operations are no-ops).
|
|
2221
2221
|
*/
|
|
2222
2222
|
useDummy() {
|
|
2223
|
-
LOGGER_SERVICE$
|
|
2223
|
+
LOGGER_SERVICE$9.log(PERSIST_BREAKEVEN_UTILS_METHOD_NAME_USE_DUMMY);
|
|
2224
2224
|
this.usePersistBreakevenAdapter(PersistBreakevenDummyInstance);
|
|
2225
2225
|
}
|
|
2226
2226
|
}
|
|
@@ -2311,7 +2311,7 @@ class PersistCandleInstance {
|
|
|
2311
2311
|
error: errorData(error),
|
|
2312
2312
|
message: getErrorMessage(error),
|
|
2313
2313
|
};
|
|
2314
|
-
LOGGER_SERVICE$
|
|
2314
|
+
LOGGER_SERVICE$9.warn(message, payload);
|
|
2315
2315
|
console.warn(message, payload);
|
|
2316
2316
|
errorEmitter.next(error);
|
|
2317
2317
|
return null;
|
|
@@ -2333,7 +2333,7 @@ class PersistCandleInstance {
|
|
|
2333
2333
|
for (const candle of candles) {
|
|
2334
2334
|
const candleCloseTime = candle.timestamp + stepMs;
|
|
2335
2335
|
if (candleCloseTime > now) {
|
|
2336
|
-
LOGGER_SERVICE$
|
|
2336
|
+
LOGGER_SERVICE$9.debug("PersistCandleInstance.writeCandlesData: skipping incomplete candle", {
|
|
2337
2337
|
symbol: this.symbol,
|
|
2338
2338
|
interval: this.interval,
|
|
2339
2339
|
exchangeName: this.exchangeName,
|
|
@@ -2410,7 +2410,7 @@ class PersistCandleUtils {
|
|
|
2410
2410
|
* @returns Promise resolving to candles in order, or null on cache miss
|
|
2411
2411
|
*/
|
|
2412
2412
|
this.readCandlesData = async (symbol, interval, exchangeName, limit, sinceTimestamp, untilTimestamp) => {
|
|
2413
|
-
LOGGER_SERVICE$
|
|
2413
|
+
LOGGER_SERVICE$9.info("PersistCandleUtils.readCandlesData", {
|
|
2414
2414
|
symbol,
|
|
2415
2415
|
interval,
|
|
2416
2416
|
exchangeName,
|
|
@@ -2434,7 +2434,7 @@ class PersistCandleUtils {
|
|
|
2434
2434
|
* @returns Promise that resolves when all writes are complete
|
|
2435
2435
|
*/
|
|
2436
2436
|
this.writeCandlesData = async (candles, symbol, interval, exchangeName) => {
|
|
2437
|
-
LOGGER_SERVICE$
|
|
2437
|
+
LOGGER_SERVICE$9.info("PersistCandleUtils.writeCandlesData", {
|
|
2438
2438
|
symbol,
|
|
2439
2439
|
interval,
|
|
2440
2440
|
exchangeName,
|
|
@@ -2454,7 +2454,7 @@ class PersistCandleUtils {
|
|
|
2454
2454
|
* @param Ctor - Custom IPersistCandleInstance constructor
|
|
2455
2455
|
*/
|
|
2456
2456
|
usePersistCandleAdapter(Ctor) {
|
|
2457
|
-
LOGGER_SERVICE$
|
|
2457
|
+
LOGGER_SERVICE$9.info("PersistCandleUtils.usePersistCandleAdapter");
|
|
2458
2458
|
this.PersistCandleInstanceCtor = Ctor;
|
|
2459
2459
|
this.getCandlesStorage.clear();
|
|
2460
2460
|
}
|
|
@@ -2463,21 +2463,21 @@ class PersistCandleUtils {
|
|
|
2463
2463
|
* Call when process.cwd() changes between strategy iterations.
|
|
2464
2464
|
*/
|
|
2465
2465
|
clear() {
|
|
2466
|
-
LOGGER_SERVICE$
|
|
2466
|
+
LOGGER_SERVICE$9.log(PERSIST_CANDLE_UTILS_METHOD_NAME_CLEAR);
|
|
2467
2467
|
this.getCandlesStorage.clear();
|
|
2468
2468
|
}
|
|
2469
2469
|
/**
|
|
2470
2470
|
* Switches to the default file-based PersistCandleInstance.
|
|
2471
2471
|
*/
|
|
2472
2472
|
useJson() {
|
|
2473
|
-
LOGGER_SERVICE$
|
|
2473
|
+
LOGGER_SERVICE$9.log("PersistCandleUtils.useJson");
|
|
2474
2474
|
this.usePersistCandleAdapter(PersistCandleInstance);
|
|
2475
2475
|
}
|
|
2476
2476
|
/**
|
|
2477
2477
|
* Switches to PersistCandleDummyInstance (always returns null on read, discards writes).
|
|
2478
2478
|
*/
|
|
2479
2479
|
useDummy() {
|
|
2480
|
-
LOGGER_SERVICE$
|
|
2480
|
+
LOGGER_SERVICE$9.log("PersistCandleUtils.useDummy");
|
|
2481
2481
|
this.usePersistCandleAdapter(PersistCandleDummyInstance);
|
|
2482
2482
|
}
|
|
2483
2483
|
}
|
|
@@ -2615,7 +2615,7 @@ class PersistStorageUtils {
|
|
|
2615
2615
|
* @returns Promise resolving to array of signal entries
|
|
2616
2616
|
*/
|
|
2617
2617
|
this.readStorageData = async (backtest) => {
|
|
2618
|
-
LOGGER_SERVICE$
|
|
2618
|
+
LOGGER_SERVICE$9.info(PERSIST_STORAGE_UTILS_METHOD_NAME_READ_DATA);
|
|
2619
2619
|
const key = backtest ? `backtest` : `live`;
|
|
2620
2620
|
const isInitial = !this.getStorage.has(key);
|
|
2621
2621
|
const instance = this.getStorage(backtest);
|
|
@@ -2631,7 +2631,7 @@ class PersistStorageUtils {
|
|
|
2631
2631
|
* @returns Promise that resolves when write is complete
|
|
2632
2632
|
*/
|
|
2633
2633
|
this.writeStorageData = async (signalData, backtest) => {
|
|
2634
|
-
LOGGER_SERVICE$
|
|
2634
|
+
LOGGER_SERVICE$9.info(PERSIST_STORAGE_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2635
2635
|
const key = backtest ? `backtest` : `live`;
|
|
2636
2636
|
const isInitial = !this.getStorage.has(key);
|
|
2637
2637
|
const instance = this.getStorage(backtest);
|
|
@@ -2646,7 +2646,7 @@ class PersistStorageUtils {
|
|
|
2646
2646
|
* @param Ctor - Custom IPersistStorageInstance constructor
|
|
2647
2647
|
*/
|
|
2648
2648
|
usePersistStorageAdapter(Ctor) {
|
|
2649
|
-
LOGGER_SERVICE$
|
|
2649
|
+
LOGGER_SERVICE$9.info(PERSIST_STORAGE_UTILS_METHOD_NAME_USE_PERSIST_STORAGE_ADAPTER);
|
|
2650
2650
|
this.PersistStorageInstanceCtor = Ctor;
|
|
2651
2651
|
this.getStorage.clear();
|
|
2652
2652
|
}
|
|
@@ -2655,21 +2655,21 @@ class PersistStorageUtils {
|
|
|
2655
2655
|
* Call when process.cwd() changes between strategy iterations.
|
|
2656
2656
|
*/
|
|
2657
2657
|
clear() {
|
|
2658
|
-
LOGGER_SERVICE$
|
|
2658
|
+
LOGGER_SERVICE$9.log(PERSIST_STORAGE_UTILS_METHOD_NAME_CLEAR);
|
|
2659
2659
|
this.getStorage.clear();
|
|
2660
2660
|
}
|
|
2661
2661
|
/**
|
|
2662
2662
|
* Switches to the default file-based PersistStorageInstance.
|
|
2663
2663
|
*/
|
|
2664
2664
|
useJson() {
|
|
2665
|
-
LOGGER_SERVICE$
|
|
2665
|
+
LOGGER_SERVICE$9.log(PERSIST_STORAGE_UTILS_METHOD_NAME_USE_JSON);
|
|
2666
2666
|
this.usePersistStorageAdapter(PersistStorageInstance);
|
|
2667
2667
|
}
|
|
2668
2668
|
/**
|
|
2669
2669
|
* Switches to PersistStorageDummyInstance (all operations are no-ops).
|
|
2670
2670
|
*/
|
|
2671
2671
|
useDummy() {
|
|
2672
|
-
LOGGER_SERVICE$
|
|
2672
|
+
LOGGER_SERVICE$9.log(PERSIST_STORAGE_UTILS_METHOD_NAME_USE_DUMMY);
|
|
2673
2673
|
this.usePersistStorageAdapter(PersistStorageDummyInstance);
|
|
2674
2674
|
}
|
|
2675
2675
|
}
|
|
@@ -2796,7 +2796,7 @@ class PersistNotificationUtils {
|
|
|
2796
2796
|
* @returns Promise resolving to array of notification entries
|
|
2797
2797
|
*/
|
|
2798
2798
|
this.readNotificationData = async (backtest) => {
|
|
2799
|
-
LOGGER_SERVICE$
|
|
2799
|
+
LOGGER_SERVICE$9.info(PERSIST_NOTIFICATION_UTILS_METHOD_NAME_READ_DATA);
|
|
2800
2800
|
const key = backtest ? `backtest` : `live`;
|
|
2801
2801
|
const isInitial = !this.getNotificationStorage.has(key);
|
|
2802
2802
|
const instance = this.getNotificationStorage(backtest);
|
|
@@ -2812,7 +2812,7 @@ class PersistNotificationUtils {
|
|
|
2812
2812
|
* @returns Promise that resolves when write is complete
|
|
2813
2813
|
*/
|
|
2814
2814
|
this.writeNotificationData = async (notificationData, backtest) => {
|
|
2815
|
-
LOGGER_SERVICE$
|
|
2815
|
+
LOGGER_SERVICE$9.info(PERSIST_NOTIFICATION_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2816
2816
|
const key = backtest ? `backtest` : `live`;
|
|
2817
2817
|
const isInitial = !this.getNotificationStorage.has(key);
|
|
2818
2818
|
const instance = this.getNotificationStorage(backtest);
|
|
@@ -2827,7 +2827,7 @@ class PersistNotificationUtils {
|
|
|
2827
2827
|
* @param Ctor - Custom IPersistNotificationInstance constructor
|
|
2828
2828
|
*/
|
|
2829
2829
|
usePersistNotificationAdapter(Ctor) {
|
|
2830
|
-
LOGGER_SERVICE$
|
|
2830
|
+
LOGGER_SERVICE$9.info(PERSIST_NOTIFICATION_UTILS_METHOD_NAME_USE_PERSIST_NOTIFICATION_ADAPTER);
|
|
2831
2831
|
this.PersistNotificationInstanceCtor = Ctor;
|
|
2832
2832
|
this.getNotificationStorage.clear();
|
|
2833
2833
|
}
|
|
@@ -2837,21 +2837,21 @@ class PersistNotificationUtils {
|
|
|
2837
2837
|
* instances are created with the updated base path.
|
|
2838
2838
|
*/
|
|
2839
2839
|
clear() {
|
|
2840
|
-
LOGGER_SERVICE$
|
|
2840
|
+
LOGGER_SERVICE$9.log(PERSIST_NOTIFICATION_UTILS_METHOD_NAME_CLEAR);
|
|
2841
2841
|
this.getNotificationStorage.clear();
|
|
2842
2842
|
}
|
|
2843
2843
|
/**
|
|
2844
2844
|
* Switches to the default file-based PersistNotificationInstance.
|
|
2845
2845
|
*/
|
|
2846
2846
|
useJson() {
|
|
2847
|
-
LOGGER_SERVICE$
|
|
2847
|
+
LOGGER_SERVICE$9.log(PERSIST_NOTIFICATION_UTILS_METHOD_NAME_USE_JSON);
|
|
2848
2848
|
this.usePersistNotificationAdapter(PersistNotificationInstance);
|
|
2849
2849
|
}
|
|
2850
2850
|
/**
|
|
2851
2851
|
* Switches to PersistNotificationDummyInstance (all operations are no-ops).
|
|
2852
2852
|
*/
|
|
2853
2853
|
useDummy() {
|
|
2854
|
-
LOGGER_SERVICE$
|
|
2854
|
+
LOGGER_SERVICE$9.log(PERSIST_NOTIFICATION_UTILS_METHOD_NAME_USE_DUMMY);
|
|
2855
2855
|
this.usePersistNotificationAdapter(PersistNotificationDummyInstance);
|
|
2856
2856
|
}
|
|
2857
2857
|
}
|
|
@@ -2975,7 +2975,7 @@ class PersistLogUtils {
|
|
|
2975
2975
|
* @returns Promise resolving to array of log entries
|
|
2976
2976
|
*/
|
|
2977
2977
|
this.readLogData = async () => {
|
|
2978
|
-
LOGGER_SERVICE$
|
|
2978
|
+
LOGGER_SERVICE$9.info(PERSIST_LOG_UTILS_METHOD_NAME_READ_DATA);
|
|
2979
2979
|
const isInitial = !this._logInstance;
|
|
2980
2980
|
const instance = this.getLogInstance();
|
|
2981
2981
|
await instance.waitForInit(isInitial);
|
|
@@ -2989,7 +2989,7 @@ class PersistLogUtils {
|
|
|
2989
2989
|
* @returns Promise that resolves when write is complete
|
|
2990
2990
|
*/
|
|
2991
2991
|
this.writeLogData = async (logData) => {
|
|
2992
|
-
LOGGER_SERVICE$
|
|
2992
|
+
LOGGER_SERVICE$9.info(PERSIST_LOG_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2993
2993
|
const isInitial = !this._logInstance;
|
|
2994
2994
|
const instance = this.getLogInstance();
|
|
2995
2995
|
await instance.waitForInit(isInitial);
|
|
@@ -3014,7 +3014,7 @@ class PersistLogUtils {
|
|
|
3014
3014
|
* @param Ctor - Custom IPersistLogInstance constructor
|
|
3015
3015
|
*/
|
|
3016
3016
|
usePersistLogAdapter(Ctor) {
|
|
3017
|
-
LOGGER_SERVICE$
|
|
3017
|
+
LOGGER_SERVICE$9.info(PERSIST_LOG_UTILS_METHOD_NAME_USE_PERSIST_LOG_ADAPTER);
|
|
3018
3018
|
this.PersistLogInstanceCtor = Ctor;
|
|
3019
3019
|
this._logInstance = null;
|
|
3020
3020
|
}
|
|
@@ -3023,21 +3023,21 @@ class PersistLogUtils {
|
|
|
3023
3023
|
* Call when process.cwd() changes between strategy iterations.
|
|
3024
3024
|
*/
|
|
3025
3025
|
clear() {
|
|
3026
|
-
LOGGER_SERVICE$
|
|
3026
|
+
LOGGER_SERVICE$9.log(PERSIST_LOG_UTILS_METHOD_NAME_CLEAR);
|
|
3027
3027
|
this._logInstance = null;
|
|
3028
3028
|
}
|
|
3029
3029
|
/**
|
|
3030
3030
|
* Switches to the default file-based PersistLogInstance.
|
|
3031
3031
|
*/
|
|
3032
3032
|
useJson() {
|
|
3033
|
-
LOGGER_SERVICE$
|
|
3033
|
+
LOGGER_SERVICE$9.log(PERSIST_LOG_UTILS_METHOD_NAME_USE_JSON);
|
|
3034
3034
|
this.usePersistLogAdapter(PersistLogInstance);
|
|
3035
3035
|
}
|
|
3036
3036
|
/**
|
|
3037
3037
|
* Switches to PersistLogDummyInstance (all operations are no-ops).
|
|
3038
3038
|
*/
|
|
3039
3039
|
useDummy() {
|
|
3040
|
-
LOGGER_SERVICE$
|
|
3040
|
+
LOGGER_SERVICE$9.log(PERSIST_LOG_UTILS_METHOD_NAME_USE_DUMMY);
|
|
3041
3041
|
this.usePersistLogAdapter(PersistLogDummyInstance);
|
|
3042
3042
|
}
|
|
3043
3043
|
}
|
|
@@ -3199,7 +3199,7 @@ class PersistMeasureUtils {
|
|
|
3199
3199
|
* @returns Promise resolving to cached value, or null if not found / soft-deleted
|
|
3200
3200
|
*/
|
|
3201
3201
|
this.readMeasureData = async (bucket, key) => {
|
|
3202
|
-
LOGGER_SERVICE$
|
|
3202
|
+
LOGGER_SERVICE$9.info(PERSIST_MEASURE_UTILS_METHOD_NAME_READ_DATA, { bucket, key });
|
|
3203
3203
|
const isInitial = !this.getMeasureStorage.has(bucket);
|
|
3204
3204
|
const instance = this.getMeasureStorage(bucket);
|
|
3205
3205
|
await instance.waitForInit(isInitial);
|
|
@@ -3215,7 +3215,7 @@ class PersistMeasureUtils {
|
|
|
3215
3215
|
* @returns Promise that resolves when write is complete
|
|
3216
3216
|
*/
|
|
3217
3217
|
this.writeMeasureData = async (data, bucket, key, when) => {
|
|
3218
|
-
LOGGER_SERVICE$
|
|
3218
|
+
LOGGER_SERVICE$9.info(PERSIST_MEASURE_UTILS_METHOD_NAME_WRITE_DATA, { bucket, key });
|
|
3219
3219
|
const isInitial = !this.getMeasureStorage.has(bucket);
|
|
3220
3220
|
const instance = this.getMeasureStorage(bucket);
|
|
3221
3221
|
await instance.waitForInit(isInitial);
|
|
@@ -3230,7 +3230,7 @@ class PersistMeasureUtils {
|
|
|
3230
3230
|
* @returns Promise that resolves when removal is complete
|
|
3231
3231
|
*/
|
|
3232
3232
|
this.removeMeasureData = async (bucket, key) => {
|
|
3233
|
-
LOGGER_SERVICE$
|
|
3233
|
+
LOGGER_SERVICE$9.info(PERSIST_MEASURE_UTILS_METHOD_NAME_REMOVE_DATA, { bucket, key });
|
|
3234
3234
|
const isInitial = !this.getMeasureStorage.has(bucket);
|
|
3235
3235
|
const instance = this.getMeasureStorage(bucket);
|
|
3236
3236
|
await instance.waitForInit(isInitial);
|
|
@@ -3244,7 +3244,7 @@ class PersistMeasureUtils {
|
|
|
3244
3244
|
* @param Ctor - Custom IPersistMeasureInstance constructor
|
|
3245
3245
|
*/
|
|
3246
3246
|
usePersistMeasureAdapter(Ctor) {
|
|
3247
|
-
LOGGER_SERVICE$
|
|
3247
|
+
LOGGER_SERVICE$9.info(PERSIST_MEASURE_UTILS_METHOD_NAME_USE_PERSIST_MEASURE_ADAPTER);
|
|
3248
3248
|
this.PersistMeasureInstanceCtor = Ctor;
|
|
3249
3249
|
this.getMeasureStorage.clear();
|
|
3250
3250
|
}
|
|
@@ -3256,7 +3256,7 @@ class PersistMeasureUtils {
|
|
|
3256
3256
|
* @returns AsyncGenerator yielding entry keys
|
|
3257
3257
|
*/
|
|
3258
3258
|
async *listMeasureData(bucket) {
|
|
3259
|
-
LOGGER_SERVICE$
|
|
3259
|
+
LOGGER_SERVICE$9.info(PERSIST_MEASURE_UTILS_METHOD_NAME_LIST_DATA, { bucket });
|
|
3260
3260
|
const isInitial = !this.getMeasureStorage.has(bucket);
|
|
3261
3261
|
const instance = this.getMeasureStorage(bucket);
|
|
3262
3262
|
await instance.waitForInit(isInitial);
|
|
@@ -3267,21 +3267,21 @@ class PersistMeasureUtils {
|
|
|
3267
3267
|
* Call when process.cwd() changes between strategy iterations.
|
|
3268
3268
|
*/
|
|
3269
3269
|
clear() {
|
|
3270
|
-
LOGGER_SERVICE$
|
|
3270
|
+
LOGGER_SERVICE$9.log(PERSIST_MEASURE_UTILS_METHOD_NAME_CLEAR);
|
|
3271
3271
|
this.getMeasureStorage.clear();
|
|
3272
3272
|
}
|
|
3273
3273
|
/**
|
|
3274
3274
|
* Switches to the default file-based PersistMeasureInstance.
|
|
3275
3275
|
*/
|
|
3276
3276
|
useJson() {
|
|
3277
|
-
LOGGER_SERVICE$
|
|
3277
|
+
LOGGER_SERVICE$9.log(PERSIST_MEASURE_UTILS_METHOD_NAME_USE_JSON);
|
|
3278
3278
|
this.usePersistMeasureAdapter(PersistMeasureInstance);
|
|
3279
3279
|
}
|
|
3280
3280
|
/**
|
|
3281
3281
|
* Switches to PersistMeasureDummyInstance (all operations are no-ops).
|
|
3282
3282
|
*/
|
|
3283
3283
|
useDummy() {
|
|
3284
|
-
LOGGER_SERVICE$
|
|
3284
|
+
LOGGER_SERVICE$9.log(PERSIST_MEASURE_UTILS_METHOD_NAME_USE_DUMMY);
|
|
3285
3285
|
this.usePersistMeasureAdapter(PersistMeasureDummyInstance);
|
|
3286
3286
|
}
|
|
3287
3287
|
}
|
|
@@ -3440,7 +3440,7 @@ class PersistIntervalUtils {
|
|
|
3440
3440
|
* @returns Promise resolving to marker data, or null if not found / soft-deleted
|
|
3441
3441
|
*/
|
|
3442
3442
|
this.readIntervalData = async (bucket, key) => {
|
|
3443
|
-
LOGGER_SERVICE$
|
|
3443
|
+
LOGGER_SERVICE$9.info(PERSIST_INTERVAL_UTILS_METHOD_NAME_READ_DATA, { bucket, key });
|
|
3444
3444
|
const isInitial = !this.getIntervalStorage.has(bucket);
|
|
3445
3445
|
const instance = this.getIntervalStorage(bucket);
|
|
3446
3446
|
await instance.waitForInit(isInitial);
|
|
@@ -3456,7 +3456,7 @@ class PersistIntervalUtils {
|
|
|
3456
3456
|
* @returns Promise that resolves when write is complete
|
|
3457
3457
|
*/
|
|
3458
3458
|
this.writeIntervalData = async (data, bucket, key, when) => {
|
|
3459
|
-
LOGGER_SERVICE$
|
|
3459
|
+
LOGGER_SERVICE$9.info(PERSIST_INTERVAL_UTILS_METHOD_NAME_WRITE_DATA, { bucket, key });
|
|
3460
3460
|
const isInitial = !this.getIntervalStorage.has(bucket);
|
|
3461
3461
|
const instance = this.getIntervalStorage(bucket);
|
|
3462
3462
|
await instance.waitForInit(isInitial);
|
|
@@ -3471,7 +3471,7 @@ class PersistIntervalUtils {
|
|
|
3471
3471
|
* @returns Promise that resolves when removal is complete
|
|
3472
3472
|
*/
|
|
3473
3473
|
this.removeIntervalData = async (bucket, key) => {
|
|
3474
|
-
LOGGER_SERVICE$
|
|
3474
|
+
LOGGER_SERVICE$9.info(PERSIST_INTERVAL_UTILS_METHOD_NAME_REMOVE_DATA, { bucket, key });
|
|
3475
3475
|
const isInitial = !this.getIntervalStorage.has(bucket);
|
|
3476
3476
|
const instance = this.getIntervalStorage(bucket);
|
|
3477
3477
|
await instance.waitForInit(isInitial);
|
|
@@ -3485,7 +3485,7 @@ class PersistIntervalUtils {
|
|
|
3485
3485
|
* @param Ctor - Custom IPersistIntervalInstance constructor
|
|
3486
3486
|
*/
|
|
3487
3487
|
usePersistIntervalAdapter(Ctor) {
|
|
3488
|
-
LOGGER_SERVICE$
|
|
3488
|
+
LOGGER_SERVICE$9.info(PERSIST_INTERVAL_UTILS_METHOD_NAME_USE_PERSIST_INTERVAL_ADAPTER);
|
|
3489
3489
|
this.PersistIntervalInstanceCtor = Ctor;
|
|
3490
3490
|
this.getIntervalStorage.clear();
|
|
3491
3491
|
}
|
|
@@ -3497,7 +3497,7 @@ class PersistIntervalUtils {
|
|
|
3497
3497
|
* @returns AsyncGenerator yielding marker keys
|
|
3498
3498
|
*/
|
|
3499
3499
|
async *listIntervalData(bucket) {
|
|
3500
|
-
LOGGER_SERVICE$
|
|
3500
|
+
LOGGER_SERVICE$9.info(PERSIST_INTERVAL_UTILS_METHOD_NAME_LIST_DATA, { bucket });
|
|
3501
3501
|
const isInitial = !this.getIntervalStorage.has(bucket);
|
|
3502
3502
|
const instance = this.getIntervalStorage(bucket);
|
|
3503
3503
|
await instance.waitForInit(isInitial);
|
|
@@ -3508,21 +3508,21 @@ class PersistIntervalUtils {
|
|
|
3508
3508
|
* Call when process.cwd() changes between strategy iterations.
|
|
3509
3509
|
*/
|
|
3510
3510
|
clear() {
|
|
3511
|
-
LOGGER_SERVICE$
|
|
3511
|
+
LOGGER_SERVICE$9.log(PERSIST_INTERVAL_UTILS_METHOD_NAME_CLEAR);
|
|
3512
3512
|
this.getIntervalStorage.clear();
|
|
3513
3513
|
}
|
|
3514
3514
|
/**
|
|
3515
3515
|
* Switches to the default file-based PersistIntervalInstance.
|
|
3516
3516
|
*/
|
|
3517
3517
|
useJson() {
|
|
3518
|
-
LOGGER_SERVICE$
|
|
3518
|
+
LOGGER_SERVICE$9.log(PERSIST_INTERVAL_UTILS_METHOD_NAME_USE_JSON);
|
|
3519
3519
|
this.usePersistIntervalAdapter(PersistIntervalInstance);
|
|
3520
3520
|
}
|
|
3521
3521
|
/**
|
|
3522
3522
|
* Switches to PersistIntervalDummyInstance (all operations are no-ops).
|
|
3523
3523
|
*/
|
|
3524
3524
|
useDummy() {
|
|
3525
|
-
LOGGER_SERVICE$
|
|
3525
|
+
LOGGER_SERVICE$9.log(PERSIST_INTERVAL_UTILS_METHOD_NAME_USE_DUMMY);
|
|
3526
3526
|
this.usePersistIntervalAdapter(PersistIntervalDummyInstance);
|
|
3527
3527
|
}
|
|
3528
3528
|
}
|
|
@@ -3728,7 +3728,7 @@ class PersistMemoryUtils {
|
|
|
3728
3728
|
* @returns Promise resolving to entry data, or null if not found / soft-deleted
|
|
3729
3729
|
*/
|
|
3730
3730
|
this.readMemoryData = async (signalId, bucketName, memoryId) => {
|
|
3731
|
-
LOGGER_SERVICE$
|
|
3731
|
+
LOGGER_SERVICE$9.info(PERSIST_MEMORY_UTILS_METHOD_NAME_READ_DATA, { signalId, bucketName, memoryId });
|
|
3732
3732
|
const key = `${signalId}:${bucketName}`;
|
|
3733
3733
|
const isInitial = !this.getMemoryStorage.has(key);
|
|
3734
3734
|
const instance = this.getMemoryStorage(signalId, bucketName);
|
|
@@ -3745,7 +3745,7 @@ class PersistMemoryUtils {
|
|
|
3745
3745
|
* @returns Promise resolving to true if entry exists
|
|
3746
3746
|
*/
|
|
3747
3747
|
this.hasMemoryData = async (signalId, bucketName, memoryId) => {
|
|
3748
|
-
LOGGER_SERVICE$
|
|
3748
|
+
LOGGER_SERVICE$9.info(PERSIST_MEMORY_UTILS_METHOD_NAME_HAS_DATA, { signalId, bucketName, memoryId });
|
|
3749
3749
|
const key = `${signalId}:${bucketName}`;
|
|
3750
3750
|
const isInitial = !this.getMemoryStorage.has(key);
|
|
3751
3751
|
const instance = this.getMemoryStorage(signalId, bucketName);
|
|
@@ -3764,7 +3764,7 @@ class PersistMemoryUtils {
|
|
|
3764
3764
|
* @returns Promise that resolves when write is complete
|
|
3765
3765
|
*/
|
|
3766
3766
|
this.writeMemoryData = async (data, signalId, bucketName, memoryId, when) => {
|
|
3767
|
-
LOGGER_SERVICE$
|
|
3767
|
+
LOGGER_SERVICE$9.info(PERSIST_MEMORY_UTILS_METHOD_NAME_WRITE_DATA, { signalId, bucketName, memoryId });
|
|
3768
3768
|
const key = `${signalId}:${bucketName}`;
|
|
3769
3769
|
const isInitial = !this.getMemoryStorage.has(key);
|
|
3770
3770
|
const instance = this.getMemoryStorage(signalId, bucketName);
|
|
@@ -3781,7 +3781,7 @@ class PersistMemoryUtils {
|
|
|
3781
3781
|
* @returns Promise that resolves when removal is complete
|
|
3782
3782
|
*/
|
|
3783
3783
|
this.removeMemoryData = async (signalId, bucketName, memoryId) => {
|
|
3784
|
-
LOGGER_SERVICE$
|
|
3784
|
+
LOGGER_SERVICE$9.info(PERSIST_MEMORY_UTILS_METHOD_NAME_REMOVE_DATA, { signalId, bucketName, memoryId });
|
|
3785
3785
|
const key = `${signalId}:${bucketName}`;
|
|
3786
3786
|
const isInitial = !this.getMemoryStorage.has(key);
|
|
3787
3787
|
const instance = this.getMemoryStorage(signalId, bucketName);
|
|
@@ -3793,7 +3793,7 @@ class PersistMemoryUtils {
|
|
|
3793
3793
|
* Call when process.cwd() changes between strategy iterations.
|
|
3794
3794
|
*/
|
|
3795
3795
|
this.clear = () => {
|
|
3796
|
-
LOGGER_SERVICE$
|
|
3796
|
+
LOGGER_SERVICE$9.info(PERSIST_MEMORY_UTILS_METHOD_NAME_CLEAR);
|
|
3797
3797
|
this.getMemoryStorage.clear();
|
|
3798
3798
|
};
|
|
3799
3799
|
/**
|
|
@@ -3804,7 +3804,7 @@ class PersistMemoryUtils {
|
|
|
3804
3804
|
* @param bucketName - Bucket name
|
|
3805
3805
|
*/
|
|
3806
3806
|
this.dispose = (signalId, bucketName) => {
|
|
3807
|
-
LOGGER_SERVICE$
|
|
3807
|
+
LOGGER_SERVICE$9.info(PERSIST_MEMORY_UTILS_METHOD_NAME_DISPOSE);
|
|
3808
3808
|
const key = `${signalId}:${bucketName}`;
|
|
3809
3809
|
this.getMemoryStorage.clear(key);
|
|
3810
3810
|
};
|
|
@@ -3816,7 +3816,7 @@ class PersistMemoryUtils {
|
|
|
3816
3816
|
* @param Ctor - Custom IPersistMemoryInstance constructor
|
|
3817
3817
|
*/
|
|
3818
3818
|
usePersistMemoryAdapter(Ctor) {
|
|
3819
|
-
LOGGER_SERVICE$
|
|
3819
|
+
LOGGER_SERVICE$9.info(PERSIST_MEMORY_UTILS_METHOD_NAME_USE_PERSIST_MEMORY_ADAPTER);
|
|
3820
3820
|
this.PersistMemoryInstanceCtor = Ctor;
|
|
3821
3821
|
this.getMemoryStorage.clear();
|
|
3822
3822
|
}
|
|
@@ -3830,7 +3830,7 @@ class PersistMemoryUtils {
|
|
|
3830
3830
|
* @returns AsyncGenerator yielding `{ memoryId, data }` tuples
|
|
3831
3831
|
*/
|
|
3832
3832
|
async *listMemoryData(signalId, bucketName) {
|
|
3833
|
-
LOGGER_SERVICE$
|
|
3833
|
+
LOGGER_SERVICE$9.info(PERSIST_MEMORY_UTILS_METHOD_NAME_LIST_DATA, { signalId, bucketName });
|
|
3834
3834
|
const key = `${signalId}:${bucketName}`;
|
|
3835
3835
|
const isInitial = !this.getMemoryStorage.has(key);
|
|
3836
3836
|
const instance = this.getMemoryStorage(signalId, bucketName);
|
|
@@ -3841,14 +3841,14 @@ class PersistMemoryUtils {
|
|
|
3841
3841
|
* Switches to the default file-based PersistMemoryInstance.
|
|
3842
3842
|
*/
|
|
3843
3843
|
useJson() {
|
|
3844
|
-
LOGGER_SERVICE$
|
|
3844
|
+
LOGGER_SERVICE$9.log(PERSIST_SIGNAL_UTILS_METHOD_NAME_USE_JSON);
|
|
3845
3845
|
this.usePersistMemoryAdapter(PersistMemoryInstance);
|
|
3846
3846
|
}
|
|
3847
3847
|
/**
|
|
3848
3848
|
* Switches to PersistMemoryDummyInstance (all operations are no-ops).
|
|
3849
3849
|
*/
|
|
3850
3850
|
useDummy() {
|
|
3851
|
-
LOGGER_SERVICE$
|
|
3851
|
+
LOGGER_SERVICE$9.log(PERSIST_SIGNAL_UTILS_METHOD_NAME_USE_DUMMY);
|
|
3852
3852
|
this.usePersistMemoryAdapter(PersistMemoryDummyInstance);
|
|
3853
3853
|
}
|
|
3854
3854
|
}
|
|
@@ -3997,7 +3997,7 @@ class PersistRecentUtils {
|
|
|
3997
3997
|
* @returns Promise resolving to recent signal or null if none persisted
|
|
3998
3998
|
*/
|
|
3999
3999
|
this.readRecentData = async (symbol, strategyName, exchangeName, frameName, backtest) => {
|
|
4000
|
-
LOGGER_SERVICE$
|
|
4000
|
+
LOGGER_SERVICE$9.info(PERSIST_RECENT_UTILS_METHOD_NAME_READ_DATA);
|
|
4001
4001
|
const key = this.createKey(symbol, strategyName, exchangeName, frameName, backtest);
|
|
4002
4002
|
const isInitial = !this.getStorage.has(key);
|
|
4003
4003
|
const instance = this.getStorage(symbol, strategyName, exchangeName, frameName, backtest);
|
|
@@ -4018,7 +4018,7 @@ class PersistRecentUtils {
|
|
|
4018
4018
|
* @returns Promise that resolves when write is complete
|
|
4019
4019
|
*/
|
|
4020
4020
|
this.writeRecentData = async (signalRow, symbol, strategyName, exchangeName, frameName, backtest, when) => {
|
|
4021
|
-
LOGGER_SERVICE$
|
|
4021
|
+
LOGGER_SERVICE$9.info(PERSIST_RECENT_UTILS_METHOD_NAME_WRITE_DATA);
|
|
4022
4022
|
const key = this.createKey(symbol, strategyName, exchangeName, frameName, backtest);
|
|
4023
4023
|
const isInitial = !this.getStorage.has(key);
|
|
4024
4024
|
const instance = this.getStorage(symbol, strategyName, exchangeName, frameName, backtest);
|
|
@@ -4051,7 +4051,7 @@ class PersistRecentUtils {
|
|
|
4051
4051
|
* @param Ctor - Custom IPersistRecentInstance constructor
|
|
4052
4052
|
*/
|
|
4053
4053
|
usePersistRecentAdapter(Ctor) {
|
|
4054
|
-
LOGGER_SERVICE$
|
|
4054
|
+
LOGGER_SERVICE$9.info(PERSIST_RECENT_UTILS_METHOD_NAME_USE_PERSIST_RECENT_ADAPTER);
|
|
4055
4055
|
this.PersistRecentInstanceCtor = Ctor;
|
|
4056
4056
|
this.getStorage.clear();
|
|
4057
4057
|
}
|
|
@@ -4060,21 +4060,21 @@ class PersistRecentUtils {
|
|
|
4060
4060
|
* Call when process.cwd() changes between strategy iterations.
|
|
4061
4061
|
*/
|
|
4062
4062
|
clear() {
|
|
4063
|
-
LOGGER_SERVICE$
|
|
4063
|
+
LOGGER_SERVICE$9.log(PERSIST_RECENT_UTILS_METHOD_NAME_CLEAR);
|
|
4064
4064
|
this.getStorage.clear();
|
|
4065
4065
|
}
|
|
4066
4066
|
/**
|
|
4067
4067
|
* Switches to the default file-based PersistRecentInstance.
|
|
4068
4068
|
*/
|
|
4069
4069
|
useJson() {
|
|
4070
|
-
LOGGER_SERVICE$
|
|
4070
|
+
LOGGER_SERVICE$9.log(PERSIST_RECENT_UTILS_METHOD_NAME_USE_JSON);
|
|
4071
4071
|
this.usePersistRecentAdapter(PersistRecentInstance);
|
|
4072
4072
|
}
|
|
4073
4073
|
/**
|
|
4074
4074
|
* Switches to PersistRecentDummyInstance (all operations are no-ops).
|
|
4075
4075
|
*/
|
|
4076
4076
|
useDummy() {
|
|
4077
|
-
LOGGER_SERVICE$
|
|
4077
|
+
LOGGER_SERVICE$9.log(PERSIST_RECENT_UTILS_METHOD_NAME_USE_DUMMY);
|
|
4078
4078
|
this.usePersistRecentAdapter(PersistRecentDummyInstance);
|
|
4079
4079
|
}
|
|
4080
4080
|
}
|
|
@@ -4209,7 +4209,7 @@ class PersistStateUtils {
|
|
|
4209
4209
|
* @returns Promise that resolves when initialization is complete
|
|
4210
4210
|
*/
|
|
4211
4211
|
this.waitForInit = async (signalId, bucketName, initial) => {
|
|
4212
|
-
LOGGER_SERVICE$
|
|
4212
|
+
LOGGER_SERVICE$9.info(PERSIST_STATE_UTILS_METHOD_NAME_WAIT_FOR_INIT, { signalId, bucketName, initial });
|
|
4213
4213
|
const key = `${signalId}:${bucketName}`;
|
|
4214
4214
|
const isInitial = initial && !this.getStateStorage.has(key);
|
|
4215
4215
|
const instance = this.getStateStorage(signalId, bucketName);
|
|
@@ -4224,7 +4224,7 @@ class PersistStateUtils {
|
|
|
4224
4224
|
* @returns Promise resolving to state data or null if none persisted
|
|
4225
4225
|
*/
|
|
4226
4226
|
this.readStateData = async (signalId, bucketName) => {
|
|
4227
|
-
LOGGER_SERVICE$
|
|
4227
|
+
LOGGER_SERVICE$9.info(PERSIST_STATE_UTILS_METHOD_NAME_READ_DATA, { signalId, bucketName });
|
|
4228
4228
|
const key = `${signalId}:${bucketName}`;
|
|
4229
4229
|
const isInitial = !this.getStateStorage.has(key);
|
|
4230
4230
|
const instance = this.getStateStorage(signalId, bucketName);
|
|
@@ -4242,7 +4242,7 @@ class PersistStateUtils {
|
|
|
4242
4242
|
* @returns Promise that resolves when write is complete
|
|
4243
4243
|
*/
|
|
4244
4244
|
this.writeStateData = async (data, signalId, bucketName, when) => {
|
|
4245
|
-
LOGGER_SERVICE$
|
|
4245
|
+
LOGGER_SERVICE$9.info(PERSIST_STATE_UTILS_METHOD_NAME_WRITE_DATA, { signalId, bucketName });
|
|
4246
4246
|
const key = `${signalId}:${bucketName}`;
|
|
4247
4247
|
const isInitial = !this.getStateStorage.has(key);
|
|
4248
4248
|
const instance = this.getStateStorage(signalId, bucketName);
|
|
@@ -4253,14 +4253,14 @@ class PersistStateUtils {
|
|
|
4253
4253
|
* Switches to PersistStateDummyInstance (all operations are no-ops).
|
|
4254
4254
|
*/
|
|
4255
4255
|
this.useDummy = () => {
|
|
4256
|
-
LOGGER_SERVICE$
|
|
4256
|
+
LOGGER_SERVICE$9.log(PERSIST_STATE_UTILS_METHOD_NAME_USE_DUMMY);
|
|
4257
4257
|
this.usePersistStateAdapter(PersistStateDummyInstance);
|
|
4258
4258
|
};
|
|
4259
4259
|
/**
|
|
4260
4260
|
* Switches to the default file-based PersistStateInstance.
|
|
4261
4261
|
*/
|
|
4262
4262
|
this.useJson = () => {
|
|
4263
|
-
LOGGER_SERVICE$
|
|
4263
|
+
LOGGER_SERVICE$9.log(PERSIST_STATE_UTILS_METHOD_NAME_USE_JSON);
|
|
4264
4264
|
this.usePersistStateAdapter(PersistStateInstance);
|
|
4265
4265
|
};
|
|
4266
4266
|
/**
|
|
@@ -4268,7 +4268,7 @@ class PersistStateUtils {
|
|
|
4268
4268
|
* Call when process.cwd() changes between strategy iterations.
|
|
4269
4269
|
*/
|
|
4270
4270
|
this.clear = () => {
|
|
4271
|
-
LOGGER_SERVICE$
|
|
4271
|
+
LOGGER_SERVICE$9.info(PERSIST_STATE_UTILS_METHOD_NAME_CLEAR);
|
|
4272
4272
|
this.getStateStorage.clear();
|
|
4273
4273
|
};
|
|
4274
4274
|
/**
|
|
@@ -4279,7 +4279,7 @@ class PersistStateUtils {
|
|
|
4279
4279
|
* @param bucketName - Bucket name
|
|
4280
4280
|
*/
|
|
4281
4281
|
this.dispose = (signalId, bucketName) => {
|
|
4282
|
-
LOGGER_SERVICE$
|
|
4282
|
+
LOGGER_SERVICE$9.info(PERSIST_STATE_UTILS_METHOD_NAME_DISPOSE);
|
|
4283
4283
|
const key = `${signalId}:${bucketName}`;
|
|
4284
4284
|
this.getStateStorage.clear(key);
|
|
4285
4285
|
};
|
|
@@ -4291,7 +4291,7 @@ class PersistStateUtils {
|
|
|
4291
4291
|
* @param Ctor - Custom IPersistStateInstance constructor
|
|
4292
4292
|
*/
|
|
4293
4293
|
usePersistStateAdapter(Ctor) {
|
|
4294
|
-
LOGGER_SERVICE$
|
|
4294
|
+
LOGGER_SERVICE$9.info(PERSIST_STATE_UTILS_METHOD_NAME_USE_PERSIST_STATE_ADAPTER);
|
|
4295
4295
|
this.PersistStateInstanceCtor = Ctor;
|
|
4296
4296
|
this.getStateStorage.clear();
|
|
4297
4297
|
}
|
|
@@ -4431,7 +4431,7 @@ class PersistSessionUtils {
|
|
|
4431
4431
|
* @returns Promise that resolves when initialization is complete
|
|
4432
4432
|
*/
|
|
4433
4433
|
this.waitForInit = async (strategyName, exchangeName, frameName, initial) => {
|
|
4434
|
-
LOGGER_SERVICE$
|
|
4434
|
+
LOGGER_SERVICE$9.info(PERSIST_SESSION_UTILS_METHOD_NAME_WAIT_FOR_INIT, { strategyName, exchangeName, frameName, initial });
|
|
4435
4435
|
const key = `${strategyName}:${exchangeName}:${frameName}`;
|
|
4436
4436
|
const isInitial = initial && !this.getSessionStorage.has(key);
|
|
4437
4437
|
const instance = this.getSessionStorage(strategyName, exchangeName, frameName);
|
|
@@ -4447,7 +4447,7 @@ class PersistSessionUtils {
|
|
|
4447
4447
|
* @returns Promise resolving to session data or null if none persisted
|
|
4448
4448
|
*/
|
|
4449
4449
|
this.readSessionData = async (strategyName, exchangeName, frameName) => {
|
|
4450
|
-
LOGGER_SERVICE$
|
|
4450
|
+
LOGGER_SERVICE$9.info(PERSIST_SESSION_UTILS_METHOD_NAME_READ_DATA, { strategyName, exchangeName, frameName });
|
|
4451
4451
|
const key = `${strategyName}:${exchangeName}:${frameName}`;
|
|
4452
4452
|
const isInitial = !this.getSessionStorage.has(key);
|
|
4453
4453
|
const instance = this.getSessionStorage(strategyName, exchangeName, frameName);
|
|
@@ -4466,7 +4466,7 @@ class PersistSessionUtils {
|
|
|
4466
4466
|
* @returns Promise that resolves when write is complete
|
|
4467
4467
|
*/
|
|
4468
4468
|
this.writeSessionData = async (data, strategyName, exchangeName, frameName, when) => {
|
|
4469
|
-
LOGGER_SERVICE$
|
|
4469
|
+
LOGGER_SERVICE$9.info(PERSIST_SESSION_UTILS_METHOD_NAME_WRITE_DATA, { strategyName, exchangeName, frameName });
|
|
4470
4470
|
const key = `${strategyName}:${exchangeName}:${frameName}`;
|
|
4471
4471
|
const isInitial = !this.getSessionStorage.has(key);
|
|
4472
4472
|
const instance = this.getSessionStorage(strategyName, exchangeName, frameName);
|
|
@@ -4477,14 +4477,14 @@ class PersistSessionUtils {
|
|
|
4477
4477
|
* Switches to PersistSessionDummyInstance (all operations are no-ops).
|
|
4478
4478
|
*/
|
|
4479
4479
|
this.useDummy = () => {
|
|
4480
|
-
LOGGER_SERVICE$
|
|
4480
|
+
LOGGER_SERVICE$9.log(PERSIST_SESSION_UTILS_METHOD_NAME_USE_DUMMY);
|
|
4481
4481
|
this.usePersistSessionAdapter(PersistSessionDummyInstance);
|
|
4482
4482
|
};
|
|
4483
4483
|
/**
|
|
4484
4484
|
* Switches to the default file-based PersistSessionInstance.
|
|
4485
4485
|
*/
|
|
4486
4486
|
this.useJson = () => {
|
|
4487
|
-
LOGGER_SERVICE$
|
|
4487
|
+
LOGGER_SERVICE$9.log(PERSIST_SESSION_UTILS_METHOD_NAME_USE_JSON);
|
|
4488
4488
|
this.usePersistSessionAdapter(PersistSessionInstance);
|
|
4489
4489
|
};
|
|
4490
4490
|
/**
|
|
@@ -4492,7 +4492,7 @@ class PersistSessionUtils {
|
|
|
4492
4492
|
* Call when process.cwd() changes between strategy iterations.
|
|
4493
4493
|
*/
|
|
4494
4494
|
this.clear = () => {
|
|
4495
|
-
LOGGER_SERVICE$
|
|
4495
|
+
LOGGER_SERVICE$9.info(PERSIST_SESSION_UTILS_METHOD_NAME_CLEAR);
|
|
4496
4496
|
this.getSessionStorage.clear();
|
|
4497
4497
|
};
|
|
4498
4498
|
/**
|
|
@@ -4504,7 +4504,7 @@ class PersistSessionUtils {
|
|
|
4504
4504
|
* @param frameName - Frame identifier
|
|
4505
4505
|
*/
|
|
4506
4506
|
this.dispose = (strategyName, exchangeName, frameName) => {
|
|
4507
|
-
LOGGER_SERVICE$
|
|
4507
|
+
LOGGER_SERVICE$9.info(PERSIST_SESSION_UTILS_METHOD_NAME_DISPOSE);
|
|
4508
4508
|
const key = `${strategyName}:${exchangeName}:${frameName}`;
|
|
4509
4509
|
this.getSessionStorage.clear(key);
|
|
4510
4510
|
};
|
|
@@ -4516,7 +4516,7 @@ class PersistSessionUtils {
|
|
|
4516
4516
|
* @param Ctor - Custom IPersistSessionInstance constructor
|
|
4517
4517
|
*/
|
|
4518
4518
|
usePersistSessionAdapter(Ctor) {
|
|
4519
|
-
LOGGER_SERVICE$
|
|
4519
|
+
LOGGER_SERVICE$9.info(PERSIST_SESSION_UTILS_METHOD_NAME_USE_PERSIST_SESSION_ADAPTER);
|
|
4520
4520
|
this.PersistSessionInstanceCtor = Ctor;
|
|
4521
4521
|
this.getSessionStorage.clear();
|
|
4522
4522
|
}
|
|
@@ -4638,7 +4638,7 @@ const METHOD_NAME_ADD_ACTIVITY = "LookupUtils.addActivity";
|
|
|
4638
4638
|
const METHOD_NAME_REMOVE_ACTIVITY = "LookupUtils.removeActivity";
|
|
4639
4639
|
const METHOD_NAME_LIST_ACTIVITY = "LookupUtils.listActivity";
|
|
4640
4640
|
/** Logger service injected as DI singleton */
|
|
4641
|
-
const LOGGER_SERVICE$
|
|
4641
|
+
const LOGGER_SERVICE$8 = new LoggerService();
|
|
4642
4642
|
/**
|
|
4643
4643
|
* Builds the composite {@link Key} used to register an activity in `_lookupMap`.
|
|
4644
4644
|
*
|
|
@@ -4692,7 +4692,7 @@ class LookupUtils {
|
|
|
4692
4692
|
* @param activity - Activity descriptor identifying the running workload.
|
|
4693
4693
|
*/
|
|
4694
4694
|
this.addActivity = (activity) => {
|
|
4695
|
-
LOGGER_SERVICE$
|
|
4695
|
+
LOGGER_SERVICE$8.info(METHOD_NAME_ADD_ACTIVITY, {
|
|
4696
4696
|
activity,
|
|
4697
4697
|
});
|
|
4698
4698
|
const key = CREATE_KEY_FN$y(activity.symbol, activity.context.strategyName, activity.context.exchangeName, activity.context.frameName, activity.backtest);
|
|
@@ -4706,7 +4706,7 @@ class LookupUtils {
|
|
|
4706
4706
|
* @param activity - Activity descriptor matching the one passed to {@link addActivity}.
|
|
4707
4707
|
*/
|
|
4708
4708
|
this.removeActivity = (activity) => {
|
|
4709
|
-
LOGGER_SERVICE$
|
|
4709
|
+
LOGGER_SERVICE$8.info(METHOD_NAME_REMOVE_ACTIVITY, {
|
|
4710
4710
|
activity,
|
|
4711
4711
|
});
|
|
4712
4712
|
const key = CREATE_KEY_FN$y(activity.symbol, activity.context.strategyName, activity.context.exchangeName, activity.context.frameName, activity.backtest);
|
|
@@ -4718,7 +4718,7 @@ class LookupUtils {
|
|
|
4718
4718
|
* @returns Array of all activities present in the lookup map at call time.
|
|
4719
4719
|
*/
|
|
4720
4720
|
this.listActivity = () => {
|
|
4721
|
-
LOGGER_SERVICE$
|
|
4721
|
+
LOGGER_SERVICE$8.info(METHOD_NAME_LIST_ACTIVITY);
|
|
4722
4722
|
return Array.from(this._lookupMap.values());
|
|
4723
4723
|
};
|
|
4724
4724
|
}
|
|
@@ -4747,7 +4747,7 @@ const METHOD_NAME_SPIN_LOCK = "CandleUtils.spinLock";
|
|
|
4747
4747
|
*/
|
|
4748
4748
|
const ROTATE_DELAY = 50;
|
|
4749
4749
|
/** Logger service injected as DI singleton */
|
|
4750
|
-
const LOGGER_SERVICE$
|
|
4750
|
+
const LOGGER_SERVICE$7 = new LoggerService();
|
|
4751
4751
|
/**
|
|
4752
4752
|
* Process-wide coordinator for candle-fetch serialization and cooperative
|
|
4753
4753
|
* yielding between parallel backtests.
|
|
@@ -4796,7 +4796,7 @@ class CandleUtils {
|
|
|
4796
4796
|
* @param source - Caller identifier for logging.
|
|
4797
4797
|
*/
|
|
4798
4798
|
this.acquireLock = async (source) => {
|
|
4799
|
-
LOGGER_SERVICE$
|
|
4799
|
+
LOGGER_SERVICE$7.info(METHOD_NAME_ACQUIRE_LOCK, {
|
|
4800
4800
|
source,
|
|
4801
4801
|
});
|
|
4802
4802
|
if (!GLOBAL_CONFIG.CC_ENABLE_CANDLE_FETCH_MUTEX) {
|
|
@@ -4812,7 +4812,7 @@ class CandleUtils {
|
|
|
4812
4812
|
* @param source - Caller identifier for logging.
|
|
4813
4813
|
*/
|
|
4814
4814
|
this.releaseLock = async (source) => {
|
|
4815
|
-
LOGGER_SERVICE$
|
|
4815
|
+
LOGGER_SERVICE$7.info(METHOD_NAME_RELEASE_LOCK, {
|
|
4816
4816
|
source,
|
|
4817
4817
|
});
|
|
4818
4818
|
if (!GLOBAL_CONFIG.CC_ENABLE_CANDLE_FETCH_MUTEX) {
|
|
@@ -4837,7 +4837,7 @@ class CandleUtils {
|
|
|
4837
4837
|
* @param source - Caller identifier for logging.
|
|
4838
4838
|
*/
|
|
4839
4839
|
this.spinLock = async (source) => {
|
|
4840
|
-
LOGGER_SERVICE$
|
|
4840
|
+
LOGGER_SERVICE$7.info(METHOD_NAME_SPIN_LOCK, {
|
|
4841
4841
|
source,
|
|
4842
4842
|
});
|
|
4843
4843
|
if (!GLOBAL_CONFIG.CC_ENABLE_CANDLE_FETCH_MUTEX) {
|
|
@@ -6347,7 +6347,7 @@ const validateCommonSignal = (signal) => {
|
|
|
6347
6347
|
}
|
|
6348
6348
|
// Кидаем ошибку если есть проблемы
|
|
6349
6349
|
if (errors.length > 0) {
|
|
6350
|
-
throw new Error(`Invalid signal for ${signal.position} position:\n${errors.join("\n")}`);
|
|
6350
|
+
throw new Error(`Invalid signal for ${signal.position} position (${signal.symbol || "empty symbol"}):\n${errors.join("\n")}`);
|
|
6351
6351
|
}
|
|
6352
6352
|
};
|
|
6353
6353
|
|
|
@@ -6400,7 +6400,7 @@ const validatePendingSignal = (signal, currentPrice) => {
|
|
|
6400
6400
|
}
|
|
6401
6401
|
}
|
|
6402
6402
|
if (errors.length > 0) {
|
|
6403
|
-
throw new Error(`Invalid signal for ${signal.position} position:\n${errors.join("\n")}`);
|
|
6403
|
+
throw new Error(`Invalid signal for ${signal.position} position (${signal.symbol || "empty symbol"}):\n${errors.join("\n")}`);
|
|
6404
6404
|
}
|
|
6405
6405
|
validateCommonSignal(signal);
|
|
6406
6406
|
// ЗАЩИТА ОТ МОМЕНТАЛЬНОГО ЗАКРЫТИЯ: проверяем что позиция не закроется сразу после открытия
|
|
@@ -6448,7 +6448,7 @@ const validatePendingSignal = (signal, currentPrice) => {
|
|
|
6448
6448
|
}
|
|
6449
6449
|
}
|
|
6450
6450
|
if (errors.length > 0) {
|
|
6451
|
-
throw new Error(`Invalid signal for ${signal.position} position:\n${errors.join("\n")}`);
|
|
6451
|
+
throw new Error(`Invalid signal for ${signal.position} position (${signal.symbol || "empty symbol"}):\n${errors.join("\n")}`);
|
|
6452
6452
|
}
|
|
6453
6453
|
};
|
|
6454
6454
|
|
|
@@ -6501,7 +6501,7 @@ const validateScheduledSignal = (signal, currentPrice) => {
|
|
|
6501
6501
|
}
|
|
6502
6502
|
}
|
|
6503
6503
|
if (errors.length > 0) {
|
|
6504
|
-
throw new Error(`Invalid signal for ${signal.position} position:\n${errors.join("\n")}`);
|
|
6504
|
+
throw new Error(`Invalid signal for ${signal.position} position (${signal.symbol || "empty symbol"}):\n${errors.join("\n")}`);
|
|
6505
6505
|
}
|
|
6506
6506
|
validateCommonSignal(signal);
|
|
6507
6507
|
// ЗАЩИТА ОТ МОМЕНТАЛЬНОГО ЗАКРЫТИЯ scheduled сигналов
|
|
@@ -6547,7 +6547,7 @@ const validateScheduledSignal = (signal, currentPrice) => {
|
|
|
6547
6547
|
// pendingAt === 0 is allowed for scheduled signals (set to SCHEDULED_SIGNAL_PENDING_MOCK until activation)
|
|
6548
6548
|
}
|
|
6549
6549
|
if (errors.length > 0) {
|
|
6550
|
-
throw new Error(`Invalid signal for ${signal.position} position:\n${errors.join("\n")}`);
|
|
6550
|
+
throw new Error(`Invalid signal for ${signal.position} position (${signal.symbol || "empty symbol"}):\n${errors.join("\n")}`);
|
|
6551
6551
|
}
|
|
6552
6552
|
};
|
|
6553
6553
|
|
|
@@ -6994,6 +6994,13 @@ const GET_SIGNAL_FN = trycatch(async (self) => {
|
|
|
6994
6994
|
if (!signal) {
|
|
6995
6995
|
return null;
|
|
6996
6996
|
}
|
|
6997
|
+
if (signal?.symbol && signal?.symbol !== self.params.execution.context.symbol) {
|
|
6998
|
+
throw new Error(`Symbol mismatch: expected ${self.params.execution.context.symbol}, got ${signal.symbol}`);
|
|
6999
|
+
}
|
|
7000
|
+
// Whipsaw protection: skip signal if its id matches the last accepted pending id
|
|
7001
|
+
if (signal.id && signal.id === self._lastPendingId) {
|
|
7002
|
+
return null;
|
|
7003
|
+
}
|
|
6997
7004
|
if (self._isStopped) {
|
|
6998
7005
|
return null;
|
|
6999
7006
|
}
|
|
@@ -7037,6 +7044,9 @@ const GET_SIGNAL_FN = trycatch(async (self) => {
|
|
|
7037
7044
|
}
|
|
7038
7045
|
// Валидируем сигнал перед возвратом
|
|
7039
7046
|
validatePendingSignal(signalRow, currentPrice);
|
|
7047
|
+
if (signal.id) {
|
|
7048
|
+
self._lastPendingId = signal.id;
|
|
7049
|
+
}
|
|
7040
7050
|
return signalRow;
|
|
7041
7051
|
}
|
|
7042
7052
|
// ОЖИДАНИЕ АКТИВАЦИИ: создаем scheduled signal (risk check при активации)
|
|
@@ -7063,6 +7073,9 @@ const GET_SIGNAL_FN = trycatch(async (self) => {
|
|
|
7063
7073
|
};
|
|
7064
7074
|
// Валидируем сигнал перед возвратом
|
|
7065
7075
|
validateScheduledSignal(scheduledSignalRow, currentPrice);
|
|
7076
|
+
if (signal.id) {
|
|
7077
|
+
self._lastPendingId = signal.id;
|
|
7078
|
+
}
|
|
7066
7079
|
return scheduledSignalRow;
|
|
7067
7080
|
}
|
|
7068
7081
|
const signalRow = {
|
|
@@ -7090,6 +7103,9 @@ const GET_SIGNAL_FN = trycatch(async (self) => {
|
|
|
7090
7103
|
}
|
|
7091
7104
|
// Валидируем сигнал перед возвратом
|
|
7092
7105
|
validatePendingSignal(signalRow, currentPrice);
|
|
7106
|
+
if (signal.id) {
|
|
7107
|
+
self._lastPendingId = signal.id;
|
|
7108
|
+
}
|
|
7093
7109
|
return signalRow;
|
|
7094
7110
|
}, {
|
|
7095
7111
|
defaultValue: null,
|
|
@@ -7119,6 +7135,13 @@ const WAIT_FOR_INIT_FN$4 = async (self) => {
|
|
|
7119
7135
|
if (self.params.execution.context.backtest) {
|
|
7120
7136
|
return;
|
|
7121
7137
|
}
|
|
7138
|
+
// Restore last pending signal id for whipsaw protection in GET_SIGNAL_FN
|
|
7139
|
+
{
|
|
7140
|
+
const recentSignal = await PersistRecentAdapter.readRecentData(self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName, self.params.method.context.frameName, false);
|
|
7141
|
+
if (recentSignal?.id) {
|
|
7142
|
+
self._lastPendingId = recentSignal.id;
|
|
7143
|
+
}
|
|
7144
|
+
}
|
|
7122
7145
|
// Restore pending signal
|
|
7123
7146
|
const pendingSignal = await PersistSignalAdapter.readSignalData(self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
|
|
7124
7147
|
if (pendingSignal) {
|
|
@@ -9259,6 +9282,7 @@ class ClientStrategy {
|
|
|
9259
9282
|
this._isStopped = false;
|
|
9260
9283
|
this._pendingSignal = null;
|
|
9261
9284
|
this._lastSignalTimestamp = null;
|
|
9285
|
+
this._lastPendingId = null;
|
|
9262
9286
|
this._scheduledSignal = null;
|
|
9263
9287
|
this._cancelledSignal = null;
|
|
9264
9288
|
this._closedSignal = null;
|
|
@@ -12048,7 +12072,7 @@ const RISK_METHOD_NAME_CHECK_SIGNAL_AND_RESERVE = "MergeRisk.checkSignalAndReser
|
|
|
12048
12072
|
const RISK_METHOD_NAME_ADD_SIGNAL = "MergeRisk.addSignal";
|
|
12049
12073
|
const RISK_METHOD_NAME_REMOVE_SIGNAL = "MergeRisk.removeSignal";
|
|
12050
12074
|
/** Logger service injected as DI singleton */
|
|
12051
|
-
const LOGGER_SERVICE$
|
|
12075
|
+
const LOGGER_SERVICE$6 = new LoggerService();
|
|
12052
12076
|
/**
|
|
12053
12077
|
* Composite risk management class that combines multiple risk profiles.
|
|
12054
12078
|
*
|
|
@@ -12104,7 +12128,7 @@ class MergeRisk {
|
|
|
12104
12128
|
* @returns Promise resolving to true if all risks approve, false if any risk rejects
|
|
12105
12129
|
*/
|
|
12106
12130
|
async checkSignal(params, options = {}) {
|
|
12107
|
-
LOGGER_SERVICE$
|
|
12131
|
+
LOGGER_SERVICE$6.info(RISK_METHOD_NAME_CHECK_SIGNAL, {
|
|
12108
12132
|
params,
|
|
12109
12133
|
});
|
|
12110
12134
|
for (const [riskName, risk] of Object.entries(this._riskMap)) {
|
|
@@ -12134,7 +12158,7 @@ class MergeRisk {
|
|
|
12134
12158
|
* @returns Promise resolving to true if all risks approve (and reserved), false if any risk rejects
|
|
12135
12159
|
*/
|
|
12136
12160
|
async checkSignalAndReserve(params) {
|
|
12137
|
-
LOGGER_SERVICE$
|
|
12161
|
+
LOGGER_SERVICE$6.info(RISK_METHOD_NAME_CHECK_SIGNAL_AND_RESERVE, {
|
|
12138
12162
|
params,
|
|
12139
12163
|
});
|
|
12140
12164
|
for (const [riskName, risk] of Object.entries(this._riskMap)) {
|
|
@@ -12158,7 +12182,7 @@ class MergeRisk {
|
|
|
12158
12182
|
* @returns Promise that resolves when all risks have registered the signal
|
|
12159
12183
|
*/
|
|
12160
12184
|
async addSignal(symbol, context, positionData) {
|
|
12161
|
-
LOGGER_SERVICE$
|
|
12185
|
+
LOGGER_SERVICE$6.info(RISK_METHOD_NAME_ADD_SIGNAL, {
|
|
12162
12186
|
symbol,
|
|
12163
12187
|
context,
|
|
12164
12188
|
});
|
|
@@ -12175,7 +12199,7 @@ class MergeRisk {
|
|
|
12175
12199
|
* @returns Promise that resolves when all risks have removed the signal
|
|
12176
12200
|
*/
|
|
12177
12201
|
async removeSignal(symbol, context) {
|
|
12178
|
-
LOGGER_SERVICE$
|
|
12202
|
+
LOGGER_SERVICE$6.info(RISK_METHOD_NAME_REMOVE_SIGNAL, {
|
|
12179
12203
|
symbol,
|
|
12180
12204
|
context,
|
|
12181
12205
|
});
|
|
@@ -14968,7 +14992,7 @@ class RiskConnectionService {
|
|
|
14968
14992
|
}
|
|
14969
14993
|
|
|
14970
14994
|
/** Logger service injected as DI singleton */
|
|
14971
|
-
const LOGGER_SERVICE$
|
|
14995
|
+
const LOGGER_SERVICE$5 = new LoggerService();
|
|
14972
14996
|
/**
|
|
14973
14997
|
* Wrapper to call init method with error capture.
|
|
14974
14998
|
*/
|
|
@@ -14983,7 +15007,7 @@ const CALL_INIT_FN = trycatch(async (self) => {
|
|
|
14983
15007
|
error: errorData(error),
|
|
14984
15008
|
message: getErrorMessage(error),
|
|
14985
15009
|
};
|
|
14986
|
-
LOGGER_SERVICE$
|
|
15010
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
14987
15011
|
console.warn(message, payload);
|
|
14988
15012
|
errorEmitter.next(error);
|
|
14989
15013
|
},
|
|
@@ -15003,7 +15027,7 @@ const CALL_SIGNAL_FN = trycatch(async (event, self) => {
|
|
|
15003
15027
|
error: errorData(error),
|
|
15004
15028
|
message: getErrorMessage(error),
|
|
15005
15029
|
};
|
|
15006
|
-
LOGGER_SERVICE$
|
|
15030
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
15007
15031
|
console.warn(message, payload);
|
|
15008
15032
|
errorEmitter.next(error);
|
|
15009
15033
|
},
|
|
@@ -15023,7 +15047,7 @@ const CALL_SIGNAL_LIVE_FN = trycatch(async (event, self) => {
|
|
|
15023
15047
|
error: errorData(error),
|
|
15024
15048
|
message: getErrorMessage(error),
|
|
15025
15049
|
};
|
|
15026
|
-
LOGGER_SERVICE$
|
|
15050
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
15027
15051
|
console.warn(message, payload);
|
|
15028
15052
|
errorEmitter.next(error);
|
|
15029
15053
|
},
|
|
@@ -15043,7 +15067,7 @@ const CALL_SIGNAL_BACKTEST_FN = trycatch(async (event, self) => {
|
|
|
15043
15067
|
error: errorData(error),
|
|
15044
15068
|
message: getErrorMessage(error),
|
|
15045
15069
|
};
|
|
15046
|
-
LOGGER_SERVICE$
|
|
15070
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
15047
15071
|
console.warn(message, payload);
|
|
15048
15072
|
errorEmitter.next(error);
|
|
15049
15073
|
},
|
|
@@ -15071,7 +15095,7 @@ const CALL_BREAKEVEN_AVAILABLE_FN = trycatch(async (event, self) => {
|
|
|
15071
15095
|
error: errorData(error),
|
|
15072
15096
|
message: getErrorMessage(error),
|
|
15073
15097
|
};
|
|
15074
|
-
LOGGER_SERVICE$
|
|
15098
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
15075
15099
|
console.warn(message, payload);
|
|
15076
15100
|
errorEmitter.next(error);
|
|
15077
15101
|
},
|
|
@@ -15099,7 +15123,7 @@ const CALL_PARTIAL_PROFIT_AVAILABLE_FN = trycatch(async (event, self) => {
|
|
|
15099
15123
|
error: errorData(error),
|
|
15100
15124
|
message: getErrorMessage(error),
|
|
15101
15125
|
};
|
|
15102
|
-
LOGGER_SERVICE$
|
|
15126
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
15103
15127
|
console.warn(message, payload);
|
|
15104
15128
|
errorEmitter.next(error);
|
|
15105
15129
|
},
|
|
@@ -15127,7 +15151,7 @@ const CALL_PARTIAL_LOSS_AVAILABLE_FN = trycatch(async (event, self) => {
|
|
|
15127
15151
|
error: errorData(error),
|
|
15128
15152
|
message: getErrorMessage(error),
|
|
15129
15153
|
};
|
|
15130
|
-
LOGGER_SERVICE$
|
|
15154
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
15131
15155
|
console.warn(message, payload);
|
|
15132
15156
|
errorEmitter.next(error);
|
|
15133
15157
|
},
|
|
@@ -15155,7 +15179,7 @@ const CALL_PING_SCHEDULED_FN = trycatch(async (event, self) => {
|
|
|
15155
15179
|
error: errorData(error),
|
|
15156
15180
|
message: getErrorMessage(error),
|
|
15157
15181
|
};
|
|
15158
|
-
LOGGER_SERVICE$
|
|
15182
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
15159
15183
|
console.warn(message, payload);
|
|
15160
15184
|
errorEmitter.next(error);
|
|
15161
15185
|
},
|
|
@@ -15183,7 +15207,7 @@ const CALL_PING_IDLE_FN = trycatch(async (event, self) => {
|
|
|
15183
15207
|
error: errorData(error),
|
|
15184
15208
|
message: getErrorMessage(error),
|
|
15185
15209
|
};
|
|
15186
|
-
LOGGER_SERVICE$
|
|
15210
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
15187
15211
|
console.warn(message, payload);
|
|
15188
15212
|
errorEmitter.next(error);
|
|
15189
15213
|
},
|
|
@@ -15211,7 +15235,7 @@ const CALL_PING_ACTIVE_FN = trycatch(async (event, self) => {
|
|
|
15211
15235
|
error: errorData(error),
|
|
15212
15236
|
message: getErrorMessage(error),
|
|
15213
15237
|
};
|
|
15214
|
-
LOGGER_SERVICE$
|
|
15238
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
15215
15239
|
console.warn(message, payload);
|
|
15216
15240
|
errorEmitter.next(error);
|
|
15217
15241
|
},
|
|
@@ -15231,7 +15255,7 @@ const CALL_RISK_REJECTION_FN = trycatch(async (event, self) => {
|
|
|
15231
15255
|
error: errorData(error),
|
|
15232
15256
|
message: getErrorMessage(error),
|
|
15233
15257
|
};
|
|
15234
|
-
LOGGER_SERVICE$
|
|
15258
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
15235
15259
|
console.warn(message, payload);
|
|
15236
15260
|
errorEmitter.next(error);
|
|
15237
15261
|
},
|
|
@@ -15251,7 +15275,7 @@ const CALL_DISPOSE_FN = trycatch(async (self) => {
|
|
|
15251
15275
|
error: errorData(error),
|
|
15252
15276
|
message: getErrorMessage(error),
|
|
15253
15277
|
};
|
|
15254
|
-
LOGGER_SERVICE$
|
|
15278
|
+
LOGGER_SERVICE$5.warn(message, payload);
|
|
15255
15279
|
console.warn(message, payload);
|
|
15256
15280
|
errorEmitter.next(error);
|
|
15257
15281
|
},
|
|
@@ -23115,7 +23139,7 @@ const REPORT_UTILS_METHOD_NAME_USE_DUMMY$1 = "ReportUtils.useDummy";
|
|
|
23115
23139
|
const REPORT_UTILS_METHOD_NAME_USE_JSONL$1 = "ReportUtils.useJsonl";
|
|
23116
23140
|
const REPORT_UTILS_METHOD_NAME_CLEAR$1 = "ReportUtils.clear";
|
|
23117
23141
|
/** Logger service injected as DI singleton */
|
|
23118
|
-
const LOGGER_SERVICE$
|
|
23142
|
+
const LOGGER_SERVICE$4 = new LoggerService();
|
|
23119
23143
|
/** Symbol key for the singleshot waitForInit function on MarkdownFileBase instances. */
|
|
23120
23144
|
const WAIT_FOR_INIT_SYMBOL$1 = Symbol("wait-for-init");
|
|
23121
23145
|
/** Symbol key for the timeout-protected write function on MarkdownFileBase instances. */
|
|
@@ -23196,7 +23220,7 @@ class MarkdownFileBase {
|
|
|
23196
23220
|
* @throws Error if stream not initialized or write timeout exceeded
|
|
23197
23221
|
*/
|
|
23198
23222
|
async dump(data, options) {
|
|
23199
|
-
LOGGER_SERVICE$
|
|
23223
|
+
LOGGER_SERVICE$4.debug(MARKDOWN_METHOD_NAME_FILE_DUMP, {
|
|
23200
23224
|
markdownName: this.markdownName,
|
|
23201
23225
|
options,
|
|
23202
23226
|
});
|
|
@@ -23276,7 +23300,7 @@ class MarkdownFolderBase {
|
|
|
23276
23300
|
* @throws Error if directory creation or file write fails
|
|
23277
23301
|
*/
|
|
23278
23302
|
async dump(content, options) {
|
|
23279
|
-
LOGGER_SERVICE$
|
|
23303
|
+
LOGGER_SERVICE$4.debug(MARKDOWN_METHOD_NAME_FOLDER_DUMP, {
|
|
23280
23304
|
markdownName: this.markdownName,
|
|
23281
23305
|
options,
|
|
23282
23306
|
});
|
|
@@ -23341,7 +23365,7 @@ class MarkdownWriterAdapter {
|
|
|
23341
23365
|
* @param Ctor - Constructor for markdown storage adapter
|
|
23342
23366
|
*/
|
|
23343
23367
|
useMarkdownAdapter(Ctor) {
|
|
23344
|
-
LOGGER_SERVICE$
|
|
23368
|
+
LOGGER_SERVICE$4.info(MARKDOWN_METHOD_NAME_USE_ADAPTER$1);
|
|
23345
23369
|
this.MarkdownFactory = Ctor;
|
|
23346
23370
|
}
|
|
23347
23371
|
/**
|
|
@@ -23355,7 +23379,7 @@ class MarkdownWriterAdapter {
|
|
|
23355
23379
|
* @throws Error if write fails or storage initialization fails
|
|
23356
23380
|
*/
|
|
23357
23381
|
async writeData(markdownName, content, options) {
|
|
23358
|
-
LOGGER_SERVICE$
|
|
23382
|
+
LOGGER_SERVICE$4.debug(MARKDOWN_METHOD_NAME_WRITE_DATA, {
|
|
23359
23383
|
markdownName,
|
|
23360
23384
|
options,
|
|
23361
23385
|
});
|
|
@@ -23369,7 +23393,7 @@ class MarkdownWriterAdapter {
|
|
|
23369
23393
|
* Each report is written as a separate .md file.
|
|
23370
23394
|
*/
|
|
23371
23395
|
useMd() {
|
|
23372
|
-
LOGGER_SERVICE$
|
|
23396
|
+
LOGGER_SERVICE$4.debug(MARKDOWN_METHOD_NAME_USE_MD$1);
|
|
23373
23397
|
this.useMarkdownAdapter(MarkdownFolderBase);
|
|
23374
23398
|
}
|
|
23375
23399
|
/**
|
|
@@ -23377,7 +23401,7 @@ class MarkdownWriterAdapter {
|
|
|
23377
23401
|
* All reports are appended to a single .jsonl file per markdown type.
|
|
23378
23402
|
*/
|
|
23379
23403
|
useJsonl() {
|
|
23380
|
-
LOGGER_SERVICE$
|
|
23404
|
+
LOGGER_SERVICE$4.debug(MARKDOWN_METHOD_NAME_USE_JSONL$1);
|
|
23381
23405
|
this.useMarkdownAdapter(MarkdownFileBase);
|
|
23382
23406
|
}
|
|
23383
23407
|
/**
|
|
@@ -23386,7 +23410,7 @@ class MarkdownWriterAdapter {
|
|
|
23386
23410
|
* so new storage instances are created with the updated base path.
|
|
23387
23411
|
*/
|
|
23388
23412
|
clear() {
|
|
23389
|
-
LOGGER_SERVICE$
|
|
23413
|
+
LOGGER_SERVICE$4.log(MARKDOWN_METHOD_NAME_CLEAR$1);
|
|
23390
23414
|
this.getMarkdownStorage.clear();
|
|
23391
23415
|
}
|
|
23392
23416
|
/**
|
|
@@ -23394,7 +23418,7 @@ class MarkdownWriterAdapter {
|
|
|
23394
23418
|
* All future markdown writes will be no-ops.
|
|
23395
23419
|
*/
|
|
23396
23420
|
useDummy() {
|
|
23397
|
-
LOGGER_SERVICE$
|
|
23421
|
+
LOGGER_SERVICE$4.debug(MARKDOWN_METHOD_NAME_USE_DUMMY$1);
|
|
23398
23422
|
this.useMarkdownAdapter(MarkdownDummy);
|
|
23399
23423
|
}
|
|
23400
23424
|
}
|
|
@@ -23455,7 +23479,7 @@ class ReportBase {
|
|
|
23455
23479
|
});
|
|
23456
23480
|
}
|
|
23457
23481
|
}, 15000));
|
|
23458
|
-
LOGGER_SERVICE$
|
|
23482
|
+
LOGGER_SERVICE$4.debug(REPORT_BASE_METHOD_NAME_CTOR, {
|
|
23459
23483
|
reportName: this.reportName,
|
|
23460
23484
|
baseDir,
|
|
23461
23485
|
});
|
|
@@ -23469,7 +23493,7 @@ class ReportBase {
|
|
|
23469
23493
|
* @returns Promise that resolves when initialization is complete
|
|
23470
23494
|
*/
|
|
23471
23495
|
async waitForInit(initial) {
|
|
23472
|
-
LOGGER_SERVICE$
|
|
23496
|
+
LOGGER_SERVICE$4.debug(REPORT_BASE_METHOD_NAME_WAIT_FOR_INIT, {
|
|
23473
23497
|
reportName: this.reportName,
|
|
23474
23498
|
initial,
|
|
23475
23499
|
});
|
|
@@ -23488,7 +23512,7 @@ class ReportBase {
|
|
|
23488
23512
|
* @throws Error if stream not initialized or write timeout exceeded
|
|
23489
23513
|
*/
|
|
23490
23514
|
async write(data, options) {
|
|
23491
|
-
LOGGER_SERVICE$
|
|
23515
|
+
LOGGER_SERVICE$4.debug(REPORT_BASE_METHOD_NAME_WRITE, {
|
|
23492
23516
|
reportName: this.reportName,
|
|
23493
23517
|
options,
|
|
23494
23518
|
});
|
|
@@ -23585,7 +23609,7 @@ class ReportWriterAdapter {
|
|
|
23585
23609
|
* @internal - Automatically called by report services, not for direct use
|
|
23586
23610
|
*/
|
|
23587
23611
|
this.writeData = async (reportName, data, options) => {
|
|
23588
|
-
LOGGER_SERVICE$
|
|
23612
|
+
LOGGER_SERVICE$4.info(REPORT_UTILS_METHOD_NAME_WRITE_DATA, {
|
|
23589
23613
|
reportName,
|
|
23590
23614
|
options,
|
|
23591
23615
|
});
|
|
@@ -23602,7 +23626,7 @@ class ReportWriterAdapter {
|
|
|
23602
23626
|
* @param Ctor - Constructor for report storage adapter
|
|
23603
23627
|
*/
|
|
23604
23628
|
useReportAdapter(Ctor) {
|
|
23605
|
-
LOGGER_SERVICE$
|
|
23629
|
+
LOGGER_SERVICE$4.info(REPORT_UTILS_METHOD_NAME_USE_REPORT_ADAPTER$1);
|
|
23606
23630
|
this.ReportFactory = Ctor;
|
|
23607
23631
|
}
|
|
23608
23632
|
/**
|
|
@@ -23611,7 +23635,7 @@ class ReportWriterAdapter {
|
|
|
23611
23635
|
* so new storage instances are created with the updated base path.
|
|
23612
23636
|
*/
|
|
23613
23637
|
clear() {
|
|
23614
|
-
LOGGER_SERVICE$
|
|
23638
|
+
LOGGER_SERVICE$4.log(REPORT_UTILS_METHOD_NAME_CLEAR$1);
|
|
23615
23639
|
this.getReportStorage.clear();
|
|
23616
23640
|
}
|
|
23617
23641
|
/**
|
|
@@ -23619,7 +23643,7 @@ class ReportWriterAdapter {
|
|
|
23619
23643
|
* All future report writes will be no-ops.
|
|
23620
23644
|
*/
|
|
23621
23645
|
useDummy() {
|
|
23622
|
-
LOGGER_SERVICE$
|
|
23646
|
+
LOGGER_SERVICE$4.log(REPORT_UTILS_METHOD_NAME_USE_DUMMY$1);
|
|
23623
23647
|
this.useReportAdapter(ReportDummy);
|
|
23624
23648
|
}
|
|
23625
23649
|
/**
|
|
@@ -23627,7 +23651,7 @@ class ReportWriterAdapter {
|
|
|
23627
23651
|
* All future report writes will use JSONL storage.
|
|
23628
23652
|
*/
|
|
23629
23653
|
useJsonl() {
|
|
23630
|
-
LOGGER_SERVICE$
|
|
23654
|
+
LOGGER_SERVICE$4.log(REPORT_UTILS_METHOD_NAME_USE_JSONL$1);
|
|
23631
23655
|
this.useReportAdapter(ReportBase);
|
|
23632
23656
|
}
|
|
23633
23657
|
}
|
|
@@ -53928,7 +53952,7 @@ const REPORT_UTILS_METHOD_NAME_USE_DUMMY = "ReportUtils.useDummy";
|
|
|
53928
53952
|
const REPORT_UTILS_METHOD_NAME_USE_JSONL = "ReportUtils.useJsonl";
|
|
53929
53953
|
const REPORT_UTILS_METHOD_NAME_CLEAR = "ReportUtils.clear";
|
|
53930
53954
|
/** Logger service injected as DI singleton */
|
|
53931
|
-
const LOGGER_SERVICE$
|
|
53955
|
+
const LOGGER_SERVICE$3 = new LoggerService();
|
|
53932
53956
|
/**
|
|
53933
53957
|
* Default configuration that enables all report services.
|
|
53934
53958
|
* Used when no specific configuration is provided to enable().
|
|
@@ -53985,7 +54009,7 @@ class ReportUtils {
|
|
|
53985
54009
|
* @returns Cleanup function that unsubscribes from all enabled services
|
|
53986
54010
|
*/
|
|
53987
54011
|
this.enable = singleshot(({ backtest: bt = false, breakeven = false, heat = false, live = false, partial = false, performance = false, risk = false, schedule = false, walker = false, strategy = false, sync = false, highest_profit = false, max_drawdown = false, } = WILDCARD_TARGET$2) => {
|
|
53988
|
-
LOGGER_SERVICE$
|
|
54012
|
+
LOGGER_SERVICE$3.debug(REPORT_UTILS_METHOD_NAME_ENABLE, {
|
|
53989
54013
|
backtest: bt,
|
|
53990
54014
|
breakeven,
|
|
53991
54015
|
heat,
|
|
@@ -54080,7 +54104,7 @@ class ReportUtils {
|
|
|
54080
54104
|
* ```
|
|
54081
54105
|
*/
|
|
54082
54106
|
this.disable = ({ backtest: bt = false, breakeven = false, heat = false, live = false, partial = false, performance = false, risk = false, schedule = false, walker = false, strategy = false, sync = false, highest_profit = false, max_drawdown = false, } = WILDCARD_TARGET$2) => {
|
|
54083
|
-
LOGGER_SERVICE$
|
|
54107
|
+
LOGGER_SERVICE$3.debug(REPORT_UTILS_METHOD_NAME_DISABLE, {
|
|
54084
54108
|
backtest: bt,
|
|
54085
54109
|
breakeven,
|
|
54086
54110
|
heat,
|
|
@@ -54160,7 +54184,7 @@ class ReportAdapter extends ReportUtils {
|
|
|
54160
54184
|
* @param Ctor - Constructor for report storage adapter
|
|
54161
54185
|
*/
|
|
54162
54186
|
useReportAdapter(Ctor) {
|
|
54163
|
-
LOGGER_SERVICE$
|
|
54187
|
+
LOGGER_SERVICE$3.info(REPORT_UTILS_METHOD_NAME_USE_REPORT_ADAPTER);
|
|
54164
54188
|
ReportWriter.useReportAdapter(Ctor);
|
|
54165
54189
|
}
|
|
54166
54190
|
/**
|
|
@@ -54169,7 +54193,7 @@ class ReportAdapter extends ReportUtils {
|
|
|
54169
54193
|
* so new storage instances are created with the updated base path.
|
|
54170
54194
|
*/
|
|
54171
54195
|
clear() {
|
|
54172
|
-
LOGGER_SERVICE$
|
|
54196
|
+
LOGGER_SERVICE$3.log(REPORT_UTILS_METHOD_NAME_CLEAR);
|
|
54173
54197
|
ReportWriter.clear();
|
|
54174
54198
|
}
|
|
54175
54199
|
/**
|
|
@@ -54177,7 +54201,7 @@ class ReportAdapter extends ReportUtils {
|
|
|
54177
54201
|
* All future report writes will be no-ops.
|
|
54178
54202
|
*/
|
|
54179
54203
|
useDummy() {
|
|
54180
|
-
LOGGER_SERVICE$
|
|
54204
|
+
LOGGER_SERVICE$3.log(REPORT_UTILS_METHOD_NAME_USE_DUMMY);
|
|
54181
54205
|
ReportWriter.useDummy();
|
|
54182
54206
|
}
|
|
54183
54207
|
/**
|
|
@@ -54185,7 +54209,7 @@ class ReportAdapter extends ReportUtils {
|
|
|
54185
54209
|
* All future report writes will use JSONL storage.
|
|
54186
54210
|
*/
|
|
54187
54211
|
useJsonl() {
|
|
54188
|
-
LOGGER_SERVICE$
|
|
54212
|
+
LOGGER_SERVICE$3.log(REPORT_UTILS_METHOD_NAME_USE_JSONL);
|
|
54189
54213
|
ReportWriter.useJsonl();
|
|
54190
54214
|
}
|
|
54191
54215
|
}
|
|
@@ -54203,7 +54227,7 @@ const MARKDOWN_METHOD_NAME_USE_JSONL = "MarkdownAdapter.useJsonl";
|
|
|
54203
54227
|
const MARKDOWN_METHOD_NAME_USE_DUMMY = "MarkdownAdapter.useDummy";
|
|
54204
54228
|
const MARKDOWN_METHOD_NAME_CLEAR = "MarkdownAdapter.clear";
|
|
54205
54229
|
/** Logger service injected as DI singleton */
|
|
54206
|
-
const LOGGER_SERVICE$
|
|
54230
|
+
const LOGGER_SERVICE$2 = new LoggerService();
|
|
54207
54231
|
/**
|
|
54208
54232
|
* Default configuration that enables all markdown services.
|
|
54209
54233
|
* Used when no specific configuration is provided to `enable()`.
|
|
@@ -54260,7 +54284,7 @@ class MarkdownUtils {
|
|
|
54260
54284
|
* @returns Cleanup function that unsubscribes from all enabled services
|
|
54261
54285
|
*/
|
|
54262
54286
|
this.enable = singleshot(({ backtest: bt = false, breakeven = false, heat = false, live = false, partial = false, performance = false, strategy = false, risk = false, schedule = false, walker = false, sync = false, highest_profit = false, max_drawdown = false, } = WILDCARD_TARGET$1) => {
|
|
54263
|
-
LOGGER_SERVICE$
|
|
54287
|
+
LOGGER_SERVICE$2.debug(MARKDOWN_METHOD_NAME_ENABLE, {
|
|
54264
54288
|
backtest: bt,
|
|
54265
54289
|
breakeven,
|
|
54266
54290
|
heat,
|
|
@@ -54357,7 +54381,7 @@ class MarkdownUtils {
|
|
|
54357
54381
|
* ```
|
|
54358
54382
|
*/
|
|
54359
54383
|
this.disable = ({ backtest: bt = false, breakeven = false, heat = false, live = false, partial = false, performance = false, risk = false, strategy = false, schedule = false, walker = false, sync = false, highest_profit = false, max_drawdown = false, } = WILDCARD_TARGET$1) => {
|
|
54360
|
-
LOGGER_SERVICE$
|
|
54384
|
+
LOGGER_SERVICE$2.debug(MARKDOWN_METHOD_NAME_DISABLE, {
|
|
54361
54385
|
backtest: bt,
|
|
54362
54386
|
breakeven,
|
|
54363
54387
|
heat,
|
|
@@ -54443,7 +54467,7 @@ class MarkdownUtils {
|
|
|
54443
54467
|
* @param config.max_drawdown - Clear max drawdown report data
|
|
54444
54468
|
*/
|
|
54445
54469
|
this.clear = ({ backtest: bt = false, breakeven = false, heat = false, live = false, partial = false, performance = false, risk = false, strategy = false, schedule = false, walker = false, sync = false, highest_profit = false, max_drawdown = false, } = WILDCARD_TARGET$1) => {
|
|
54446
|
-
LOGGER_SERVICE$
|
|
54470
|
+
LOGGER_SERVICE$2.debug(MARKDOWN_METHOD_NAME_CLEAR, {
|
|
54447
54471
|
backtest: bt,
|
|
54448
54472
|
breakeven,
|
|
54449
54473
|
heat,
|
|
@@ -54518,7 +54542,7 @@ class MarkdownAdapter extends MarkdownUtils {
|
|
|
54518
54542
|
* @param Ctor - Constructor for markdown storage adapter
|
|
54519
54543
|
*/
|
|
54520
54544
|
useMarkdownAdapter(Ctor) {
|
|
54521
|
-
LOGGER_SERVICE$
|
|
54545
|
+
LOGGER_SERVICE$2.info(MARKDOWN_METHOD_NAME_USE_ADAPTER);
|
|
54522
54546
|
return MarkdownWriter.useMarkdownAdapter(Ctor);
|
|
54523
54547
|
}
|
|
54524
54548
|
/**
|
|
@@ -54527,7 +54551,7 @@ class MarkdownAdapter extends MarkdownUtils {
|
|
|
54527
54551
|
* Each dump creates a separate .md file.
|
|
54528
54552
|
*/
|
|
54529
54553
|
useMd() {
|
|
54530
|
-
LOGGER_SERVICE$
|
|
54554
|
+
LOGGER_SERVICE$2.debug(MARKDOWN_METHOD_NAME_USE_MD);
|
|
54531
54555
|
MarkdownWriter.useMd();
|
|
54532
54556
|
}
|
|
54533
54557
|
/**
|
|
@@ -54536,7 +54560,7 @@ class MarkdownAdapter extends MarkdownUtils {
|
|
|
54536
54560
|
* All dumps append to a single .jsonl file per markdown type.
|
|
54537
54561
|
*/
|
|
54538
54562
|
useJsonl() {
|
|
54539
|
-
LOGGER_SERVICE$
|
|
54563
|
+
LOGGER_SERVICE$2.debug(MARKDOWN_METHOD_NAME_USE_JSONL);
|
|
54540
54564
|
MarkdownWriter.useJsonl();
|
|
54541
54565
|
}
|
|
54542
54566
|
/**
|
|
@@ -54544,7 +54568,7 @@ class MarkdownAdapter extends MarkdownUtils {
|
|
|
54544
54568
|
* All future markdown writes will be no-ops.
|
|
54545
54569
|
*/
|
|
54546
54570
|
useDummy() {
|
|
54547
|
-
LOGGER_SERVICE$
|
|
54571
|
+
LOGGER_SERVICE$2.debug(MARKDOWN_METHOD_NAME_USE_DUMMY);
|
|
54548
54572
|
MarkdownWriter.useDummy();
|
|
54549
54573
|
}
|
|
54550
54574
|
}
|
|
@@ -63233,6 +63257,470 @@ class IntervalUtils {
|
|
|
63233
63257
|
*/
|
|
63234
63258
|
const Interval = new IntervalUtils();
|
|
63235
63259
|
|
|
63260
|
+
const CRON_METHOD_NAME_REGISTER = "CronUtils.register";
|
|
63261
|
+
const CRON_METHOD_NAME_UNREGISTER = "CronUtils.unregister";
|
|
63262
|
+
const CRON_METHOD_NAME_CLEAR = "CronUtils.clear";
|
|
63263
|
+
const CRON_METHOD_NAME_TICK = "CronUtils._tick";
|
|
63264
|
+
const CRON_METHOD_NAME_ENABLE = "CronUtils.enable";
|
|
63265
|
+
const CRON_METHOD_NAME_DISABLE = "CronUtils.disable";
|
|
63266
|
+
/**
|
|
63267
|
+
* Local logger instance.
|
|
63268
|
+
*
|
|
63269
|
+
* Created directly rather than resolved from the DI container so that
|
|
63270
|
+
* `CronUtils` has no compile-time dependency on the rest of the framework
|
|
63271
|
+
* being bootstrapped — `Cron` can be imported and used in isolation.
|
|
63272
|
+
*/
|
|
63273
|
+
const LOGGER_SERVICE$1 = new LoggerService();
|
|
63274
|
+
/**
|
|
63275
|
+
* Utility class for registering periodic tasks that fire on candle-interval
|
|
63276
|
+
* boundaries of the virtual time produced by parallel backtests.
|
|
63277
|
+
*
|
|
63278
|
+
* Exported as singleton instance `Cron` for convenient usage.
|
|
63279
|
+
*
|
|
63280
|
+
* Key property — **singleshot coordination across parallel backtests**:
|
|
63281
|
+
* when several `Backtest.background(symbol, ...)` runs hit the same aligned
|
|
63282
|
+
* boundary concurrently, the handler is invoked exactly once. Every parallel
|
|
63283
|
+
* `tick` for that boundary awaits the same in-flight promise and is released
|
|
63284
|
+
* together when the promise settles. After settlement the slot is cleared and
|
|
63285
|
+
* the next boundary produces a fresh promise.
|
|
63286
|
+
*
|
|
63287
|
+
* Typical wiring:
|
|
63288
|
+
*
|
|
63289
|
+
* @example
|
|
63290
|
+
* ```typescript
|
|
63291
|
+
* import { Cron, Backtest } from "backtest-kit";
|
|
63292
|
+
*
|
|
63293
|
+
* Cron.register({
|
|
63294
|
+
* name: "tg-signal-parser",
|
|
63295
|
+
* interval: "1h",
|
|
63296
|
+
* handler: async (symbol, when, backtest) => {
|
|
63297
|
+
* await parseTelegramSignalsToMongo(when);
|
|
63298
|
+
* },
|
|
63299
|
+
* });
|
|
63300
|
+
*
|
|
63301
|
+
* // Subscribe Cron to the engine's lifecycle subjects (beforeStart,
|
|
63302
|
+
* // idlePing, activePing, schedulePing) once at startup. After this every
|
|
63303
|
+
* // strategy tick is forwarded into Cron automatically.
|
|
63304
|
+
* Cron.enable();
|
|
63305
|
+
*
|
|
63306
|
+
* for (const symbol of ["BTCUSDT", "ETHUSDT", "SOLUSDT", "BNBUSDT", "TRXUSDT"]) {
|
|
63307
|
+
* Backtest.background(symbol, { strategyName, exchangeName, frameName });
|
|
63308
|
+
* }
|
|
63309
|
+
*
|
|
63310
|
+
* // On shutdown:
|
|
63311
|
+
* // Cron.disable();
|
|
63312
|
+
* ```
|
|
63313
|
+
*/
|
|
63314
|
+
class CronUtils {
|
|
63315
|
+
constructor() {
|
|
63316
|
+
/**
|
|
63317
|
+
* Registered entries by `name`.
|
|
63318
|
+
*
|
|
63319
|
+
* Each record carries a monotonically increasing `generation` counter that
|
|
63320
|
+
* is bumped on every `register(entry)` call for the same name. The
|
|
63321
|
+
* generation participates in `firedKey` so writes from a still-in-flight
|
|
63322
|
+
* handler of a previous incarnation cannot poison `_firedOnce` for the
|
|
63323
|
+
* current incarnation — their key has a different generation suffix and
|
|
63324
|
+
* is simply ignored on lookup.
|
|
63325
|
+
*/
|
|
63326
|
+
this._entries = new Map();
|
|
63327
|
+
/** Monotonic counter used to mint new entry generations on `register`. */
|
|
63328
|
+
this._generationCounter = 0;
|
|
63329
|
+
/**
|
|
63330
|
+
* In-flight handler slots.
|
|
63331
|
+
*
|
|
63332
|
+
* Slot key shape (always includes the generation suffix `:g${generation}`;
|
|
63333
|
+
* the `:${symbol}` scope is present only in fan-out mode):
|
|
63334
|
+
* - Periodic global: `${name}:${alignedMs}:g${generation}`.
|
|
63335
|
+
* - Periodic fan-out: `${name}:${alignedMs}:${symbol}:g${generation}`.
|
|
63336
|
+
* - Fire-once global: `${name}:once:g${generation}`.
|
|
63337
|
+
* - Fire-once fan-out: `${name}:once:${symbol}:g${generation}`.
|
|
63338
|
+
*
|
|
63339
|
+
* Value is the shared in-flight handler promise. Every parallel `tick` for
|
|
63340
|
+
* the same slot key awaits this exact promise (mutex semantics) and is
|
|
63341
|
+
* released together when it settles. `_inFlight` is owned exclusively by
|
|
63342
|
+
* `_runEntry` — `clear()` does **not** touch it, so the singleshot promise
|
|
63343
|
+
* survives concurrent `clear` calls and continues to coordinate parallel
|
|
63344
|
+
* ticks until it settles.
|
|
63345
|
+
*/
|
|
63346
|
+
this._inFlight = new Map();
|
|
63347
|
+
/**
|
|
63348
|
+
* Keys of fire-once entries whose handler has already settled successfully.
|
|
63349
|
+
*
|
|
63350
|
+
* Key shape (always includes the entry generation suffix `:g${generation}`):
|
|
63351
|
+
* - Global fire-once: `${name}:g${generation}`.
|
|
63352
|
+
* - Fan-out fire-once: `${name}:${symbol}:g${generation}` — one entry per
|
|
63353
|
+
* whitelisted symbol.
|
|
63354
|
+
*
|
|
63355
|
+
* The generation suffix isolates incarnations of the same `name`: writes
|
|
63356
|
+
* landing from a still-in-flight handler of a previous `register()` carry
|
|
63357
|
+
* the old generation and are never matched by the new entry's lookup.
|
|
63358
|
+
* Stale entries are pruned by `_clearFiredOnceFor` on `register`/`unregister`
|
|
63359
|
+
* and wiped by `clear()`.
|
|
63360
|
+
*
|
|
63361
|
+
* Looked up by `_tick` to decide whether to skip; written by `_runEntry`
|
|
63362
|
+
* on successful settle.
|
|
63363
|
+
*/
|
|
63364
|
+
this._firedOnce = new Set();
|
|
63365
|
+
/**
|
|
63366
|
+
* Register a periodic cron entry.
|
|
63367
|
+
*
|
|
63368
|
+
* Idempotent on `name`: re-registering the same name replaces the previous
|
|
63369
|
+
* entry (interval/symbols/handler can all change). Re-registration does
|
|
63370
|
+
* **not** clear in-flight promises — entries still resolving complete with
|
|
63371
|
+
* the previous handler.
|
|
63372
|
+
*
|
|
63373
|
+
* @param entry - Entry configuration; see {@link CronEntry}.
|
|
63374
|
+
* @returns Disposer function — call it to unregister the entry.
|
|
63375
|
+
*
|
|
63376
|
+
* @example
|
|
63377
|
+
* ```typescript
|
|
63378
|
+
* const dispose = Cron.register({
|
|
63379
|
+
* name: "fetch-funding",
|
|
63380
|
+
* interval: "8h",
|
|
63381
|
+
* symbols: ["BTCUSDT", "ETHUSDT"],
|
|
63382
|
+
* handler: async (symbol, when, backtest) => { ... },
|
|
63383
|
+
* });
|
|
63384
|
+
* // Later:
|
|
63385
|
+
* dispose();
|
|
63386
|
+
* ```
|
|
63387
|
+
*/
|
|
63388
|
+
this.register = (entry) => {
|
|
63389
|
+
LOGGER_SERVICE$1.info(CRON_METHOD_NAME_REGISTER, {
|
|
63390
|
+
name: entry.name,
|
|
63391
|
+
interval: entry.interval,
|
|
63392
|
+
symbols: entry.symbols,
|
|
63393
|
+
});
|
|
63394
|
+
if (!entry.name) {
|
|
63395
|
+
throw new Error("CronUtils.register requires a non-empty name");
|
|
63396
|
+
}
|
|
63397
|
+
if (entry.name.includes(":")) {
|
|
63398
|
+
throw new Error(`CronUtils.register: name must not contain ':' (got "${entry.name}"). ` +
|
|
63399
|
+
`':' is reserved as the segment separator in slot keys.`);
|
|
63400
|
+
}
|
|
63401
|
+
if (entry.symbols) {
|
|
63402
|
+
for (const symbol of entry.symbols) {
|
|
63403
|
+
if (symbol.includes(":")) {
|
|
63404
|
+
throw new Error(`CronUtils.register: symbols[] entry must not contain ':' (got "${symbol}"). ` +
|
|
63405
|
+
`':' is reserved as the segment separator in slot keys.`);
|
|
63406
|
+
}
|
|
63407
|
+
}
|
|
63408
|
+
}
|
|
63409
|
+
this._clearFiredOnceFor(entry.name);
|
|
63410
|
+
const generation = ++this._generationCounter;
|
|
63411
|
+
this._entries.set(entry.name, { entry, generation });
|
|
63412
|
+
return () => this.unregister(entry.name);
|
|
63413
|
+
};
|
|
63414
|
+
/**
|
|
63415
|
+
* Remove a registered entry by name.
|
|
63416
|
+
*
|
|
63417
|
+
* Does not cancel handlers already in flight — those resolve on their own
|
|
63418
|
+
* and clear their slot via `.finally()`.
|
|
63419
|
+
*
|
|
63420
|
+
* @param name - Name passed to `register`.
|
|
63421
|
+
*/
|
|
63422
|
+
this.unregister = (name) => {
|
|
63423
|
+
LOGGER_SERVICE$1.info(CRON_METHOD_NAME_UNREGISTER, { name });
|
|
63424
|
+
this._entries.delete(name);
|
|
63425
|
+
this._clearFiredOnceFor(name);
|
|
63426
|
+
};
|
|
63427
|
+
/**
|
|
63428
|
+
* Clear fire-once marks so that fire-once entries can fire again.
|
|
63429
|
+
*
|
|
63430
|
+
* Does **not** touch `_inFlight` — that map holds shared in-flight handler
|
|
63431
|
+
* promises through which parallel `tick`s coordinate. Wiping it mid-flight
|
|
63432
|
+
* would let a new `tick` start a second handler for a boundary that's
|
|
63433
|
+
* already running, breaking the singleshot contract.
|
|
63434
|
+
*
|
|
63435
|
+
* Two modes:
|
|
63436
|
+
* - **Per-symbol** (`symbol` provided): clears only fan-out fire-once
|
|
63437
|
+
* marks for that symbol — keys of the shape `${name}:${symbol}:g${gen}`.
|
|
63438
|
+
* Global fire-once marks (`${name}:g${gen}`, no symbol component) are
|
|
63439
|
+
* left intact, since they are not attributable to a single symbol.
|
|
63440
|
+
* Useful for re-arming fan-out fire-once entries when a particular
|
|
63441
|
+
* symbol's run finishes and you want a future re-run to fire again.
|
|
63442
|
+
* - **All** (no argument): wipes every fire-once mark across all entries
|
|
63443
|
+
* and symbols. Registered entries are not removed — use `unregister`
|
|
63444
|
+
* (or the disposer returned by `register`) for that.
|
|
63445
|
+
*
|
|
63446
|
+
* **Race with in-flight handlers.** `_firedOnce` is written in
|
|
63447
|
+
* `_runEntry`'s `.finally()`, which can run *after* a concurrent
|
|
63448
|
+
* `clear()` call. In that case the fire-once mark reappears immediately
|
|
63449
|
+
* after being wiped, and the next tick will treat the entry as already
|
|
63450
|
+
* fired. This is consistent with the singleshot promise itself surviving
|
|
63451
|
+
* `clear()` — the handler is allowed to finish — and the entry's
|
|
63452
|
+
* generation suffix in `firedKey` guarantees the stale mark cannot
|
|
63453
|
+
* outlive a subsequent `register()` of the same name. If you need a hard
|
|
63454
|
+
* re-arm, `unregister` + `register` bumps the generation and makes any
|
|
63455
|
+
* late write a no-op.
|
|
63456
|
+
*
|
|
63457
|
+
* @param symbol - Optional symbol filter; if omitted, clears all fire-once
|
|
63458
|
+
* marks.
|
|
63459
|
+
*/
|
|
63460
|
+
this.clear = (symbol) => {
|
|
63461
|
+
LOGGER_SERVICE$1.info(CRON_METHOD_NAME_CLEAR, { symbol });
|
|
63462
|
+
if (!symbol) {
|
|
63463
|
+
this._firedOnce.clear();
|
|
63464
|
+
return;
|
|
63465
|
+
}
|
|
63466
|
+
const symbolSegment = `:${symbol}:`;
|
|
63467
|
+
for (const key of this._firedOnce) {
|
|
63468
|
+
if (key.includes(symbolSegment)) {
|
|
63469
|
+
this._firedOnce.delete(key);
|
|
63470
|
+
}
|
|
63471
|
+
}
|
|
63472
|
+
};
|
|
63473
|
+
/**
|
|
63474
|
+
* Process a virtual-time tick for `symbol` and fire any due cron entries.
|
|
63475
|
+
*
|
|
63476
|
+
* **Private.** Invoked exclusively by the lifecycle bridge installed in
|
|
63477
|
+
* {@link enable} — `beforeStart` / `idlePing` / `activePing` / `schedulePing`
|
|
63478
|
+
* are funneled here through a shared `singlerun` queue, so calls to
|
|
63479
|
+
* `_tick` are serialised end-to-end. Do not call directly.
|
|
63480
|
+
*
|
|
63481
|
+
* Algorithm (per registered entry):
|
|
63482
|
+
* 0. Base-align the incoming `when` down to the 1-minute boundary (`ts`).
|
|
63483
|
+
* Lifecycle subjects may emit with sub-second jitter; rounding here
|
|
63484
|
+
* guarantees that `beforeStart` / `idlePing` / `activePing` /
|
|
63485
|
+
* `schedulePing` for the same virtual minute all hash to the same
|
|
63486
|
+
* slot key.
|
|
63487
|
+
* 1. If `entry.symbols` is non-empty and does not include `symbol`, skip.
|
|
63488
|
+
* 2. Decide scope from `entry.symbols`:
|
|
63489
|
+
* - Empty/undefined → **global** (slot key has no symbol component).
|
|
63490
|
+
* - Non-empty → **fan-out**, slot key carries `:${symbol}` so each
|
|
63491
|
+
* whitelisted symbol gets its own slot and handler invocation.
|
|
63492
|
+
* 3. Append the current entry generation suffix `:g${generation}` to both
|
|
63493
|
+
* slot key and fired-once key. This isolates incarnations of the same
|
|
63494
|
+
* `name`: a `register()` after an in-flight handler bumps the
|
|
63495
|
+
* generation, so the late `_firedOnce` write from the old handler can
|
|
63496
|
+
* never block the new entry.
|
|
63497
|
+
* 4. **Fire-once** (`entry.interval === undefined`):
|
|
63498
|
+
* - If the entry's fired-once key is already in `_firedOnce`, skip.
|
|
63499
|
+
* - Slot key: `${name}:once` (+ scope) (+ gen).
|
|
63500
|
+
* - `aligned` = the 1-minute-aligned `when` from step 0.
|
|
63501
|
+
* 5. **Periodic** (`entry.interval` set):
|
|
63502
|
+
* - Align `when` further to the entry's interval via {@link alignToInterval}.
|
|
63503
|
+
* - If `ts !== alignedMs`, the tick is mid-interval — skip.
|
|
63504
|
+
* (This is the "remainder === 0" boundary check from the spec;
|
|
63505
|
+
* since `ts` is already on the 1-minute boundary, the check is exact
|
|
63506
|
+
* for `1m` and consistent for higher intervals.)
|
|
63507
|
+
* - Slot key: `${name}:${alignedMs}` (+ scope) (+ gen).
|
|
63508
|
+
* 6. Singleshot per slot key: look up the slot in `_inFlight`. If a promise
|
|
63509
|
+
* already exists, `await` the same promise. Otherwise invoke
|
|
63510
|
+
* `entry.handler`, store the promise, and `await` it. The slot is
|
|
63511
|
+
* removed in `.finally()` so the next boundary creates a fresh promise;
|
|
63512
|
+
* for fire-once entries the fired-once key is also added to
|
|
63513
|
+
* `_firedOnce` on success so subsequent ticks skip it.
|
|
63514
|
+
*
|
|
63515
|
+
* Errors thrown by `handler` are caught, logged via `console.error`, and
|
|
63516
|
+
* **not** rethrown — a failing handler must not break the per-symbol
|
|
63517
|
+
* tick loop or unblock other parallel backtests with an unhandled
|
|
63518
|
+
* rejection. A failed fire-once handler is **not** marked as fired and
|
|
63519
|
+
* will retry on the next tick.
|
|
63520
|
+
*
|
|
63521
|
+
* Requires active method context and execution context.
|
|
63522
|
+
*
|
|
63523
|
+
* @param symbol - Trading symbol from the current tick.
|
|
63524
|
+
* @param when - Virtual time of the current tick.
|
|
63525
|
+
* @param backtest - `true` for backtest ticks, `false` for live ticks.
|
|
63526
|
+
* Forwarded as the third argument to `entry.handler`. Only the value
|
|
63527
|
+
* from the tick that **opens** a given slot is observed by all parallel
|
|
63528
|
+
* awaiters of that slot.
|
|
63529
|
+
* @throws Error if method or execution context is missing.
|
|
63530
|
+
*/
|
|
63531
|
+
this._tick = async (symbol, when, backtest) => {
|
|
63532
|
+
LOGGER_SERVICE$1.debug(CRON_METHOD_NAME_TICK, {
|
|
63533
|
+
symbol,
|
|
63534
|
+
when,
|
|
63535
|
+
});
|
|
63536
|
+
if (!MethodContextService.hasContext()) {
|
|
63537
|
+
throw new Error("CronUtils _tick requires method context");
|
|
63538
|
+
}
|
|
63539
|
+
if (!ExecutionContextService.hasContext()) {
|
|
63540
|
+
throw new Error("CronUtils _tick requires execution context");
|
|
63541
|
+
}
|
|
63542
|
+
const ts = alignToInterval(when, "1m").getTime();
|
|
63543
|
+
const taskList = [];
|
|
63544
|
+
for (const { entry, generation } of this._entries.values()) {
|
|
63545
|
+
if (entry.symbols?.length && !entry.symbols.includes(symbol)) {
|
|
63546
|
+
continue;
|
|
63547
|
+
}
|
|
63548
|
+
const perSymbol = !!entry.symbols?.length;
|
|
63549
|
+
const scope = perSymbol ? `:${symbol}` : "";
|
|
63550
|
+
const genSuffix = `:g${generation}`;
|
|
63551
|
+
let aligned;
|
|
63552
|
+
let alignedMs;
|
|
63553
|
+
let slotKey;
|
|
63554
|
+
let firedKey;
|
|
63555
|
+
if (entry.interval === undefined) {
|
|
63556
|
+
const onceKey = `${entry.name}${scope}${genSuffix}`;
|
|
63557
|
+
if (this._firedOnce.has(onceKey)) {
|
|
63558
|
+
continue;
|
|
63559
|
+
}
|
|
63560
|
+
aligned = alignToInterval(when, "1m");
|
|
63561
|
+
alignedMs = ts;
|
|
63562
|
+
slotKey = `${entry.name}:once${scope}${genSuffix}`;
|
|
63563
|
+
firedKey = onceKey;
|
|
63564
|
+
}
|
|
63565
|
+
else {
|
|
63566
|
+
aligned = alignToInterval(when, entry.interval);
|
|
63567
|
+
alignedMs = aligned.getTime();
|
|
63568
|
+
if (ts !== alignedMs) {
|
|
63569
|
+
continue;
|
|
63570
|
+
}
|
|
63571
|
+
slotKey = `${entry.name}:${alignedMs}${scope}${genSuffix}`;
|
|
63572
|
+
firedKey = null;
|
|
63573
|
+
}
|
|
63574
|
+
let pending = this._inFlight.get(slotKey);
|
|
63575
|
+
if (!pending) {
|
|
63576
|
+
pending = this._runEntry(entry, symbol, aligned, alignedMs, slotKey, firedKey, backtest);
|
|
63577
|
+
this._inFlight.set(slotKey, pending);
|
|
63578
|
+
}
|
|
63579
|
+
taskList.push(pending);
|
|
63580
|
+
}
|
|
63581
|
+
await Promise.all(taskList);
|
|
63582
|
+
};
|
|
63583
|
+
/**
|
|
63584
|
+
* Subscribe `Cron` to the engine's strategy lifecycle subjects so registered
|
|
63585
|
+
* entries fire automatically — no manual wiring of `listenTickBacktest` /
|
|
63586
|
+
* `listenSchedulePing` etc. needed.
|
|
63587
|
+
*
|
|
63588
|
+
* Subjects funneled into {@link _tick}:
|
|
63589
|
+
* - `beforeStartSubject` — first event of every run.
|
|
63590
|
+
* - `idlePingSubject` — every tick when no signal is pending or scheduled.
|
|
63591
|
+
* - `activePingSubject` — every tick while a pending signal is being monitored.
|
|
63592
|
+
* - `schedulePingSubject` — every tick while a scheduled signal is being monitored.
|
|
63593
|
+
*
|
|
63594
|
+
* All four subjects are subscribed to a single `singlerun`-wrapped
|
|
63595
|
+
* handler that builds `_tick(event.symbol, new Date(event.timestamp),
|
|
63596
|
+
* event.backtest)`. `singlerun` merges the four streams into one serial
|
|
63597
|
+
* queue: at most one `_tick` runs at a time, the next waits. This matters
|
|
63598
|
+
* because the engine can emit `beforeStart` and an immediate `idlePing`
|
|
63599
|
+
* on the very same minute, and concurrent `_tick`s on the same
|
|
63600
|
+
* `(symbol, minute)` would otherwise race to open the same `_inFlight`
|
|
63601
|
+
* slot before either commit. Together these four sources cover every
|
|
63602
|
+
* tick the engine processes for every `(symbol, virtual-minute)` pair
|
|
63603
|
+
* regardless of whether the strategy is idle, active, or scheduled.
|
|
63604
|
+
*
|
|
63605
|
+
* `enable` itself is wrapped in `singleshot`, so calling it repeatedly is
|
|
63606
|
+
* a no-op — subsequent calls return the same disposer. The disposer
|
|
63607
|
+
* unsubscribes from every subject and resets the singleshot so a future
|
|
63608
|
+
* `enable()` can re-subscribe cleanly. Equivalent to the
|
|
63609
|
+
* `RecentAdapter.enable` pattern.
|
|
63610
|
+
*
|
|
63611
|
+
* The `.subscribe` callbacks are synchronous wrappers around the
|
|
63612
|
+
* `singlerun`-async handler; `_tick`'s returned promise is awaited inside
|
|
63613
|
+
* `singlerun` to enforce ordering but not bubbled back to the subject.
|
|
63614
|
+
* Errors are caught and logged inside `_runEntry`.
|
|
63615
|
+
*
|
|
63616
|
+
* @returns Cleanup function that unsubscribes from all four subjects and
|
|
63617
|
+
* resets the singleshot. Idempotent.
|
|
63618
|
+
*
|
|
63619
|
+
* @example
|
|
63620
|
+
* ```typescript
|
|
63621
|
+
* import { Cron } from "backtest-kit";
|
|
63622
|
+
*
|
|
63623
|
+
* Cron.register({ name: "tg-parser", interval: "1h", handler });
|
|
63624
|
+
* Cron.enable(); // wire once at startup
|
|
63625
|
+
* // ... run backtests / live as usual
|
|
63626
|
+
* Cron.disable(); // on shutdown
|
|
63627
|
+
* ```
|
|
63628
|
+
*/
|
|
63629
|
+
this.enable = singleshot(() => {
|
|
63630
|
+
LOGGER_SERVICE$1.info(CRON_METHOD_NAME_ENABLE);
|
|
63631
|
+
const handleTick = singlerun(async (event) => {
|
|
63632
|
+
return await this._tick(event.symbol, new Date(event.timestamp), event.backtest);
|
|
63633
|
+
});
|
|
63634
|
+
const unBeforeStart = beforeStartSubject.subscribe(handleTick);
|
|
63635
|
+
const unIdlePing = idlePingSubject.subscribe(handleTick);
|
|
63636
|
+
const unActivePing = activePingSubject.subscribe(handleTick);
|
|
63637
|
+
const unSchedulePing = schedulePingSubject.subscribe(handleTick);
|
|
63638
|
+
return compose(() => unBeforeStart(), () => unIdlePing(), () => unActivePing(), () => unSchedulePing(), () => this.enable.clear());
|
|
63639
|
+
});
|
|
63640
|
+
/**
|
|
63641
|
+
* Tear down the lifecycle subscriptions installed by {@link enable}.
|
|
63642
|
+
*
|
|
63643
|
+
* Safe to call multiple times and safe to call before `enable()` — both
|
|
63644
|
+
* are no-ops. Does **not** unregister entries, does **not** touch
|
|
63645
|
+
* `_inFlight`, and does **not** wipe `_firedOnce` (use `unregister` or
|
|
63646
|
+
* `clear()` for those).
|
|
63647
|
+
*/
|
|
63648
|
+
this.disable = () => {
|
|
63649
|
+
LOGGER_SERVICE$1.info(CRON_METHOD_NAME_DISABLE);
|
|
63650
|
+
if (this.enable.hasValue()) {
|
|
63651
|
+
const lastSubscription = this.enable();
|
|
63652
|
+
lastSubscription();
|
|
63653
|
+
}
|
|
63654
|
+
};
|
|
63655
|
+
}
|
|
63656
|
+
/**
|
|
63657
|
+
* Garbage-collect every `_firedOnce` key that belongs to the entry `name`
|
|
63658
|
+
* (any generation, global or fan-out).
|
|
63659
|
+
*
|
|
63660
|
+
* Called from `register`/`unregister` to free memory; **not** required
|
|
63661
|
+
* for correctness — the generation suffix already isolates re-registrations,
|
|
63662
|
+
* so leftover keys from old generations can never block a new entry.
|
|
63663
|
+
* They just sit unused until they are GC'd here or wiped by `clear()`.
|
|
63664
|
+
*/
|
|
63665
|
+
_clearFiredOnceFor(name) {
|
|
63666
|
+
if (!name) {
|
|
63667
|
+
return;
|
|
63668
|
+
}
|
|
63669
|
+
const prefix = `${name}:`;
|
|
63670
|
+
for (const key of this._firedOnce) {
|
|
63671
|
+
if (key === name || key.startsWith(prefix)) {
|
|
63672
|
+
this._firedOnce.delete(key);
|
|
63673
|
+
}
|
|
63674
|
+
}
|
|
63675
|
+
}
|
|
63676
|
+
/**
|
|
63677
|
+
* Build the singleshot promise for a single in-flight slot.
|
|
63678
|
+
*
|
|
63679
|
+
* Invokes `entry.handler(symbol, aligned, backtest)`, swallows and logs
|
|
63680
|
+
* any error via `console.error`, and clears the `_inFlight` slot
|
|
63681
|
+
* in `.finally()` so the next boundary produces a fresh promise. For
|
|
63682
|
+
* fire-once entries `firedKey` is added to `_firedOnce` on success so
|
|
63683
|
+
* subsequent ticks skip it.
|
|
63684
|
+
*
|
|
63685
|
+
* @param firedKey - Key to add to `_firedOnce` on success, or `null` for
|
|
63686
|
+
* periodic entries (which never populate `_firedOnce`).
|
|
63687
|
+
* @param backtest - Value forwarded as the third handler argument; the
|
|
63688
|
+
* "winner" tick's flag is what all parallel awaiters of this slot see.
|
|
63689
|
+
*/
|
|
63690
|
+
async _runEntry(entry, symbol, aligned, alignedMs, slotKey, firedKey, backtest) {
|
|
63691
|
+
let failed = false;
|
|
63692
|
+
try {
|
|
63693
|
+
await entry.handler(symbol, aligned, backtest);
|
|
63694
|
+
}
|
|
63695
|
+
catch (err) {
|
|
63696
|
+
failed = true;
|
|
63697
|
+
console.error(`${CRON_METHOD_NAME_TICK} entry "${entry.name}" failed`, { symbol, alignedMs, err });
|
|
63698
|
+
}
|
|
63699
|
+
finally {
|
|
63700
|
+
this._inFlight.delete(slotKey);
|
|
63701
|
+
if (!failed && firedKey !== null) {
|
|
63702
|
+
this._firedOnce.add(firedKey);
|
|
63703
|
+
}
|
|
63704
|
+
}
|
|
63705
|
+
}
|
|
63706
|
+
}
|
|
63707
|
+
/**
|
|
63708
|
+
* Singleton instance of {@link CronUtils} for registering periodic tasks
|
|
63709
|
+
* coordinated across parallel `Backtest.background` runs.
|
|
63710
|
+
*
|
|
63711
|
+
* @example
|
|
63712
|
+
* ```typescript
|
|
63713
|
+
* import { Cron } from "backtest-kit";
|
|
63714
|
+
*
|
|
63715
|
+
* Cron.register({
|
|
63716
|
+
* name: "tg-parser",
|
|
63717
|
+
* interval: "1h",
|
|
63718
|
+
* handler: async (symbol, when, backtest) => { ... },
|
|
63719
|
+
* });
|
|
63720
|
+
* ```
|
|
63721
|
+
*/
|
|
63722
|
+
const Cron = new CronUtils();
|
|
63723
|
+
|
|
63236
63724
|
const BREAKEVEN_METHOD_NAME_GET_DATA = "BreakevenUtils.getData";
|
|
63237
63725
|
const BREAKEVEN_METHOD_NAME_GET_REPORT = "BreakevenUtils.getReport";
|
|
63238
63726
|
const BREAKEVEN_METHOD_NAME_DUMP = "BreakevenUtils.dump";
|
|
@@ -64315,7 +64803,7 @@ const validateSignal = (signal, currentPrice) => {
|
|
|
64315
64803
|
}
|
|
64316
64804
|
}
|
|
64317
64805
|
if (errors.length > 0) {
|
|
64318
|
-
console.error(`Invalid signal for ${signal.position} position:\n${errors.join("\n")}`);
|
|
64806
|
+
console.error(`Invalid signal for ${signal.position} position (${signal.symbol || "empty symbol"}):\n${errors.join("\n")}`);
|
|
64319
64807
|
return false;
|
|
64320
64808
|
}
|
|
64321
64809
|
try {
|
|
@@ -64388,9 +64876,9 @@ const validateSignal = (signal, currentPrice) => {
|
|
|
64388
64876
|
}
|
|
64389
64877
|
}
|
|
64390
64878
|
if (errors.length > 0) {
|
|
64391
|
-
console.error(`Invalid signal for ${signal.position} position:\n${errors.join("\n")}`);
|
|
64879
|
+
console.error(`Invalid signal for ${signal.position} position (${signal.symbol || "empty symbol"}):\n${errors.join("\n")}`);
|
|
64392
64880
|
}
|
|
64393
64881
|
return !errors.length;
|
|
64394
64882
|
};
|
|
64395
64883
|
|
|
64396
|
-
export { ActionBase, Backtest, Breakeven, Broker, BrokerBase, Cache, Constant, Dump, Exchange, ExecutionContextService, Heat, HighestProfit, Interval, Live, Log, Lookup, Markdown, MarkdownFileBase, MarkdownFolderBase, MarkdownWriter, MaxDrawdown, Memory, MemoryBacktest, MemoryBacktestAdapter, MemoryLive, MemoryLiveAdapter, MethodContextService, Notification, NotificationBacktest, NotificationLive, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistBreakevenInstance, PersistCandleAdapter, PersistCandleInstance, PersistIntervalAdapter, PersistIntervalInstance, PersistLogAdapter, PersistLogInstance, PersistMeasureAdapter, PersistMeasureInstance, PersistMemoryAdapter, PersistMemoryInstance, PersistNotificationAdapter, PersistNotificationInstance, PersistPartialAdapter, PersistPartialInstance, PersistRecentAdapter, PersistRecentInstance, PersistRiskAdapter, PersistRiskInstance, PersistScheduleAdapter, PersistScheduleInstance, PersistSessionAdapter, PersistSessionInstance, PersistSignalAdapter, PersistSignalInstance, PersistStateAdapter, PersistStateInstance, PersistStorageAdapter, PersistStorageInstance, Position, PositionSize, Recent, RecentBacktest, RecentLive, Reflect$1 as Reflect, Report, ReportBase, ReportWriter, Risk, Schedule, Session, SessionBacktest, SessionLive, State, StateBacktest, StateBacktestAdapter, StateLive, StateLiveAdapter, Storage, StorageBacktest, StorageLive, Strategy, Sync, System, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, alignToInterval, cacheCandles, checkCandles, commitActivateScheduled, commitAverageBuy, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialLossCost, commitPartialProfit, commitPartialProfitCost, commitSignalNotify, commitTrailingStop, commitTrailingStopCost, commitTrailingTake, commitTrailingTakeCost, createSignalState, dumpAgentAnswer, dumpError, dumpJson, dumpRecord, dumpTable, dumpText, emitters, formatPrice, formatQuantity, get, getActionSchema, getAggregatedTrades, getAveragePrice, getBacktestTimeframe, getBreakeven, getCandles, getClosePrice, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getEffectivePriceOpen, getExchangeSchema, getFrameSchema, getLatestSignal, getMaxDrawdownDistancePnlCost, getMaxDrawdownDistancePnlPercentage, getMinutesSinceLatestSignalCreated, getMode, getNextCandles, getOrderBook, getPendingSignal, getPositionActiveMinutes, getPositionCountdownMinutes, getPositionDrawdownMinutes, getPositionEffectivePrice, getPositionEntries, getPositionEntryOverlap, getPositionEstimateMinutes, getPositionHighestMaxDrawdownPnlCost, getPositionHighestMaxDrawdownPnlPercentage, getPositionHighestPnlCost, getPositionHighestPnlPercentage, getPositionHighestProfitBreakeven, getPositionHighestProfitDistancePnlCost, getPositionHighestProfitDistancePnlPercentage, getPositionHighestProfitMinutes, getPositionHighestProfitPrice, getPositionHighestProfitTimestamp, getPositionInvestedCost, getPositionInvestedCount, getPositionLevels, getPositionMaxDrawdownMinutes, getPositionMaxDrawdownPnlCost, getPositionMaxDrawdownPnlPercentage, getPositionMaxDrawdownPrice, getPositionMaxDrawdownTimestamp, getPositionPartialOverlap, getPositionPartials, getPositionPnlCost, getPositionPnlPercent, getPositionWaitingMinutes, getRawCandles, getRiskSchema, getScheduledSignal, getSessionData, getSignalState, getSizingSchema, getStrategySchema, getSymbol, getTimestamp, getTotalClosed, getTotalCostClosed, getTotalPercentClosed, getWalkerSchema, hasNoPendingSignal, hasNoScheduledSignal, hasTradeContext, intervalStepMs, investedCostToPercent, backtest as lib, listExchangeSchema, listFrameSchema, listMemory, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenAfterEnd, listenAfterEndOnce, listenBacktestProgress, listenBeforeStart, listenBeforeStartOnce, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenHighestProfit, listenHighestProfitOnce, listenIdlePing, listenIdlePingOnce, listenMaxDrawdown, listenMaxDrawdownOnce, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalNotify, listenSignalNotifyOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenSync, listenSyncOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, percentDiff, percentToCloseCost, percentValue, readMemory, removeMemory, roundTicks, runInMockContext, searchMemory, set, setColumns, setConfig, setLogger, setSessionData, setSignalState, shutdown, slPercentShiftToPrice, slPriceToPercentShift, stopStrategy, toProfitLossDto, tpPercentShiftToPrice, tpPriceToPercentShift, validate, validateCommonSignal, validatePendingSignal, validateScheduledSignal, validateSignal, waitForCandle, waitForReady, warmCandles, writeMemory };
|
|
64884
|
+
export { ActionBase, Backtest, Breakeven, Broker, BrokerBase, Cache, Constant, Cron, Dump, Exchange, ExecutionContextService, Heat, HighestProfit, Interval, Live, Log, Lookup, Markdown, MarkdownFileBase, MarkdownFolderBase, MarkdownWriter, MaxDrawdown, Memory, MemoryBacktest, MemoryBacktestAdapter, MemoryLive, MemoryLiveAdapter, MethodContextService, Notification, NotificationBacktest, NotificationLive, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistBreakevenInstance, PersistCandleAdapter, PersistCandleInstance, PersistIntervalAdapter, PersistIntervalInstance, PersistLogAdapter, PersistLogInstance, PersistMeasureAdapter, PersistMeasureInstance, PersistMemoryAdapter, PersistMemoryInstance, PersistNotificationAdapter, PersistNotificationInstance, PersistPartialAdapter, PersistPartialInstance, PersistRecentAdapter, PersistRecentInstance, PersistRiskAdapter, PersistRiskInstance, PersistScheduleAdapter, PersistScheduleInstance, PersistSessionAdapter, PersistSessionInstance, PersistSignalAdapter, PersistSignalInstance, PersistStateAdapter, PersistStateInstance, PersistStorageAdapter, PersistStorageInstance, Position, PositionSize, Recent, RecentBacktest, RecentLive, Reflect$1 as Reflect, Report, ReportBase, ReportWriter, Risk, Schedule, Session, SessionBacktest, SessionLive, State, StateBacktest, StateBacktestAdapter, StateLive, StateLiveAdapter, Storage, StorageBacktest, StorageLive, Strategy, Sync, System, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, alignToInterval, beginContext, beginTime, cacheCandles, checkCandles, commitActivateScheduled, commitAverageBuy, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialLossCost, commitPartialProfit, commitPartialProfitCost, commitSignalNotify, commitTrailingStop, commitTrailingStopCost, commitTrailingTake, commitTrailingTakeCost, createSignalState, dumpAgentAnswer, dumpError, dumpJson, dumpRecord, dumpTable, dumpText, emitters, formatPrice, formatQuantity, get, getActionSchema, getAggregatedTrades, getAveragePrice, getBacktestTimeframe, getBreakeven, getCandles, getClosePrice, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getEffectivePriceOpen, getExchangeSchema, getFrameSchema, getLatestSignal, getMaxDrawdownDistancePnlCost, getMaxDrawdownDistancePnlPercentage, getMinutesSinceLatestSignalCreated, getMode, getNextCandles, getOrderBook, getPendingSignal, getPositionActiveMinutes, getPositionCountdownMinutes, getPositionDrawdownMinutes, getPositionEffectivePrice, getPositionEntries, getPositionEntryOverlap, getPositionEstimateMinutes, getPositionHighestMaxDrawdownPnlCost, getPositionHighestMaxDrawdownPnlPercentage, getPositionHighestPnlCost, getPositionHighestPnlPercentage, getPositionHighestProfitBreakeven, getPositionHighestProfitDistancePnlCost, getPositionHighestProfitDistancePnlPercentage, getPositionHighestProfitMinutes, getPositionHighestProfitPrice, getPositionHighestProfitTimestamp, getPositionInvestedCost, getPositionInvestedCount, getPositionLevels, getPositionMaxDrawdownMinutes, getPositionMaxDrawdownPnlCost, getPositionMaxDrawdownPnlPercentage, getPositionMaxDrawdownPrice, getPositionMaxDrawdownTimestamp, getPositionPartialOverlap, getPositionPartials, getPositionPnlCost, getPositionPnlPercent, getPositionWaitingMinutes, getRawCandles, getRiskSchema, getScheduledSignal, getSessionData, getSignalState, getSizingSchema, getStrategySchema, getSymbol, getTimestamp, getTotalClosed, getTotalCostClosed, getTotalPercentClosed, getWalkerSchema, hasNoPendingSignal, hasNoScheduledSignal, hasTradeContext, intervalStepMs, investedCostToPercent, backtest as lib, listExchangeSchema, listFrameSchema, listMemory, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenAfterEnd, listenAfterEndOnce, listenBacktestProgress, listenBeforeStart, listenBeforeStartOnce, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenHighestProfit, listenHighestProfitOnce, listenIdlePing, listenIdlePingOnce, listenMaxDrawdown, listenMaxDrawdownOnce, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalNotify, listenSignalNotifyOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenSync, listenSyncOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, percentDiff, percentToCloseCost, percentValue, readMemory, removeMemory, roundTicks, runInMockContext, searchMemory, set, setColumns, setConfig, setLogger, setSessionData, setSignalState, shutdown, slPercentShiftToPrice, slPriceToPercentShift, stopStrategy, toPlainString, toProfitLossDto, tpPercentShiftToPrice, tpPriceToPercentShift, validate, validateCommonSignal, validatePendingSignal, validateScheduledSignal, validateSignal, waitForCandle, waitForReady, warmCandles, writeMemory };
|