backtest-kit 1.5.19 → 1.5.21

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
@@ -2075,7 +2075,7 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
2075
2075
  // НЕМЕДЛЕННАЯ АКТИВАЦИЯ: priceOpen уже достигнут
2076
2076
  // Создаем активный сигнал напрямую (БЕЗ scheduled фазы)
2077
2077
  const signalRow = {
2078
- id: functoolsKit.randomString(),
2078
+ id: signal.id || functoolsKit.randomString(),
2079
2079
  priceOpen: signal.priceOpen, // Используем priceOpen из сигнала
2080
2080
  position: signal.position,
2081
2081
  note: toPlainString(signal.note),
@@ -2095,7 +2095,7 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
2095
2095
  }
2096
2096
  // ОЖИДАНИЕ АКТИВАЦИИ: создаем scheduled signal (risk check при активации)
2097
2097
  const scheduledSignalRow = {
2098
- id: functoolsKit.randomString(),
2098
+ id: signal.id || functoolsKit.randomString(),
2099
2099
  priceOpen: signal.priceOpen,
2100
2100
  position: signal.position,
2101
2101
  note: toPlainString(signal.note),
@@ -2114,7 +2114,7 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
2114
2114
  return scheduledSignalRow;
2115
2115
  }
2116
2116
  const signalRow = {
2117
- id: functoolsKit.randomString(),
2117
+ id: signal.id || functoolsKit.randomString(),
2118
2118
  priceOpen: currentPrice,
2119
2119
  ...signal,
2120
2120
  note: toPlainString(signal.note),
@@ -3249,11 +3249,321 @@ class ClientStrategy {
3249
3249
  }
3250
3250
  }
3251
3251
 
3252
+ const RISK_METHOD_NAME_GET_DATA = "RiskUtils.getData";
3253
+ const RISK_METHOD_NAME_GET_REPORT = "RiskUtils.getReport";
3254
+ const RISK_METHOD_NAME_DUMP = "RiskUtils.dump";
3255
+ /**
3256
+ * Composite risk management class that combines multiple risk profiles.
3257
+ *
3258
+ * Implements the Composite pattern to merge multiple IRisk instances into a single
3259
+ * risk checker. All risk checks must pass (logical AND) for a signal to be allowed.
3260
+ *
3261
+ * Features:
3262
+ * - Combines multiple risk profiles into one
3263
+ * - Signal is allowed only if ALL risks approve (checkSignal returns true for all)
3264
+ * - Propagates addSignal/removeSignal to all child risks
3265
+ * - Used internally when strategy has both riskName and riskList
3266
+ *
3267
+ * @example
3268
+ * ```typescript
3269
+ * import { MergeRisk } from "./classes/Risk";
3270
+ *
3271
+ * // Combine multiple risk profiles
3272
+ * const maxPositionsRisk = new MaxPositionsRisk(3);
3273
+ * const correlationRisk = new CorrelationRisk(0.7);
3274
+ * const mergedRisk = new MergeRisk([maxPositionsRisk, correlationRisk]);
3275
+ *
3276
+ * // Check if signal passes all risks
3277
+ * const canTrade = await mergedRisk.checkSignal({
3278
+ * symbol: "BTCUSDT",
3279
+ * strategyName: "my-strategy",
3280
+ * position: PositionEnum.LONG,
3281
+ * exchangeName: "binance"
3282
+ * });
3283
+ *
3284
+ * // If canTrade is true, all risks approved
3285
+ * // If false, at least one risk rejected the signal
3286
+ * ```
3287
+ */
3288
+ class MergeRisk {
3289
+ /**
3290
+ * Creates a merged risk profile from multiple risk instances.
3291
+ *
3292
+ * @param _riskList - Array of IRisk instances to combine
3293
+ */
3294
+ constructor(_riskList) {
3295
+ this._riskList = _riskList;
3296
+ }
3297
+ /**
3298
+ * Checks if signal passes all combined risk profiles.
3299
+ *
3300
+ * Executes checkSignal on all child risks in parallel and returns true only
3301
+ * if ALL risks approve the signal (logical AND operation).
3302
+ *
3303
+ * @param params - Risk check parameters (symbol, strategy, position, exchange)
3304
+ * @returns Promise resolving to true if all risks approve, false if any risk rejects
3305
+ */
3306
+ async checkSignal(params) {
3307
+ backtest$1.loggerService.info("MergeRisk checkSignal", {
3308
+ params,
3309
+ });
3310
+ const riskCheck = await Promise.all(this._riskList.map(async (risk) => await risk.checkSignal(params)));
3311
+ return riskCheck.every((isSafe) => isSafe);
3312
+ }
3313
+ /**
3314
+ * Registers a signal with all child risk profiles.
3315
+ *
3316
+ * Propagates the addSignal call to all child risks in parallel.
3317
+ * Used to track active positions across all risk management systems.
3318
+ *
3319
+ * @param symbol - Trading pair symbol
3320
+ * @param context - Context with strategyName and riskName
3321
+ * @returns Promise that resolves when all risks have registered the signal
3322
+ */
3323
+ async addSignal(symbol, context) {
3324
+ backtest$1.loggerService.info("MergeRisk addSignal", {
3325
+ symbol,
3326
+ context,
3327
+ });
3328
+ await Promise.all(this._riskList.map(async (risk) => await risk.addSignal(symbol, context)));
3329
+ }
3330
+ /**
3331
+ * Removes a signal from all child risk profiles.
3332
+ *
3333
+ * Propagates the removeSignal call to all child risks in parallel.
3334
+ * Used to update risk state when a position closes.
3335
+ *
3336
+ * @param symbol - Trading pair symbol
3337
+ * @param context - Context with strategyName and riskName
3338
+ * @returns Promise that resolves when all risks have removed the signal
3339
+ */
3340
+ async removeSignal(symbol, context) {
3341
+ backtest$1.loggerService.info("MergeRisk removeSignal", {
3342
+ symbol,
3343
+ context,
3344
+ });
3345
+ await Promise.all(this._riskList.map(async (risk) => await risk.removeSignal(symbol, context)));
3346
+ }
3347
+ }
3348
+ /**
3349
+ * Utility class for accessing risk rejection reports and statistics.
3350
+ *
3351
+ * Provides static-like methods (via singleton instance) to retrieve data
3352
+ * accumulated by RiskMarkdownService from risk rejection events.
3353
+ *
3354
+ * Features:
3355
+ * - Statistical data extraction (total rejections count, by symbol, by strategy)
3356
+ * - Markdown report generation with event tables
3357
+ * - File export to disk
3358
+ *
3359
+ * Data source:
3360
+ * - RiskMarkdownService listens to riskSubject
3361
+ * - Accumulates rejection events in ReportStorage (max 250 events per symbol-strategy pair)
3362
+ * - Events include: timestamp, symbol, strategyName, position, exchangeName, price, activePositionCount, comment
3363
+ *
3364
+ * @example
3365
+ * ```typescript
3366
+ * import { Risk } from "./classes/Risk";
3367
+ *
3368
+ * // Get statistical data for BTCUSDT:my-strategy
3369
+ * const stats = await Risk.getData("BTCUSDT", "my-strategy");
3370
+ * console.log(`Total rejections: ${stats.totalRejections}`);
3371
+ * console.log(`By symbol:`, stats.bySymbol);
3372
+ * console.log(`By strategy:`, stats.byStrategy);
3373
+ *
3374
+ * // Generate markdown report
3375
+ * const markdown = await Risk.getReport("BTCUSDT", "my-strategy");
3376
+ * console.log(markdown); // Formatted table with all rejection events
3377
+ *
3378
+ * // Export report to file
3379
+ * await Risk.dump("BTCUSDT", "my-strategy"); // Saves to ./dump/risk/BTCUSDT_my-strategy.md
3380
+ * await Risk.dump("BTCUSDT", "my-strategy", "./custom/path"); // Custom directory
3381
+ * ```
3382
+ */
3383
+ class RiskUtils {
3384
+ constructor() {
3385
+ /**
3386
+ * Retrieves statistical data from accumulated risk rejection events.
3387
+ *
3388
+ * Delegates to RiskMarkdownService.getData() which reads from ReportStorage.
3389
+ * Returns aggregated metrics calculated from all rejection events.
3390
+ *
3391
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
3392
+ * @param strategyName - Strategy name (e.g., "my-strategy")
3393
+ * @returns Promise resolving to RiskStatistics object with counts and event list
3394
+ *
3395
+ * @example
3396
+ * ```typescript
3397
+ * const stats = await Risk.getData("BTCUSDT", "my-strategy");
3398
+ *
3399
+ * console.log(`Total rejections: ${stats.totalRejections}`);
3400
+ * console.log(`Rejections by symbol:`, stats.bySymbol);
3401
+ * console.log(`Rejections by strategy:`, stats.byStrategy);
3402
+ *
3403
+ * // Iterate through all rejection events
3404
+ * for (const event of stats.eventList) {
3405
+ * console.log(`REJECTED: ${event.symbol} - ${event.comment} (${event.activePositionCount} active)`);
3406
+ * }
3407
+ * ```
3408
+ */
3409
+ this.getData = async (symbol, strategyName) => {
3410
+ backtest$1.loggerService.info(RISK_METHOD_NAME_GET_DATA, {
3411
+ symbol,
3412
+ strategyName,
3413
+ });
3414
+ backtest$1.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_GET_DATA);
3415
+ {
3416
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
3417
+ riskName &&
3418
+ backtest$1.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_DATA);
3419
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_DATA));
3420
+ }
3421
+ return await backtest$1.riskMarkdownService.getData(symbol, strategyName);
3422
+ };
3423
+ /**
3424
+ * Generates markdown report with all risk rejection events for a symbol-strategy pair.
3425
+ *
3426
+ * Creates formatted table containing:
3427
+ * - Symbol
3428
+ * - Strategy
3429
+ * - Position (LONG/SHORT)
3430
+ * - Exchange
3431
+ * - Price
3432
+ * - Active Positions (at rejection time)
3433
+ * - Reason (from validation note)
3434
+ * - Timestamp (ISO 8601)
3435
+ *
3436
+ * Also includes summary statistics at the end (total rejections, by symbol, by strategy).
3437
+ *
3438
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
3439
+ * @param strategyName - Strategy name (e.g., "my-strategy")
3440
+ * @returns Promise resolving to markdown formatted report string
3441
+ *
3442
+ * @example
3443
+ * ```typescript
3444
+ * const markdown = await Risk.getReport("BTCUSDT", "my-strategy");
3445
+ * console.log(markdown);
3446
+ *
3447
+ * // Output:
3448
+ * // # Risk Rejection Report: BTCUSDT:my-strategy
3449
+ * //
3450
+ * // | Symbol | Strategy | Position | Exchange | Price | Active Positions | Reason | Timestamp |
3451
+ * // | --- | --- | --- | --- | --- | --- | --- | --- |
3452
+ * // | BTCUSDT | my-strategy | LONG | binance | 50000.00000000 USD | 3 | Max 3 positions allowed | 2024-01-15T10:30:00.000Z |
3453
+ * //
3454
+ * // **Total rejections:** 1
3455
+ * //
3456
+ * // ## Rejections by Symbol
3457
+ * // - BTCUSDT: 1
3458
+ * //
3459
+ * // ## Rejections by Strategy
3460
+ * // - my-strategy: 1
3461
+ * ```
3462
+ */
3463
+ this.getReport = async (symbol, strategyName) => {
3464
+ backtest$1.loggerService.info(RISK_METHOD_NAME_GET_REPORT, {
3465
+ symbol,
3466
+ strategyName,
3467
+ });
3468
+ backtest$1.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_GET_REPORT);
3469
+ {
3470
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
3471
+ riskName &&
3472
+ backtest$1.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_REPORT);
3473
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_REPORT));
3474
+ }
3475
+ return await backtest$1.riskMarkdownService.getReport(symbol, strategyName);
3476
+ };
3477
+ /**
3478
+ * Generates and saves markdown report to file.
3479
+ *
3480
+ * Creates directory if it doesn't exist.
3481
+ * Filename format: {symbol}_{strategyName}.md (e.g., "BTCUSDT_my-strategy.md")
3482
+ *
3483
+ * Delegates to RiskMarkdownService.dump() which:
3484
+ * 1. Generates markdown report via getReport()
3485
+ * 2. Creates output directory (recursive mkdir)
3486
+ * 3. Writes file with UTF-8 encoding
3487
+ * 4. Logs success/failure to console
3488
+ *
3489
+ * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
3490
+ * @param strategyName - Strategy name (e.g., "my-strategy")
3491
+ * @param path - Output directory path (default: "./dump/risk")
3492
+ * @returns Promise that resolves when file is written
3493
+ *
3494
+ * @example
3495
+ * ```typescript
3496
+ * // Save to default path: ./dump/risk/BTCUSDT_my-strategy.md
3497
+ * await Risk.dump("BTCUSDT", "my-strategy");
3498
+ *
3499
+ * // Save to custom path: ./reports/risk/BTCUSDT_my-strategy.md
3500
+ * await Risk.dump("BTCUSDT", "my-strategy", "./reports/risk");
3501
+ *
3502
+ * // After multiple symbols backtested, export all risk reports
3503
+ * for (const symbol of ["BTCUSDT", "ETHUSDT", "BNBUSDT"]) {
3504
+ * await Risk.dump(symbol, "my-strategy", "./backtest-results");
3505
+ * }
3506
+ * ```
3507
+ */
3508
+ this.dump = async (symbol, strategyName, path) => {
3509
+ backtest$1.loggerService.info(RISK_METHOD_NAME_DUMP, {
3510
+ symbol,
3511
+ strategyName,
3512
+ path,
3513
+ });
3514
+ backtest$1.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_DUMP);
3515
+ {
3516
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
3517
+ riskName &&
3518
+ backtest$1.riskValidationService.validate(riskName, RISK_METHOD_NAME_DUMP);
3519
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, RISK_METHOD_NAME_DUMP));
3520
+ }
3521
+ await backtest$1.riskMarkdownService.dump(symbol, strategyName, path);
3522
+ };
3523
+ }
3524
+ }
3525
+ /**
3526
+ * Global singleton instance of RiskUtils.
3527
+ * Provides static-like access to risk rejection reporting methods.
3528
+ *
3529
+ * @example
3530
+ * ```typescript
3531
+ * import { Risk } from "backtest-kit";
3532
+ *
3533
+ * // Usage same as RiskUtils methods
3534
+ * const stats = await Risk.getData("BTCUSDT", "my-strategy");
3535
+ * const report = await Risk.getReport("BTCUSDT", "my-strategy");
3536
+ * await Risk.dump("BTCUSDT", "my-strategy");
3537
+ * ```
3538
+ */
3539
+ const Risk = new RiskUtils();
3540
+
3252
3541
  const NOOP_RISK = {
3253
3542
  checkSignal: () => Promise.resolve(true),
3254
3543
  addSignal: () => Promise.resolve(),
3255
3544
  removeSignal: () => Promise.resolve(),
3256
3545
  };
3546
+ const GET_RISK_FN = (dto, self) => {
3547
+ const hasRiskName = !!dto.riskName;
3548
+ const hasRiskList = !!(dto.riskList?.length);
3549
+ // Нет ни riskName, ни riskList
3550
+ if (!hasRiskName && !hasRiskList) {
3551
+ return NOOP_RISK;
3552
+ }
3553
+ // Есть только riskName (без riskList)
3554
+ if (hasRiskName && !hasRiskList) {
3555
+ return self.riskConnectionService.getRisk(dto.riskName);
3556
+ }
3557
+ // Есть только riskList (без riskName)
3558
+ if (!hasRiskName && hasRiskList) {
3559
+ return new MergeRisk(dto.riskList.map((riskName) => self.riskConnectionService.getRisk(riskName)));
3560
+ }
3561
+ // Есть и riskName, и riskList - объединяем (riskName в начало)
3562
+ return new MergeRisk([
3563
+ self.riskConnectionService.getRisk(dto.riskName),
3564
+ ...dto.riskList.map((riskName) => self.riskConnectionService.getRisk(riskName))
3565
+ ]);
3566
+ };
3257
3567
  /**
3258
3568
  * Connection service routing strategy operations to correct ClientStrategy instance.
3259
3569
  *
@@ -3294,7 +3604,7 @@ class StrategyConnectionService {
3294
3604
  * @returns Configured ClientStrategy instance
3295
3605
  */
3296
3606
  this.getStrategy = functoolsKit.memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, (symbol, strategyName) => {
3297
- const { riskName, getSignal, interval, callbacks } = this.strategySchemaService.get(strategyName);
3607
+ const { riskName = "", riskList = [], getSignal, interval, callbacks, } = this.strategySchemaService.get(strategyName);
3298
3608
  return new ClientStrategy({
3299
3609
  symbol,
3300
3610
  interval,
@@ -3303,7 +3613,10 @@ class StrategyConnectionService {
3303
3613
  logger: this.loggerService,
3304
3614
  partial: this.partialConnectionService,
3305
3615
  exchange: this.exchangeConnectionService,
3306
- risk: riskName ? this.riskConnectionService.getRisk(riskName) : NOOP_RISK,
3616
+ risk: GET_RISK_FN({
3617
+ riskName,
3618
+ riskList,
3619
+ }, this),
3307
3620
  riskName,
3308
3621
  strategyName,
3309
3622
  getSignal,
@@ -3415,7 +3728,7 @@ class StrategyConnectionService {
3415
3728
  */
3416
3729
  this.stop = async (ctx, backtest) => {
3417
3730
  this.loggerService.log("strategyConnectionService stop", {
3418
- ctx
3731
+ ctx,
3419
3732
  });
3420
3733
  const strategy = this.getStrategy(ctx.symbol, ctx.strategyName);
3421
3734
  await strategy.stop(ctx.symbol, ctx.strategyName, backtest);
@@ -4310,11 +4623,10 @@ class StrategyCoreService {
4310
4623
  symbol,
4311
4624
  strategyName,
4312
4625
  });
4313
- const strategySchema = this.strategySchemaService.get(strategyName);
4626
+ const { riskName, riskList } = this.strategySchemaService.get(strategyName);
4314
4627
  this.strategyValidationService.validate(strategyName, METHOD_NAME_VALIDATE);
4315
- const riskName = strategySchema.riskName;
4316
- riskName &&
4317
- this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE);
4628
+ riskName && this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE);
4629
+ riskList && riskList.forEach((riskName) => this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE));
4318
4630
  });
4319
4631
  /**
4320
4632
  * Retrieves the currently active pending signal for the symbol.
@@ -5920,10 +6232,9 @@ class LiveCommandService {
5920
6232
  this.exchangeValidationService.validate(context.exchangeName, METHOD_NAME_RUN$2);
5921
6233
  }
5922
6234
  {
5923
- const strategySchema = this.strategySchemaService.get(context.strategyName);
5924
- const riskName = strategySchema.riskName;
5925
- riskName &&
5926
- this.riskValidationService.validate(riskName, METHOD_NAME_RUN$2);
6235
+ const { riskName, riskList } = this.strategySchemaService.get(context.strategyName);
6236
+ riskName && this.riskValidationService.validate(riskName, METHOD_NAME_RUN$2);
6237
+ riskList && riskList.forEach((riskName) => this.riskValidationService.validate(riskName, METHOD_NAME_RUN$2));
5927
6238
  }
5928
6239
  return this.liveLogicPublicService.run(symbol, context);
5929
6240
  };
@@ -5964,9 +6275,9 @@ class BacktestCommandService {
5964
6275
  this.frameValidationService.validate(context.frameName, METHOD_NAME_RUN$1);
5965
6276
  }
5966
6277
  {
5967
- const strategySchema = this.strategySchemaService.get(context.strategyName);
5968
- const riskName = strategySchema.riskName;
6278
+ const { riskName, riskList } = this.strategySchemaService.get(context.strategyName);
5969
6279
  riskName && this.riskValidationService.validate(riskName, METHOD_NAME_RUN$1);
6280
+ riskList && riskList.forEach((riskName) => this.riskValidationService.validate(riskName, METHOD_NAME_RUN$1));
5970
6281
  }
5971
6282
  return this.backtestLogicPublicService.run(symbol, context);
5972
6283
  };
@@ -6010,11 +6321,10 @@ class WalkerCommandService {
6010
6321
  {
6011
6322
  const walkerSchema = this.walkerSchemaService.get(context.walkerName);
6012
6323
  for (const strategyName of walkerSchema.strategies) {
6013
- const strategySchema = this.strategySchemaService.get(strategyName);
6324
+ const { riskName, riskList } = this.strategySchemaService.get(strategyName);
6014
6325
  this.strategyValidationService.validate(strategyName, METHOD_NAME_RUN);
6015
- const riskName = strategySchema.riskName;
6016
- riskName &&
6017
- this.riskValidationService.validate(riskName, METHOD_NAME_RUN);
6326
+ riskName && this.riskValidationService.validate(riskName, METHOD_NAME_RUN);
6327
+ riskList && riskList.forEach((riskName) => this.riskValidationService.validate(riskName, METHOD_NAME_RUN));
6018
6328
  }
6019
6329
  }
6020
6330
  return this.walkerLogicPublicService.run(symbol, context);
@@ -9135,6 +9445,9 @@ class StrategyValidationService {
9135
9445
  if (strategy.riskName) {
9136
9446
  this.riskValidationService.validate(strategy.riskName, source);
9137
9447
  }
9448
+ if (strategy.riskList) {
9449
+ strategy.riskList.forEach((riskName) => this.riskValidationService.validate(riskName, source));
9450
+ }
9138
9451
  return true;
9139
9452
  });
9140
9453
  /**
@@ -11772,9 +12085,9 @@ class PartialGlobalService {
11772
12085
  methodName,
11773
12086
  });
11774
12087
  this.strategyValidationService.validate(strategyName, methodName);
11775
- const strategySchema = this.strategySchemaService.get(strategyName);
11776
- const riskName = strategySchema.riskName;
12088
+ const { riskName, riskList } = this.strategySchemaService.get(strategyName);
11777
12089
  riskName && this.riskValidationService.validate(riskName, methodName);
12090
+ riskList && riskList.forEach((riskName) => this.riskValidationService.validate(riskName, methodName));
11778
12091
  });
11779
12092
  /**
11780
12093
  * Processes profit state and emits events for newly reached profit levels.
@@ -14609,8 +14922,9 @@ class BacktestInstance {
14609
14922
  backtest$1.strategyCoreService.clear({ symbol, strategyName: context.strategyName });
14610
14923
  }
14611
14924
  {
14612
- const { riskName } = backtest$1.strategySchemaService.get(context.strategyName);
14925
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
14613
14926
  riskName && backtest$1.riskGlobalService.clear(riskName);
14927
+ riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(riskName));
14614
14928
  }
14615
14929
  return backtest$1.backtestCommandService.run(symbol, context);
14616
14930
  };
@@ -14794,8 +15108,9 @@ class BacktestUtils {
14794
15108
  backtest$1.frameValidationService.validate(context.frameName, BACKTEST_METHOD_NAME_RUN);
14795
15109
  }
14796
15110
  {
14797
- const { riskName } = backtest$1.strategySchemaService.get(context.strategyName);
15111
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
14798
15112
  riskName && backtest$1.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_RUN);
15113
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_RUN));
14799
15114
  }
14800
15115
  const instance = this._getInstance(symbol, context.strategyName);
14801
15116
  return instance.run(symbol, context);
@@ -14826,8 +15141,9 @@ class BacktestUtils {
14826
15141
  backtest$1.exchangeValidationService.validate(context.exchangeName, BACKTEST_METHOD_NAME_BACKGROUND);
14827
15142
  backtest$1.frameValidationService.validate(context.frameName, BACKTEST_METHOD_NAME_BACKGROUND);
14828
15143
  {
14829
- const { riskName } = backtest$1.strategySchemaService.get(context.strategyName);
15144
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
14830
15145
  riskName && backtest$1.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_BACKGROUND);
15146
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_BACKGROUND));
14831
15147
  }
14832
15148
  const instance = this._getInstance(symbol, context.strategyName);
14833
15149
  return instance.background(symbol, context);
@@ -14852,8 +15168,9 @@ class BacktestUtils {
14852
15168
  this.stop = async (symbol, strategyName) => {
14853
15169
  backtest$1.strategyValidationService.validate(strategyName, BACKTEST_METHOD_NAME_STOP);
14854
15170
  {
14855
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15171
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
14856
15172
  riskName && backtest$1.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_STOP);
15173
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_STOP));
14857
15174
  }
14858
15175
  const instance = this._getInstance(symbol, strategyName);
14859
15176
  return await instance.stop(symbol, strategyName);
@@ -14874,8 +15191,9 @@ class BacktestUtils {
14874
15191
  this.getData = async (symbol, strategyName) => {
14875
15192
  backtest$1.strategyValidationService.validate(strategyName, "BacktestUtils.getData");
14876
15193
  {
14877
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15194
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
14878
15195
  riskName && backtest$1.riskValidationService.validate(riskName, "BacktestUtils.getData");
15196
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, "BacktestUtils.getData"));
14879
15197
  }
14880
15198
  const instance = this._getInstance(symbol, strategyName);
14881
15199
  return await instance.getData(symbol, strategyName);
@@ -14896,8 +15214,9 @@ class BacktestUtils {
14896
15214
  this.getReport = async (symbol, strategyName) => {
14897
15215
  backtest$1.strategyValidationService.validate(strategyName, BACKTEST_METHOD_NAME_GET_REPORT);
14898
15216
  {
14899
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15217
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
14900
15218
  riskName && backtest$1.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_REPORT);
15219
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_REPORT));
14901
15220
  }
14902
15221
  const instance = this._getInstance(symbol, strategyName);
14903
15222
  return await instance.getReport(symbol, strategyName);
@@ -14921,8 +15240,9 @@ class BacktestUtils {
14921
15240
  this.dump = async (symbol, strategyName, path) => {
14922
15241
  backtest$1.strategyValidationService.validate(strategyName, BACKTEST_METHOD_NAME_DUMP);
14923
15242
  {
14924
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15243
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
14925
15244
  riskName && backtest$1.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_DUMP);
15245
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_DUMP));
14926
15246
  }
14927
15247
  const instance = this._getInstance(symbol, strategyName);
14928
15248
  return await instance.dump(symbol, strategyName, path);
@@ -14970,6 +15290,7 @@ const LIVE_METHOD_NAME_RUN = "LiveUtils.run";
14970
15290
  const LIVE_METHOD_NAME_BACKGROUND = "LiveUtils.background";
14971
15291
  const LIVE_METHOD_NAME_STOP = "LiveUtils.stop";
14972
15292
  const LIVE_METHOD_NAME_GET_REPORT = "LiveUtils.getReport";
15293
+ const LIVE_METHOD_NAME_GET_DATA = "LiveUtils.getData";
14973
15294
  const LIVE_METHOD_NAME_DUMP = "LiveUtils.dump";
14974
15295
  const LIVE_METHOD_NAME_TASK = "LiveUtils.task";
14975
15296
  const LIVE_METHOD_NAME_GET_STATUS = "LiveUtils.getStatus";
@@ -15101,8 +15422,9 @@ class LiveInstance {
15101
15422
  backtest$1.strategyCoreService.clear({ symbol, strategyName: context.strategyName });
15102
15423
  }
15103
15424
  {
15104
- const { riskName } = backtest$1.strategySchemaService.get(context.strategyName);
15425
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
15105
15426
  riskName && backtest$1.riskGlobalService.clear(riskName);
15427
+ riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(riskName));
15106
15428
  }
15107
15429
  return backtest$1.liveCommandService.run(symbol, context);
15108
15430
  };
@@ -15298,8 +15620,9 @@ class LiveUtils {
15298
15620
  backtest$1.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_RUN);
15299
15621
  }
15300
15622
  {
15301
- const { riskName } = backtest$1.strategySchemaService.get(context.strategyName);
15623
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
15302
15624
  riskName && backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_RUN);
15625
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_RUN));
15303
15626
  }
15304
15627
  const instance = this._getInstance(symbol, context.strategyName);
15305
15628
  return instance.run(symbol, context);
@@ -15329,8 +15652,9 @@ class LiveUtils {
15329
15652
  backtest$1.strategyValidationService.validate(context.strategyName, LIVE_METHOD_NAME_BACKGROUND);
15330
15653
  backtest$1.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_BACKGROUND);
15331
15654
  {
15332
- const { riskName } = backtest$1.strategySchemaService.get(context.strategyName);
15655
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
15333
15656
  riskName && backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_BACKGROUND);
15657
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_BACKGROUND));
15334
15658
  }
15335
15659
  const instance = this._getInstance(symbol, context.strategyName);
15336
15660
  return instance.background(symbol, context);
@@ -15355,8 +15679,9 @@ class LiveUtils {
15355
15679
  this.stop = async (symbol, strategyName) => {
15356
15680
  backtest$1.strategyValidationService.validate(strategyName, LIVE_METHOD_NAME_STOP);
15357
15681
  {
15358
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15682
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
15359
15683
  riskName && backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_STOP);
15684
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_STOP));
15360
15685
  }
15361
15686
  const instance = this._getInstance(symbol, strategyName);
15362
15687
  return await instance.stop(symbol, strategyName);
@@ -15377,8 +15702,9 @@ class LiveUtils {
15377
15702
  this.getData = async (symbol, strategyName) => {
15378
15703
  backtest$1.strategyValidationService.validate(strategyName, "LiveUtils.getData");
15379
15704
  {
15380
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15381
- riskName && backtest$1.riskValidationService.validate(riskName, "LiveUtils.getData");
15705
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
15706
+ riskName && backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_DATA);
15707
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_DATA));
15382
15708
  }
15383
15709
  const instance = this._getInstance(symbol, strategyName);
15384
15710
  return await instance.getData(symbol, strategyName);
@@ -15399,8 +15725,9 @@ class LiveUtils {
15399
15725
  this.getReport = async (symbol, strategyName) => {
15400
15726
  backtest$1.strategyValidationService.validate(strategyName, LIVE_METHOD_NAME_GET_REPORT);
15401
15727
  {
15402
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15728
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
15403
15729
  riskName && backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_REPORT);
15730
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_REPORT));
15404
15731
  }
15405
15732
  const instance = this._getInstance(symbol, strategyName);
15406
15733
  return await instance.getReport(symbol, strategyName);
@@ -15424,8 +15751,9 @@ class LiveUtils {
15424
15751
  this.dump = async (symbol, strategyName, path) => {
15425
15752
  backtest$1.strategyValidationService.validate(strategyName, LIVE_METHOD_NAME_DUMP);
15426
15753
  {
15427
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15754
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
15428
15755
  riskName && backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_DUMP);
15756
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, LIVE_METHOD_NAME_DUMP));
15429
15757
  }
15430
15758
  const instance = this._getInstance(symbol, strategyName);
15431
15759
  return await instance.dump(symbol, strategyName, path);
@@ -15516,8 +15844,9 @@ class ScheduleUtils {
15516
15844
  });
15517
15845
  backtest$1.strategyValidationService.validate(strategyName, SCHEDULE_METHOD_NAME_GET_DATA);
15518
15846
  {
15519
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15847
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
15520
15848
  riskName && backtest$1.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_DATA);
15849
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_DATA));
15521
15850
  }
15522
15851
  return await backtest$1.scheduleMarkdownService.getData(symbol, strategyName);
15523
15852
  };
@@ -15541,8 +15870,9 @@ class ScheduleUtils {
15541
15870
  });
15542
15871
  backtest$1.strategyValidationService.validate(strategyName, SCHEDULE_METHOD_NAME_GET_REPORT);
15543
15872
  {
15544
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15873
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
15545
15874
  riskName && backtest$1.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_REPORT);
15875
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_REPORT));
15546
15876
  }
15547
15877
  return await backtest$1.scheduleMarkdownService.getReport(symbol, strategyName);
15548
15878
  };
@@ -15570,8 +15900,9 @@ class ScheduleUtils {
15570
15900
  });
15571
15901
  backtest$1.strategyValidationService.validate(strategyName, SCHEDULE_METHOD_NAME_DUMP);
15572
15902
  {
15573
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15903
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
15574
15904
  riskName && backtest$1.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_DUMP);
15905
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_DUMP));
15575
15906
  }
15576
15907
  await backtest$1.scheduleMarkdownService.dump(symbol, strategyName, path);
15577
15908
  };
@@ -15590,6 +15921,9 @@ class ScheduleUtils {
15590
15921
  */
15591
15922
  const Schedule = new ScheduleUtils();
15592
15923
 
15924
+ const PERFORMANCE_METHOD_NAME_GET_DATA = "Performance.getData";
15925
+ const PERFORMANCE_METHOD_NAME_GET_REPORT = "Performance.getReport";
15926
+ const PERFORMANCE_METHOD_NAME_DUMP = "Performance.dump";
15593
15927
  /**
15594
15928
  * Performance class provides static methods for performance metrics analysis.
15595
15929
  *
@@ -15652,10 +15986,11 @@ class Performance {
15652
15986
  * ```
15653
15987
  */
15654
15988
  static async getData(symbol, strategyName) {
15655
- backtest$1.strategyValidationService.validate(strategyName, "Performance.getData");
15989
+ backtest$1.strategyValidationService.validate(strategyName, PERFORMANCE_METHOD_NAME_GET_DATA);
15656
15990
  {
15657
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15658
- riskName && backtest$1.riskValidationService.validate(riskName, "Performance.getData");
15991
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
15992
+ riskName && backtest$1.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_DATA);
15993
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_DATA));
15659
15994
  }
15660
15995
  return backtest$1.performanceMarkdownService.getData(symbol, strategyName);
15661
15996
  }
@@ -15682,10 +16017,11 @@ class Performance {
15682
16017
  * ```
15683
16018
  */
15684
16019
  static async getReport(symbol, strategyName) {
15685
- backtest$1.strategyValidationService.validate(strategyName, "Performance.getReport");
16020
+ backtest$1.strategyValidationService.validate(strategyName, PERFORMANCE_METHOD_NAME_GET_REPORT);
15686
16021
  {
15687
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15688
- riskName && backtest$1.riskValidationService.validate(riskName, "Performance.getReport");
16022
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16023
+ riskName && backtest$1.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_REPORT);
16024
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_REPORT));
15689
16025
  }
15690
16026
  return backtest$1.performanceMarkdownService.getReport(symbol, strategyName);
15691
16027
  }
@@ -15709,10 +16045,11 @@ class Performance {
15709
16045
  * ```
15710
16046
  */
15711
16047
  static async dump(symbol, strategyName, path = "./dump/performance") {
15712
- backtest$1.strategyValidationService.validate(strategyName, "Performance.dump");
16048
+ backtest$1.strategyValidationService.validate(strategyName, PERFORMANCE_METHOD_NAME_DUMP);
15713
16049
  {
15714
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
15715
- riskName && backtest$1.riskValidationService.validate(riskName, "Performance.dump");
16050
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16051
+ riskName && backtest$1.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_DUMP);
16052
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_DUMP));
15716
16053
  }
15717
16054
  return backtest$1.performanceMarkdownService.dump(symbol, strategyName, path);
15718
16055
  }
@@ -15859,8 +16196,9 @@ class WalkerInstance {
15859
16196
  backtest$1.strategyCoreService.clear({ symbol, strategyName });
15860
16197
  }
15861
16198
  {
15862
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
16199
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
15863
16200
  riskName && backtest$1.riskGlobalService.clear(riskName);
16201
+ riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(riskName));
15864
16202
  }
15865
16203
  }
15866
16204
  return backtest$1.walkerCommandService.run(symbol, {
@@ -16066,9 +16404,9 @@ class WalkerUtils {
16066
16404
  backtest$1.frameValidationService.validate(walkerSchema.frameName, WALKER_METHOD_NAME_RUN);
16067
16405
  for (const strategyName of walkerSchema.strategies) {
16068
16406
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_RUN);
16069
- const strategySchema = backtest$1.strategySchemaService.get(strategyName);
16070
- const riskName = strategySchema.riskName;
16407
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16071
16408
  riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_RUN);
16409
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_RUN));
16072
16410
  }
16073
16411
  const instance = this._getInstance(symbol, context.walkerName);
16074
16412
  return instance.run(symbol, context);
@@ -16099,9 +16437,9 @@ class WalkerUtils {
16099
16437
  backtest$1.frameValidationService.validate(walkerSchema.frameName, WALKER_METHOD_NAME_BACKGROUND);
16100
16438
  for (const strategyName of walkerSchema.strategies) {
16101
16439
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_BACKGROUND);
16102
- const strategySchema = backtest$1.strategySchemaService.get(strategyName);
16103
- const riskName = strategySchema.riskName;
16440
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16104
16441
  riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_BACKGROUND);
16442
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_BACKGROUND));
16105
16443
  }
16106
16444
  const instance = this._getInstance(symbol, context.walkerName);
16107
16445
  return instance.background(symbol, context);
@@ -16134,9 +16472,9 @@ class WalkerUtils {
16134
16472
  const walkerSchema = backtest$1.walkerSchemaService.get(walkerName);
16135
16473
  for (const strategyName of walkerSchema.strategies) {
16136
16474
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_STOP);
16137
- const strategySchema = backtest$1.strategySchemaService.get(strategyName);
16138
- const riskName = strategySchema.riskName;
16475
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16139
16476
  riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_STOP);
16477
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_STOP));
16140
16478
  }
16141
16479
  const instance = this._getInstance(symbol, walkerName);
16142
16480
  return await instance.stop(symbol, walkerName);
@@ -16159,9 +16497,9 @@ class WalkerUtils {
16159
16497
  const walkerSchema = backtest$1.walkerSchemaService.get(walkerName);
16160
16498
  for (const strategyName of walkerSchema.strategies) {
16161
16499
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_GET_DATA);
16162
- const strategySchema = backtest$1.strategySchemaService.get(strategyName);
16163
- const riskName = strategySchema.riskName;
16500
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16164
16501
  riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_DATA);
16502
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_DATA));
16165
16503
  }
16166
16504
  const instance = this._getInstance(symbol, walkerName);
16167
16505
  return await instance.getData(symbol, walkerName);
@@ -16184,9 +16522,9 @@ class WalkerUtils {
16184
16522
  const walkerSchema = backtest$1.walkerSchemaService.get(walkerName);
16185
16523
  for (const strategyName of walkerSchema.strategies) {
16186
16524
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_GET_REPORT);
16187
- const strategySchema = backtest$1.strategySchemaService.get(strategyName);
16188
- const riskName = strategySchema.riskName;
16525
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16189
16526
  riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_REPORT);
16527
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_REPORT));
16190
16528
  }
16191
16529
  const instance = this._getInstance(symbol, walkerName);
16192
16530
  return await instance.getReport(symbol, walkerName);
@@ -16212,9 +16550,9 @@ class WalkerUtils {
16212
16550
  const walkerSchema = backtest$1.walkerSchemaService.get(walkerName);
16213
16551
  for (const strategyName of walkerSchema.strategies) {
16214
16552
  backtest$1.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_DUMP);
16215
- const strategySchema = backtest$1.strategySchemaService.get(strategyName);
16216
- const riskName = strategySchema.riskName;
16553
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16217
16554
  riskName && backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_DUMP);
16555
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, WALKER_METHOD_NAME_DUMP));
16218
16556
  }
16219
16557
  const instance = this._getInstance(symbol, walkerName);
16220
16558
  return await instance.dump(symbol, walkerName, path);
@@ -16310,8 +16648,9 @@ class HeatUtils {
16310
16648
  backtest$1.loggerService.info(HEAT_METHOD_NAME_GET_DATA, { strategyName });
16311
16649
  backtest$1.strategyValidationService.validate(strategyName, HEAT_METHOD_NAME_GET_DATA);
16312
16650
  {
16313
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
16651
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16314
16652
  riskName && backtest$1.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_DATA);
16653
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_DATA));
16315
16654
  }
16316
16655
  return await backtest$1.heatMarkdownService.getData(strategyName);
16317
16656
  };
@@ -16344,8 +16683,9 @@ class HeatUtils {
16344
16683
  backtest$1.loggerService.info(HEAT_METHOD_NAME_GET_REPORT, { strategyName });
16345
16684
  backtest$1.strategyValidationService.validate(strategyName, HEAT_METHOD_NAME_GET_REPORT);
16346
16685
  {
16347
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
16686
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16348
16687
  riskName && backtest$1.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_REPORT);
16688
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_REPORT));
16349
16689
  }
16350
16690
  return await backtest$1.heatMarkdownService.getReport(strategyName);
16351
16691
  };
@@ -16371,8 +16711,9 @@ class HeatUtils {
16371
16711
  backtest$1.loggerService.info(HEAT_METHOD_NAME_DUMP, { strategyName, path });
16372
16712
  backtest$1.strategyValidationService.validate(strategyName, HEAT_METHOD_NAME_DUMP);
16373
16713
  {
16374
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
16714
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16375
16715
  riskName && backtest$1.riskValidationService.validate(riskName, HEAT_METHOD_NAME_DUMP);
16716
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, HEAT_METHOD_NAME_DUMP));
16376
16717
  }
16377
16718
  await backtest$1.heatMarkdownService.dump(strategyName, path);
16378
16719
  };
@@ -16694,8 +17035,9 @@ class PartialUtils {
16694
17035
  backtest$1.loggerService.info(PARTIAL_METHOD_NAME_GET_DATA, { symbol, strategyName });
16695
17036
  backtest$1.strategyValidationService.validate(strategyName, PARTIAL_METHOD_NAME_GET_DATA);
16696
17037
  {
16697
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
17038
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16698
17039
  riskName && backtest$1.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_DATA);
17040
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_DATA));
16699
17041
  }
16700
17042
  return await backtest$1.partialMarkdownService.getData(symbol, strategyName);
16701
17043
  };
@@ -16741,8 +17083,9 @@ class PartialUtils {
16741
17083
  backtest$1.loggerService.info(PARTIAL_METHOD_NAME_GET_REPORT, { symbol, strategyName });
16742
17084
  backtest$1.strategyValidationService.validate(strategyName, PARTIAL_METHOD_NAME_GET_REPORT);
16743
17085
  {
16744
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
17086
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16745
17087
  riskName && backtest$1.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_REPORT);
17088
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_REPORT));
16746
17089
  }
16747
17090
  return await backtest$1.partialMarkdownService.getReport(symbol, strategyName);
16748
17091
  };
@@ -16781,8 +17124,9 @@ class PartialUtils {
16781
17124
  backtest$1.loggerService.info(PARTIAL_METHOD_NAME_DUMP, { symbol, strategyName, path });
16782
17125
  backtest$1.strategyValidationService.validate(strategyName, PARTIAL_METHOD_NAME_DUMP);
16783
17126
  {
16784
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
17127
+ const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
16785
17128
  riskName && backtest$1.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_DUMP);
17129
+ riskList && riskList.forEach((riskName) => backtest$1.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_DUMP));
16786
17130
  }
16787
17131
  await backtest$1.partialMarkdownService.dump(symbol, strategyName, path);
16788
17132
  };
@@ -16885,186 +17229,6 @@ class ConstantUtils {
16885
17229
  */
16886
17230
  const Constant = new ConstantUtils();
16887
17231
 
16888
- const RISK_METHOD_NAME_GET_DATA = "RiskUtils.getData";
16889
- const RISK_METHOD_NAME_GET_REPORT = "RiskUtils.getReport";
16890
- const RISK_METHOD_NAME_DUMP = "RiskUtils.dump";
16891
- /**
16892
- * Utility class for accessing risk rejection reports and statistics.
16893
- *
16894
- * Provides static-like methods (via singleton instance) to retrieve data
16895
- * accumulated by RiskMarkdownService from risk rejection events.
16896
- *
16897
- * Features:
16898
- * - Statistical data extraction (total rejections count, by symbol, by strategy)
16899
- * - Markdown report generation with event tables
16900
- * - File export to disk
16901
- *
16902
- * Data source:
16903
- * - RiskMarkdownService listens to riskSubject
16904
- * - Accumulates rejection events in ReportStorage (max 250 events per symbol-strategy pair)
16905
- * - Events include: timestamp, symbol, strategyName, position, exchangeName, price, activePositionCount, comment
16906
- *
16907
- * @example
16908
- * ```typescript
16909
- * import { Risk } from "./classes/Risk";
16910
- *
16911
- * // Get statistical data for BTCUSDT:my-strategy
16912
- * const stats = await Risk.getData("BTCUSDT", "my-strategy");
16913
- * console.log(`Total rejections: ${stats.totalRejections}`);
16914
- * console.log(`By symbol:`, stats.bySymbol);
16915
- * console.log(`By strategy:`, stats.byStrategy);
16916
- *
16917
- * // Generate markdown report
16918
- * const markdown = await Risk.getReport("BTCUSDT", "my-strategy");
16919
- * console.log(markdown); // Formatted table with all rejection events
16920
- *
16921
- * // Export report to file
16922
- * await Risk.dump("BTCUSDT", "my-strategy"); // Saves to ./dump/risk/BTCUSDT_my-strategy.md
16923
- * await Risk.dump("BTCUSDT", "my-strategy", "./custom/path"); // Custom directory
16924
- * ```
16925
- */
16926
- class RiskUtils {
16927
- constructor() {
16928
- /**
16929
- * Retrieves statistical data from accumulated risk rejection events.
16930
- *
16931
- * Delegates to RiskMarkdownService.getData() which reads from ReportStorage.
16932
- * Returns aggregated metrics calculated from all rejection events.
16933
- *
16934
- * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
16935
- * @param strategyName - Strategy name (e.g., "my-strategy")
16936
- * @returns Promise resolving to RiskStatistics object with counts and event list
16937
- *
16938
- * @example
16939
- * ```typescript
16940
- * const stats = await Risk.getData("BTCUSDT", "my-strategy");
16941
- *
16942
- * console.log(`Total rejections: ${stats.totalRejections}`);
16943
- * console.log(`Rejections by symbol:`, stats.bySymbol);
16944
- * console.log(`Rejections by strategy:`, stats.byStrategy);
16945
- *
16946
- * // Iterate through all rejection events
16947
- * for (const event of stats.eventList) {
16948
- * console.log(`REJECTED: ${event.symbol} - ${event.comment} (${event.activePositionCount} active)`);
16949
- * }
16950
- * ```
16951
- */
16952
- this.getData = async (symbol, strategyName) => {
16953
- backtest$1.loggerService.info(RISK_METHOD_NAME_GET_DATA, { symbol, strategyName });
16954
- backtest$1.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_GET_DATA);
16955
- {
16956
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
16957
- riskName && backtest$1.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_DATA);
16958
- }
16959
- return await backtest$1.riskMarkdownService.getData(symbol, strategyName);
16960
- };
16961
- /**
16962
- * Generates markdown report with all risk rejection events for a symbol-strategy pair.
16963
- *
16964
- * Creates formatted table containing:
16965
- * - Symbol
16966
- * - Strategy
16967
- * - Position (LONG/SHORT)
16968
- * - Exchange
16969
- * - Price
16970
- * - Active Positions (at rejection time)
16971
- * - Reason (from validation note)
16972
- * - Timestamp (ISO 8601)
16973
- *
16974
- * Also includes summary statistics at the end (total rejections, by symbol, by strategy).
16975
- *
16976
- * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
16977
- * @param strategyName - Strategy name (e.g., "my-strategy")
16978
- * @returns Promise resolving to markdown formatted report string
16979
- *
16980
- * @example
16981
- * ```typescript
16982
- * const markdown = await Risk.getReport("BTCUSDT", "my-strategy");
16983
- * console.log(markdown);
16984
- *
16985
- * // Output:
16986
- * // # Risk Rejection Report: BTCUSDT:my-strategy
16987
- * //
16988
- * // | Symbol | Strategy | Position | Exchange | Price | Active Positions | Reason | Timestamp |
16989
- * // | --- | --- | --- | --- | --- | --- | --- | --- |
16990
- * // | BTCUSDT | my-strategy | LONG | binance | 50000.00000000 USD | 3 | Max 3 positions allowed | 2024-01-15T10:30:00.000Z |
16991
- * //
16992
- * // **Total rejections:** 1
16993
- * //
16994
- * // ## Rejections by Symbol
16995
- * // - BTCUSDT: 1
16996
- * //
16997
- * // ## Rejections by Strategy
16998
- * // - my-strategy: 1
16999
- * ```
17000
- */
17001
- this.getReport = async (symbol, strategyName) => {
17002
- backtest$1.loggerService.info(RISK_METHOD_NAME_GET_REPORT, { symbol, strategyName });
17003
- backtest$1.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_GET_REPORT);
17004
- {
17005
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
17006
- riskName && backtest$1.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_REPORT);
17007
- }
17008
- return await backtest$1.riskMarkdownService.getReport(symbol, strategyName);
17009
- };
17010
- /**
17011
- * Generates and saves markdown report to file.
17012
- *
17013
- * Creates directory if it doesn't exist.
17014
- * Filename format: {symbol}_{strategyName}.md (e.g., "BTCUSDT_my-strategy.md")
17015
- *
17016
- * Delegates to RiskMarkdownService.dump() which:
17017
- * 1. Generates markdown report via getReport()
17018
- * 2. Creates output directory (recursive mkdir)
17019
- * 3. Writes file with UTF-8 encoding
17020
- * 4. Logs success/failure to console
17021
- *
17022
- * @param symbol - Trading pair symbol (e.g., "BTCUSDT")
17023
- * @param strategyName - Strategy name (e.g., "my-strategy")
17024
- * @param path - Output directory path (default: "./dump/risk")
17025
- * @returns Promise that resolves when file is written
17026
- *
17027
- * @example
17028
- * ```typescript
17029
- * // Save to default path: ./dump/risk/BTCUSDT_my-strategy.md
17030
- * await Risk.dump("BTCUSDT", "my-strategy");
17031
- *
17032
- * // Save to custom path: ./reports/risk/BTCUSDT_my-strategy.md
17033
- * await Risk.dump("BTCUSDT", "my-strategy", "./reports/risk");
17034
- *
17035
- * // After multiple symbols backtested, export all risk reports
17036
- * for (const symbol of ["BTCUSDT", "ETHUSDT", "BNBUSDT"]) {
17037
- * await Risk.dump(symbol, "my-strategy", "./backtest-results");
17038
- * }
17039
- * ```
17040
- */
17041
- this.dump = async (symbol, strategyName, path) => {
17042
- backtest$1.loggerService.info(RISK_METHOD_NAME_DUMP, { symbol, strategyName, path });
17043
- backtest$1.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_DUMP);
17044
- {
17045
- const { riskName } = backtest$1.strategySchemaService.get(strategyName);
17046
- riskName && backtest$1.riskValidationService.validate(riskName, RISK_METHOD_NAME_DUMP);
17047
- }
17048
- await backtest$1.riskMarkdownService.dump(symbol, strategyName, path);
17049
- };
17050
- }
17051
- }
17052
- /**
17053
- * Global singleton instance of RiskUtils.
17054
- * Provides static-like access to risk rejection reporting methods.
17055
- *
17056
- * @example
17057
- * ```typescript
17058
- * import { Risk } from "backtest-kit";
17059
- *
17060
- * // Usage same as RiskUtils methods
17061
- * const stats = await Risk.getData("BTCUSDT", "my-strategy");
17062
- * const report = await Risk.getReport("BTCUSDT", "my-strategy");
17063
- * await Risk.dump("BTCUSDT", "my-strategy");
17064
- * ```
17065
- */
17066
- const Risk = new RiskUtils();
17067
-
17068
17232
  exports.Backtest = Backtest;
17069
17233
  exports.Constant = Constant;
17070
17234
  exports.ExecutionContextService = ExecutionContextService;