backtest-kit 2.2.7 → 2.2.8

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/build/index.cjs CHANGED
@@ -6554,6 +6554,40 @@ class RiskUtils {
6554
6554
  */
6555
6555
  const Risk = new RiskUtils();
6556
6556
 
6557
+ /**
6558
+ * Emits signal tick results with correct execution context timestamp.
6559
+ * Wraps emitter calls in ExecutionContextService.runInContext to preserve
6560
+ * the temporal context from the tick's createdAt timestamp.
6561
+ */
6562
+ const CALL_SIGNAL_EMIT_FN = functoolsKit.trycatch(beginTime(async (self, tick, context, isBacktest, symbol) => {
6563
+ await ExecutionContextService.runInContext(async () => {
6564
+ if (isBacktest) {
6565
+ await signalBacktestEmitter.next(tick);
6566
+ await self.actionCoreService.signalBacktest(isBacktest, tick, context);
6567
+ }
6568
+ if (!isBacktest) {
6569
+ await signalLiveEmitter.next(tick);
6570
+ await self.actionCoreService.signalLive(isBacktest, tick, context);
6571
+ }
6572
+ await signalEmitter.next(tick);
6573
+ await self.actionCoreService.signal(isBacktest, tick, context);
6574
+ }, {
6575
+ when: new Date(tick.createdAt),
6576
+ symbol: symbol,
6577
+ backtest: isBacktest,
6578
+ });
6579
+ }), {
6580
+ fallback: (error) => {
6581
+ const message = "StrategyConnectionService CALL_SIGNAL_EMIT_FN thrown";
6582
+ const payload = {
6583
+ error: functoolsKit.errorData(error),
6584
+ message: functoolsKit.getErrorMessage(error),
6585
+ };
6586
+ bt.loggerService.warn(message, payload);
6587
+ console.warn(message, payload);
6588
+ errorEmitter.next(error);
6589
+ },
6590
+ });
6557
6591
  /**
6558
6592
  * No-operation IRisk implementation.
6559
6593
  * Always allows signals and performs no actions.
@@ -6926,16 +6960,7 @@ class StrategyConnectionService {
6926
6960
  await strategy.waitForInit();
6927
6961
  const tick = await strategy.tick(symbol, context.strategyName);
6928
6962
  {
6929
- if (this.executionContextService.context.backtest) {
6930
- await signalBacktestEmitter.next(tick);
6931
- await this.actionCoreService.signalBacktest(backtest, tick, context);
6932
- }
6933
- if (!this.executionContextService.context.backtest) {
6934
- await signalLiveEmitter.next(tick);
6935
- await this.actionCoreService.signalLive(backtest, tick, context);
6936
- }
6937
- await signalEmitter.next(tick);
6938
- await this.actionCoreService.signal(backtest, tick, context);
6963
+ await CALL_SIGNAL_EMIT_FN(this, tick, context, backtest, symbol);
6939
6964
  }
6940
6965
  return tick;
6941
6966
  };
@@ -6962,16 +6987,7 @@ class StrategyConnectionService {
6962
6987
  await strategy.waitForInit();
6963
6988
  const tick = await strategy.backtest(symbol, context.strategyName, candles);
6964
6989
  {
6965
- if (this.executionContextService.context.backtest) {
6966
- await signalBacktestEmitter.next(tick);
6967
- await this.actionCoreService.signalBacktest(backtest, tick, context);
6968
- }
6969
- if (!this.executionContextService.context.backtest) {
6970
- await signalLiveEmitter.next(tick);
6971
- await this.actionCoreService.signalLive(backtest, tick, context);
6972
- }
6973
- await signalEmitter.next(tick);
6974
- await this.actionCoreService.signal(backtest, tick, context);
6990
+ await CALL_SIGNAL_EMIT_FN(this, tick, context, backtest, symbol);
6975
6991
  }
6976
6992
  return tick;
6977
6993
  };
@@ -12001,6 +12017,7 @@ class BacktestLogicPrivateService {
12001
12017
  this.exchangeCoreService = inject(TYPES.exchangeCoreService);
12002
12018
  this.frameCoreService = inject(TYPES.frameCoreService);
12003
12019
  this.methodContextService = inject(TYPES.methodContextService);
12020
+ this.actionCoreService = inject(TYPES.actionCoreService);
12004
12021
  }
12005
12022
  /**
12006
12023
  * Runs backtest for a symbol, streaming closed signals as async generator.
@@ -12147,7 +12164,14 @@ class BacktestLogicPrivateService {
12147
12164
  isOk = isOk && event.symbol === symbol;
12148
12165
  }
12149
12166
  return isOk;
12150
- }).connect(async (tick) => await signalBacktestEmitter.next(tick));
12167
+ }).connect(async (tick) => {
12168
+ await signalBacktestEmitter.next(tick);
12169
+ await this.actionCoreService.signalBacktest(true, tick, {
12170
+ strategyName,
12171
+ exchangeName,
12172
+ frameName,
12173
+ });
12174
+ });
12151
12175
  }
12152
12176
  try {
12153
12177
  backtestResult = await this.strategyCoreService.backtest(symbol, candles, when, true, {
package/build/index.mjs CHANGED
@@ -6534,6 +6534,40 @@ class RiskUtils {
6534
6534
  */
6535
6535
  const Risk = new RiskUtils();
6536
6536
 
6537
+ /**
6538
+ * Emits signal tick results with correct execution context timestamp.
6539
+ * Wraps emitter calls in ExecutionContextService.runInContext to preserve
6540
+ * the temporal context from the tick's createdAt timestamp.
6541
+ */
6542
+ const CALL_SIGNAL_EMIT_FN = trycatch(beginTime(async (self, tick, context, isBacktest, symbol) => {
6543
+ await ExecutionContextService.runInContext(async () => {
6544
+ if (isBacktest) {
6545
+ await signalBacktestEmitter.next(tick);
6546
+ await self.actionCoreService.signalBacktest(isBacktest, tick, context);
6547
+ }
6548
+ if (!isBacktest) {
6549
+ await signalLiveEmitter.next(tick);
6550
+ await self.actionCoreService.signalLive(isBacktest, tick, context);
6551
+ }
6552
+ await signalEmitter.next(tick);
6553
+ await self.actionCoreService.signal(isBacktest, tick, context);
6554
+ }, {
6555
+ when: new Date(tick.createdAt),
6556
+ symbol: symbol,
6557
+ backtest: isBacktest,
6558
+ });
6559
+ }), {
6560
+ fallback: (error) => {
6561
+ const message = "StrategyConnectionService CALL_SIGNAL_EMIT_FN thrown";
6562
+ const payload = {
6563
+ error: errorData(error),
6564
+ message: getErrorMessage(error),
6565
+ };
6566
+ bt.loggerService.warn(message, payload);
6567
+ console.warn(message, payload);
6568
+ errorEmitter.next(error);
6569
+ },
6570
+ });
6537
6571
  /**
6538
6572
  * No-operation IRisk implementation.
6539
6573
  * Always allows signals and performs no actions.
@@ -6906,16 +6940,7 @@ class StrategyConnectionService {
6906
6940
  await strategy.waitForInit();
6907
6941
  const tick = await strategy.tick(symbol, context.strategyName);
6908
6942
  {
6909
- if (this.executionContextService.context.backtest) {
6910
- await signalBacktestEmitter.next(tick);
6911
- await this.actionCoreService.signalBacktest(backtest, tick, context);
6912
- }
6913
- if (!this.executionContextService.context.backtest) {
6914
- await signalLiveEmitter.next(tick);
6915
- await this.actionCoreService.signalLive(backtest, tick, context);
6916
- }
6917
- await signalEmitter.next(tick);
6918
- await this.actionCoreService.signal(backtest, tick, context);
6943
+ await CALL_SIGNAL_EMIT_FN(this, tick, context, backtest, symbol);
6919
6944
  }
6920
6945
  return tick;
6921
6946
  };
@@ -6942,16 +6967,7 @@ class StrategyConnectionService {
6942
6967
  await strategy.waitForInit();
6943
6968
  const tick = await strategy.backtest(symbol, context.strategyName, candles);
6944
6969
  {
6945
- if (this.executionContextService.context.backtest) {
6946
- await signalBacktestEmitter.next(tick);
6947
- await this.actionCoreService.signalBacktest(backtest, tick, context);
6948
- }
6949
- if (!this.executionContextService.context.backtest) {
6950
- await signalLiveEmitter.next(tick);
6951
- await this.actionCoreService.signalLive(backtest, tick, context);
6952
- }
6953
- await signalEmitter.next(tick);
6954
- await this.actionCoreService.signal(backtest, tick, context);
6970
+ await CALL_SIGNAL_EMIT_FN(this, tick, context, backtest, symbol);
6955
6971
  }
6956
6972
  return tick;
6957
6973
  };
@@ -11981,6 +11997,7 @@ class BacktestLogicPrivateService {
11981
11997
  this.exchangeCoreService = inject(TYPES.exchangeCoreService);
11982
11998
  this.frameCoreService = inject(TYPES.frameCoreService);
11983
11999
  this.methodContextService = inject(TYPES.methodContextService);
12000
+ this.actionCoreService = inject(TYPES.actionCoreService);
11984
12001
  }
11985
12002
  /**
11986
12003
  * Runs backtest for a symbol, streaming closed signals as async generator.
@@ -12127,7 +12144,14 @@ class BacktestLogicPrivateService {
12127
12144
  isOk = isOk && event.symbol === symbol;
12128
12145
  }
12129
12146
  return isOk;
12130
- }).connect(async (tick) => await signalBacktestEmitter.next(tick));
12147
+ }).connect(async (tick) => {
12148
+ await signalBacktestEmitter.next(tick);
12149
+ await this.actionCoreService.signalBacktest(true, tick, {
12150
+ strategyName,
12151
+ exchangeName,
12152
+ frameName,
12153
+ });
12154
+ });
12131
12155
  }
12132
12156
  try {
12133
12157
  backtestResult = await this.strategyCoreService.backtest(symbol, candles, when, true, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backtest-kit",
3
- "version": "2.2.7",
3
+ "version": "2.2.8",
4
4
  "description": "A TypeScript library for trading system backtest",
5
5
  "author": {
6
6
  "name": "Petr Tripolsky",
package/types.d.ts CHANGED
@@ -17436,6 +17436,7 @@ declare class BacktestLogicPrivateService {
17436
17436
  private readonly exchangeCoreService;
17437
17437
  private readonly frameCoreService;
17438
17438
  private readonly methodContextService;
17439
+ private readonly actionCoreService;
17439
17440
  /**
17440
17441
  * Runs backtest for a symbol, streaming closed signals as async generator.
17441
17442
  *