backtest-kit 7.1.0 → 7.2.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.cjs CHANGED
@@ -4770,8 +4770,7 @@ const TIMEOUT_SYMBOL = Symbol('timeout');
4770
4770
  * The framework will retry on the next tick.
4771
4771
  */
4772
4772
  const CALL_SIGNAL_SYNC_OPEN_FN = functoolsKit.trycatch(async (timestamp, currentPrice, pendingSignal, self) => {
4773
- const publicSignal = TO_PUBLIC_SIGNAL(pendingSignal, currentPrice);
4774
- const pnl = toProfitLossDto(pendingSignal, currentPrice);
4773
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", pendingSignal, currentPrice);
4775
4774
  return await self.params.onSignalSync({
4776
4775
  action: "signal-open",
4777
4776
  symbol: self.params.execution.context.symbol,
@@ -4782,10 +4781,12 @@ const CALL_SIGNAL_SYNC_OPEN_FN = functoolsKit.trycatch(async (timestamp, current
4782
4781
  signalId: pendingSignal.id,
4783
4782
  timestamp,
4784
4783
  signal: publicSignal,
4784
+ maxDrawdown: publicSignal.maxDrawdown,
4785
+ peakProfit: publicSignal.peakProfit,
4785
4786
  cost: pendingSignal.cost,
4786
4787
  currentPrice,
4787
4788
  position: publicSignal.position,
4788
- pnl,
4789
+ pnl: publicSignal.pnl,
4789
4790
  priceOpen: publicSignal.priceOpen,
4790
4791
  priceTakeProfit: publicSignal.priceTakeProfit,
4791
4792
  priceStopLoss: publicSignal.priceStopLoss,
@@ -4809,8 +4810,7 @@ const CALL_SIGNAL_SYNC_OPEN_FN = functoolsKit.trycatch(async (timestamp, current
4809
4810
  * strategy state is NOT mutated. The framework will retry on the next tick.
4810
4811
  */
4811
4812
  const CALL_SIGNAL_SYNC_CLOSE_FN = functoolsKit.trycatch(async (timestamp, currentPrice, closeReason, signal, self) => {
4812
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
4813
- const pnl = toProfitLossDto(signal, currentPrice);
4813
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
4814
4814
  return await self.params.onSignalSync({
4815
4815
  action: "signal-close",
4816
4816
  symbol: self.params.execution.context.symbol,
@@ -4821,8 +4821,10 @@ const CALL_SIGNAL_SYNC_CLOSE_FN = functoolsKit.trycatch(async (timestamp, curren
4821
4821
  signalId: signal.id,
4822
4822
  timestamp,
4823
4823
  signal: publicSignal,
4824
+ maxDrawdown: publicSignal.maxDrawdown,
4825
+ peakProfit: publicSignal.peakProfit,
4824
4826
  currentPrice,
4825
- pnl,
4827
+ pnl: publicSignal.pnl,
4826
4828
  position: publicSignal.position,
4827
4829
  priceOpen: publicSignal.priceOpen,
4828
4830
  priceTakeProfit: publicSignal.priceTakeProfit,
@@ -4883,10 +4885,9 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4883
4885
  if (!self._pendingSignal) {
4884
4886
  return;
4885
4887
  }
4886
- // Get public signal data for commit events (contains effective and original SL/TP)
4887
- const publicSignal = TO_PUBLIC_SIGNAL(self._pendingSignal, currentPrice);
4888
4888
  for (const commit of queue) {
4889
4889
  if (commit.action === "partial-profit") {
4890
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
4890
4891
  await CALL_COMMIT_FN(self, {
4891
4892
  action: "partial-profit",
4892
4893
  symbol: commit.symbol,
@@ -4896,7 +4897,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4896
4897
  backtest: commit.backtest,
4897
4898
  percentToClose: commit.percentToClose,
4898
4899
  currentPrice: commit.currentPrice,
4899
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
4900
+ pnl: publicSignal.pnl,
4901
+ maxDrawdown: publicSignal.maxDrawdown,
4902
+ peakProfit: publicSignal.peakProfit,
4903
+ signal: publicSignal,
4900
4904
  timestamp,
4901
4905
  totalEntries: publicSignal.totalEntries,
4902
4906
  totalPartials: publicSignal.totalPartials,
@@ -4915,6 +4919,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4915
4919
  continue;
4916
4920
  }
4917
4921
  if (commit.action === "partial-loss") {
4922
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
4918
4923
  await CALL_COMMIT_FN(self, {
4919
4924
  action: "partial-loss",
4920
4925
  symbol: commit.symbol,
@@ -4924,7 +4929,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4924
4929
  backtest: commit.backtest,
4925
4930
  percentToClose: commit.percentToClose,
4926
4931
  currentPrice: commit.currentPrice,
4927
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
4932
+ pnl: publicSignal.pnl,
4933
+ maxDrawdown: publicSignal.maxDrawdown,
4934
+ peakProfit: publicSignal.peakProfit,
4935
+ signal: publicSignal,
4928
4936
  timestamp,
4929
4937
  totalEntries: publicSignal.totalEntries,
4930
4938
  totalPartials: publicSignal.totalPartials,
@@ -4943,6 +4951,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4943
4951
  continue;
4944
4952
  }
4945
4953
  if (commit.action === "breakeven") {
4954
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
4946
4955
  await CALL_COMMIT_FN(self, {
4947
4956
  action: "breakeven",
4948
4957
  symbol: commit.symbol,
@@ -4951,7 +4960,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4951
4960
  frameName: self.params.frameName,
4952
4961
  backtest: commit.backtest,
4953
4962
  currentPrice: commit.currentPrice,
4954
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
4963
+ pnl: publicSignal.pnl,
4964
+ maxDrawdown: publicSignal.maxDrawdown,
4965
+ peakProfit: publicSignal.peakProfit,
4966
+ signal: publicSignal,
4955
4967
  timestamp,
4956
4968
  totalEntries: publicSignal.totalEntries,
4957
4969
  totalPartials: publicSignal.totalPartials,
@@ -4970,6 +4982,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4970
4982
  continue;
4971
4983
  }
4972
4984
  if (commit.action === "trailing-stop") {
4985
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
4973
4986
  await CALL_COMMIT_FN(self, {
4974
4987
  action: "trailing-stop",
4975
4988
  symbol: commit.symbol,
@@ -4979,7 +4992,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4979
4992
  backtest: commit.backtest,
4980
4993
  percentShift: commit.percentShift,
4981
4994
  currentPrice: commit.currentPrice,
4982
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
4995
+ pnl: publicSignal.pnl,
4996
+ maxDrawdown: publicSignal.maxDrawdown,
4997
+ peakProfit: publicSignal.peakProfit,
4998
+ signal: publicSignal,
4983
4999
  timestamp,
4984
5000
  totalEntries: publicSignal.totalEntries,
4985
5001
  totalPartials: publicSignal.totalPartials,
@@ -4998,6 +5014,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4998
5014
  continue;
4999
5015
  }
5000
5016
  if (commit.action === "trailing-take") {
5017
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
5001
5018
  await CALL_COMMIT_FN(self, {
5002
5019
  action: "trailing-take",
5003
5020
  symbol: commit.symbol,
@@ -5007,7 +5024,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
5007
5024
  backtest: commit.backtest,
5008
5025
  percentShift: commit.percentShift,
5009
5026
  currentPrice: commit.currentPrice,
5010
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
5027
+ pnl: publicSignal.pnl,
5028
+ maxDrawdown: publicSignal.maxDrawdown,
5029
+ peakProfit: publicSignal.peakProfit,
5030
+ signal: publicSignal,
5011
5031
  timestamp,
5012
5032
  totalEntries: publicSignal.totalEntries,
5013
5033
  totalPartials: publicSignal.totalPartials,
@@ -5026,6 +5046,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
5026
5046
  continue;
5027
5047
  }
5028
5048
  if (commit.action === "average-buy") {
5049
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
5029
5050
  const effectivePriceOpen = getEffectivePriceOpen(self._pendingSignal);
5030
5051
  await CALL_COMMIT_FN(self, {
5031
5052
  action: "average-buy",
@@ -5037,7 +5058,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
5037
5058
  currentPrice: commit.currentPrice,
5038
5059
  cost: commit.cost,
5039
5060
  effectivePriceOpen,
5040
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
5061
+ pnl: publicSignal.pnl,
5062
+ maxDrawdown: publicSignal.maxDrawdown,
5063
+ peakProfit: publicSignal.peakProfit,
5064
+ signal: publicSignal,
5041
5065
  timestamp,
5042
5066
  totalEntries: publicSignal.totalEntries,
5043
5067
  totalPartials: publicSignal.totalPartials,
@@ -5057,6 +5081,8 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
5057
5081
  }
5058
5082
  }
5059
5083
  };
5084
+ /** Zero PNL constant for scheduled signals (which don't have priceOpen or PNL yet) */
5085
+ const ZERO_PNL$1 = { pnlPercentage: 0, priceOpen: 0, priceClose: 0, pnlCost: 0, pnlEntries: 0 };
5060
5086
  /**
5061
5087
  * Converts internal signal to public API format.
5062
5088
  *
@@ -5104,7 +5130,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
5104
5130
  * // publicSignal._trailingPriceTakeProfit = undefined (hidden from external API)
5105
5131
  * ```
5106
5132
  */
5107
- const TO_PUBLIC_SIGNAL = (signal, currentPrice) => {
5133
+ const TO_PUBLIC_SIGNAL = (type, signal, currentPrice) => {
5108
5134
  const hasTrailingSL = "_trailingPriceStopLoss" in signal && signal._trailingPriceStopLoss !== undefined;
5109
5135
  const hasTrailingTP = "_trailingPriceTakeProfit" in signal && signal._trailingPriceTakeProfit !== undefined;
5110
5136
  const partialExecuted = "_partial" in signal
@@ -5112,11 +5138,14 @@ const TO_PUBLIC_SIGNAL = (signal, currentPrice) => {
5112
5138
  : 0;
5113
5139
  const totalEntries = ("_entry" in signal && Array.isArray(signal._entry))
5114
5140
  ? signal._entry.length
5115
- : 1;
5141
+ : type === "scheduled" ? 0 : 1;
5116
5142
  const totalPartials = ("_partial" in signal && Array.isArray(signal._partial))
5117
5143
  ? signal._partial.length
5118
5144
  : 0;
5119
- const effectivePriceOpen = "_entry" in signal ? getEffectivePriceOpen(signal) : signal.priceOpen;
5145
+ const pnl = type === "scheduled" ? ZERO_PNL$1 : toProfitLossDto(signal, currentPrice);
5146
+ const maxDrawdown = type === "scheduled" ? ZERO_PNL$1 : ("_fall" in signal ? !!signal["_fall"] ? ({ ...signal._fall }) : ZERO_PNL$1 : ZERO_PNL$1);
5147
+ const peakProfit = type === "scheduled" ? ZERO_PNL$1 : ("_peak" in signal ? signal["_peak"] ? ({ ...signal._peak }) : ZERO_PNL$1 : ZERO_PNL$1);
5148
+ const effectivePriceOpen = type === "scheduled" ? signal.priceOpen : "_entry" in signal ? signal["_entry"] ? getEffectivePriceOpen(signal) : signal.priceOpen : signal.priceOpen;
5120
5149
  return {
5121
5150
  ...structuredClone(signal),
5122
5151
  priceOpen: effectivePriceOpen,
@@ -5125,10 +5154,12 @@ const TO_PUBLIC_SIGNAL = (signal, currentPrice) => {
5125
5154
  originalPriceOpen: signal.priceOpen,
5126
5155
  originalPriceStopLoss: signal.priceStopLoss,
5127
5156
  originalPriceTakeProfit: signal.priceTakeProfit,
5157
+ maxDrawdown,
5158
+ peakProfit,
5128
5159
  partialExecuted,
5129
5160
  totalEntries,
5130
5161
  totalPartials,
5131
- pnl: toProfitLossDto(signal, currentPrice),
5162
+ pnl,
5132
5163
  };
5133
5164
  };
5134
5165
  const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
@@ -5193,8 +5224,8 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
5193
5224
  timestamp: currentTime,
5194
5225
  _isScheduled: false,
5195
5226
  _entry: [{ price: signal.priceOpen, cost: signal.cost ?? GLOBAL_CONFIG.CC_POSITION_ENTRY_COST, timestamp: currentTime }],
5196
- _peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5197
- _fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5227
+ _peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5228
+ _fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5198
5229
  };
5199
5230
  // Валидируем сигнал перед возвратом
5200
5231
  validatePendingSignal(signalRow, currentPrice);
@@ -5219,8 +5250,8 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
5219
5250
  timestamp: currentTime,
5220
5251
  _isScheduled: true,
5221
5252
  _entry: [{ price: signal.priceOpen, cost: signal.cost ?? GLOBAL_CONFIG.CC_POSITION_ENTRY_COST, timestamp: currentTime }],
5222
- _peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5223
- _fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5253
+ _peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5254
+ _fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5224
5255
  };
5225
5256
  // Валидируем сигнал перед возвратом
5226
5257
  validateScheduledSignal(scheduledSignalRow, currentPrice);
@@ -5242,8 +5273,8 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
5242
5273
  timestamp: currentTime,
5243
5274
  _isScheduled: false,
5244
5275
  _entry: [{ price: currentPrice, cost: signal.cost ?? GLOBAL_CONFIG.CC_POSITION_ENTRY_COST, timestamp: currentTime }],
5245
- _peak: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5246
- _fall: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5276
+ _peak: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5277
+ _fall: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5247
5278
  };
5248
5279
  // Валидируем сигнал перед возвратом
5249
5280
  validatePendingSignal(signalRow, currentPrice);
@@ -5847,7 +5878,7 @@ const CHECK_SCHEDULED_SIGNAL_TIMEOUT_FN = async (self, scheduled, currentPrice)
5847
5878
  await CALL_CANCEL_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, currentPrice, currentTime, self.params.execution.context.backtest);
5848
5879
  const result = {
5849
5880
  action: "cancelled",
5850
- signal: TO_PUBLIC_SIGNAL(scheduled, currentPrice),
5881
+ signal: TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice),
5851
5882
  currentPrice: currentPrice,
5852
5883
  closeTimestamp: currentTime,
5853
5884
  strategyName: self.params.method.context.strategyName,
@@ -5903,7 +5934,7 @@ const CANCEL_SCHEDULED_SIGNAL_BY_STOPLOSS_FN = async (self, scheduled, currentPr
5903
5934
  await CALL_CANCEL_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, currentPrice, currentTime, self.params.execution.context.backtest);
5904
5935
  const result = {
5905
5936
  action: "cancelled",
5906
- signal: TO_PUBLIC_SIGNAL(scheduled, currentPrice),
5937
+ signal: TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice),
5907
5938
  currentPrice: currentPrice,
5908
5939
  closeTimestamp: currentTime,
5909
5940
  strategyName: self.params.method.context.strategyName,
@@ -5954,8 +5985,8 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
5954
5985
  ...scheduled,
5955
5986
  pendingAt: activationTime,
5956
5987
  _isScheduled: false,
5957
- _peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
5958
- _fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
5988
+ _peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
5989
+ _fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
5959
5990
  };
5960
5991
  // Sync open: if external system rejects — cancel scheduled signal instead of opening
5961
5992
  const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(activationTime, activatedSignal.priceOpen, activatedSignal, self);
@@ -5965,6 +5996,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
5965
5996
  signalId: scheduled.id,
5966
5997
  });
5967
5998
  await self.setScheduledSignal(null);
5999
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, scheduled.priceOpen);
5968
6000
  await CALL_COMMIT_FN(self, {
5969
6001
  action: "cancel-scheduled",
5970
6002
  symbol: self.params.execution.context.symbol,
@@ -5977,7 +6009,10 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
5977
6009
  totalEntries: scheduled._entry?.length ?? 1,
5978
6010
  totalPartials: scheduled._partial?.length ?? 0,
5979
6011
  originalPriceOpen: scheduled.priceOpen,
5980
- pnl: toProfitLossDto(scheduled, scheduled.priceOpen),
6012
+ pnl: publicSignal.pnl,
6013
+ maxDrawdown: publicSignal.maxDrawdown,
6014
+ peakProfit: publicSignal.peakProfit,
6015
+ signal: publicSignal,
5981
6016
  note: scheduled.note,
5982
6017
  });
5983
6018
  return null;
@@ -5988,7 +6023,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
5988
6023
  await CALL_OPEN_CALLBACKS_FN(self, self.params.execution.context.symbol, self._pendingSignal, self._pendingSignal.priceOpen, activationTime, self.params.execution.context.backtest);
5989
6024
  const result = {
5990
6025
  action: "opened",
5991
- signal: TO_PUBLIC_SIGNAL(self._pendingSignal, self._pendingSignal.priceOpen),
6026
+ signal: TO_PUBLIC_SIGNAL("pending", self._pendingSignal, self._pendingSignal.priceOpen),
5992
6027
  strategyName: self.params.method.context.strategyName,
5993
6028
  exchangeName: self.params.method.context.exchangeName,
5994
6029
  frameName: self.params.method.context.frameName,
@@ -6002,7 +6037,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
6002
6037
  };
6003
6038
  const CALL_SCHEDULE_PING_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, scheduled, timestamp, backtest, currentPrice) => {
6004
6039
  await ExecutionContextService.runInContext(async () => {
6005
- const publicSignal = TO_PUBLIC_SIGNAL(scheduled, currentPrice);
6040
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice);
6006
6041
  // Call system onSchedulePing callback first (emits to pingSubject)
6007
6042
  await self.params.onSchedulePing(self.params.execution.context.symbol, self.params.method.context.strategyName, self.params.method.context.exchangeName, publicSignal, currentPrice, self.params.execution.context.backtest, timestamp);
6008
6043
  // Call user onSchedulePing callback only if signal is still active (not cancelled, not activated)
@@ -6028,7 +6063,7 @@ const CALL_SCHEDULE_PING_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (s
6028
6063
  });
6029
6064
  const CALL_ACTIVE_PING_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, pending, timestamp, backtest, currentPrice) => {
6030
6065
  await ExecutionContextService.runInContext(async () => {
6031
- const publicSignal = TO_PUBLIC_SIGNAL(pending, currentPrice);
6066
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", pending, currentPrice);
6032
6067
  // Call system onActivePing callback first (emits to activePingSubject)
6033
6068
  await self.params.onActivePing(self.params.execution.context.symbol, self.params.method.context.strategyName, self.params.method.context.exchangeName, publicSignal, currentPrice, self.params.execution.context.backtest, timestamp);
6034
6069
  // Call user onActivePing callback only if signal is still active (not closed)
@@ -6076,7 +6111,7 @@ const CALL_IDLE_PING_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self,
6076
6111
  const CALL_ACTIVE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6077
6112
  await ExecutionContextService.runInContext(async () => {
6078
6113
  if (self.params.callbacks?.onActive) {
6079
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6114
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6080
6115
  await self.params.callbacks.onActive(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
6081
6116
  }
6082
6117
  }, {
@@ -6099,7 +6134,7 @@ const CALL_ACTIVE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, sy
6099
6134
  const CALL_SCHEDULE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6100
6135
  await ExecutionContextService.runInContext(async () => {
6101
6136
  if (self.params.callbacks?.onSchedule) {
6102
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6137
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", signal, currentPrice);
6103
6138
  await self.params.callbacks.onSchedule(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
6104
6139
  }
6105
6140
  }, {
@@ -6122,7 +6157,7 @@ const CALL_SCHEDULE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self,
6122
6157
  const CALL_CANCEL_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6123
6158
  await ExecutionContextService.runInContext(async () => {
6124
6159
  if (self.params.callbacks?.onCancel) {
6125
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6160
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", signal, currentPrice);
6126
6161
  await self.params.callbacks.onCancel(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
6127
6162
  }
6128
6163
  }, {
@@ -6145,7 +6180,7 @@ const CALL_CANCEL_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, sy
6145
6180
  const CALL_OPEN_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, priceOpen, timestamp, backtest) => {
6146
6181
  await ExecutionContextService.runInContext(async () => {
6147
6182
  if (self.params.callbacks?.onOpen) {
6148
- const publicSignal = TO_PUBLIC_SIGNAL(signal, priceOpen);
6183
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, priceOpen);
6149
6184
  await self.params.callbacks.onOpen(self.params.execution.context.symbol, publicSignal, priceOpen, self.params.execution.context.backtest);
6150
6185
  }
6151
6186
  }, {
@@ -6168,7 +6203,7 @@ const CALL_OPEN_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symb
6168
6203
  const CALL_CLOSE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6169
6204
  await ExecutionContextService.runInContext(async () => {
6170
6205
  if (self.params.callbacks?.onClose) {
6171
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6206
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6172
6207
  await self.params.callbacks.onClose(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
6173
6208
  }
6174
6209
  }, {
@@ -6291,7 +6326,7 @@ const CALL_RISK_REMOVE_SIGNAL_FN = functoolsKit.trycatch(beginTime(async (self,
6291
6326
  });
6292
6327
  const CALL_PARTIAL_CLEAR_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6293
6328
  await ExecutionContextService.runInContext(async () => {
6294
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6329
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6295
6330
  await self.params.partial.clear(symbol, publicSignal, currentPrice, backtest);
6296
6331
  }, {
6297
6332
  when: new Date(timestamp),
@@ -6313,7 +6348,7 @@ const CALL_PARTIAL_CLEAR_FN = functoolsKit.trycatch(beginTime(async (self, symbo
6313
6348
  const CALL_RISK_CHECK_SIGNAL_FN = functoolsKit.trycatch(beginTime(async (self, symbol, pendingSignal, currentPrice, timestamp, backtest) => {
6314
6349
  return await ExecutionContextService.runInContext(async () => {
6315
6350
  return await self.params.risk.checkSignal({
6316
- currentSignal: TO_PUBLIC_SIGNAL(pendingSignal, currentPrice),
6351
+ currentSignal: TO_PUBLIC_SIGNAL("scheduled", pendingSignal, currentPrice),
6317
6352
  symbol: symbol,
6318
6353
  strategyName: self.params.method.context.strategyName,
6319
6354
  exchangeName: self.params.method.context.exchangeName,
@@ -6342,7 +6377,7 @@ const CALL_RISK_CHECK_SIGNAL_FN = functoolsKit.trycatch(beginTime(async (self, s
6342
6377
  });
6343
6378
  const CALL_PARTIAL_PROFIT_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, percentTp, timestamp, backtest) => {
6344
6379
  await ExecutionContextService.runInContext(async () => {
6345
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6380
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6346
6381
  await self.params.partial.profit(symbol, publicSignal, currentPrice, percentTp, backtest, new Date(timestamp));
6347
6382
  if (self.params.callbacks?.onPartialProfit) {
6348
6383
  await self.params.callbacks.onPartialProfit(symbol, publicSignal, currentPrice, percentTp, backtest);
@@ -6366,7 +6401,7 @@ const CALL_PARTIAL_PROFIT_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (
6366
6401
  });
6367
6402
  const CALL_PARTIAL_LOSS_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, percentSl, timestamp, backtest) => {
6368
6403
  await ExecutionContextService.runInContext(async () => {
6369
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6404
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6370
6405
  await self.params.partial.loss(symbol, publicSignal, currentPrice, percentSl, backtest, new Date(timestamp));
6371
6406
  if (self.params.callbacks?.onPartialLoss) {
6372
6407
  await self.params.callbacks.onPartialLoss(symbol, publicSignal, currentPrice, percentSl, backtest);
@@ -6390,7 +6425,7 @@ const CALL_PARTIAL_LOSS_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (se
6390
6425
  });
6391
6426
  const CALL_BREAKEVEN_CHECK_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6392
6427
  await ExecutionContextService.runInContext(async () => {
6393
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6428
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6394
6429
  const isBreakeven = await self.params.breakeven.check(symbol, publicSignal, currentPrice, backtest, new Date(timestamp));
6395
6430
  if (self.params.callbacks?.onBreakeven) {
6396
6431
  isBreakeven && await self.params.callbacks.onBreakeven(symbol, publicSignal, currentPrice, backtest);
@@ -6414,7 +6449,7 @@ const CALL_BREAKEVEN_CHECK_FN = functoolsKit.trycatch(beginTime(async (self, sym
6414
6449
  });
6415
6450
  const CALL_BREAKEVEN_CLEAR_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6416
6451
  await ExecutionContextService.runInContext(async () => {
6417
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6452
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6418
6453
  await self.params.breakeven.clear(symbol, publicSignal, currentPrice, backtest);
6419
6454
  }, {
6420
6455
  when: new Date(timestamp),
@@ -6437,7 +6472,7 @@ const CALL_BACKTEST_SCHEDULE_OPEN_FN = functoolsKit.trycatch(beginTime(async (se
6437
6472
  await ExecutionContextService.runInContext(async () => {
6438
6473
  backtestScheduleOpenSubject.next({
6439
6474
  action: "opened",
6440
- signal: TO_PUBLIC_SIGNAL(signal, signal.priceOpen),
6475
+ signal: TO_PUBLIC_SIGNAL("pending", signal, signal.priceOpen),
6441
6476
  strategyName: self.params.method.context.strategyName,
6442
6477
  exchangeName: self.params.method.context.exchangeName,
6443
6478
  frameName: self.params.method.context.frameName,
@@ -6466,10 +6501,10 @@ const CALL_BACKTEST_SCHEDULE_OPEN_FN = functoolsKit.trycatch(beginTime(async (se
6466
6501
  const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice) => {
6467
6502
  const currentTime = self.params.execution.context.when.getTime();
6468
6503
  await CALL_SCHEDULE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, currentTime, self.params.execution.context.backtest, currentPrice);
6469
- const pnl = toProfitLossDto(scheduled, currentPrice);
6504
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice);
6470
6505
  const result = {
6471
6506
  action: "waiting",
6472
- signal: TO_PUBLIC_SIGNAL(scheduled, currentPrice),
6507
+ signal: publicSignal,
6473
6508
  currentPrice: currentPrice,
6474
6509
  strategyName: self.params.method.context.strategyName,
6475
6510
  exchangeName: self.params.method.context.exchangeName,
@@ -6477,7 +6512,7 @@ const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice)
6477
6512
  symbol: self.params.execution.context.symbol,
6478
6513
  percentTp: 0,
6479
6514
  percentSl: 0,
6480
- pnl,
6515
+ pnl: publicSignal.pnl,
6481
6516
  backtest: self.params.execution.context.backtest,
6482
6517
  createdAt: currentTime,
6483
6518
  };
@@ -6497,7 +6532,7 @@ const OPEN_NEW_SCHEDULED_SIGNAL_FN = async (self, signal) => {
6497
6532
  await CALL_SCHEDULE_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, currentTime, self.params.execution.context.backtest);
6498
6533
  const result = {
6499
6534
  action: "scheduled",
6500
- signal: TO_PUBLIC_SIGNAL(signal, currentPrice),
6535
+ signal: TO_PUBLIC_SIGNAL("scheduled", signal, currentPrice),
6501
6536
  strategyName: self.params.method.context.strategyName,
6502
6537
  exchangeName: self.params.method.context.exchangeName,
6503
6538
  frameName: self.params.method.context.frameName,
@@ -6527,7 +6562,7 @@ const OPEN_NEW_PENDING_SIGNAL_FN = async (self, signal) => {
6527
6562
  await CALL_OPEN_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, signal.priceOpen, currentTime, self.params.execution.context.backtest);
6528
6563
  const result = {
6529
6564
  action: "opened",
6530
- signal: TO_PUBLIC_SIGNAL(signal, signal.priceOpen),
6565
+ signal: TO_PUBLIC_SIGNAL("pending", signal, signal.priceOpen),
6531
6566
  strategyName: self.params.method.context.strategyName,
6532
6567
  exchangeName: self.params.method.context.exchangeName,
6533
6568
  frameName: self.params.method.context.frameName,
@@ -6582,13 +6617,13 @@ const CLOSE_PENDING_SIGNAL_FN = async (self, signal, currentPrice, closeReason)
6582
6617
  });
6583
6618
  return null;
6584
6619
  }
6585
- const pnl = toProfitLossDto(signal, currentPrice);
6620
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6586
6621
  self.params.logger.info(`ClientStrategy signal ${closeReason}`, {
6587
6622
  symbol: self.params.execution.context.symbol,
6588
6623
  signalId: signal.id,
6589
6624
  closeReason,
6590
6625
  priceClose: currentPrice,
6591
- pnlPercentage: pnl.pnlPercentage,
6626
+ pnlPercentage: publicSignal.pnl.pnlPercentage,
6592
6627
  });
6593
6628
  await CALL_CLOSE_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, currentTime, self.params.execution.context.backtest);
6594
6629
  // КРИТИЧНО: Очищаем состояние ClientPartial при закрытии позиции
@@ -6599,11 +6634,11 @@ const CLOSE_PENDING_SIGNAL_FN = async (self, signal, currentPrice, closeReason)
6599
6634
  await self.setPendingSignal(null);
6600
6635
  const result = {
6601
6636
  action: "closed",
6602
- signal: TO_PUBLIC_SIGNAL(signal, currentPrice),
6637
+ signal: publicSignal,
6603
6638
  currentPrice: currentPrice,
6604
6639
  closeReason: closeReason,
6605
6640
  closeTimestamp: currentTime,
6606
- pnl: pnl,
6641
+ pnl: publicSignal.pnl,
6607
6642
  strategyName: self.params.method.context.strategyName,
6608
6643
  exchangeName: self.params.method.context.exchangeName,
6609
6644
  frameName: self.params.method.context.frameName,
@@ -6636,13 +6671,13 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
6636
6671
  const progressPercent = (currentDistance / tpDistance) * 100;
6637
6672
  percentTp = Math.min(progressPercent, 100);
6638
6673
  if (currentPrice > signal._peak.price) {
6639
- const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
6640
- signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
6674
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6675
+ signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
6641
6676
  if (self.params.callbacks?.onWrite) {
6642
6677
  self.params.callbacks.onWrite(signal.symbol, signal, backtest);
6643
6678
  }
6644
6679
  !backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
6645
- await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
6680
+ await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
6646
6681
  }
6647
6682
  await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentTp, currentTime, self.params.execution.context.backtest);
6648
6683
  }
@@ -6653,13 +6688,13 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
6653
6688
  const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
6654
6689
  percentSl = Math.min(progressPercent, 100);
6655
6690
  if (currentPrice < signal._fall.price) {
6656
- const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
6657
- signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
6691
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6692
+ signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
6658
6693
  if (self.params.callbacks?.onWrite) {
6659
6694
  self.params.callbacks.onWrite(signal.symbol, signal, backtest);
6660
6695
  }
6661
6696
  !backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
6662
- await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
6697
+ await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
6663
6698
  }
6664
6699
  await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentSl, currentTime, self.params.execution.context.backtest);
6665
6700
  }
@@ -6678,13 +6713,13 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
6678
6713
  const progressPercent = (currentDistance / tpDistance) * 100;
6679
6714
  percentTp = Math.min(progressPercent, 100);
6680
6715
  if (currentPrice < signal._peak.price) {
6681
- const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
6682
- signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
6716
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6717
+ signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
6683
6718
  if (self.params.callbacks?.onWrite) {
6684
6719
  self.params.callbacks.onWrite(signal.symbol, signal, backtest);
6685
6720
  }
6686
6721
  !backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
6687
- await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
6722
+ await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
6688
6723
  }
6689
6724
  await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentTp, currentTime, self.params.execution.context.backtest);
6690
6725
  }
@@ -6695,22 +6730,22 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
6695
6730
  const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
6696
6731
  percentSl = Math.min(progressPercent, 100);
6697
6732
  if (currentPrice > signal._fall.price) {
6698
- const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
6699
- signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
6733
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6734
+ signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
6700
6735
  if (self.params.callbacks?.onWrite) {
6701
6736
  self.params.callbacks.onWrite(signal.symbol, signal, backtest);
6702
6737
  }
6703
6738
  !backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
6704
- await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
6739
+ await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
6705
6740
  }
6706
6741
  await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentSl, currentTime, self.params.execution.context.backtest);
6707
6742
  }
6708
6743
  }
6709
6744
  }
6710
- const pnl = toProfitLossDto(signal, currentPrice);
6745
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6711
6746
  const result = {
6712
6747
  action: "active",
6713
- signal: TO_PUBLIC_SIGNAL(signal, currentPrice),
6748
+ signal: publicSignal,
6714
6749
  currentPrice: currentPrice,
6715
6750
  strategyName: self.params.method.context.strategyName,
6716
6751
  exchangeName: self.params.method.context.exchangeName,
@@ -6718,7 +6753,7 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
6718
6753
  symbol: self.params.execution.context.symbol,
6719
6754
  percentTp,
6720
6755
  percentSl,
6721
- pnl,
6756
+ pnl: publicSignal.pnl,
6722
6757
  backtest: self.params.execution.context.backtest,
6723
6758
  createdAt: currentTime,
6724
6759
  _backtestLastTimestamp: currentTime,
@@ -6754,6 +6789,7 @@ const CANCEL_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, averagePr
6754
6789
  reason,
6755
6790
  });
6756
6791
  await self.setScheduledSignal(null);
6792
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, averagePrice);
6757
6793
  if (reason === "user") {
6758
6794
  await CALL_COMMIT_FN(self, {
6759
6795
  action: "cancel-scheduled",
@@ -6768,14 +6804,17 @@ const CANCEL_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, averagePr
6768
6804
  totalEntries: scheduled._entry?.length ?? 1,
6769
6805
  totalPartials: scheduled._partial?.length ?? 0,
6770
6806
  originalPriceOpen: scheduled.priceOpen,
6771
- pnl: toProfitLossDto(scheduled, averagePrice),
6807
+ pnl: publicSignal.pnl,
6808
+ maxDrawdown: publicSignal.maxDrawdown,
6809
+ peakProfit: publicSignal.peakProfit,
6810
+ signal: publicSignal,
6772
6811
  note: cancelNote ?? scheduled.note,
6773
6812
  });
6774
6813
  }
6775
6814
  await CALL_CANCEL_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, averagePrice, closeTimestamp, self.params.execution.context.backtest);
6776
6815
  const result = {
6777
6816
  action: "cancelled",
6778
- signal: TO_PUBLIC_SIGNAL(scheduled, averagePrice),
6817
+ signal: publicSignal,
6779
6818
  currentPrice: averagePrice,
6780
6819
  closeTimestamp: closeTimestamp,
6781
6820
  strategyName: self.params.method.context.strategyName,
@@ -6824,8 +6863,8 @@ const ACTIVATE_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, activat
6824
6863
  ...scheduled,
6825
6864
  pendingAt: activationTime,
6826
6865
  _isScheduled: false,
6827
- _peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
6828
- _fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
6866
+ _peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
6867
+ _fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
6829
6868
  };
6830
6869
  // Sync open: if external system rejects — cancel scheduled signal instead of opening
6831
6870
  const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(activationTime, activatedSignal.priceOpen, activatedSignal, self);
@@ -6835,6 +6874,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, activat
6835
6874
  signalId: scheduled.id,
6836
6875
  });
6837
6876
  await self.setScheduledSignal(null);
6877
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, scheduled.priceOpen);
6838
6878
  await CALL_COMMIT_FN(self, {
6839
6879
  action: "cancel-scheduled",
6840
6880
  symbol: self.params.execution.context.symbol,
@@ -6847,7 +6887,10 @@ const ACTIVATE_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, activat
6847
6887
  totalEntries: scheduled._entry?.length ?? 1,
6848
6888
  totalPartials: scheduled._partial?.length ?? 0,
6849
6889
  originalPriceOpen: scheduled.priceOpen,
6850
- pnl: toProfitLossDto(scheduled, scheduled.priceOpen),
6890
+ pnl: publicSignal.pnl,
6891
+ maxDrawdown: publicSignal.maxDrawdown,
6892
+ peakProfit: publicSignal.peakProfit,
6893
+ signal: publicSignal,
6851
6894
  note: scheduled.note,
6852
6895
  });
6853
6896
  return false;
@@ -6870,20 +6913,20 @@ const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, c
6870
6913
  });
6871
6914
  return null;
6872
6915
  }
6873
- const pnl = toProfitLossDto(signal, averagePrice);
6916
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
6874
6917
  self.params.logger.debug(`ClientStrategy backtest ${closeReason}`, {
6875
6918
  symbol: self.params.execution.context.symbol,
6876
6919
  signalId: signal.id,
6877
6920
  reason: closeReason,
6878
6921
  priceClose: averagePrice,
6879
6922
  closeTimestamp,
6880
- pnlPercentage: pnl.pnlPercentage,
6923
+ pnlPercentage: publicSignal.pnl.pnlPercentage,
6881
6924
  });
6882
6925
  if (closeReason === "stop_loss") {
6883
- self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (stop_loss), PNL: ${pnl.pnlPercentage.toFixed(2)}%`);
6926
+ self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (stop_loss), PNL: ${publicSignal.pnl.pnlPercentage.toFixed(2)}%`);
6884
6927
  }
6885
- if (closeReason === "time_expired" && pnl.pnlPercentage < 0) {
6886
- self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (time_expired), PNL: ${pnl.pnlPercentage.toFixed(2)}%`);
6928
+ if (closeReason === "time_expired" && publicSignal.pnl.pnlPercentage < 0) {
6929
+ self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (time_expired), PNL: ${publicSignal.pnl.pnlPercentage.toFixed(2)}%`);
6887
6930
  }
6888
6931
  await CALL_CLOSE_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
6889
6932
  // КРИТИЧНО: Очищаем состояние ClientPartial при закрытии позиции
@@ -6894,11 +6937,11 @@ const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, c
6894
6937
  await self.setPendingSignal(null);
6895
6938
  const result = {
6896
6939
  action: "closed",
6897
- signal: TO_PUBLIC_SIGNAL(signal, averagePrice),
6940
+ signal: publicSignal,
6898
6941
  currentPrice: averagePrice,
6899
6942
  closeReason: closeReason,
6900
6943
  closeTimestamp: closeTimestamp,
6901
- pnl: pnl,
6944
+ pnl: publicSignal.pnl,
6902
6945
  strategyName: self.params.method.context.strategyName,
6903
6946
  exchangeName: self.params.method.context.exchangeName,
6904
6947
  frameName: self.params.method.context.frameName,
@@ -6922,6 +6965,7 @@ const CLOSE_USER_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, closedSignal, aver
6922
6965
  `Retry backtest() with new candle data.`);
6923
6966
  }
6924
6967
  self._closedSignal = null;
6968
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", closedSignal, averagePrice);
6925
6969
  await CALL_COMMIT_FN(self, {
6926
6970
  action: "close-pending",
6927
6971
  symbol: self.params.execution.context.symbol,
@@ -6935,21 +6979,23 @@ const CLOSE_USER_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, closedSignal, aver
6935
6979
  totalEntries: closedSignal._entry?.length ?? 1,
6936
6980
  totalPartials: closedSignal._partial?.length ?? 0,
6937
6981
  originalPriceOpen: closedSignal.priceOpen,
6938
- pnl: toProfitLossDto(closedSignal, averagePrice),
6982
+ pnl: publicSignal.pnl,
6983
+ maxDrawdown: publicSignal.maxDrawdown,
6984
+ peakProfit: publicSignal.peakProfit,
6985
+ signal: publicSignal,
6939
6986
  note: closedSignal.closeNote ?? closedSignal.note,
6940
6987
  });
6941
6988
  await CALL_CLOSE_CALLBACKS_FN(self, self.params.execution.context.symbol, closedSignal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
6942
6989
  await CALL_PARTIAL_CLEAR_FN(self, self.params.execution.context.symbol, closedSignal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
6943
6990
  await CALL_BREAKEVEN_CLEAR_FN(self, self.params.execution.context.symbol, closedSignal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
6944
6991
  await CALL_RISK_REMOVE_SIGNAL_FN(self, self.params.execution.context.symbol, closeTimestamp, self.params.execution.context.backtest);
6945
- const pnl = toProfitLossDto(closedSignal, averagePrice);
6946
6992
  const result = {
6947
6993
  action: "closed",
6948
- signal: TO_PUBLIC_SIGNAL(closedSignal, averagePrice),
6994
+ signal: publicSignal,
6949
6995
  currentPrice: averagePrice,
6950
6996
  closeReason: "closed",
6951
6997
  closeTimestamp,
6952
- pnl,
6998
+ pnl: publicSignal.pnl,
6953
6999
  strategyName: self.params.method.context.strategyName,
6954
7000
  exchangeName: self.params.method.context.exchangeName,
6955
7001
  frameName: self.params.method.context.frameName,
@@ -7014,8 +7060,8 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
7014
7060
  ...activatedSignal,
7015
7061
  pendingAt: candle.timestamp,
7016
7062
  _isScheduled: false,
7017
- _peak: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0 },
7018
- _fall: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0 },
7063
+ _peak: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
7064
+ _fall: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
7019
7065
  };
7020
7066
  // Sync open: if external system rejects — cancel scheduled signal instead of opening
7021
7067
  const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(candle.timestamp, pendingSignal.priceOpen, pendingSignal, self);
@@ -7025,6 +7071,7 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
7025
7071
  signalId: activatedSignal.id,
7026
7072
  });
7027
7073
  await self.setScheduledSignal(null);
7074
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", activatedSignal, averagePrice);
7028
7075
  await CALL_COMMIT_FN(self, {
7029
7076
  action: "cancel-scheduled",
7030
7077
  symbol: self.params.execution.context.symbol,
@@ -7037,7 +7084,10 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
7037
7084
  totalEntries: activatedSignal._entry?.length ?? 1,
7038
7085
  totalPartials: activatedSignal._partial?.length ?? 0,
7039
7086
  originalPriceOpen: activatedSignal.priceOpen,
7040
- pnl: toProfitLossDto(activatedSignal, averagePrice),
7087
+ pnl: publicSignal.pnl,
7088
+ maxDrawdown: publicSignal.maxDrawdown,
7089
+ peakProfit: publicSignal.peakProfit,
7090
+ signal: publicSignal,
7041
7091
  note: activatedSignal.activateNote ?? activatedSignal.note,
7042
7092
  });
7043
7093
  return { outcome: "pending" };
@@ -7046,7 +7096,7 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
7046
7096
  await self.setPendingSignal(pendingSignal);
7047
7097
  await CALL_RISK_ADD_SIGNAL_FN(self, self.params.execution.context.symbol, pendingSignal, candle.timestamp, self.params.execution.context.backtest);
7048
7098
  // Emit commit AFTER successful risk check
7049
- const publicSignalForCommit = TO_PUBLIC_SIGNAL(pendingSignal, averagePrice);
7099
+ const publicSignalForCommit = TO_PUBLIC_SIGNAL("pending", pendingSignal, averagePrice);
7050
7100
  await CALL_COMMIT_FN(self, {
7051
7101
  action: "activate-scheduled",
7052
7102
  symbol: self.params.execution.context.symbol,
@@ -7058,7 +7108,10 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
7058
7108
  activateId: activatedSignal.activateId,
7059
7109
  timestamp: candle.timestamp,
7060
7110
  currentPrice: averagePrice,
7061
- pnl: toProfitLossDto(pendingSignal, averagePrice),
7111
+ pnl: publicSignalForCommit.pnl,
7112
+ maxDrawdown: publicSignalForCommit.maxDrawdown,
7113
+ peakProfit: publicSignalForCommit.peakProfit,
7114
+ signal: publicSignalForCommit,
7062
7115
  position: publicSignalForCommit.position,
7063
7116
  priceOpen: publicSignalForCommit.priceOpen,
7064
7117
  priceTakeProfit: publicSignalForCommit.priceTakeProfit,
@@ -7228,12 +7281,12 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7228
7281
  const tpDistance = effectiveTakeProfit - effectivePriceOpen;
7229
7282
  const progressPercent = (currentDistance / tpDistance) * 100;
7230
7283
  if (averagePrice > signal._peak.price) {
7231
- const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
7232
- signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
7284
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
7285
+ signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
7233
7286
  if (self.params.callbacks?.onWrite) {
7234
7287
  self.params.callbacks.onWrite(signal.symbol, signal, true);
7235
7288
  }
7236
- await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
7289
+ await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
7237
7290
  }
7238
7291
  await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
7239
7292
  }
@@ -7243,12 +7296,12 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7243
7296
  const slDistance = effectivePriceOpen - effectiveStopLoss;
7244
7297
  const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
7245
7298
  if (averagePrice < signal._fall.price) {
7246
- const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
7247
- signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
7299
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
7300
+ signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
7248
7301
  if (self.params.callbacks?.onWrite) {
7249
7302
  self.params.callbacks.onWrite(signal.symbol, signal, true);
7250
7303
  }
7251
- await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
7304
+ await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
7252
7305
  }
7253
7306
  await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
7254
7307
  }
@@ -7266,12 +7319,12 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7266
7319
  const tpDistance = effectivePriceOpen - effectiveTakeProfit;
7267
7320
  const progressPercent = (currentDistance / tpDistance) * 100;
7268
7321
  if (averagePrice < signal._peak.price) {
7269
- const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
7270
- signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
7322
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
7323
+ signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
7271
7324
  if (self.params.callbacks?.onWrite) {
7272
7325
  self.params.callbacks.onWrite(signal.symbol, signal, true);
7273
7326
  }
7274
- await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
7327
+ await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
7275
7328
  }
7276
7329
  await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
7277
7330
  }
@@ -7281,12 +7334,12 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7281
7334
  const slDistance = effectiveStopLoss - effectivePriceOpen;
7282
7335
  const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
7283
7336
  if (averagePrice > signal._fall.price) {
7284
- const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
7285
- signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
7337
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
7338
+ signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
7286
7339
  if (self.params.callbacks?.onWrite) {
7287
7340
  self.params.callbacks.onWrite(signal.symbol, signal, true);
7288
7341
  }
7289
- await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
7342
+ await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
7290
7343
  }
7291
7344
  await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
7292
7345
  }
@@ -7300,9 +7353,10 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7300
7353
  const lastPrice = GET_AVG_PRICE_FN(lastCandles);
7301
7354
  const closeTimestamp = lastCandles[lastCandles.length - 1].timestamp;
7302
7355
  if (signal.minuteEstimatedTime === Infinity) {
7356
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, lastPrice);
7303
7357
  const result = {
7304
7358
  action: "active",
7305
- signal: TO_PUBLIC_SIGNAL(signal, lastPrice),
7359
+ signal: publicSignal,
7306
7360
  currentPrice: lastPrice,
7307
7361
  strategyName: self.params.method.context.strategyName,
7308
7362
  exchangeName: self.params.method.context.exchangeName,
@@ -7310,7 +7364,7 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7310
7364
  symbol: self.params.execution.context.symbol,
7311
7365
  percentTp: 0,
7312
7366
  percentSl: 0,
7313
- pnl: toProfitLossDto(signal, lastPrice),
7367
+ pnl: publicSignal.pnl,
7314
7368
  backtest: self.params.execution.context.backtest,
7315
7369
  createdAt: closeTimestamp,
7316
7370
  _backtestLastTimestamp: closeTimestamp,
@@ -7493,7 +7547,7 @@ class ClientStrategy {
7493
7547
  this.params.logger.debug("ClientStrategy getPendingSignal", {
7494
7548
  symbol,
7495
7549
  });
7496
- return this._pendingSignal ? TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice) : null;
7550
+ return this._pendingSignal ? TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice) : null;
7497
7551
  }
7498
7552
  /**
7499
7553
  * Retrieves the current scheduled signal.
@@ -7504,7 +7558,7 @@ class ClientStrategy {
7504
7558
  this.params.logger.debug("ClientStrategy getScheduledSignal", {
7505
7559
  symbol,
7506
7560
  });
7507
- return this._scheduledSignal ? TO_PUBLIC_SIGNAL(this._scheduledSignal, currentPrice) : null;
7561
+ return this._scheduledSignal ? TO_PUBLIC_SIGNAL("scheduled", this._scheduledSignal, currentPrice) : null;
7508
7562
  }
7509
7563
  /**
7510
7564
  * Checks if breakeven threshold has been reached for the current pending signal.
@@ -8313,6 +8367,7 @@ class ClientStrategy {
8313
8367
  signalId: cancelledSignal.id,
8314
8368
  });
8315
8369
  // Emit commit with correct timestamp from tick context
8370
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", cancelledSignal, currentPrice);
8316
8371
  await CALL_COMMIT_FN(this, {
8317
8372
  action: "cancel-scheduled",
8318
8373
  symbol: this.params.execution.context.symbol,
@@ -8326,14 +8381,17 @@ class ClientStrategy {
8326
8381
  totalEntries: cancelledSignal._entry?.length ?? 1,
8327
8382
  totalPartials: cancelledSignal._partial?.length ?? 0,
8328
8383
  originalPriceOpen: cancelledSignal.priceOpen,
8329
- pnl: toProfitLossDto(cancelledSignal, currentPrice),
8384
+ pnl: publicSignal.pnl,
8385
+ maxDrawdown: publicSignal.maxDrawdown,
8386
+ peakProfit: publicSignal.peakProfit,
8387
+ signal: publicSignal,
8330
8388
  note: cancelledSignal.cancelNote ?? cancelledSignal.note,
8331
8389
  });
8332
8390
  // Call onCancel callback
8333
8391
  await CALL_CANCEL_CALLBACKS_FN(this, this.params.execution.context.symbol, cancelledSignal, currentPrice, currentTime, this.params.execution.context.backtest);
8334
8392
  const result = {
8335
8393
  action: "cancelled",
8336
- signal: TO_PUBLIC_SIGNAL(cancelledSignal, currentPrice),
8394
+ signal: publicSignal,
8337
8395
  currentPrice,
8338
8396
  closeTimestamp: currentTime,
8339
8397
  strategyName: this.params.method.context.strategyName,
@@ -8367,6 +8425,7 @@ class ClientStrategy {
8367
8425
  signalId: closedSignal.id,
8368
8426
  });
8369
8427
  // Emit commit with correct timestamp from tick context
8428
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", closedSignal, currentPrice);
8370
8429
  await CALL_COMMIT_FN(this, {
8371
8430
  action: "close-pending",
8372
8431
  symbol: this.params.execution.context.symbol,
@@ -8380,7 +8439,10 @@ class ClientStrategy {
8380
8439
  totalEntries: closedSignal._entry?.length ?? 1,
8381
8440
  totalPartials: closedSignal._partial?.length ?? 0,
8382
8441
  originalPriceOpen: closedSignal.priceOpen,
8383
- pnl: toProfitLossDto(closedSignal, currentPrice),
8442
+ pnl: publicSignal.pnl,
8443
+ maxDrawdown: publicSignal.maxDrawdown,
8444
+ peakProfit: publicSignal.peakProfit,
8445
+ signal: publicSignal,
8384
8446
  note: closedSignal.closeNote ?? closedSignal.note,
8385
8447
  });
8386
8448
  // Call onClose callback
@@ -8390,14 +8452,13 @@ class ClientStrategy {
8390
8452
  // КРИТИЧНО: Очищаем состояние ClientBreakeven при закрытии позиции
8391
8453
  await CALL_BREAKEVEN_CLEAR_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, currentTime, this.params.execution.context.backtest);
8392
8454
  await CALL_RISK_REMOVE_SIGNAL_FN(this, this.params.execution.context.symbol, currentTime, this.params.execution.context.backtest);
8393
- const pnl = toProfitLossDto(closedSignal, currentPrice);
8394
8455
  const result = {
8395
8456
  action: "closed",
8396
- signal: TO_PUBLIC_SIGNAL(closedSignal, currentPrice),
8457
+ signal: publicSignal,
8397
8458
  currentPrice,
8398
8459
  closeReason: "closed",
8399
8460
  closeTimestamp: currentTime,
8400
- pnl,
8461
+ pnl: publicSignal.pnl,
8401
8462
  strategyName: this.params.method.context.strategyName,
8402
8463
  exchangeName: this.params.method.context.exchangeName,
8403
8464
  frameName: this.params.method.context.frameName,
@@ -8440,8 +8501,8 @@ class ClientStrategy {
8440
8501
  ...activatedSignal,
8441
8502
  pendingAt: currentTime,
8442
8503
  _isScheduled: false,
8443
- _peak: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
8444
- _fall: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
8504
+ _peak: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, pnlEntries: 0, priceOpen: 0 },
8505
+ _fall: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, pnlEntries: 0, priceOpen: 0 },
8445
8506
  };
8446
8507
  const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(currentTime, currentPrice, pendingSignal, this);
8447
8508
  if (!syncOpenAllowed) {
@@ -8450,6 +8511,7 @@ class ClientStrategy {
8450
8511
  signalId: activatedSignal.id,
8451
8512
  });
8452
8513
  await this.setScheduledSignal(null);
8514
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", activatedSignal, currentPrice);
8453
8515
  await CALL_COMMIT_FN(this, {
8454
8516
  action: "cancel-scheduled",
8455
8517
  symbol: this.params.execution.context.symbol,
@@ -8462,7 +8524,10 @@ class ClientStrategy {
8462
8524
  totalEntries: activatedSignal._entry?.length ?? 1,
8463
8525
  totalPartials: activatedSignal._partial?.length ?? 0,
8464
8526
  originalPriceOpen: activatedSignal.priceOpen,
8465
- pnl: toProfitLossDto(activatedSignal, currentPrice),
8527
+ pnl: publicSignal.pnl,
8528
+ maxDrawdown: publicSignal.maxDrawdown,
8529
+ peakProfit: publicSignal.peakProfit,
8530
+ signal: publicSignal,
8466
8531
  note: activatedSignal.activateNote ?? activatedSignal.note,
8467
8532
  });
8468
8533
  return await RETURN_IDLE_FN(this, currentPrice);
@@ -8470,7 +8535,7 @@ class ClientStrategy {
8470
8535
  await this.setPendingSignal(pendingSignal);
8471
8536
  await CALL_RISK_ADD_SIGNAL_FN(this, this.params.execution.context.symbol, pendingSignal, currentTime, this.params.execution.context.backtest);
8472
8537
  // Emit commit AFTER successful risk check
8473
- const publicSignalForCommit = TO_PUBLIC_SIGNAL(pendingSignal, currentPrice);
8538
+ const publicSignalForCommit = TO_PUBLIC_SIGNAL("pending", pendingSignal, currentPrice);
8474
8539
  await CALL_COMMIT_FN(this, {
8475
8540
  action: "activate-scheduled",
8476
8541
  symbol: this.params.execution.context.symbol,
@@ -8482,7 +8547,10 @@ class ClientStrategy {
8482
8547
  activateId: activatedSignal.activateId,
8483
8548
  timestamp: currentTime,
8484
8549
  currentPrice,
8485
- pnl: toProfitLossDto(pendingSignal, currentPrice),
8550
+ pnl: publicSignalForCommit.pnl,
8551
+ maxDrawdown: publicSignalForCommit.maxDrawdown,
8552
+ peakProfit: publicSignalForCommit.peakProfit,
8553
+ signal: publicSignalForCommit,
8486
8554
  position: publicSignalForCommit.position,
8487
8555
  priceOpen: publicSignalForCommit.priceOpen,
8488
8556
  priceTakeProfit: publicSignalForCommit.priceTakeProfit,
@@ -8500,7 +8568,7 @@ class ClientStrategy {
8500
8568
  await CALL_OPEN_CALLBACKS_FN(this, this.params.execution.context.symbol, pendingSignal, currentPrice, currentTime, this.params.execution.context.backtest);
8501
8569
  const result = {
8502
8570
  action: "opened",
8503
- signal: TO_PUBLIC_SIGNAL(pendingSignal, currentPrice),
8571
+ signal: publicSignalForCommit,
8504
8572
  strategyName: this.params.method.context.strategyName,
8505
8573
  exchangeName: this.params.method.context.exchangeName,
8506
8574
  frameName: this.params.method.context.frameName,
@@ -8616,6 +8684,7 @@ class ClientStrategy {
8616
8684
  this._cancelledSignal = null; // Clear after using
8617
8685
  const closeTimestamp = this.params.execution.context.when.getTime();
8618
8686
  // Emit commit with correct timestamp from backtest context
8687
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", cancelledSignal, currentPrice);
8619
8688
  await CALL_COMMIT_FN(this, {
8620
8689
  action: "cancel-scheduled",
8621
8690
  symbol: this.params.execution.context.symbol,
@@ -8629,13 +8698,16 @@ class ClientStrategy {
8629
8698
  totalEntries: cancelledSignal._entry?.length ?? 1,
8630
8699
  totalPartials: cancelledSignal._partial?.length ?? 0,
8631
8700
  originalPriceOpen: cancelledSignal.priceOpen,
8632
- pnl: toProfitLossDto(cancelledSignal, currentPrice),
8701
+ pnl: publicSignal.pnl,
8702
+ maxDrawdown: publicSignal.maxDrawdown,
8703
+ peakProfit: publicSignal.peakProfit,
8704
+ signal: publicSignal,
8633
8705
  note: cancelledSignal.cancelNote ?? cancelledSignal.note,
8634
8706
  });
8635
8707
  await CALL_CANCEL_CALLBACKS_FN(this, this.params.execution.context.symbol, cancelledSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
8636
8708
  const cancelledResult = {
8637
8709
  action: "cancelled",
8638
- signal: TO_PUBLIC_SIGNAL(cancelledSignal, currentPrice),
8710
+ signal: publicSignal,
8639
8711
  currentPrice,
8640
8712
  closeTimestamp: closeTimestamp,
8641
8713
  strategyName: this.params.method.context.strategyName,
@@ -8671,6 +8743,7 @@ class ClientStrategy {
8671
8743
  }
8672
8744
  this._closedSignal = null; // Clear only after sync confirmed
8673
8745
  // Emit commit with correct timestamp from backtest context
8746
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", closedSignal, currentPrice);
8674
8747
  await CALL_COMMIT_FN(this, {
8675
8748
  action: "close-pending",
8676
8749
  symbol: this.params.execution.context.symbol,
@@ -8684,7 +8757,10 @@ class ClientStrategy {
8684
8757
  totalEntries: closedSignal._entry?.length ?? 1,
8685
8758
  totalPartials: closedSignal._partial?.length ?? 0,
8686
8759
  originalPriceOpen: closedSignal.priceOpen,
8687
- pnl: toProfitLossDto(closedSignal, currentPrice),
8760
+ pnl: publicSignal.pnl,
8761
+ maxDrawdown: publicSignal.maxDrawdown,
8762
+ peakProfit: publicSignal.peakProfit,
8763
+ signal: publicSignal,
8688
8764
  note: closedSignal.closeNote ?? closedSignal.note,
8689
8765
  });
8690
8766
  await CALL_CLOSE_CALLBACKS_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
@@ -8693,14 +8769,13 @@ class ClientStrategy {
8693
8769
  // КРИТИЧНО: Очищаем состояние ClientBreakeven при закрытии позиции
8694
8770
  await CALL_BREAKEVEN_CLEAR_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
8695
8771
  await CALL_RISK_REMOVE_SIGNAL_FN(this, this.params.execution.context.symbol, closeTimestamp, this.params.execution.context.backtest);
8696
- const pnl = toProfitLossDto(closedSignal, currentPrice);
8697
8772
  const closedResult = {
8698
8773
  action: "closed",
8699
- signal: TO_PUBLIC_SIGNAL(closedSignal, currentPrice),
8774
+ signal: publicSignal,
8700
8775
  currentPrice,
8701
8776
  closeReason: "closed",
8702
8777
  closeTimestamp: closeTimestamp,
8703
- pnl,
8778
+ pnl: publicSignal.pnl,
8704
8779
  strategyName: this.params.method.context.strategyName,
8705
8780
  exchangeName: this.params.method.context.exchangeName,
8706
8781
  frameName: this.params.method.context.frameName,
@@ -9156,7 +9231,7 @@ class ClientStrategy {
9156
9231
  });
9157
9232
  // Call onWrite callback for testing persist storage
9158
9233
  if (this.params.callbacks?.onWrite) {
9159
- this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice), backtest);
9234
+ this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice), backtest);
9160
9235
  }
9161
9236
  if (!backtest) {
9162
9237
  await PersistSignalAdapter.writeSignalData(this._pendingSignal, this.params.execution.context.symbol, this.params.strategyName, this.params.exchangeName);
@@ -9339,7 +9414,7 @@ class ClientStrategy {
9339
9414
  });
9340
9415
  // Call onWrite callback for testing persist storage
9341
9416
  if (this.params.callbacks?.onWrite) {
9342
- this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice), backtest);
9417
+ this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice), backtest);
9343
9418
  }
9344
9419
  if (!backtest) {
9345
9420
  await PersistSignalAdapter.writeSignalData(this._pendingSignal, this.params.execution.context.symbol, this.params.strategyName, this.params.exchangeName);
@@ -9537,7 +9612,7 @@ class ClientStrategy {
9537
9612
  });
9538
9613
  // Call onWrite callback for testing persist storage
9539
9614
  if (this.params.callbacks?.onWrite) {
9540
- const publicSignal = TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice);
9615
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice);
9541
9616
  this.params.callbacks.onWrite(this.params.execution.context.symbol, publicSignal, backtest);
9542
9617
  }
9543
9618
  if (!backtest) {
@@ -9786,7 +9861,7 @@ class ClientStrategy {
9786
9861
  });
9787
9862
  // Call onWrite callback for testing persist storage
9788
9863
  if (this.params.callbacks?.onWrite) {
9789
- const publicSignal = TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice);
9864
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice);
9790
9865
  this.params.callbacks.onWrite(this.params.execution.context.symbol, publicSignal, backtest);
9791
9866
  }
9792
9867
  if (!backtest) {
@@ -10022,7 +10097,7 @@ class ClientStrategy {
10022
10097
  });
10023
10098
  // Call onWrite callback for testing persist storage
10024
10099
  if (this.params.callbacks?.onWrite) {
10025
- const publicSignal = TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice);
10100
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice);
10026
10101
  this.params.callbacks.onWrite(this.params.execution.context.symbol, publicSignal, backtest);
10027
10102
  }
10028
10103
  if (!backtest) {
@@ -10114,7 +10189,7 @@ class ClientStrategy {
10114
10189
  });
10115
10190
  // Call onWrite callback for testing persist storage
10116
10191
  if (this.params.callbacks?.onWrite) {
10117
- this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice), backtest);
10192
+ this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice), backtest);
10118
10193
  }
10119
10194
  if (!backtest) {
10120
10195
  await PersistSignalAdapter.writeSignalData(this._pendingSignal, this.params.execution.context.symbol, this.params.strategyName, this.params.exchangeName);
@@ -12485,12 +12560,15 @@ const alignToInterval = (date, interval) => {
12485
12560
 
12486
12561
  /** Symbol indicating that positions need to be fetched from persistence */
12487
12562
  const POSITION_NEED_FETCH = Symbol("risk-need-fetch");
12563
+ /** Get timestamp from execution context or fallback to aligned current time */
12488
12564
  const GET_CONTEXT_TIMESTAMP_FN = (self) => {
12489
12565
  if (ExecutionContextService.hasContext()) {
12490
12566
  return self.params.execution.context.when.getTime();
12491
12567
  }
12492
12568
  return alignToInterval(new Date(), "1m").getTime();
12493
12569
  };
12570
+ /** Zero PNL constant for scheduled signals (which don't have priceOpen or PNL yet) */
12571
+ const ZERO_PNL = { pnlPercentage: 0, priceOpen: 0, priceClose: 0, pnlCost: 0, pnlEntries: 0 };
12494
12572
  /**
12495
12573
  * Converts signal to risk validation format.
12496
12574
  *
@@ -12533,6 +12611,9 @@ const TO_RISK_SIGNAL = (signal, currentPrice, timestamp) => {
12533
12611
  const partialExecuted = ("_partial" in signal && Array.isArray(signal._partial))
12534
12612
  ? signal._partial.reduce((sum, partial) => sum + partial.percent, 0)
12535
12613
  : 0;
12614
+ const pnl = signal._isScheduled ? ZERO_PNL : toProfitLossDto(signal, currentPrice);
12615
+ const maxDrawdown = signal._isScheduled ? ZERO_PNL : pnl;
12616
+ const peakProfit = signal._isScheduled ? ZERO_PNL : pnl;
12536
12617
  return {
12537
12618
  ...structuredClone(signal),
12538
12619
  cost: signal.cost || GLOBAL_CONFIG.CC_POSITION_ENTRY_COST,
@@ -12546,7 +12627,9 @@ const TO_RISK_SIGNAL = (signal, currentPrice, timestamp) => {
12546
12627
  originalPriceTakeProfit: signal.priceTakeProfit,
12547
12628
  originalPriceOpen: signal.priceOpen ?? currentPrice,
12548
12629
  partialExecuted,
12549
- pnl: toProfitLossDto(signal, currentPrice),
12630
+ pnl,
12631
+ maxDrawdown,
12632
+ peakProfit,
12550
12633
  };
12551
12634
  };
12552
12635
  /** Key generator for active position map */
@@ -18816,7 +18899,9 @@ const backtest_columns = [
18816
18899
  key: "peakPnl",
18817
18900
  label: "Peak PNL",
18818
18901
  format: (data) => {
18819
- const v = data.signal._peak?.pnlPercentage;
18902
+ const v = data.signal.peakProfit?.pnlPercentage;
18903
+ if (v === undefined)
18904
+ return "N/A";
18820
18905
  return `${v > 0 ? "+" : ""}${v.toFixed(2)}%`;
18821
18906
  },
18822
18907
  isVisible: () => true,
@@ -18824,7 +18909,12 @@ const backtest_columns = [
18824
18909
  {
18825
18910
  key: "fallPnl",
18826
18911
  label: "Max DD PNL",
18827
- format: (data) => `${data.signal._fall?.pnlPercentage.toFixed(2)}%`,
18912
+ format: (data) => {
18913
+ const v = data.signal.maxDrawdown?.pnlPercentage;
18914
+ if (v === undefined)
18915
+ return "N/A";
18916
+ return `${v.toFixed(2)}%`;
18917
+ },
18828
18918
  isVisible: () => true,
18829
18919
  },
18830
18920
  ];
@@ -21385,8 +21475,8 @@ let ReportStorage$a = class ReportStorage {
21385
21475
  const tradesPerYear = avgDurationDays > 0 ? 365 / avgDurationDays : 0;
21386
21476
  const expectedYearlyReturns = avgPnl * tradesPerYear;
21387
21477
  // Calculate average peak and fall PNL across all signals
21388
- const avgPeakPnl = this._signalList.reduce((sum, s) => sum + (s.signal._peak?.pnlPercentage ?? 0), 0) / totalSignals;
21389
- const avgFallPnl = this._signalList.reduce((sum, s) => sum + (s.signal._fall?.pnlPercentage ?? 0), 0) / totalSignals;
21478
+ const avgPeakPnl = this._signalList.reduce((sum, s) => sum + (s.signal.peakProfit?.pnlPercentage ?? 0), 0) / totalSignals;
21479
+ const avgFallPnl = this._signalList.reduce((sum, s) => sum + (s.signal.maxDrawdown?.pnlPercentage ?? 0), 0) / totalSignals;
21390
21480
  return {
21391
21481
  signalList: this._signalList,
21392
21482
  totalSignals,
@@ -21915,8 +22005,8 @@ let ReportStorage$9 = class ReportStorage {
21915
22005
  duration: durationMin,
21916
22006
  pendingAt: data.signal.pendingAt,
21917
22007
  scheduledAt: data.signal.scheduledAt,
21918
- peakPnl: data.signal._peak?.pnlPercentage,
21919
- fallPnl: data.signal._fall?.pnlPercentage,
22008
+ peakPnl: data.signal.peakProfit?.pnlPercentage,
22009
+ fallPnl: data.signal.maxDrawdown?.pnlPercentage,
21920
22010
  };
21921
22011
  this._eventList.unshift(newEvent);
21922
22012
  // Trim queue if exceeded GLOBAL_CONFIG.CC_MAX_LIVE_MARKDOWN_ROWS
@@ -24067,8 +24157,8 @@ class HeatmapStorage {
24067
24157
  let avgPeakPnl = null;
24068
24158
  let avgFallPnl = null;
24069
24159
  if (signals.length > 0) {
24070
- avgPeakPnl = signals.reduce((acc, s) => acc + (s.signal._peak?.pnlPercentage ?? 0), 0) / signals.length;
24071
- avgFallPnl = signals.reduce((acc, s) => acc + (s.signal._fall?.pnlPercentage ?? 0), 0) / signals.length;
24160
+ avgPeakPnl = signals.reduce((acc, s) => acc + (s.signal.peakProfit?.pnlPercentage ?? 0), 0) / signals.length;
24161
+ avgFallPnl = signals.reduce((acc, s) => acc + (s.signal.maxDrawdown?.pnlPercentage ?? 0), 0) / signals.length;
24072
24162
  }
24073
24163
  // Apply safe math checks
24074
24164
  if (isUnsafe(winRate))
@@ -28195,8 +28285,16 @@ class BacktestReportService {
28195
28285
  pnlPriceClose: data.pnl.priceClose,
28196
28286
  totalPartials: data.signal?.totalPartials,
28197
28287
  cost: data.signal?.cost,
28198
- peakPnl: data.signal?._peak?.pnlPercentage,
28199
- fallPnl: data.signal?._fall?.pnlPercentage,
28288
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
28289
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
28290
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
28291
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
28292
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
28293
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
28294
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
28295
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
28296
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
28297
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
28200
28298
  }, { ...searchOptions, signalId: data.signal?.id });
28201
28299
  }
28202
28300
  else if (data.action === "closed") {
@@ -28229,8 +28327,16 @@ class BacktestReportService {
28229
28327
  closeReason: data.closeReason,
28230
28328
  closeTime: data.closeTimestamp,
28231
28329
  duration: durationMin,
28232
- peakPnl: data.signal?._peak?.pnlPercentage,
28233
- fallPnl: data.signal?._fall?.pnlPercentage,
28330
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
28331
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
28332
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
28333
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
28334
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
28335
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
28336
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
28337
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
28338
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
28339
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
28234
28340
  }, { ...searchOptions, signalId: data.signal?.id });
28235
28341
  }
28236
28342
  };
@@ -28393,8 +28499,16 @@ class LiveReportService {
28393
28499
  pnlPriceClose: data.pnl.priceClose,
28394
28500
  totalPartials: data.signal?.totalPartials,
28395
28501
  cost: data.signal?.cost,
28396
- peakPnl: data.signal?._peak?.pnlPercentage,
28397
- fallPnl: data.signal?._fall?.pnlPercentage,
28502
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
28503
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
28504
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
28505
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
28506
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
28507
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
28508
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
28509
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
28510
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
28511
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
28398
28512
  }, { ...searchOptions, signalId: data.signal?.id });
28399
28513
  }
28400
28514
  else if (data.action === "opened") {
@@ -28445,8 +28559,16 @@ class LiveReportService {
28445
28559
  pnlPriceClose: data.pnl.priceClose,
28446
28560
  totalPartials: data.signal?.totalPartials,
28447
28561
  cost: data.signal?.cost,
28448
- peakPnl: data.signal?._peak?.pnlPercentage,
28449
- fallPnl: data.signal?._fall?.pnlPercentage,
28562
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
28563
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
28564
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
28565
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
28566
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
28567
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
28568
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
28569
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
28570
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
28571
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
28450
28572
  }, { ...searchOptions, signalId: data.signal?.id });
28451
28573
  }
28452
28574
  else if (data.action === "closed") {
@@ -28479,8 +28601,16 @@ class LiveReportService {
28479
28601
  closeReason: data.closeReason,
28480
28602
  duration: durationMin,
28481
28603
  closeTime: data.closeTimestamp,
28482
- peakPnl: data.signal?._peak?.pnlPercentage,
28483
- fallPnl: data.signal?._fall?.pnlPercentage,
28604
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
28605
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
28606
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
28607
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
28608
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
28609
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
28610
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
28611
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
28612
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
28613
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
28484
28614
  }, { ...searchOptions, signalId: data.signal?.id });
28485
28615
  }
28486
28616
  else if (data.action === "cancelled") {
@@ -29072,8 +29202,16 @@ class HeatReportService {
29072
29202
  openTime: data.signal?.pendingAt,
29073
29203
  scheduledAt: data.signal?.scheduledAt,
29074
29204
  closeTime: data.closeTimestamp,
29075
- peakPnl: data.signal?._peak?.pnlPercentage,
29076
- fallPnl: data.signal?._fall?.pnlPercentage,
29205
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
29206
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
29207
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
29208
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
29209
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
29210
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
29211
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
29212
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
29213
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
29214
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
29077
29215
  }, {
29078
29216
  symbol: data.symbol,
29079
29217
  strategyName: data.strategyName,
@@ -29207,6 +29345,16 @@ class PartialReportService {
29207
29345
  pnlEntries: data.data.pnl.pnlEntries,
29208
29346
  pnlPriceOpen: data.data.pnl.priceOpen,
29209
29347
  pnlPriceClose: data.data.pnl.priceClose,
29348
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
29349
+ peakProfitCost: data.data.peakProfit.pnlCost,
29350
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
29351
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
29352
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
29353
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
29354
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
29355
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
29356
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
29357
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
29210
29358
  }, {
29211
29359
  symbol: data.symbol,
29212
29360
  strategyName: data.data.strategyName,
@@ -29257,6 +29405,16 @@ class PartialReportService {
29257
29405
  pnlEntries: data.data.pnl.pnlEntries,
29258
29406
  pnlPriceOpen: data.data.pnl.priceOpen,
29259
29407
  pnlPriceClose: data.data.pnl.priceClose,
29408
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
29409
+ peakProfitCost: data.data.peakProfit.pnlCost,
29410
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
29411
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
29412
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
29413
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
29414
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
29415
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
29416
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
29417
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
29260
29418
  }, {
29261
29419
  symbol: data.symbol,
29262
29420
  strategyName: data.data.strategyName,
@@ -29388,6 +29546,16 @@ class BreakevenReportService {
29388
29546
  pnlEntries: data.data.pnl.pnlEntries,
29389
29547
  pnlPriceOpen: data.data.pnl.priceOpen,
29390
29548
  pnlPriceClose: data.data.pnl.priceClose,
29549
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
29550
+ peakProfitCost: data.data.peakProfit.pnlCost,
29551
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
29552
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
29553
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
29554
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
29555
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
29556
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
29557
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
29558
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
29391
29559
  }, {
29392
29560
  symbol: data.symbol,
29393
29561
  strategyName: data.data.strategyName,
@@ -29518,6 +29686,16 @@ class RiskReportService {
29518
29686
  pnlEntries: data.currentSignal?.pnl?.pnlEntries,
29519
29687
  pnlPriceOpen: data.currentSignal?.pnl?.priceOpen,
29520
29688
  pnlPriceClose: data.currentSignal?.pnl?.priceClose,
29689
+ peakProfitPercentage: data.currentSignal?.peakProfit?.pnlPercentage,
29690
+ peakProfitCost: data.currentSignal?.peakProfit?.pnlCost,
29691
+ peakProfitEntries: data.currentSignal?.peakProfit?.pnlEntries,
29692
+ peakProfitPriceOpen: data.currentSignal?.peakProfit?.priceOpen,
29693
+ peakProfitPriceClose: data.currentSignal?.peakProfit?.priceClose,
29694
+ maxDrawdownPercentage: data.currentSignal?.maxDrawdown?.pnlPercentage,
29695
+ maxDrawdownCost: data.currentSignal?.maxDrawdown?.pnlCost,
29696
+ maxDrawdownEntries: data.currentSignal?.maxDrawdown?.pnlEntries,
29697
+ maxDrawdownPriceOpen: data.currentSignal?.maxDrawdown?.priceOpen,
29698
+ maxDrawdownPriceClose: data.currentSignal?.maxDrawdown?.priceClose,
29521
29699
  }, {
29522
29700
  symbol: data.symbol,
29523
29701
  strategyName: data.strategyName,
@@ -29597,7 +29775,7 @@ class StrategyReportService {
29597
29775
  /**
29598
29776
  * Logs a cancel-scheduled event when a scheduled signal is cancelled.
29599
29777
  */
29600
- this.cancelScheduled = async (symbol, isBacktest, context, timestamp, signalId, pnl, totalPartials, cancelId, note) => {
29778
+ this.cancelScheduled = async (symbol, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, cancelId, note) => {
29601
29779
  this.loggerService.log("strategyReportService cancelScheduled", {
29602
29780
  symbol,
29603
29781
  isBacktest,
@@ -29619,6 +29797,16 @@ class StrategyReportService {
29619
29797
  pnlEntries: pnl.pnlEntries,
29620
29798
  pnlPriceOpen: pnl.priceOpen,
29621
29799
  pnlPriceClose: pnl.priceClose,
29800
+ peakProfitPercentage: peakProfit.pnlPercentage,
29801
+ peakProfitCost: peakProfit.pnlCost,
29802
+ peakProfitEntries: peakProfit.pnlEntries,
29803
+ peakProfitPriceOpen: peakProfit.priceOpen,
29804
+ peakProfitPriceClose: peakProfit.priceClose,
29805
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
29806
+ maxDrawdownCost: maxDrawdown.pnlCost,
29807
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
29808
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
29809
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29622
29810
  totalPartials,
29623
29811
  }, {
29624
29812
  signalId,
@@ -29632,7 +29820,7 @@ class StrategyReportService {
29632
29820
  /**
29633
29821
  * Logs a close-pending event when a pending signal is closed.
29634
29822
  */
29635
- this.closePending = async (symbol, isBacktest, context, timestamp, signalId, pnl, totalPartials, closeId, note) => {
29823
+ this.closePending = async (symbol, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, closeId, note) => {
29636
29824
  this.loggerService.log("strategyReportService closePending", {
29637
29825
  symbol,
29638
29826
  isBacktest,
@@ -29654,6 +29842,16 @@ class StrategyReportService {
29654
29842
  pnlEntries: pnl.pnlEntries,
29655
29843
  pnlPriceOpen: pnl.priceOpen,
29656
29844
  pnlPriceClose: pnl.priceClose,
29845
+ peakProfitPercentage: peakProfit.pnlPercentage,
29846
+ peakProfitCost: peakProfit.pnlCost,
29847
+ peakProfitEntries: peakProfit.pnlEntries,
29848
+ peakProfitPriceOpen: peakProfit.priceOpen,
29849
+ peakProfitPriceClose: peakProfit.priceClose,
29850
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
29851
+ maxDrawdownCost: maxDrawdown.pnlCost,
29852
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
29853
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
29854
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29657
29855
  totalPartials,
29658
29856
  }, {
29659
29857
  signalId,
@@ -29667,7 +29865,7 @@ class StrategyReportService {
29667
29865
  /**
29668
29866
  * Logs a partial-profit event when a portion of the position is closed at profit.
29669
29867
  */
29670
- this.partialProfit = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29868
+ this.partialProfit = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29671
29869
  this.loggerService.log("strategyReportService partialProfit", {
29672
29870
  symbol,
29673
29871
  percentToClose,
@@ -29700,6 +29898,16 @@ class StrategyReportService {
29700
29898
  pnlEntries: pnl.pnlEntries,
29701
29899
  pnlPriceOpen: pnl.priceOpen,
29702
29900
  pnlPriceClose: pnl.priceClose,
29901
+ peakProfitPercentage: peakProfit.pnlPercentage,
29902
+ peakProfitCost: peakProfit.pnlCost,
29903
+ peakProfitEntries: peakProfit.pnlEntries,
29904
+ peakProfitPriceOpen: peakProfit.priceOpen,
29905
+ peakProfitPriceClose: peakProfit.priceClose,
29906
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
29907
+ maxDrawdownCost: maxDrawdown.pnlCost,
29908
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
29909
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
29910
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29703
29911
  totalPartials,
29704
29912
  }, {
29705
29913
  signalId,
@@ -29713,7 +29921,7 @@ class StrategyReportService {
29713
29921
  /**
29714
29922
  * Logs a partial-loss event when a portion of the position is closed at loss.
29715
29923
  */
29716
- this.partialLoss = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29924
+ this.partialLoss = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29717
29925
  this.loggerService.log("strategyReportService partialLoss", {
29718
29926
  symbol,
29719
29927
  percentToClose,
@@ -29746,6 +29954,16 @@ class StrategyReportService {
29746
29954
  pnlEntries: pnl.pnlEntries,
29747
29955
  pnlPriceOpen: pnl.priceOpen,
29748
29956
  pnlPriceClose: pnl.priceClose,
29957
+ peakProfitPercentage: peakProfit.pnlPercentage,
29958
+ peakProfitCost: peakProfit.pnlCost,
29959
+ peakProfitEntries: peakProfit.pnlEntries,
29960
+ peakProfitPriceOpen: peakProfit.priceOpen,
29961
+ peakProfitPriceClose: peakProfit.priceClose,
29962
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
29963
+ maxDrawdownCost: maxDrawdown.pnlCost,
29964
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
29965
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
29966
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29749
29967
  totalPartials,
29750
29968
  }, {
29751
29969
  signalId,
@@ -29759,7 +29977,7 @@ class StrategyReportService {
29759
29977
  /**
29760
29978
  * Logs a trailing-stop event when the stop-loss is adjusted.
29761
29979
  */
29762
- this.trailingStop = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29980
+ this.trailingStop = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29763
29981
  this.loggerService.log("strategyReportService trailingStop", {
29764
29982
  symbol,
29765
29983
  percentShift,
@@ -29792,6 +30010,16 @@ class StrategyReportService {
29792
30010
  pnlEntries: pnl.pnlEntries,
29793
30011
  pnlPriceOpen: pnl.priceOpen,
29794
30012
  pnlPriceClose: pnl.priceClose,
30013
+ peakProfitPercentage: peakProfit.pnlPercentage,
30014
+ peakProfitCost: peakProfit.pnlCost,
30015
+ peakProfitEntries: peakProfit.pnlEntries,
30016
+ peakProfitPriceOpen: peakProfit.priceOpen,
30017
+ peakProfitPriceClose: peakProfit.priceClose,
30018
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
30019
+ maxDrawdownCost: maxDrawdown.pnlCost,
30020
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
30021
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
30022
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29795
30023
  totalPartials,
29796
30024
  }, {
29797
30025
  signalId,
@@ -29805,7 +30033,7 @@ class StrategyReportService {
29805
30033
  /**
29806
30034
  * Logs a trailing-take event when the take-profit is adjusted.
29807
30035
  */
29808
- this.trailingTake = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
30036
+ this.trailingTake = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29809
30037
  this.loggerService.log("strategyReportService trailingTake", {
29810
30038
  symbol,
29811
30039
  percentShift,
@@ -29838,6 +30066,16 @@ class StrategyReportService {
29838
30066
  pnlEntries: pnl.pnlEntries,
29839
30067
  pnlPriceOpen: pnl.priceOpen,
29840
30068
  pnlPriceClose: pnl.priceClose,
30069
+ peakProfitPercentage: peakProfit.pnlPercentage,
30070
+ peakProfitCost: peakProfit.pnlCost,
30071
+ peakProfitEntries: peakProfit.pnlEntries,
30072
+ peakProfitPriceOpen: peakProfit.priceOpen,
30073
+ peakProfitPriceClose: peakProfit.priceClose,
30074
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
30075
+ maxDrawdownCost: maxDrawdown.pnlCost,
30076
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
30077
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
30078
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29841
30079
  totalPartials,
29842
30080
  }, {
29843
30081
  signalId,
@@ -29851,7 +30089,7 @@ class StrategyReportService {
29851
30089
  /**
29852
30090
  * Logs a breakeven event when the stop-loss is moved to entry price.
29853
30091
  */
29854
- this.breakeven = async (symbol, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
30092
+ this.breakeven = async (symbol, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29855
30093
  this.loggerService.log("strategyReportService breakeven", {
29856
30094
  symbol,
29857
30095
  currentPrice,
@@ -29882,6 +30120,16 @@ class StrategyReportService {
29882
30120
  pnlEntries: pnl.pnlEntries,
29883
30121
  pnlPriceOpen: pnl.priceOpen,
29884
30122
  pnlPriceClose: pnl.priceClose,
30123
+ peakProfitPercentage: peakProfit.pnlPercentage,
30124
+ peakProfitCost: peakProfit.pnlCost,
30125
+ peakProfitEntries: peakProfit.pnlEntries,
30126
+ peakProfitPriceOpen: peakProfit.priceOpen,
30127
+ peakProfitPriceClose: peakProfit.priceClose,
30128
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
30129
+ maxDrawdownCost: maxDrawdown.pnlCost,
30130
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
30131
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
30132
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29885
30133
  totalPartials,
29886
30134
  }, {
29887
30135
  signalId,
@@ -29895,7 +30143,7 @@ class StrategyReportService {
29895
30143
  /**
29896
30144
  * Logs an activate-scheduled event when a scheduled signal is activated early.
29897
30145
  */
29898
- this.activateScheduled = async (symbol, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen, activateId, note) => {
30146
+ this.activateScheduled = async (symbol, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen, activateId, note) => {
29899
30147
  this.loggerService.log("strategyReportService activateScheduled", {
29900
30148
  symbol,
29901
30149
  currentPrice,
@@ -29929,6 +30177,16 @@ class StrategyReportService {
29929
30177
  pnlEntries: pnl.pnlEntries,
29930
30178
  pnlPriceOpen: pnl.priceOpen,
29931
30179
  pnlPriceClose: pnl.priceClose,
30180
+ peakProfitPercentage: peakProfit.pnlPercentage,
30181
+ peakProfitCost: peakProfit.pnlCost,
30182
+ peakProfitEntries: peakProfit.pnlEntries,
30183
+ peakProfitPriceOpen: peakProfit.priceOpen,
30184
+ peakProfitPriceClose: peakProfit.priceClose,
30185
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
30186
+ maxDrawdownCost: maxDrawdown.pnlCost,
30187
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
30188
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
30189
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29932
30190
  totalPartials,
29933
30191
  }, {
29934
30192
  signalId,
@@ -29942,7 +30200,7 @@ class StrategyReportService {
29942
30200
  /**
29943
30201
  * Logs an average-buy (DCA) event when a new averaging entry is added to an open position.
29944
30202
  */
29945
- this.averageBuy = async (symbol, currentPrice, effectivePriceOpen, totalEntries, isBacktest, context, timestamp, signalId, pnl, totalPartials, cost, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, originalPriceOpen) => {
30203
+ this.averageBuy = async (symbol, currentPrice, effectivePriceOpen, totalEntries, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, cost, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, originalPriceOpen) => {
29946
30204
  this.loggerService.log("strategyReportService averageBuy", {
29947
30205
  symbol,
29948
30206
  currentPrice,
@@ -29976,6 +30234,16 @@ class StrategyReportService {
29976
30234
  pnlEntries: pnl.pnlEntries,
29977
30235
  pnlPriceOpen: pnl.priceOpen,
29978
30236
  pnlPriceClose: pnl.priceClose,
30237
+ peakProfitPercentage: peakProfit.pnlPercentage,
30238
+ peakProfitCost: peakProfit.pnlCost,
30239
+ peakProfitEntries: peakProfit.pnlEntries,
30240
+ peakProfitPriceOpen: peakProfit.priceOpen,
30241
+ peakProfitPriceClose: peakProfit.priceClose,
30242
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
30243
+ maxDrawdownCost: maxDrawdown.pnlCost,
30244
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
30245
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
30246
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29979
30247
  totalPartials,
29980
30248
  cost,
29981
30249
  }, {
@@ -30003,63 +30271,63 @@ class StrategyReportService {
30003
30271
  exchangeName: event.exchangeName,
30004
30272
  frameName: event.frameName,
30005
30273
  strategyName: event.strategyName,
30006
- }, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.cancelId, event.note));
30274
+ }, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.cancelId, event.note));
30007
30275
  const unClosePending = strategyCommitSubject
30008
30276
  .filter(({ action }) => action === "close-pending")
30009
30277
  .connect(async (event) => await this.closePending(event.symbol, event.backtest, {
30010
30278
  exchangeName: event.exchangeName,
30011
30279
  frameName: event.frameName,
30012
30280
  strategyName: event.strategyName,
30013
- }, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.closeId, event.note));
30281
+ }, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.closeId, event.note));
30014
30282
  const unPartialProfit = strategyCommitSubject
30015
30283
  .filter(({ action }) => action === "partial-profit")
30016
30284
  .connect(async (event) => await this.partialProfit(event.symbol, event.percentToClose, event.currentPrice, event.backtest, {
30017
30285
  exchangeName: event.exchangeName,
30018
30286
  frameName: event.frameName,
30019
30287
  strategyName: event.strategyName,
30020
- }, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
30288
+ }, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
30021
30289
  const unPartialLoss = strategyCommitSubject
30022
30290
  .filter(({ action }) => action === "partial-loss")
30023
30291
  .connect(async (event) => await this.partialLoss(event.symbol, event.percentToClose, event.currentPrice, event.backtest, {
30024
30292
  exchangeName: event.exchangeName,
30025
30293
  frameName: event.frameName,
30026
30294
  strategyName: event.strategyName,
30027
- }, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
30295
+ }, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
30028
30296
  const unTrailingStop = strategyCommitSubject
30029
30297
  .filter(({ action }) => action === "trailing-stop")
30030
30298
  .connect(async (event) => await this.trailingStop(event.symbol, event.percentShift, event.currentPrice, event.backtest, {
30031
30299
  exchangeName: event.exchangeName,
30032
30300
  frameName: event.frameName,
30033
30301
  strategyName: event.strategyName,
30034
- }, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
30302
+ }, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
30035
30303
  const unTrailingTake = strategyCommitSubject
30036
30304
  .filter(({ action }) => action === "trailing-take")
30037
30305
  .connect(async (event) => await this.trailingTake(event.symbol, event.percentShift, event.currentPrice, event.backtest, {
30038
30306
  exchangeName: event.exchangeName,
30039
30307
  frameName: event.frameName,
30040
30308
  strategyName: event.strategyName,
30041
- }, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
30309
+ }, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
30042
30310
  const unBreakeven = strategyCommitSubject
30043
30311
  .filter(({ action }) => action === "breakeven")
30044
30312
  .connect(async (event) => await this.breakeven(event.symbol, event.currentPrice, event.backtest, {
30045
30313
  exchangeName: event.exchangeName,
30046
30314
  frameName: event.frameName,
30047
30315
  strategyName: event.strategyName,
30048
- }, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
30316
+ }, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
30049
30317
  const unActivateScheduled = strategyCommitSubject
30050
30318
  .filter(({ action }) => action === "activate-scheduled")
30051
30319
  .connect(async (event) => await this.activateScheduled(event.symbol, event.currentPrice, event.backtest, {
30052
30320
  exchangeName: event.exchangeName,
30053
30321
  frameName: event.frameName,
30054
30322
  strategyName: event.strategyName,
30055
- }, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen, event.activateId, event.note));
30323
+ }, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen, event.activateId, event.note));
30056
30324
  const unAverageBuy = strategyCommitSubject
30057
30325
  .filter(({ action }) => action === "average-buy")
30058
30326
  .connect(async (event) => await this.averageBuy(event.symbol, event.currentPrice, event.effectivePriceOpen, event.totalEntries, event.backtest, {
30059
30327
  exchangeName: event.exchangeName,
30060
30328
  frameName: event.frameName,
30061
30329
  strategyName: event.strategyName,
30062
- }, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.cost, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.originalPriceOpen));
30330
+ }, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.cost, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.originalPriceOpen));
30063
30331
  const disposeFn = functoolsKit.compose(() => unCancelSchedule(), () => unClosePending(), () => unPartialProfit(), () => unPartialLoss(), () => unTrailingStop(), () => unTrailingTake(), () => unBreakeven(), () => unActivateScheduled(), () => unAverageBuy());
30064
30332
  return () => {
30065
30333
  disposeFn();
@@ -30158,6 +30426,16 @@ class SyncReportService {
30158
30426
  pnlEntries: data.pnl.pnlEntries,
30159
30427
  pnlPriceOpen: data.pnl.priceOpen,
30160
30428
  pnlPriceClose: data.pnl.priceClose,
30429
+ peakProfitPercentage: data.peakProfit.pnlPercentage,
30430
+ peakProfitCost: data.peakProfit.pnlCost,
30431
+ peakProfitEntries: data.peakProfit.pnlEntries,
30432
+ peakProfitPriceOpen: data.peakProfit.priceOpen,
30433
+ peakProfitPriceClose: data.peakProfit.priceClose,
30434
+ maxDrawdownPercentage: data.maxDrawdown.pnlPercentage,
30435
+ maxDrawdownCost: data.maxDrawdown.pnlCost,
30436
+ maxDrawdownEntries: data.maxDrawdown.pnlEntries,
30437
+ maxDrawdownPriceOpen: data.maxDrawdown.priceOpen,
30438
+ maxDrawdownPriceClose: data.maxDrawdown.priceClose,
30161
30439
  currentPrice: data.currentPrice,
30162
30440
  };
30163
30441
  const searchOptions = {
@@ -30268,6 +30546,16 @@ class HighestProfitReportService {
30268
30546
  priceOpen: data.signal.priceOpen,
30269
30547
  priceTakeProfit: data.signal.priceTakeProfit,
30270
30548
  priceStopLoss: data.signal.priceStopLoss,
30549
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
30550
+ peakProfitCost: data.signal.peakProfit.pnlCost,
30551
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
30552
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
30553
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
30554
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
30555
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
30556
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
30557
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
30558
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
30271
30559
  }, {
30272
30560
  symbol: data.symbol,
30273
30561
  strategyName: data.signal.strategyName,
@@ -31545,7 +31833,9 @@ class SyncMarkdownService {
31545
31833
  pendingAt: data.pendingAt,
31546
31834
  totalEntries: data.totalEntries,
31547
31835
  totalPartials: data.totalPartials,
31548
- pnl: data.pnl,
31836
+ pnl: data.signal.pnl,
31837
+ maxDrawdown: data.signal.maxDrawdown,
31838
+ peakProfit: data.signal.peakProfit,
31549
31839
  closeReason: data.action === "signal-close" ? data.closeReason : undefined,
31550
31840
  backtest: data.backtest,
31551
31841
  createdAt,
@@ -31720,6 +32010,8 @@ let ReportStorage$1 = class ReportStorage {
31720
32010
  signalId: data.id,
31721
32011
  position: data.position,
31722
32012
  pnl: data.pnl,
32013
+ maxDrawdown: data.maxDrawdown,
32014
+ peakProfit: data.peakProfit,
31723
32015
  currentPrice,
31724
32016
  priceOpen: data.priceOpen,
31725
32017
  priceTakeProfit: data.priceTakeProfit,
@@ -32331,6 +32623,16 @@ class MaxDrawdownReportService {
32331
32623
  priceOpen: data.signal.priceOpen,
32332
32624
  priceTakeProfit: data.signal.priceTakeProfit,
32333
32625
  priceStopLoss: data.signal.priceStopLoss,
32626
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
32627
+ peakProfitCost: data.signal.peakProfit.pnlCost,
32628
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
32629
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
32630
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
32631
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
32632
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
32633
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
32634
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
32635
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
32334
32636
  }, {
32335
32637
  symbol: data.symbol,
32336
32638
  strategyName: data.signal.strategyName,
@@ -32423,6 +32725,8 @@ class ReportStorage {
32423
32725
  signalId: data.id,
32424
32726
  position: data.position,
32425
32727
  pnl: data.pnl,
32728
+ maxDrawdown: data.maxDrawdown,
32729
+ peakProfit: data.peakProfit,
32426
32730
  currentPrice,
32427
32731
  priceOpen: data.priceOpen,
32428
32732
  priceTakeProfit: data.priceTakeProfit,
@@ -35374,6 +35678,9 @@ class BrokerAdapter {
35374
35678
  priceTakeProfit: event.signal.priceTakeProfit,
35375
35679
  priceStopLoss: event.signal.priceStopLoss,
35376
35680
  priceOpen: event.signal.priceOpen,
35681
+ pnl: event.signal.pnl,
35682
+ peakProfit: event.signal.peakProfit,
35683
+ maxDrawdown: event.signal.maxDrawdown,
35377
35684
  context: {
35378
35685
  strategyName: event.strategyName,
35379
35686
  exchangeName: event.exchangeName,
@@ -35391,7 +35698,10 @@ class BrokerAdapter {
35391
35698
  currentPrice: event.currentPrice,
35392
35699
  cost: event.signal.cost,
35393
35700
  symbol: event.symbol,
35394
- pnl: event.pnl,
35701
+ pnl: event.signal.pnl,
35702
+ priceOpen: event.signal.priceOpen,
35703
+ peakProfit: event.signal.peakProfit,
35704
+ maxDrawdown: event.signal.maxDrawdown,
35395
35705
  totalEntries: event.totalEntries,
35396
35706
  totalPartials: event.totalPartials,
35397
35707
  priceStopLoss: event.signal.priceStopLoss,
@@ -54433,11 +54743,23 @@ const CREATE_SIGNAL_NOTIFICATION_FN = (data) => {
54433
54743
  totalPartials: data.signal.totalPartials,
54434
54744
  cost: data.signal.cost,
54435
54745
  pnl: data.signal.pnl,
54746
+ maxDrawdown: data.signal.maxDrawdown,
54747
+ peakProfit: data.signal.peakProfit,
54436
54748
  pnlPercentage: data.signal.pnl.pnlPercentage,
54437
54749
  pnlPriceOpen: data.signal.pnl.priceOpen,
54438
54750
  pnlPriceClose: data.signal.pnl.priceClose,
54439
54751
  pnlCost: data.signal.pnl.pnlCost,
54440
54752
  pnlEntries: data.signal.pnl.pnlEntries,
54753
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
54754
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
54755
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
54756
+ peakProfitCost: data.signal.peakProfit.pnlCost,
54757
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
54758
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
54759
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
54760
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
54761
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
54762
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54441
54763
  note: data.signal.note,
54442
54764
  scheduledAt: data.signal.scheduledAt,
54443
54765
  pendingAt: data.signal.pendingAt,
@@ -54467,11 +54789,23 @@ const CREATE_SIGNAL_NOTIFICATION_FN = (data) => {
54467
54789
  totalEntries: data.signal.totalEntries,
54468
54790
  totalPartials: data.signal.totalPartials,
54469
54791
  pnlPercentage: data.pnl.pnlPercentage,
54470
- pnl: data.pnl,
54792
+ pnl: data.signal.pnl,
54793
+ maxDrawdown: data.signal.maxDrawdown,
54794
+ peakProfit: data.signal.peakProfit,
54471
54795
  pnlPriceOpen: data.pnl.priceOpen,
54472
54796
  pnlPriceClose: data.pnl.priceClose,
54473
54797
  pnlCost: data.pnl.pnlCost,
54474
54798
  pnlEntries: data.pnl.pnlEntries,
54799
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
54800
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
54801
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
54802
+ peakProfitCost: data.signal.peakProfit.pnlCost,
54803
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
54804
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
54805
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
54806
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
54807
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
54808
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54475
54809
  closeReason: data.closeReason,
54476
54810
  duration: durationMin,
54477
54811
  note: data.signal.note,
@@ -54501,11 +54835,23 @@ const CREATE_SIGNAL_NOTIFICATION_FN = (data) => {
54501
54835
  totalPartials: data.signal.totalPartials,
54502
54836
  cost: data.signal.cost,
54503
54837
  pnl: data.signal.pnl,
54838
+ maxDrawdown: data.signal.maxDrawdown,
54839
+ peakProfit: data.signal.peakProfit,
54504
54840
  pnlPercentage: data.signal.pnl.pnlPercentage,
54505
54841
  pnlPriceOpen: data.signal.pnl.priceOpen,
54506
54842
  pnlPriceClose: data.signal.pnl.priceClose,
54507
54843
  pnlCost: data.signal.pnl.pnlCost,
54508
54844
  pnlEntries: data.signal.pnl.pnlEntries,
54845
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
54846
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
54847
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
54848
+ peakProfitCost: data.signal.peakProfit.pnlCost,
54849
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
54850
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
54851
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
54852
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
54853
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
54854
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54509
54855
  scheduledAt: data.signal.scheduledAt,
54510
54856
  currentPrice: data.currentPrice,
54511
54857
  note: data.signal.note,
@@ -54570,11 +54916,23 @@ const CREATE_PARTIAL_PROFIT_NOTIFICATION_FN = (data) => ({
54570
54916
  totalEntries: data.data.totalEntries,
54571
54917
  totalPartials: data.data.totalPartials,
54572
54918
  pnl: data.data.pnl,
54919
+ maxDrawdown: data.data.maxDrawdown,
54920
+ peakProfit: data.data.peakProfit,
54573
54921
  pnlPercentage: data.data.pnl.pnlPercentage,
54574
54922
  pnlPriceOpen: data.data.pnl.priceOpen,
54575
54923
  pnlPriceClose: data.data.pnl.priceClose,
54576
54924
  pnlCost: data.data.pnl.pnlCost,
54577
54925
  pnlEntries: data.data.pnl.pnlEntries,
54926
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
54927
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
54928
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
54929
+ peakProfitCost: data.data.peakProfit.pnlCost,
54930
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
54931
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
54932
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
54933
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
54934
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
54935
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
54578
54936
  note: data.data.note,
54579
54937
  scheduledAt: data.data.scheduledAt,
54580
54938
  pendingAt: data.data.pendingAt,
@@ -54606,11 +54964,23 @@ const CREATE_PARTIAL_LOSS_NOTIFICATION_FN = (data) => ({
54606
54964
  totalEntries: data.data.totalEntries,
54607
54965
  totalPartials: data.data.totalPartials,
54608
54966
  pnl: data.data.pnl,
54967
+ maxDrawdown: data.data.maxDrawdown,
54968
+ peakProfit: data.data.peakProfit,
54609
54969
  pnlPercentage: data.data.pnl.pnlPercentage,
54610
54970
  pnlPriceOpen: data.data.pnl.priceOpen,
54611
54971
  pnlPriceClose: data.data.pnl.priceClose,
54612
54972
  pnlCost: data.data.pnl.pnlCost,
54613
54973
  pnlEntries: data.data.pnl.pnlEntries,
54974
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
54975
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
54976
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
54977
+ peakProfitCost: data.data.peakProfit.pnlCost,
54978
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
54979
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
54980
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
54981
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
54982
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
54983
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
54614
54984
  note: data.data.note,
54615
54985
  scheduledAt: data.data.scheduledAt,
54616
54986
  pendingAt: data.data.pendingAt,
@@ -54641,11 +55011,23 @@ const CREATE_BREAKEVEN_NOTIFICATION_FN = (data) => ({
54641
55011
  totalEntries: data.data.totalEntries,
54642
55012
  totalPartials: data.data.totalPartials,
54643
55013
  pnl: data.data.pnl,
55014
+ maxDrawdown: data.data.maxDrawdown,
55015
+ peakProfit: data.data.peakProfit,
54644
55016
  pnlPercentage: data.data.pnl.pnlPercentage,
54645
55017
  pnlPriceOpen: data.data.pnl.priceOpen,
54646
55018
  pnlPriceClose: data.data.pnl.priceClose,
54647
55019
  pnlCost: data.data.pnl.pnlCost,
54648
55020
  pnlEntries: data.data.pnl.pnlEntries,
55021
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
55022
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
55023
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
55024
+ peakProfitCost: data.data.peakProfit.pnlCost,
55025
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
55026
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
55027
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
55028
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
55029
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
55030
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
54649
55031
  note: data.data.note,
54650
55032
  scheduledAt: data.data.scheduledAt,
54651
55033
  pendingAt: data.data.pendingAt,
@@ -54680,12 +55062,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54680
55062
  originalPriceOpen: data.originalPriceOpen,
54681
55063
  totalEntries: data.totalEntries,
54682
55064
  totalPartials: data.totalPartials,
54683
- pnl: data.pnl,
55065
+ pnl: data.signal.pnl,
55066
+ maxDrawdown: data.signal.maxDrawdown,
55067
+ peakProfit: data.signal.peakProfit,
54684
55068
  pnlPercentage: data.pnl.pnlPercentage,
54685
55069
  pnlPriceOpen: data.pnl.priceOpen,
54686
55070
  pnlPriceClose: data.pnl.priceClose,
54687
55071
  pnlCost: data.pnl.pnlCost,
54688
55072
  pnlEntries: data.pnl.pnlEntries,
55073
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55074
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55075
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55076
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55077
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55078
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55079
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55080
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55081
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55082
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54689
55083
  scheduledAt: data.scheduledAt,
54690
55084
  pendingAt: data.pendingAt,
54691
55085
  note: data.note,
@@ -54713,12 +55107,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54713
55107
  originalPriceOpen: data.originalPriceOpen,
54714
55108
  totalEntries: data.totalEntries,
54715
55109
  totalPartials: data.totalPartials,
54716
- pnl: data.pnl,
55110
+ pnl: data.signal.pnl,
55111
+ maxDrawdown: data.signal.maxDrawdown,
55112
+ peakProfit: data.signal.peakProfit,
54717
55113
  pnlPercentage: data.pnl.pnlPercentage,
54718
55114
  pnlPriceOpen: data.pnl.priceOpen,
54719
55115
  pnlPriceClose: data.pnl.priceClose,
54720
55116
  pnlCost: data.pnl.pnlCost,
54721
55117
  pnlEntries: data.pnl.pnlEntries,
55118
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55119
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55120
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55121
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55122
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55123
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55124
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55125
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55126
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55127
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54722
55128
  scheduledAt: data.scheduledAt,
54723
55129
  pendingAt: data.pendingAt,
54724
55130
  note: data.note,
@@ -54745,12 +55151,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54745
55151
  originalPriceOpen: data.originalPriceOpen,
54746
55152
  totalEntries: data.totalEntries,
54747
55153
  totalPartials: data.totalPartials,
54748
- pnl: data.pnl,
55154
+ pnl: data.signal.pnl,
55155
+ maxDrawdown: data.signal.maxDrawdown,
55156
+ peakProfit: data.signal.peakProfit,
54749
55157
  pnlPercentage: data.pnl.pnlPercentage,
54750
55158
  pnlPriceOpen: data.pnl.priceOpen,
54751
55159
  pnlPriceClose: data.pnl.priceClose,
54752
55160
  pnlCost: data.pnl.pnlCost,
54753
55161
  pnlEntries: data.pnl.pnlEntries,
55162
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55163
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55164
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55165
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55166
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55167
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55168
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55169
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55170
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55171
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54754
55172
  scheduledAt: data.scheduledAt,
54755
55173
  pendingAt: data.pendingAt,
54756
55174
  note: data.note,
@@ -54778,12 +55196,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54778
55196
  originalPriceOpen: data.originalPriceOpen,
54779
55197
  totalEntries: data.totalEntries,
54780
55198
  totalPartials: data.totalPartials,
54781
- pnl: data.pnl,
55199
+ pnl: data.signal.pnl,
55200
+ maxDrawdown: data.signal.maxDrawdown,
55201
+ peakProfit: data.signal.peakProfit,
54782
55202
  pnlPercentage: data.pnl.pnlPercentage,
54783
55203
  pnlPriceOpen: data.pnl.priceOpen,
54784
55204
  pnlPriceClose: data.pnl.priceClose,
54785
55205
  pnlCost: data.pnl.pnlCost,
54786
55206
  pnlEntries: data.pnl.pnlEntries,
55207
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55208
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55209
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55210
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55211
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55212
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55213
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55214
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55215
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55216
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54787
55217
  scheduledAt: data.scheduledAt,
54788
55218
  pendingAt: data.pendingAt,
54789
55219
  note: data.note,
@@ -54811,12 +55241,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54811
55241
  originalPriceOpen: data.originalPriceOpen,
54812
55242
  totalEntries: data.totalEntries,
54813
55243
  totalPartials: data.totalPartials,
54814
- pnl: data.pnl,
55244
+ pnl: data.signal.pnl,
55245
+ maxDrawdown: data.signal.maxDrawdown,
55246
+ peakProfit: data.signal.peakProfit,
54815
55247
  pnlPercentage: data.pnl.pnlPercentage,
54816
55248
  pnlPriceOpen: data.pnl.priceOpen,
54817
55249
  pnlPriceClose: data.pnl.priceClose,
54818
55250
  pnlCost: data.pnl.pnlCost,
54819
55251
  pnlEntries: data.pnl.pnlEntries,
55252
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55253
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55254
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55255
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55256
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55257
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55258
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55259
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55260
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55261
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54820
55262
  scheduledAt: data.scheduledAt,
54821
55263
  pendingAt: data.pendingAt,
54822
55264
  note: data.note,
@@ -54844,12 +55286,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54844
55286
  originalPriceOpen: data.originalPriceOpen,
54845
55287
  totalEntries: data.totalEntries,
54846
55288
  totalPartials: data.totalPartials,
54847
- pnl: data.pnl,
55289
+ pnl: data.signal.pnl,
55290
+ maxDrawdown: data.signal.maxDrawdown,
55291
+ peakProfit: data.signal.peakProfit,
54848
55292
  pnlPercentage: data.pnl.pnlPercentage,
54849
55293
  pnlPriceOpen: data.pnl.priceOpen,
54850
55294
  pnlPriceClose: data.pnl.priceClose,
54851
55295
  pnlCost: data.pnl.pnlCost,
54852
55296
  pnlEntries: data.pnl.pnlEntries,
55297
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55298
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55299
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55300
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55301
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55302
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55303
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55304
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55305
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55306
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54853
55307
  scheduledAt: data.scheduledAt,
54854
55308
  pendingAt: data.pendingAt,
54855
55309
  note: data.note,
@@ -54878,12 +55332,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54878
55332
  originalPriceTakeProfit: data.originalPriceTakeProfit,
54879
55333
  originalPriceStopLoss: data.originalPriceStopLoss,
54880
55334
  originalPriceOpen: data.originalPriceOpen,
54881
- pnl: data.pnl,
55335
+ pnl: data.signal.pnl,
55336
+ maxDrawdown: data.signal.maxDrawdown,
55337
+ peakProfit: data.signal.peakProfit,
54882
55338
  pnlPercentage: data.pnl.pnlPercentage,
54883
55339
  pnlPriceOpen: data.pnl.priceOpen,
54884
55340
  pnlPriceClose: data.pnl.priceClose,
54885
55341
  pnlCost: data.pnl.pnlCost,
54886
55342
  pnlEntries: data.pnl.pnlEntries,
55343
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55344
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55345
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55346
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55347
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55348
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55349
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55350
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55351
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55352
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54887
55353
  scheduledAt: data.scheduledAt,
54888
55354
  pendingAt: data.pendingAt,
54889
55355
  note: data.note,
@@ -54904,12 +55370,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54904
55370
  totalEntries: data.totalEntries,
54905
55371
  totalPartials: data.totalPartials,
54906
55372
  originalPriceOpen: data.originalPriceOpen,
54907
- pnl: data.pnl,
55373
+ pnl: data.signal.pnl,
55374
+ maxDrawdown: data.signal.maxDrawdown,
55375
+ peakProfit: data.signal.peakProfit,
54908
55376
  pnlPercentage: data.pnl.pnlPercentage,
54909
55377
  pnlPriceOpen: data.pnl.priceOpen,
54910
55378
  pnlPriceClose: data.pnl.priceClose,
54911
55379
  pnlCost: data.pnl.pnlCost,
54912
55380
  pnlEntries: data.pnl.pnlEntries,
55381
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55382
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55383
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55384
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55385
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55386
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55387
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55388
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55389
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55390
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54913
55391
  note: data.note,
54914
55392
  createdAt: data.timestamp,
54915
55393
  };
@@ -54928,12 +55406,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54928
55406
  totalEntries: data.totalEntries,
54929
55407
  totalPartials: data.totalPartials,
54930
55408
  originalPriceOpen: data.originalPriceOpen,
54931
- pnl: data.pnl,
55409
+ pnl: data.signal.pnl,
55410
+ maxDrawdown: data.signal.maxDrawdown,
55411
+ peakProfit: data.signal.peakProfit,
54932
55412
  pnlPercentage: data.pnl.pnlPercentage,
54933
55413
  pnlPriceOpen: data.pnl.priceOpen,
54934
55414
  pnlPriceClose: data.pnl.priceClose,
54935
55415
  pnlCost: data.pnl.pnlCost,
54936
55416
  pnlEntries: data.pnl.pnlEntries,
55417
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55418
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55419
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55420
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55421
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55422
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55423
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55424
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55425
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55426
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54937
55427
  note: data.note,
54938
55428
  createdAt: data.timestamp,
54939
55429
  };
@@ -54958,12 +55448,24 @@ const CREATE_SIGNAL_SYNC_NOTIFICATION_FN = (data) => {
54958
55448
  exchangeName: data.exchangeName,
54959
55449
  signalId: data.signalId,
54960
55450
  currentPrice: data.currentPrice,
54961
- pnl: data.pnl,
55451
+ pnl: data.signal.pnl,
55452
+ maxDrawdown: data.signal.maxDrawdown,
55453
+ peakProfit: data.signal.peakProfit,
54962
55454
  pnlPercentage: data.pnl.pnlPercentage,
54963
55455
  pnlPriceOpen: data.pnl.priceOpen,
54964
55456
  pnlPriceClose: data.pnl.priceClose,
54965
55457
  pnlCost: data.pnl.pnlCost,
54966
55458
  pnlEntries: data.pnl.pnlEntries,
55459
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55460
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55461
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55462
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55463
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55464
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55465
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55466
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55467
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55468
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54967
55469
  cost: data.cost,
54968
55470
  position: data.position,
54969
55471
  priceOpen: data.priceOpen,
@@ -54991,12 +55493,24 @@ const CREATE_SIGNAL_SYNC_NOTIFICATION_FN = (data) => {
54991
55493
  exchangeName: data.exchangeName,
54992
55494
  signalId: data.signalId,
54993
55495
  currentPrice: data.currentPrice,
54994
- pnl: data.pnl,
55496
+ pnl: data.signal.pnl,
55497
+ maxDrawdown: data.signal.maxDrawdown,
55498
+ peakProfit: data.signal.peakProfit,
54995
55499
  pnlPercentage: data.pnl.pnlPercentage,
54996
55500
  pnlPriceOpen: data.pnl.priceOpen,
54997
55501
  pnlPriceClose: data.pnl.priceClose,
54998
55502
  pnlCost: data.pnl.pnlCost,
54999
55503
  pnlEntries: data.pnl.pnlEntries,
55504
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55505
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55506
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55507
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55508
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55509
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55510
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55511
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55512
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55513
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
55000
55514
  position: data.position,
55001
55515
  priceOpen: data.priceOpen,
55002
55516
  priceTakeProfit: data.priceTakeProfit,
@@ -55102,11 +55616,23 @@ const CREATE_SIGNAL_INFO_NOTIFICATION_FN = (data) => ({
55102
55616
  totalEntries: data.data.totalEntries,
55103
55617
  totalPartials: data.data.totalPartials,
55104
55618
  pnl: data.data.pnl,
55619
+ maxDrawdown: data.data.maxDrawdown,
55620
+ peakProfit: data.data.peakProfit,
55105
55621
  pnlPercentage: data.data.pnl.pnlPercentage,
55106
55622
  pnlPriceOpen: data.data.pnl.priceOpen,
55107
55623
  pnlPriceClose: data.data.pnl.priceClose,
55108
55624
  pnlCost: data.data.pnl.pnlCost,
55109
55625
  pnlEntries: data.data.pnl.pnlEntries,
55626
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
55627
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
55628
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
55629
+ peakProfitCost: data.data.peakProfit.pnlCost,
55630
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
55631
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
55632
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
55633
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
55634
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
55635
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
55110
55636
  note: data.note,
55111
55637
  notificationId: data.notificationId,
55112
55638
  scheduledAt: data.data.scheduledAt,