backtest-kit 2.2.3 → 2.2.6

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
@@ -3702,6 +3702,7 @@ const CHECK_SCHEDULED_SIGNAL_TIMEOUT_FN = async (self, scheduled, currentPrice)
3702
3702
  symbol: self.params.execution.context.symbol,
3703
3703
  backtest: self.params.execution.context.backtest,
3704
3704
  reason: "timeout",
3705
+ createdAt: currentTime,
3705
3706
  };
3706
3707
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
3707
3708
  return result;
@@ -3757,6 +3758,7 @@ const CANCEL_SCHEDULED_SIGNAL_BY_STOPLOSS_FN = async (self, scheduled, currentPr
3757
3758
  symbol: self.params.execution.context.symbol,
3758
3759
  backtest: self.params.execution.context.backtest,
3759
3760
  reason: "price_reject",
3761
+ createdAt: currentTime,
3760
3762
  };
3761
3763
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
3762
3764
  return result;
@@ -3812,6 +3814,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
3812
3814
  symbol: self.params.execution.context.symbol,
3813
3815
  currentPrice: self._pendingSignal.priceOpen,
3814
3816
  backtest: self.params.execution.context.backtest,
3817
+ createdAt: activationTime,
3815
3818
  };
3816
3819
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, activationTime, self.params.execution.context.backtest);
3817
3820
  return result;
@@ -4244,6 +4247,7 @@ const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice)
4244
4247
  percentSl: 0,
4245
4248
  pnl,
4246
4249
  backtest: self.params.execution.context.backtest,
4250
+ createdAt: currentTime,
4247
4251
  };
4248
4252
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4249
4253
  return result;
@@ -4268,6 +4272,7 @@ const OPEN_NEW_SCHEDULED_SIGNAL_FN = async (self, signal) => {
4268
4272
  symbol: self.params.execution.context.symbol,
4269
4273
  currentPrice: currentPrice,
4270
4274
  backtest: self.params.execution.context.backtest,
4275
+ createdAt: currentTime,
4271
4276
  };
4272
4277
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4273
4278
  return result;
@@ -4288,6 +4293,7 @@ const OPEN_NEW_PENDING_SIGNAL_FN = async (self, signal) => {
4288
4293
  symbol: self.params.execution.context.symbol,
4289
4294
  currentPrice: signal.priceOpen,
4290
4295
  backtest: self.params.execution.context.backtest,
4296
+ createdAt: currentTime,
4291
4297
  };
4292
4298
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4293
4299
  return result;
@@ -4352,6 +4358,7 @@ const CLOSE_PENDING_SIGNAL_FN = async (self, signal, currentPrice, closeReason)
4352
4358
  frameName: self.params.method.context.frameName,
4353
4359
  symbol: self.params.execution.context.symbol,
4354
4360
  backtest: self.params.execution.context.backtest,
4361
+ createdAt: currentTime,
4355
4362
  };
4356
4363
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4357
4364
  return result;
@@ -4425,6 +4432,7 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice) => {
4425
4432
  percentSl,
4426
4433
  pnl,
4427
4434
  backtest: self.params.execution.context.backtest,
4435
+ createdAt: currentTime,
4428
4436
  };
4429
4437
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4430
4438
  return result;
@@ -4441,6 +4449,7 @@ const RETURN_IDLE_FN = async (self, currentPrice) => {
4441
4449
  symbol: self.params.execution.context.symbol,
4442
4450
  currentPrice: currentPrice,
4443
4451
  backtest: self.params.execution.context.backtest,
4452
+ createdAt: currentTime,
4444
4453
  };
4445
4454
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4446
4455
  return result;
@@ -4467,6 +4476,7 @@ const CANCEL_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, averagePr
4467
4476
  symbol: self.params.execution.context.symbol,
4468
4477
  backtest: self.params.execution.context.backtest,
4469
4478
  reason,
4479
+ createdAt: closeTimestamp,
4470
4480
  };
4471
4481
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, closeTimestamp, self.params.execution.context.backtest);
4472
4482
  return result;
@@ -4547,6 +4557,7 @@ const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, c
4547
4557
  frameName: self.params.method.context.frameName,
4548
4558
  symbol: self.params.execution.context.symbol,
4549
4559
  backtest: self.params.execution.context.backtest,
4560
+ createdAt: closeTimestamp,
4550
4561
  };
4551
4562
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, closeTimestamp, self.params.execution.context.backtest);
4552
4563
  return result;
@@ -5063,6 +5074,7 @@ class ClientStrategy {
5063
5074
  backtest: this.params.execution.context.backtest,
5064
5075
  reason: "user",
5065
5076
  cancelId: cancelledSignal.cancelId,
5077
+ createdAt: currentTime,
5066
5078
  };
5067
5079
  await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, result, currentTime, this.params.execution.context.backtest);
5068
5080
  return result;
@@ -5097,6 +5109,7 @@ class ClientStrategy {
5097
5109
  symbol: this.params.execution.context.symbol,
5098
5110
  backtest: this.params.execution.context.backtest,
5099
5111
  closeId: closedSignal.closeId,
5112
+ createdAt: currentTime,
5100
5113
  };
5101
5114
  await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, result, currentTime, this.params.execution.context.backtest);
5102
5115
  return result;
@@ -5211,6 +5224,7 @@ class ClientStrategy {
5211
5224
  backtest: true,
5212
5225
  reason: "user",
5213
5226
  cancelId: cancelledSignal.cancelId,
5227
+ createdAt: closeTimestamp,
5214
5228
  };
5215
5229
  await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, cancelledResult, closeTimestamp, this.params.execution.context.backtest);
5216
5230
  return cancelledResult;
@@ -5242,6 +5256,7 @@ class ClientStrategy {
5242
5256
  symbol: this.params.execution.context.symbol,
5243
5257
  backtest: true,
5244
5258
  closeId: closedSignal.closeId,
5259
+ createdAt: closeTimestamp,
5245
5260
  };
5246
5261
  await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, closedResult, closeTimestamp, this.params.execution.context.backtest);
5247
5262
  return closedResult;
@@ -32356,6 +32371,7 @@ class NotificationInstance {
32356
32371
  priceTakeProfit: data.signal.priceTakeProfit,
32357
32372
  priceStopLoss: data.signal.priceStopLoss,
32358
32373
  note: data.signal.note,
32374
+ createdAt: data.createdAt,
32359
32375
  });
32360
32376
  }
32361
32377
  else if (data.action === "closed") {
@@ -32377,6 +32393,7 @@ class NotificationInstance {
32377
32393
  closeReason: data.closeReason,
32378
32394
  duration: durationMin,
32379
32395
  note: data.signal.note,
32396
+ createdAt: data.createdAt,
32380
32397
  });
32381
32398
  }
32382
32399
  else if (data.action === "scheduled") {
@@ -32393,6 +32410,7 @@ class NotificationInstance {
32393
32410
  priceOpen: data.signal.priceOpen,
32394
32411
  scheduledAt: data.signal.scheduledAt,
32395
32412
  currentPrice: data.currentPrice,
32413
+ createdAt: data.createdAt,
32396
32414
  });
32397
32415
  }
32398
32416
  else if (data.action === "cancelled") {
@@ -32411,6 +32429,7 @@ class NotificationInstance {
32411
32429
  cancelReason: data.reason,
32412
32430
  cancelId: data.cancelId,
32413
32431
  duration: durationMin,
32432
+ createdAt: data.createdAt,
32414
32433
  });
32415
32434
  }
32416
32435
  };
@@ -32419,7 +32438,7 @@ class NotificationInstance {
32419
32438
  */
32420
32439
  this._handlePartialProfit = async (data) => {
32421
32440
  this._addNotification({
32422
- type: "partial.profit",
32441
+ type: "partial_profit.available",
32423
32442
  id: CREATE_KEY_FN(),
32424
32443
  timestamp: data.timestamp,
32425
32444
  backtest: data.backtest,
@@ -32438,7 +32457,7 @@ class NotificationInstance {
32438
32457
  */
32439
32458
  this._handlePartialLoss = async (data) => {
32440
32459
  this._addNotification({
32441
- type: "partial.loss",
32460
+ type: "partial_loss.available",
32442
32461
  id: CREATE_KEY_FN(),
32443
32462
  timestamp: data.timestamp,
32444
32463
  backtest: data.backtest,
@@ -32453,50 +32472,109 @@ class NotificationInstance {
32453
32472
  });
32454
32473
  };
32455
32474
  /**
32456
- * Processes risk rejection events.
32475
+ * Processes breakeven events.
32457
32476
  */
32458
- this._handleRisk = async (data) => {
32477
+ this._handleBreakeven = async (data) => {
32459
32478
  this._addNotification({
32460
- type: "risk.rejection",
32479
+ type: "breakeven.available",
32461
32480
  id: CREATE_KEY_FN(),
32462
32481
  timestamp: data.timestamp,
32463
32482
  backtest: data.backtest,
32464
32483
  symbol: data.symbol,
32465
32484
  strategyName: data.strategyName,
32466
32485
  exchangeName: data.exchangeName,
32467
- rejectionNote: data.rejectionNote,
32468
- rejectionId: data.rejectionId,
32469
- activePositionCount: data.activePositionCount,
32486
+ signalId: data.data.id,
32470
32487
  currentPrice: data.currentPrice,
32471
- pendingSignal: data.pendingSignal,
32488
+ priceOpen: data.data.priceOpen,
32489
+ position: data.data.position,
32472
32490
  });
32473
32491
  };
32474
32492
  /**
32475
- * Processes done events (live/backtest).
32493
+ * Processes strategy commit events.
32476
32494
  */
32477
- this._handleDoneLive = async (data) => {
32478
- this._addNotification({
32479
- type: "live.done",
32480
- id: CREATE_KEY_FN(),
32481
- timestamp: Date.now(),
32482
- backtest: false,
32483
- symbol: data.symbol,
32484
- strategyName: data.strategyName,
32485
- exchangeName: data.exchangeName,
32486
- });
32495
+ this._handleStrategyCommit = async (data) => {
32496
+ if (data.action === "partial-profit") {
32497
+ this._addNotification({
32498
+ type: "partial_profit.commit",
32499
+ id: CREATE_KEY_FN(),
32500
+ timestamp: Date.now(),
32501
+ backtest: data.backtest,
32502
+ symbol: data.symbol,
32503
+ strategyName: data.strategyName,
32504
+ exchangeName: data.exchangeName,
32505
+ percentToClose: data.percentToClose,
32506
+ currentPrice: data.currentPrice,
32507
+ });
32508
+ }
32509
+ else if (data.action === "partial-loss") {
32510
+ this._addNotification({
32511
+ type: "partial_loss.commit",
32512
+ id: CREATE_KEY_FN(),
32513
+ timestamp: Date.now(),
32514
+ backtest: data.backtest,
32515
+ symbol: data.symbol,
32516
+ strategyName: data.strategyName,
32517
+ exchangeName: data.exchangeName,
32518
+ percentToClose: data.percentToClose,
32519
+ currentPrice: data.currentPrice,
32520
+ });
32521
+ }
32522
+ else if (data.action === "breakeven") {
32523
+ this._addNotification({
32524
+ type: "breakeven.commit",
32525
+ id: CREATE_KEY_FN(),
32526
+ timestamp: Date.now(),
32527
+ backtest: data.backtest,
32528
+ symbol: data.symbol,
32529
+ strategyName: data.strategyName,
32530
+ exchangeName: data.exchangeName,
32531
+ currentPrice: data.currentPrice,
32532
+ });
32533
+ }
32534
+ else if (data.action === "trailing-stop") {
32535
+ this._addNotification({
32536
+ type: "trailing_stop.commit",
32537
+ id: CREATE_KEY_FN(),
32538
+ timestamp: Date.now(),
32539
+ backtest: data.backtest,
32540
+ symbol: data.symbol,
32541
+ strategyName: data.strategyName,
32542
+ exchangeName: data.exchangeName,
32543
+ percentShift: data.percentShift,
32544
+ currentPrice: data.currentPrice,
32545
+ });
32546
+ }
32547
+ else if (data.action === "trailing-take") {
32548
+ this._addNotification({
32549
+ type: "trailing_take.commit",
32550
+ id: CREATE_KEY_FN(),
32551
+ timestamp: Date.now(),
32552
+ backtest: data.backtest,
32553
+ symbol: data.symbol,
32554
+ strategyName: data.strategyName,
32555
+ exchangeName: data.exchangeName,
32556
+ percentShift: data.percentShift,
32557
+ currentPrice: data.currentPrice,
32558
+ });
32559
+ }
32487
32560
  };
32488
32561
  /**
32489
- * Processes done events (backtest).
32562
+ * Processes risk rejection events.
32490
32563
  */
32491
- this._handleDoneBacktest = async (data) => {
32564
+ this._handleRisk = async (data) => {
32492
32565
  this._addNotification({
32493
- type: "backtest.done",
32566
+ type: "risk.rejection",
32494
32567
  id: CREATE_KEY_FN(),
32495
- timestamp: Date.now(),
32496
- backtest: true,
32568
+ timestamp: data.timestamp,
32569
+ backtest: data.backtest,
32497
32570
  symbol: data.symbol,
32498
32571
  strategyName: data.strategyName,
32499
32572
  exchangeName: data.exchangeName,
32573
+ rejectionNote: data.rejectionNote,
32574
+ rejectionId: data.rejectionId,
32575
+ activePositionCount: data.activePositionCount,
32576
+ currentPrice: data.currentPrice,
32577
+ pendingSignal: data.pendingSignal,
32500
32578
  });
32501
32579
  };
32502
32580
  /**
@@ -32538,23 +32616,6 @@ class NotificationInstance {
32538
32616
  backtest: false,
32539
32617
  });
32540
32618
  };
32541
- /**
32542
- * Processes progress events.
32543
- */
32544
- this._handleProgressBacktest = async (data) => {
32545
- this._addNotification({
32546
- type: "progress.backtest",
32547
- id: CREATE_KEY_FN(),
32548
- timestamp: Date.now(),
32549
- backtest: true,
32550
- exchangeName: data.exchangeName,
32551
- strategyName: data.strategyName,
32552
- symbol: data.symbol,
32553
- totalFrames: data.totalFrames,
32554
- processedFrames: data.processedFrames,
32555
- progress: data.progress,
32556
- });
32557
- };
32558
32619
  /**
32559
32620
  * Subscribes to all notification emitters and returns an unsubscribe function.
32560
32621
  * Protected against multiple subscriptions using singleshot.
@@ -32573,14 +32634,13 @@ class NotificationInstance {
32573
32634
  const unSignal = signalEmitter.subscribe(this._handleSignal);
32574
32635
  const unProfit = partialProfitSubject.subscribe(this._handlePartialProfit);
32575
32636
  const unLoss = partialLossSubject.subscribe(this._handlePartialLoss);
32637
+ const unBreakeven = breakevenSubject.subscribe(this._handleBreakeven);
32638
+ const unStrategyCommit = strategyCommitSubject.subscribe(this._handleStrategyCommit);
32576
32639
  const unRisk = riskSubject.subscribe(this._handleRisk);
32577
- const unDoneLine = doneLiveSubject.subscribe(this._handleDoneLive);
32578
- const unDoneBacktest = doneBacktestSubject.subscribe(this._handleDoneBacktest);
32579
32640
  const unError = errorEmitter.subscribe(this._handleError);
32580
32641
  const unExit = exitEmitter.subscribe(this._handleCriticalError);
32581
32642
  const unValidation = validationSubject.subscribe(this._handleValidationError);
32582
- const unProgressBacktest = progressBacktestEmitter.subscribe(this._handleProgressBacktest);
32583
- const disposeFn = functoolsKit.compose(() => unSignal(), () => unProfit(), () => unLoss(), () => unRisk(), () => unDoneLine(), () => unDoneBacktest(), () => unError(), () => unExit(), () => unValidation(), () => unProgressBacktest());
32643
+ const disposeFn = functoolsKit.compose(() => unSignal(), () => unProfit(), () => unLoss(), () => unBreakeven(), () => unStrategyCommit(), () => unRisk(), () => unError(), () => unExit(), () => unValidation());
32584
32644
  return () => {
32585
32645
  disposeFn();
32586
32646
  this.enable.clear();
package/build/index.mjs CHANGED
@@ -3682,6 +3682,7 @@ const CHECK_SCHEDULED_SIGNAL_TIMEOUT_FN = async (self, scheduled, currentPrice)
3682
3682
  symbol: self.params.execution.context.symbol,
3683
3683
  backtest: self.params.execution.context.backtest,
3684
3684
  reason: "timeout",
3685
+ createdAt: currentTime,
3685
3686
  };
3686
3687
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
3687
3688
  return result;
@@ -3737,6 +3738,7 @@ const CANCEL_SCHEDULED_SIGNAL_BY_STOPLOSS_FN = async (self, scheduled, currentPr
3737
3738
  symbol: self.params.execution.context.symbol,
3738
3739
  backtest: self.params.execution.context.backtest,
3739
3740
  reason: "price_reject",
3741
+ createdAt: currentTime,
3740
3742
  };
3741
3743
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
3742
3744
  return result;
@@ -3792,6 +3794,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
3792
3794
  symbol: self.params.execution.context.symbol,
3793
3795
  currentPrice: self._pendingSignal.priceOpen,
3794
3796
  backtest: self.params.execution.context.backtest,
3797
+ createdAt: activationTime,
3795
3798
  };
3796
3799
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, activationTime, self.params.execution.context.backtest);
3797
3800
  return result;
@@ -4224,6 +4227,7 @@ const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice)
4224
4227
  percentSl: 0,
4225
4228
  pnl,
4226
4229
  backtest: self.params.execution.context.backtest,
4230
+ createdAt: currentTime,
4227
4231
  };
4228
4232
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4229
4233
  return result;
@@ -4248,6 +4252,7 @@ const OPEN_NEW_SCHEDULED_SIGNAL_FN = async (self, signal) => {
4248
4252
  symbol: self.params.execution.context.symbol,
4249
4253
  currentPrice: currentPrice,
4250
4254
  backtest: self.params.execution.context.backtest,
4255
+ createdAt: currentTime,
4251
4256
  };
4252
4257
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4253
4258
  return result;
@@ -4268,6 +4273,7 @@ const OPEN_NEW_PENDING_SIGNAL_FN = async (self, signal) => {
4268
4273
  symbol: self.params.execution.context.symbol,
4269
4274
  currentPrice: signal.priceOpen,
4270
4275
  backtest: self.params.execution.context.backtest,
4276
+ createdAt: currentTime,
4271
4277
  };
4272
4278
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4273
4279
  return result;
@@ -4332,6 +4338,7 @@ const CLOSE_PENDING_SIGNAL_FN = async (self, signal, currentPrice, closeReason)
4332
4338
  frameName: self.params.method.context.frameName,
4333
4339
  symbol: self.params.execution.context.symbol,
4334
4340
  backtest: self.params.execution.context.backtest,
4341
+ createdAt: currentTime,
4335
4342
  };
4336
4343
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4337
4344
  return result;
@@ -4405,6 +4412,7 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice) => {
4405
4412
  percentSl,
4406
4413
  pnl,
4407
4414
  backtest: self.params.execution.context.backtest,
4415
+ createdAt: currentTime,
4408
4416
  };
4409
4417
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4410
4418
  return result;
@@ -4421,6 +4429,7 @@ const RETURN_IDLE_FN = async (self, currentPrice) => {
4421
4429
  symbol: self.params.execution.context.symbol,
4422
4430
  currentPrice: currentPrice,
4423
4431
  backtest: self.params.execution.context.backtest,
4432
+ createdAt: currentTime,
4424
4433
  };
4425
4434
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, currentTime, self.params.execution.context.backtest);
4426
4435
  return result;
@@ -4447,6 +4456,7 @@ const CANCEL_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, averagePr
4447
4456
  symbol: self.params.execution.context.symbol,
4448
4457
  backtest: self.params.execution.context.backtest,
4449
4458
  reason,
4459
+ createdAt: closeTimestamp,
4450
4460
  };
4451
4461
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, closeTimestamp, self.params.execution.context.backtest);
4452
4462
  return result;
@@ -4527,6 +4537,7 @@ const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, c
4527
4537
  frameName: self.params.method.context.frameName,
4528
4538
  symbol: self.params.execution.context.symbol,
4529
4539
  backtest: self.params.execution.context.backtest,
4540
+ createdAt: closeTimestamp,
4530
4541
  };
4531
4542
  await CALL_TICK_CALLBACKS_FN(self, self.params.execution.context.symbol, result, closeTimestamp, self.params.execution.context.backtest);
4532
4543
  return result;
@@ -5043,6 +5054,7 @@ class ClientStrategy {
5043
5054
  backtest: this.params.execution.context.backtest,
5044
5055
  reason: "user",
5045
5056
  cancelId: cancelledSignal.cancelId,
5057
+ createdAt: currentTime,
5046
5058
  };
5047
5059
  await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, result, currentTime, this.params.execution.context.backtest);
5048
5060
  return result;
@@ -5077,6 +5089,7 @@ class ClientStrategy {
5077
5089
  symbol: this.params.execution.context.symbol,
5078
5090
  backtest: this.params.execution.context.backtest,
5079
5091
  closeId: closedSignal.closeId,
5092
+ createdAt: currentTime,
5080
5093
  };
5081
5094
  await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, result, currentTime, this.params.execution.context.backtest);
5082
5095
  return result;
@@ -5191,6 +5204,7 @@ class ClientStrategy {
5191
5204
  backtest: true,
5192
5205
  reason: "user",
5193
5206
  cancelId: cancelledSignal.cancelId,
5207
+ createdAt: closeTimestamp,
5194
5208
  };
5195
5209
  await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, cancelledResult, closeTimestamp, this.params.execution.context.backtest);
5196
5210
  return cancelledResult;
@@ -5222,6 +5236,7 @@ class ClientStrategy {
5222
5236
  symbol: this.params.execution.context.symbol,
5223
5237
  backtest: true,
5224
5238
  closeId: closedSignal.closeId,
5239
+ createdAt: closeTimestamp,
5225
5240
  };
5226
5241
  await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, closedResult, closeTimestamp, this.params.execution.context.backtest);
5227
5242
  return closedResult;
@@ -32336,6 +32351,7 @@ class NotificationInstance {
32336
32351
  priceTakeProfit: data.signal.priceTakeProfit,
32337
32352
  priceStopLoss: data.signal.priceStopLoss,
32338
32353
  note: data.signal.note,
32354
+ createdAt: data.createdAt,
32339
32355
  });
32340
32356
  }
32341
32357
  else if (data.action === "closed") {
@@ -32357,6 +32373,7 @@ class NotificationInstance {
32357
32373
  closeReason: data.closeReason,
32358
32374
  duration: durationMin,
32359
32375
  note: data.signal.note,
32376
+ createdAt: data.createdAt,
32360
32377
  });
32361
32378
  }
32362
32379
  else if (data.action === "scheduled") {
@@ -32373,6 +32390,7 @@ class NotificationInstance {
32373
32390
  priceOpen: data.signal.priceOpen,
32374
32391
  scheduledAt: data.signal.scheduledAt,
32375
32392
  currentPrice: data.currentPrice,
32393
+ createdAt: data.createdAt,
32376
32394
  });
32377
32395
  }
32378
32396
  else if (data.action === "cancelled") {
@@ -32391,6 +32409,7 @@ class NotificationInstance {
32391
32409
  cancelReason: data.reason,
32392
32410
  cancelId: data.cancelId,
32393
32411
  duration: durationMin,
32412
+ createdAt: data.createdAt,
32394
32413
  });
32395
32414
  }
32396
32415
  };
@@ -32399,7 +32418,7 @@ class NotificationInstance {
32399
32418
  */
32400
32419
  this._handlePartialProfit = async (data) => {
32401
32420
  this._addNotification({
32402
- type: "partial.profit",
32421
+ type: "partial_profit.available",
32403
32422
  id: CREATE_KEY_FN(),
32404
32423
  timestamp: data.timestamp,
32405
32424
  backtest: data.backtest,
@@ -32418,7 +32437,7 @@ class NotificationInstance {
32418
32437
  */
32419
32438
  this._handlePartialLoss = async (data) => {
32420
32439
  this._addNotification({
32421
- type: "partial.loss",
32440
+ type: "partial_loss.available",
32422
32441
  id: CREATE_KEY_FN(),
32423
32442
  timestamp: data.timestamp,
32424
32443
  backtest: data.backtest,
@@ -32433,50 +32452,109 @@ class NotificationInstance {
32433
32452
  });
32434
32453
  };
32435
32454
  /**
32436
- * Processes risk rejection events.
32455
+ * Processes breakeven events.
32437
32456
  */
32438
- this._handleRisk = async (data) => {
32457
+ this._handleBreakeven = async (data) => {
32439
32458
  this._addNotification({
32440
- type: "risk.rejection",
32459
+ type: "breakeven.available",
32441
32460
  id: CREATE_KEY_FN(),
32442
32461
  timestamp: data.timestamp,
32443
32462
  backtest: data.backtest,
32444
32463
  symbol: data.symbol,
32445
32464
  strategyName: data.strategyName,
32446
32465
  exchangeName: data.exchangeName,
32447
- rejectionNote: data.rejectionNote,
32448
- rejectionId: data.rejectionId,
32449
- activePositionCount: data.activePositionCount,
32466
+ signalId: data.data.id,
32450
32467
  currentPrice: data.currentPrice,
32451
- pendingSignal: data.pendingSignal,
32468
+ priceOpen: data.data.priceOpen,
32469
+ position: data.data.position,
32452
32470
  });
32453
32471
  };
32454
32472
  /**
32455
- * Processes done events (live/backtest).
32473
+ * Processes strategy commit events.
32456
32474
  */
32457
- this._handleDoneLive = async (data) => {
32458
- this._addNotification({
32459
- type: "live.done",
32460
- id: CREATE_KEY_FN(),
32461
- timestamp: Date.now(),
32462
- backtest: false,
32463
- symbol: data.symbol,
32464
- strategyName: data.strategyName,
32465
- exchangeName: data.exchangeName,
32466
- });
32475
+ this._handleStrategyCommit = async (data) => {
32476
+ if (data.action === "partial-profit") {
32477
+ this._addNotification({
32478
+ type: "partial_profit.commit",
32479
+ id: CREATE_KEY_FN(),
32480
+ timestamp: Date.now(),
32481
+ backtest: data.backtest,
32482
+ symbol: data.symbol,
32483
+ strategyName: data.strategyName,
32484
+ exchangeName: data.exchangeName,
32485
+ percentToClose: data.percentToClose,
32486
+ currentPrice: data.currentPrice,
32487
+ });
32488
+ }
32489
+ else if (data.action === "partial-loss") {
32490
+ this._addNotification({
32491
+ type: "partial_loss.commit",
32492
+ id: CREATE_KEY_FN(),
32493
+ timestamp: Date.now(),
32494
+ backtest: data.backtest,
32495
+ symbol: data.symbol,
32496
+ strategyName: data.strategyName,
32497
+ exchangeName: data.exchangeName,
32498
+ percentToClose: data.percentToClose,
32499
+ currentPrice: data.currentPrice,
32500
+ });
32501
+ }
32502
+ else if (data.action === "breakeven") {
32503
+ this._addNotification({
32504
+ type: "breakeven.commit",
32505
+ id: CREATE_KEY_FN(),
32506
+ timestamp: Date.now(),
32507
+ backtest: data.backtest,
32508
+ symbol: data.symbol,
32509
+ strategyName: data.strategyName,
32510
+ exchangeName: data.exchangeName,
32511
+ currentPrice: data.currentPrice,
32512
+ });
32513
+ }
32514
+ else if (data.action === "trailing-stop") {
32515
+ this._addNotification({
32516
+ type: "trailing_stop.commit",
32517
+ id: CREATE_KEY_FN(),
32518
+ timestamp: Date.now(),
32519
+ backtest: data.backtest,
32520
+ symbol: data.symbol,
32521
+ strategyName: data.strategyName,
32522
+ exchangeName: data.exchangeName,
32523
+ percentShift: data.percentShift,
32524
+ currentPrice: data.currentPrice,
32525
+ });
32526
+ }
32527
+ else if (data.action === "trailing-take") {
32528
+ this._addNotification({
32529
+ type: "trailing_take.commit",
32530
+ id: CREATE_KEY_FN(),
32531
+ timestamp: Date.now(),
32532
+ backtest: data.backtest,
32533
+ symbol: data.symbol,
32534
+ strategyName: data.strategyName,
32535
+ exchangeName: data.exchangeName,
32536
+ percentShift: data.percentShift,
32537
+ currentPrice: data.currentPrice,
32538
+ });
32539
+ }
32467
32540
  };
32468
32541
  /**
32469
- * Processes done events (backtest).
32542
+ * Processes risk rejection events.
32470
32543
  */
32471
- this._handleDoneBacktest = async (data) => {
32544
+ this._handleRisk = async (data) => {
32472
32545
  this._addNotification({
32473
- type: "backtest.done",
32546
+ type: "risk.rejection",
32474
32547
  id: CREATE_KEY_FN(),
32475
- timestamp: Date.now(),
32476
- backtest: true,
32548
+ timestamp: data.timestamp,
32549
+ backtest: data.backtest,
32477
32550
  symbol: data.symbol,
32478
32551
  strategyName: data.strategyName,
32479
32552
  exchangeName: data.exchangeName,
32553
+ rejectionNote: data.rejectionNote,
32554
+ rejectionId: data.rejectionId,
32555
+ activePositionCount: data.activePositionCount,
32556
+ currentPrice: data.currentPrice,
32557
+ pendingSignal: data.pendingSignal,
32480
32558
  });
32481
32559
  };
32482
32560
  /**
@@ -32518,23 +32596,6 @@ class NotificationInstance {
32518
32596
  backtest: false,
32519
32597
  });
32520
32598
  };
32521
- /**
32522
- * Processes progress events.
32523
- */
32524
- this._handleProgressBacktest = async (data) => {
32525
- this._addNotification({
32526
- type: "progress.backtest",
32527
- id: CREATE_KEY_FN(),
32528
- timestamp: Date.now(),
32529
- backtest: true,
32530
- exchangeName: data.exchangeName,
32531
- strategyName: data.strategyName,
32532
- symbol: data.symbol,
32533
- totalFrames: data.totalFrames,
32534
- processedFrames: data.processedFrames,
32535
- progress: data.progress,
32536
- });
32537
- };
32538
32599
  /**
32539
32600
  * Subscribes to all notification emitters and returns an unsubscribe function.
32540
32601
  * Protected against multiple subscriptions using singleshot.
@@ -32553,14 +32614,13 @@ class NotificationInstance {
32553
32614
  const unSignal = signalEmitter.subscribe(this._handleSignal);
32554
32615
  const unProfit = partialProfitSubject.subscribe(this._handlePartialProfit);
32555
32616
  const unLoss = partialLossSubject.subscribe(this._handlePartialLoss);
32617
+ const unBreakeven = breakevenSubject.subscribe(this._handleBreakeven);
32618
+ const unStrategyCommit = strategyCommitSubject.subscribe(this._handleStrategyCommit);
32556
32619
  const unRisk = riskSubject.subscribe(this._handleRisk);
32557
- const unDoneLine = doneLiveSubject.subscribe(this._handleDoneLive);
32558
- const unDoneBacktest = doneBacktestSubject.subscribe(this._handleDoneBacktest);
32559
32620
  const unError = errorEmitter.subscribe(this._handleError);
32560
32621
  const unExit = exitEmitter.subscribe(this._handleCriticalError);
32561
32622
  const unValidation = validationSubject.subscribe(this._handleValidationError);
32562
- const unProgressBacktest = progressBacktestEmitter.subscribe(this._handleProgressBacktest);
32563
- const disposeFn = compose(() => unSignal(), () => unProfit(), () => unLoss(), () => unRisk(), () => unDoneLine(), () => unDoneBacktest(), () => unError(), () => unExit(), () => unValidation(), () => unProgressBacktest());
32623
+ const disposeFn = compose(() => unSignal(), () => unProfit(), () => unLoss(), () => unBreakeven(), () => unStrategyCommit(), () => unRisk(), () => unError(), () => unExit(), () => unValidation());
32564
32624
  return () => {
32565
32625
  disposeFn();
32566
32626
  this.enable.clear();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backtest-kit",
3
- "version": "2.2.3",
3
+ "version": "2.2.6",
4
4
  "description": "A TypeScript library for trading system backtest",
5
5
  "author": {
6
6
  "name": "Petr Tripolsky",
package/types.d.ts CHANGED
@@ -1257,6 +1257,8 @@ interface IStrategyTickResultIdle {
1257
1257
  currentPrice: number;
1258
1258
  /** Whether this event is from backtest mode (true) or live mode (false) */
1259
1259
  backtest: boolean;
1260
+ /** Unix timestamp in milliseconds when this tick result was created (from candle timestamp in backtest or execution context when in live) */
1261
+ createdAt: number;
1260
1262
  }
1261
1263
  /**
1262
1264
  * Tick result: scheduled signal created, waiting for price to reach entry point.
@@ -1279,6 +1281,8 @@ interface IStrategyTickResultScheduled {
1279
1281
  currentPrice: number;
1280
1282
  /** Whether this event is from backtest mode (true) or live mode (false) */
1281
1283
  backtest: boolean;
1284
+ /** Unix timestamp in milliseconds when this tick result was created (from candle timestamp in backtest or execution context when in live) */
1285
+ createdAt: number;
1282
1286
  }
1283
1287
  /**
1284
1288
  * Tick result: scheduled signal is waiting for price to reach entry point.
@@ -1308,6 +1312,8 @@ interface IStrategyTickResultWaiting {
1308
1312
  pnl: IStrategyPnL;
1309
1313
  /** Whether this event is from backtest mode (true) or live mode (false) */
1310
1314
  backtest: boolean;
1315
+ /** Unix timestamp in milliseconds when this tick result was created (from candle timestamp in backtest or execution context when in live) */
1316
+ createdAt: number;
1311
1317
  }
1312
1318
  /**
1313
1319
  * Tick result: new signal just created.
@@ -1330,6 +1336,8 @@ interface IStrategyTickResultOpened {
1330
1336
  currentPrice: number;
1331
1337
  /** Whether this event is from backtest mode (true) or live mode (false) */
1332
1338
  backtest: boolean;
1339
+ /** Unix timestamp in milliseconds when this tick result was created (from candle timestamp in backtest or execution context when in live) */
1340
+ createdAt: number;
1333
1341
  }
1334
1342
  /**
1335
1343
  * Tick result: signal is being monitored.
@@ -1358,6 +1366,8 @@ interface IStrategyTickResultActive {
1358
1366
  pnl: IStrategyPnL;
1359
1367
  /** Whether this event is from backtest mode (true) or live mode (false) */
1360
1368
  backtest: boolean;
1369
+ /** Unix timestamp in milliseconds when this tick result was created (from candle timestamp in backtest or execution context when in live) */
1370
+ createdAt: number;
1361
1371
  }
1362
1372
  /**
1363
1373
  * Tick result: signal closed with PNL.
@@ -1388,6 +1398,8 @@ interface IStrategyTickResultClosed {
1388
1398
  backtest: boolean;
1389
1399
  /** Close ID (only for user-initiated closes with reason "closed") */
1390
1400
  closeId?: string;
1401
+ /** Unix timestamp in milliseconds when this tick result was created (from candle timestamp in backtest or execution context when in live) */
1402
+ createdAt: number;
1391
1403
  }
1392
1404
  /**
1393
1405
  * Tick result: scheduled signal cancelled without opening position.
@@ -1416,6 +1428,8 @@ interface IStrategyTickResultCancelled {
1416
1428
  reason: StrategyCancelReason;
1417
1429
  /** Optional cancellation ID (provided when user calls Backtest.cancel() or Live.cancel()) */
1418
1430
  cancelId?: string;
1431
+ /** Unix timestamp in milliseconds when this tick result was created (from candle timestamp in backtest or execution context when in live) */
1432
+ createdAt: number;
1419
1433
  }
1420
1434
  /**
1421
1435
  * Discriminated union of all tick results.
@@ -6436,93 +6450,307 @@ interface ColumnModel<T extends object = any> {
6436
6450
  * Emitted when a new trading position is opened.
6437
6451
  */
6438
6452
  interface SignalOpenedNotification {
6453
+ /** Discriminator for type-safe union */
6439
6454
  type: "signal.opened";
6455
+ /** Unique notification identifier */
6440
6456
  id: string;
6457
+ /** Unix timestamp in milliseconds when signal was opened (pendingAt) */
6441
6458
  timestamp: number;
6459
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6442
6460
  backtest: boolean;
6461
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6443
6462
  symbol: string;
6463
+ /** Strategy name that generated this signal */
6444
6464
  strategyName: StrategyName;
6465
+ /** Exchange name where signal was executed */
6445
6466
  exchangeName: ExchangeName;
6467
+ /** Unique signal identifier (UUID v4) */
6446
6468
  signalId: string;
6469
+ /** Trade direction: "long" (buy) or "short" (sell) */
6447
6470
  position: "long" | "short";
6471
+ /** Entry price for the position */
6448
6472
  priceOpen: number;
6473
+ /** Take profit target price */
6449
6474
  priceTakeProfit: number;
6475
+ /** Stop loss exit price */
6450
6476
  priceStopLoss: number;
6477
+ /** Optional human-readable description of signal reason */
6451
6478
  note?: string;
6479
+ /** Unix timestamp in milliseconds when the tick result was created (from candle timestamp in backtest or execution context when in live) */
6480
+ createdAt: number;
6452
6481
  }
6453
6482
  /**
6454
6483
  * Signal closed notification.
6455
6484
  * Emitted when a trading position is closed (TP/SL hit).
6456
6485
  */
6457
6486
  interface SignalClosedNotification {
6487
+ /** Discriminator for type-safe union */
6458
6488
  type: "signal.closed";
6489
+ /** Unique notification identifier */
6459
6490
  id: string;
6491
+ /** Unix timestamp in milliseconds when signal was closed (closeTimestamp) */
6460
6492
  timestamp: number;
6493
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6461
6494
  backtest: boolean;
6495
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6462
6496
  symbol: string;
6497
+ /** Strategy name that generated this signal */
6463
6498
  strategyName: StrategyName;
6499
+ /** Exchange name where signal was executed */
6464
6500
  exchangeName: ExchangeName;
6501
+ /** Unique signal identifier (UUID v4) */
6465
6502
  signalId: string;
6503
+ /** Trade direction: "long" (buy) or "short" (sell) */
6466
6504
  position: "long" | "short";
6505
+ /** Entry price for the position */
6467
6506
  priceOpen: number;
6507
+ /** Exit price when position was closed */
6468
6508
  priceClose: number;
6509
+ /** Profit/loss as percentage (e.g., 1.5 for +1.5%, -2.3 for -2.3%) */
6469
6510
  pnlPercentage: number;
6511
+ /** Why signal closed (time_expired | take_profit | stop_loss | closed) */
6470
6512
  closeReason: string;
6513
+ /** Duration of position in minutes (from pendingAt to closeTimestamp) */
6471
6514
  duration: number;
6515
+ /** Optional human-readable description of signal reason */
6472
6516
  note?: string;
6517
+ /** Unix timestamp in milliseconds when the tick result was created (from candle timestamp in backtest or execution context when in live) */
6518
+ createdAt: number;
6473
6519
  }
6474
6520
  /**
6475
6521
  * Partial profit notification.
6476
6522
  * Emitted when signal reaches profit level milestone (10%, 20%, etc).
6477
6523
  */
6478
- interface PartialProfitNotification {
6479
- type: "partial.profit";
6524
+ interface PartialProfitAvailableNotification {
6525
+ /** Discriminator for type-safe union */
6526
+ type: "partial_profit.available";
6527
+ /** Unique notification identifier */
6480
6528
  id: string;
6529
+ /** Unix timestamp in milliseconds when partial profit level was reached */
6481
6530
  timestamp: number;
6531
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6482
6532
  backtest: boolean;
6533
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6483
6534
  symbol: string;
6535
+ /** Strategy name that generated this signal */
6484
6536
  strategyName: StrategyName;
6537
+ /** Exchange name where signal was executed */
6485
6538
  exchangeName: ExchangeName;
6539
+ /** Unique signal identifier (UUID v4) */
6486
6540
  signalId: string;
6541
+ /** Profit level milestone reached (10, 20, 30, etc) */
6487
6542
  level: PartialLevel;
6543
+ /** Current market price when milestone was reached */
6488
6544
  currentPrice: number;
6545
+ /** Entry price for the position */
6489
6546
  priceOpen: number;
6547
+ /** Trade direction: "long" (buy) or "short" (sell) */
6490
6548
  position: "long" | "short";
6491
6549
  }
6492
6550
  /**
6493
6551
  * Partial loss notification.
6494
6552
  * Emitted when signal reaches loss level milestone (-10%, -20%, etc).
6495
6553
  */
6496
- interface PartialLossNotification {
6497
- type: "partial.loss";
6554
+ interface PartialLossAvailableNotification {
6555
+ /** Discriminator for type-safe union */
6556
+ type: "partial_loss.available";
6557
+ /** Unique notification identifier */
6498
6558
  id: string;
6559
+ /** Unix timestamp in milliseconds when partial loss level was reached */
6499
6560
  timestamp: number;
6561
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6500
6562
  backtest: boolean;
6563
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6501
6564
  symbol: string;
6565
+ /** Strategy name that generated this signal */
6502
6566
  strategyName: StrategyName;
6567
+ /** Exchange name where signal was executed */
6503
6568
  exchangeName: ExchangeName;
6569
+ /** Unique signal identifier (UUID v4) */
6504
6570
  signalId: string;
6571
+ /** Loss level milestone reached (10, 20, 30, etc) */
6505
6572
  level: PartialLevel;
6573
+ /** Current market price when milestone was reached */
6574
+ currentPrice: number;
6575
+ /** Entry price for the position */
6576
+ priceOpen: number;
6577
+ /** Trade direction: "long" (buy) or "short" (sell) */
6578
+ position: "long" | "short";
6579
+ }
6580
+ /**
6581
+ * Breakeven available notification.
6582
+ * Emitted when signal's stop-loss can be moved to breakeven (entry price).
6583
+ */
6584
+ interface BreakevenAvailableNotification {
6585
+ /** Discriminator for type-safe union */
6586
+ type: "breakeven.available";
6587
+ /** Unique notification identifier */
6588
+ id: string;
6589
+ /** Unix timestamp in milliseconds when breakeven became available */
6590
+ timestamp: number;
6591
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6592
+ backtest: boolean;
6593
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6594
+ symbol: string;
6595
+ /** Strategy name that generated this signal */
6596
+ strategyName: StrategyName;
6597
+ /** Exchange name where signal was executed */
6598
+ exchangeName: ExchangeName;
6599
+ /** Unique signal identifier (UUID v4) */
6600
+ signalId: string;
6601
+ /** Current market price when breakeven became available */
6506
6602
  currentPrice: number;
6603
+ /** Entry price for the position (breakeven level) */
6507
6604
  priceOpen: number;
6605
+ /** Trade direction: "long" (buy) or "short" (sell) */
6508
6606
  position: "long" | "short";
6509
6607
  }
6608
+ /**
6609
+ * Partial profit commit notification.
6610
+ * Emitted when partial profit action is executed.
6611
+ */
6612
+ interface PartialProfitCommitNotification {
6613
+ /** Discriminator for type-safe union */
6614
+ type: "partial_profit.commit";
6615
+ /** Unique notification identifier */
6616
+ id: string;
6617
+ /** Unix timestamp in milliseconds when partial profit was committed */
6618
+ timestamp: number;
6619
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6620
+ backtest: boolean;
6621
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6622
+ symbol: string;
6623
+ /** Strategy name that generated this signal */
6624
+ strategyName: StrategyName;
6625
+ /** Exchange name where signal was executed */
6626
+ exchangeName: ExchangeName;
6627
+ /** Percentage of position closed (0-100) */
6628
+ percentToClose: number;
6629
+ /** Current market price when partial was executed */
6630
+ currentPrice: number;
6631
+ }
6632
+ /**
6633
+ * Partial loss commit notification.
6634
+ * Emitted when partial loss action is executed.
6635
+ */
6636
+ interface PartialLossCommitNotification {
6637
+ /** Discriminator for type-safe union */
6638
+ type: "partial_loss.commit";
6639
+ /** Unique notification identifier */
6640
+ id: string;
6641
+ /** Unix timestamp in milliseconds when partial loss was committed */
6642
+ timestamp: number;
6643
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6644
+ backtest: boolean;
6645
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6646
+ symbol: string;
6647
+ /** Strategy name that generated this signal */
6648
+ strategyName: StrategyName;
6649
+ /** Exchange name where signal was executed */
6650
+ exchangeName: ExchangeName;
6651
+ /** Percentage of position closed (0-100) */
6652
+ percentToClose: number;
6653
+ /** Current market price when partial was executed */
6654
+ currentPrice: number;
6655
+ }
6656
+ /**
6657
+ * Breakeven commit notification.
6658
+ * Emitted when breakeven action is executed.
6659
+ */
6660
+ interface BreakevenCommitNotification {
6661
+ /** Discriminator for type-safe union */
6662
+ type: "breakeven.commit";
6663
+ /** Unique notification identifier */
6664
+ id: string;
6665
+ /** Unix timestamp in milliseconds when breakeven was committed */
6666
+ timestamp: number;
6667
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6668
+ backtest: boolean;
6669
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6670
+ symbol: string;
6671
+ /** Strategy name that generated this signal */
6672
+ strategyName: StrategyName;
6673
+ /** Exchange name where signal was executed */
6674
+ exchangeName: ExchangeName;
6675
+ /** Current market price when breakeven was executed */
6676
+ currentPrice: number;
6677
+ }
6678
+ /**
6679
+ * Trailing stop commit notification.
6680
+ * Emitted when trailing stop action is executed.
6681
+ */
6682
+ interface TrailingStopCommitNotification {
6683
+ /** Discriminator for type-safe union */
6684
+ type: "trailing_stop.commit";
6685
+ /** Unique notification identifier */
6686
+ id: string;
6687
+ /** Unix timestamp in milliseconds when trailing stop was committed */
6688
+ timestamp: number;
6689
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6690
+ backtest: boolean;
6691
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6692
+ symbol: string;
6693
+ /** Strategy name that generated this signal */
6694
+ strategyName: StrategyName;
6695
+ /** Exchange name where signal was executed */
6696
+ exchangeName: ExchangeName;
6697
+ /** Percentage shift of original SL distance (-100 to 100) */
6698
+ percentShift: number;
6699
+ /** Current market price when trailing stop was executed */
6700
+ currentPrice: number;
6701
+ }
6702
+ /**
6703
+ * Trailing take commit notification.
6704
+ * Emitted when trailing take action is executed.
6705
+ */
6706
+ interface TrailingTakeCommitNotification {
6707
+ /** Discriminator for type-safe union */
6708
+ type: "trailing_take.commit";
6709
+ /** Unique notification identifier */
6710
+ id: string;
6711
+ /** Unix timestamp in milliseconds when trailing take was committed */
6712
+ timestamp: number;
6713
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6714
+ backtest: boolean;
6715
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6716
+ symbol: string;
6717
+ /** Strategy name that generated this signal */
6718
+ strategyName: StrategyName;
6719
+ /** Exchange name where signal was executed */
6720
+ exchangeName: ExchangeName;
6721
+ /** Percentage shift of original TP distance (-100 to 100) */
6722
+ percentShift: number;
6723
+ /** Current market price when trailing take was executed */
6724
+ currentPrice: number;
6725
+ }
6510
6726
  /**
6511
6727
  * Risk rejection notification.
6512
6728
  * Emitted when a signal is rejected due to risk management rules.
6513
6729
  */
6514
6730
  interface RiskRejectionNotification {
6731
+ /** Discriminator for type-safe union */
6515
6732
  type: "risk.rejection";
6733
+ /** Unique notification identifier */
6516
6734
  id: string;
6735
+ /** Unix timestamp in milliseconds when signal was rejected */
6517
6736
  timestamp: number;
6737
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6518
6738
  backtest: boolean;
6739
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6519
6740
  symbol: string;
6741
+ /** Strategy name that attempted to create signal */
6520
6742
  strategyName: StrategyName;
6743
+ /** Exchange name where signal was rejected */
6521
6744
  exchangeName: ExchangeName;
6745
+ /** Human-readable reason for rejection */
6522
6746
  rejectionNote: string;
6747
+ /** Optional unique rejection identifier for tracking */
6523
6748
  rejectionId: string | null;
6749
+ /** Number of currently active positions at rejection time */
6524
6750
  activePositionCount: number;
6751
+ /** Current market price when rejection occurred */
6525
6752
  currentPrice: number;
6753
+ /** The signal that was rejected */
6526
6754
  pendingSignal: ISignalDto;
6527
6755
  }
6528
6756
  /**
@@ -6530,73 +6758,81 @@ interface RiskRejectionNotification {
6530
6758
  * Emitted when a signal is scheduled for future execution.
6531
6759
  */
6532
6760
  interface SignalScheduledNotification {
6761
+ /** Discriminator for type-safe union */
6533
6762
  type: "signal.scheduled";
6763
+ /** Unique notification identifier */
6534
6764
  id: string;
6765
+ /** Unix timestamp in milliseconds when signal was scheduled (scheduledAt) */
6535
6766
  timestamp: number;
6767
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6536
6768
  backtest: boolean;
6769
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6537
6770
  symbol: string;
6771
+ /** Strategy name that generated this signal */
6538
6772
  strategyName: StrategyName;
6773
+ /** Exchange name where signal will be executed */
6539
6774
  exchangeName: ExchangeName;
6775
+ /** Unique signal identifier (UUID v4) */
6540
6776
  signalId: string;
6777
+ /** Trade direction: "long" (buy) or "short" (sell) */
6541
6778
  position: "long" | "short";
6779
+ /** Target entry price for activation */
6542
6780
  priceOpen: number;
6781
+ /** Unix timestamp in milliseconds when signal was scheduled */
6543
6782
  scheduledAt: number;
6783
+ /** Current market price when signal was scheduled */
6544
6784
  currentPrice: number;
6785
+ /** Unix timestamp in milliseconds when the tick result was created (from candle timestamp in backtest or execution context when in live) */
6786
+ createdAt: number;
6545
6787
  }
6546
6788
  /**
6547
6789
  * Signal cancelled notification.
6548
6790
  * Emitted when a scheduled signal is cancelled before activation.
6549
6791
  */
6550
6792
  interface SignalCancelledNotification {
6793
+ /** Discriminator for type-safe union */
6551
6794
  type: "signal.cancelled";
6795
+ /** Unique notification identifier */
6552
6796
  id: string;
6797
+ /** Unix timestamp in milliseconds when signal was cancelled (closeTimestamp) */
6553
6798
  timestamp: number;
6799
+ /** Whether this notification is from backtest mode (true) or live mode (false) */
6554
6800
  backtest: boolean;
6801
+ /** Trading pair symbol (e.g., "BTCUSDT") */
6555
6802
  symbol: string;
6803
+ /** Strategy name that generated this signal */
6556
6804
  strategyName: StrategyName;
6805
+ /** Exchange name where signal was scheduled */
6557
6806
  exchangeName: ExchangeName;
6807
+ /** Unique signal identifier (UUID v4) */
6558
6808
  signalId: string;
6809
+ /** Trade direction: "long" (buy) or "short" (sell) */
6559
6810
  position: "long" | "short";
6811
+ /** Why signal was cancelled (timeout | price_reject | user) */
6560
6812
  cancelReason: string;
6813
+ /** Optional cancellation identifier (provided when user calls cancel()) */
6561
6814
  cancelId: string;
6815
+ /** Duration in minutes from scheduledAt to cancellation */
6562
6816
  duration: number;
6563
- }
6564
- /**
6565
- * Backtest completed notification.
6566
- * Emitted when backtest execution completes.
6567
- */
6568
- interface BacktestDoneNotification {
6569
- type: "backtest.done";
6570
- id: string;
6571
- timestamp: number;
6572
- backtest: true;
6573
- symbol: string;
6574
- strategyName: StrategyName;
6575
- exchangeName: ExchangeName;
6576
- }
6577
- /**
6578
- * Live trading completed notification.
6579
- * Emitted when live trading execution completes.
6580
- */
6581
- interface LiveDoneNotification {
6582
- type: "live.done";
6583
- id: string;
6584
- timestamp: number;
6585
- backtest: false;
6586
- symbol: string;
6587
- strategyName: StrategyName;
6588
- exchangeName: ExchangeName;
6817
+ /** Unix timestamp in milliseconds when the tick result was created (from candle timestamp in backtest or execution context when in live) */
6818
+ createdAt: number;
6589
6819
  }
6590
6820
  /**
6591
6821
  * Error notification.
6592
6822
  * Emitted for recoverable errors in background tasks.
6593
6823
  */
6594
6824
  interface InfoErrorNotification {
6825
+ /** Discriminator for type-safe union */
6595
6826
  type: "error.info";
6827
+ /** Unique notification identifier */
6596
6828
  id: string;
6829
+ /** Serialized error object with stack trace and metadata */
6597
6830
  error: object;
6831
+ /** Human-readable error message */
6598
6832
  message: string;
6833
+ /** Unix timestamp in milliseconds when error occurred */
6599
6834
  timestamp: number;
6835
+ /** Always false for error notifications (errors are from live context) */
6600
6836
  backtest: boolean;
6601
6837
  }
6602
6838
  /**
@@ -6604,11 +6840,17 @@ interface InfoErrorNotification {
6604
6840
  * Emitted for fatal errors requiring process termination.
6605
6841
  */
6606
6842
  interface CriticalErrorNotification {
6843
+ /** Discriminator for type-safe union */
6607
6844
  type: "error.critical";
6845
+ /** Unique notification identifier */
6608
6846
  id: string;
6847
+ /** Serialized error object with stack trace and metadata */
6609
6848
  error: object;
6849
+ /** Human-readable error message */
6610
6850
  message: string;
6851
+ /** Unix timestamp in milliseconds when critical error occurred */
6611
6852
  timestamp: number;
6853
+ /** Always false for error notifications (errors are from live context) */
6612
6854
  backtest: boolean;
6613
6855
  }
6614
6856
  /**
@@ -6616,29 +6858,19 @@ interface CriticalErrorNotification {
6616
6858
  * Emitted when risk validation functions throw errors.
6617
6859
  */
6618
6860
  interface ValidationErrorNotification {
6861
+ /** Discriminator for type-safe union */
6619
6862
  type: "error.validation";
6863
+ /** Unique notification identifier */
6620
6864
  id: string;
6865
+ /** Serialized error object with stack trace and metadata */
6621
6866
  error: object;
6867
+ /** Human-readable validation error message */
6622
6868
  message: string;
6869
+ /** Unix timestamp in milliseconds when validation error occurred */
6623
6870
  timestamp: number;
6871
+ /** Always false for error notifications (errors are from live context) */
6624
6872
  backtest: boolean;
6625
6873
  }
6626
- /**
6627
- * Progress update notification.
6628
- * Emitted during backtest execution.
6629
- */
6630
- interface ProgressBacktestNotification {
6631
- type: "progress.backtest";
6632
- id: string;
6633
- timestamp: number;
6634
- backtest: true;
6635
- exchangeName: ExchangeName;
6636
- strategyName: StrategyName;
6637
- symbol: string;
6638
- totalFrames: number;
6639
- processedFrames: number;
6640
- progress: number;
6641
- }
6642
6874
  /**
6643
6875
  * Root discriminated union of all notification types.
6644
6876
  * Type discrimination is done via the `type` field.
@@ -6665,7 +6897,7 @@ interface ProgressBacktestNotification {
6665
6897
  * }
6666
6898
  * ```
6667
6899
  */
6668
- type NotificationModel = SignalOpenedNotification | SignalClosedNotification | PartialProfitNotification | PartialLossNotification | RiskRejectionNotification | SignalScheduledNotification | SignalCancelledNotification | BacktestDoneNotification | LiveDoneNotification | InfoErrorNotification | CriticalErrorNotification | ValidationErrorNotification | ProgressBacktestNotification;
6900
+ type NotificationModel = SignalOpenedNotification | SignalClosedNotification | PartialProfitAvailableNotification | PartialLossAvailableNotification | BreakevenAvailableNotification | PartialProfitCommitNotification | PartialLossCommitNotification | BreakevenCommitNotification | TrailingStopCommitNotification | TrailingTakeCommitNotification | RiskRejectionNotification | SignalScheduledNotification | SignalCancelledNotification | InfoErrorNotification | CriticalErrorNotification | ValidationErrorNotification;
6669
6901
 
6670
6902
  /**
6671
6903
  * Unified tick event data for report generation.
@@ -19085,4 +19317,4 @@ declare const backtest: {
19085
19317
  loggerService: LoggerService;
19086
19318
  };
19087
19319
 
19088
- export { ActionBase, type ActivePingContract, Backtest, type BacktestDoneNotification, type BacktestStatisticsModel, Breakeven, type BreakevenContract, type BreakevenData, Cache, type CandleData, type CandleInterval, type ColumnConfig, type ColumnModel, Constant, type CriticalErrorNotification, type DoneContract, type EntityId, Exchange, ExecutionContextService, type FrameInterval, type GlobalConfig, Heat, type HeatmapStatisticsModel, type IBidData, type ICandleData, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type IMarkdownDumpOptions, type IOrderBookData, type IPersistBase, type IPositionSizeATRParams, type IPositionSizeFixedPercentageParams, type IPositionSizeKellyParams, type IPublicSignalRow, type IReportDumpOptions, type IRiskActivePosition, type IRiskCheckArgs, type IRiskSchema, type IRiskValidation, type IRiskValidationFn, type IRiskValidationPayload, type IScheduledSignalCancelRow, type IScheduledSignalRow, type ISignalDto, type ISignalRow, type ISizingCalculateParams, type ISizingCalculateParamsATR, type ISizingCalculateParamsFixedPercentage, type ISizingCalculateParamsKelly, type ISizingSchema, type ISizingSchemaATR, type ISizingSchemaFixedPercentage, type ISizingSchemaKelly, type IStrategyPnL, type IStrategyResult, type IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultCancelled, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, type IStrategyTickResultScheduled, type IWalkerResults, type IWalkerSchema, type IWalkerStrategyResult, type InfoErrorNotification, Live, type LiveDoneNotification, type LiveStatisticsModel, Markdown, MarkdownFileBase, MarkdownFolderBase, type MarkdownName, MethodContextService, type MetricStats, Notification, type NotificationModel, Partial$1 as Partial, type PartialData, type PartialEvent, type PartialLossContract, type PartialLossNotification, type PartialProfitContract, type PartialProfitNotification, type PartialStatisticsModel, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatisticsModel, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PositionSize, type ProgressBacktestContract, type ProgressBacktestNotification, type ProgressWalkerContract, Report, ReportBase, type ReportName, Risk, type RiskContract, type RiskData, type RiskEvent, type RiskRejectionNotification, type RiskStatisticsModel, Schedule, type ScheduleData, type SchedulePingContract, type ScheduleStatisticsModel, type ScheduledEvent, type SignalCancelledNotification, type SignalClosedNotification, type SignalData, type SignalInterval, type SignalOpenedNotification, type SignalScheduledNotification, Strategy, type StrategyActionType, type StrategyCommitContract, type StrategyEvent, type StrategyStatisticsModel, type TMarkdownBase, type TPersistBase, type TPersistBaseCtor, type TReportBase, type TickEvent, type ValidationErrorNotification, Walker, type WalkerCompleteContract, type WalkerContract, type WalkerMetric, type SignalData$1 as WalkerSignalData, type WalkerStatisticsModel, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialProfit, commitTrailingStop, commitTrailingTake, emitters, formatPrice, formatQuantity, get, getActionSchema, getAveragePrice, getBacktestTimeframe, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getExchangeSchema, getFrameSchema, getMode, getOrderBook, getRawCandles, getRiskSchema, getSizingSchema, getStrategySchema, getSymbol, getWalkerSchema, hasTradeContext, backtest as lib, listExchangeSchema, listFrameSchema, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, roundTicks, set, setColumns, setConfig, setLogger, stopStrategy, validate };
19320
+ export { ActionBase, type ActivePingContract, Backtest, type BacktestStatisticsModel, Breakeven, type BreakevenAvailableNotification, type BreakevenCommitNotification, type BreakevenContract, type BreakevenData, Cache, type CandleData, type CandleInterval, type ColumnConfig, type ColumnModel, Constant, type CriticalErrorNotification, type DoneContract, type EntityId, Exchange, ExecutionContextService, type FrameInterval, type GlobalConfig, Heat, type HeatmapStatisticsModel, type IBidData, type ICandleData, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type IMarkdownDumpOptions, type IOrderBookData, type IPersistBase, type IPositionSizeATRParams, type IPositionSizeFixedPercentageParams, type IPositionSizeKellyParams, type IPublicSignalRow, type IReportDumpOptions, type IRiskActivePosition, type IRiskCheckArgs, type IRiskSchema, type IRiskValidation, type IRiskValidationFn, type IRiskValidationPayload, type IScheduledSignalCancelRow, type IScheduledSignalRow, type ISignalDto, type ISignalRow, type ISizingCalculateParams, type ISizingCalculateParamsATR, type ISizingCalculateParamsFixedPercentage, type ISizingCalculateParamsKelly, type ISizingSchema, type ISizingSchemaATR, type ISizingSchemaFixedPercentage, type ISizingSchemaKelly, type IStrategyPnL, type IStrategyResult, type IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultCancelled, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, type IStrategyTickResultScheduled, type IWalkerResults, type IWalkerSchema, type IWalkerStrategyResult, type InfoErrorNotification, Live, type LiveStatisticsModel, Markdown, MarkdownFileBase, MarkdownFolderBase, type MarkdownName, MethodContextService, type MetricStats, Notification, type NotificationModel, Partial$1 as Partial, type PartialData, type PartialEvent, type PartialLossAvailableNotification, type PartialLossCommitNotification, type PartialLossContract, type PartialProfitAvailableNotification, type PartialProfitCommitNotification, type PartialProfitContract, type PartialStatisticsModel, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatisticsModel, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PositionSize, type ProgressBacktestContract, type ProgressWalkerContract, Report, ReportBase, type ReportName, Risk, type RiskContract, type RiskData, type RiskEvent, type RiskRejectionNotification, type RiskStatisticsModel, Schedule, type ScheduleData, type SchedulePingContract, type ScheduleStatisticsModel, type ScheduledEvent, type SignalCancelledNotification, type SignalClosedNotification, type SignalData, type SignalInterval, type SignalOpenedNotification, type SignalScheduledNotification, Strategy, type StrategyActionType, type StrategyCommitContract, type StrategyEvent, type StrategyStatisticsModel, type TMarkdownBase, type TPersistBase, type TPersistBaseCtor, type TReportBase, type TickEvent, type TrailingStopCommitNotification, type TrailingTakeCommitNotification, type ValidationErrorNotification, Walker, type WalkerCompleteContract, type WalkerContract, type WalkerMetric, type SignalData$1 as WalkerSignalData, type WalkerStatisticsModel, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialProfit, commitTrailingStop, commitTrailingTake, emitters, formatPrice, formatQuantity, get, getActionSchema, getAveragePrice, getBacktestTimeframe, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getExchangeSchema, getFrameSchema, getMode, getOrderBook, getRawCandles, getRiskSchema, getSizingSchema, getStrategySchema, getSymbol, getWalkerSchema, hasTradeContext, backtest as lib, listExchangeSchema, listFrameSchema, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, roundTicks, set, setColumns, setConfig, setLogger, stopStrategy, validate };