backtest-kit 3.0.2 → 3.0.4

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
@@ -428,6 +428,20 @@ const GLOBAL_CONFIG = {
428
428
  * Default: 20 levels
429
429
  */
430
430
  CC_ORDER_BOOK_MAX_DEPTH_LEVELS: 1000,
431
+ /**
432
+ * Maximum number of notifications to keep in storage.
433
+ * Older notifications are removed when this limit is exceeded.
434
+ *
435
+ * Default: 500 notifications
436
+ */
437
+ CC_MAX_NOTIFICATIONS: 500,
438
+ /**
439
+ * Maximum number of signals to keep in storage.
440
+ * Older signals are removed when this limit is exceeded.
441
+ *
442
+ * Default: 50 signals
443
+ */
444
+ CC_MAX_SIGNALS: 50,
431
445
  };
432
446
  const DEFAULT_CONFIG = Object.freeze({ ...GLOBAL_CONFIG });
433
447
 
@@ -22066,6 +22080,13 @@ class ConfigValidationService {
22066
22080
  if (!Number.isInteger(GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES) || GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES < 0) {
22067
22081
  errors.push(`CC_ORDER_BOOK_TIME_OFFSET_MINUTES must be a non-negative integer, got ${GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES}`);
22068
22082
  }
22083
+ // Validate notification and storage limits
22084
+ if (!Number.isInteger(GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS) || GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS <= 0) {
22085
+ errors.push(`CC_MAX_NOTIFICATIONS must be a positive integer, got ${GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS}`);
22086
+ }
22087
+ if (!Number.isInteger(GLOBAL_CONFIG.CC_MAX_SIGNALS) || GLOBAL_CONFIG.CC_MAX_SIGNALS <= 0) {
22088
+ errors.push(`CC_MAX_SIGNALS must be a positive integer, got ${GLOBAL_CONFIG.CC_MAX_SIGNALS}`);
22089
+ }
22069
22090
  // Throw aggregated errors if any
22070
22091
  if (errors.length > 0) {
22071
22092
  const errorMessage = `GLOBAL_CONFIG validation failed:\n${errors.map((e, i) => ` ${i + 1}. ${e}`).join('\n')}`;
@@ -32724,7 +32745,6 @@ class ConstantUtils {
32724
32745
  */
32725
32746
  const Constant = new ConstantUtils();
32726
32747
 
32727
- const MAX_SIGNALS = 25;
32728
32748
  const STORAGE_BACKTEST_METHOD_NAME_WAIT_FOR_INIT = "StoragePersistBacktestUtils.waitForInit";
32729
32749
  const STORAGE_BACKTEST_METHOD_NAME_UPDATE_STORAGE = "StoragePersistBacktestUtils._updateStorage";
32730
32750
  const STORAGE_BACKTEST_METHOD_NAME_HANDLE_OPENED = "StoragePersistBacktestUtils.handleOpened";
@@ -32789,7 +32809,7 @@ class StoragePersistBacktestUtils {
32789
32809
  const signalList = await PersistStorageAdapter.readStorageData(true);
32790
32810
  signalList.sort((a, b) => a.priority - b.priority);
32791
32811
  this._signals = new Map(signalList
32792
- .slice(-MAX_SIGNALS)
32812
+ .slice(-GLOBAL_CONFIG.CC_MAX_SIGNALS)
32793
32813
  .map((signal) => [signal.id, signal]));
32794
32814
  });
32795
32815
  /**
@@ -32813,6 +32833,7 @@ class StoragePersistBacktestUtils {
32813
32833
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32814
32834
  updatedAt: tick.createdAt,
32815
32835
  });
32836
+ this._enforceLimit();
32816
32837
  await this._updateStorage();
32817
32838
  };
32818
32839
  /**
@@ -32837,6 +32858,7 @@ class StoragePersistBacktestUtils {
32837
32858
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32838
32859
  updatedAt: tick.createdAt,
32839
32860
  });
32861
+ this._enforceLimit();
32840
32862
  await this._updateStorage();
32841
32863
  };
32842
32864
  /**
@@ -32860,6 +32882,7 @@ class StoragePersistBacktestUtils {
32860
32882
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32861
32883
  updatedAt: tick.createdAt,
32862
32884
  });
32885
+ this._enforceLimit();
32863
32886
  await this._updateStorage();
32864
32887
  };
32865
32888
  /**
@@ -32883,6 +32906,7 @@ class StoragePersistBacktestUtils {
32883
32906
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32884
32907
  updatedAt: tick.createdAt,
32885
32908
  });
32909
+ this._enforceLimit();
32886
32910
  await this._updateStorage();
32887
32911
  };
32888
32912
  /**
@@ -32905,6 +32929,17 @@ class StoragePersistBacktestUtils {
32905
32929
  return Array.from(this._signals.values());
32906
32930
  };
32907
32931
  }
32932
+ /**
32933
+ * Removes oldest signal if limit is exceeded.
32934
+ */
32935
+ _enforceLimit() {
32936
+ if (this._signals.size > GLOBAL_CONFIG.CC_MAX_SIGNALS) {
32937
+ const firstKey = this._signals.keys().next().value;
32938
+ if (firstKey) {
32939
+ this._signals.delete(firstKey);
32940
+ }
32941
+ }
32942
+ }
32908
32943
  /**
32909
32944
  * Persists the current signal map to disk storage.
32910
32945
  * Sorts signals by priority and keeps only the most recent MAX_SIGNALS.
@@ -32917,7 +32952,7 @@ class StoragePersistBacktestUtils {
32917
32952
  }
32918
32953
  const signalList = Array.from(this._signals.values());
32919
32954
  signalList.sort((a, b) => a.priority - b.priority);
32920
- await PersistStorageAdapter.writeStorageData(signalList.slice(-MAX_SIGNALS), true);
32955
+ await PersistStorageAdapter.writeStorageData(signalList.slice(-GLOBAL_CONFIG.CC_MAX_SIGNALS), true);
32921
32956
  }
32922
32957
  }
32923
32958
  /**
@@ -32956,6 +32991,7 @@ class StorageMemoryBacktestUtils {
32956
32991
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32957
32992
  updatedAt: tick.createdAt,
32958
32993
  });
32994
+ this._enforceLimit();
32959
32995
  };
32960
32996
  /**
32961
32997
  * Handles signal closed event.
@@ -32978,6 +33014,7 @@ class StorageMemoryBacktestUtils {
32978
33014
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32979
33015
  updatedAt: tick.createdAt,
32980
33016
  });
33017
+ this._enforceLimit();
32981
33018
  };
32982
33019
  /**
32983
33020
  * Handles signal scheduled event.
@@ -32999,6 +33036,7 @@ class StorageMemoryBacktestUtils {
32999
33036
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33000
33037
  updatedAt: tick.createdAt,
33001
33038
  });
33039
+ this._enforceLimit();
33002
33040
  };
33003
33041
  /**
33004
33042
  * Handles signal cancelled event.
@@ -33020,6 +33058,7 @@ class StorageMemoryBacktestUtils {
33020
33058
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33021
33059
  updatedAt: tick.createdAt,
33022
33060
  });
33061
+ this._enforceLimit();
33023
33062
  };
33024
33063
  /**
33025
33064
  * Finds a signal by its ID.
@@ -33039,6 +33078,17 @@ class StorageMemoryBacktestUtils {
33039
33078
  return Array.from(this._signals.values());
33040
33079
  };
33041
33080
  }
33081
+ /**
33082
+ * Removes oldest signal if limit is exceeded.
33083
+ */
33084
+ _enforceLimit() {
33085
+ if (this._signals.size > GLOBAL_CONFIG.CC_MAX_SIGNALS) {
33086
+ const firstKey = this._signals.keys().next().value;
33087
+ if (firstKey) {
33088
+ this._signals.delete(firstKey);
33089
+ }
33090
+ }
33091
+ }
33042
33092
  }
33043
33093
  /**
33044
33094
  * Dummy storage adapter for backtest signals that discards all writes.
@@ -33111,7 +33161,7 @@ class StoragePersistLiveUtils {
33111
33161
  const signalList = await PersistStorageAdapter.readStorageData(false);
33112
33162
  signalList.sort((a, b) => a.priority - b.priority);
33113
33163
  this._signals = new Map(signalList
33114
- .slice(-MAX_SIGNALS)
33164
+ .slice(-GLOBAL_CONFIG.CC_MAX_SIGNALS)
33115
33165
  .map((signal) => [signal.id, signal]));
33116
33166
  });
33117
33167
  /**
@@ -33135,6 +33185,7 @@ class StoragePersistLiveUtils {
33135
33185
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33136
33186
  updatedAt: tick.createdAt,
33137
33187
  });
33188
+ this._enforceLimit();
33138
33189
  await this._updateStorage();
33139
33190
  };
33140
33191
  /**
@@ -33159,6 +33210,7 @@ class StoragePersistLiveUtils {
33159
33210
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33160
33211
  updatedAt: tick.createdAt,
33161
33212
  });
33213
+ this._enforceLimit();
33162
33214
  await this._updateStorage();
33163
33215
  };
33164
33216
  /**
@@ -33182,6 +33234,7 @@ class StoragePersistLiveUtils {
33182
33234
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33183
33235
  updatedAt: tick.createdAt,
33184
33236
  });
33237
+ this._enforceLimit();
33185
33238
  await this._updateStorage();
33186
33239
  };
33187
33240
  /**
@@ -33205,6 +33258,7 @@ class StoragePersistLiveUtils {
33205
33258
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33206
33259
  updatedAt: tick.createdAt,
33207
33260
  });
33261
+ this._enforceLimit();
33208
33262
  await this._updateStorage();
33209
33263
  };
33210
33264
  /**
@@ -33227,6 +33281,17 @@ class StoragePersistLiveUtils {
33227
33281
  return Array.from(this._signals.values());
33228
33282
  };
33229
33283
  }
33284
+ /**
33285
+ * Removes oldest signal if limit is exceeded.
33286
+ */
33287
+ _enforceLimit() {
33288
+ if (this._signals.size > GLOBAL_CONFIG.CC_MAX_SIGNALS) {
33289
+ const firstKey = this._signals.keys().next().value;
33290
+ if (firstKey) {
33291
+ this._signals.delete(firstKey);
33292
+ }
33293
+ }
33294
+ }
33230
33295
  /**
33231
33296
  * Persists the current signal map to disk storage.
33232
33297
  * Sorts signals by priority and keeps only the most recent MAX_SIGNALS.
@@ -33239,7 +33304,7 @@ class StoragePersistLiveUtils {
33239
33304
  }
33240
33305
  const signalList = Array.from(this._signals.values());
33241
33306
  signalList.sort((a, b) => a.priority - b.priority);
33242
- await PersistStorageAdapter.writeStorageData(signalList.slice(-MAX_SIGNALS), false);
33307
+ await PersistStorageAdapter.writeStorageData(signalList.slice(-GLOBAL_CONFIG.CC_MAX_SIGNALS), false);
33243
33308
  }
33244
33309
  }
33245
33310
  /**
@@ -33278,6 +33343,7 @@ class StorageMemoryLiveUtils {
33278
33343
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33279
33344
  updatedAt: tick.createdAt,
33280
33345
  });
33346
+ this._enforceLimit();
33281
33347
  };
33282
33348
  /**
33283
33349
  * Handles signal closed event.
@@ -33300,6 +33366,7 @@ class StorageMemoryLiveUtils {
33300
33366
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33301
33367
  updatedAt: tick.createdAt,
33302
33368
  });
33369
+ this._enforceLimit();
33303
33370
  };
33304
33371
  /**
33305
33372
  * Handles signal scheduled event.
@@ -33321,6 +33388,7 @@ class StorageMemoryLiveUtils {
33321
33388
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33322
33389
  updatedAt: tick.createdAt,
33323
33390
  });
33391
+ this._enforceLimit();
33324
33392
  };
33325
33393
  /**
33326
33394
  * Handles signal cancelled event.
@@ -33342,6 +33410,7 @@ class StorageMemoryLiveUtils {
33342
33410
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33343
33411
  updatedAt: tick.createdAt,
33344
33412
  });
33413
+ this._enforceLimit();
33345
33414
  };
33346
33415
  /**
33347
33416
  * Finds a signal by its ID.
@@ -33361,6 +33430,17 @@ class StorageMemoryLiveUtils {
33361
33430
  return Array.from(this._signals.values());
33362
33431
  };
33363
33432
  }
33433
+ /**
33434
+ * Removes oldest signal if limit is exceeded.
33435
+ */
33436
+ _enforceLimit() {
33437
+ if (this._signals.size > GLOBAL_CONFIG.CC_MAX_SIGNALS) {
33438
+ const firstKey = this._signals.keys().next().value;
33439
+ if (firstKey) {
33440
+ this._signals.delete(firstKey);
33441
+ }
33442
+ }
33443
+ }
33364
33444
  }
33365
33445
  /**
33366
33446
  * Dummy storage adapter for live trading signals that discards all writes.
@@ -33740,11 +33820,6 @@ const StorageLive = new StorageLiveAdapter();
33740
33820
  */
33741
33821
  const StorageBacktest = new StorageBacktestAdapter();
33742
33822
 
33743
- /**
33744
- * Maximum number of notifications to keep in storage.
33745
- * Older notifications are removed when this limit is exceeded.
33746
- */
33747
- const MAX_NOTIFICATIONS = 250;
33748
33823
  /**
33749
33824
  * Generates a unique key for notification identification.
33750
33825
  * @returns Random string identifier
@@ -34167,8 +34242,6 @@ const NOTIFICATION_MEMORY_LIVE_METHOD_NAME_CLEAR = "NotificationMemoryLiveUtils.
34167
34242
  const NOTIFICATION_ADAPTER_METHOD_NAME_ENABLE = "NotificationAdapter.enable";
34168
34243
  const NOTIFICATION_ADAPTER_METHOD_NAME_DISABLE = "NotificationAdapter.disable";
34169
34244
  const NOTIFICATION_ADAPTER_METHOD_NAME_GET_DATA_BACKTEST = "NotificationAdapter.getDataBacktest";
34170
- const NOTIFICATION_ADAPTER_METHOD_NAME_GET_DATA_LIVE = "NotificationAdapter.getDataLive";
34171
- const NOTIFICATION_ADAPTER_METHOD_NAME_CLEAR_BACKTEST = "NotificationAdapter.clearBacktest";
34172
34245
  const NOTIFICATION_ADAPTER_METHOD_NAME_CLEAR_LIVE = "NotificationAdapter.clearLive";
34173
34246
  const NOTIFICATION_BACKTEST_ADAPTER_METHOD_NAME_USE_ADAPTER = "NotificationBacktestAdapter.useNotificationAdapter";
34174
34247
  const NOTIFICATION_BACKTEST_ADAPTER_METHOD_NAME_USE_DUMMY = "NotificationBacktestAdapter.useDummy";
@@ -34227,7 +34300,7 @@ class NotificationMemoryBacktestUtils {
34227
34300
  */
34228
34301
  this.handleSignal = async (data) => {
34229
34302
  bt.loggerService.info(NOTIFICATION_MEMORY_BACKTEST_METHOD_NAME_HANDLE_SIGNAL, {
34230
- signalId: data.signal.id,
34303
+ signalId: data.signal?.id,
34231
34304
  action: data.action,
34232
34305
  });
34233
34306
  const notification = CREATE_SIGNAL_NOTIFICATION_FN(data);
@@ -34345,7 +34418,7 @@ class NotificationMemoryBacktestUtils {
34345
34418
  */
34346
34419
  _addNotification(notification) {
34347
34420
  this._notifications.unshift(notification);
34348
- if (this._notifications.length > MAX_NOTIFICATIONS) {
34421
+ if (this._notifications.length > GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS) {
34349
34422
  this._notifications.pop();
34350
34423
  }
34351
34424
  }
@@ -34446,7 +34519,7 @@ class NotificationPersistBacktestUtils {
34446
34519
  return aTime - bTime;
34447
34520
  });
34448
34521
  this._notifications = new Map(notificationList
34449
- .slice(-MAX_NOTIFICATIONS)
34522
+ .slice(-GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS)
34450
34523
  .map((notification) => [notification.id, notification]));
34451
34524
  });
34452
34525
  /**
@@ -34456,7 +34529,7 @@ class NotificationPersistBacktestUtils {
34456
34529
  */
34457
34530
  this.handleSignal = async (data) => {
34458
34531
  bt.loggerService.info(NOTIFICATION_PERSIST_BACKTEST_METHOD_NAME_HANDLE_SIGNAL, {
34459
- signalId: data.signal.id,
34532
+ signalId: data.signal?.id,
34460
34533
  action: data.action,
34461
34534
  });
34462
34535
  await this.waitForInit();
@@ -34604,7 +34677,7 @@ class NotificationPersistBacktestUtils {
34604
34677
  const bTime = 'createdAt' in b ? b.createdAt : 0;
34605
34678
  return aTime - bTime;
34606
34679
  });
34607
- await PersistNotificationAdapter.writeNotificationData(notificationList.slice(-MAX_NOTIFICATIONS), true);
34680
+ await PersistNotificationAdapter.writeNotificationData(notificationList.slice(-GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS), true);
34608
34681
  }
34609
34682
  /**
34610
34683
  * Adds a notification to the map.
@@ -34613,7 +34686,7 @@ class NotificationPersistBacktestUtils {
34613
34686
  */
34614
34687
  _addNotification(notification) {
34615
34688
  this._notifications.set(notification.id, notification);
34616
- if (this._notifications.size > MAX_NOTIFICATIONS) {
34689
+ if (this._notifications.size > GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS) {
34617
34690
  const firstKey = this._notifications.keys().next().value;
34618
34691
  if (firstKey) {
34619
34692
  this._notifications.delete(firstKey);
@@ -34644,7 +34717,7 @@ class NotificationMemoryLiveUtils {
34644
34717
  */
34645
34718
  this.handleSignal = async (data) => {
34646
34719
  bt.loggerService.info(NOTIFICATION_MEMORY_LIVE_METHOD_NAME_HANDLE_SIGNAL, {
34647
- signalId: data.signal.id,
34720
+ signalId: data.signal?.id,
34648
34721
  action: data.action,
34649
34722
  });
34650
34723
  const notification = CREATE_SIGNAL_NOTIFICATION_FN(data);
@@ -34762,7 +34835,7 @@ class NotificationMemoryLiveUtils {
34762
34835
  */
34763
34836
  _addNotification(notification) {
34764
34837
  this._notifications.unshift(notification);
34765
- if (this._notifications.length > MAX_NOTIFICATIONS) {
34838
+ if (this._notifications.length > GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS) {
34766
34839
  this._notifications.pop();
34767
34840
  }
34768
34841
  }
@@ -34864,7 +34937,7 @@ class NotificationPersistLiveUtils {
34864
34937
  return aTime - bTime;
34865
34938
  });
34866
34939
  this._notifications = new Map(notificationList
34867
- .slice(-MAX_NOTIFICATIONS)
34940
+ .slice(-GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS)
34868
34941
  .map((notification) => [notification.id, notification]));
34869
34942
  });
34870
34943
  /**
@@ -34874,7 +34947,7 @@ class NotificationPersistLiveUtils {
34874
34947
  */
34875
34948
  this.handleSignal = async (data) => {
34876
34949
  bt.loggerService.info(NOTIFICATION_PERSIST_LIVE_METHOD_NAME_HANDLE_SIGNAL, {
34877
- signalId: data.signal.id,
34950
+ signalId: data.signal?.id,
34878
34951
  action: data.action,
34879
34952
  });
34880
34953
  await this.waitForInit();
@@ -35024,7 +35097,7 @@ class NotificationPersistLiveUtils {
35024
35097
  const bTime = 'createdAt' in b ? b.createdAt : 0;
35025
35098
  return aTime - bTime;
35026
35099
  });
35027
- await PersistNotificationAdapter.writeNotificationData(notificationList.slice(-MAX_NOTIFICATIONS), false);
35100
+ await PersistNotificationAdapter.writeNotificationData(notificationList.slice(-GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS), false);
35028
35101
  }
35029
35102
  /**
35030
35103
  * Adds a notification to the map.
@@ -35033,7 +35106,7 @@ class NotificationPersistLiveUtils {
35033
35106
  */
35034
35107
  _addNotification(notification) {
35035
35108
  this._notifications.set(notification.id, notification);
35036
- if (this._notifications.size > MAX_NOTIFICATIONS) {
35109
+ if (this._notifications.size > GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS) {
35037
35110
  const firstKey = this._notifications.keys().next().value;
35038
35111
  if (firstKey) {
35039
35112
  this._notifications.delete(firstKey);
@@ -35396,52 +35469,37 @@ class NotificationAdapter {
35396
35469
  }
35397
35470
  };
35398
35471
  /**
35399
- * Gets all backtest notifications from storage.
35472
+ * Gets all backtest/live notifications from storage.
35400
35473
  *
35401
35474
  * @returns Array of all backtest notification models
35402
35475
  * @throws Error if NotificationAdapter is not enabled
35403
35476
  */
35404
- this.getDataBacktest = async () => {
35405
- bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_GET_DATA_BACKTEST);
35477
+ this.getData = async (isBacktest) => {
35478
+ bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_GET_DATA_BACKTEST, {
35479
+ backtest: isBacktest,
35480
+ });
35406
35481
  if (!this.enable.hasValue()) {
35407
35482
  throw new Error("NotificationAdapter is not enabled. Call enable() first.");
35408
35483
  }
35409
- return await NotificationBacktest.getData();
35410
- };
35411
- /**
35412
- * Gets all live notifications from storage.
35413
- *
35414
- * @returns Array of all live notification models
35415
- * @throws Error if NotificationAdapter is not enabled
35416
- */
35417
- this.getDataLive = async () => {
35418
- bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_GET_DATA_LIVE);
35419
- if (!this.enable.hasValue()) {
35420
- throw new Error("NotificationAdapter is not enabled. Call enable() first.");
35484
+ if (isBacktest) {
35485
+ return await NotificationBacktest.getData();
35421
35486
  }
35422
35487
  return await NotificationLive.getData();
35423
35488
  };
35424
35489
  /**
35425
- * Clears all backtest notifications from storage.
35490
+ * Clears all backtest/live notifications from storage.
35426
35491
  *
35427
35492
  * @throws Error if NotificationAdapter is not enabled
35428
35493
  */
35429
- this.clearBacktest = async () => {
35430
- bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_CLEAR_BACKTEST);
35494
+ this.clear = async (isBacktest) => {
35495
+ bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_CLEAR_LIVE, {
35496
+ backtest: isBacktest,
35497
+ });
35431
35498
  if (!this.enable.hasValue()) {
35432
35499
  throw new Error("NotificationAdapter is not enabled. Call enable() first.");
35433
35500
  }
35434
- return await NotificationBacktest.clear();
35435
- };
35436
- /**
35437
- * Clears all live notifications from storage.
35438
- *
35439
- * @throws Error if NotificationAdapter is not enabled
35440
- */
35441
- this.clearLive = async () => {
35442
- bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_CLEAR_LIVE);
35443
- if (!this.enable.hasValue()) {
35444
- throw new Error("NotificationAdapter is not enabled. Call enable() first.");
35501
+ if (isBacktest) {
35502
+ return await NotificationBacktest.clear();
35445
35503
  }
35446
35504
  return await NotificationLive.clear();
35447
35505
  };
package/build/index.mjs CHANGED
@@ -408,6 +408,20 @@ const GLOBAL_CONFIG = {
408
408
  * Default: 20 levels
409
409
  */
410
410
  CC_ORDER_BOOK_MAX_DEPTH_LEVELS: 1000,
411
+ /**
412
+ * Maximum number of notifications to keep in storage.
413
+ * Older notifications are removed when this limit is exceeded.
414
+ *
415
+ * Default: 500 notifications
416
+ */
417
+ CC_MAX_NOTIFICATIONS: 500,
418
+ /**
419
+ * Maximum number of signals to keep in storage.
420
+ * Older signals are removed when this limit is exceeded.
421
+ *
422
+ * Default: 50 signals
423
+ */
424
+ CC_MAX_SIGNALS: 50,
411
425
  };
412
426
  const DEFAULT_CONFIG = Object.freeze({ ...GLOBAL_CONFIG });
413
427
 
@@ -22046,6 +22060,13 @@ class ConfigValidationService {
22046
22060
  if (!Number.isInteger(GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES) || GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES < 0) {
22047
22061
  errors.push(`CC_ORDER_BOOK_TIME_OFFSET_MINUTES must be a non-negative integer, got ${GLOBAL_CONFIG.CC_ORDER_BOOK_TIME_OFFSET_MINUTES}`);
22048
22062
  }
22063
+ // Validate notification and storage limits
22064
+ if (!Number.isInteger(GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS) || GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS <= 0) {
22065
+ errors.push(`CC_MAX_NOTIFICATIONS must be a positive integer, got ${GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS}`);
22066
+ }
22067
+ if (!Number.isInteger(GLOBAL_CONFIG.CC_MAX_SIGNALS) || GLOBAL_CONFIG.CC_MAX_SIGNALS <= 0) {
22068
+ errors.push(`CC_MAX_SIGNALS must be a positive integer, got ${GLOBAL_CONFIG.CC_MAX_SIGNALS}`);
22069
+ }
22049
22070
  // Throw aggregated errors if any
22050
22071
  if (errors.length > 0) {
22051
22072
  const errorMessage = `GLOBAL_CONFIG validation failed:\n${errors.map((e, i) => ` ${i + 1}. ${e}`).join('\n')}`;
@@ -32704,7 +32725,6 @@ class ConstantUtils {
32704
32725
  */
32705
32726
  const Constant = new ConstantUtils();
32706
32727
 
32707
- const MAX_SIGNALS = 25;
32708
32728
  const STORAGE_BACKTEST_METHOD_NAME_WAIT_FOR_INIT = "StoragePersistBacktestUtils.waitForInit";
32709
32729
  const STORAGE_BACKTEST_METHOD_NAME_UPDATE_STORAGE = "StoragePersistBacktestUtils._updateStorage";
32710
32730
  const STORAGE_BACKTEST_METHOD_NAME_HANDLE_OPENED = "StoragePersistBacktestUtils.handleOpened";
@@ -32769,7 +32789,7 @@ class StoragePersistBacktestUtils {
32769
32789
  const signalList = await PersistStorageAdapter.readStorageData(true);
32770
32790
  signalList.sort((a, b) => a.priority - b.priority);
32771
32791
  this._signals = new Map(signalList
32772
- .slice(-MAX_SIGNALS)
32792
+ .slice(-GLOBAL_CONFIG.CC_MAX_SIGNALS)
32773
32793
  .map((signal) => [signal.id, signal]));
32774
32794
  });
32775
32795
  /**
@@ -32793,6 +32813,7 @@ class StoragePersistBacktestUtils {
32793
32813
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32794
32814
  updatedAt: tick.createdAt,
32795
32815
  });
32816
+ this._enforceLimit();
32796
32817
  await this._updateStorage();
32797
32818
  };
32798
32819
  /**
@@ -32817,6 +32838,7 @@ class StoragePersistBacktestUtils {
32817
32838
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32818
32839
  updatedAt: tick.createdAt,
32819
32840
  });
32841
+ this._enforceLimit();
32820
32842
  await this._updateStorage();
32821
32843
  };
32822
32844
  /**
@@ -32840,6 +32862,7 @@ class StoragePersistBacktestUtils {
32840
32862
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32841
32863
  updatedAt: tick.createdAt,
32842
32864
  });
32865
+ this._enforceLimit();
32843
32866
  await this._updateStorage();
32844
32867
  };
32845
32868
  /**
@@ -32863,6 +32886,7 @@ class StoragePersistBacktestUtils {
32863
32886
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32864
32887
  updatedAt: tick.createdAt,
32865
32888
  });
32889
+ this._enforceLimit();
32866
32890
  await this._updateStorage();
32867
32891
  };
32868
32892
  /**
@@ -32885,6 +32909,17 @@ class StoragePersistBacktestUtils {
32885
32909
  return Array.from(this._signals.values());
32886
32910
  };
32887
32911
  }
32912
+ /**
32913
+ * Removes oldest signal if limit is exceeded.
32914
+ */
32915
+ _enforceLimit() {
32916
+ if (this._signals.size > GLOBAL_CONFIG.CC_MAX_SIGNALS) {
32917
+ const firstKey = this._signals.keys().next().value;
32918
+ if (firstKey) {
32919
+ this._signals.delete(firstKey);
32920
+ }
32921
+ }
32922
+ }
32888
32923
  /**
32889
32924
  * Persists the current signal map to disk storage.
32890
32925
  * Sorts signals by priority and keeps only the most recent MAX_SIGNALS.
@@ -32897,7 +32932,7 @@ class StoragePersistBacktestUtils {
32897
32932
  }
32898
32933
  const signalList = Array.from(this._signals.values());
32899
32934
  signalList.sort((a, b) => a.priority - b.priority);
32900
- await PersistStorageAdapter.writeStorageData(signalList.slice(-MAX_SIGNALS), true);
32935
+ await PersistStorageAdapter.writeStorageData(signalList.slice(-GLOBAL_CONFIG.CC_MAX_SIGNALS), true);
32901
32936
  }
32902
32937
  }
32903
32938
  /**
@@ -32936,6 +32971,7 @@ class StorageMemoryBacktestUtils {
32936
32971
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32937
32972
  updatedAt: tick.createdAt,
32938
32973
  });
32974
+ this._enforceLimit();
32939
32975
  };
32940
32976
  /**
32941
32977
  * Handles signal closed event.
@@ -32958,6 +32994,7 @@ class StorageMemoryBacktestUtils {
32958
32994
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32959
32995
  updatedAt: tick.createdAt,
32960
32996
  });
32997
+ this._enforceLimit();
32961
32998
  };
32962
32999
  /**
32963
33000
  * Handles signal scheduled event.
@@ -32979,6 +33016,7 @@ class StorageMemoryBacktestUtils {
32979
33016
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
32980
33017
  updatedAt: tick.createdAt,
32981
33018
  });
33019
+ this._enforceLimit();
32982
33020
  };
32983
33021
  /**
32984
33022
  * Handles signal cancelled event.
@@ -33000,6 +33038,7 @@ class StorageMemoryBacktestUtils {
33000
33038
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33001
33039
  updatedAt: tick.createdAt,
33002
33040
  });
33041
+ this._enforceLimit();
33003
33042
  };
33004
33043
  /**
33005
33044
  * Finds a signal by its ID.
@@ -33019,6 +33058,17 @@ class StorageMemoryBacktestUtils {
33019
33058
  return Array.from(this._signals.values());
33020
33059
  };
33021
33060
  }
33061
+ /**
33062
+ * Removes oldest signal if limit is exceeded.
33063
+ */
33064
+ _enforceLimit() {
33065
+ if (this._signals.size > GLOBAL_CONFIG.CC_MAX_SIGNALS) {
33066
+ const firstKey = this._signals.keys().next().value;
33067
+ if (firstKey) {
33068
+ this._signals.delete(firstKey);
33069
+ }
33070
+ }
33071
+ }
33022
33072
  }
33023
33073
  /**
33024
33074
  * Dummy storage adapter for backtest signals that discards all writes.
@@ -33091,7 +33141,7 @@ class StoragePersistLiveUtils {
33091
33141
  const signalList = await PersistStorageAdapter.readStorageData(false);
33092
33142
  signalList.sort((a, b) => a.priority - b.priority);
33093
33143
  this._signals = new Map(signalList
33094
- .slice(-MAX_SIGNALS)
33144
+ .slice(-GLOBAL_CONFIG.CC_MAX_SIGNALS)
33095
33145
  .map((signal) => [signal.id, signal]));
33096
33146
  });
33097
33147
  /**
@@ -33115,6 +33165,7 @@ class StoragePersistLiveUtils {
33115
33165
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33116
33166
  updatedAt: tick.createdAt,
33117
33167
  });
33168
+ this._enforceLimit();
33118
33169
  await this._updateStorage();
33119
33170
  };
33120
33171
  /**
@@ -33139,6 +33190,7 @@ class StoragePersistLiveUtils {
33139
33190
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33140
33191
  updatedAt: tick.createdAt,
33141
33192
  });
33193
+ this._enforceLimit();
33142
33194
  await this._updateStorage();
33143
33195
  };
33144
33196
  /**
@@ -33162,6 +33214,7 @@ class StoragePersistLiveUtils {
33162
33214
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33163
33215
  updatedAt: tick.createdAt,
33164
33216
  });
33217
+ this._enforceLimit();
33165
33218
  await this._updateStorage();
33166
33219
  };
33167
33220
  /**
@@ -33185,6 +33238,7 @@ class StoragePersistLiveUtils {
33185
33238
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33186
33239
  updatedAt: tick.createdAt,
33187
33240
  });
33241
+ this._enforceLimit();
33188
33242
  await this._updateStorage();
33189
33243
  };
33190
33244
  /**
@@ -33207,6 +33261,17 @@ class StoragePersistLiveUtils {
33207
33261
  return Array.from(this._signals.values());
33208
33262
  };
33209
33263
  }
33264
+ /**
33265
+ * Removes oldest signal if limit is exceeded.
33266
+ */
33267
+ _enforceLimit() {
33268
+ if (this._signals.size > GLOBAL_CONFIG.CC_MAX_SIGNALS) {
33269
+ const firstKey = this._signals.keys().next().value;
33270
+ if (firstKey) {
33271
+ this._signals.delete(firstKey);
33272
+ }
33273
+ }
33274
+ }
33210
33275
  /**
33211
33276
  * Persists the current signal map to disk storage.
33212
33277
  * Sorts signals by priority and keeps only the most recent MAX_SIGNALS.
@@ -33219,7 +33284,7 @@ class StoragePersistLiveUtils {
33219
33284
  }
33220
33285
  const signalList = Array.from(this._signals.values());
33221
33286
  signalList.sort((a, b) => a.priority - b.priority);
33222
- await PersistStorageAdapter.writeStorageData(signalList.slice(-MAX_SIGNALS), false);
33287
+ await PersistStorageAdapter.writeStorageData(signalList.slice(-GLOBAL_CONFIG.CC_MAX_SIGNALS), false);
33223
33288
  }
33224
33289
  }
33225
33290
  /**
@@ -33258,6 +33323,7 @@ class StorageMemoryLiveUtils {
33258
33323
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33259
33324
  updatedAt: tick.createdAt,
33260
33325
  });
33326
+ this._enforceLimit();
33261
33327
  };
33262
33328
  /**
33263
33329
  * Handles signal closed event.
@@ -33280,6 +33346,7 @@ class StorageMemoryLiveUtils {
33280
33346
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33281
33347
  updatedAt: tick.createdAt,
33282
33348
  });
33349
+ this._enforceLimit();
33283
33350
  };
33284
33351
  /**
33285
33352
  * Handles signal scheduled event.
@@ -33301,6 +33368,7 @@ class StorageMemoryLiveUtils {
33301
33368
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33302
33369
  updatedAt: tick.createdAt,
33303
33370
  });
33371
+ this._enforceLimit();
33304
33372
  };
33305
33373
  /**
33306
33374
  * Handles signal cancelled event.
@@ -33322,6 +33390,7 @@ class StorageMemoryLiveUtils {
33322
33390
  createdAt: lastStorage ? lastStorage.createdAt : tick.createdAt,
33323
33391
  updatedAt: tick.createdAt,
33324
33392
  });
33393
+ this._enforceLimit();
33325
33394
  };
33326
33395
  /**
33327
33396
  * Finds a signal by its ID.
@@ -33341,6 +33410,17 @@ class StorageMemoryLiveUtils {
33341
33410
  return Array.from(this._signals.values());
33342
33411
  };
33343
33412
  }
33413
+ /**
33414
+ * Removes oldest signal if limit is exceeded.
33415
+ */
33416
+ _enforceLimit() {
33417
+ if (this._signals.size > GLOBAL_CONFIG.CC_MAX_SIGNALS) {
33418
+ const firstKey = this._signals.keys().next().value;
33419
+ if (firstKey) {
33420
+ this._signals.delete(firstKey);
33421
+ }
33422
+ }
33423
+ }
33344
33424
  }
33345
33425
  /**
33346
33426
  * Dummy storage adapter for live trading signals that discards all writes.
@@ -33720,11 +33800,6 @@ const StorageLive = new StorageLiveAdapter();
33720
33800
  */
33721
33801
  const StorageBacktest = new StorageBacktestAdapter();
33722
33802
 
33723
- /**
33724
- * Maximum number of notifications to keep in storage.
33725
- * Older notifications are removed when this limit is exceeded.
33726
- */
33727
- const MAX_NOTIFICATIONS = 250;
33728
33803
  /**
33729
33804
  * Generates a unique key for notification identification.
33730
33805
  * @returns Random string identifier
@@ -34147,8 +34222,6 @@ const NOTIFICATION_MEMORY_LIVE_METHOD_NAME_CLEAR = "NotificationMemoryLiveUtils.
34147
34222
  const NOTIFICATION_ADAPTER_METHOD_NAME_ENABLE = "NotificationAdapter.enable";
34148
34223
  const NOTIFICATION_ADAPTER_METHOD_NAME_DISABLE = "NotificationAdapter.disable";
34149
34224
  const NOTIFICATION_ADAPTER_METHOD_NAME_GET_DATA_BACKTEST = "NotificationAdapter.getDataBacktest";
34150
- const NOTIFICATION_ADAPTER_METHOD_NAME_GET_DATA_LIVE = "NotificationAdapter.getDataLive";
34151
- const NOTIFICATION_ADAPTER_METHOD_NAME_CLEAR_BACKTEST = "NotificationAdapter.clearBacktest";
34152
34225
  const NOTIFICATION_ADAPTER_METHOD_NAME_CLEAR_LIVE = "NotificationAdapter.clearLive";
34153
34226
  const NOTIFICATION_BACKTEST_ADAPTER_METHOD_NAME_USE_ADAPTER = "NotificationBacktestAdapter.useNotificationAdapter";
34154
34227
  const NOTIFICATION_BACKTEST_ADAPTER_METHOD_NAME_USE_DUMMY = "NotificationBacktestAdapter.useDummy";
@@ -34207,7 +34280,7 @@ class NotificationMemoryBacktestUtils {
34207
34280
  */
34208
34281
  this.handleSignal = async (data) => {
34209
34282
  bt.loggerService.info(NOTIFICATION_MEMORY_BACKTEST_METHOD_NAME_HANDLE_SIGNAL, {
34210
- signalId: data.signal.id,
34283
+ signalId: data.signal?.id,
34211
34284
  action: data.action,
34212
34285
  });
34213
34286
  const notification = CREATE_SIGNAL_NOTIFICATION_FN(data);
@@ -34325,7 +34398,7 @@ class NotificationMemoryBacktestUtils {
34325
34398
  */
34326
34399
  _addNotification(notification) {
34327
34400
  this._notifications.unshift(notification);
34328
- if (this._notifications.length > MAX_NOTIFICATIONS) {
34401
+ if (this._notifications.length > GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS) {
34329
34402
  this._notifications.pop();
34330
34403
  }
34331
34404
  }
@@ -34426,7 +34499,7 @@ class NotificationPersistBacktestUtils {
34426
34499
  return aTime - bTime;
34427
34500
  });
34428
34501
  this._notifications = new Map(notificationList
34429
- .slice(-MAX_NOTIFICATIONS)
34502
+ .slice(-GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS)
34430
34503
  .map((notification) => [notification.id, notification]));
34431
34504
  });
34432
34505
  /**
@@ -34436,7 +34509,7 @@ class NotificationPersistBacktestUtils {
34436
34509
  */
34437
34510
  this.handleSignal = async (data) => {
34438
34511
  bt.loggerService.info(NOTIFICATION_PERSIST_BACKTEST_METHOD_NAME_HANDLE_SIGNAL, {
34439
- signalId: data.signal.id,
34512
+ signalId: data.signal?.id,
34440
34513
  action: data.action,
34441
34514
  });
34442
34515
  await this.waitForInit();
@@ -34584,7 +34657,7 @@ class NotificationPersistBacktestUtils {
34584
34657
  const bTime = 'createdAt' in b ? b.createdAt : 0;
34585
34658
  return aTime - bTime;
34586
34659
  });
34587
- await PersistNotificationAdapter.writeNotificationData(notificationList.slice(-MAX_NOTIFICATIONS), true);
34660
+ await PersistNotificationAdapter.writeNotificationData(notificationList.slice(-GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS), true);
34588
34661
  }
34589
34662
  /**
34590
34663
  * Adds a notification to the map.
@@ -34593,7 +34666,7 @@ class NotificationPersistBacktestUtils {
34593
34666
  */
34594
34667
  _addNotification(notification) {
34595
34668
  this._notifications.set(notification.id, notification);
34596
- if (this._notifications.size > MAX_NOTIFICATIONS) {
34669
+ if (this._notifications.size > GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS) {
34597
34670
  const firstKey = this._notifications.keys().next().value;
34598
34671
  if (firstKey) {
34599
34672
  this._notifications.delete(firstKey);
@@ -34624,7 +34697,7 @@ class NotificationMemoryLiveUtils {
34624
34697
  */
34625
34698
  this.handleSignal = async (data) => {
34626
34699
  bt.loggerService.info(NOTIFICATION_MEMORY_LIVE_METHOD_NAME_HANDLE_SIGNAL, {
34627
- signalId: data.signal.id,
34700
+ signalId: data.signal?.id,
34628
34701
  action: data.action,
34629
34702
  });
34630
34703
  const notification = CREATE_SIGNAL_NOTIFICATION_FN(data);
@@ -34742,7 +34815,7 @@ class NotificationMemoryLiveUtils {
34742
34815
  */
34743
34816
  _addNotification(notification) {
34744
34817
  this._notifications.unshift(notification);
34745
- if (this._notifications.length > MAX_NOTIFICATIONS) {
34818
+ if (this._notifications.length > GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS) {
34746
34819
  this._notifications.pop();
34747
34820
  }
34748
34821
  }
@@ -34844,7 +34917,7 @@ class NotificationPersistLiveUtils {
34844
34917
  return aTime - bTime;
34845
34918
  });
34846
34919
  this._notifications = new Map(notificationList
34847
- .slice(-MAX_NOTIFICATIONS)
34920
+ .slice(-GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS)
34848
34921
  .map((notification) => [notification.id, notification]));
34849
34922
  });
34850
34923
  /**
@@ -34854,7 +34927,7 @@ class NotificationPersistLiveUtils {
34854
34927
  */
34855
34928
  this.handleSignal = async (data) => {
34856
34929
  bt.loggerService.info(NOTIFICATION_PERSIST_LIVE_METHOD_NAME_HANDLE_SIGNAL, {
34857
- signalId: data.signal.id,
34930
+ signalId: data.signal?.id,
34858
34931
  action: data.action,
34859
34932
  });
34860
34933
  await this.waitForInit();
@@ -35004,7 +35077,7 @@ class NotificationPersistLiveUtils {
35004
35077
  const bTime = 'createdAt' in b ? b.createdAt : 0;
35005
35078
  return aTime - bTime;
35006
35079
  });
35007
- await PersistNotificationAdapter.writeNotificationData(notificationList.slice(-MAX_NOTIFICATIONS), false);
35080
+ await PersistNotificationAdapter.writeNotificationData(notificationList.slice(-GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS), false);
35008
35081
  }
35009
35082
  /**
35010
35083
  * Adds a notification to the map.
@@ -35013,7 +35086,7 @@ class NotificationPersistLiveUtils {
35013
35086
  */
35014
35087
  _addNotification(notification) {
35015
35088
  this._notifications.set(notification.id, notification);
35016
- if (this._notifications.size > MAX_NOTIFICATIONS) {
35089
+ if (this._notifications.size > GLOBAL_CONFIG.CC_MAX_NOTIFICATIONS) {
35017
35090
  const firstKey = this._notifications.keys().next().value;
35018
35091
  if (firstKey) {
35019
35092
  this._notifications.delete(firstKey);
@@ -35376,52 +35449,37 @@ class NotificationAdapter {
35376
35449
  }
35377
35450
  };
35378
35451
  /**
35379
- * Gets all backtest notifications from storage.
35452
+ * Gets all backtest/live notifications from storage.
35380
35453
  *
35381
35454
  * @returns Array of all backtest notification models
35382
35455
  * @throws Error if NotificationAdapter is not enabled
35383
35456
  */
35384
- this.getDataBacktest = async () => {
35385
- bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_GET_DATA_BACKTEST);
35457
+ this.getData = async (isBacktest) => {
35458
+ bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_GET_DATA_BACKTEST, {
35459
+ backtest: isBacktest,
35460
+ });
35386
35461
  if (!this.enable.hasValue()) {
35387
35462
  throw new Error("NotificationAdapter is not enabled. Call enable() first.");
35388
35463
  }
35389
- return await NotificationBacktest.getData();
35390
- };
35391
- /**
35392
- * Gets all live notifications from storage.
35393
- *
35394
- * @returns Array of all live notification models
35395
- * @throws Error if NotificationAdapter is not enabled
35396
- */
35397
- this.getDataLive = async () => {
35398
- bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_GET_DATA_LIVE);
35399
- if (!this.enable.hasValue()) {
35400
- throw new Error("NotificationAdapter is not enabled. Call enable() first.");
35464
+ if (isBacktest) {
35465
+ return await NotificationBacktest.getData();
35401
35466
  }
35402
35467
  return await NotificationLive.getData();
35403
35468
  };
35404
35469
  /**
35405
- * Clears all backtest notifications from storage.
35470
+ * Clears all backtest/live notifications from storage.
35406
35471
  *
35407
35472
  * @throws Error if NotificationAdapter is not enabled
35408
35473
  */
35409
- this.clearBacktest = async () => {
35410
- bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_CLEAR_BACKTEST);
35474
+ this.clear = async (isBacktest) => {
35475
+ bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_CLEAR_LIVE, {
35476
+ backtest: isBacktest,
35477
+ });
35411
35478
  if (!this.enable.hasValue()) {
35412
35479
  throw new Error("NotificationAdapter is not enabled. Call enable() first.");
35413
35480
  }
35414
- return await NotificationBacktest.clear();
35415
- };
35416
- /**
35417
- * Clears all live notifications from storage.
35418
- *
35419
- * @throws Error if NotificationAdapter is not enabled
35420
- */
35421
- this.clearLive = async () => {
35422
- bt.loggerService.info(NOTIFICATION_ADAPTER_METHOD_NAME_CLEAR_LIVE);
35423
- if (!this.enable.hasValue()) {
35424
- throw new Error("NotificationAdapter is not enabled. Call enable() first.");
35481
+ if (isBacktest) {
35482
+ return await NotificationBacktest.clear();
35425
35483
  }
35426
35484
  return await NotificationLive.clear();
35427
35485
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backtest-kit",
3
- "version": "3.0.2",
3
+ "version": "3.0.4",
4
4
  "description": "A TypeScript library for trading system backtest",
5
5
  "author": {
6
6
  "name": "Petr Tripolsky",
package/types.d.ts CHANGED
@@ -4209,6 +4209,20 @@ declare const GLOBAL_CONFIG: {
4209
4209
  * Default: 20 levels
4210
4210
  */
4211
4211
  CC_ORDER_BOOK_MAX_DEPTH_LEVELS: number;
4212
+ /**
4213
+ * Maximum number of notifications to keep in storage.
4214
+ * Older notifications are removed when this limit is exceeded.
4215
+ *
4216
+ * Default: 500 notifications
4217
+ */
4218
+ CC_MAX_NOTIFICATIONS: number;
4219
+ /**
4220
+ * Maximum number of signals to keep in storage.
4221
+ * Older signals are removed when this limit is exceeded.
4222
+ *
4223
+ * Default: 50 signals
4224
+ */
4225
+ CC_MAX_SIGNALS: number;
4212
4226
  };
4213
4227
  /**
4214
4228
  * Type for global configuration object.
@@ -4315,6 +4329,8 @@ declare function getConfig(): {
4315
4329
  CC_BREAKEVEN_THRESHOLD: number;
4316
4330
  CC_ORDER_BOOK_TIME_OFFSET_MINUTES: number;
4317
4331
  CC_ORDER_BOOK_MAX_DEPTH_LEVELS: number;
4332
+ CC_MAX_NOTIFICATIONS: number;
4333
+ CC_MAX_SIGNALS: number;
4318
4334
  };
4319
4335
  /**
4320
4336
  * Retrieves the default configuration object for the framework.
@@ -4349,6 +4365,8 @@ declare function getDefaultConfig(): Readonly<{
4349
4365
  CC_BREAKEVEN_THRESHOLD: number;
4350
4366
  CC_ORDER_BOOK_TIME_OFFSET_MINUTES: number;
4351
4367
  CC_ORDER_BOOK_MAX_DEPTH_LEVELS: number;
4368
+ CC_MAX_NOTIFICATIONS: number;
4369
+ CC_MAX_SIGNALS: number;
4352
4370
  }>;
4353
4371
  /**
4354
4372
  * Sets custom column configurations for markdown report generation.
@@ -13686,31 +13704,18 @@ declare class NotificationAdapter {
13686
13704
  */
13687
13705
  disable: () => void;
13688
13706
  /**
13689
- * Gets all backtest notifications from storage.
13707
+ * Gets all backtest/live notifications from storage.
13690
13708
  *
13691
13709
  * @returns Array of all backtest notification models
13692
13710
  * @throws Error if NotificationAdapter is not enabled
13693
13711
  */
13694
- getDataBacktest: () => Promise<NotificationModel[]>;
13695
- /**
13696
- * Gets all live notifications from storage.
13697
- *
13698
- * @returns Array of all live notification models
13699
- * @throws Error if NotificationAdapter is not enabled
13700
- */
13701
- getDataLive: () => Promise<NotificationModel[]>;
13702
- /**
13703
- * Clears all backtest notifications from storage.
13704
- *
13705
- * @throws Error if NotificationAdapter is not enabled
13706
- */
13707
- clearBacktest: () => Promise<void>;
13712
+ getData: (isBacktest: boolean) => Promise<NotificationModel[]>;
13708
13713
  /**
13709
- * Clears all live notifications from storage.
13714
+ * Clears all backtest/live notifications from storage.
13710
13715
  *
13711
13716
  * @throws Error if NotificationAdapter is not enabled
13712
13717
  */
13713
- clearLive: () => Promise<void>;
13718
+ clear: (isBacktest: boolean) => Promise<void>;
13714
13719
  }
13715
13720
  /**
13716
13721
  * Global singleton instance of NotificationAdapter.