backtest-kit 1.6.2 → 1.6.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # 🧿 Backtest Kit
4
4
 
5
- > A TypeScript framework for backtesting and live trading strategies on multi-asset, crypto or forex, with crash-safe persistence, signal validation, and AI optimization.
5
+ > A TypeScript framework for backtesting and live trading strategies on multi-asset, crypto, forex or [DEX (peer-to-peer marketplace)](https://en.wikipedia.org/wiki/Decentralized_finance#Decentralized_exchanges) with crash-safe persistence, signal validation, and AI optimization.
6
6
 
7
7
  ![future](./assets/prophet.png)
8
8
 
package/build/index.cjs CHANGED
@@ -2401,7 +2401,7 @@ const CALL_PING_CALLBACKS_FN = functoolsKit.trycatch(async (self, scheduled, tim
2401
2401
  backtest$1.loggerService.warn(message, payload);
2402
2402
  console.warn(message, payload);
2403
2403
  errorEmitter.next(error);
2404
- }
2404
+ },
2405
2405
  });
2406
2406
  const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice) => {
2407
2407
  await CALL_PING_CALLBACKS_FN(self, scheduled, self.params.execution.context.when.getTime());
@@ -3760,6 +3760,15 @@ const GET_RISK_FN = (dto, backtest, self) => {
3760
3760
  ...dto.riskList.map((riskName) => self.riskConnectionService.getRisk(riskName, backtest)),
3761
3761
  ]);
3762
3762
  };
3763
+ /**
3764
+ * Creates a unique key for memoizing ClientStrategy instances.
3765
+ * Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
3766
+ * @param symbol - Trading pair symbol
3767
+ * @param strategyName - Name of the strategy
3768
+ * @param backtest - Whether running in backtest mode
3769
+ * @returns Unique string key for memoization
3770
+ */
3771
+ const CREATE_KEY_FN$9 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
3763
3772
  /**
3764
3773
  * Callback function for emitting ping events to pingSubject.
3765
3774
  *
@@ -3820,7 +3829,7 @@ class StrategyConnectionService {
3820
3829
  * @param strategyName - Name of registered strategy schema
3821
3830
  * @returns Configured ClientStrategy instance
3822
3831
  */
3823
- this.getStrategy = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, (symbol, strategyName, backtest) => {
3832
+ this.getStrategy = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$9(symbol, strategyName, backtest), (symbol, strategyName, backtest) => {
3824
3833
  const { riskName = "", riskList = [], getSignal, interval, callbacks, } = this.strategySchemaService.get(strategyName);
3825
3834
  return new ClientStrategy({
3826
3835
  symbol,
@@ -3987,7 +3996,7 @@ class StrategyConnectionService {
3987
3996
  ctx,
3988
3997
  });
3989
3998
  if (ctx) {
3990
- const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
3999
+ const key = CREATE_KEY_FN$9(ctx.symbol, ctx.strategyName, backtest);
3991
4000
  this.getStrategy.clear(key);
3992
4001
  }
3993
4002
  else {
@@ -4590,6 +4599,14 @@ class ClientRisk {
4590
4599
  }
4591
4600
  }
4592
4601
 
4602
+ /**
4603
+ * Creates a unique key for memoizing ClientRisk instances.
4604
+ * Key format: "riskName:backtest" or "riskName:live"
4605
+ * @param riskName - Name of the risk schema
4606
+ * @param backtest - Whether running in backtest mode
4607
+ * @returns Unique string key for memoization
4608
+ */
4609
+ const CREATE_KEY_FN$8 = (riskName, backtest) => `${riskName}:${backtest ? "backtest" : "live"}`;
4593
4610
  /**
4594
4611
  * Callback function for emitting risk rejection events to riskSubject.
4595
4612
  *
@@ -4661,7 +4678,7 @@ class RiskConnectionService {
4661
4678
  * @param backtest - True if backtest mode, false if live mode
4662
4679
  * @returns Configured ClientRisk instance
4663
4680
  */
4664
- this.getRisk = functoolsKit.memoize(([riskName, backtest]) => `${riskName}:${backtest ? "backtest" : "live"}`, (riskName, backtest) => {
4681
+ this.getRisk = functoolsKit.memoize(([riskName, backtest]) => CREATE_KEY_FN$8(riskName, backtest), (riskName, backtest) => {
4665
4682
  const schema = this.riskSchemaService.get(riskName);
4666
4683
  return new ClientRisk({
4667
4684
  ...schema,
@@ -4719,15 +4736,21 @@ class RiskConnectionService {
4719
4736
  /**
4720
4737
  * Clears the cached ClientRisk instance for the given risk name.
4721
4738
  *
4722
- * @param riskName - Name of the risk schema to clear from cache
4739
+ * @param backtest - Whether running in backtest mode
4740
+ * @param ctx - Optional context with riskName (clears all if not provided)
4723
4741
  */
4724
- this.clear = async (backtest, riskName) => {
4742
+ this.clear = async (backtest, ctx) => {
4725
4743
  this.loggerService.log("riskConnectionService clear", {
4726
- riskName,
4744
+ ctx,
4727
4745
  backtest,
4728
4746
  });
4729
- const key = `${riskName}:${backtest ? "backtest" : "live"}`;
4730
- this.getRisk.clear(key);
4747
+ if (ctx) {
4748
+ const key = CREATE_KEY_FN$8(ctx.riskName, backtest);
4749
+ this.getRisk.clear(key);
4750
+ }
4751
+ else {
4752
+ this.getRisk.clear();
4753
+ }
4731
4754
  };
4732
4755
  }
4733
4756
  }
@@ -5256,19 +5279,20 @@ class RiskGlobalService {
5256
5279
  };
5257
5280
  /**
5258
5281
  * Clears risk data.
5259
- * If riskName is provided, clears data for that specific risk instance.
5260
- * If no riskName is provided, clears all risk data.
5261
- * @param riskName - Optional name of the risk instance to clear
5282
+ * If ctx is provided, clears data for that specific risk instance.
5283
+ * If no ctx is provided, clears all risk data.
5284
+ * @param backtest - Whether running in backtest mode
5285
+ * @param ctx - Optional context with riskName (clears all if not provided)
5262
5286
  */
5263
- this.clear = async (backtest, riskName) => {
5287
+ this.clear = async (backtest, ctx) => {
5264
5288
  this.loggerService.log("riskGlobalService clear", {
5265
- riskName,
5289
+ ctx,
5266
5290
  backtest,
5267
5291
  });
5268
- if (riskName) {
5269
- await this.validate(riskName);
5292
+ if (ctx) {
5293
+ await this.validate(ctx.riskName);
5270
5294
  }
5271
- return await this.riskConnectionService.clear(backtest, riskName);
5295
+ return await this.riskConnectionService.clear(backtest, ctx);
5272
5296
  };
5273
5297
  }
5274
5298
  }
@@ -7761,6 +7785,15 @@ const COLUMN_CONFIG = {
7761
7785
  */
7762
7786
  const DEFAULT_COLUMNS = Object.freeze({ ...COLUMN_CONFIG });
7763
7787
 
7788
+ /**
7789
+ * Creates a unique key for memoizing ReportStorage instances.
7790
+ * Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
7791
+ * @param symbol - Trading pair symbol
7792
+ * @param strategyName - Name of the strategy
7793
+ * @param backtest - Whether running in backtest mode
7794
+ * @returns Unique string key for memoization
7795
+ */
7796
+ const CREATE_KEY_FN$7 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
7764
7797
  /**
7765
7798
  * Checks if a value is unsafe for display (not a number, NaN, or Infinity).
7766
7799
  *
@@ -7969,7 +8002,7 @@ class BacktestMarkdownService {
7969
8002
  * Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
7970
8003
  * Each symbol-strategy-backtest combination gets its own isolated storage instance.
7971
8004
  */
7972
- this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$5());
8005
+ this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$7(symbol, strategyName, backtest), () => new ReportStorage$5());
7973
8006
  /**
7974
8007
  * Processes tick events and accumulates closed signals.
7975
8008
  * Should be called from IStrategyCallbacks.onTick.
@@ -8107,7 +8140,7 @@ class BacktestMarkdownService {
8107
8140
  ctx,
8108
8141
  });
8109
8142
  if (ctx) {
8110
- const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
8143
+ const key = CREATE_KEY_FN$7(ctx.symbol, ctx.strategyName, backtest);
8111
8144
  this.getStorage.clear(key);
8112
8145
  }
8113
8146
  else {
@@ -8132,6 +8165,15 @@ class BacktestMarkdownService {
8132
8165
  }
8133
8166
  }
8134
8167
 
8168
+ /**
8169
+ * Creates a unique key for memoizing ReportStorage instances.
8170
+ * Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
8171
+ * @param symbol - Trading pair symbol
8172
+ * @param strategyName - Name of the strategy
8173
+ * @param backtest - Whether running in backtest mode
8174
+ * @returns Unique string key for memoization
8175
+ */
8176
+ const CREATE_KEY_FN$6 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
8135
8177
  /**
8136
8178
  * Checks if a value is unsafe for display (not a number, NaN, or Infinity).
8137
8179
  *
@@ -8461,7 +8503,7 @@ class LiveMarkdownService {
8461
8503
  * Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
8462
8504
  * Each symbol-strategy-backtest combination gets its own isolated storage instance.
8463
8505
  */
8464
- this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$4());
8506
+ this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$6(symbol, strategyName, backtest), () => new ReportStorage$4());
8465
8507
  /**
8466
8508
  * Processes tick events and accumulates all event types.
8467
8509
  * Should be called from IStrategyCallbacks.onTick.
@@ -8609,7 +8651,7 @@ class LiveMarkdownService {
8609
8651
  ctx,
8610
8652
  });
8611
8653
  if (ctx) {
8612
- const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
8654
+ const key = CREATE_KEY_FN$6(ctx.symbol, ctx.strategyName, backtest);
8613
8655
  this.getStorage.clear(key);
8614
8656
  }
8615
8657
  else {
@@ -8634,6 +8676,15 @@ class LiveMarkdownService {
8634
8676
  }
8635
8677
  }
8636
8678
 
8679
+ /**
8680
+ * Creates a unique key for memoizing ReportStorage instances.
8681
+ * Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
8682
+ * @param symbol - Trading pair symbol
8683
+ * @param strategyName - Name of the strategy
8684
+ * @param backtest - Whether running in backtest mode
8685
+ * @returns Unique string key for memoization
8686
+ */
8687
+ const CREATE_KEY_FN$5 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
8637
8688
  /** Maximum number of events to store in schedule reports */
8638
8689
  const MAX_EVENTS$4 = 250;
8639
8690
  /**
@@ -8869,7 +8920,7 @@ class ScheduleMarkdownService {
8869
8920
  * Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
8870
8921
  * Each symbol-strategy-backtest combination gets its own isolated storage instance.
8871
8922
  */
8872
- this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$3());
8923
+ this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$5(symbol, strategyName, backtest), () => new ReportStorage$3());
8873
8924
  /**
8874
8925
  * Processes tick events and accumulates scheduled/opened/cancelled events.
8875
8926
  * Should be called from signalEmitter subscription.
@@ -9011,7 +9062,7 @@ class ScheduleMarkdownService {
9011
9062
  ctx,
9012
9063
  });
9013
9064
  if (ctx) {
9014
- const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
9065
+ const key = CREATE_KEY_FN$5(ctx.symbol, ctx.strategyName, backtest);
9015
9066
  this.getStorage.clear(key);
9016
9067
  }
9017
9068
  else {
@@ -9036,6 +9087,15 @@ class ScheduleMarkdownService {
9036
9087
  }
9037
9088
  }
9038
9089
 
9090
+ /**
9091
+ * Creates a unique key for memoizing PerformanceStorage instances.
9092
+ * Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
9093
+ * @param symbol - Trading pair symbol
9094
+ * @param strategyName - Name of the strategy
9095
+ * @param backtest - Whether running in backtest mode
9096
+ * @returns Unique string key for memoization
9097
+ */
9098
+ const CREATE_KEY_FN$4 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
9039
9099
  /**
9040
9100
  * Calculates percentile value from sorted array.
9041
9101
  */
@@ -9253,7 +9313,7 @@ class PerformanceMarkdownService {
9253
9313
  * Memoized function to get or create PerformanceStorage for a symbol-strategy-backtest triple.
9254
9314
  * Each symbol-strategy-backtest combination gets its own isolated storage instance.
9255
9315
  */
9256
- this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new PerformanceStorage());
9316
+ this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$4(symbol, strategyName, backtest), () => new PerformanceStorage());
9257
9317
  /**
9258
9318
  * Processes performance events and accumulates metrics.
9259
9319
  * Should be called from performance tracking code.
@@ -9358,7 +9418,7 @@ class PerformanceMarkdownService {
9358
9418
  ctx,
9359
9419
  });
9360
9420
  if (ctx) {
9361
- const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
9421
+ const key = CREATE_KEY_FN$4(ctx.symbol, ctx.strategyName, backtest);
9362
9422
  this.getStorage.clear(key);
9363
9423
  }
9364
9424
  else {
@@ -9785,6 +9845,14 @@ class WalkerMarkdownService {
9785
9845
  }
9786
9846
  }
9787
9847
 
9848
+ /**
9849
+ * Creates a unique key for memoizing HeatmapStorage instances.
9850
+ * Key format: "strategyName:backtest" or "strategyName:live"
9851
+ * @param strategyName - Name of the strategy
9852
+ * @param backtest - Whether running in backtest mode
9853
+ * @returns Unique string key for memoization
9854
+ */
9855
+ const CREATE_KEY_FN$3 = (strategyName, backtest) => `${strategyName}:${backtest ? "backtest" : "live"}`;
9788
9856
  const HEATMAP_METHOD_NAME_GET_DATA = "HeatMarkdownService.getData";
9789
9857
  const HEATMAP_METHOD_NAME_GET_REPORT = "HeatMarkdownService.getReport";
9790
9858
  const HEATMAP_METHOD_NAME_DUMP = "HeatMarkdownService.dump";
@@ -10128,7 +10196,7 @@ class HeatMarkdownService {
10128
10196
  * Memoized function to get or create HeatmapStorage for a strategy and backtest mode.
10129
10197
  * Each strategy + backtest mode combination gets its own isolated heatmap storage instance.
10130
10198
  */
10131
- this.getStorage = functoolsKit.memoize(([strategyName, backtest]) => `${strategyName}:${backtest ? "backtest" : "live"}`, () => new HeatmapStorage());
10199
+ this.getStorage = functoolsKit.memoize(([strategyName, backtest]) => CREATE_KEY_FN$3(strategyName, backtest), () => new HeatmapStorage());
10132
10200
  /**
10133
10201
  * Processes tick events and accumulates closed signals.
10134
10202
  * Should be called from signal emitter subscription.
@@ -10264,7 +10332,7 @@ class HeatMarkdownService {
10264
10332
  ctx,
10265
10333
  });
10266
10334
  if (ctx) {
10267
- const key = `${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
10335
+ const key = CREATE_KEY_FN$3(ctx.strategyName, backtest);
10268
10336
  this.getStorage.clear(key);
10269
10337
  }
10270
10338
  else {
@@ -12474,6 +12542,15 @@ class ClientPartial {
12474
12542
  }
12475
12543
  }
12476
12544
 
12545
+ /**
12546
+ * Creates a unique key for memoizing ClientPartial instances.
12547
+ * Key format: "signalId:backtest" or "signalId:live"
12548
+ *
12549
+ * @param signalId - Signal ID
12550
+ * @param backtest - Whether running in backtest mode
12551
+ * @returns Unique string key for memoization
12552
+ */
12553
+ const CREATE_KEY_FN$2 = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
12477
12554
  /**
12478
12555
  * Callback function for emitting profit events to partialProfitSubject.
12479
12556
  *
@@ -12571,7 +12648,7 @@ class PartialConnectionService {
12571
12648
  * Key format: "signalId:backtest" or "signalId:live"
12572
12649
  * Value: ClientPartial instance with logger and event emitters
12573
12650
  */
12574
- this.getPartial = functoolsKit.memoize(([signalId, backtest]) => `${signalId}:${backtest ? "backtest" : "live"}`, (signalId, backtest) => {
12651
+ this.getPartial = functoolsKit.memoize(([signalId, backtest]) => CREATE_KEY_FN$2(signalId, backtest), (signalId, backtest) => {
12575
12652
  return new ClientPartial({
12576
12653
  signalId,
12577
12654
  logger: this.loggerService,
@@ -12661,12 +12738,19 @@ class PartialConnectionService {
12661
12738
  const partial = this.getPartial(data.id, backtest);
12662
12739
  await partial.waitForInit(symbol, data.strategyName);
12663
12740
  await partial.clear(symbol, data, priceClose, backtest);
12664
- const key = `${data.id}:${backtest ? "backtest" : "live"}`;
12741
+ const key = CREATE_KEY_FN$2(data.id, backtest);
12665
12742
  this.getPartial.clear(key);
12666
12743
  };
12667
12744
  }
12668
12745
  }
12669
12746
 
12747
+ /**
12748
+ * Creates a unique key for memoizing ReportStorage instances.
12749
+ * Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
12750
+ * @param param0 - Tuple of symbol, strategyName and backtest boolean
12751
+ * @returns Unique string key for memoization
12752
+ */
12753
+ const CREATE_KEY_FN$1 = ([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
12670
12754
  /** Maximum number of events to store in partial reports */
12671
12755
  const MAX_EVENTS$1 = 250;
12672
12756
  /**
@@ -12841,7 +12925,7 @@ class PartialMarkdownService {
12841
12925
  * Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
12842
12926
  * Each symbol-strategy-backtest combination gets its own isolated storage instance.
12843
12927
  */
12844
- this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$1());
12928
+ this.getStorage = functoolsKit.memoize(CREATE_KEY_FN$1, () => new ReportStorage$1());
12845
12929
  /**
12846
12930
  * Processes profit events and accumulates them.
12847
12931
  * Should be called from partialProfitSubject subscription.
@@ -12988,7 +13072,7 @@ class PartialMarkdownService {
12988
13072
  ctx,
12989
13073
  });
12990
13074
  if (ctx) {
12991
- const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
13075
+ const key = CREATE_KEY_FN$1([ctx.symbol, ctx.strategyName, backtest]);
12992
13076
  this.getStorage.clear(key);
12993
13077
  }
12994
13078
  else {
@@ -13423,6 +13507,15 @@ class ConfigValidationService {
13423
13507
  }
13424
13508
  }
13425
13509
 
13510
+ /**
13511
+ * Creates a unique key for memoizing ReportStorage instances.
13512
+ * Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
13513
+ * @param symbol - Trading pair symbol
13514
+ * @param strategyName - Name of the strategy
13515
+ * @param backtest - Whether running in backtest mode
13516
+ * @returns Unique string key for memoization
13517
+ */
13518
+ const CREATE_KEY_FN = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
13426
13519
  /** Maximum number of events to store in risk reports */
13427
13520
  const MAX_EVENTS = 250;
13428
13521
  /**
@@ -13567,7 +13660,7 @@ class RiskMarkdownService {
13567
13660
  * Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
13568
13661
  * Each symbol-strategy-backtest combination gets its own isolated storage instance.
13569
13662
  */
13570
- this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage());
13663
+ this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN(symbol, strategyName, backtest), () => new ReportStorage());
13571
13664
  /**
13572
13665
  * Processes risk rejection events and accumulates them.
13573
13666
  * Should be called from riskSubject subscription.
@@ -13695,7 +13788,7 @@ class RiskMarkdownService {
13695
13788
  ctx,
13696
13789
  });
13697
13790
  if (ctx) {
13698
- const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
13791
+ const key = CREATE_KEY_FN(ctx.symbol, ctx.strategyName, backtest);
13699
13792
  this.getStorage.clear(key);
13700
13793
  }
13701
13794
  else {
@@ -14182,6 +14275,81 @@ async function validate(args = {}) {
14182
14275
  return await validateInternal(args);
14183
14276
  }
14184
14277
 
14278
+ const STOP_METHOD_NAME = "strategy.stop";
14279
+ const CANCEL_METHOD_NAME = "strategy.cancel";
14280
+ /**
14281
+ * Stops the strategy from generating new signals.
14282
+ *
14283
+ * Sets internal flag to prevent strategy from opening new signals.
14284
+ * Current active signal (if any) will complete normally.
14285
+ * Backtest/Live mode will stop at the next safe point (idle state or after signal closes).
14286
+ *
14287
+ * Automatically detects backtest/live mode from execution context.
14288
+ *
14289
+ * @param symbol - Trading pair symbol
14290
+ * @param strategyName - Strategy name to stop
14291
+ * @returns Promise that resolves when stop flag is set
14292
+ *
14293
+ * @example
14294
+ * ```typescript
14295
+ * import { stop } from "backtest-kit";
14296
+ *
14297
+ * // Stop strategy after some condition
14298
+ * await stop("BTCUSDT", "my-strategy");
14299
+ * ```
14300
+ */
14301
+ async function stop(symbol, strategyName) {
14302
+ backtest$1.loggerService.info(STOP_METHOD_NAME, {
14303
+ symbol,
14304
+ strategyName,
14305
+ });
14306
+ if (!ExecutionContextService.hasContext()) {
14307
+ throw new Error("stop requires an execution context");
14308
+ }
14309
+ if (!MethodContextService.hasContext()) {
14310
+ throw new Error("stop requires a method context");
14311
+ }
14312
+ const { backtest: isBacktest } = backtest$1.executionContextService.context;
14313
+ await backtest$1.strategyCoreService.stop(isBacktest, { symbol, strategyName });
14314
+ }
14315
+ /**
14316
+ * Cancels the scheduled signal without stopping the strategy.
14317
+ *
14318
+ * Clears the scheduled signal (waiting for priceOpen activation).
14319
+ * Does NOT affect active pending signals or strategy operation.
14320
+ * Does NOT set stop flag - strategy can continue generating new signals.
14321
+ *
14322
+ * Automatically detects backtest/live mode from execution context.
14323
+ *
14324
+ * @param symbol - Trading pair symbol
14325
+ * @param strategyName - Strategy name
14326
+ * @param cancelId - Optional cancellation ID for tracking user-initiated cancellations
14327
+ * @returns Promise that resolves when scheduled signal is cancelled
14328
+ *
14329
+ * @example
14330
+ * ```typescript
14331
+ * import { cancel } from "backtest-kit";
14332
+ *
14333
+ * // Cancel scheduled signal with custom ID
14334
+ * await cancel("BTCUSDT", "my-strategy", "manual-cancel-001");
14335
+ * ```
14336
+ */
14337
+ async function cancel(symbol, strategyName, cancelId) {
14338
+ backtest$1.loggerService.info(CANCEL_METHOD_NAME, {
14339
+ symbol,
14340
+ strategyName,
14341
+ cancelId,
14342
+ });
14343
+ if (!ExecutionContextService.hasContext()) {
14344
+ throw new Error("cancel requires an execution context");
14345
+ }
14346
+ if (!MethodContextService.hasContext()) {
14347
+ throw new Error("cancel requires a method context");
14348
+ }
14349
+ const { backtest: isBacktest } = backtest$1.executionContextService.context;
14350
+ await backtest$1.strategyCoreService.cancel(isBacktest, { symbol, strategyName }, cancelId);
14351
+ }
14352
+
14185
14353
  /**
14186
14354
  * Sets custom logger implementation for the framework.
14187
14355
  *
@@ -16332,8 +16500,8 @@ class BacktestInstance {
16332
16500
  }
16333
16501
  {
16334
16502
  const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
16335
- riskName && backtest$1.riskGlobalService.clear(true, riskName);
16336
- riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, riskName));
16503
+ riskName && backtest$1.riskGlobalService.clear(true, { riskName });
16504
+ riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, { riskName }));
16337
16505
  }
16338
16506
  return backtest$1.backtestCommandService.run(symbol, context);
16339
16507
  };
@@ -17006,8 +17174,8 @@ class LiveInstance {
17006
17174
  }
17007
17175
  {
17008
17176
  const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
17009
- riskName && backtest$1.riskGlobalService.clear(false, riskName);
17010
- riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(false, riskName));
17177
+ riskName && backtest$1.riskGlobalService.clear(false, { riskName });
17178
+ riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(false, { riskName }));
17011
17179
  }
17012
17180
  return backtest$1.liveCommandService.run(symbol, context);
17013
17181
  };
@@ -17958,9 +18126,9 @@ class WalkerInstance {
17958
18126
  }
17959
18127
  {
17960
18128
  const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
17961
- riskName && backtest$1.riskGlobalService.clear(true, riskName);
18129
+ riskName && backtest$1.riskGlobalService.clear(true, { riskName });
17962
18130
  riskList &&
17963
- riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, riskName));
18131
+ riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, { riskName }));
17964
18132
  }
17965
18133
  }
17966
18134
  return backtest$1.walkerCommandService.run(symbol, {
@@ -19621,6 +19789,7 @@ exports.addRisk = addRisk;
19621
19789
  exports.addSizing = addSizing;
19622
19790
  exports.addStrategy = addStrategy;
19623
19791
  exports.addWalker = addWalker;
19792
+ exports.cancel = cancel;
19624
19793
  exports.dumpSignal = dumpSignal;
19625
19794
  exports.emitters = emitters;
19626
19795
  exports.formatPrice = formatPrice;
@@ -19675,4 +19844,5 @@ exports.listenWalkerProgress = listenWalkerProgress;
19675
19844
  exports.setColumns = setColumns;
19676
19845
  exports.setConfig = setConfig;
19677
19846
  exports.setLogger = setLogger;
19847
+ exports.stop = stop;
19678
19848
  exports.validate = validate;