backtest-kit 5.9.0 → 5.10.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 +17 -4
- package/build/index.cjs +254 -128
- package/build/index.mjs +254 -128
- package/package.json +1 -1
- package/types.d.ts +23 -7
package/build/index.cjs
CHANGED
|
@@ -6345,7 +6345,7 @@ const CLOSE_USER_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, closedSignal, aver
|
|
|
6345
6345
|
await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, closeTimestamp, self.params.execution.context.backtest);
|
|
6346
6346
|
return result;
|
|
6347
6347
|
};
|
|
6348
|
-
const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles) => {
|
|
6348
|
+
const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, frameEndTime) => {
|
|
6349
6349
|
const candlesCount = GLOBAL_CONFIG.CC_AVG_PRICE_CANDLES_COUNT;
|
|
6350
6350
|
const maxTimeToWait = GLOBAL_CONFIG.CC_SCHEDULE_AWAIT_MINUTES * 60 * 1000;
|
|
6351
6351
|
const bufferCandlesCount = candlesCount - 1;
|
|
@@ -6358,6 +6358,11 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles) =>
|
|
|
6358
6358
|
}
|
|
6359
6359
|
const recentCandles = candles.slice(Math.max(0, i - (candlesCount - 1)), i + 1);
|
|
6360
6360
|
const averagePrice = GET_AVG_PRICE_FN(recentCandles);
|
|
6361
|
+
// Если timestamp свечи вышел за frameEndTime — отменяем scheduled сигнал
|
|
6362
|
+
if (candle.timestamp > frameEndTime) {
|
|
6363
|
+
const result = await CANCEL_SCHEDULED_SIGNAL_IN_BACKTEST_FN(self, scheduled, averagePrice, candle.timestamp, "timeout");
|
|
6364
|
+
return { outcome: "cancelled", result };
|
|
6365
|
+
}
|
|
6361
6366
|
// КРИТИЧНО: Проверяем был ли сигнал отменен пользователем через cancel()
|
|
6362
6367
|
if (self._cancelledSignal) {
|
|
6363
6368
|
// Сигнал был отменен через cancel() в onSchedulePing
|
|
@@ -6505,7 +6510,7 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles) =>
|
|
|
6505
6510
|
}
|
|
6506
6511
|
return { outcome: "pending" };
|
|
6507
6512
|
};
|
|
6508
|
-
const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles) => {
|
|
6513
|
+
const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEndTime) => {
|
|
6509
6514
|
const candlesCount = GLOBAL_CONFIG.CC_AVG_PRICE_CANDLES_COUNT;
|
|
6510
6515
|
const bufferCandlesCount = candlesCount - 1;
|
|
6511
6516
|
// КРИТИЧНО: проверяем TP/SL на КАЖДОЙ свече начиная после буфера
|
|
@@ -6522,6 +6527,14 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles) => {
|
|
|
6522
6527
|
const startIndex = Math.max(0, i - (candlesCount - 1));
|
|
6523
6528
|
const recentCandles = candles.slice(startIndex, i + 1);
|
|
6524
6529
|
const averagePrice = GET_AVG_PRICE_FN(recentCandles);
|
|
6530
|
+
// Если timestamp свечи вышел за frameEndTime — закрываем pending сигнал по time_expired
|
|
6531
|
+
if (currentCandleTimestamp > frameEndTime) {
|
|
6532
|
+
const result = await CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN(self, signal, averagePrice, "time_expired", currentCandleTimestamp);
|
|
6533
|
+
if (!result) {
|
|
6534
|
+
throw new Error(`ClientStrategy backtest: frameEndTime time_expired close rejected by sync (signalId=${signal.id}).`);
|
|
6535
|
+
}
|
|
6536
|
+
return result;
|
|
6537
|
+
}
|
|
6525
6538
|
// КРИТИЧНО: Проверяем был ли сигнал закрыт пользователем через closePending()
|
|
6526
6539
|
if (self._closedSignal) {
|
|
6527
6540
|
return await CLOSE_USER_PENDING_SIGNAL_IN_BACKTEST_FN(self, self._closedSignal, averagePrice, currentCandleTimestamp);
|
|
@@ -7687,7 +7700,7 @@ class ClientStrategy {
|
|
|
7687
7700
|
* console.log(result.closeReason); // "take_profit" | "stop_loss" | "time_expired" | "cancelled"
|
|
7688
7701
|
* ```
|
|
7689
7702
|
*/
|
|
7690
|
-
async backtest(symbol, strategyName, candles) {
|
|
7703
|
+
async backtest(symbol, strategyName, candles, frameEndTime) {
|
|
7691
7704
|
this.params.logger.debug("ClientStrategy backtest", {
|
|
7692
7705
|
symbol,
|
|
7693
7706
|
strategyName,
|
|
@@ -7695,6 +7708,7 @@ class ClientStrategy {
|
|
|
7695
7708
|
candlesCount: candles.length,
|
|
7696
7709
|
hasScheduled: !!this._scheduledSignal,
|
|
7697
7710
|
hasPending: !!this._pendingSignal,
|
|
7711
|
+
frameEndTime,
|
|
7698
7712
|
});
|
|
7699
7713
|
if (!this.params.execution.context.backtest) {
|
|
7700
7714
|
throw new Error("ClientStrategy backtest: running in live context");
|
|
@@ -7813,7 +7827,7 @@ class ClientStrategy {
|
|
|
7813
7827
|
priceOpen: scheduled.priceOpen,
|
|
7814
7828
|
position: scheduled.position,
|
|
7815
7829
|
});
|
|
7816
|
-
const scheduledResult = await PROCESS_SCHEDULED_SIGNAL_CANDLES_FN(this, scheduled, candles);
|
|
7830
|
+
const scheduledResult = await PROCESS_SCHEDULED_SIGNAL_CANDLES_FN(this, scheduled, candles, frameEndTime);
|
|
7817
7831
|
if (scheduledResult.outcome === "cancelled") {
|
|
7818
7832
|
return scheduledResult.result;
|
|
7819
7833
|
}
|
|
@@ -7890,7 +7904,7 @@ class ClientStrategy {
|
|
|
7890
7904
|
if (candles.length < candlesCount) {
|
|
7891
7905
|
this.params.logger.warn(`ClientStrategy backtest: Expected at least ${candlesCount} candles for VWAP, got ${candles.length}`);
|
|
7892
7906
|
}
|
|
7893
|
-
return await PROCESS_PENDING_SIGNAL_CANDLES_FN(this, signal, candles);
|
|
7907
|
+
return await PROCESS_PENDING_SIGNAL_CANDLES_FN(this, signal, candles, frameEndTime);
|
|
7894
7908
|
}
|
|
7895
7909
|
/**
|
|
7896
7910
|
* Stops the strategy from generating new signals.
|
|
@@ -10283,17 +10297,18 @@ class StrategyConnectionService {
|
|
|
10283
10297
|
* @param candles - Array of historical candle data to backtest
|
|
10284
10298
|
* @returns Promise resolving to backtest result (signal or idle)
|
|
10285
10299
|
*/
|
|
10286
|
-
this.backtest = async (symbol, context, candles) => {
|
|
10300
|
+
this.backtest = async (symbol, context, candles, frameEndTime) => {
|
|
10287
10301
|
const backtest = this.executionContextService.context.backtest;
|
|
10288
10302
|
this.loggerService.log("strategyConnectionService backtest", {
|
|
10289
10303
|
symbol,
|
|
10290
10304
|
context,
|
|
10291
10305
|
candleCount: candles.length,
|
|
10306
|
+
frameEndTime,
|
|
10292
10307
|
backtest,
|
|
10293
10308
|
});
|
|
10294
10309
|
const strategy = this.getStrategy(symbol, context.strategyName, context.exchangeName, context.frameName, backtest);
|
|
10295
10310
|
await strategy.waitForInit();
|
|
10296
|
-
const tick = await strategy.backtest(symbol, context.strategyName, candles);
|
|
10311
|
+
const tick = await strategy.backtest(symbol, context.strategyName, candles, frameEndTime);
|
|
10297
10312
|
{
|
|
10298
10313
|
await CALL_SIGNAL_EMIT_FN(this, tick, context, backtest, symbol);
|
|
10299
10314
|
}
|
|
@@ -14228,17 +14243,18 @@ class StrategyCoreService {
|
|
|
14228
14243
|
* @param context - Execution context with strategyName, exchangeName, frameName
|
|
14229
14244
|
* @returns Closed signal result with PNL
|
|
14230
14245
|
*/
|
|
14231
|
-
this.backtest = async (symbol, candles, when, backtest, context) => {
|
|
14246
|
+
this.backtest = async (symbol, candles, frameEndTime, when, backtest, context) => {
|
|
14232
14247
|
this.loggerService.log("strategyCoreService backtest", {
|
|
14233
14248
|
symbol,
|
|
14234
14249
|
candleCount: candles.length,
|
|
14235
14250
|
when,
|
|
14236
14251
|
backtest,
|
|
14237
14252
|
context,
|
|
14253
|
+
frameEndTime,
|
|
14238
14254
|
});
|
|
14239
14255
|
await this.validate(context);
|
|
14240
14256
|
return await ExecutionContextService.runInContext(async () => {
|
|
14241
|
-
return await this.strategyConnectionService.backtest(symbol, context, candles);
|
|
14257
|
+
return await this.strategyConnectionService.backtest(symbol, context, candles, frameEndTime);
|
|
14242
14258
|
}, {
|
|
14243
14259
|
symbol,
|
|
14244
14260
|
when,
|
|
@@ -16231,7 +16247,9 @@ const TICK_FN = async (self, symbol, when) => {
|
|
|
16231
16247
|
});
|
|
16232
16248
|
}
|
|
16233
16249
|
catch (error) {
|
|
16234
|
-
console.error(`backtestLogicPrivateService tick failed symbol=${symbol} when=${when.toISOString()} strategyName=${self.methodContextService.context.strategyName} exchangeName=${self.methodContextService.context.exchangeName}
|
|
16250
|
+
console.error(`backtestLogicPrivateService tick failed symbol=${symbol} when=${when.toISOString()} strategyName=${self.methodContextService.context.strategyName} exchangeName=${self.methodContextService.context.exchangeName} error=${functoolsKit.getErrorMessage(error)}`, {
|
|
16251
|
+
error: functoolsKit.errorData(error),
|
|
16252
|
+
});
|
|
16235
16253
|
self.loggerService.warn("backtestLogicPrivateService tick failed", {
|
|
16236
16254
|
symbol,
|
|
16237
16255
|
when: when.toISOString(),
|
|
@@ -16257,9 +16275,9 @@ const GET_CANDLES_FN = async (self, symbol, candlesNeeded, bufferStartTime, logM
|
|
|
16257
16275
|
return { type: "error", __error__: SYMBOL_FN_ERROR, reason: "GET_CANDLES_FN", message: functoolsKit.getErrorMessage(error) };
|
|
16258
16276
|
}
|
|
16259
16277
|
};
|
|
16260
|
-
const BACKTEST_FN = async (self, symbol, candles, when, context, logMeta) => {
|
|
16278
|
+
const BACKTEST_FN = async (self, symbol, candles, frameEndTime, when, context, logMeta) => {
|
|
16261
16279
|
try {
|
|
16262
|
-
return await self.strategyCoreService.backtest(symbol, candles, when, true, context);
|
|
16280
|
+
return await self.strategyCoreService.backtest(symbol, candles, frameEndTime, when, true, context);
|
|
16263
16281
|
}
|
|
16264
16282
|
catch (error) {
|
|
16265
16283
|
console.error(`backtestLogicPrivateService backtest failed symbol=${symbol} when=${when.toISOString()} strategyName=${context.strategyName} exchangeName=${context.exchangeName}`);
|
|
@@ -16272,7 +16290,29 @@ const BACKTEST_FN = async (self, symbol, candles, when, context, logMeta) => {
|
|
|
16272
16290
|
return { type: "error", __error__: SYMBOL_FN_ERROR, reason: "BACKTEST_FN", message: functoolsKit.getErrorMessage(error) };
|
|
16273
16291
|
}
|
|
16274
16292
|
};
|
|
16275
|
-
const
|
|
16293
|
+
const CLOSE_PENDING_FN = async (self, symbol, context, lastChunkCandles, frameEndTime, when, signalId) => {
|
|
16294
|
+
try {
|
|
16295
|
+
await self.strategyCoreService.closePending(true, symbol, context);
|
|
16296
|
+
}
|
|
16297
|
+
catch (error) {
|
|
16298
|
+
const message = `closePending failed: ${functoolsKit.getErrorMessage(error)}`;
|
|
16299
|
+
console.error(`backtestLogicPrivateService CLOSE_PENDING_FN: ${message} symbol=${symbol}`);
|
|
16300
|
+
await errorEmitter.next(error instanceof Error ? error : new Error(message));
|
|
16301
|
+
return { type: "error", __error__: SYMBOL_FN_ERROR, reason: "CLOSE_PENDING_FN", message };
|
|
16302
|
+
}
|
|
16303
|
+
const result = await BACKTEST_FN(self, symbol, lastChunkCandles, frameEndTime, when, context, { signalId });
|
|
16304
|
+
if ("__error__" in result) {
|
|
16305
|
+
return result;
|
|
16306
|
+
}
|
|
16307
|
+
if (result.action === "active") {
|
|
16308
|
+
const message = `signal ${signalId} still active after closePending`;
|
|
16309
|
+
console.error(`backtestLogicPrivateService CLOSE_PENDING_FN: ${message} symbol=${symbol}`);
|
|
16310
|
+
await errorEmitter.next(new Error(message));
|
|
16311
|
+
return { type: "error", __error__: SYMBOL_FN_ERROR, reason: "CLOSE_PENDING_FN", message };
|
|
16312
|
+
}
|
|
16313
|
+
return result;
|
|
16314
|
+
};
|
|
16315
|
+
const RUN_INFINITY_CHUNK_LOOP_FN = async (self, symbol, when, context, initialResult, bufferMs, signalId, frameEndTime) => {
|
|
16276
16316
|
let backtestResult = initialResult;
|
|
16277
16317
|
const CHUNK = GLOBAL_CONFIG.CC_MAX_CANDLES_PER_REQUEST;
|
|
16278
16318
|
let lastChunkCandles = [];
|
|
@@ -16283,25 +16323,14 @@ const RUN_INFINITY_CHUNK_LOOP_FN = async (self, symbol, when, context, initialRe
|
|
|
16283
16323
|
return chunkCandles;
|
|
16284
16324
|
}
|
|
16285
16325
|
if (!chunkCandles.length) {
|
|
16286
|
-
await self
|
|
16287
|
-
const result = await BACKTEST_FN(self, symbol, lastChunkCandles, when, context, { signalId });
|
|
16288
|
-
if ("__error__" in result) {
|
|
16289
|
-
return result;
|
|
16290
|
-
}
|
|
16291
|
-
if (result.action === "active") {
|
|
16292
|
-
const message = `signal ${signalId} still active after closePending`;
|
|
16293
|
-
console.error(`backtestLogicPrivateService RUN_INFINITY_CHUNK_LOOP_FN: ${message} symbol=${symbol}`);
|
|
16294
|
-
await errorEmitter.next(new Error(message));
|
|
16295
|
-
return { type: "error", __error__: SYMBOL_FN_ERROR, reason: "RUN_INFINITY_CHUNK_LOOP_FN", message };
|
|
16296
|
-
}
|
|
16297
|
-
return result;
|
|
16326
|
+
return await CLOSE_PENDING_FN(self, symbol, context, lastChunkCandles, frameEndTime, when, signalId);
|
|
16298
16327
|
}
|
|
16299
16328
|
self.loggerService.info("backtestLogicPrivateService candles fetched for infinity chunk", {
|
|
16300
16329
|
symbol,
|
|
16301
16330
|
signalId,
|
|
16302
16331
|
candlesCount: chunkCandles.length,
|
|
16303
16332
|
});
|
|
16304
|
-
const chunkResult = await BACKTEST_FN(self, symbol, chunkCandles, when, context, { signalId });
|
|
16333
|
+
const chunkResult = await BACKTEST_FN(self, symbol, chunkCandles, frameEndTime, when, context, { signalId });
|
|
16305
16334
|
if ("__error__" in chunkResult) {
|
|
16306
16335
|
return chunkResult;
|
|
16307
16336
|
}
|
|
@@ -16346,7 +16375,7 @@ const EMIT_TIMEFRAME_PERFORMANCE_FN = async (self, symbol, timeframeStartTime, p
|
|
|
16346
16375
|
});
|
|
16347
16376
|
return currentTimestamp;
|
|
16348
16377
|
};
|
|
16349
|
-
const PROCESS_SCHEDULED_SIGNAL_FN = async function* (self, symbol, when, result, previousEventTimestamp) {
|
|
16378
|
+
const PROCESS_SCHEDULED_SIGNAL_FN = async function* (self, symbol, when, result, previousEventTimestamp, frameEndTime) {
|
|
16350
16379
|
const signalStartTime = performance.now();
|
|
16351
16380
|
const signal = result.signal;
|
|
16352
16381
|
self.loggerService.info("backtestLogicPrivateService scheduled signal detected", {
|
|
@@ -16366,6 +16395,10 @@ const PROCESS_SCHEDULED_SIGNAL_FN = async function* (self, symbol, when, result,
|
|
|
16366
16395
|
console.error(`backtestLogicPrivateService scheduled signal: getCandles failed, stopping backtest symbol=${symbol} signalId=${signal.id} reason=${candles.reason} message=${candles.message}`);
|
|
16367
16396
|
return candles;
|
|
16368
16397
|
}
|
|
16398
|
+
// No candles available for this scheduled signal — the frame ends before the signal
|
|
16399
|
+
// could be evaluated. Unlike pending (Infinity) signals that require CLOSE_PENDING_FN,
|
|
16400
|
+
// a scheduled signal that never activated needs no explicit cancellation: it simply
|
|
16401
|
+
// did not start. Returning "skip" moves the backtest to the next timeframe.
|
|
16369
16402
|
if (!candles.length) {
|
|
16370
16403
|
return { type: "skip" };
|
|
16371
16404
|
}
|
|
@@ -16407,7 +16440,7 @@ const PROCESS_SCHEDULED_SIGNAL_FN = async function* (self, symbol, when, result,
|
|
|
16407
16440
|
});
|
|
16408
16441
|
}
|
|
16409
16442
|
try {
|
|
16410
|
-
const firstResult = await BACKTEST_FN(self, symbol, candles, when, context, { signalId: signal.id });
|
|
16443
|
+
const firstResult = await BACKTEST_FN(self, symbol, candles, frameEndTime, when, context, { signalId: signal.id });
|
|
16411
16444
|
if ("__error__" in firstResult) {
|
|
16412
16445
|
console.error(`backtestLogicPrivateService scheduled signal: backtest failed, stopping backtest symbol=${symbol} signalId=${signal.id} reason=${firstResult.reason} message=${firstResult.message}`);
|
|
16413
16446
|
return firstResult;
|
|
@@ -16419,7 +16452,7 @@ const PROCESS_SCHEDULED_SIGNAL_FN = async function* (self, symbol, when, result,
|
|
|
16419
16452
|
}
|
|
16420
16453
|
if (backtestResult.action === "active" && signal.minuteEstimatedTime === Infinity) {
|
|
16421
16454
|
const bufferMs = bufferMinutes * 60000;
|
|
16422
|
-
const chunkResult = await RUN_INFINITY_CHUNK_LOOP_FN(self, symbol, when, context, backtestResult, bufferMs, signal.id);
|
|
16455
|
+
const chunkResult = await RUN_INFINITY_CHUNK_LOOP_FN(self, symbol, when, context, backtestResult, bufferMs, signal.id, frameEndTime);
|
|
16423
16456
|
if ("__error__" in chunkResult) {
|
|
16424
16457
|
console.error(`backtestLogicPrivateService scheduled signal: infinity chunk loop failed, stopping backtest symbol=${symbol} signalId=${signal.id} reason=${chunkResult.reason} message=${chunkResult.message}`);
|
|
16425
16458
|
return chunkResult;
|
|
@@ -16449,7 +16482,7 @@ const PROCESS_SCHEDULED_SIGNAL_FN = async function* (self, symbol, when, result,
|
|
|
16449
16482
|
yield backtestResult;
|
|
16450
16483
|
return { type: "closed", previousEventTimestamp: newTimestamp, closeTimestamp: backtestResult.closeTimestamp, shouldStop };
|
|
16451
16484
|
};
|
|
16452
|
-
const RUN_OPENED_CHUNK_LOOP_FN = async (self, symbol, when, context, bufferStartTime, bufferMs, signalId) => {
|
|
16485
|
+
const RUN_OPENED_CHUNK_LOOP_FN = async (self, symbol, when, context, bufferStartTime, bufferMs, signalId, frameEndTime) => {
|
|
16453
16486
|
const CHUNK = GLOBAL_CONFIG.CC_MAX_CANDLES_PER_REQUEST;
|
|
16454
16487
|
let chunkStart = bufferStartTime;
|
|
16455
16488
|
let lastChunkCandles = [];
|
|
@@ -16470,29 +16503,14 @@ const RUN_OPENED_CHUNK_LOOP_FN = async (self, symbol, when, context, bufferStart
|
|
|
16470
16503
|
await errorEmitter.next(new Error(message));
|
|
16471
16504
|
return { type: "error", __error__: SYMBOL_FN_ERROR, reason: "RUN_OPENED_CHUNK_LOOP_FN", message };
|
|
16472
16505
|
}
|
|
16473
|
-
await self
|
|
16474
|
-
const result = await BACKTEST_FN(self, symbol, lastChunkCandles, when, context, { signalId });
|
|
16475
|
-
if ("__error__" in result) {
|
|
16476
|
-
return result;
|
|
16477
|
-
}
|
|
16478
|
-
if (result.action === "active") {
|
|
16479
|
-
const message = `signal ${signalId} still active after closePending`;
|
|
16480
|
-
console.error(`backtestLogicPrivateService RUN_OPENED_CHUNK_LOOP_FN: ${message} symbol=${symbol}`);
|
|
16481
|
-
self.loggerService.warn("backtestLogicPrivateService opened infinity: signal still active after closePending", {
|
|
16482
|
-
symbol,
|
|
16483
|
-
signalId,
|
|
16484
|
-
});
|
|
16485
|
-
await errorEmitter.next(new Error(message));
|
|
16486
|
-
return { type: "error", __error__: SYMBOL_FN_ERROR, reason: "RUN_OPENED_CHUNK_LOOP_FN", message };
|
|
16487
|
-
}
|
|
16488
|
-
return result;
|
|
16506
|
+
return await CLOSE_PENDING_FN(self, symbol, context, lastChunkCandles, frameEndTime, when, signalId);
|
|
16489
16507
|
}
|
|
16490
16508
|
self.loggerService.info("backtestLogicPrivateService candles fetched", {
|
|
16491
16509
|
symbol,
|
|
16492
16510
|
signalId,
|
|
16493
16511
|
candlesCount: chunkCandles.length,
|
|
16494
16512
|
});
|
|
16495
|
-
const chunkResult = await BACKTEST_FN(self, symbol, chunkCandles, when, context, { signalId });
|
|
16513
|
+
const chunkResult = await BACKTEST_FN(self, symbol, chunkCandles, frameEndTime, when, context, { signalId });
|
|
16496
16514
|
if ("__error__" in chunkResult) {
|
|
16497
16515
|
return chunkResult;
|
|
16498
16516
|
}
|
|
@@ -16503,7 +16521,7 @@ const RUN_OPENED_CHUNK_LOOP_FN = async (self, symbol, when, context, bufferStart
|
|
|
16503
16521
|
chunkStart = new Date(chunkResult._backtestLastTimestamp + 60000 - bufferMs);
|
|
16504
16522
|
}
|
|
16505
16523
|
};
|
|
16506
|
-
const PROCESS_OPENED_SIGNAL_FN = async function* (self, symbol, when, result, previousEventTimestamp) {
|
|
16524
|
+
const PROCESS_OPENED_SIGNAL_FN = async function* (self, symbol, when, result, previousEventTimestamp, frameEndTime) {
|
|
16507
16525
|
const signalStartTime = performance.now();
|
|
16508
16526
|
const signal = result.signal;
|
|
16509
16527
|
self.loggerService.info("backtestLogicPrivateService signal opened", {
|
|
@@ -16534,7 +16552,7 @@ const PROCESS_OPENED_SIGNAL_FN = async function* (self, symbol, when, result, pr
|
|
|
16534
16552
|
signalId: signal.id,
|
|
16535
16553
|
candlesCount: candles.length,
|
|
16536
16554
|
});
|
|
16537
|
-
const firstResult = await BACKTEST_FN(self, symbol, candles, when, context, { signalId: signal.id });
|
|
16555
|
+
const firstResult = await BACKTEST_FN(self, symbol, candles, frameEndTime, when, context, { signalId: signal.id });
|
|
16538
16556
|
if ("__error__" in firstResult) {
|
|
16539
16557
|
console.error(`backtestLogicPrivateService opened signal: backtest failed, stopping backtest symbol=${symbol} signalId=${signal.id} reason=${firstResult.reason} message=${firstResult.message}`);
|
|
16540
16558
|
return firstResult;
|
|
@@ -16543,7 +16561,7 @@ const PROCESS_OPENED_SIGNAL_FN = async function* (self, symbol, when, result, pr
|
|
|
16543
16561
|
}
|
|
16544
16562
|
else {
|
|
16545
16563
|
const bufferMs = bufferMinutes * 60000;
|
|
16546
|
-
const chunkResult = await RUN_OPENED_CHUNK_LOOP_FN(self, symbol, when, context, bufferStartTime, bufferMs, signal.id);
|
|
16564
|
+
const chunkResult = await RUN_OPENED_CHUNK_LOOP_FN(self, symbol, when, context, bufferStartTime, bufferMs, signal.id, frameEndTime);
|
|
16547
16565
|
if ("__error__" in chunkResult) {
|
|
16548
16566
|
console.error(`backtestLogicPrivateService opened signal: chunk loop failed, stopping backtest symbol=${symbol} signalId=${signal.id} reason=${chunkResult.reason} message=${chunkResult.message}`);
|
|
16549
16567
|
return chunkResult;
|
|
@@ -16609,86 +16627,103 @@ class BacktestLogicPrivateService {
|
|
|
16609
16627
|
symbol,
|
|
16610
16628
|
});
|
|
16611
16629
|
const backtestStartTime = performance.now();
|
|
16630
|
+
let _fatalError = null;
|
|
16631
|
+
let previousEventTimestamp = null;
|
|
16612
16632
|
const timeframes = await this.frameCoreService.getTimeframe(symbol, this.methodContextService.context.frameName);
|
|
16613
16633
|
const totalFrames = timeframes.length;
|
|
16634
|
+
let frameEndTime = timeframes[totalFrames - 1].getTime();
|
|
16614
16635
|
let i = 0;
|
|
16615
|
-
|
|
16616
|
-
|
|
16617
|
-
|
|
16618
|
-
|
|
16619
|
-
|
|
16620
|
-
|
|
16621
|
-
break;
|
|
16622
|
-
}
|
|
16623
|
-
const result = await TICK_FN(this, symbol, when);
|
|
16624
|
-
if ("__error__" in result) {
|
|
16625
|
-
break;
|
|
16626
|
-
}
|
|
16627
|
-
if (result.action === "idle" &&
|
|
16628
|
-
await functoolsKit.and(Promise.resolve(true), this.strategyCoreService.getStopped(true, symbol, {
|
|
16629
|
-
strategyName: this.methodContextService.context.strategyName,
|
|
16630
|
-
exchangeName: this.methodContextService.context.exchangeName,
|
|
16631
|
-
frameName: this.methodContextService.context.frameName,
|
|
16632
|
-
}))) {
|
|
16633
|
-
this.loggerService.info("backtestLogicPrivateService stopped by user request (idle state)", {
|
|
16634
|
-
symbol,
|
|
16635
|
-
when: when.toISOString(),
|
|
16636
|
-
processedFrames: i,
|
|
16637
|
-
totalFrames,
|
|
16638
|
-
});
|
|
16639
|
-
break;
|
|
16640
|
-
}
|
|
16641
|
-
if (result.action === "scheduled") {
|
|
16642
|
-
yield result;
|
|
16643
|
-
const r = yield* PROCESS_SCHEDULED_SIGNAL_FN(this, symbol, when, result, previousEventTimestamp);
|
|
16644
|
-
if (r.type === "error") {
|
|
16636
|
+
try {
|
|
16637
|
+
while (i < timeframes.length) {
|
|
16638
|
+
const timeframeStartTime = performance.now();
|
|
16639
|
+
const when = timeframes[i];
|
|
16640
|
+
await EMIT_PROGRESS_FN(this, symbol, totalFrames, i);
|
|
16641
|
+
if (await CHECK_STOPPED_FN(this, symbol, "before tick", { when: when.toISOString(), processedFrames: i, totalFrames })) {
|
|
16645
16642
|
break;
|
|
16646
16643
|
}
|
|
16647
|
-
|
|
16648
|
-
|
|
16649
|
-
|
|
16650
|
-
|
|
16651
|
-
}
|
|
16652
|
-
if (r.shouldStop) {
|
|
16653
|
-
break;
|
|
16654
|
-
}
|
|
16644
|
+
const result = await TICK_FN(this, symbol, when);
|
|
16645
|
+
if ("__error__" in result) {
|
|
16646
|
+
_fatalError = new Error(`[${result.reason}] ${result.message}`);
|
|
16647
|
+
break;
|
|
16655
16648
|
}
|
|
16656
|
-
|
|
16657
|
-
|
|
16658
|
-
|
|
16659
|
-
|
|
16660
|
-
|
|
16649
|
+
if (result.action === "idle" &&
|
|
16650
|
+
await functoolsKit.and(Promise.resolve(true), this.strategyCoreService.getStopped(true, symbol, {
|
|
16651
|
+
strategyName: this.methodContextService.context.strategyName,
|
|
16652
|
+
exchangeName: this.methodContextService.context.exchangeName,
|
|
16653
|
+
frameName: this.methodContextService.context.frameName,
|
|
16654
|
+
}))) {
|
|
16655
|
+
this.loggerService.info("backtestLogicPrivateService stopped by user request (idle state)", {
|
|
16656
|
+
symbol,
|
|
16657
|
+
when: when.toISOString(),
|
|
16658
|
+
processedFrames: i,
|
|
16659
|
+
totalFrames,
|
|
16660
|
+
});
|
|
16661
16661
|
break;
|
|
16662
16662
|
}
|
|
16663
|
-
if (
|
|
16664
|
-
|
|
16665
|
-
|
|
16666
|
-
|
|
16663
|
+
if (result.action === "scheduled") {
|
|
16664
|
+
yield result;
|
|
16665
|
+
const r = yield* PROCESS_SCHEDULED_SIGNAL_FN(this, symbol, when, result, previousEventTimestamp, frameEndTime);
|
|
16666
|
+
if (r.type === "error") {
|
|
16667
|
+
_fatalError = new Error(`[${r.reason}] ${r.message}`);
|
|
16668
|
+
break;
|
|
16669
|
+
}
|
|
16670
|
+
if (r.type === "closed") {
|
|
16671
|
+
previousEventTimestamp = r.previousEventTimestamp;
|
|
16672
|
+
while (i < timeframes.length && timeframes[i].getTime() < r.closeTimestamp) {
|
|
16673
|
+
i++;
|
|
16674
|
+
}
|
|
16675
|
+
if (r.shouldStop) {
|
|
16676
|
+
break;
|
|
16677
|
+
}
|
|
16667
16678
|
}
|
|
16668
|
-
|
|
16679
|
+
}
|
|
16680
|
+
if (result.action === "opened") {
|
|
16681
|
+
yield result;
|
|
16682
|
+
const r = yield* PROCESS_OPENED_SIGNAL_FN(this, symbol, when, result, previousEventTimestamp, frameEndTime);
|
|
16683
|
+
if (r.type === "error") {
|
|
16684
|
+
_fatalError = new Error(`[${r.reason}] ${r.message}`);
|
|
16669
16685
|
break;
|
|
16670
16686
|
}
|
|
16687
|
+
if (r.type === "closed") {
|
|
16688
|
+
previousEventTimestamp = r.previousEventTimestamp;
|
|
16689
|
+
while (i < timeframes.length && timeframes[i].getTime() < r.closeTimestamp) {
|
|
16690
|
+
i++;
|
|
16691
|
+
}
|
|
16692
|
+
if (r.shouldStop) {
|
|
16693
|
+
break;
|
|
16694
|
+
}
|
|
16695
|
+
}
|
|
16671
16696
|
}
|
|
16697
|
+
previousEventTimestamp = await EMIT_TIMEFRAME_PERFORMANCE_FN(this, symbol, timeframeStartTime, previousEventTimestamp);
|
|
16698
|
+
i++;
|
|
16672
16699
|
}
|
|
16673
|
-
|
|
16674
|
-
|
|
16675
|
-
|
|
16676
|
-
|
|
16677
|
-
|
|
16678
|
-
|
|
16679
|
-
|
|
16680
|
-
|
|
16681
|
-
|
|
16682
|
-
|
|
16683
|
-
|
|
16684
|
-
|
|
16685
|
-
|
|
16686
|
-
|
|
16687
|
-
|
|
16688
|
-
|
|
16689
|
-
|
|
16690
|
-
|
|
16691
|
-
|
|
16700
|
+
// Emit final progress event (100%)
|
|
16701
|
+
await EMIT_PROGRESS_FN(this, symbol, totalFrames, totalFrames);
|
|
16702
|
+
// Track total backtest duration
|
|
16703
|
+
const backtestEndTime = performance.now();
|
|
16704
|
+
const currentTimestamp = Date.now();
|
|
16705
|
+
await performanceEmitter.next({
|
|
16706
|
+
timestamp: currentTimestamp,
|
|
16707
|
+
previousTimestamp: previousEventTimestamp,
|
|
16708
|
+
metricType: "backtest_total",
|
|
16709
|
+
duration: backtestEndTime - backtestStartTime,
|
|
16710
|
+
strategyName: this.methodContextService.context.strategyName,
|
|
16711
|
+
exchangeName: this.methodContextService.context.exchangeName,
|
|
16712
|
+
frameName: this.methodContextService.context.frameName,
|
|
16713
|
+
symbol,
|
|
16714
|
+
backtest: true,
|
|
16715
|
+
});
|
|
16716
|
+
}
|
|
16717
|
+
catch (error) {
|
|
16718
|
+
_fatalError = error;
|
|
16719
|
+
}
|
|
16720
|
+
finally {
|
|
16721
|
+
if (_fatalError !== null) {
|
|
16722
|
+
console.error(`[BacktestLogicPrivateService] Fatal error — backtest sequence broken for symbol=${symbol} ` +
|
|
16723
|
+
`strategy=${this.methodContextService.context.strategyName}`, _fatalError);
|
|
16724
|
+
process.exit(-1);
|
|
16725
|
+
}
|
|
16726
|
+
}
|
|
16692
16727
|
}
|
|
16693
16728
|
}
|
|
16694
16729
|
|
|
@@ -33344,54 +33379,144 @@ const BROKER_BASE_METHOD_NAME_ON_TRAILING_STOP = "BrokerBase.onTrailingStopCommi
|
|
|
33344
33379
|
const BROKER_BASE_METHOD_NAME_ON_TRAILING_TAKE = "BrokerBase.onTrailingTakeCommit";
|
|
33345
33380
|
const BROKER_BASE_METHOD_NAME_ON_BREAKEVEN = "BrokerBase.onBreakevenCommit";
|
|
33346
33381
|
const BROKER_BASE_METHOD_NAME_ON_AVERAGE_BUY = "BrokerBase.onAverageBuyCommit";
|
|
33382
|
+
/**
|
|
33383
|
+
* Wrapper around a `Partial<IBroker>` adapter instance.
|
|
33384
|
+
*
|
|
33385
|
+
* Implements the full `IBroker` interface but guards every method call —
|
|
33386
|
+
* if the underlying adapter does not implement a given method, an error is thrown.
|
|
33387
|
+
* `waitForInit` is the only exception: it is silently skipped when not implemented.
|
|
33388
|
+
*
|
|
33389
|
+
* Created internally by `BrokerAdapter.useBrokerAdapter` and stored as
|
|
33390
|
+
* `_brokerInstance`. All `BrokerAdapter.commit*` methods delegate here
|
|
33391
|
+
* after backtest-mode and enable-state checks pass.
|
|
33392
|
+
*/
|
|
33347
33393
|
class BrokerProxy {
|
|
33348
33394
|
constructor(_instance) {
|
|
33349
33395
|
this._instance = _instance;
|
|
33396
|
+
/**
|
|
33397
|
+
* Calls `waitForInit` on the underlying adapter exactly once (singleshot).
|
|
33398
|
+
* If the adapter does not implement `waitForInit`, the call is silently skipped.
|
|
33399
|
+
*
|
|
33400
|
+
* @returns Resolves when initialization is complete (or immediately if not implemented).
|
|
33401
|
+
*/
|
|
33350
33402
|
this.waitForInit = functoolsKit.singleshot(async () => {
|
|
33351
33403
|
if (this._instance.waitForInit) {
|
|
33352
33404
|
await this._instance.waitForInit();
|
|
33405
|
+
return;
|
|
33353
33406
|
}
|
|
33354
33407
|
});
|
|
33355
33408
|
}
|
|
33409
|
+
/**
|
|
33410
|
+
* Forwards a signal-open event to the underlying adapter.
|
|
33411
|
+
* Throws if the adapter does not implement `onSignalOpenCommit`.
|
|
33412
|
+
*
|
|
33413
|
+
* @param payload - Signal open details: symbol, cost, position, prices, context, backtest flag.
|
|
33414
|
+
* @throws {Error} If the adapter does not implement `onSignalOpenCommit`.
|
|
33415
|
+
*/
|
|
33356
33416
|
async onSignalOpenCommit(payload) {
|
|
33357
33417
|
if (this._instance.onSignalOpenCommit) {
|
|
33358
33418
|
await this._instance.onSignalOpenCommit(payload);
|
|
33419
|
+
return;
|
|
33359
33420
|
}
|
|
33421
|
+
throw new Error("BrokerProxy onSignalOpenCommit is not implemented");
|
|
33360
33422
|
}
|
|
33423
|
+
/**
|
|
33424
|
+
* Forwards a signal-close event to the underlying adapter.
|
|
33425
|
+
* Throws if the adapter does not implement `onSignalCloseCommit`.
|
|
33426
|
+
*
|
|
33427
|
+
* @param payload - Signal close details: symbol, cost, position, currentPrice, pnl, context, backtest flag.
|
|
33428
|
+
* @throws {Error} If the adapter does not implement `onSignalCloseCommit`.
|
|
33429
|
+
*/
|
|
33361
33430
|
async onSignalCloseCommit(payload) {
|
|
33362
33431
|
if (this._instance.onSignalCloseCommit) {
|
|
33363
33432
|
await this._instance.onSignalCloseCommit(payload);
|
|
33433
|
+
return;
|
|
33364
33434
|
}
|
|
33435
|
+
throw new Error("BrokerProxy onSignalCloseCommit is not implemented");
|
|
33365
33436
|
}
|
|
33437
|
+
/**
|
|
33438
|
+
* Forwards a partial-profit close event to the underlying adapter.
|
|
33439
|
+
* Throws if the adapter does not implement `onPartialProfitCommit`.
|
|
33440
|
+
*
|
|
33441
|
+
* @param payload - Partial profit details: symbol, percentToClose, cost, currentPrice, context, backtest flag.
|
|
33442
|
+
* @throws {Error} If the adapter does not implement `onPartialProfitCommit`.
|
|
33443
|
+
*/
|
|
33366
33444
|
async onPartialProfitCommit(payload) {
|
|
33367
33445
|
if (this._instance.onPartialProfitCommit) {
|
|
33368
33446
|
await this._instance.onPartialProfitCommit(payload);
|
|
33447
|
+
return;
|
|
33369
33448
|
}
|
|
33449
|
+
throw new Error("BrokerProxy onPartialProfitCommit is not implemented");
|
|
33370
33450
|
}
|
|
33451
|
+
/**
|
|
33452
|
+
* Forwards a partial-loss close event to the underlying adapter.
|
|
33453
|
+
* Throws if the adapter does not implement `onPartialLossCommit`.
|
|
33454
|
+
*
|
|
33455
|
+
* @param payload - Partial loss details: symbol, percentToClose, cost, currentPrice, context, backtest flag.
|
|
33456
|
+
* @throws {Error} If the adapter does not implement `onPartialLossCommit`.
|
|
33457
|
+
*/
|
|
33371
33458
|
async onPartialLossCommit(payload) {
|
|
33372
33459
|
if (this._instance.onPartialLossCommit) {
|
|
33373
33460
|
await this._instance.onPartialLossCommit(payload);
|
|
33461
|
+
return;
|
|
33374
33462
|
}
|
|
33463
|
+
throw new Error("BrokerProxy onPartialLossCommit is not implemented");
|
|
33375
33464
|
}
|
|
33465
|
+
/**
|
|
33466
|
+
* Forwards a trailing stop-loss update event to the underlying adapter.
|
|
33467
|
+
* Throws if the adapter does not implement `onTrailingStopCommit`.
|
|
33468
|
+
*
|
|
33469
|
+
* @param payload - Trailing stop details: symbol, percentShift, currentPrice, newStopLossPrice, context, backtest flag.
|
|
33470
|
+
* @throws {Error} If the adapter does not implement `onTrailingStopCommit`.
|
|
33471
|
+
*/
|
|
33376
33472
|
async onTrailingStopCommit(payload) {
|
|
33377
33473
|
if (this._instance.onTrailingStopCommit) {
|
|
33378
33474
|
await this._instance.onTrailingStopCommit(payload);
|
|
33475
|
+
return;
|
|
33379
33476
|
}
|
|
33477
|
+
throw new Error("BrokerProxy onTrailingStopCommit is not implemented");
|
|
33380
33478
|
}
|
|
33479
|
+
/**
|
|
33480
|
+
* Forwards a trailing take-profit update event to the underlying adapter.
|
|
33481
|
+
* Throws if the adapter does not implement `onTrailingTakeCommit`.
|
|
33482
|
+
*
|
|
33483
|
+
* @param payload - Trailing take details: symbol, percentShift, currentPrice, newTakeProfitPrice, context, backtest flag.
|
|
33484
|
+
* @throws {Error} If the adapter does not implement `onTrailingTakeCommit`.
|
|
33485
|
+
*/
|
|
33381
33486
|
async onTrailingTakeCommit(payload) {
|
|
33382
33487
|
if (this._instance.onTrailingTakeCommit) {
|
|
33383
33488
|
await this._instance.onTrailingTakeCommit(payload);
|
|
33489
|
+
return;
|
|
33384
33490
|
}
|
|
33491
|
+
throw new Error("BrokerProxy onTrailingTakeCommit is not implemented");
|
|
33385
33492
|
}
|
|
33493
|
+
/**
|
|
33494
|
+
* Forwards a breakeven event to the underlying adapter.
|
|
33495
|
+
* Throws if the adapter does not implement `onBreakevenCommit`.
|
|
33496
|
+
*
|
|
33497
|
+
* @param payload - Breakeven details: symbol, currentPrice, newStopLossPrice (= effectivePriceOpen), newTakeProfitPrice, context, backtest flag.
|
|
33498
|
+
* @throws {Error} If the adapter does not implement `onBreakevenCommit`.
|
|
33499
|
+
*/
|
|
33386
33500
|
async onBreakevenCommit(payload) {
|
|
33387
33501
|
if (this._instance.onBreakevenCommit) {
|
|
33388
33502
|
await this._instance.onBreakevenCommit(payload);
|
|
33503
|
+
return;
|
|
33389
33504
|
}
|
|
33505
|
+
throw new Error("BrokerProxy onBreakevenCommit is not implemented");
|
|
33390
33506
|
}
|
|
33507
|
+
/**
|
|
33508
|
+
* Forwards a DCA average-buy entry event to the underlying adapter.
|
|
33509
|
+
* Throws if the adapter does not implement `onAverageBuyCommit`.
|
|
33510
|
+
*
|
|
33511
|
+
* @param payload - Average buy details: symbol, currentPrice, cost, context, backtest flag.
|
|
33512
|
+
* @throws {Error} If the adapter does not implement `onAverageBuyCommit`.
|
|
33513
|
+
*/
|
|
33391
33514
|
async onAverageBuyCommit(payload) {
|
|
33392
33515
|
if (this._instance.onAverageBuyCommit) {
|
|
33393
33516
|
await this._instance.onAverageBuyCommit(payload);
|
|
33517
|
+
return;
|
|
33394
33518
|
}
|
|
33519
|
+
throw new Error("BrokerProxy onAverageBuyCommit is not implemented");
|
|
33395
33520
|
}
|
|
33396
33521
|
}
|
|
33397
33522
|
/**
|
|
@@ -43163,7 +43288,7 @@ class MemoryLocalInstance {
|
|
|
43163
43288
|
* @param value - Value to store and index
|
|
43164
43289
|
* @param index - Optional BM25 index string; defaults to JSON.stringify(value)
|
|
43165
43290
|
*/
|
|
43166
|
-
async writeMemory(memoryId, value,
|
|
43291
|
+
async writeMemory(memoryId, value, description) {
|
|
43167
43292
|
bt.loggerService.debug(MEMORY_LOCAL_INSTANCE_METHOD_NAME_WRITE, {
|
|
43168
43293
|
signalId: this.signalId,
|
|
43169
43294
|
bucketName: this.bucketName,
|
|
@@ -43172,7 +43297,7 @@ class MemoryLocalInstance {
|
|
|
43172
43297
|
this._index.upsert({
|
|
43173
43298
|
id: memoryId,
|
|
43174
43299
|
content: value,
|
|
43175
|
-
index:
|
|
43300
|
+
index: description,
|
|
43176
43301
|
priority: Date.now(),
|
|
43177
43302
|
});
|
|
43178
43303
|
}
|
|
@@ -43471,7 +43596,7 @@ class MemoryAdapter {
|
|
|
43471
43596
|
* @param dto.value - Value to store
|
|
43472
43597
|
* @param dto.signalId - Signal identifier
|
|
43473
43598
|
* @param dto.bucketName - Bucket name
|
|
43474
|
-
* @param dto.
|
|
43599
|
+
* @param dto.description - Optional BM25 index string; defaults to JSON.stringify(value)
|
|
43475
43600
|
*/
|
|
43476
43601
|
this.writeMemory = async (dto) => {
|
|
43477
43602
|
if (!this.enable.hasValue()) {
|
|
@@ -43486,7 +43611,7 @@ class MemoryAdapter {
|
|
|
43486
43611
|
const isInitial = !this.getInstance.has(key);
|
|
43487
43612
|
const instance = this.getInstance(dto.signalId, dto.bucketName);
|
|
43488
43613
|
await instance.waitForInit(isInitial);
|
|
43489
|
-
return await instance.writeMemory(dto.memoryId, dto.value, dto.
|
|
43614
|
+
return await instance.writeMemory(dto.memoryId, dto.value, dto.description);
|
|
43490
43615
|
};
|
|
43491
43616
|
/**
|
|
43492
43617
|
* Search memory using BM25 full-text scoring.
|
|
@@ -43637,7 +43762,7 @@ const REMOVE_MEMORY_METHOD_NAME = "memory.removeMemory";
|
|
|
43637
43762
|
* ```
|
|
43638
43763
|
*/
|
|
43639
43764
|
async function writeMemory(dto) {
|
|
43640
|
-
const { bucketName, memoryId, value } = dto;
|
|
43765
|
+
const { bucketName, memoryId, value, description } = dto;
|
|
43641
43766
|
bt.loggerService.info(WRITE_MEMORY_METHOD_NAME, {
|
|
43642
43767
|
bucketName,
|
|
43643
43768
|
memoryId,
|
|
@@ -43661,6 +43786,7 @@ async function writeMemory(dto) {
|
|
|
43661
43786
|
value,
|
|
43662
43787
|
signalId: signal.id,
|
|
43663
43788
|
bucketName,
|
|
43789
|
+
description,
|
|
43664
43790
|
});
|
|
43665
43791
|
}
|
|
43666
43792
|
/**
|
|
@@ -44104,7 +44230,7 @@ class DumpMemoryInstance {
|
|
|
44104
44230
|
bucketName: this.bucketName,
|
|
44105
44231
|
signalId: this.signalId,
|
|
44106
44232
|
value: { messages },
|
|
44107
|
-
|
|
44233
|
+
description,
|
|
44108
44234
|
});
|
|
44109
44235
|
}
|
|
44110
44236
|
/**
|
|
@@ -44125,7 +44251,7 @@ class DumpMemoryInstance {
|
|
|
44125
44251
|
bucketName: this.bucketName,
|
|
44126
44252
|
signalId: this.signalId,
|
|
44127
44253
|
value: record,
|
|
44128
|
-
|
|
44254
|
+
description,
|
|
44129
44255
|
});
|
|
44130
44256
|
}
|
|
44131
44257
|
/**
|
|
@@ -44147,7 +44273,7 @@ class DumpMemoryInstance {
|
|
|
44147
44273
|
bucketName: this.bucketName,
|
|
44148
44274
|
signalId: this.signalId,
|
|
44149
44275
|
value: { rows },
|
|
44150
|
-
|
|
44276
|
+
description,
|
|
44151
44277
|
});
|
|
44152
44278
|
}
|
|
44153
44279
|
/**
|
|
@@ -44168,7 +44294,7 @@ class DumpMemoryInstance {
|
|
|
44168
44294
|
bucketName: this.bucketName,
|
|
44169
44295
|
signalId: this.signalId,
|
|
44170
44296
|
value: { content },
|
|
44171
|
-
|
|
44297
|
+
description,
|
|
44172
44298
|
});
|
|
44173
44299
|
}
|
|
44174
44300
|
/**
|
|
@@ -44189,7 +44315,7 @@ class DumpMemoryInstance {
|
|
|
44189
44315
|
bucketName: this.bucketName,
|
|
44190
44316
|
signalId: this.signalId,
|
|
44191
44317
|
value: { content },
|
|
44192
|
-
|
|
44318
|
+
description,
|
|
44193
44319
|
});
|
|
44194
44320
|
}
|
|
44195
44321
|
/**
|
|
@@ -44211,7 +44337,7 @@ class DumpMemoryInstance {
|
|
|
44211
44337
|
bucketName: this.bucketName,
|
|
44212
44338
|
signalId: this.signalId,
|
|
44213
44339
|
value: json,
|
|
44214
|
-
|
|
44340
|
+
description,
|
|
44215
44341
|
});
|
|
44216
44342
|
}
|
|
44217
44343
|
/** Releases resources held by this instance. */
|