backtest-kit 6.13.0 → 6.14.0

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
@@ -127,6 +127,9 @@ const reportServices$1 = {
127
127
  highestProfitReportService: Symbol('highestProfitReportService'),
128
128
  maxDrawdownReportService: Symbol('maxDrawdownReportService'),
129
129
  };
130
+ const helperServices$1 = {
131
+ notificationHelperService: Symbol('notificationHelperService'),
132
+ };
130
133
  const validationServices$1 = {
131
134
  exchangeValidationService: Symbol('exchangeValidationService'),
132
135
  strategyValidationService: Symbol('strategyValidationService'),
@@ -152,6 +155,7 @@ const TYPES = {
152
155
  ...markdownServices$1,
153
156
  ...reportServices$1,
154
157
  ...validationServices$1,
158
+ ...helperServices$1,
155
159
  };
156
160
 
157
161
  /**
@@ -744,6 +748,11 @@ const highestProfitSubject = new Subject();
744
748
  * Allows users to track drawdown levels and implement custom risk management logic based on drawdown thresholds.
745
749
  */
746
750
  const maxDrawdownSubject = new Subject();
751
+ /**
752
+ * Signal info emitter for user-defined informational notes on open positions.
753
+ * Emits when a strategy calls commitSignalInfo() to broadcast a custom annotation.
754
+ */
755
+ const signalNotifySubject = new Subject();
747
756
 
748
757
  var emitters = /*#__PURE__*/Object.freeze({
749
758
  __proto__: null,
@@ -768,6 +777,7 @@ var emitters = /*#__PURE__*/Object.freeze({
768
777
  signalBacktestEmitter: signalBacktestEmitter,
769
778
  signalEmitter: signalEmitter,
770
779
  signalLiveEmitter: signalLiveEmitter,
780
+ signalNotifySubject: signalNotifySubject,
771
781
  strategyCommitSubject: strategyCommitSubject,
772
782
  syncSubject: syncSubject,
773
783
  validationSubject: validationSubject,
@@ -10270,7 +10280,7 @@ const GET_RISK_FN = (dto, backtest, exchangeName, frameName, self) => {
10270
10280
  * @param backtest - Whether running in backtest mode
10271
10281
  * @returns Unique string key for memoization
10272
10282
  */
10273
- const CREATE_KEY_FN$u = (symbol, strategyName, exchangeName, frameName, backtest) => {
10283
+ const CREATE_KEY_FN$v = (symbol, strategyName, exchangeName, frameName, backtest) => {
10274
10284
  const parts = [symbol, strategyName, exchangeName];
10275
10285
  if (frameName)
10276
10286
  parts.push(frameName);
@@ -10537,7 +10547,7 @@ class StrategyConnectionService {
10537
10547
  * @param backtest - Whether running in backtest mode
10538
10548
  * @returns Configured ClientStrategy instance
10539
10549
  */
10540
- this.getStrategy = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$u(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => {
10550
+ this.getStrategy = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$v(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => {
10541
10551
  const { riskName = "", riskList = [], getSignal, interval = STRATEGY_DEFAULT_INTERVAL, callbacks, } = this.strategySchemaService.get(strategyName);
10542
10552
  return new ClientStrategy({
10543
10553
  symbol,
@@ -11458,7 +11468,7 @@ class StrategyConnectionService {
11458
11468
  }
11459
11469
  return;
11460
11470
  }
11461
- const key = CREATE_KEY_FN$u(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
11471
+ const key = CREATE_KEY_FN$v(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
11462
11472
  if (!this.getStrategy.has(key)) {
11463
11473
  return;
11464
11474
  }
@@ -12627,7 +12637,7 @@ class ClientRisk {
12627
12637
  * @param backtest - Whether running in backtest mode
12628
12638
  * @returns Unique string key for memoization
12629
12639
  */
12630
- const CREATE_KEY_FN$t = (riskName, exchangeName, frameName, backtest) => {
12640
+ const CREATE_KEY_FN$u = (riskName, exchangeName, frameName, backtest) => {
12631
12641
  const parts = [riskName, exchangeName];
12632
12642
  if (frameName)
12633
12643
  parts.push(frameName);
@@ -12727,7 +12737,7 @@ class RiskConnectionService {
12727
12737
  * @param backtest - True if backtest mode, false if live mode
12728
12738
  * @returns Configured ClientRisk instance
12729
12739
  */
12730
- this.getRisk = memoize(([riskName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$t(riskName, exchangeName, frameName, backtest), (riskName, exchangeName, frameName, backtest) => {
12740
+ this.getRisk = memoize(([riskName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$u(riskName, exchangeName, frameName, backtest), (riskName, exchangeName, frameName, backtest) => {
12731
12741
  const schema = this.riskSchemaService.get(riskName);
12732
12742
  return new ClientRisk({
12733
12743
  ...schema,
@@ -12796,7 +12806,7 @@ class RiskConnectionService {
12796
12806
  payload,
12797
12807
  });
12798
12808
  if (payload) {
12799
- const key = CREATE_KEY_FN$t(payload.riskName, payload.exchangeName, payload.frameName, payload.backtest);
12809
+ const key = CREATE_KEY_FN$u(payload.riskName, payload.exchangeName, payload.frameName, payload.backtest);
12800
12810
  this.getRisk.clear(key);
12801
12811
  }
12802
12812
  else {
@@ -13840,7 +13850,7 @@ class ClientAction {
13840
13850
  * @param backtest - Whether running in backtest mode
13841
13851
  * @returns Unique string key for memoization
13842
13852
  */
13843
- const CREATE_KEY_FN$s = (actionName, strategyName, exchangeName, frameName, backtest) => {
13853
+ const CREATE_KEY_FN$t = (actionName, strategyName, exchangeName, frameName, backtest) => {
13844
13854
  const parts = [actionName, strategyName, exchangeName];
13845
13855
  if (frameName)
13846
13856
  parts.push(frameName);
@@ -13892,7 +13902,7 @@ class ActionConnectionService {
13892
13902
  * @param backtest - True if backtest mode, false if live mode
13893
13903
  * @returns Configured ClientAction instance
13894
13904
  */
13895
- this.getAction = memoize(([actionName, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$s(actionName, strategyName, exchangeName, frameName, backtest), (actionName, strategyName, exchangeName, frameName, backtest) => {
13905
+ this.getAction = memoize(([actionName, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$t(actionName, strategyName, exchangeName, frameName, backtest), (actionName, strategyName, exchangeName, frameName, backtest) => {
13896
13906
  const schema = this.actionSchemaService.get(actionName);
13897
13907
  return new ClientAction({
13898
13908
  ...schema,
@@ -14103,7 +14113,7 @@ class ActionConnectionService {
14103
14113
  await Promise.all(actions.map(async (action) => await action.dispose()));
14104
14114
  return;
14105
14115
  }
14106
- const key = CREATE_KEY_FN$s(payload.actionName, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
14116
+ const key = CREATE_KEY_FN$t(payload.actionName, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
14107
14117
  if (!this.getAction.has(key)) {
14108
14118
  return;
14109
14119
  }
@@ -14114,14 +14124,14 @@ class ActionConnectionService {
14114
14124
  }
14115
14125
  }
14116
14126
 
14117
- const METHOD_NAME_VALIDATE$2 = "exchangeCoreService validate";
14127
+ const METHOD_NAME_VALIDATE$3 = "exchangeCoreService validate";
14118
14128
  /**
14119
14129
  * Creates a unique key for memoizing validate calls.
14120
14130
  * Key format: "exchangeName"
14121
14131
  * @param exchangeName - Exchange name
14122
14132
  * @returns Unique string key for memoization
14123
14133
  */
14124
- const CREATE_KEY_FN$r = (exchangeName) => {
14134
+ const CREATE_KEY_FN$s = (exchangeName) => {
14125
14135
  return exchangeName;
14126
14136
  };
14127
14137
  /**
@@ -14145,11 +14155,11 @@ class ExchangeCoreService {
14145
14155
  * @param exchangeName - Name of the exchange to validate
14146
14156
  * @returns Promise that resolves when validation is complete
14147
14157
  */
14148
- this.validate = memoize(([exchangeName]) => CREATE_KEY_FN$r(exchangeName), async (exchangeName) => {
14149
- this.loggerService.log(METHOD_NAME_VALIDATE$2, {
14158
+ this.validate = memoize(([exchangeName]) => CREATE_KEY_FN$s(exchangeName), async (exchangeName) => {
14159
+ this.loggerService.log(METHOD_NAME_VALIDATE$3, {
14150
14160
  exchangeName,
14151
14161
  });
14152
- this.exchangeValidationService.validate(exchangeName, METHOD_NAME_VALIDATE$2);
14162
+ this.exchangeValidationService.validate(exchangeName, METHOD_NAME_VALIDATE$3);
14153
14163
  });
14154
14164
  /**
14155
14165
  * Fetches historical candles with execution context.
@@ -14390,14 +14400,14 @@ class ExchangeCoreService {
14390
14400
  }
14391
14401
  }
14392
14402
 
14393
- const METHOD_NAME_VALIDATE$1 = "strategyCoreService validate";
14403
+ const METHOD_NAME_VALIDATE$2 = "strategyCoreService validate";
14394
14404
  /**
14395
14405
  * Creates a unique key for memoizing validate calls.
14396
14406
  * Key format: "strategyName:exchangeName:frameName"
14397
14407
  * @param context - Execution context with strategyName, exchangeName, frameName
14398
14408
  * @returns Unique string key for memoization
14399
14409
  */
14400
- const CREATE_KEY_FN$q = (context) => {
14410
+ const CREATE_KEY_FN$r = (context) => {
14401
14411
  const parts = [context.strategyName, context.exchangeName];
14402
14412
  if (context.frameName)
14403
14413
  parts.push(context.frameName);
@@ -14429,16 +14439,16 @@ class StrategyCoreService {
14429
14439
  * @param context - Execution context with strategyName, exchangeName, frameName
14430
14440
  * @returns Promise that resolves when validation is complete
14431
14441
  */
14432
- this.validate = memoize(([context]) => CREATE_KEY_FN$q(context), async (context) => {
14433
- this.loggerService.log(METHOD_NAME_VALIDATE$1, {
14442
+ this.validate = memoize(([context]) => CREATE_KEY_FN$r(context), async (context) => {
14443
+ this.loggerService.log(METHOD_NAME_VALIDATE$2, {
14434
14444
  context,
14435
14445
  });
14436
14446
  const { riskName, riskList } = this.strategySchemaService.get(context.strategyName);
14437
- this.strategyValidationService.validate(context.strategyName, METHOD_NAME_VALIDATE$1);
14438
- this.exchangeValidationService.validate(context.exchangeName, METHOD_NAME_VALIDATE$1);
14439
- context.frameName && this.frameValidationService.validate(context.frameName, METHOD_NAME_VALIDATE$1);
14440
- riskName && this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE$1);
14441
- riskList && riskList.forEach((riskName) => this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE$1));
14447
+ this.strategyValidationService.validate(context.strategyName, METHOD_NAME_VALIDATE$2);
14448
+ this.exchangeValidationService.validate(context.exchangeName, METHOD_NAME_VALIDATE$2);
14449
+ context.frameName && this.frameValidationService.validate(context.frameName, METHOD_NAME_VALIDATE$2);
14450
+ riskName && this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE$2);
14451
+ riskList && riskList.forEach((riskName) => this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE$2));
14442
14452
  });
14443
14453
  /**
14444
14454
  * Retrieves the currently active pending signal for the symbol.
@@ -15767,7 +15777,7 @@ class SizingGlobalService {
15767
15777
  * @param context - Context with riskName, exchangeName, frameName
15768
15778
  * @returns Unique string key for memoization
15769
15779
  */
15770
- const CREATE_KEY_FN$p = (context) => {
15780
+ const CREATE_KEY_FN$q = (context) => {
15771
15781
  const parts = [context.riskName, context.exchangeName];
15772
15782
  if (context.frameName)
15773
15783
  parts.push(context.frameName);
@@ -15793,7 +15803,7 @@ class RiskGlobalService {
15793
15803
  * @param payload - Payload with riskName, exchangeName and frameName
15794
15804
  * @returns Promise that resolves when validation is complete
15795
15805
  */
15796
- this.validate = memoize(([context]) => CREATE_KEY_FN$p(context), async (context) => {
15806
+ this.validate = memoize(([context]) => CREATE_KEY_FN$q(context), async (context) => {
15797
15807
  this.loggerService.log("riskGlobalService validate", {
15798
15808
  context,
15799
15809
  });
@@ -15864,14 +15874,14 @@ class RiskGlobalService {
15864
15874
  }
15865
15875
  }
15866
15876
 
15867
- const METHOD_NAME_VALIDATE = "actionCoreService validate";
15877
+ const METHOD_NAME_VALIDATE$1 = "actionCoreService validate";
15868
15878
  /**
15869
15879
  * Creates a unique key for memoizing validate calls.
15870
15880
  * Key format: "strategyName:exchangeName:frameName"
15871
15881
  * @param context - Execution context with strategyName, exchangeName, frameName
15872
15882
  * @returns Unique string key for memoization
15873
15883
  */
15874
- const CREATE_KEY_FN$o = (context) => {
15884
+ const CREATE_KEY_FN$p = (context) => {
15875
15885
  const parts = [context.strategyName, context.exchangeName];
15876
15886
  if (context.frameName)
15877
15887
  parts.push(context.frameName);
@@ -15915,17 +15925,17 @@ class ActionCoreService {
15915
15925
  * @param context - Strategy execution context with strategyName, exchangeName and frameName
15916
15926
  * @returns Promise that resolves when all validations complete
15917
15927
  */
15918
- this.validate = memoize(([context]) => CREATE_KEY_FN$o(context), async (context) => {
15919
- this.loggerService.log(METHOD_NAME_VALIDATE, {
15928
+ this.validate = memoize(([context]) => CREATE_KEY_FN$p(context), async (context) => {
15929
+ this.loggerService.log(METHOD_NAME_VALIDATE$1, {
15920
15930
  context,
15921
15931
  });
15922
15932
  const { riskName, riskList, actions } = this.strategySchemaService.get(context.strategyName);
15923
- this.strategyValidationService.validate(context.strategyName, METHOD_NAME_VALIDATE);
15924
- this.exchangeValidationService.validate(context.exchangeName, METHOD_NAME_VALIDATE);
15925
- context.frameName && this.frameValidationService.validate(context.frameName, METHOD_NAME_VALIDATE);
15926
- riskName && this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE);
15927
- riskList && riskList.forEach((riskName) => this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE));
15928
- actions && actions.forEach((actionName) => this.actionValidationService.validate(actionName, METHOD_NAME_VALIDATE));
15933
+ this.strategyValidationService.validate(context.strategyName, METHOD_NAME_VALIDATE$1);
15934
+ this.exchangeValidationService.validate(context.exchangeName, METHOD_NAME_VALIDATE$1);
15935
+ context.frameName && this.frameValidationService.validate(context.frameName, METHOD_NAME_VALIDATE$1);
15936
+ riskName && this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE$1);
15937
+ riskList && riskList.forEach((riskName) => this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE$1));
15938
+ actions && actions.forEach((actionName) => this.actionValidationService.validate(actionName, METHOD_NAME_VALIDATE$1));
15929
15939
  });
15930
15940
  /**
15931
15941
  * Initializes all ClientAction instances for the strategy.
@@ -20958,7 +20968,7 @@ const ReportWriter = new ReportWriterAdapter();
20958
20968
  * @param backtest - Whether running in backtest mode
20959
20969
  * @returns Unique string key for memoization
20960
20970
  */
20961
- const CREATE_KEY_FN$n = (symbol, strategyName, exchangeName, frameName, backtest) => {
20971
+ const CREATE_KEY_FN$o = (symbol, strategyName, exchangeName, frameName, backtest) => {
20962
20972
  const parts = [symbol, strategyName, exchangeName];
20963
20973
  if (frameName)
20964
20974
  parts.push(frameName);
@@ -21204,7 +21214,7 @@ class BacktestMarkdownService {
21204
21214
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
21205
21215
  * Each combination gets its own isolated storage instance.
21206
21216
  */
21207
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$n(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$a(symbol, strategyName, exchangeName, frameName));
21217
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$o(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$a(symbol, strategyName, exchangeName, frameName));
21208
21218
  /**
21209
21219
  * Processes tick events and accumulates closed signals.
21210
21220
  * Should be called from IStrategyCallbacks.onTick.
@@ -21361,7 +21371,7 @@ class BacktestMarkdownService {
21361
21371
  payload,
21362
21372
  });
21363
21373
  if (payload) {
21364
- const key = CREATE_KEY_FN$n(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
21374
+ const key = CREATE_KEY_FN$o(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
21365
21375
  this.getStorage.clear(key);
21366
21376
  }
21367
21377
  else {
@@ -21423,7 +21433,7 @@ class BacktestMarkdownService {
21423
21433
  * @param backtest - Whether running in backtest mode
21424
21434
  * @returns Unique string key for memoization
21425
21435
  */
21426
- const CREATE_KEY_FN$m = (symbol, strategyName, exchangeName, frameName, backtest) => {
21436
+ const CREATE_KEY_FN$n = (symbol, strategyName, exchangeName, frameName, backtest) => {
21427
21437
  const parts = [symbol, strategyName, exchangeName];
21428
21438
  if (frameName)
21429
21439
  parts.push(frameName);
@@ -21918,7 +21928,7 @@ class LiveMarkdownService {
21918
21928
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
21919
21929
  * Each combination gets its own isolated storage instance.
21920
21930
  */
21921
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$m(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$9(symbol, strategyName, exchangeName, frameName));
21931
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$n(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$9(symbol, strategyName, exchangeName, frameName));
21922
21932
  /**
21923
21933
  * Subscribes to live signal emitter to receive tick events.
21924
21934
  * Protected against multiple subscriptions.
@@ -22136,7 +22146,7 @@ class LiveMarkdownService {
22136
22146
  payload,
22137
22147
  });
22138
22148
  if (payload) {
22139
- const key = CREATE_KEY_FN$m(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
22149
+ const key = CREATE_KEY_FN$n(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
22140
22150
  this.getStorage.clear(key);
22141
22151
  }
22142
22152
  else {
@@ -22156,7 +22166,7 @@ class LiveMarkdownService {
22156
22166
  * @param backtest - Whether running in backtest mode
22157
22167
  * @returns Unique string key for memoization
22158
22168
  */
22159
- const CREATE_KEY_FN$l = (symbol, strategyName, exchangeName, frameName, backtest) => {
22169
+ const CREATE_KEY_FN$m = (symbol, strategyName, exchangeName, frameName, backtest) => {
22160
22170
  const parts = [symbol, strategyName, exchangeName];
22161
22171
  if (frameName)
22162
22172
  parts.push(frameName);
@@ -22445,7 +22455,7 @@ class ScheduleMarkdownService {
22445
22455
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
22446
22456
  * Each combination gets its own isolated storage instance.
22447
22457
  */
22448
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$l(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$8(symbol, strategyName, exchangeName, frameName));
22458
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$m(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$8(symbol, strategyName, exchangeName, frameName));
22449
22459
  /**
22450
22460
  * Subscribes to signal emitter to receive scheduled signal events.
22451
22461
  * Protected against multiple subscriptions.
@@ -22648,7 +22658,7 @@ class ScheduleMarkdownService {
22648
22658
  payload,
22649
22659
  });
22650
22660
  if (payload) {
22651
- const key = CREATE_KEY_FN$l(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
22661
+ const key = CREATE_KEY_FN$m(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
22652
22662
  this.getStorage.clear(key);
22653
22663
  }
22654
22664
  else {
@@ -22668,7 +22678,7 @@ class ScheduleMarkdownService {
22668
22678
  * @param backtest - Whether running in backtest mode
22669
22679
  * @returns Unique string key for memoization
22670
22680
  */
22671
- const CREATE_KEY_FN$k = (symbol, strategyName, exchangeName, frameName, backtest) => {
22681
+ const CREATE_KEY_FN$l = (symbol, strategyName, exchangeName, frameName, backtest) => {
22672
22682
  const parts = [symbol, strategyName, exchangeName];
22673
22683
  if (frameName)
22674
22684
  parts.push(frameName);
@@ -22913,7 +22923,7 @@ class PerformanceMarkdownService {
22913
22923
  * Memoized function to get or create PerformanceStorage for a symbol-strategy-exchange-frame-backtest combination.
22914
22924
  * Each combination gets its own isolated storage instance.
22915
22925
  */
22916
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$k(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new PerformanceStorage(symbol, strategyName, exchangeName, frameName));
22926
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$l(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new PerformanceStorage(symbol, strategyName, exchangeName, frameName));
22917
22927
  /**
22918
22928
  * Subscribes to performance emitter to receive performance events.
22919
22929
  * Protected against multiple subscriptions.
@@ -23080,7 +23090,7 @@ class PerformanceMarkdownService {
23080
23090
  payload,
23081
23091
  });
23082
23092
  if (payload) {
23083
- const key = CREATE_KEY_FN$k(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
23093
+ const key = CREATE_KEY_FN$l(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
23084
23094
  this.getStorage.clear(key);
23085
23095
  }
23086
23096
  else {
@@ -23559,7 +23569,7 @@ class WalkerMarkdownService {
23559
23569
  * @param backtest - Whether running in backtest mode
23560
23570
  * @returns Unique string key for memoization
23561
23571
  */
23562
- const CREATE_KEY_FN$j = (exchangeName, frameName, backtest) => {
23572
+ const CREATE_KEY_FN$k = (exchangeName, frameName, backtest) => {
23563
23573
  const parts = [exchangeName];
23564
23574
  if (frameName)
23565
23575
  parts.push(frameName);
@@ -24006,7 +24016,7 @@ class HeatMarkdownService {
24006
24016
  * Memoized function to get or create HeatmapStorage for exchange, frame and backtest mode.
24007
24017
  * Each exchangeName + frameName + backtest mode combination gets its own isolated heatmap storage instance.
24008
24018
  */
24009
- this.getStorage = memoize(([exchangeName, frameName, backtest]) => CREATE_KEY_FN$j(exchangeName, frameName, backtest), (exchangeName, frameName, backtest) => new HeatmapStorage(exchangeName, frameName, backtest));
24019
+ this.getStorage = memoize(([exchangeName, frameName, backtest]) => CREATE_KEY_FN$k(exchangeName, frameName, backtest), (exchangeName, frameName, backtest) => new HeatmapStorage(exchangeName, frameName, backtest));
24010
24020
  /**
24011
24021
  * Subscribes to signal emitter to receive tick events.
24012
24022
  * Protected against multiple subscriptions.
@@ -24224,7 +24234,7 @@ class HeatMarkdownService {
24224
24234
  payload,
24225
24235
  });
24226
24236
  if (payload) {
24227
- const key = CREATE_KEY_FN$j(payload.exchangeName, payload.frameName, payload.backtest);
24237
+ const key = CREATE_KEY_FN$k(payload.exchangeName, payload.frameName, payload.backtest);
24228
24238
  this.getStorage.clear(key);
24229
24239
  }
24230
24240
  else {
@@ -25255,7 +25265,7 @@ class ClientPartial {
25255
25265
  * @param backtest - Whether running in backtest mode
25256
25266
  * @returns Unique string key for memoization
25257
25267
  */
25258
- const CREATE_KEY_FN$i = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
25268
+ const CREATE_KEY_FN$j = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
25259
25269
  /**
25260
25270
  * Creates a callback function for emitting profit events to partialProfitSubject.
25261
25271
  *
@@ -25377,7 +25387,7 @@ class PartialConnectionService {
25377
25387
  * Key format: "signalId:backtest" or "signalId:live"
25378
25388
  * Value: ClientPartial instance with logger and event emitters
25379
25389
  */
25380
- this.getPartial = memoize(([signalId, backtest]) => CREATE_KEY_FN$i(signalId, backtest), (signalId, backtest) => {
25390
+ this.getPartial = memoize(([signalId, backtest]) => CREATE_KEY_FN$j(signalId, backtest), (signalId, backtest) => {
25381
25391
  return new ClientPartial({
25382
25392
  signalId,
25383
25393
  logger: this.loggerService,
@@ -25467,7 +25477,7 @@ class PartialConnectionService {
25467
25477
  const partial = this.getPartial(data.id, backtest);
25468
25478
  await partial.waitForInit(symbol, data.strategyName, data.exchangeName, backtest);
25469
25479
  await partial.clear(symbol, data, priceClose, backtest);
25470
- const key = CREATE_KEY_FN$i(data.id, backtest);
25480
+ const key = CREATE_KEY_FN$j(data.id, backtest);
25471
25481
  this.getPartial.clear(key);
25472
25482
  };
25473
25483
  }
@@ -25483,7 +25493,7 @@ class PartialConnectionService {
25483
25493
  * @param backtest - Whether running in backtest mode
25484
25494
  * @returns Unique string key for memoization
25485
25495
  */
25486
- const CREATE_KEY_FN$h = (symbol, strategyName, exchangeName, frameName, backtest) => {
25496
+ const CREATE_KEY_FN$i = (symbol, strategyName, exchangeName, frameName, backtest) => {
25487
25497
  const parts = [symbol, strategyName, exchangeName];
25488
25498
  if (frameName)
25489
25499
  parts.push(frameName);
@@ -25706,7 +25716,7 @@ class PartialMarkdownService {
25706
25716
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
25707
25717
  * Each combination gets its own isolated storage instance.
25708
25718
  */
25709
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$h(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$6(symbol, strategyName, exchangeName, frameName));
25719
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$i(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$6(symbol, strategyName, exchangeName, frameName));
25710
25720
  /**
25711
25721
  * Subscribes to partial profit/loss signal emitters to receive events.
25712
25722
  * Protected against multiple subscriptions.
@@ -25916,7 +25926,7 @@ class PartialMarkdownService {
25916
25926
  payload,
25917
25927
  });
25918
25928
  if (payload) {
25919
- const key = CREATE_KEY_FN$h(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
25929
+ const key = CREATE_KEY_FN$i(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
25920
25930
  this.getStorage.clear(key);
25921
25931
  }
25922
25932
  else {
@@ -25932,7 +25942,7 @@ class PartialMarkdownService {
25932
25942
  * @param context - Context with strategyName, exchangeName, frameName
25933
25943
  * @returns Unique string key for memoization
25934
25944
  */
25935
- const CREATE_KEY_FN$g = (context) => {
25945
+ const CREATE_KEY_FN$h = (context) => {
25936
25946
  const parts = [context.strategyName, context.exchangeName];
25937
25947
  if (context.frameName)
25938
25948
  parts.push(context.frameName);
@@ -26006,7 +26016,7 @@ class PartialGlobalService {
26006
26016
  * @param context - Context with strategyName, exchangeName and frameName
26007
26017
  * @param methodName - Name of the calling method for error tracking
26008
26018
  */
26009
- this.validate = memoize(([context]) => CREATE_KEY_FN$g(context), (context, methodName) => {
26019
+ this.validate = memoize(([context]) => CREATE_KEY_FN$h(context), (context, methodName) => {
26010
26020
  this.loggerService.log("partialGlobalService validate", {
26011
26021
  context,
26012
26022
  methodName,
@@ -26461,7 +26471,7 @@ class ClientBreakeven {
26461
26471
  * @param backtest - Whether running in backtest mode
26462
26472
  * @returns Unique string key for memoization
26463
26473
  */
26464
- const CREATE_KEY_FN$f = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
26474
+ const CREATE_KEY_FN$g = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
26465
26475
  /**
26466
26476
  * Creates a callback function for emitting breakeven events to breakevenSubject.
26467
26477
  *
@@ -26547,7 +26557,7 @@ class BreakevenConnectionService {
26547
26557
  * Key format: "signalId:backtest" or "signalId:live"
26548
26558
  * Value: ClientBreakeven instance with logger and event emitter
26549
26559
  */
26550
- this.getBreakeven = memoize(([signalId, backtest]) => CREATE_KEY_FN$f(signalId, backtest), (signalId, backtest) => {
26560
+ this.getBreakeven = memoize(([signalId, backtest]) => CREATE_KEY_FN$g(signalId, backtest), (signalId, backtest) => {
26551
26561
  return new ClientBreakeven({
26552
26562
  signalId,
26553
26563
  logger: this.loggerService,
@@ -26608,7 +26618,7 @@ class BreakevenConnectionService {
26608
26618
  const breakeven = this.getBreakeven(data.id, backtest);
26609
26619
  await breakeven.waitForInit(symbol, data.strategyName, data.exchangeName, backtest);
26610
26620
  await breakeven.clear(symbol, data, priceClose, backtest);
26611
- const key = CREATE_KEY_FN$f(data.id, backtest);
26621
+ const key = CREATE_KEY_FN$g(data.id, backtest);
26612
26622
  this.getBreakeven.clear(key);
26613
26623
  };
26614
26624
  }
@@ -26624,7 +26634,7 @@ class BreakevenConnectionService {
26624
26634
  * @param backtest - Whether running in backtest mode
26625
26635
  * @returns Unique string key for memoization
26626
26636
  */
26627
- const CREATE_KEY_FN$e = (symbol, strategyName, exchangeName, frameName, backtest) => {
26637
+ const CREATE_KEY_FN$f = (symbol, strategyName, exchangeName, frameName, backtest) => {
26628
26638
  const parts = [symbol, strategyName, exchangeName];
26629
26639
  if (frameName)
26630
26640
  parts.push(frameName);
@@ -26799,7 +26809,7 @@ class BreakevenMarkdownService {
26799
26809
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
26800
26810
  * Each combination gets its own isolated storage instance.
26801
26811
  */
26802
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$e(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$5(symbol, strategyName, exchangeName, frameName));
26812
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$f(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$5(symbol, strategyName, exchangeName, frameName));
26803
26813
  /**
26804
26814
  * Subscribes to breakeven signal emitter to receive events.
26805
26815
  * Protected against multiple subscriptions.
@@ -26988,7 +26998,7 @@ class BreakevenMarkdownService {
26988
26998
  payload,
26989
26999
  });
26990
27000
  if (payload) {
26991
- const key = CREATE_KEY_FN$e(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
27001
+ const key = CREATE_KEY_FN$f(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
26992
27002
  this.getStorage.clear(key);
26993
27003
  }
26994
27004
  else {
@@ -27004,7 +27014,7 @@ class BreakevenMarkdownService {
27004
27014
  * @param context - Context with strategyName, exchangeName, frameName
27005
27015
  * @returns Unique string key for memoization
27006
27016
  */
27007
- const CREATE_KEY_FN$d = (context) => {
27017
+ const CREATE_KEY_FN$e = (context) => {
27008
27018
  const parts = [context.strategyName, context.exchangeName];
27009
27019
  if (context.frameName)
27010
27020
  parts.push(context.frameName);
@@ -27078,7 +27088,7 @@ class BreakevenGlobalService {
27078
27088
  * @param context - Context with strategyName, exchangeName and frameName
27079
27089
  * @param methodName - Name of the calling method for error tracking
27080
27090
  */
27081
- this.validate = memoize(([context]) => CREATE_KEY_FN$d(context), (context, methodName) => {
27091
+ this.validate = memoize(([context]) => CREATE_KEY_FN$e(context), (context, methodName) => {
27082
27092
  this.loggerService.log("breakevenGlobalService validate", {
27083
27093
  context,
27084
27094
  methodName,
@@ -27299,7 +27309,7 @@ class ConfigValidationService {
27299
27309
  * @param backtest - Whether running in backtest mode
27300
27310
  * @returns Unique string key for memoization
27301
27311
  */
27302
- const CREATE_KEY_FN$c = (symbol, strategyName, exchangeName, frameName, backtest) => {
27312
+ const CREATE_KEY_FN$d = (symbol, strategyName, exchangeName, frameName, backtest) => {
27303
27313
  const parts = [symbol, strategyName, exchangeName];
27304
27314
  if (frameName)
27305
27315
  parts.push(frameName);
@@ -27466,7 +27476,7 @@ class RiskMarkdownService {
27466
27476
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
27467
27477
  * Each combination gets its own isolated storage instance.
27468
27478
  */
27469
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$c(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$4(symbol, strategyName, exchangeName, frameName));
27479
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$d(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$4(symbol, strategyName, exchangeName, frameName));
27470
27480
  /**
27471
27481
  * Subscribes to risk rejection emitter to receive rejection events.
27472
27482
  * Protected against multiple subscriptions.
@@ -27655,7 +27665,7 @@ class RiskMarkdownService {
27655
27665
  payload,
27656
27666
  });
27657
27667
  if (payload) {
27658
- const key = CREATE_KEY_FN$c(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
27668
+ const key = CREATE_KEY_FN$d(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
27659
27669
  this.getStorage.clear(key);
27660
27670
  }
27661
27671
  else {
@@ -30037,7 +30047,7 @@ class HighestProfitReportService {
30037
30047
  * @returns Colon-separated key string for memoization
30038
30048
  * @internal
30039
30049
  */
30040
- const CREATE_KEY_FN$b = (symbol, strategyName, exchangeName, frameName, backtest) => {
30050
+ const CREATE_KEY_FN$c = (symbol, strategyName, exchangeName, frameName, backtest) => {
30041
30051
  const parts = [symbol, strategyName, exchangeName];
30042
30052
  if (frameName)
30043
30053
  parts.push(frameName);
@@ -30279,7 +30289,7 @@ class StrategyMarkdownService {
30279
30289
  *
30280
30290
  * @internal
30281
30291
  */
30282
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$b(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$3(symbol, strategyName, exchangeName, frameName));
30292
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$c(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$3(symbol, strategyName, exchangeName, frameName));
30283
30293
  /**
30284
30294
  * Records a cancel-scheduled event when a scheduled signal is cancelled.
30285
30295
  *
@@ -30853,7 +30863,7 @@ class StrategyMarkdownService {
30853
30863
  this.clear = async (payload) => {
30854
30864
  this.loggerService.log("strategyMarkdownService clear", { payload });
30855
30865
  if (payload) {
30856
- const key = CREATE_KEY_FN$b(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
30866
+ const key = CREATE_KEY_FN$c(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
30857
30867
  this.getStorage.clear(key);
30858
30868
  }
30859
30869
  else {
@@ -30961,7 +30971,7 @@ class StrategyMarkdownService {
30961
30971
  * Creates a unique key for memoizing ReportStorage instances.
30962
30972
  * Key format: "symbol:strategyName:exchangeName[:frameName]:backtest|live"
30963
30973
  */
30964
- const CREATE_KEY_FN$a = (symbol, strategyName, exchangeName, frameName, backtest) => {
30974
+ const CREATE_KEY_FN$b = (symbol, strategyName, exchangeName, frameName, backtest) => {
30965
30975
  const parts = [symbol, strategyName, exchangeName];
30966
30976
  if (frameName)
30967
30977
  parts.push(frameName);
@@ -31154,7 +31164,7 @@ let ReportStorage$2 = class ReportStorage {
31154
31164
  class SyncMarkdownService {
31155
31165
  constructor() {
31156
31166
  this.loggerService = inject(TYPES.loggerService);
31157
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$a(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$2(symbol, strategyName, exchangeName, frameName, backtest));
31167
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$b(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$2(symbol, strategyName, exchangeName, frameName, backtest));
31158
31168
  /**
31159
31169
  * Subscribes to `syncSubject` to start receiving `SignalSyncContract` events.
31160
31170
  * Protected against multiple subscriptions via `singleshot` — subsequent calls
@@ -31350,7 +31360,7 @@ class SyncMarkdownService {
31350
31360
  this.clear = async (payload) => {
31351
31361
  this.loggerService.log("syncMarkdownService clear", { payload });
31352
31362
  if (payload) {
31353
- const key = CREATE_KEY_FN$a(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
31363
+ const key = CREATE_KEY_FN$b(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
31354
31364
  this.getStorage.clear(key);
31355
31365
  }
31356
31366
  else {
@@ -31363,7 +31373,7 @@ class SyncMarkdownService {
31363
31373
  /**
31364
31374
  * Creates a unique memoization key for a symbol-strategy-exchange-frame-backtest combination.
31365
31375
  */
31366
- const CREATE_KEY_FN$9 = (symbol, strategyName, exchangeName, frameName, backtest) => {
31376
+ const CREATE_KEY_FN$a = (symbol, strategyName, exchangeName, frameName, backtest) => {
31367
31377
  const parts = [symbol, strategyName, exchangeName];
31368
31378
  if (frameName)
31369
31379
  parts.push(frameName);
@@ -31539,7 +31549,7 @@ let ReportStorage$1 = class ReportStorage {
31539
31549
  class HighestProfitMarkdownService {
31540
31550
  constructor() {
31541
31551
  this.loggerService = inject(TYPES.loggerService);
31542
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$9(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$1(symbol, strategyName, exchangeName, frameName));
31552
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$a(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$1(symbol, strategyName, exchangeName, frameName));
31543
31553
  /**
31544
31554
  * Subscribes to `highestProfitSubject` to start receiving `HighestProfitContract`
31545
31555
  * events. Protected against multiple subscriptions via `singleshot` — subsequent
@@ -31705,7 +31715,7 @@ class HighestProfitMarkdownService {
31705
31715
  this.clear = async (payload) => {
31706
31716
  this.loggerService.log("highestProfitMarkdownService clear", { payload });
31707
31717
  if (payload) {
31708
- const key = CREATE_KEY_FN$9(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
31718
+ const key = CREATE_KEY_FN$a(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
31709
31719
  this.getStorage.clear(key);
31710
31720
  }
31711
31721
  else {
@@ -31727,7 +31737,7 @@ const LISTEN_TIMEOUT$1 = 120000;
31727
31737
  * @param backtest - Whether running in backtest mode
31728
31738
  * @returns Unique string key for memoization
31729
31739
  */
31730
- const CREATE_KEY_FN$8 = (symbol, strategyName, exchangeName, frameName, backtest) => {
31740
+ const CREATE_KEY_FN$9 = (symbol, strategyName, exchangeName, frameName, backtest) => {
31731
31741
  const parts = [symbol, strategyName, exchangeName];
31732
31742
  if (frameName)
31733
31743
  parts.push(frameName);
@@ -31770,7 +31780,7 @@ class PriceMetaService {
31770
31780
  * Each subject holds the latest currentPrice emitted by the strategy iterator for that key.
31771
31781
  * Instances are cached until clear() is called.
31772
31782
  */
31773
- this.getSource = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$8(symbol, strategyName, exchangeName, frameName, backtest), () => new BehaviorSubject());
31783
+ this.getSource = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$9(symbol, strategyName, exchangeName, frameName, backtest), () => new BehaviorSubject());
31774
31784
  /**
31775
31785
  * Returns the current market price for the given symbol and context.
31776
31786
  *
@@ -31799,10 +31809,10 @@ class PriceMetaService {
31799
31809
  if (source.data) {
31800
31810
  return source.data;
31801
31811
  }
31802
- console.warn(`PriceMetaService: No currentPrice available for ${CREATE_KEY_FN$8(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}. Trying to fetch from strategy iterator as a fallback...`);
31812
+ console.warn(`PriceMetaService: No currentPrice available for ${CREATE_KEY_FN$9(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}. Trying to fetch from strategy iterator as a fallback...`);
31803
31813
  const currentPrice = await waitForNext(source, (data) => !!data, LISTEN_TIMEOUT$1);
31804
31814
  if (typeof currentPrice === "symbol") {
31805
- throw new Error(`PriceMetaService: Timeout while waiting for currentPrice for ${CREATE_KEY_FN$8(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}`);
31815
+ throw new Error(`PriceMetaService: Timeout while waiting for currentPrice for ${CREATE_KEY_FN$9(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}`);
31806
31816
  }
31807
31817
  return currentPrice;
31808
31818
  };
@@ -31844,7 +31854,7 @@ class PriceMetaService {
31844
31854
  this.getSource.clear();
31845
31855
  return;
31846
31856
  }
31847
- const key = CREATE_KEY_FN$8(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
31857
+ const key = CREATE_KEY_FN$9(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
31848
31858
  this.getSource.clear(key);
31849
31859
  };
31850
31860
  }
@@ -31862,7 +31872,7 @@ const LISTEN_TIMEOUT = 120000;
31862
31872
  * @param backtest - Whether running in backtest mode
31863
31873
  * @returns Unique string key for memoization
31864
31874
  */
31865
- const CREATE_KEY_FN$7 = (symbol, strategyName, exchangeName, frameName, backtest) => {
31875
+ const CREATE_KEY_FN$8 = (symbol, strategyName, exchangeName, frameName, backtest) => {
31866
31876
  const parts = [symbol, strategyName, exchangeName];
31867
31877
  if (frameName)
31868
31878
  parts.push(frameName);
@@ -31905,7 +31915,7 @@ class TimeMetaService {
31905
31915
  * Each subject holds the latest createdAt timestamp emitted by the strategy iterator for that key.
31906
31916
  * Instances are cached until clear() is called.
31907
31917
  */
31908
- this.getSource = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$7(symbol, strategyName, exchangeName, frameName, backtest), () => new BehaviorSubject());
31918
+ this.getSource = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$8(symbol, strategyName, exchangeName, frameName, backtest), () => new BehaviorSubject());
31909
31919
  /**
31910
31920
  * Returns the current candle timestamp (in milliseconds) for the given symbol and context.
31911
31921
  *
@@ -31933,10 +31943,10 @@ class TimeMetaService {
31933
31943
  if (source.data) {
31934
31944
  return source.data;
31935
31945
  }
31936
- console.warn(`TimeMetaService: No timestamp available for ${CREATE_KEY_FN$7(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}. Trying to fetch from strategy iterator as a fallback...`);
31946
+ console.warn(`TimeMetaService: No timestamp available for ${CREATE_KEY_FN$8(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}. Trying to fetch from strategy iterator as a fallback...`);
31937
31947
  const timestamp = await waitForNext(source, (data) => !!data, LISTEN_TIMEOUT);
31938
31948
  if (typeof timestamp === "symbol") {
31939
- throw new Error(`TimeMetaService: Timeout while waiting for timestamp for ${CREATE_KEY_FN$7(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}`);
31949
+ throw new Error(`TimeMetaService: Timeout while waiting for timestamp for ${CREATE_KEY_FN$8(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}`);
31940
31950
  }
31941
31951
  return timestamp;
31942
31952
  };
@@ -31978,7 +31988,7 @@ class TimeMetaService {
31978
31988
  this.getSource.clear();
31979
31989
  return;
31980
31990
  }
31981
- const key = CREATE_KEY_FN$7(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
31991
+ const key = CREATE_KEY_FN$8(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
31982
31992
  this.getSource.clear(key);
31983
31993
  };
31984
31994
  }
@@ -32074,7 +32084,7 @@ class MaxDrawdownReportService {
32074
32084
  /**
32075
32085
  * Creates a unique memoization key for a symbol-strategy-exchange-frame-backtest combination.
32076
32086
  */
32077
- const CREATE_KEY_FN$6 = (symbol, strategyName, exchangeName, frameName, backtest) => {
32087
+ const CREATE_KEY_FN$7 = (symbol, strategyName, exchangeName, frameName, backtest) => {
32078
32088
  const parts = [symbol, strategyName, exchangeName];
32079
32089
  if (frameName)
32080
32090
  parts.push(frameName);
@@ -32198,7 +32208,7 @@ class ReportStorage {
32198
32208
  class MaxDrawdownMarkdownService {
32199
32209
  constructor() {
32200
32210
  this.loggerService = inject(TYPES.loggerService);
32201
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$6(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage(symbol, strategyName, exchangeName, frameName));
32211
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$7(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage(symbol, strategyName, exchangeName, frameName));
32202
32212
  /**
32203
32213
  * Subscribes to `maxDrawdownSubject` to start receiving `MaxDrawdownContract`
32204
32214
  * events. Protected against multiple subscriptions via `singleshot`.
@@ -32277,7 +32287,7 @@ class MaxDrawdownMarkdownService {
32277
32287
  this.clear = async (payload) => {
32278
32288
  this.loggerService.log("maxDrawdownMarkdownService clear", { payload });
32279
32289
  if (payload) {
32280
- const key = CREATE_KEY_FN$6(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
32290
+ const key = CREATE_KEY_FN$7(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
32281
32291
  this.getStorage.clear(key);
32282
32292
  }
32283
32293
  else {
@@ -32287,6 +32297,125 @@ class MaxDrawdownMarkdownService {
32287
32297
  }
32288
32298
  }
32289
32299
 
32300
+ const METHOD_NAME_COMMIT_SIGNAL_NOTIFY = "notificationHelperService.commitSignalNotify";
32301
+ const METHOD_NAME_VALIDATE = "notificationHelperService.validate";
32302
+ /**
32303
+ * Creates a unique key for memoizing validate calls.
32304
+ * Key format: "strategyName:exchangeName:frameName"
32305
+ * @param context - Execution context with strategyName, exchangeName, frameName
32306
+ * @returns Unique string key for memoization
32307
+ */
32308
+ const CREATE_KEY_FN$6 = (context) => {
32309
+ const parts = [context.strategyName, context.exchangeName];
32310
+ if (context.frameName)
32311
+ parts.push(context.frameName);
32312
+ return parts.join(":");
32313
+ };
32314
+ /**
32315
+ * Helper service for emitting signal info notifications.
32316
+ *
32317
+ * Handles validation (memoized per context) and emission of `signal.info` events
32318
+ * via `signalNotifySubject`. Used internally by the framework action pipeline —
32319
+ * end users interact with this via `commitSignalNotify()` in `onActivePing` callbacks.
32320
+ */
32321
+ class NotificationHelperService {
32322
+ constructor() {
32323
+ this.loggerService = inject(TYPES.loggerService);
32324
+ this.strategySchemaService = inject(TYPES.strategySchemaService);
32325
+ this.riskValidationService = inject(TYPES.riskValidationService);
32326
+ this.strategyValidationService = inject(TYPES.strategyValidationService);
32327
+ this.exchangeValidationService = inject(TYPES.exchangeValidationService);
32328
+ this.frameValidationService = inject(TYPES.frameValidationService);
32329
+ this.actionValidationService = inject(TYPES.actionValidationService);
32330
+ this.strategyCoreService = inject(TYPES.strategyCoreService);
32331
+ this.timeMetaService = inject(TYPES.timeMetaService);
32332
+ /**
32333
+ * Validates strategy, exchange, frame, risk, and action schemas for the given context.
32334
+ *
32335
+ * Memoized per unique `"strategyName:exchangeName[:frameName]"` key — subsequent calls
32336
+ * with the same context are no-ops, so validation runs at most once per context.
32337
+ *
32338
+ * @param context - Routing context: strategyName, exchangeName, frameName
32339
+ * @throws {Error} If any registered schema fails validation
32340
+ */
32341
+ this.validate = memoize(([context]) => CREATE_KEY_FN$6(context), async (context) => {
32342
+ this.loggerService.log(METHOD_NAME_VALIDATE, {
32343
+ context,
32344
+ });
32345
+ this.strategyValidationService.validate(context.strategyName, METHOD_NAME_VALIDATE);
32346
+ this.exchangeValidationService.validate(context.exchangeName, METHOD_NAME_VALIDATE);
32347
+ const { riskName, riskList, actions } = this.strategySchemaService.get(context.strategyName);
32348
+ context.frameName &&
32349
+ this.frameValidationService.validate(context.frameName, METHOD_NAME_VALIDATE);
32350
+ riskName &&
32351
+ this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE);
32352
+ riskList &&
32353
+ riskList.forEach((riskName) => this.riskValidationService.validate(riskName, METHOD_NAME_VALIDATE));
32354
+ actions &&
32355
+ actions.forEach((actionName) => this.actionValidationService.validate(actionName, METHOD_NAME_VALIDATE));
32356
+ });
32357
+ /**
32358
+ * Emits a `signal.info` notification for the currently active pending signal.
32359
+ *
32360
+ * Validates all schemas (via memoized `validate`), resolves the pending signal
32361
+ * for the given symbol, then emits a `SignalInfoContract` via `signalNotifySubject`,
32362
+ * which is routed to all registered `listenSignalNotify` callbacks and persisted
32363
+ * by `NotificationAdapter`.
32364
+ *
32365
+ * @param payload - Optional notification fields (notificationId, notificationNote)
32366
+ * @param symbol - Trading pair symbol (e.g. "BTCUSDT")
32367
+ * @param currentPrice - Market price at the time of the call
32368
+ * @param context - Routing context: strategyName, exchangeName, frameName
32369
+ * @param backtest - true when called during a backtest run
32370
+ *
32371
+ * @throws {Error} If no active pending signal is found for the given symbol
32372
+ *
32373
+ * @example
32374
+ * ```typescript
32375
+ * // Inside onActivePing callback:
32376
+ * await commitSignalNotify("BTCUSDT", {
32377
+ * notificationNote: "RSI crossed 70, consider closing",
32378
+ * notificationId: "msg-123",
32379
+ * });
32380
+ * ```
32381
+ */
32382
+ this.commitSignalNotify = async (payload, symbol, currentPrice, context, backtest) => {
32383
+ this.loggerService.info(METHOD_NAME_COMMIT_SIGNAL_NOTIFY, {
32384
+ symbol,
32385
+ context,
32386
+ backtest,
32387
+ currentPrice,
32388
+ });
32389
+ this.validate(context);
32390
+ const pendingSignal = await this.strategyCoreService.getPendingSignal(backtest, symbol, currentPrice, {
32391
+ strategyName: context.strategyName,
32392
+ exchangeName: context.exchangeName,
32393
+ frameName: "",
32394
+ });
32395
+ if (!pendingSignal) {
32396
+ throw new Error(`SignalUtils notify No pending signal found symbol=${symbol} `);
32397
+ }
32398
+ const timestamp = await this.timeMetaService.getTimestamp(symbol, {
32399
+ strategyName: context.strategyName,
32400
+ exchangeName: context.exchangeName,
32401
+ frameName: context.frameName,
32402
+ }, backtest);
32403
+ await signalNotifySubject.next({
32404
+ backtest,
32405
+ symbol,
32406
+ currentPrice,
32407
+ data: pendingSignal,
32408
+ exchangeName: context.exchangeName,
32409
+ strategyName: context.strategyName,
32410
+ frameName: context.frameName,
32411
+ note: payload.notificationNote || pendingSignal.note,
32412
+ notificationId: payload.notificationId,
32413
+ timestamp,
32414
+ });
32415
+ };
32416
+ }
32417
+ }
32418
+
32290
32419
  {
32291
32420
  provide(TYPES.loggerService, () => new LoggerService());
32292
32421
  }
@@ -32375,6 +32504,9 @@ class MaxDrawdownMarkdownService {
32375
32504
  provide(TYPES.highestProfitReportService, () => new HighestProfitReportService());
32376
32505
  provide(TYPES.maxDrawdownReportService, () => new MaxDrawdownReportService());
32377
32506
  }
32507
+ {
32508
+ provide(TYPES.notificationHelperService, () => new NotificationHelperService());
32509
+ }
32378
32510
  {
32379
32511
  provide(TYPES.exchangeValidationService, () => new ExchangeValidationService());
32380
32512
  provide(TYPES.strategyValidationService, () => new StrategyValidationService());
@@ -32475,6 +32607,9 @@ const reportServices = {
32475
32607
  highestProfitReportService: inject(TYPES.highestProfitReportService),
32476
32608
  maxDrawdownReportService: inject(TYPES.maxDrawdownReportService),
32477
32609
  };
32610
+ const helperServices = {
32611
+ notificationHelperService: inject(TYPES.notificationHelperService),
32612
+ };
32478
32613
  const validationServices = {
32479
32614
  exchangeValidationService: inject(TYPES.exchangeValidationService),
32480
32615
  strategyValidationService: inject(TYPES.strategyValidationService),
@@ -32500,6 +32635,7 @@ const backtest = {
32500
32635
  ...markdownServices,
32501
32636
  ...reportServices,
32502
32637
  ...validationServices,
32638
+ ...helperServices,
32503
32639
  };
32504
32640
  init();
32505
32641
 
@@ -35416,6 +35552,7 @@ const GET_POSITION_ENTRY_OVERLAP_METHOD_NAME = "strategy.getPositionEntryOverlap
35416
35552
  const GET_POSITION_PARTIAL_OVERLAP_METHOD_NAME = "strategy.getPositionPartialOverlap";
35417
35553
  const HAS_NO_PENDING_SIGNAL_METHOD_NAME = "strategy.hasNoPendingSignal";
35418
35554
  const HAS_NO_SCHEDULED_SIGNAL_METHOD_NAME = "strategy.hasNoScheduledSignal";
35555
+ const COMMIT_SIGNAL_NOTIFY_METHOD_NAME = "strategy.commitSignalNotify";
35419
35556
  /**
35420
35557
  * Cancels the scheduled signal without stopping the strategy.
35421
35558
  *
@@ -37380,6 +37517,50 @@ async function hasNoScheduledSignal(symbol) {
37380
37517
  const { exchangeName, frameName, strategyName } = backtest.methodContextService.context;
37381
37518
  return await not(backtest.strategyCoreService.hasScheduledSignal(isBacktest, symbol, { exchangeName, frameName, strategyName }));
37382
37519
  }
37520
+ /**
37521
+ * Emits a `signal.info` notification for the currently active pending signal.
37522
+ *
37523
+ * Broadcasts a user-defined informational note without affecting position state.
37524
+ * Useful for annotating strategy decisions, triggering external alerts, or logging
37525
+ * mid-position events (e.g. RSI crossing a threshold, volume spike detected).
37526
+ *
37527
+ * Automatically reads backtest/live mode from execution context.
37528
+ * Automatically reads strategyName, exchangeName, frameName from method context.
37529
+ * Automatically fetches current price via getAveragePrice.
37530
+ *
37531
+ * @param symbol - Trading pair symbol (e.g. "BTCUSDT")
37532
+ * @param payload - Optional notification fields
37533
+ * @param payload.notificationNote - Human-readable note. Falls back to signal.note if omitted.
37534
+ * @param payload.notificationId - Optional correlation ID for external systems (e.g. Telegram message ID).
37535
+ *
37536
+ * @throws {Error} If called outside an execution context
37537
+ * @throws {Error} If called outside a method context
37538
+ * @throws {Error} If no active pending signal exists for the given symbol
37539
+ *
37540
+ * @example
37541
+ * ```typescript
37542
+ * import { commitSignalNotify } from "backtest-kit";
37543
+ *
37544
+ * // Inside onActivePing callback:
37545
+ * await commitSignalNotify("BTCUSDT", {
37546
+ * notificationNote: "RSI crossed 70, consider closing",
37547
+ * notificationId: "msg-123",
37548
+ * });
37549
+ * ```
37550
+ */
37551
+ async function commitSignalNotify(symbol, payload = {}) {
37552
+ backtest.loggerService.info(COMMIT_SIGNAL_NOTIFY_METHOD_NAME, { symbol, payload });
37553
+ if (!ExecutionContextService.hasContext()) {
37554
+ throw new Error("commitSignalNotify requires an execution context");
37555
+ }
37556
+ if (!MethodContextService.hasContext()) {
37557
+ throw new Error("commitSignalNotify requires a method context");
37558
+ }
37559
+ const currentPrice = await getAveragePrice(symbol);
37560
+ const { backtest: isBacktest } = backtest.executionContextService.context;
37561
+ const { exchangeName, frameName, strategyName } = backtest.methodContextService.context;
37562
+ await backtest.notificationHelperService.commitSignalNotify(payload, symbol, currentPrice, { strategyName, exchangeName, frameName }, isBacktest);
37563
+ }
37383
37564
 
37384
37565
  const STOP_STRATEGY_METHOD_NAME = "control.stopStrategy";
37385
37566
  /**
@@ -37463,6 +37644,8 @@ const LISTEN_HIGHEST_PROFIT_METHOD_NAME = "event.listenHighestProfit";
37463
37644
  const LISTEN_HIGHEST_PROFIT_ONCE_METHOD_NAME = "event.listenHighestProfitOnce";
37464
37645
  const LISTEN_MAX_DRAWDOWN_METHOD_NAME = "event.listenMaxDrawdown";
37465
37646
  const LISTEN_MAX_DRAWDOWN_ONCE_METHOD_NAME = "event.listenMaxDrawdownOnce";
37647
+ const LISTEN_SIGNAL_NOTIFY_METHOD_NAME = "event.listenSignalNotify";
37648
+ const LISTEN_SIGNAL_NOTIFY_ONCE_METHOD_NAME = "event.listenSignalNotifyOnce";
37466
37649
  /**
37467
37650
  * Subscribes to all signal events with queued async processing.
37468
37651
  *
@@ -38854,6 +39037,46 @@ function listenMaxDrawdownOnce(filterFn, fn) {
38854
39037
  };
38855
39038
  return disposeFn = listenMaxDrawdown(wrappedFn);
38856
39039
  }
39040
+ /**
39041
+ * Subscribes to signal info events with queued async processing.
39042
+ * Emits when a strategy calls commitSignalInfo() to broadcast a user-defined note for an open position.
39043
+ * Events are processed sequentially in order received, even if callback is async.
39044
+ * Uses queued wrapper to prevent concurrent execution of the callback.
39045
+ * @param fn - Callback function to handle signal info events
39046
+ * @return Unsubscribe function to stop listening to events
39047
+ */
39048
+ function listenSignalNotify(fn) {
39049
+ backtest.loggerService.log(LISTEN_SIGNAL_NOTIFY_METHOD_NAME);
39050
+ const wrappedFn = async (event) => {
39051
+ if (await backtest.strategyCoreService.hasPendingSignal(event.backtest, event.symbol, {
39052
+ strategyName: event.strategyName,
39053
+ exchangeName: event.exchangeName,
39054
+ frameName: event.frameName,
39055
+ })) {
39056
+ await fn(event);
39057
+ }
39058
+ };
39059
+ return signalNotifySubject.subscribe(queued(wrappedFn));
39060
+ }
39061
+ /**
39062
+ * Subscribes to filtered signal info events with one-time execution.
39063
+ * Listens for events matching the filter predicate, then executes callback once
39064
+ * and automatically unsubscribes.
39065
+ * @param filterFn - Predicate to filter which events trigger the callback
39066
+ * @param fn - Callback function to handle the filtered event (called only once)
39067
+ * @return Unsubscribe function to cancel the listener before it fires
39068
+ */
39069
+ function listenSignalNotifyOnce(filterFn, fn) {
39070
+ backtest.loggerService.log(LISTEN_SIGNAL_NOTIFY_ONCE_METHOD_NAME);
39071
+ let disposeFn;
39072
+ const wrappedFn = async (event) => {
39073
+ if (filterFn(event)) {
39074
+ await fn(event);
39075
+ disposeFn && disposeFn();
39076
+ }
39077
+ };
39078
+ return disposeFn = listenSignalNotify(wrappedFn);
39079
+ }
38857
39080
 
38858
39081
  const BACKTEST_METHOD_NAME_RUN = "BacktestUtils.run";
38859
39082
  const BACKTEST_METHOD_NAME_BACKGROUND = "BacktestUtils.background";
@@ -38910,6 +39133,7 @@ const BACKTEST_METHOD_NAME_TRAILING_STOP_COST = "BacktestUtils.commitTrailingSto
38910
39133
  const BACKTEST_METHOD_NAME_TRAILING_PROFIT_COST = "BacktestUtils.commitTrailingTakeCost";
38911
39134
  const BACKTEST_METHOD_NAME_ACTIVATE_SCHEDULED = "Backtest.commitActivateScheduled";
38912
39135
  const BACKTEST_METHOD_NAME_AVERAGE_BUY = "Backtest.commitAverageBuy";
39136
+ const BACKTEST_METHOD_NAME_SIGNAL_NOTIFY = "Backtest.commitSignalNotify";
38913
39137
  const BACKTEST_METHOD_NAME_GET_DATA = "BacktestUtils.getData";
38914
39138
  const BACKTEST_METHOD_NAME_HAS_NO_PENDING_SIGNAL = "BacktestUtils.hasNoPendingSignal";
38915
39139
  const BACKTEST_METHOD_NAME_HAS_NO_SCHEDULED_SIGNAL = "BacktestUtils.hasNoScheduledSignal";
@@ -41265,6 +41489,33 @@ class BacktestUtils {
41265
41489
  });
41266
41490
  return await backtest.strategyCoreService.averageBuy(true, symbol, currentPrice, context, cost);
41267
41491
  };
41492
+ /**
41493
+ * Emits a `signal.info` notification for the currently active pending signal.
41494
+ *
41495
+ * @param symbol - Trading pair symbol
41496
+ * @param currentPrice - Market price at the time of the call
41497
+ * @param context - Execution context with strategyName, exchangeName, frameName
41498
+ * @param payload - Optional notification fields (notificationNote, notificationId)
41499
+ *
41500
+ * @throws {Error} If no active pending signal exists for the given symbol
41501
+ *
41502
+ * @example
41503
+ * ```typescript
41504
+ * await Backtest.commitSignalNotify("BTCUSDT", 42000, {
41505
+ * strategyName: "my-strategy",
41506
+ * exchangeName: "binance",
41507
+ * frameName: "1h"
41508
+ * }, { notificationNote: "RSI crossed 70" });
41509
+ * ```
41510
+ */
41511
+ this.commitSignalNotify = async (symbol, currentPrice, context, payload = {}) => {
41512
+ backtest.loggerService.info(BACKTEST_METHOD_NAME_SIGNAL_NOTIFY, {
41513
+ symbol,
41514
+ currentPrice,
41515
+ context,
41516
+ });
41517
+ await backtest.notificationHelperService.commitSignalNotify(payload, symbol, currentPrice, context, true);
41518
+ };
41268
41519
  /**
41269
41520
  * Gets statistical data from all closed signals for a symbol-strategy pair.
41270
41521
  *
@@ -41478,6 +41729,7 @@ const LIVE_METHOD_NAME_TRAILING_STOP_COST = "LiveUtils.commitTrailingStopCost";
41478
41729
  const LIVE_METHOD_NAME_TRAILING_PROFIT_COST = "LiveUtils.commitTrailingTakeCost";
41479
41730
  const LIVE_METHOD_NAME_ACTIVATE_SCHEDULED = "Live.commitActivateScheduled";
41480
41731
  const LIVE_METHOD_NAME_AVERAGE_BUY = "Live.commitAverageBuy";
41732
+ const LIVE_METHOD_NAME_SIGNAL_NOTIFY = "Live.commitSignalNotify";
41481
41733
  const LIVE_METHOD_NAME_HAS_NO_PENDING_SIGNAL = "LiveUtils.hasNoPendingSignal";
41482
41734
  const LIVE_METHOD_NAME_HAS_NO_SCHEDULED_SIGNAL = "LiveUtils.hasNoScheduledSignal";
41483
41735
  /**
@@ -44174,6 +44426,36 @@ class LiveUtils {
44174
44426
  frameName: "",
44175
44427
  }, cost);
44176
44428
  };
44429
+ /**
44430
+ * Emits a `signal.info` notification for the currently active pending signal.
44431
+ *
44432
+ * @param symbol - Trading pair symbol
44433
+ * @param currentPrice - Market price at the time of the call
44434
+ * @param context - Execution context with strategyName and exchangeName
44435
+ * @param payload - Optional notification fields (notificationNote, notificationId)
44436
+ *
44437
+ * @throws {Error} If no active pending signal exists for the given symbol
44438
+ *
44439
+ * @example
44440
+ * ```typescript
44441
+ * await Live.commitSignalNotify("BTCUSDT", 42000, {
44442
+ * strategyName: "my-strategy",
44443
+ * exchangeName: "binance",
44444
+ * }, { notificationNote: "RSI crossed 70" });
44445
+ * ```
44446
+ */
44447
+ this.commitSignalNotify = async (symbol, currentPrice, context, payload = {}) => {
44448
+ backtest.loggerService.info(LIVE_METHOD_NAME_SIGNAL_NOTIFY, {
44449
+ symbol,
44450
+ currentPrice,
44451
+ context,
44452
+ });
44453
+ await backtest.notificationHelperService.commitSignalNotify(payload, symbol, currentPrice, {
44454
+ strategyName: context.strategyName,
44455
+ exchangeName: context.exchangeName,
44456
+ frameName: "",
44457
+ }, false);
44458
+ };
44177
44459
  /**
44178
44460
  * Gets statistical data from all live trading events for a symbol-strategy pair.
44179
44461
  *
@@ -48368,6 +48650,87 @@ class MarkdownUtils {
48368
48650
  backtest.maxDrawdownMarkdownService.unsubscribe();
48369
48651
  }
48370
48652
  };
48653
+ /**
48654
+ * Clears markdown report data selectively.
48655
+ *
48656
+ * Clears accumulated data for specified markdown services without unsubscribing.
48657
+ * Use this method to reset report data for specific services while keeping them active.
48658
+ *
48659
+ * Each cleared service will:
48660
+ * - Clear accumulated data for all reports
48661
+ * - Start fresh with new data for future events
48662
+ * - Not affect event subscriptions or report generation status
48663
+ *
48664
+ * @param config - Service configuration object specifying which services to clear. Defaults to clearing all services.
48665
+ * @param config.backtest - Clear backtest result report data
48666
+ * @param config.breakeven - Clear breakeven event tracking data
48667
+ * @param config.partial - Clear partial profit/loss event tracking data
48668
+ * @param config.heat - Clear portfolio heatmap analysis data
48669
+ * @param config.walker - Clear walker strategy comparison report data
48670
+ * @param config.performance - Clear performance bottleneck analysis data
48671
+ * @param config.risk - Clear risk rejection tracking data
48672
+ * @param config.schedule - Clear scheduled signal tracking data
48673
+ * @param config.live - Clear live trading event report data
48674
+ * @param config.strategy - Clear strategy report data
48675
+ * @param config.sync - Clear sync report data
48676
+ * @param config.highest_profit - Clear highest profit report data
48677
+ * @param config.max_drawdown - Clear max drawdown report data
48678
+ */
48679
+ this.clear = ({ backtest: bt = false, breakeven = false, heat = false, live = false, partial = false, performance = false, risk = false, strategy = false, schedule = false, walker = false, sync = false, highest_profit = false, max_drawdown = false, } = WILDCARD_TARGET) => {
48680
+ LOGGER_SERVICE$1.debug(MARKDOWN_METHOD_NAME_CLEAR, {
48681
+ backtest: bt,
48682
+ breakeven,
48683
+ heat,
48684
+ live,
48685
+ partial,
48686
+ performance,
48687
+ risk,
48688
+ strategy,
48689
+ schedule,
48690
+ walker,
48691
+ sync,
48692
+ highest_profit,
48693
+ });
48694
+ if (bt) {
48695
+ backtest.backtestMarkdownService.clear();
48696
+ }
48697
+ if (breakeven) {
48698
+ backtest.breakevenMarkdownService.clear();
48699
+ }
48700
+ if (heat) {
48701
+ backtest.heatMarkdownService.clear();
48702
+ }
48703
+ if (live) {
48704
+ backtest.liveMarkdownService.clear();
48705
+ }
48706
+ if (partial) {
48707
+ backtest.partialMarkdownService.clear();
48708
+ }
48709
+ if (performance) {
48710
+ backtest.performanceMarkdownService.clear();
48711
+ }
48712
+ if (risk) {
48713
+ backtest.riskMarkdownService.clear();
48714
+ }
48715
+ if (strategy) {
48716
+ backtest.strategyMarkdownService.clear();
48717
+ }
48718
+ if (schedule) {
48719
+ backtest.scheduleMarkdownService.clear();
48720
+ }
48721
+ if (walker) {
48722
+ backtest.walkerMarkdownService.clear();
48723
+ }
48724
+ if (sync) {
48725
+ backtest.syncMarkdownService.clear();
48726
+ }
48727
+ if (highest_profit) {
48728
+ backtest.highestProfitMarkdownService.clear();
48729
+ }
48730
+ if (max_drawdown) {
48731
+ backtest.maxDrawdownMarkdownService.clear();
48732
+ }
48733
+ };
48371
48734
  }
48372
48735
  }
48373
48736
  /**
@@ -48410,15 +48773,6 @@ class MarkdownAdapter extends MarkdownUtils {
48410
48773
  LOGGER_SERVICE$1.debug(MARKDOWN_METHOD_NAME_USE_JSONL);
48411
48774
  MarkdownWriter.useJsonl();
48412
48775
  }
48413
- /**
48414
- * Clears the memoized storage cache.
48415
- * Call this when process.cwd() changes between strategy iterations
48416
- * so new storage instances are created with the updated base path.
48417
- */
48418
- clear() {
48419
- LOGGER_SERVICE$1.log(MARKDOWN_METHOD_NAME_CLEAR);
48420
- MarkdownWriter.clear();
48421
- }
48422
48776
  /**
48423
48777
  * Switches to a dummy markdown adapter that discards all writes.
48424
48778
  * All future markdown writes will be no-ops.
@@ -49115,6 +49469,7 @@ const SUBJECT_ISOLATION_LIST = [
49115
49469
  strategyCommitSubject,
49116
49470
  syncSubject,
49117
49471
  validationSubject,
49472
+ signalNotifySubject,
49118
49473
  ];
49119
49474
  /**
49120
49475
  * Creates a snapshot function for a given subject by clearing its internal
@@ -53960,7 +54315,44 @@ const CREATE_VALIDATION_ERROR_NOTIFICATION_FN = (error) => ({
53960
54315
  message: getErrorMessage(error),
53961
54316
  backtest: false,
53962
54317
  });
54318
+ /**
54319
+ * Creates a notification model for signal info events.
54320
+ * @param data - The signal info contract data
54321
+ * @returns NotificationModel for signal info event
54322
+ */
54323
+ const CREATE_SIGNAL_INFO_NOTIFICATION_FN = (data) => ({
54324
+ type: "signal.info",
54325
+ id: CREATE_KEY_FN$2(),
54326
+ timestamp: data.timestamp,
54327
+ backtest: data.backtest,
54328
+ symbol: data.symbol,
54329
+ strategyName: data.strategyName,
54330
+ exchangeName: data.exchangeName,
54331
+ signalId: data.data.id,
54332
+ currentPrice: data.currentPrice,
54333
+ position: data.data.position,
54334
+ priceOpen: data.data.priceOpen,
54335
+ priceTakeProfit: data.data.priceTakeProfit,
54336
+ priceStopLoss: data.data.priceStopLoss,
54337
+ originalPriceTakeProfit: data.data.originalPriceTakeProfit,
54338
+ originalPriceStopLoss: data.data.originalPriceStopLoss,
54339
+ originalPriceOpen: data.data.originalPriceOpen,
54340
+ totalEntries: data.data.totalEntries,
54341
+ totalPartials: data.data.totalPartials,
54342
+ pnl: data.data.pnl,
54343
+ pnlPercentage: data.data.pnl.pnlPercentage,
54344
+ pnlPriceOpen: data.data.pnl.priceOpen,
54345
+ pnlPriceClose: data.data.pnl.priceClose,
54346
+ pnlCost: data.data.pnl.pnlCost,
54347
+ pnlEntries: data.data.pnl.pnlEntries,
54348
+ note: data.note,
54349
+ notificationId: data.notificationId,
54350
+ scheduledAt: data.data.scheduledAt,
54351
+ pendingAt: data.data.pendingAt,
54352
+ createdAt: data.timestamp,
54353
+ });
53963
54354
  const NOTIFICATION_MEMORY_BACKTEST_METHOD_NAME_HANDLE_SIGNAL = "NotificationMemoryBacktestUtils.handleSignal";
54355
+ const NOTIFICATION_MEMORY_BACKTEST_METHOD_NAME_HANDLE_SIGNAL_NOTIFY = "NotificationMemoryBacktestUtils.handleSignalNotify";
53964
54356
  const NOTIFICATION_MEMORY_BACKTEST_METHOD_NAME_HANDLE_PARTIAL_PROFIT = "NotificationMemoryBacktestUtils.handlePartialProfit";
53965
54357
  const NOTIFICATION_MEMORY_BACKTEST_METHOD_NAME_HANDLE_PARTIAL_LOSS = "NotificationMemoryBacktestUtils.handlePartialLoss";
53966
54358
  const NOTIFICATION_MEMORY_BACKTEST_METHOD_NAME_HANDLE_BREAKEVEN = "NotificationMemoryBacktestUtils.handleBreakeven";
@@ -53973,6 +54365,7 @@ const NOTIFICATION_MEMORY_BACKTEST_METHOD_NAME_HANDLE_VALIDATION_ERROR = "Notifi
53973
54365
  const NOTIFICATION_MEMORY_BACKTEST_METHOD_NAME_GET_DATA = "NotificationMemoryBacktestUtils.getData";
53974
54366
  const NOTIFICATION_MEMORY_BACKTEST_METHOD_NAME_DISPOSE = "NotificationMemoryBacktestUtils.dispose";
53975
54367
  const NOTIFICATION_MEMORY_LIVE_METHOD_NAME_HANDLE_SIGNAL = "NotificationMemoryLiveUtils.handleSignal";
54368
+ const NOTIFICATION_MEMORY_LIVE_METHOD_NAME_HANDLE_SIGNAL_NOTIFY = "NotificationMemoryLiveUtils.handleSignalNotify";
53976
54369
  const NOTIFICATION_MEMORY_LIVE_METHOD_NAME_HANDLE_PARTIAL_PROFIT = "NotificationMemoryLiveUtils.handlePartialProfit";
53977
54370
  const NOTIFICATION_MEMORY_LIVE_METHOD_NAME_HANDLE_PARTIAL_LOSS = "NotificationMemoryLiveUtils.handlePartialLoss";
53978
54371
  const NOTIFICATION_MEMORY_LIVE_METHOD_NAME_HANDLE_BREAKEVEN = "NotificationMemoryLiveUtils.handleBreakeven";
@@ -54001,6 +54394,7 @@ const NOTIFICATION_LIVE_ADAPTER_METHOD_NAME_CLEAR = "NotificationLiveAdapter.cle
54001
54394
  const NOTIFICATION_PERSIST_BACKTEST_METHOD_NAME_WAIT_FOR_INIT = "NotificationPersistBacktestUtils.waitForInit";
54002
54395
  const NOTIFICATION_PERSIST_BACKTEST_METHOD_NAME_UPDATE_NOTIFICATIONS = "NotificationPersistBacktestUtils._updateNotifications";
54003
54396
  const NOTIFICATION_PERSIST_BACKTEST_METHOD_NAME_HANDLE_SIGNAL = "NotificationPersistBacktestUtils.handleSignal";
54397
+ const NOTIFICATION_PERSIST_BACKTEST_METHOD_NAME_HANDLE_SIGNAL_NOTIFY = "NotificationPersistBacktestUtils.handleSignalNotify";
54004
54398
  const NOTIFICATION_PERSIST_BACKTEST_METHOD_NAME_HANDLE_PARTIAL_PROFIT = "NotificationPersistBacktestUtils.handlePartialProfit";
54005
54399
  const NOTIFICATION_PERSIST_BACKTEST_METHOD_NAME_HANDLE_PARTIAL_LOSS = "NotificationPersistBacktestUtils.handlePartialLoss";
54006
54400
  const NOTIFICATION_PERSIST_BACKTEST_METHOD_NAME_HANDLE_BREAKEVEN = "NotificationPersistBacktestUtils.handleBreakeven";
@@ -54015,6 +54409,7 @@ const NOTIFICATION_PERSIST_BACKTEST_METHOD_NAME_DISPOSE = "NotificationPersistBa
54015
54409
  const NOTIFICATION_PERSIST_LIVE_METHOD_NAME_WAIT_FOR_INIT = "NotificationPersistLiveUtils.waitForInit";
54016
54410
  const NOTIFICATION_PERSIST_LIVE_METHOD_NAME_UPDATE_NOTIFICATIONS = "NotificationPersistLiveUtils._updateNotifications";
54017
54411
  const NOTIFICATION_PERSIST_LIVE_METHOD_NAME_HANDLE_SIGNAL = "NotificationPersistLiveUtils.handleSignal";
54412
+ const NOTIFICATION_PERSIST_LIVE_METHOD_NAME_HANDLE_SIGNAL_NOTIFY = "NotificationPersistLiveUtils.handleSignalNotify";
54018
54413
  const NOTIFICATION_PERSIST_LIVE_METHOD_NAME_HANDLE_PARTIAL_PROFIT = "NotificationPersistLiveUtils.handlePartialProfit";
54019
54414
  const NOTIFICATION_PERSIST_LIVE_METHOD_NAME_HANDLE_PARTIAL_LOSS = "NotificationPersistLiveUtils.handlePartialLoss";
54020
54415
  const NOTIFICATION_PERSIST_LIVE_METHOD_NAME_HANDLE_BREAKEVEN = "NotificationPersistLiveUtils.handleBreakeven";
@@ -54057,6 +54452,12 @@ class NotificationMemoryBacktestUtils {
54057
54452
  this._addNotification(notification);
54058
54453
  }
54059
54454
  };
54455
+ this.handleSignalNotify = async (data) => {
54456
+ backtest.loggerService.info(NOTIFICATION_MEMORY_BACKTEST_METHOD_NAME_HANDLE_SIGNAL_NOTIFY, {
54457
+ signalId: data.data.id,
54458
+ });
54459
+ this._addNotification(CREATE_SIGNAL_INFO_NOTIFICATION_FN(data));
54460
+ };
54060
54461
  /**
54061
54462
  * Handles partial profit availability event.
54062
54463
  * @param data - The partial profit contract data
@@ -54201,6 +54602,8 @@ class NotificationDummyBacktestUtils {
54201
54602
  */
54202
54603
  this.handleSignal = async () => {
54203
54604
  };
54605
+ this.handleSignalNotify = async () => {
54606
+ };
54204
54607
  /**
54205
54608
  * No-op handler for partial profit event.
54206
54609
  */
@@ -54308,6 +54711,14 @@ class NotificationPersistBacktestUtils {
54308
54711
  await this._updateNotifications();
54309
54712
  }
54310
54713
  };
54714
+ this.handleSignalNotify = async (data) => {
54715
+ backtest.loggerService.info(NOTIFICATION_PERSIST_BACKTEST_METHOD_NAME_HANDLE_SIGNAL_NOTIFY, {
54716
+ signalId: data.data.id,
54717
+ });
54718
+ await this.waitForInit();
54719
+ this._addNotification(CREATE_SIGNAL_INFO_NOTIFICATION_FN(data));
54720
+ await this._updateNotifications();
54721
+ };
54311
54722
  /**
54312
54723
  * Handles partial profit availability event.
54313
54724
  * @param data - The partial profit contract data
@@ -54509,6 +54920,12 @@ class NotificationMemoryLiveUtils {
54509
54920
  this._addNotification(notification);
54510
54921
  }
54511
54922
  };
54923
+ this.handleSignalNotify = async (data) => {
54924
+ backtest.loggerService.info(NOTIFICATION_MEMORY_LIVE_METHOD_NAME_HANDLE_SIGNAL_NOTIFY, {
54925
+ signalId: data.data.id,
54926
+ });
54927
+ this._addNotification(CREATE_SIGNAL_INFO_NOTIFICATION_FN(data));
54928
+ };
54512
54929
  /**
54513
54930
  * Handles partial profit availability event.
54514
54931
  * @param data - The partial profit contract data
@@ -54653,6 +55070,8 @@ class NotificationDummyLiveUtils {
54653
55070
  */
54654
55071
  this.handleSignal = async () => {
54655
55072
  };
55073
+ this.handleSignalNotify = async () => {
55074
+ };
54656
55075
  /**
54657
55076
  * No-op handler for partial profit event.
54658
55077
  */
@@ -54761,6 +55180,14 @@ class NotificationPersistLiveUtils {
54761
55180
  await this._updateNotifications();
54762
55181
  }
54763
55182
  };
55183
+ this.handleSignalNotify = async (data) => {
55184
+ backtest.loggerService.info(NOTIFICATION_PERSIST_LIVE_METHOD_NAME_HANDLE_SIGNAL_NOTIFY, {
55185
+ signalId: data.data.id,
55186
+ });
55187
+ await this.waitForInit();
55188
+ this._addNotification(CREATE_SIGNAL_INFO_NOTIFICATION_FN(data));
55189
+ await this._updateNotifications();
55190
+ };
54764
55191
  /**
54765
55192
  * Handles partial profit availability event.
54766
55193
  * @param data - The partial profit contract data
@@ -54954,6 +55381,9 @@ class NotificationBacktestAdapter {
54954
55381
  this.handleSignal = async (data) => {
54955
55382
  return await this._notificationBacktestUtils.handleSignal(data);
54956
55383
  };
55384
+ this.handleSignalNotify = async (data) => {
55385
+ return await this._notificationBacktestUtils.handleSignalNotify(data);
55386
+ };
54957
55387
  /**
54958
55388
  * Handles partial profit availability event.
54959
55389
  * Proxies call to the underlying notification adapter.
@@ -55109,6 +55539,9 @@ class NotificationLiveAdapter {
55109
55539
  this.handleSignal = async (data) => {
55110
55540
  return await this._notificationLiveUtils.handleSignal(data);
55111
55541
  };
55542
+ this.handleSignalNotify = async (data) => {
55543
+ return await this._notificationLiveUtils.handleSignalNotify(data);
55544
+ };
55112
55545
  /**
55113
55546
  * Handles partial profit availability event.
55114
55547
  * Proxies call to the underlying notification adapter.
@@ -55287,7 +55720,10 @@ class NotificationAdapter {
55287
55720
  const unBacktestError = errorEmitter.subscribe((error) => NotificationBacktest.handleError(error));
55288
55721
  const unBacktestExit = exitEmitter.subscribe((error) => NotificationBacktest.handleCriticalError(error));
55289
55722
  const unBacktestValidation = validationSubject.subscribe((error) => NotificationBacktest.handleValidationError(error));
55290
- unBacktest = compose(() => unBacktestSignal(), () => unBacktestPartialProfit(), () => unBacktestPartialLoss(), () => unBacktestBreakeven(), () => unBacktestStrategyCommit(), () => unBacktestSync(), () => unBacktestRisk(), () => unBacktestError(), () => unBacktestExit(), () => unBacktestValidation());
55723
+ const unBacktestSignalNotify = signalNotifySubject
55724
+ .filter(({ backtest }) => backtest)
55725
+ .connect((data) => NotificationBacktest.handleSignalNotify(data));
55726
+ unBacktest = compose(() => unBacktestSignal(), () => unBacktestPartialProfit(), () => unBacktestPartialLoss(), () => unBacktestBreakeven(), () => unBacktestStrategyCommit(), () => unBacktestSync(), () => unBacktestRisk(), () => unBacktestError(), () => unBacktestExit(), () => unBacktestValidation(), () => unBacktestSignalNotify());
55291
55727
  }
55292
55728
  {
55293
55729
  const unLiveSignal = signalLiveEmitter.subscribe((data) => NotificationLive.handleSignal(data));
@@ -55312,7 +55748,10 @@ class NotificationAdapter {
55312
55748
  const unLiveError = errorEmitter.subscribe((error) => NotificationLive.handleError(error));
55313
55749
  const unLiveExit = exitEmitter.subscribe((error) => NotificationLive.handleCriticalError(error));
55314
55750
  const unLiveValidation = validationSubject.subscribe((error) => NotificationLive.handleValidationError(error));
55315
- unLive = compose(() => unLiveSignal(), () => unLivePartialProfit(), () => unLivePartialLoss(), () => unLiveBreakeven(), () => unLiveStrategyCommit(), () => unLiveSync(), () => unLiveRisk(), () => unLiveError(), () => unLiveExit(), () => unLiveValidation());
55751
+ const unLiveSignalNotify = signalNotifySubject
55752
+ .filter(({ backtest }) => !backtest)
55753
+ .connect((data) => NotificationLive.handleSignalNotify(data));
55754
+ unLive = compose(() => unLiveSignal(), () => unLivePartialProfit(), () => unLivePartialLoss(), () => unLiveBreakeven(), () => unLiveStrategyCommit(), () => unLiveSync(), () => unLiveRisk(), () => unLiveError(), () => unLiveExit(), () => unLiveValidation(), () => unLiveSignalNotify());
55316
55755
  }
55317
55756
  return () => {
55318
55757
  unLive();
@@ -55550,11 +55989,17 @@ class CacheFnInstance {
55550
55989
  return cached;
55551
55990
  }
55552
55991
  }
55992
+ const value = this.fn(...args);
55553
55993
  const newCache = {
55554
55994
  when: currentWhen,
55555
- value: this.fn(...args),
55995
+ value,
55556
55996
  };
55557
55997
  this._cacheMap.set(key, newCache);
55998
+ if (value && value instanceof Promise) {
55999
+ value.catch(() => {
56000
+ this._cacheMap.delete(key);
56001
+ });
56002
+ }
55558
56003
  return newCache;
55559
56004
  };
55560
56005
  /**
@@ -56135,7 +56580,7 @@ class IntervalFnInstance {
56135
56580
  * within the same interval or when `fn` itself returned `null`
56136
56581
  * @throws Error if method context, execution context, or interval is missing
56137
56582
  */
56138
- this.run = async (...args) => {
56583
+ this.run = (...args) => {
56139
56584
  backtest.loggerService.debug(INTERVAL_METHOD_NAME_RUN, { args });
56140
56585
  const step = INTERVAL_MINUTES[this.interval];
56141
56586
  {
@@ -56157,10 +56602,15 @@ class IntervalFnInstance {
56157
56602
  if (this._stateMap.get(stateKey) === currentAligned) {
56158
56603
  return null;
56159
56604
  }
56160
- const result = await this.fn.apply(null, args);
56605
+ const result = this.fn.apply(null, args);
56161
56606
  if (result !== null) {
56162
56607
  this._stateMap.set(stateKey, currentAligned);
56163
56608
  }
56609
+ if (result && result instanceof Promise) {
56610
+ result.catch(() => {
56611
+ this._stateMap.delete(stateKey);
56612
+ });
56613
+ }
56164
56614
  return result;
56165
56615
  };
56166
56616
  /**
@@ -57691,4 +58141,4 @@ const validateSignal = (signal, currentPrice) => {
57691
58141
  return !errors.length;
57692
58142
  };
57693
58143
 
57694
- export { ActionBase, Backtest, Breakeven, Broker, BrokerBase, Cache, Constant, Dump, Exchange, ExecutionContextService, Heat, HighestProfit, Interval, Live, Log, Markdown, MarkdownFileBase, MarkdownFolderBase, MarkdownWriter, MaxDrawdown, Memory, MethodContextService, Notification, NotificationBacktest, NotificationLive, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistIntervalAdapter, PersistLogAdapter, PersistMeasureAdapter, PersistMemoryAdapter, PersistNotificationAdapter, PersistPartialAdapter, PersistRecentAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PersistStorageAdapter, Position, PositionSize, Recent, RecentBacktest, RecentLive, Reflect$1 as Reflect, Report, ReportBase, ReportWriter, Risk, Schedule, Session, Storage, StorageBacktest, StorageLive, Strategy, Sync, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, alignToInterval, checkCandles, commitActivateScheduled, commitAverageBuy, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialLossCost, commitPartialProfit, commitPartialProfitCost, commitTrailingStop, commitTrailingStopCost, commitTrailingTake, commitTrailingTakeCost, dumpAgentAnswer, dumpError, dumpJson, dumpRecord, dumpTable, dumpText, emitters, formatPrice, formatQuantity, get, getActionSchema, getAggregatedTrades, getAveragePrice, getBacktestTimeframe, getBreakeven, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getEffectivePriceOpen, getExchangeSchema, getFrameSchema, getLatestSignal, getMaxDrawdownDistancePnlCost, getMaxDrawdownDistancePnlPercentage, getMode, getNextCandles, getOrderBook, getPendingSignal, getPositionCountdownMinutes, getPositionDrawdownMinutes, getPositionEffectivePrice, getPositionEntries, getPositionEntryOverlap, getPositionEstimateMinutes, getPositionHighestMaxDrawdownPnlCost, getPositionHighestMaxDrawdownPnlPercentage, getPositionHighestPnlCost, getPositionHighestPnlPercentage, getPositionHighestProfitBreakeven, getPositionHighestProfitDistancePnlCost, getPositionHighestProfitDistancePnlPercentage, getPositionHighestProfitMinutes, getPositionHighestProfitPrice, getPositionHighestProfitTimestamp, getPositionInvestedCost, getPositionInvestedCount, getPositionLevels, getPositionMaxDrawdownMinutes, getPositionMaxDrawdownPnlCost, getPositionMaxDrawdownPnlPercentage, getPositionMaxDrawdownPrice, getPositionMaxDrawdownTimestamp, getPositionPartialOverlap, getPositionPartials, getPositionPnlCost, getPositionPnlPercent, getRawCandles, getRiskSchema, getScheduledSignal, getSizingSchema, getStrategySchema, getSymbol, getTimestamp, getTotalClosed, getTotalCostClosed, getTotalPercentClosed, getWalkerSchema, hasNoPendingSignal, hasNoScheduledSignal, hasTradeContext, investedCostToPercent, backtest as lib, listExchangeSchema, listFrameSchema, listMemory, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenHighestProfit, listenHighestProfitOnce, listenMaxDrawdown, listenMaxDrawdownOnce, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenSync, listenSyncOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, percentDiff, percentToCloseCost, percentValue, readMemory, removeMemory, roundTicks, runInMockContext, searchMemory, set, setColumns, setConfig, setLogger, shutdown, slPercentShiftToPrice, slPriceToPercentShift, stopStrategy, toProfitLossDto, tpPercentShiftToPrice, tpPriceToPercentShift, validate, validateCommonSignal, validatePendingSignal, validateScheduledSignal, validateSignal, waitForCandle, warmCandles, writeMemory };
58144
+ export { ActionBase, Backtest, Breakeven, Broker, BrokerBase, Cache, Constant, Dump, Exchange, ExecutionContextService, Heat, HighestProfit, Interval, Live, Log, Markdown, MarkdownFileBase, MarkdownFolderBase, MarkdownWriter, MaxDrawdown, Memory, MethodContextService, Notification, NotificationBacktest, NotificationLive, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistIntervalAdapter, PersistLogAdapter, PersistMeasureAdapter, PersistMemoryAdapter, PersistNotificationAdapter, PersistPartialAdapter, PersistRecentAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PersistStorageAdapter, Position, PositionSize, Recent, RecentBacktest, RecentLive, Reflect$1 as Reflect, Report, ReportBase, ReportWriter, Risk, Schedule, Session, Storage, StorageBacktest, StorageLive, Strategy, Sync, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, alignToInterval, checkCandles, commitActivateScheduled, commitAverageBuy, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialLossCost, commitPartialProfit, commitPartialProfitCost, commitSignalNotify, commitTrailingStop, commitTrailingStopCost, commitTrailingTake, commitTrailingTakeCost, dumpAgentAnswer, dumpError, dumpJson, dumpRecord, dumpTable, dumpText, emitters, formatPrice, formatQuantity, get, getActionSchema, getAggregatedTrades, getAveragePrice, getBacktestTimeframe, getBreakeven, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getEffectivePriceOpen, getExchangeSchema, getFrameSchema, getLatestSignal, getMaxDrawdownDistancePnlCost, getMaxDrawdownDistancePnlPercentage, getMode, getNextCandles, getOrderBook, getPendingSignal, getPositionCountdownMinutes, getPositionDrawdownMinutes, getPositionEffectivePrice, getPositionEntries, getPositionEntryOverlap, getPositionEstimateMinutes, getPositionHighestMaxDrawdownPnlCost, getPositionHighestMaxDrawdownPnlPercentage, getPositionHighestPnlCost, getPositionHighestPnlPercentage, getPositionHighestProfitBreakeven, getPositionHighestProfitDistancePnlCost, getPositionHighestProfitDistancePnlPercentage, getPositionHighestProfitMinutes, getPositionHighestProfitPrice, getPositionHighestProfitTimestamp, getPositionInvestedCost, getPositionInvestedCount, getPositionLevels, getPositionMaxDrawdownMinutes, getPositionMaxDrawdownPnlCost, getPositionMaxDrawdownPnlPercentage, getPositionMaxDrawdownPrice, getPositionMaxDrawdownTimestamp, getPositionPartialOverlap, getPositionPartials, getPositionPnlCost, getPositionPnlPercent, getRawCandles, getRiskSchema, getScheduledSignal, getSizingSchema, getStrategySchema, getSymbol, getTimestamp, getTotalClosed, getTotalCostClosed, getTotalPercentClosed, getWalkerSchema, hasNoPendingSignal, hasNoScheduledSignal, hasTradeContext, investedCostToPercent, backtest as lib, listExchangeSchema, listFrameSchema, listMemory, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenHighestProfit, listenHighestProfitOnce, listenMaxDrawdown, listenMaxDrawdownOnce, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalNotify, listenSignalNotifyOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenSync, listenSyncOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, percentDiff, percentToCloseCost, percentValue, readMemory, removeMemory, roundTicks, runInMockContext, searchMemory, set, setColumns, setConfig, setLogger, shutdown, slPercentShiftToPrice, slPriceToPercentShift, stopStrategy, toProfitLossDto, tpPercentShiftToPrice, tpPriceToPercentShift, validate, validateCommonSignal, validatePendingSignal, validateScheduledSignal, validateSignal, waitForCandle, warmCandles, writeMemory };