backtest-kit 1.5.26 → 1.5.27

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.mjs CHANGED
@@ -2626,7 +2626,7 @@ const PersistScheduleAdapter = new PersistScheduleUtils();
2626
2626
  * Utility class for managing partial profit/loss levels persistence.
2627
2627
  *
2628
2628
  * Features:
2629
- * - Memoized storage instances per symbol
2629
+ * - Memoized storage instances per symbol:strategyName
2630
2630
  * - Custom adapter support
2631
2631
  * - Atomic read/write operations for partial data
2632
2632
  * - Crash-safe partial state management
@@ -2636,23 +2636,25 @@ const PersistScheduleAdapter = new PersistScheduleUtils();
2636
2636
  class PersistPartialUtils {
2637
2637
  constructor() {
2638
2638
  this.PersistPartialFactory = PersistBase;
2639
- this.getPartialStorage = memoize(([symbol]) => `${symbol}`, (symbol) => Reflect.construct(this.PersistPartialFactory, [
2640
- symbol,
2639
+ this.getPartialStorage = memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, (symbol, strategyName) => Reflect.construct(this.PersistPartialFactory, [
2640
+ `${symbol}_${strategyName}`,
2641
2641
  `./dump/data/partial/`,
2642
2642
  ]));
2643
2643
  /**
2644
- * Reads persisted partial data for a symbol.
2644
+ * Reads persisted partial data for a symbol and strategy.
2645
2645
  *
2646
2646
  * Called by ClientPartial.waitForInit() to restore state.
2647
2647
  * Returns empty object if no partial data exists.
2648
2648
  *
2649
2649
  * @param symbol - Trading pair symbol
2650
+ * @param strategyName - Strategy identifier
2650
2651
  * @returns Promise resolving to partial data record
2651
2652
  */
2652
- this.readPartialData = async (symbol) => {
2653
+ this.readPartialData = async (symbol, strategyName) => {
2653
2654
  backtest$1.loggerService.info(PERSIST_PARTIAL_UTILS_METHOD_NAME_READ_DATA);
2654
- const isInitial = !this.getPartialStorage.has(symbol);
2655
- const stateStorage = this.getPartialStorage(symbol);
2655
+ const key = `${symbol}:${strategyName}`;
2656
+ const isInitial = !this.getPartialStorage.has(key);
2657
+ const stateStorage = this.getPartialStorage(symbol, strategyName);
2656
2658
  await stateStorage.waitForInit(isInitial);
2657
2659
  const PARTIAL_STORAGE_KEY = "levels";
2658
2660
  if (await stateStorage.hasValue(PARTIAL_STORAGE_KEY)) {
@@ -2668,12 +2670,14 @@ class PersistPartialUtils {
2668
2670
  *
2669
2671
  * @param partialData - Record of signal IDs to partial data
2670
2672
  * @param symbol - Trading pair symbol
2673
+ * @param strategyName - Strategy identifier
2671
2674
  * @returns Promise that resolves when write is complete
2672
2675
  */
2673
- this.writePartialData = async (partialData, symbol) => {
2676
+ this.writePartialData = async (partialData, symbol, strategyName) => {
2674
2677
  backtest$1.loggerService.info(PERSIST_PARTIAL_UTILS_METHOD_NAME_WRITE_DATA);
2675
- const isInitial = !this.getPartialStorage.has(symbol);
2676
- const stateStorage = this.getPartialStorage(symbol);
2678
+ const key = `${symbol}:${strategyName}`;
2679
+ const isInitial = !this.getPartialStorage.has(key);
2680
+ const stateStorage = this.getPartialStorage(symbol, strategyName);
2677
2681
  await stateStorage.waitForInit(isInitial);
2678
2682
  const PARTIAL_STORAGE_KEY = "levels";
2679
2683
  await stateStorage.writeValue(PARTIAL_STORAGE_KEY, partialData);
@@ -2708,10 +2712,10 @@ class PersistPartialUtils {
2708
2712
  * PersistPartialAdapter.usePersistPartialAdapter(RedisPersist);
2709
2713
  *
2710
2714
  * // Read partial data
2711
- * const partialData = await PersistPartialAdapter.readPartialData("BTCUSDT");
2715
+ * const partialData = await PersistPartialAdapter.readPartialData("BTCUSDT", "my-strategy");
2712
2716
  *
2713
2717
  * // Write partial data
2714
- * await PersistPartialAdapter.writePartialData(partialData, "BTCUSDT");
2718
+ * await PersistPartialAdapter.writePartialData(partialData, "BTCUSDT", "my-strategy");
2715
2719
  * ```
2716
2720
  */
2717
2721
  const PersistPartialAdapter = new PersistPartialUtils();
@@ -4572,25 +4576,25 @@ const NOOP_RISK = {
4572
4576
  addSignal: () => Promise.resolve(),
4573
4577
  removeSignal: () => Promise.resolve(),
4574
4578
  };
4575
- const GET_RISK_FN = (dto, self) => {
4579
+ const GET_RISK_FN = (dto, backtest, self) => {
4576
4580
  const hasRiskName = !!dto.riskName;
4577
- const hasRiskList = !!(dto.riskList?.length);
4581
+ const hasRiskList = !!dto.riskList?.length;
4578
4582
  // Нет ни riskName, ни riskList
4579
4583
  if (!hasRiskName && !hasRiskList) {
4580
4584
  return NOOP_RISK;
4581
4585
  }
4582
4586
  // Есть только riskName (без riskList)
4583
4587
  if (hasRiskName && !hasRiskList) {
4584
- return self.riskConnectionService.getRisk(dto.riskName);
4588
+ return self.riskConnectionService.getRisk(dto.riskName, backtest);
4585
4589
  }
4586
4590
  // Есть только riskList (без riskName)
4587
4591
  if (!hasRiskName && hasRiskList) {
4588
- return new MergeRisk(dto.riskList.map((riskName) => self.riskConnectionService.getRisk(riskName)));
4592
+ return new MergeRisk(dto.riskList.map((riskName) => self.riskConnectionService.getRisk(riskName, backtest)));
4589
4593
  }
4590
4594
  // Есть и riskName, и riskList - объединяем (riskName в начало)
4591
4595
  return new MergeRisk([
4592
- self.riskConnectionService.getRisk(dto.riskName),
4593
- ...dto.riskList.map((riskName) => self.riskConnectionService.getRisk(riskName))
4596
+ self.riskConnectionService.getRisk(dto.riskName, backtest),
4597
+ ...dto.riskList.map((riskName) => self.riskConnectionService.getRisk(riskName, backtest)),
4594
4598
  ]);
4595
4599
  };
4596
4600
  /**
@@ -4632,7 +4636,7 @@ class StrategyConnectionService {
4632
4636
  * @param strategyName - Name of registered strategy schema
4633
4637
  * @returns Configured ClientStrategy instance
4634
4638
  */
4635
- this.getStrategy = memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, (symbol, strategyName) => {
4639
+ this.getStrategy = memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, (symbol, strategyName, backtest) => {
4636
4640
  const { riskName = "", riskList = [], getSignal, interval, callbacks, } = this.strategySchemaService.get(strategyName);
4637
4641
  return new ClientStrategy({
4638
4642
  symbol,
@@ -4645,7 +4649,7 @@ class StrategyConnectionService {
4645
4649
  risk: GET_RISK_FN({
4646
4650
  riskName,
4647
4651
  riskList,
4648
- }, this),
4652
+ }, backtest, this),
4649
4653
  riskName,
4650
4654
  strategyName,
4651
4655
  getSignal,
@@ -4662,12 +4666,13 @@ class StrategyConnectionService {
4662
4666
  *
4663
4667
  * @returns Promise resolving to pending signal or null
4664
4668
  */
4665
- this.getPendingSignal = async (symbol, strategyName) => {
4669
+ this.getPendingSignal = async (backtest, symbol, strategyName) => {
4666
4670
  this.loggerService.log("strategyConnectionService getPendingSignal", {
4667
4671
  symbol,
4668
4672
  strategyName,
4673
+ backtest,
4669
4674
  });
4670
- const strategy = this.getStrategy(symbol, strategyName);
4675
+ const strategy = this.getStrategy(symbol, strategyName, backtest);
4671
4676
  return await strategy.getPendingSignal(symbol, strategyName);
4672
4677
  };
4673
4678
  /**
@@ -4680,12 +4685,13 @@ class StrategyConnectionService {
4680
4685
  * @param strategyName - Name of the strategy
4681
4686
  * @returns Promise resolving to true if strategy is stopped, false otherwise
4682
4687
  */
4683
- this.getStopped = async (symbol, strategyName) => {
4688
+ this.getStopped = async (backtest, symbol, strategyName) => {
4684
4689
  this.loggerService.log("strategyConnectionService getStopped", {
4685
4690
  symbol,
4686
4691
  strategyName,
4692
+ backtest,
4687
4693
  });
4688
- const strategy = this.getStrategy(symbol, strategyName);
4694
+ const strategy = this.getStrategy(symbol, strategyName, backtest);
4689
4695
  return await strategy.getStopped(symbol, strategyName);
4690
4696
  };
4691
4697
  /**
@@ -4703,7 +4709,8 @@ class StrategyConnectionService {
4703
4709
  symbol,
4704
4710
  strategyName,
4705
4711
  });
4706
- const strategy = this.getStrategy(symbol, strategyName);
4712
+ const backtest = this.executionContextService.context.backtest;
4713
+ const strategy = this.getStrategy(symbol, strategyName, backtest);
4707
4714
  await strategy.waitForInit();
4708
4715
  const tick = await strategy.tick(symbol, strategyName);
4709
4716
  {
@@ -4734,7 +4741,8 @@ class StrategyConnectionService {
4734
4741
  strategyName,
4735
4742
  candleCount: candles.length,
4736
4743
  });
4737
- const strategy = this.getStrategy(symbol, strategyName);
4744
+ const backtest = this.executionContextService.context.backtest;
4745
+ const strategy = this.getStrategy(symbol, strategyName, backtest);
4738
4746
  await strategy.waitForInit();
4739
4747
  const tick = await strategy.backtest(symbol, strategyName, candles);
4740
4748
  {
@@ -4755,11 +4763,11 @@ class StrategyConnectionService {
4755
4763
  * @param strategyName - Name of strategy to stop
4756
4764
  * @returns Promise that resolves when stop flag is set
4757
4765
  */
4758
- this.stop = async (ctx, backtest) => {
4766
+ this.stop = async (backtest, ctx) => {
4759
4767
  this.loggerService.log("strategyConnectionService stop", {
4760
4768
  ctx,
4761
4769
  });
4762
- const strategy = this.getStrategy(ctx.symbol, ctx.strategyName);
4770
+ const strategy = this.getStrategy(ctx.symbol, ctx.strategyName, backtest);
4763
4771
  await strategy.stop(ctx.symbol, ctx.strategyName, backtest);
4764
4772
  };
4765
4773
  /**
@@ -4770,12 +4778,12 @@ class StrategyConnectionService {
4770
4778
  *
4771
4779
  * @param ctx - Optional context with symbol and strategyName (clears all if not provided)
4772
4780
  */
4773
- this.clear = async (ctx) => {
4781
+ this.clear = async (backtest, ctx) => {
4774
4782
  this.loggerService.log("strategyConnectionService clear", {
4775
4783
  ctx,
4776
4784
  });
4777
4785
  if (ctx) {
4778
- const key = `${ctx.symbol}:${ctx.strategyName}`;
4786
+ const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
4779
4787
  this.getStrategy.clear(key);
4780
4788
  }
4781
4789
  else {
@@ -5170,9 +5178,15 @@ const DO_VALIDATION_FN = trycatch(async (validation, params) => {
5170
5178
  * Initializes active positions by reading from persistence.
5171
5179
  * Uses singleshot pattern to ensure it only runs once.
5172
5180
  * This function is exported for use in tests or other modules.
5181
+ *
5182
+ * In backtest mode, initializes with empty Map. In live mode, reads from persist storage.
5173
5183
  */
5174
5184
  const WAIT_FOR_INIT_FN$1 = async (self) => {
5175
- self.params.logger.debug("ClientRisk waitForInit");
5185
+ self.params.logger.debug("ClientRisk waitForInit", { backtest: self.params.backtest });
5186
+ if (self.params.backtest) {
5187
+ self._activePositions = new Map();
5188
+ return;
5189
+ }
5176
5190
  const persistedPositions = await PersistRiskAdapter.readPositionData(self.params.riskName);
5177
5191
  self._activePositions = new Map(persistedPositions);
5178
5192
  };
@@ -5220,6 +5234,7 @@ class ClientRisk {
5220
5234
  this.params.logger.debug("ClientRisk checkSignal", {
5221
5235
  symbol: params.symbol,
5222
5236
  strategyName: params.strategyName,
5237
+ backtest: this.params.backtest,
5223
5238
  });
5224
5239
  if (this._activePositions === POSITION_NEED_FETCH) {
5225
5240
  await this.waitForInit();
@@ -5265,8 +5280,12 @@ class ClientRisk {
5265
5280
  }
5266
5281
  /**
5267
5282
  * Persists current active positions to disk.
5283
+ * Skips in backtest mode.
5268
5284
  */
5269
5285
  async _updatePositions() {
5286
+ if (this.params.backtest) {
5287
+ return;
5288
+ }
5270
5289
  if (this._activePositions === POSITION_NEED_FETCH) {
5271
5290
  await this.waitForInit();
5272
5291
  }
@@ -5280,6 +5299,7 @@ class ClientRisk {
5280
5299
  this.params.logger.debug("ClientRisk addSignal", {
5281
5300
  symbol,
5282
5301
  context,
5302
+ backtest: this.params.backtest,
5283
5303
  });
5284
5304
  if (this._activePositions === POSITION_NEED_FETCH) {
5285
5305
  await this.waitForInit();
@@ -5302,6 +5322,7 @@ class ClientRisk {
5302
5322
  this.params.logger.debug("ClientRisk removeSignal", {
5303
5323
  symbol,
5304
5324
  context,
5325
+ backtest: this.params.backtest,
5305
5326
  });
5306
5327
  if (this._activePositions === POSITION_NEED_FETCH) {
5307
5328
  await this.waitForInit();
@@ -5372,19 +5393,21 @@ class RiskConnectionService {
5372
5393
  this.loggerService = inject(TYPES.loggerService);
5373
5394
  this.riskSchemaService = inject(TYPES.riskSchemaService);
5374
5395
  /**
5375
- * Retrieves memoized ClientRisk instance for given risk name.
5396
+ * Retrieves memoized ClientRisk instance for given risk name and backtest mode.
5376
5397
  *
5377
5398
  * Creates ClientRisk on first call, returns cached instance on subsequent calls.
5378
- * Cache key is riskName string.
5399
+ * Cache key is "riskName:backtest" string to separate live and backtest instances.
5379
5400
  *
5380
5401
  * @param riskName - Name of registered risk schema
5402
+ * @param backtest - True if backtest mode, false if live mode
5381
5403
  * @returns Configured ClientRisk instance
5382
5404
  */
5383
- this.getRisk = memoize(([riskName]) => `${riskName}`, (riskName) => {
5405
+ this.getRisk = memoize(([riskName, backtest]) => `${riskName}:${backtest ? "backtest" : "live"}`, (riskName, backtest) => {
5384
5406
  const schema = this.riskSchemaService.get(riskName);
5385
5407
  return new ClientRisk({
5386
5408
  ...schema,
5387
5409
  logger: this.loggerService,
5410
+ backtest,
5388
5411
  onRejected: COMMIT_REJECTION_FN,
5389
5412
  });
5390
5413
  });
@@ -5396,7 +5419,7 @@ class RiskConnectionService {
5396
5419
  * ClientRisk will emit riskSubject event via onRejected callback when signal is rejected.
5397
5420
  *
5398
5421
  * @param params - Risk check arguments (portfolio state, position details)
5399
- * @param context - Execution context with risk name
5422
+ * @param context - Execution context with risk name and backtest mode
5400
5423
  * @returns Promise resolving to risk check result
5401
5424
  */
5402
5425
  this.checkSignal = async (params, context) => {
@@ -5404,46 +5427,48 @@ class RiskConnectionService {
5404
5427
  symbol: params.symbol,
5405
5428
  context,
5406
5429
  });
5407
- return await this.getRisk(context.riskName).checkSignal(params);
5430
+ return await this.getRisk(context.riskName, context.backtest).checkSignal(params);
5408
5431
  };
5409
5432
  /**
5410
5433
  * Registers an opened signal with the risk management system.
5411
5434
  * Routes to appropriate ClientRisk instance.
5412
5435
  *
5413
5436
  * @param symbol - Trading pair symbol
5414
- * @param context - Context information (strategyName, riskName)
5437
+ * @param context - Context information (strategyName, riskName, backtest)
5415
5438
  */
5416
5439
  this.addSignal = async (symbol, context) => {
5417
5440
  this.loggerService.log("riskConnectionService addSignal", {
5418
5441
  symbol,
5419
5442
  context,
5420
5443
  });
5421
- await this.getRisk(context.riskName).addSignal(symbol, context);
5444
+ await this.getRisk(context.riskName, context.backtest).addSignal(symbol, context);
5422
5445
  };
5423
5446
  /**
5424
5447
  * Removes a closed signal from the risk management system.
5425
5448
  * Routes to appropriate ClientRisk instance.
5426
5449
  *
5427
5450
  * @param symbol - Trading pair symbol
5428
- * @param context - Context information (strategyName, riskName)
5451
+ * @param context - Context information (strategyName, riskName, backtest)
5429
5452
  */
5430
5453
  this.removeSignal = async (symbol, context) => {
5431
5454
  this.loggerService.log("riskConnectionService removeSignal", {
5432
5455
  symbol,
5433
5456
  context,
5434
5457
  });
5435
- await this.getRisk(context.riskName).removeSignal(symbol, context);
5458
+ await this.getRisk(context.riskName, context.backtest).removeSignal(symbol, context);
5436
5459
  };
5437
5460
  /**
5438
5461
  * Clears the cached ClientRisk instance for the given risk name.
5439
5462
  *
5440
5463
  * @param riskName - Name of the risk schema to clear from cache
5441
5464
  */
5442
- this.clear = async (riskName) => {
5465
+ this.clear = async (backtest, riskName) => {
5443
5466
  this.loggerService.log("riskConnectionService clear", {
5444
5467
  riskName,
5468
+ backtest,
5445
5469
  });
5446
- this.getRisk.clear(riskName);
5470
+ const key = `${riskName}:${backtest ? "backtest" : "live"}`;
5471
+ this.getRisk.clear(key);
5447
5472
  };
5448
5473
  }
5449
5474
  }
@@ -5666,7 +5691,7 @@ class StrategyCoreService {
5666
5691
  * @param strategyName - Name of the strategy
5667
5692
  * @returns Promise resolving to pending signal or null
5668
5693
  */
5669
- this.getPendingSignal = async (symbol, strategyName) => {
5694
+ this.getPendingSignal = async (backtest, symbol, strategyName) => {
5670
5695
  this.loggerService.log("strategyCoreService getPendingSignal", {
5671
5696
  symbol,
5672
5697
  strategyName,
@@ -5675,7 +5700,7 @@ class StrategyCoreService {
5675
5700
  throw new Error("strategyCoreService getPendingSignal requires a method context");
5676
5701
  }
5677
5702
  await this.validate(symbol, strategyName);
5678
- return await this.strategyConnectionService.getPendingSignal(symbol, strategyName);
5703
+ return await this.strategyConnectionService.getPendingSignal(backtest, symbol, strategyName);
5679
5704
  };
5680
5705
  /**
5681
5706
  * Checks if the strategy has been stopped.
@@ -5687,16 +5712,17 @@ class StrategyCoreService {
5687
5712
  * @param strategyName - Name of the strategy
5688
5713
  * @returns Promise resolving to true if strategy is stopped, false otherwise
5689
5714
  */
5690
- this.getStopped = async (symbol, strategyName) => {
5715
+ this.getStopped = async (backtest, symbol, strategyName) => {
5691
5716
  this.loggerService.log("strategyCoreService getStopped", {
5692
5717
  symbol,
5693
5718
  strategyName,
5719
+ backtest,
5694
5720
  });
5695
5721
  if (!MethodContextService.hasContext()) {
5696
5722
  throw new Error("strategyCoreService getStopped requires a method context");
5697
5723
  }
5698
5724
  await this.validate(symbol, strategyName);
5699
- return await this.strategyConnectionService.getStopped(symbol, strategyName);
5725
+ return await this.strategyConnectionService.getStopped(backtest, symbol, strategyName);
5700
5726
  };
5701
5727
  /**
5702
5728
  * Checks signal status at a specific timestamp.
@@ -5770,13 +5796,13 @@ class StrategyCoreService {
5770
5796
  * @param strategyName - Name of strategy to stop
5771
5797
  * @returns Promise that resolves when stop flag is set
5772
5798
  */
5773
- this.stop = async (ctx, backtest) => {
5799
+ this.stop = async (backtest, ctx) => {
5774
5800
  this.loggerService.log("strategyCoreService stop", {
5775
5801
  ctx,
5776
5802
  backtest,
5777
5803
  });
5778
5804
  await this.validate(ctx.symbol, ctx.strategyName);
5779
- return await this.strategyConnectionService.stop(ctx, backtest);
5805
+ return await this.strategyConnectionService.stop(backtest, ctx);
5780
5806
  };
5781
5807
  /**
5782
5808
  * Clears the memoized ClientStrategy instance from cache.
@@ -5786,14 +5812,14 @@ class StrategyCoreService {
5786
5812
  *
5787
5813
  * @param ctx - Optional context with symbol and strategyName (clears all if not provided)
5788
5814
  */
5789
- this.clear = async (ctx) => {
5815
+ this.clear = async (backtest, ctx) => {
5790
5816
  this.loggerService.log("strategyCoreService clear", {
5791
5817
  ctx,
5792
5818
  });
5793
5819
  if (ctx) {
5794
5820
  await this.validate(ctx.symbol, ctx.strategyName);
5795
5821
  }
5796
- return await this.strategyConnectionService.clear(ctx);
5822
+ return await this.strategyConnectionService.clear(backtest, ctx);
5797
5823
  };
5798
5824
  }
5799
5825
  }
@@ -5934,14 +5960,15 @@ class RiskGlobalService {
5934
5960
  * If no riskName is provided, clears all risk data.
5935
5961
  * @param riskName - Optional name of the risk instance to clear
5936
5962
  */
5937
- this.clear = async (riskName) => {
5963
+ this.clear = async (backtest, riskName) => {
5938
5964
  this.loggerService.log("riskGlobalService clear", {
5939
5965
  riskName,
5966
+ backtest,
5940
5967
  });
5941
5968
  if (riskName) {
5942
5969
  await this.validate(riskName);
5943
5970
  }
5944
- return await this.riskConnectionService.clear(riskName);
5971
+ return await this.riskConnectionService.clear(backtest, riskName);
5945
5972
  };
5946
5973
  }
5947
5974
  }
@@ -6485,7 +6512,7 @@ class BacktestLogicPrivateService {
6485
6512
  });
6486
6513
  }
6487
6514
  // Check if strategy should stop before processing next frame
6488
- if (await this.strategyCoreService.getStopped(symbol, this.methodContextService.context.strategyName)) {
6515
+ if (await this.strategyCoreService.getStopped(true, symbol, this.methodContextService.context.strategyName)) {
6489
6516
  this.loggerService.info("backtestLogicPrivateService stopped by user request (before tick)", {
6490
6517
  symbol,
6491
6518
  when: when.toISOString(),
@@ -6510,7 +6537,7 @@ class BacktestLogicPrivateService {
6510
6537
  continue;
6511
6538
  }
6512
6539
  // Check if strategy should stop when idle (no active signal)
6513
- if (await and(Promise.resolve(result.action === "idle"), this.strategyCoreService.getStopped(symbol, this.methodContextService.context.strategyName))) {
6540
+ if (await and(Promise.resolve(result.action === "idle"), this.strategyCoreService.getStopped(true, symbol, this.methodContextService.context.strategyName))) {
6514
6541
  this.loggerService.info("backtestLogicPrivateService stopped by user request (idle state)", {
6515
6542
  symbol,
6516
6543
  when: when.toISOString(),
@@ -6612,7 +6639,7 @@ class BacktestLogicPrivateService {
6612
6639
  }
6613
6640
  yield backtestResult;
6614
6641
  // Check if strategy should stop after signal is closed
6615
- if (await this.strategyCoreService.getStopped(symbol, this.methodContextService.context.strategyName)) {
6642
+ if (await this.strategyCoreService.getStopped(true, symbol, this.methodContextService.context.strategyName)) {
6616
6643
  this.loggerService.info("backtestLogicPrivateService stopped by user request (after scheduled signal closed)", {
6617
6644
  symbol,
6618
6645
  signalId: backtestResult.signal.id,
@@ -6705,7 +6732,7 @@ class BacktestLogicPrivateService {
6705
6732
  }
6706
6733
  yield backtestResult;
6707
6734
  // Check if strategy should stop after signal is closed
6708
- if (await this.strategyCoreService.getStopped(symbol, this.methodContextService.context.strategyName)) {
6735
+ if (await this.strategyCoreService.getStopped(true, symbol, this.methodContextService.context.strategyName)) {
6709
6736
  this.loggerService.info("backtestLogicPrivateService stopped by user request (after signal closed)", {
6710
6737
  symbol,
6711
6738
  signalId: backtestResult.signal.id,
@@ -6848,7 +6875,7 @@ class LiveLogicPrivateService {
6848
6875
  previousEventTimestamp = currentTimestamp;
6849
6876
  // Check if strategy should stop when idle (no active signal)
6850
6877
  if (result.action === "idle") {
6851
- if (await and(Promise.resolve(true), this.strategyCoreService.getStopped(symbol, this.methodContextService.context.strategyName))) {
6878
+ if (await and(Promise.resolve(true), this.strategyCoreService.getStopped(false, symbol, this.methodContextService.context.strategyName))) {
6852
6879
  this.loggerService.info("liveLogicPrivateService stopped by user request (idle state)", {
6853
6880
  symbol,
6854
6881
  when: when.toISOString(),
@@ -6870,7 +6897,7 @@ class LiveLogicPrivateService {
6870
6897
  yield result;
6871
6898
  // Check if strategy should stop after signal is closed
6872
6899
  if (result.action === "closed") {
6873
- if (await this.strategyCoreService.getStopped(symbol, this.methodContextService.context.strategyName)) {
6900
+ if (await this.strategyCoreService.getStopped(false, symbol, this.methodContextService.context.strategyName)) {
6874
6901
  this.loggerService.info("liveLogicPrivateService stopped by user request (after signal closed)", {
6875
6902
  symbol,
6876
6903
  signalId: result.signal.id,
@@ -11665,6 +11692,9 @@ const HANDLE_PROFIT_FN = async (symbol, data, currentPrice, revenuePercent, back
11665
11692
  if (self._states === NEED_FETCH) {
11666
11693
  throw new Error("ClientPartial not initialized. Call waitForInit() before using.");
11667
11694
  }
11695
+ if (data.id !== self.params.signalId) {
11696
+ throw new Error(`Signal ID mismatch: expected ${self.params.signalId}, got ${data.id}`);
11697
+ }
11668
11698
  let state = self._states.get(data.id);
11669
11699
  if (!state) {
11670
11700
  state = {
@@ -11689,7 +11719,7 @@ const HANDLE_PROFIT_FN = async (symbol, data, currentPrice, revenuePercent, back
11689
11719
  }
11690
11720
  }
11691
11721
  if (shouldPersist) {
11692
- await self._persistState(symbol, backtest);
11722
+ await self._persistState(symbol, data.strategyName);
11693
11723
  }
11694
11724
  };
11695
11725
  /**
@@ -11711,6 +11741,9 @@ const HANDLE_LOSS_FN = async (symbol, data, currentPrice, lossPercent, backtest,
11711
11741
  if (self._states === NEED_FETCH) {
11712
11742
  throw new Error("ClientPartial not initialized. Call waitForInit() before using.");
11713
11743
  }
11744
+ if (data.id !== self.params.signalId) {
11745
+ throw new Error(`Signal ID mismatch: expected ${self.params.signalId}, got ${data.id}`);
11746
+ }
11714
11747
  let state = self._states.get(data.id);
11715
11748
  if (!state) {
11716
11749
  state = {
@@ -11736,7 +11769,7 @@ const HANDLE_LOSS_FN = async (symbol, data, currentPrice, lossPercent, backtest,
11736
11769
  }
11737
11770
  }
11738
11771
  if (shouldPersist) {
11739
- await self._persistState(symbol, backtest);
11772
+ await self._persistState(symbol, data.strategyName);
11740
11773
  }
11741
11774
  };
11742
11775
  /**
@@ -11745,15 +11778,29 @@ const HANDLE_LOSS_FN = async (symbol, data, currentPrice, lossPercent, backtest,
11745
11778
  * Loads persisted partial state from disk and restores in-memory Maps.
11746
11779
  * Converts serialized arrays back to Sets for O(1) lookups.
11747
11780
  *
11781
+ * ONLY runs in LIVE mode (backtest=false). In backtest mode, state is not persisted.
11782
+ *
11748
11783
  * @param symbol - Trading pair symbol
11784
+ * @param strategyName - Strategy identifier
11785
+ * @param backtest - True if backtest mode, false if live mode
11749
11786
  * @param self - ClientPartial instance reference
11750
11787
  */
11751
- const WAIT_FOR_INIT_FN = async (symbol, self) => {
11752
- self.params.logger.debug("ClientPartial waitForInit", { symbol });
11753
- if (self._states === NEED_FETCH) {
11754
- throw new Error("ClientPartial not initialized. Call waitForInit() before using.");
11788
+ const WAIT_FOR_INIT_FN = async (symbol, strategyName, self) => {
11789
+ self.params.logger.debug("ClientPartial waitForInit", {
11790
+ symbol,
11791
+ strategyName,
11792
+ backtest: self.params.backtest
11793
+ });
11794
+ if (self._states !== NEED_FETCH) {
11795
+ throw new Error("ClientPartial WAIT_FOR_INIT_FN should be called once!");
11796
+ }
11797
+ self._states = new Map();
11798
+ // Skip persistence in backtest mode
11799
+ if (self.params.backtest) {
11800
+ self.params.logger.debug("ClientPartial waitForInit: skipping persist read in backtest mode");
11801
+ return;
11755
11802
  }
11756
- const partialData = await PersistPartialAdapter.readPartialData(symbol);
11803
+ const partialData = await PersistPartialAdapter.readPartialData(symbol, strategyName);
11757
11804
  for (const [signalId, data] of Object.entries(partialData)) {
11758
11805
  const state = {
11759
11806
  profitLevels: new Set(data.profitLevels),
@@ -11763,6 +11810,7 @@ const WAIT_FOR_INIT_FN = async (symbol, self) => {
11763
11810
  }
11764
11811
  self.params.logger.info("ClientPartial restored state", {
11765
11812
  symbol,
11813
+ strategyName,
11766
11814
  signalCount: Object.keys(partialData).length,
11767
11815
  });
11768
11816
  };
@@ -11841,23 +11889,24 @@ class ClientPartial {
11841
11889
  /**
11842
11890
  * Initializes partial state by loading from disk.
11843
11891
  *
11844
- * Uses singleshot pattern to ensure initialization happens exactly once per symbol.
11892
+ * Uses singleshot pattern to ensure initialization happens exactly once per symbol:strategyName.
11845
11893
  * Reads persisted state from PersistPartialAdapter and restores to _states Map.
11846
11894
  *
11847
11895
  * Must be called before profit()/loss()/clear() methods.
11848
11896
  *
11849
11897
  * @param symbol - Trading pair symbol
11898
+ * @param strategyName - Strategy identifier
11899
+ * @param backtest - True if backtest mode, false if live mode
11850
11900
  * @returns Promise that resolves when initialization is complete
11851
11901
  *
11852
11902
  * @example
11853
11903
  * ```typescript
11854
11904
  * const partial = new ClientPartial(params);
11855
- * await partial.waitForInit("BTCUSDT"); // Load persisted state
11905
+ * await partial.waitForInit("BTCUSDT", "my-strategy", false); // Load persisted state (live mode)
11856
11906
  * // Now profit()/loss() can be called
11857
11907
  * ```
11858
11908
  */
11859
- this.waitForInit = singleshot(async (symbol) => await WAIT_FOR_INIT_FN(symbol, this));
11860
- this._states = new Map();
11909
+ this.waitForInit = singleshot(async (symbol, strategyName) => await WAIT_FOR_INIT_FN(symbol, strategyName, this));
11861
11910
  }
11862
11911
  /**
11863
11912
  * Persists current partial state to disk.
@@ -11870,13 +11919,15 @@ class ClientPartial {
11870
11919
  * Uses atomic file writes via PersistPartialAdapter.
11871
11920
  *
11872
11921
  * @param symbol - Trading pair symbol
11922
+ * @param strategyName - Strategy identifier
11923
+ * @param backtest - True if backtest mode
11873
11924
  * @returns Promise that resolves when persistence is complete
11874
11925
  */
11875
- async _persistState(symbol, backtest) {
11876
- if (backtest) {
11926
+ async _persistState(symbol, strategyName) {
11927
+ if (this.params.backtest) {
11877
11928
  return;
11878
11929
  }
11879
- this.params.logger.debug("ClientPartial persistState", { symbol });
11930
+ this.params.logger.debug("ClientPartial persistState", { symbol, strategyName });
11880
11931
  if (this._states === NEED_FETCH) {
11881
11932
  throw new Error("ClientPartial not initialized. Call waitForInit() before using.");
11882
11933
  }
@@ -11887,7 +11938,7 @@ class ClientPartial {
11887
11938
  lossLevels: Array.from(state.lossLevels),
11888
11939
  };
11889
11940
  }
11890
- await PersistPartialAdapter.writePartialData(partialData, symbol);
11941
+ await PersistPartialAdapter.writePartialData(partialData, symbol, strategyName);
11891
11942
  }
11892
11943
  /**
11893
11944
  * Processes profit state and emits events for newly reached profit levels.
@@ -12008,8 +12059,11 @@ class ClientPartial {
12008
12059
  if (this._states === NEED_FETCH) {
12009
12060
  throw new Error("ClientPartial not initialized. Call waitForInit() before using.");
12010
12061
  }
12062
+ if (data.id !== this.params.signalId) {
12063
+ throw new Error(`Signal ID mismatch: expected ${this.params.signalId}, got ${data.id}`);
12064
+ }
12011
12065
  this._states.delete(data.id);
12012
- await this._persistState(symbol, backtest);
12066
+ await this._persistState(symbol, data.strategyName);
12013
12067
  }
12014
12068
  }
12015
12069
 
@@ -12104,15 +12158,17 @@ class PartialConnectionService {
12104
12158
  /**
12105
12159
  * Memoized factory function for ClientPartial instances.
12106
12160
  *
12107
- * Creates one ClientPartial per signal ID with configured callbacks.
12161
+ * Creates one ClientPartial per signal ID and backtest mode with configured callbacks.
12108
12162
  * Instances are cached until clear() is called.
12109
12163
  *
12110
- * Key format: signalId
12164
+ * Key format: "signalId:backtest" or "signalId:live"
12111
12165
  * Value: ClientPartial instance with logger and event emitters
12112
12166
  */
12113
- this.getPartial = memoize(([signalId]) => `${signalId}`, () => {
12167
+ this.getPartial = memoize(([signalId, backtest]) => `${signalId}:${backtest ? "backtest" : "live"}`, (signalId, backtest) => {
12114
12168
  return new ClientPartial({
12169
+ signalId,
12115
12170
  logger: this.loggerService,
12171
+ backtest,
12116
12172
  onProfit: COMMIT_PROFIT_FN,
12117
12173
  onLoss: COMMIT_LOSS_FN,
12118
12174
  });
@@ -12140,8 +12196,8 @@ class PartialConnectionService {
12140
12196
  backtest,
12141
12197
  when,
12142
12198
  });
12143
- const partial = this.getPartial(data.id);
12144
- await partial.waitForInit(symbol);
12199
+ const partial = this.getPartial(data.id, backtest);
12200
+ await partial.waitForInit(symbol, data.strategyName);
12145
12201
  return await partial.profit(symbol, data, currentPrice, revenuePercent, backtest, when);
12146
12202
  };
12147
12203
  /**
@@ -12167,8 +12223,8 @@ class PartialConnectionService {
12167
12223
  backtest,
12168
12224
  when,
12169
12225
  });
12170
- const partial = this.getPartial(data.id);
12171
- await partial.waitForInit(symbol);
12226
+ const partial = this.getPartial(data.id, backtest);
12227
+ await partial.waitForInit(symbol, data.strategyName);
12172
12228
  return await partial.loss(symbol, data, currentPrice, lossPercent, backtest, when);
12173
12229
  };
12174
12230
  /**
@@ -12189,15 +12245,17 @@ class PartialConnectionService {
12189
12245
  * @returns Promise that resolves when clear is complete
12190
12246
  */
12191
12247
  this.clear = async (symbol, data, priceClose, backtest) => {
12192
- this.loggerService.log("partialConnectionService profit", {
12248
+ this.loggerService.log("partialConnectionService clear", {
12193
12249
  symbol,
12194
12250
  data,
12195
12251
  priceClose,
12252
+ backtest,
12196
12253
  });
12197
- const partial = this.getPartial(data.id);
12198
- await partial.waitForInit(symbol);
12254
+ const partial = this.getPartial(data.id, backtest);
12255
+ await partial.waitForInit(symbol, data.strategyName);
12199
12256
  await partial.clear(symbol, data, priceClose, backtest);
12200
- this.getPartial.clear(data.id);
12257
+ const key = `${data.id}:${backtest ? "backtest" : "live"}`;
12258
+ this.getPartial.clear(key);
12201
12259
  };
12202
12260
  }
12203
12261
  }
@@ -15549,12 +15607,12 @@ class BacktestInstance {
15549
15607
  backtest$1.scheduleMarkdownService.clear({ symbol, strategyName: context.strategyName });
15550
15608
  }
15551
15609
  {
15552
- backtest$1.strategyCoreService.clear({ symbol, strategyName: context.strategyName });
15610
+ backtest$1.strategyCoreService.clear(true, { symbol, strategyName: context.strategyName });
15553
15611
  }
15554
15612
  {
15555
15613
  const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
15556
- riskName && backtest$1.riskGlobalService.clear(riskName);
15557
- riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(riskName));
15614
+ riskName && backtest$1.riskGlobalService.clear(true, riskName);
15615
+ riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, riskName));
15558
15616
  }
15559
15617
  return backtest$1.backtestCommandService.run(symbol, context);
15560
15618
  };
@@ -15585,9 +15643,9 @@ class BacktestInstance {
15585
15643
  });
15586
15644
  this.task(symbol, context).catch((error) => exitEmitter.next(new Error(getErrorMessage(error))));
15587
15645
  return () => {
15588
- backtest$1.strategyCoreService.stop({ symbol, strategyName: context.strategyName }, true);
15646
+ backtest$1.strategyCoreService.stop(true, { symbol, strategyName: context.strategyName });
15589
15647
  backtest$1.strategyCoreService
15590
- .getPendingSignal(symbol, context.strategyName)
15648
+ .getPendingSignal(true, symbol, context.strategyName)
15591
15649
  .then(async (pendingSignal) => {
15592
15650
  if (pendingSignal) {
15593
15651
  return;
@@ -15627,7 +15685,7 @@ class BacktestInstance {
15627
15685
  symbol,
15628
15686
  strategyName,
15629
15687
  });
15630
- await backtest$1.strategyCoreService.stop({ symbol, strategyName }, true);
15688
+ await backtest$1.strategyCoreService.stop(true, { symbol, strategyName });
15631
15689
  };
15632
15690
  /**
15633
15691
  * Gets statistical data from all closed signals for a symbol-strategy pair.
@@ -16053,12 +16111,12 @@ class LiveInstance {
16053
16111
  backtest$1.scheduleMarkdownService.clear({ symbol, strategyName: context.strategyName });
16054
16112
  }
16055
16113
  {
16056
- backtest$1.strategyCoreService.clear({ symbol, strategyName: context.strategyName });
16114
+ backtest$1.strategyCoreService.clear(false, { symbol, strategyName: context.strategyName });
16057
16115
  }
16058
16116
  {
16059
16117
  const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
16060
- riskName && backtest$1.riskGlobalService.clear(riskName);
16061
- riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(riskName));
16118
+ riskName && backtest$1.riskGlobalService.clear(false, riskName);
16119
+ riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(false, riskName));
16062
16120
  }
16063
16121
  return backtest$1.liveCommandService.run(symbol, context);
16064
16122
  };
@@ -16089,9 +16147,9 @@ class LiveInstance {
16089
16147
  });
16090
16148
  this.task(symbol, context).catch((error) => exitEmitter.next(new Error(getErrorMessage(error))));
16091
16149
  return () => {
16092
- backtest$1.strategyCoreService.stop({ symbol, strategyName: context.strategyName }, false);
16150
+ backtest$1.strategyCoreService.stop(false, { symbol, strategyName: context.strategyName });
16093
16151
  backtest$1.strategyCoreService
16094
- .getPendingSignal(symbol, context.strategyName)
16152
+ .getPendingSignal(false, symbol, context.strategyName)
16095
16153
  .then(async (pendingSignal) => {
16096
16154
  if (pendingSignal) {
16097
16155
  return;
@@ -16131,7 +16189,7 @@ class LiveInstance {
16131
16189
  symbol,
16132
16190
  strategyName,
16133
16191
  });
16134
- await backtest$1.strategyCoreService.stop({ symbol, strategyName }, false);
16192
+ await backtest$1.strategyCoreService.stop(false, { symbol, strategyName });
16135
16193
  };
16136
16194
  /**
16137
16195
  * Gets statistical data from all live trading events for a symbol-strategy pair.
@@ -16835,12 +16893,13 @@ class WalkerInstance {
16835
16893
  backtest$1.scheduleMarkdownService.clear({ symbol, strategyName });
16836
16894
  }
16837
16895
  {
16838
- backtest$1.strategyCoreService.clear({ symbol, strategyName });
16896
+ backtest$1.strategyCoreService.clear(true, { symbol, strategyName });
16839
16897
  }
16840
16898
  {
16841
16899
  const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16842
- riskName && backtest$1.riskGlobalService.clear(riskName);
16843
- riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(riskName));
16900
+ riskName && backtest$1.riskGlobalService.clear(true, riskName);
16901
+ riskList &&
16902
+ riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, riskName));
16844
16903
  }
16845
16904
  }
16846
16905
  return backtest$1.walkerCommandService.run(symbol, {
@@ -16876,8 +16935,12 @@ class WalkerInstance {
16876
16935
  this.task(symbol, context).catch((error) => exitEmitter.next(new Error(getErrorMessage(error))));
16877
16936
  return () => {
16878
16937
  for (const strategyName of walkerSchema.strategies) {
16879
- backtest$1.strategyCoreService.stop({ symbol, strategyName }, true);
16880
- walkerStopSubject.next({ symbol, strategyName, walkerName: context.walkerName });
16938
+ backtest$1.strategyCoreService.stop(true, { symbol, strategyName });
16939
+ walkerStopSubject.next({
16940
+ symbol,
16941
+ strategyName,
16942
+ walkerName: context.walkerName,
16943
+ });
16881
16944
  }
16882
16945
  if (!this._isDone) {
16883
16946
  doneWalkerSubject.next({
@@ -16922,7 +16985,7 @@ class WalkerInstance {
16922
16985
  const walkerSchema = backtest$1.walkerSchemaService.get(walkerName);
16923
16986
  for (const strategyName of walkerSchema.strategies) {
16924
16987
  await walkerStopSubject.next({ symbol, strategyName, walkerName });
16925
- await backtest$1.strategyCoreService.stop({ symbol, strategyName }, true);
16988
+ await backtest$1.strategyCoreService.stop(true, { symbol, strategyName });
16926
16989
  }
16927
16990
  };
16928
16991
  /**
@@ -17051,8 +17114,10 @@ class WalkerUtils {
17051
17114
  for (const strategyName of walkerSchema.strategies) {
17052
17115
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_RUN);
17053
17116
  const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
17054
- riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_RUN);
17055
- riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_RUN));
17117
+ riskName &&
17118
+ backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_RUN);
17119
+ riskList &&
17120
+ riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_RUN));
17056
17121
  }
17057
17122
  const instance = this._getInstance(symbol, context.walkerName);
17058
17123
  return instance.run(symbol, context);
@@ -17084,8 +17149,10 @@ class WalkerUtils {
17084
17149
  for (const strategyName of walkerSchema.strategies) {
17085
17150
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_BACKGROUND);
17086
17151
  const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
17087
- riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_BACKGROUND);
17088
- riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_BACKGROUND));
17152
+ riskName &&
17153
+ backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_BACKGROUND);
17154
+ riskList &&
17155
+ riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_BACKGROUND));
17089
17156
  }
17090
17157
  const instance = this._getInstance(symbol, context.walkerName);
17091
17158
  return instance.background(symbol, context);
@@ -17119,8 +17186,10 @@ class WalkerUtils {
17119
17186
  for (const strategyName of walkerSchema.strategies) {
17120
17187
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_STOP);
17121
17188
  const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
17122
- riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_STOP);
17123
- riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_STOP));
17189
+ riskName &&
17190
+ backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_STOP);
17191
+ riskList &&
17192
+ riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_STOP));
17124
17193
  }
17125
17194
  const instance = this._getInstance(symbol, walkerName);
17126
17195
  return await instance.stop(symbol, walkerName);
@@ -17144,8 +17213,10 @@ class WalkerUtils {
17144
17213
  for (const strategyName of walkerSchema.strategies) {
17145
17214
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_GET_DATA);
17146
17215
  const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
17147
- riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_DATA);
17148
- riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_DATA));
17216
+ riskName &&
17217
+ backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_DATA);
17218
+ riskList &&
17219
+ riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_DATA));
17149
17220
  }
17150
17221
  const instance = this._getInstance(symbol, walkerName);
17151
17222
  return await instance.getData(symbol, walkerName);
@@ -17171,8 +17242,10 @@ class WalkerUtils {
17171
17242
  for (const strategyName of walkerSchema.strategies) {
17172
17243
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_GET_REPORT);
17173
17244
  const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
17174
- riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_REPORT);
17175
- riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_REPORT));
17245
+ riskName &&
17246
+ backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_REPORT);
17247
+ riskList &&
17248
+ riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_REPORT));
17176
17249
  }
17177
17250
  const instance = this._getInstance(symbol, walkerName);
17178
17251
  return await instance.getReport(symbol, walkerName, strategyColumns, pnlColumns);
@@ -17201,8 +17274,10 @@ class WalkerUtils {
17201
17274
  for (const strategyName of walkerSchema.strategies) {
17202
17275
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_DUMP);
17203
17276
  const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
17204
- riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_DUMP);
17205
- riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_DUMP));
17277
+ riskName &&
17278
+ backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_DUMP);
17279
+ riskList &&
17280
+ riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_DUMP));
17206
17281
  }
17207
17282
  const instance = this._getInstance(symbol, walkerName);
17208
17283
  return await instance.dump(symbol, walkerName, path, strategyColumns, pnlColumns);