backtest-kit 7.0.2 → 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.mjs CHANGED
@@ -4750,8 +4750,7 @@ const TIMEOUT_SYMBOL = Symbol('timeout');
4750
4750
  * The framework will retry on the next tick.
4751
4751
  */
4752
4752
  const CALL_SIGNAL_SYNC_OPEN_FN = trycatch(async (timestamp, currentPrice, pendingSignal, self) => {
4753
- const publicSignal = TO_PUBLIC_SIGNAL(pendingSignal, currentPrice);
4754
- const pnl = toProfitLossDto(pendingSignal, currentPrice);
4753
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", pendingSignal, currentPrice);
4755
4754
  return await self.params.onSignalSync({
4756
4755
  action: "signal-open",
4757
4756
  symbol: self.params.execution.context.symbol,
@@ -4762,10 +4761,12 @@ const CALL_SIGNAL_SYNC_OPEN_FN = trycatch(async (timestamp, currentPrice, pendin
4762
4761
  signalId: pendingSignal.id,
4763
4762
  timestamp,
4764
4763
  signal: publicSignal,
4764
+ maxDrawdown: publicSignal.maxDrawdown,
4765
+ peakProfit: publicSignal.peakProfit,
4765
4766
  cost: pendingSignal.cost,
4766
4767
  currentPrice,
4767
4768
  position: publicSignal.position,
4768
- pnl,
4769
+ pnl: publicSignal.pnl,
4769
4770
  priceOpen: publicSignal.priceOpen,
4770
4771
  priceTakeProfit: publicSignal.priceTakeProfit,
4771
4772
  priceStopLoss: publicSignal.priceStopLoss,
@@ -4789,8 +4790,7 @@ const CALL_SIGNAL_SYNC_OPEN_FN = trycatch(async (timestamp, currentPrice, pendin
4789
4790
  * strategy state is NOT mutated. The framework will retry on the next tick.
4790
4791
  */
4791
4792
  const CALL_SIGNAL_SYNC_CLOSE_FN = trycatch(async (timestamp, currentPrice, closeReason, signal, self) => {
4792
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
4793
- const pnl = toProfitLossDto(signal, currentPrice);
4793
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
4794
4794
  return await self.params.onSignalSync({
4795
4795
  action: "signal-close",
4796
4796
  symbol: self.params.execution.context.symbol,
@@ -4801,8 +4801,10 @@ const CALL_SIGNAL_SYNC_CLOSE_FN = trycatch(async (timestamp, currentPrice, close
4801
4801
  signalId: signal.id,
4802
4802
  timestamp,
4803
4803
  signal: publicSignal,
4804
+ maxDrawdown: publicSignal.maxDrawdown,
4805
+ peakProfit: publicSignal.peakProfit,
4804
4806
  currentPrice,
4805
- pnl,
4807
+ pnl: publicSignal.pnl,
4806
4808
  position: publicSignal.position,
4807
4809
  priceOpen: publicSignal.priceOpen,
4808
4810
  priceTakeProfit: publicSignal.priceTakeProfit,
@@ -4863,10 +4865,9 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4863
4865
  if (!self._pendingSignal) {
4864
4866
  return;
4865
4867
  }
4866
- // Get public signal data for commit events (contains effective and original SL/TP)
4867
- const publicSignal = TO_PUBLIC_SIGNAL(self._pendingSignal, currentPrice);
4868
4868
  for (const commit of queue) {
4869
4869
  if (commit.action === "partial-profit") {
4870
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
4870
4871
  await CALL_COMMIT_FN(self, {
4871
4872
  action: "partial-profit",
4872
4873
  symbol: commit.symbol,
@@ -4876,7 +4877,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4876
4877
  backtest: commit.backtest,
4877
4878
  percentToClose: commit.percentToClose,
4878
4879
  currentPrice: commit.currentPrice,
4879
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
4880
+ pnl: publicSignal.pnl,
4881
+ maxDrawdown: publicSignal.maxDrawdown,
4882
+ peakProfit: publicSignal.peakProfit,
4883
+ signal: publicSignal,
4880
4884
  timestamp,
4881
4885
  totalEntries: publicSignal.totalEntries,
4882
4886
  totalPartials: publicSignal.totalPartials,
@@ -4895,6 +4899,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4895
4899
  continue;
4896
4900
  }
4897
4901
  if (commit.action === "partial-loss") {
4902
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
4898
4903
  await CALL_COMMIT_FN(self, {
4899
4904
  action: "partial-loss",
4900
4905
  symbol: commit.symbol,
@@ -4904,7 +4909,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4904
4909
  backtest: commit.backtest,
4905
4910
  percentToClose: commit.percentToClose,
4906
4911
  currentPrice: commit.currentPrice,
4907
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
4912
+ pnl: publicSignal.pnl,
4913
+ maxDrawdown: publicSignal.maxDrawdown,
4914
+ peakProfit: publicSignal.peakProfit,
4915
+ signal: publicSignal,
4908
4916
  timestamp,
4909
4917
  totalEntries: publicSignal.totalEntries,
4910
4918
  totalPartials: publicSignal.totalPartials,
@@ -4923,6 +4931,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4923
4931
  continue;
4924
4932
  }
4925
4933
  if (commit.action === "breakeven") {
4934
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
4926
4935
  await CALL_COMMIT_FN(self, {
4927
4936
  action: "breakeven",
4928
4937
  symbol: commit.symbol,
@@ -4931,7 +4940,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4931
4940
  frameName: self.params.frameName,
4932
4941
  backtest: commit.backtest,
4933
4942
  currentPrice: commit.currentPrice,
4934
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
4943
+ pnl: publicSignal.pnl,
4944
+ maxDrawdown: publicSignal.maxDrawdown,
4945
+ peakProfit: publicSignal.peakProfit,
4946
+ signal: publicSignal,
4935
4947
  timestamp,
4936
4948
  totalEntries: publicSignal.totalEntries,
4937
4949
  totalPartials: publicSignal.totalPartials,
@@ -4950,6 +4962,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4950
4962
  continue;
4951
4963
  }
4952
4964
  if (commit.action === "trailing-stop") {
4965
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
4953
4966
  await CALL_COMMIT_FN(self, {
4954
4967
  action: "trailing-stop",
4955
4968
  symbol: commit.symbol,
@@ -4959,7 +4972,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4959
4972
  backtest: commit.backtest,
4960
4973
  percentShift: commit.percentShift,
4961
4974
  currentPrice: commit.currentPrice,
4962
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
4975
+ pnl: publicSignal.pnl,
4976
+ maxDrawdown: publicSignal.maxDrawdown,
4977
+ peakProfit: publicSignal.peakProfit,
4978
+ signal: publicSignal,
4963
4979
  timestamp,
4964
4980
  totalEntries: publicSignal.totalEntries,
4965
4981
  totalPartials: publicSignal.totalPartials,
@@ -4978,6 +4994,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4978
4994
  continue;
4979
4995
  }
4980
4996
  if (commit.action === "trailing-take") {
4997
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
4981
4998
  await CALL_COMMIT_FN(self, {
4982
4999
  action: "trailing-take",
4983
5000
  symbol: commit.symbol,
@@ -4987,7 +5004,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
4987
5004
  backtest: commit.backtest,
4988
5005
  percentShift: commit.percentShift,
4989
5006
  currentPrice: commit.currentPrice,
4990
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
5007
+ pnl: publicSignal.pnl,
5008
+ maxDrawdown: publicSignal.maxDrawdown,
5009
+ peakProfit: publicSignal.peakProfit,
5010
+ signal: publicSignal,
4991
5011
  timestamp,
4992
5012
  totalEntries: publicSignal.totalEntries,
4993
5013
  totalPartials: publicSignal.totalPartials,
@@ -5006,6 +5026,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
5006
5026
  continue;
5007
5027
  }
5008
5028
  if (commit.action === "average-buy") {
5029
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
5009
5030
  const effectivePriceOpen = getEffectivePriceOpen(self._pendingSignal);
5010
5031
  await CALL_COMMIT_FN(self, {
5011
5032
  action: "average-buy",
@@ -5017,7 +5038,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
5017
5038
  currentPrice: commit.currentPrice,
5018
5039
  cost: commit.cost,
5019
5040
  effectivePriceOpen,
5020
- pnl: toProfitLossDto(self._pendingSignal, commit.currentPrice),
5041
+ pnl: publicSignal.pnl,
5042
+ maxDrawdown: publicSignal.maxDrawdown,
5043
+ peakProfit: publicSignal.peakProfit,
5044
+ signal: publicSignal,
5021
5045
  timestamp,
5022
5046
  totalEntries: publicSignal.totalEntries,
5023
5047
  totalPartials: publicSignal.totalPartials,
@@ -5037,6 +5061,8 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
5037
5061
  }
5038
5062
  }
5039
5063
  };
5064
+ /** Zero PNL constant for scheduled signals (which don't have priceOpen or PNL yet) */
5065
+ const ZERO_PNL$1 = { pnlPercentage: 0, priceOpen: 0, priceClose: 0, pnlCost: 0, pnlEntries: 0 };
5040
5066
  /**
5041
5067
  * Converts internal signal to public API format.
5042
5068
  *
@@ -5084,7 +5110,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
5084
5110
  * // publicSignal._trailingPriceTakeProfit = undefined (hidden from external API)
5085
5111
  * ```
5086
5112
  */
5087
- const TO_PUBLIC_SIGNAL = (signal, currentPrice) => {
5113
+ const TO_PUBLIC_SIGNAL = (type, signal, currentPrice) => {
5088
5114
  const hasTrailingSL = "_trailingPriceStopLoss" in signal && signal._trailingPriceStopLoss !== undefined;
5089
5115
  const hasTrailingTP = "_trailingPriceTakeProfit" in signal && signal._trailingPriceTakeProfit !== undefined;
5090
5116
  const partialExecuted = "_partial" in signal
@@ -5092,11 +5118,14 @@ const TO_PUBLIC_SIGNAL = (signal, currentPrice) => {
5092
5118
  : 0;
5093
5119
  const totalEntries = ("_entry" in signal && Array.isArray(signal._entry))
5094
5120
  ? signal._entry.length
5095
- : 1;
5121
+ : type === "scheduled" ? 0 : 1;
5096
5122
  const totalPartials = ("_partial" in signal && Array.isArray(signal._partial))
5097
5123
  ? signal._partial.length
5098
5124
  : 0;
5099
- const effectivePriceOpen = "_entry" in signal ? getEffectivePriceOpen(signal) : signal.priceOpen;
5125
+ const pnl = type === "scheduled" ? ZERO_PNL$1 : toProfitLossDto(signal, currentPrice);
5126
+ const maxDrawdown = type === "scheduled" ? ZERO_PNL$1 : ("_fall" in signal ? !!signal["_fall"] ? ({ ...signal._fall }) : ZERO_PNL$1 : ZERO_PNL$1);
5127
+ const peakProfit = type === "scheduled" ? ZERO_PNL$1 : ("_peak" in signal ? signal["_peak"] ? ({ ...signal._peak }) : ZERO_PNL$1 : ZERO_PNL$1);
5128
+ const effectivePriceOpen = type === "scheduled" ? signal.priceOpen : "_entry" in signal ? signal["_entry"] ? getEffectivePriceOpen(signal) : signal.priceOpen : signal.priceOpen;
5100
5129
  return {
5101
5130
  ...structuredClone(signal),
5102
5131
  priceOpen: effectivePriceOpen,
@@ -5105,10 +5134,12 @@ const TO_PUBLIC_SIGNAL = (signal, currentPrice) => {
5105
5134
  originalPriceOpen: signal.priceOpen,
5106
5135
  originalPriceStopLoss: signal.priceStopLoss,
5107
5136
  originalPriceTakeProfit: signal.priceTakeProfit,
5137
+ maxDrawdown,
5138
+ peakProfit,
5108
5139
  partialExecuted,
5109
5140
  totalEntries,
5110
5141
  totalPartials,
5111
- pnl: toProfitLossDto(signal, currentPrice),
5142
+ pnl,
5112
5143
  };
5113
5144
  };
5114
5145
  const GET_SIGNAL_FN = trycatch(async (self) => {
@@ -5173,8 +5204,8 @@ const GET_SIGNAL_FN = trycatch(async (self) => {
5173
5204
  timestamp: currentTime,
5174
5205
  _isScheduled: false,
5175
5206
  _entry: [{ price: signal.priceOpen, cost: signal.cost ?? GLOBAL_CONFIG.CC_POSITION_ENTRY_COST, timestamp: currentTime }],
5176
- _peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5177
- _fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5207
+ _peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5208
+ _fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5178
5209
  };
5179
5210
  // Валидируем сигнал перед возвратом
5180
5211
  validatePendingSignal(signalRow, currentPrice);
@@ -5199,8 +5230,8 @@ const GET_SIGNAL_FN = trycatch(async (self) => {
5199
5230
  timestamp: currentTime,
5200
5231
  _isScheduled: true,
5201
5232
  _entry: [{ price: signal.priceOpen, cost: signal.cost ?? GLOBAL_CONFIG.CC_POSITION_ENTRY_COST, timestamp: currentTime }],
5202
- _peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5203
- _fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5233
+ _peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5234
+ _fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5204
5235
  };
5205
5236
  // Валидируем сигнал перед возвратом
5206
5237
  validateScheduledSignal(scheduledSignalRow, currentPrice);
@@ -5222,8 +5253,8 @@ const GET_SIGNAL_FN = trycatch(async (self) => {
5222
5253
  timestamp: currentTime,
5223
5254
  _isScheduled: false,
5224
5255
  _entry: [{ price: currentPrice, cost: signal.cost ?? GLOBAL_CONFIG.CC_POSITION_ENTRY_COST, timestamp: currentTime }],
5225
- _peak: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5226
- _fall: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
5256
+ _peak: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5257
+ _fall: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
5227
5258
  };
5228
5259
  // Валидируем сигнал перед возвратом
5229
5260
  validatePendingSignal(signalRow, currentPrice);
@@ -5827,7 +5858,7 @@ const CHECK_SCHEDULED_SIGNAL_TIMEOUT_FN = async (self, scheduled, currentPrice)
5827
5858
  await CALL_CANCEL_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, currentPrice, currentTime, self.params.execution.context.backtest);
5828
5859
  const result = {
5829
5860
  action: "cancelled",
5830
- signal: TO_PUBLIC_SIGNAL(scheduled, currentPrice),
5861
+ signal: TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice),
5831
5862
  currentPrice: currentPrice,
5832
5863
  closeTimestamp: currentTime,
5833
5864
  strategyName: self.params.method.context.strategyName,
@@ -5883,7 +5914,7 @@ const CANCEL_SCHEDULED_SIGNAL_BY_STOPLOSS_FN = async (self, scheduled, currentPr
5883
5914
  await CALL_CANCEL_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, currentPrice, currentTime, self.params.execution.context.backtest);
5884
5915
  const result = {
5885
5916
  action: "cancelled",
5886
- signal: TO_PUBLIC_SIGNAL(scheduled, currentPrice),
5917
+ signal: TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice),
5887
5918
  currentPrice: currentPrice,
5888
5919
  closeTimestamp: currentTime,
5889
5920
  strategyName: self.params.method.context.strategyName,
@@ -5934,8 +5965,8 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
5934
5965
  ...scheduled,
5935
5966
  pendingAt: activationTime,
5936
5967
  _isScheduled: false,
5937
- _peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
5938
- _fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
5968
+ _peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
5969
+ _fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
5939
5970
  };
5940
5971
  // Sync open: if external system rejects — cancel scheduled signal instead of opening
5941
5972
  const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(activationTime, activatedSignal.priceOpen, activatedSignal, self);
@@ -5945,6 +5976,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
5945
5976
  signalId: scheduled.id,
5946
5977
  });
5947
5978
  await self.setScheduledSignal(null);
5979
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, scheduled.priceOpen);
5948
5980
  await CALL_COMMIT_FN(self, {
5949
5981
  action: "cancel-scheduled",
5950
5982
  symbol: self.params.execution.context.symbol,
@@ -5957,7 +5989,10 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
5957
5989
  totalEntries: scheduled._entry?.length ?? 1,
5958
5990
  totalPartials: scheduled._partial?.length ?? 0,
5959
5991
  originalPriceOpen: scheduled.priceOpen,
5960
- pnl: toProfitLossDto(scheduled, scheduled.priceOpen),
5992
+ pnl: publicSignal.pnl,
5993
+ maxDrawdown: publicSignal.maxDrawdown,
5994
+ peakProfit: publicSignal.peakProfit,
5995
+ signal: publicSignal,
5961
5996
  note: scheduled.note,
5962
5997
  });
5963
5998
  return null;
@@ -5968,7 +6003,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
5968
6003
  await CALL_OPEN_CALLBACKS_FN(self, self.params.execution.context.symbol, self._pendingSignal, self._pendingSignal.priceOpen, activationTime, self.params.execution.context.backtest);
5969
6004
  const result = {
5970
6005
  action: "opened",
5971
- signal: TO_PUBLIC_SIGNAL(self._pendingSignal, self._pendingSignal.priceOpen),
6006
+ signal: TO_PUBLIC_SIGNAL("pending", self._pendingSignal, self._pendingSignal.priceOpen),
5972
6007
  strategyName: self.params.method.context.strategyName,
5973
6008
  exchangeName: self.params.method.context.exchangeName,
5974
6009
  frameName: self.params.method.context.frameName,
@@ -5982,7 +6017,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
5982
6017
  };
5983
6018
  const CALL_SCHEDULE_PING_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, scheduled, timestamp, backtest, currentPrice) => {
5984
6019
  await ExecutionContextService.runInContext(async () => {
5985
- const publicSignal = TO_PUBLIC_SIGNAL(scheduled, currentPrice);
6020
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice);
5986
6021
  // Call system onSchedulePing callback first (emits to pingSubject)
5987
6022
  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);
5988
6023
  // Call user onSchedulePing callback only if signal is still active (not cancelled, not activated)
@@ -6008,7 +6043,7 @@ const CALL_SCHEDULE_PING_CALLBACKS_FN = trycatch(beginTime(async (self, symbol,
6008
6043
  });
6009
6044
  const CALL_ACTIVE_PING_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, pending, timestamp, backtest, currentPrice) => {
6010
6045
  await ExecutionContextService.runInContext(async () => {
6011
- const publicSignal = TO_PUBLIC_SIGNAL(pending, currentPrice);
6046
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", pending, currentPrice);
6012
6047
  // Call system onActivePing callback first (emits to activePingSubject)
6013
6048
  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);
6014
6049
  // Call user onActivePing callback only if signal is still active (not closed)
@@ -6056,7 +6091,7 @@ const CALL_IDLE_PING_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, time
6056
6091
  const CALL_ACTIVE_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6057
6092
  await ExecutionContextService.runInContext(async () => {
6058
6093
  if (self.params.callbacks?.onActive) {
6059
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6094
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6060
6095
  await self.params.callbacks.onActive(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
6061
6096
  }
6062
6097
  }, {
@@ -6079,7 +6114,7 @@ const CALL_ACTIVE_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal,
6079
6114
  const CALL_SCHEDULE_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6080
6115
  await ExecutionContextService.runInContext(async () => {
6081
6116
  if (self.params.callbacks?.onSchedule) {
6082
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6117
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", signal, currentPrice);
6083
6118
  await self.params.callbacks.onSchedule(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
6084
6119
  }
6085
6120
  }, {
@@ -6102,7 +6137,7 @@ const CALL_SCHEDULE_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signa
6102
6137
  const CALL_CANCEL_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6103
6138
  await ExecutionContextService.runInContext(async () => {
6104
6139
  if (self.params.callbacks?.onCancel) {
6105
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6140
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", signal, currentPrice);
6106
6141
  await self.params.callbacks.onCancel(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
6107
6142
  }
6108
6143
  }, {
@@ -6125,7 +6160,7 @@ const CALL_CANCEL_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal,
6125
6160
  const CALL_OPEN_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, priceOpen, timestamp, backtest) => {
6126
6161
  await ExecutionContextService.runInContext(async () => {
6127
6162
  if (self.params.callbacks?.onOpen) {
6128
- const publicSignal = TO_PUBLIC_SIGNAL(signal, priceOpen);
6163
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, priceOpen);
6129
6164
  await self.params.callbacks.onOpen(self.params.execution.context.symbol, publicSignal, priceOpen, self.params.execution.context.backtest);
6130
6165
  }
6131
6166
  }, {
@@ -6148,7 +6183,7 @@ const CALL_OPEN_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, p
6148
6183
  const CALL_CLOSE_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6149
6184
  await ExecutionContextService.runInContext(async () => {
6150
6185
  if (self.params.callbacks?.onClose) {
6151
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6186
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6152
6187
  await self.params.callbacks.onClose(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
6153
6188
  }
6154
6189
  }, {
@@ -6271,7 +6306,7 @@ const CALL_RISK_REMOVE_SIGNAL_FN = trycatch(beginTime(async (self, symbol, times
6271
6306
  });
6272
6307
  const CALL_PARTIAL_CLEAR_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6273
6308
  await ExecutionContextService.runInContext(async () => {
6274
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6309
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6275
6310
  await self.params.partial.clear(symbol, publicSignal, currentPrice, backtest);
6276
6311
  }, {
6277
6312
  when: new Date(timestamp),
@@ -6293,7 +6328,7 @@ const CALL_PARTIAL_CLEAR_FN = trycatch(beginTime(async (self, symbol, signal, cu
6293
6328
  const CALL_RISK_CHECK_SIGNAL_FN = trycatch(beginTime(async (self, symbol, pendingSignal, currentPrice, timestamp, backtest) => {
6294
6329
  return await ExecutionContextService.runInContext(async () => {
6295
6330
  return await self.params.risk.checkSignal({
6296
- currentSignal: TO_PUBLIC_SIGNAL(pendingSignal, currentPrice),
6331
+ currentSignal: TO_PUBLIC_SIGNAL("scheduled", pendingSignal, currentPrice),
6297
6332
  symbol: symbol,
6298
6333
  strategyName: self.params.method.context.strategyName,
6299
6334
  exchangeName: self.params.method.context.exchangeName,
@@ -6322,7 +6357,7 @@ const CALL_RISK_CHECK_SIGNAL_FN = trycatch(beginTime(async (self, symbol, pendin
6322
6357
  });
6323
6358
  const CALL_PARTIAL_PROFIT_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, percentTp, timestamp, backtest) => {
6324
6359
  await ExecutionContextService.runInContext(async () => {
6325
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6360
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6326
6361
  await self.params.partial.profit(symbol, publicSignal, currentPrice, percentTp, backtest, new Date(timestamp));
6327
6362
  if (self.params.callbacks?.onPartialProfit) {
6328
6363
  await self.params.callbacks.onPartialProfit(symbol, publicSignal, currentPrice, percentTp, backtest);
@@ -6346,7 +6381,7 @@ const CALL_PARTIAL_PROFIT_CALLBACKS_FN = trycatch(beginTime(async (self, symbol,
6346
6381
  });
6347
6382
  const CALL_PARTIAL_LOSS_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, percentSl, timestamp, backtest) => {
6348
6383
  await ExecutionContextService.runInContext(async () => {
6349
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6384
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6350
6385
  await self.params.partial.loss(symbol, publicSignal, currentPrice, percentSl, backtest, new Date(timestamp));
6351
6386
  if (self.params.callbacks?.onPartialLoss) {
6352
6387
  await self.params.callbacks.onPartialLoss(symbol, publicSignal, currentPrice, percentSl, backtest);
@@ -6370,7 +6405,7 @@ const CALL_PARTIAL_LOSS_CALLBACKS_FN = trycatch(beginTime(async (self, symbol, s
6370
6405
  });
6371
6406
  const CALL_BREAKEVEN_CHECK_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6372
6407
  await ExecutionContextService.runInContext(async () => {
6373
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6408
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6374
6409
  const isBreakeven = await self.params.breakeven.check(symbol, publicSignal, currentPrice, backtest, new Date(timestamp));
6375
6410
  if (self.params.callbacks?.onBreakeven) {
6376
6411
  isBreakeven && await self.params.callbacks.onBreakeven(symbol, publicSignal, currentPrice, backtest);
@@ -6394,7 +6429,7 @@ const CALL_BREAKEVEN_CHECK_FN = trycatch(beginTime(async (self, symbol, signal,
6394
6429
  });
6395
6430
  const CALL_BREAKEVEN_CLEAR_FN = trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
6396
6431
  await ExecutionContextService.runInContext(async () => {
6397
- const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
6432
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6398
6433
  await self.params.breakeven.clear(symbol, publicSignal, currentPrice, backtest);
6399
6434
  }, {
6400
6435
  when: new Date(timestamp),
@@ -6417,7 +6452,7 @@ const CALL_BACKTEST_SCHEDULE_OPEN_FN = trycatch(beginTime(async (self, symbol, s
6417
6452
  await ExecutionContextService.runInContext(async () => {
6418
6453
  backtestScheduleOpenSubject.next({
6419
6454
  action: "opened",
6420
- signal: TO_PUBLIC_SIGNAL(signal, signal.priceOpen),
6455
+ signal: TO_PUBLIC_SIGNAL("pending", signal, signal.priceOpen),
6421
6456
  strategyName: self.params.method.context.strategyName,
6422
6457
  exchangeName: self.params.method.context.exchangeName,
6423
6458
  frameName: self.params.method.context.frameName,
@@ -6446,10 +6481,10 @@ const CALL_BACKTEST_SCHEDULE_OPEN_FN = trycatch(beginTime(async (self, symbol, s
6446
6481
  const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice) => {
6447
6482
  const currentTime = self.params.execution.context.when.getTime();
6448
6483
  await CALL_SCHEDULE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, currentTime, self.params.execution.context.backtest, currentPrice);
6449
- const pnl = toProfitLossDto(scheduled, currentPrice);
6484
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice);
6450
6485
  const result = {
6451
6486
  action: "waiting",
6452
- signal: TO_PUBLIC_SIGNAL(scheduled, currentPrice),
6487
+ signal: publicSignal,
6453
6488
  currentPrice: currentPrice,
6454
6489
  strategyName: self.params.method.context.strategyName,
6455
6490
  exchangeName: self.params.method.context.exchangeName,
@@ -6457,7 +6492,7 @@ const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice)
6457
6492
  symbol: self.params.execution.context.symbol,
6458
6493
  percentTp: 0,
6459
6494
  percentSl: 0,
6460
- pnl,
6495
+ pnl: publicSignal.pnl,
6461
6496
  backtest: self.params.execution.context.backtest,
6462
6497
  createdAt: currentTime,
6463
6498
  };
@@ -6477,7 +6512,7 @@ const OPEN_NEW_SCHEDULED_SIGNAL_FN = async (self, signal) => {
6477
6512
  await CALL_SCHEDULE_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, currentTime, self.params.execution.context.backtest);
6478
6513
  const result = {
6479
6514
  action: "scheduled",
6480
- signal: TO_PUBLIC_SIGNAL(signal, currentPrice),
6515
+ signal: TO_PUBLIC_SIGNAL("scheduled", signal, currentPrice),
6481
6516
  strategyName: self.params.method.context.strategyName,
6482
6517
  exchangeName: self.params.method.context.exchangeName,
6483
6518
  frameName: self.params.method.context.frameName,
@@ -6507,7 +6542,7 @@ const OPEN_NEW_PENDING_SIGNAL_FN = async (self, signal) => {
6507
6542
  await CALL_OPEN_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, signal.priceOpen, currentTime, self.params.execution.context.backtest);
6508
6543
  const result = {
6509
6544
  action: "opened",
6510
- signal: TO_PUBLIC_SIGNAL(signal, signal.priceOpen),
6545
+ signal: TO_PUBLIC_SIGNAL("pending", signal, signal.priceOpen),
6511
6546
  strategyName: self.params.method.context.strategyName,
6512
6547
  exchangeName: self.params.method.context.exchangeName,
6513
6548
  frameName: self.params.method.context.frameName,
@@ -6562,13 +6597,13 @@ const CLOSE_PENDING_SIGNAL_FN = async (self, signal, currentPrice, closeReason)
6562
6597
  });
6563
6598
  return null;
6564
6599
  }
6565
- const pnl = toProfitLossDto(signal, currentPrice);
6600
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6566
6601
  self.params.logger.info(`ClientStrategy signal ${closeReason}`, {
6567
6602
  symbol: self.params.execution.context.symbol,
6568
6603
  signalId: signal.id,
6569
6604
  closeReason,
6570
6605
  priceClose: currentPrice,
6571
- pnlPercentage: pnl.pnlPercentage,
6606
+ pnlPercentage: publicSignal.pnl.pnlPercentage,
6572
6607
  });
6573
6608
  await CALL_CLOSE_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, currentTime, self.params.execution.context.backtest);
6574
6609
  // КРИТИЧНО: Очищаем состояние ClientPartial при закрытии позиции
@@ -6579,11 +6614,11 @@ const CLOSE_PENDING_SIGNAL_FN = async (self, signal, currentPrice, closeReason)
6579
6614
  await self.setPendingSignal(null);
6580
6615
  const result = {
6581
6616
  action: "closed",
6582
- signal: TO_PUBLIC_SIGNAL(signal, currentPrice),
6617
+ signal: publicSignal,
6583
6618
  currentPrice: currentPrice,
6584
6619
  closeReason: closeReason,
6585
6620
  closeTimestamp: currentTime,
6586
- pnl: pnl,
6621
+ pnl: publicSignal.pnl,
6587
6622
  strategyName: self.params.method.context.strategyName,
6588
6623
  exchangeName: self.params.method.context.exchangeName,
6589
6624
  frameName: self.params.method.context.frameName,
@@ -6616,13 +6651,13 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
6616
6651
  const progressPercent = (currentDistance / tpDistance) * 100;
6617
6652
  percentTp = Math.min(progressPercent, 100);
6618
6653
  if (currentPrice > signal._peak.price) {
6619
- const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
6620
- signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
6654
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6655
+ signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
6621
6656
  if (self.params.callbacks?.onWrite) {
6622
6657
  self.params.callbacks.onWrite(signal.symbol, signal, backtest);
6623
6658
  }
6624
6659
  !backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
6625
- await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
6660
+ await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
6626
6661
  }
6627
6662
  await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentTp, currentTime, self.params.execution.context.backtest);
6628
6663
  }
@@ -6633,13 +6668,13 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
6633
6668
  const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
6634
6669
  percentSl = Math.min(progressPercent, 100);
6635
6670
  if (currentPrice < signal._fall.price) {
6636
- const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
6637
- signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
6671
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6672
+ signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
6638
6673
  if (self.params.callbacks?.onWrite) {
6639
6674
  self.params.callbacks.onWrite(signal.symbol, signal, backtest);
6640
6675
  }
6641
6676
  !backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
6642
- await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
6677
+ await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
6643
6678
  }
6644
6679
  await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentSl, currentTime, self.params.execution.context.backtest);
6645
6680
  }
@@ -6658,13 +6693,13 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
6658
6693
  const progressPercent = (currentDistance / tpDistance) * 100;
6659
6694
  percentTp = Math.min(progressPercent, 100);
6660
6695
  if (currentPrice < signal._peak.price) {
6661
- const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
6662
- signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
6696
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6697
+ signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
6663
6698
  if (self.params.callbacks?.onWrite) {
6664
6699
  self.params.callbacks.onWrite(signal.symbol, signal, backtest);
6665
6700
  }
6666
6701
  !backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
6667
- await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
6702
+ await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
6668
6703
  }
6669
6704
  await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentTp, currentTime, self.params.execution.context.backtest);
6670
6705
  }
@@ -6675,22 +6710,22 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
6675
6710
  const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
6676
6711
  percentSl = Math.min(progressPercent, 100);
6677
6712
  if (currentPrice > signal._fall.price) {
6678
- const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
6679
- signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
6713
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6714
+ signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
6680
6715
  if (self.params.callbacks?.onWrite) {
6681
6716
  self.params.callbacks.onWrite(signal.symbol, signal, backtest);
6682
6717
  }
6683
6718
  !backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
6684
- await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
6719
+ await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
6685
6720
  }
6686
6721
  await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentSl, currentTime, self.params.execution.context.backtest);
6687
6722
  }
6688
6723
  }
6689
6724
  }
6690
- const pnl = toProfitLossDto(signal, currentPrice);
6725
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
6691
6726
  const result = {
6692
6727
  action: "active",
6693
- signal: TO_PUBLIC_SIGNAL(signal, currentPrice),
6728
+ signal: publicSignal,
6694
6729
  currentPrice: currentPrice,
6695
6730
  strategyName: self.params.method.context.strategyName,
6696
6731
  exchangeName: self.params.method.context.exchangeName,
@@ -6698,7 +6733,7 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
6698
6733
  symbol: self.params.execution.context.symbol,
6699
6734
  percentTp,
6700
6735
  percentSl,
6701
- pnl,
6736
+ pnl: publicSignal.pnl,
6702
6737
  backtest: self.params.execution.context.backtest,
6703
6738
  createdAt: currentTime,
6704
6739
  _backtestLastTimestamp: currentTime,
@@ -6734,6 +6769,7 @@ const CANCEL_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, averagePr
6734
6769
  reason,
6735
6770
  });
6736
6771
  await self.setScheduledSignal(null);
6772
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, averagePrice);
6737
6773
  if (reason === "user") {
6738
6774
  await CALL_COMMIT_FN(self, {
6739
6775
  action: "cancel-scheduled",
@@ -6748,14 +6784,17 @@ const CANCEL_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, averagePr
6748
6784
  totalEntries: scheduled._entry?.length ?? 1,
6749
6785
  totalPartials: scheduled._partial?.length ?? 0,
6750
6786
  originalPriceOpen: scheduled.priceOpen,
6751
- pnl: toProfitLossDto(scheduled, averagePrice),
6787
+ pnl: publicSignal.pnl,
6788
+ maxDrawdown: publicSignal.maxDrawdown,
6789
+ peakProfit: publicSignal.peakProfit,
6790
+ signal: publicSignal,
6752
6791
  note: cancelNote ?? scheduled.note,
6753
6792
  });
6754
6793
  }
6755
6794
  await CALL_CANCEL_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, averagePrice, closeTimestamp, self.params.execution.context.backtest);
6756
6795
  const result = {
6757
6796
  action: "cancelled",
6758
- signal: TO_PUBLIC_SIGNAL(scheduled, averagePrice),
6797
+ signal: publicSignal,
6759
6798
  currentPrice: averagePrice,
6760
6799
  closeTimestamp: closeTimestamp,
6761
6800
  strategyName: self.params.method.context.strategyName,
@@ -6804,8 +6843,8 @@ const ACTIVATE_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, activat
6804
6843
  ...scheduled,
6805
6844
  pendingAt: activationTime,
6806
6845
  _isScheduled: false,
6807
- _peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
6808
- _fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
6846
+ _peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
6847
+ _fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
6809
6848
  };
6810
6849
  // Sync open: if external system rejects — cancel scheduled signal instead of opening
6811
6850
  const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(activationTime, activatedSignal.priceOpen, activatedSignal, self);
@@ -6815,6 +6854,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, activat
6815
6854
  signalId: scheduled.id,
6816
6855
  });
6817
6856
  await self.setScheduledSignal(null);
6857
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, scheduled.priceOpen);
6818
6858
  await CALL_COMMIT_FN(self, {
6819
6859
  action: "cancel-scheduled",
6820
6860
  symbol: self.params.execution.context.symbol,
@@ -6827,7 +6867,10 @@ const ACTIVATE_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, activat
6827
6867
  totalEntries: scheduled._entry?.length ?? 1,
6828
6868
  totalPartials: scheduled._partial?.length ?? 0,
6829
6869
  originalPriceOpen: scheduled.priceOpen,
6830
- pnl: toProfitLossDto(scheduled, scheduled.priceOpen),
6870
+ pnl: publicSignal.pnl,
6871
+ maxDrawdown: publicSignal.maxDrawdown,
6872
+ peakProfit: publicSignal.peakProfit,
6873
+ signal: publicSignal,
6831
6874
  note: scheduled.note,
6832
6875
  });
6833
6876
  return false;
@@ -6850,20 +6893,20 @@ const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, c
6850
6893
  });
6851
6894
  return null;
6852
6895
  }
6853
- const pnl = toProfitLossDto(signal, averagePrice);
6896
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
6854
6897
  self.params.logger.debug(`ClientStrategy backtest ${closeReason}`, {
6855
6898
  symbol: self.params.execution.context.symbol,
6856
6899
  signalId: signal.id,
6857
6900
  reason: closeReason,
6858
6901
  priceClose: averagePrice,
6859
6902
  closeTimestamp,
6860
- pnlPercentage: pnl.pnlPercentage,
6903
+ pnlPercentage: publicSignal.pnl.pnlPercentage,
6861
6904
  });
6862
6905
  if (closeReason === "stop_loss") {
6863
- self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (stop_loss), PNL: ${pnl.pnlPercentage.toFixed(2)}%`);
6906
+ self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (stop_loss), PNL: ${publicSignal.pnl.pnlPercentage.toFixed(2)}%`);
6864
6907
  }
6865
- if (closeReason === "time_expired" && pnl.pnlPercentage < 0) {
6866
- self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (time_expired), PNL: ${pnl.pnlPercentage.toFixed(2)}%`);
6908
+ if (closeReason === "time_expired" && publicSignal.pnl.pnlPercentage < 0) {
6909
+ self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (time_expired), PNL: ${publicSignal.pnl.pnlPercentage.toFixed(2)}%`);
6867
6910
  }
6868
6911
  await CALL_CLOSE_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
6869
6912
  // КРИТИЧНО: Очищаем состояние ClientPartial при закрытии позиции
@@ -6874,11 +6917,11 @@ const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, c
6874
6917
  await self.setPendingSignal(null);
6875
6918
  const result = {
6876
6919
  action: "closed",
6877
- signal: TO_PUBLIC_SIGNAL(signal, averagePrice),
6920
+ signal: publicSignal,
6878
6921
  currentPrice: averagePrice,
6879
6922
  closeReason: closeReason,
6880
6923
  closeTimestamp: closeTimestamp,
6881
- pnl: pnl,
6924
+ pnl: publicSignal.pnl,
6882
6925
  strategyName: self.params.method.context.strategyName,
6883
6926
  exchangeName: self.params.method.context.exchangeName,
6884
6927
  frameName: self.params.method.context.frameName,
@@ -6902,6 +6945,7 @@ const CLOSE_USER_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, closedSignal, aver
6902
6945
  `Retry backtest() with new candle data.`);
6903
6946
  }
6904
6947
  self._closedSignal = null;
6948
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", closedSignal, averagePrice);
6905
6949
  await CALL_COMMIT_FN(self, {
6906
6950
  action: "close-pending",
6907
6951
  symbol: self.params.execution.context.symbol,
@@ -6915,21 +6959,23 @@ const CLOSE_USER_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, closedSignal, aver
6915
6959
  totalEntries: closedSignal._entry?.length ?? 1,
6916
6960
  totalPartials: closedSignal._partial?.length ?? 0,
6917
6961
  originalPriceOpen: closedSignal.priceOpen,
6918
- pnl: toProfitLossDto(closedSignal, averagePrice),
6962
+ pnl: publicSignal.pnl,
6963
+ maxDrawdown: publicSignal.maxDrawdown,
6964
+ peakProfit: publicSignal.peakProfit,
6965
+ signal: publicSignal,
6919
6966
  note: closedSignal.closeNote ?? closedSignal.note,
6920
6967
  });
6921
6968
  await CALL_CLOSE_CALLBACKS_FN(self, self.params.execution.context.symbol, closedSignal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
6922
6969
  await CALL_PARTIAL_CLEAR_FN(self, self.params.execution.context.symbol, closedSignal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
6923
6970
  await CALL_BREAKEVEN_CLEAR_FN(self, self.params.execution.context.symbol, closedSignal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
6924
6971
  await CALL_RISK_REMOVE_SIGNAL_FN(self, self.params.execution.context.symbol, closeTimestamp, self.params.execution.context.backtest);
6925
- const pnl = toProfitLossDto(closedSignal, averagePrice);
6926
6972
  const result = {
6927
6973
  action: "closed",
6928
- signal: TO_PUBLIC_SIGNAL(closedSignal, averagePrice),
6974
+ signal: publicSignal,
6929
6975
  currentPrice: averagePrice,
6930
6976
  closeReason: "closed",
6931
6977
  closeTimestamp,
6932
- pnl,
6978
+ pnl: publicSignal.pnl,
6933
6979
  strategyName: self.params.method.context.strategyName,
6934
6980
  exchangeName: self.params.method.context.exchangeName,
6935
6981
  frameName: self.params.method.context.frameName,
@@ -6994,8 +7040,8 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
6994
7040
  ...activatedSignal,
6995
7041
  pendingAt: candle.timestamp,
6996
7042
  _isScheduled: false,
6997
- _peak: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0 },
6998
- _fall: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0 },
7043
+ _peak: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
7044
+ _fall: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
6999
7045
  };
7000
7046
  // Sync open: if external system rejects — cancel scheduled signal instead of opening
7001
7047
  const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(candle.timestamp, pendingSignal.priceOpen, pendingSignal, self);
@@ -7005,6 +7051,7 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
7005
7051
  signalId: activatedSignal.id,
7006
7052
  });
7007
7053
  await self.setScheduledSignal(null);
7054
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", activatedSignal, averagePrice);
7008
7055
  await CALL_COMMIT_FN(self, {
7009
7056
  action: "cancel-scheduled",
7010
7057
  symbol: self.params.execution.context.symbol,
@@ -7017,7 +7064,10 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
7017
7064
  totalEntries: activatedSignal._entry?.length ?? 1,
7018
7065
  totalPartials: activatedSignal._partial?.length ?? 0,
7019
7066
  originalPriceOpen: activatedSignal.priceOpen,
7020
- pnl: toProfitLossDto(activatedSignal, averagePrice),
7067
+ pnl: publicSignal.pnl,
7068
+ maxDrawdown: publicSignal.maxDrawdown,
7069
+ peakProfit: publicSignal.peakProfit,
7070
+ signal: publicSignal,
7021
7071
  note: activatedSignal.activateNote ?? activatedSignal.note,
7022
7072
  });
7023
7073
  return { outcome: "pending" };
@@ -7026,7 +7076,7 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
7026
7076
  await self.setPendingSignal(pendingSignal);
7027
7077
  await CALL_RISK_ADD_SIGNAL_FN(self, self.params.execution.context.symbol, pendingSignal, candle.timestamp, self.params.execution.context.backtest);
7028
7078
  // Emit commit AFTER successful risk check
7029
- const publicSignalForCommit = TO_PUBLIC_SIGNAL(pendingSignal, averagePrice);
7079
+ const publicSignalForCommit = TO_PUBLIC_SIGNAL("pending", pendingSignal, averagePrice);
7030
7080
  await CALL_COMMIT_FN(self, {
7031
7081
  action: "activate-scheduled",
7032
7082
  symbol: self.params.execution.context.symbol,
@@ -7038,7 +7088,10 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
7038
7088
  activateId: activatedSignal.activateId,
7039
7089
  timestamp: candle.timestamp,
7040
7090
  currentPrice: averagePrice,
7041
- pnl: toProfitLossDto(pendingSignal, averagePrice),
7091
+ pnl: publicSignalForCommit.pnl,
7092
+ maxDrawdown: publicSignalForCommit.maxDrawdown,
7093
+ peakProfit: publicSignalForCommit.peakProfit,
7094
+ signal: publicSignalForCommit,
7042
7095
  position: publicSignalForCommit.position,
7043
7096
  priceOpen: publicSignalForCommit.priceOpen,
7044
7097
  priceTakeProfit: publicSignalForCommit.priceTakeProfit,
@@ -7208,12 +7261,12 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7208
7261
  const tpDistance = effectiveTakeProfit - effectivePriceOpen;
7209
7262
  const progressPercent = (currentDistance / tpDistance) * 100;
7210
7263
  if (averagePrice > signal._peak.price) {
7211
- const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
7212
- signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
7264
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
7265
+ signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
7213
7266
  if (self.params.callbacks?.onWrite) {
7214
7267
  self.params.callbacks.onWrite(signal.symbol, signal, true);
7215
7268
  }
7216
- await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
7269
+ await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
7217
7270
  }
7218
7271
  await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
7219
7272
  }
@@ -7223,12 +7276,12 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7223
7276
  const slDistance = effectivePriceOpen - effectiveStopLoss;
7224
7277
  const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
7225
7278
  if (averagePrice < signal._fall.price) {
7226
- const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
7227
- signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
7279
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
7280
+ signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
7228
7281
  if (self.params.callbacks?.onWrite) {
7229
7282
  self.params.callbacks.onWrite(signal.symbol, signal, true);
7230
7283
  }
7231
- await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
7284
+ await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
7232
7285
  }
7233
7286
  await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
7234
7287
  }
@@ -7246,12 +7299,12 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7246
7299
  const tpDistance = effectivePriceOpen - effectiveTakeProfit;
7247
7300
  const progressPercent = (currentDistance / tpDistance) * 100;
7248
7301
  if (averagePrice < signal._peak.price) {
7249
- const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
7250
- signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
7302
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
7303
+ signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
7251
7304
  if (self.params.callbacks?.onWrite) {
7252
7305
  self.params.callbacks.onWrite(signal.symbol, signal, true);
7253
7306
  }
7254
- await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
7307
+ await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
7255
7308
  }
7256
7309
  await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
7257
7310
  }
@@ -7261,12 +7314,12 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7261
7314
  const slDistance = effectiveStopLoss - effectivePriceOpen;
7262
7315
  const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
7263
7316
  if (averagePrice > signal._fall.price) {
7264
- const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
7265
- signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
7317
+ const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
7318
+ signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
7266
7319
  if (self.params.callbacks?.onWrite) {
7267
7320
  self.params.callbacks.onWrite(signal.symbol, signal, true);
7268
7321
  }
7269
- await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
7322
+ await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
7270
7323
  }
7271
7324
  await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
7272
7325
  }
@@ -7280,9 +7333,10 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7280
7333
  const lastPrice = GET_AVG_PRICE_FN(lastCandles);
7281
7334
  const closeTimestamp = lastCandles[lastCandles.length - 1].timestamp;
7282
7335
  if (signal.minuteEstimatedTime === Infinity) {
7336
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, lastPrice);
7283
7337
  const result = {
7284
7338
  action: "active",
7285
- signal: TO_PUBLIC_SIGNAL(signal, lastPrice),
7339
+ signal: publicSignal,
7286
7340
  currentPrice: lastPrice,
7287
7341
  strategyName: self.params.method.context.strategyName,
7288
7342
  exchangeName: self.params.method.context.exchangeName,
@@ -7290,7 +7344,7 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
7290
7344
  symbol: self.params.execution.context.symbol,
7291
7345
  percentTp: 0,
7292
7346
  percentSl: 0,
7293
- pnl: toProfitLossDto(signal, lastPrice),
7347
+ pnl: publicSignal.pnl,
7294
7348
  backtest: self.params.execution.context.backtest,
7295
7349
  createdAt: closeTimestamp,
7296
7350
  _backtestLastTimestamp: closeTimestamp,
@@ -7473,7 +7527,7 @@ class ClientStrategy {
7473
7527
  this.params.logger.debug("ClientStrategy getPendingSignal", {
7474
7528
  symbol,
7475
7529
  });
7476
- return this._pendingSignal ? TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice) : null;
7530
+ return this._pendingSignal ? TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice) : null;
7477
7531
  }
7478
7532
  /**
7479
7533
  * Retrieves the current scheduled signal.
@@ -7484,7 +7538,7 @@ class ClientStrategy {
7484
7538
  this.params.logger.debug("ClientStrategy getScheduledSignal", {
7485
7539
  symbol,
7486
7540
  });
7487
- return this._scheduledSignal ? TO_PUBLIC_SIGNAL(this._scheduledSignal, currentPrice) : null;
7541
+ return this._scheduledSignal ? TO_PUBLIC_SIGNAL("scheduled", this._scheduledSignal, currentPrice) : null;
7488
7542
  }
7489
7543
  /**
7490
7544
  * Checks if breakeven threshold has been reached for the current pending signal.
@@ -8293,6 +8347,7 @@ class ClientStrategy {
8293
8347
  signalId: cancelledSignal.id,
8294
8348
  });
8295
8349
  // Emit commit with correct timestamp from tick context
8350
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", cancelledSignal, currentPrice);
8296
8351
  await CALL_COMMIT_FN(this, {
8297
8352
  action: "cancel-scheduled",
8298
8353
  symbol: this.params.execution.context.symbol,
@@ -8306,14 +8361,17 @@ class ClientStrategy {
8306
8361
  totalEntries: cancelledSignal._entry?.length ?? 1,
8307
8362
  totalPartials: cancelledSignal._partial?.length ?? 0,
8308
8363
  originalPriceOpen: cancelledSignal.priceOpen,
8309
- pnl: toProfitLossDto(cancelledSignal, currentPrice),
8364
+ pnl: publicSignal.pnl,
8365
+ maxDrawdown: publicSignal.maxDrawdown,
8366
+ peakProfit: publicSignal.peakProfit,
8367
+ signal: publicSignal,
8310
8368
  note: cancelledSignal.cancelNote ?? cancelledSignal.note,
8311
8369
  });
8312
8370
  // Call onCancel callback
8313
8371
  await CALL_CANCEL_CALLBACKS_FN(this, this.params.execution.context.symbol, cancelledSignal, currentPrice, currentTime, this.params.execution.context.backtest);
8314
8372
  const result = {
8315
8373
  action: "cancelled",
8316
- signal: TO_PUBLIC_SIGNAL(cancelledSignal, currentPrice),
8374
+ signal: publicSignal,
8317
8375
  currentPrice,
8318
8376
  closeTimestamp: currentTime,
8319
8377
  strategyName: this.params.method.context.strategyName,
@@ -8347,6 +8405,7 @@ class ClientStrategy {
8347
8405
  signalId: closedSignal.id,
8348
8406
  });
8349
8407
  // Emit commit with correct timestamp from tick context
8408
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", closedSignal, currentPrice);
8350
8409
  await CALL_COMMIT_FN(this, {
8351
8410
  action: "close-pending",
8352
8411
  symbol: this.params.execution.context.symbol,
@@ -8360,7 +8419,10 @@ class ClientStrategy {
8360
8419
  totalEntries: closedSignal._entry?.length ?? 1,
8361
8420
  totalPartials: closedSignal._partial?.length ?? 0,
8362
8421
  originalPriceOpen: closedSignal.priceOpen,
8363
- pnl: toProfitLossDto(closedSignal, currentPrice),
8422
+ pnl: publicSignal.pnl,
8423
+ maxDrawdown: publicSignal.maxDrawdown,
8424
+ peakProfit: publicSignal.peakProfit,
8425
+ signal: publicSignal,
8364
8426
  note: closedSignal.closeNote ?? closedSignal.note,
8365
8427
  });
8366
8428
  // Call onClose callback
@@ -8370,14 +8432,13 @@ class ClientStrategy {
8370
8432
  // КРИТИЧНО: Очищаем состояние ClientBreakeven при закрытии позиции
8371
8433
  await CALL_BREAKEVEN_CLEAR_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, currentTime, this.params.execution.context.backtest);
8372
8434
  await CALL_RISK_REMOVE_SIGNAL_FN(this, this.params.execution.context.symbol, currentTime, this.params.execution.context.backtest);
8373
- const pnl = toProfitLossDto(closedSignal, currentPrice);
8374
8435
  const result = {
8375
8436
  action: "closed",
8376
- signal: TO_PUBLIC_SIGNAL(closedSignal, currentPrice),
8437
+ signal: publicSignal,
8377
8438
  currentPrice,
8378
8439
  closeReason: "closed",
8379
8440
  closeTimestamp: currentTime,
8380
- pnl,
8441
+ pnl: publicSignal.pnl,
8381
8442
  strategyName: this.params.method.context.strategyName,
8382
8443
  exchangeName: this.params.method.context.exchangeName,
8383
8444
  frameName: this.params.method.context.frameName,
@@ -8420,8 +8481,8 @@ class ClientStrategy {
8420
8481
  ...activatedSignal,
8421
8482
  pendingAt: currentTime,
8422
8483
  _isScheduled: false,
8423
- _peak: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
8424
- _fall: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
8484
+ _peak: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, pnlEntries: 0, priceOpen: 0 },
8485
+ _fall: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, pnlEntries: 0, priceOpen: 0 },
8425
8486
  };
8426
8487
  const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(currentTime, currentPrice, pendingSignal, this);
8427
8488
  if (!syncOpenAllowed) {
@@ -8430,6 +8491,7 @@ class ClientStrategy {
8430
8491
  signalId: activatedSignal.id,
8431
8492
  });
8432
8493
  await this.setScheduledSignal(null);
8494
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", activatedSignal, currentPrice);
8433
8495
  await CALL_COMMIT_FN(this, {
8434
8496
  action: "cancel-scheduled",
8435
8497
  symbol: this.params.execution.context.symbol,
@@ -8442,7 +8504,10 @@ class ClientStrategy {
8442
8504
  totalEntries: activatedSignal._entry?.length ?? 1,
8443
8505
  totalPartials: activatedSignal._partial?.length ?? 0,
8444
8506
  originalPriceOpen: activatedSignal.priceOpen,
8445
- pnl: toProfitLossDto(activatedSignal, currentPrice),
8507
+ pnl: publicSignal.pnl,
8508
+ maxDrawdown: publicSignal.maxDrawdown,
8509
+ peakProfit: publicSignal.peakProfit,
8510
+ signal: publicSignal,
8446
8511
  note: activatedSignal.activateNote ?? activatedSignal.note,
8447
8512
  });
8448
8513
  return await RETURN_IDLE_FN(this, currentPrice);
@@ -8450,7 +8515,7 @@ class ClientStrategy {
8450
8515
  await this.setPendingSignal(pendingSignal);
8451
8516
  await CALL_RISK_ADD_SIGNAL_FN(this, this.params.execution.context.symbol, pendingSignal, currentTime, this.params.execution.context.backtest);
8452
8517
  // Emit commit AFTER successful risk check
8453
- const publicSignalForCommit = TO_PUBLIC_SIGNAL(pendingSignal, currentPrice);
8518
+ const publicSignalForCommit = TO_PUBLIC_SIGNAL("pending", pendingSignal, currentPrice);
8454
8519
  await CALL_COMMIT_FN(this, {
8455
8520
  action: "activate-scheduled",
8456
8521
  symbol: this.params.execution.context.symbol,
@@ -8462,7 +8527,10 @@ class ClientStrategy {
8462
8527
  activateId: activatedSignal.activateId,
8463
8528
  timestamp: currentTime,
8464
8529
  currentPrice,
8465
- pnl: toProfitLossDto(pendingSignal, currentPrice),
8530
+ pnl: publicSignalForCommit.pnl,
8531
+ maxDrawdown: publicSignalForCommit.maxDrawdown,
8532
+ peakProfit: publicSignalForCommit.peakProfit,
8533
+ signal: publicSignalForCommit,
8466
8534
  position: publicSignalForCommit.position,
8467
8535
  priceOpen: publicSignalForCommit.priceOpen,
8468
8536
  priceTakeProfit: publicSignalForCommit.priceTakeProfit,
@@ -8480,7 +8548,7 @@ class ClientStrategy {
8480
8548
  await CALL_OPEN_CALLBACKS_FN(this, this.params.execution.context.symbol, pendingSignal, currentPrice, currentTime, this.params.execution.context.backtest);
8481
8549
  const result = {
8482
8550
  action: "opened",
8483
- signal: TO_PUBLIC_SIGNAL(pendingSignal, currentPrice),
8551
+ signal: publicSignalForCommit,
8484
8552
  strategyName: this.params.method.context.strategyName,
8485
8553
  exchangeName: this.params.method.context.exchangeName,
8486
8554
  frameName: this.params.method.context.frameName,
@@ -8596,6 +8664,7 @@ class ClientStrategy {
8596
8664
  this._cancelledSignal = null; // Clear after using
8597
8665
  const closeTimestamp = this.params.execution.context.when.getTime();
8598
8666
  // Emit commit with correct timestamp from backtest context
8667
+ const publicSignal = TO_PUBLIC_SIGNAL("scheduled", cancelledSignal, currentPrice);
8599
8668
  await CALL_COMMIT_FN(this, {
8600
8669
  action: "cancel-scheduled",
8601
8670
  symbol: this.params.execution.context.symbol,
@@ -8609,13 +8678,16 @@ class ClientStrategy {
8609
8678
  totalEntries: cancelledSignal._entry?.length ?? 1,
8610
8679
  totalPartials: cancelledSignal._partial?.length ?? 0,
8611
8680
  originalPriceOpen: cancelledSignal.priceOpen,
8612
- pnl: toProfitLossDto(cancelledSignal, currentPrice),
8681
+ pnl: publicSignal.pnl,
8682
+ maxDrawdown: publicSignal.maxDrawdown,
8683
+ peakProfit: publicSignal.peakProfit,
8684
+ signal: publicSignal,
8613
8685
  note: cancelledSignal.cancelNote ?? cancelledSignal.note,
8614
8686
  });
8615
8687
  await CALL_CANCEL_CALLBACKS_FN(this, this.params.execution.context.symbol, cancelledSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
8616
8688
  const cancelledResult = {
8617
8689
  action: "cancelled",
8618
- signal: TO_PUBLIC_SIGNAL(cancelledSignal, currentPrice),
8690
+ signal: publicSignal,
8619
8691
  currentPrice,
8620
8692
  closeTimestamp: closeTimestamp,
8621
8693
  strategyName: this.params.method.context.strategyName,
@@ -8651,6 +8723,7 @@ class ClientStrategy {
8651
8723
  }
8652
8724
  this._closedSignal = null; // Clear only after sync confirmed
8653
8725
  // Emit commit with correct timestamp from backtest context
8726
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", closedSignal, currentPrice);
8654
8727
  await CALL_COMMIT_FN(this, {
8655
8728
  action: "close-pending",
8656
8729
  symbol: this.params.execution.context.symbol,
@@ -8664,7 +8737,10 @@ class ClientStrategy {
8664
8737
  totalEntries: closedSignal._entry?.length ?? 1,
8665
8738
  totalPartials: closedSignal._partial?.length ?? 0,
8666
8739
  originalPriceOpen: closedSignal.priceOpen,
8667
- pnl: toProfitLossDto(closedSignal, currentPrice),
8740
+ pnl: publicSignal.pnl,
8741
+ maxDrawdown: publicSignal.maxDrawdown,
8742
+ peakProfit: publicSignal.peakProfit,
8743
+ signal: publicSignal,
8668
8744
  note: closedSignal.closeNote ?? closedSignal.note,
8669
8745
  });
8670
8746
  await CALL_CLOSE_CALLBACKS_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
@@ -8673,14 +8749,13 @@ class ClientStrategy {
8673
8749
  // КРИТИЧНО: Очищаем состояние ClientBreakeven при закрытии позиции
8674
8750
  await CALL_BREAKEVEN_CLEAR_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
8675
8751
  await CALL_RISK_REMOVE_SIGNAL_FN(this, this.params.execution.context.symbol, closeTimestamp, this.params.execution.context.backtest);
8676
- const pnl = toProfitLossDto(closedSignal, currentPrice);
8677
8752
  const closedResult = {
8678
8753
  action: "closed",
8679
- signal: TO_PUBLIC_SIGNAL(closedSignal, currentPrice),
8754
+ signal: publicSignal,
8680
8755
  currentPrice,
8681
8756
  closeReason: "closed",
8682
8757
  closeTimestamp: closeTimestamp,
8683
- pnl,
8758
+ pnl: publicSignal.pnl,
8684
8759
  strategyName: this.params.method.context.strategyName,
8685
8760
  exchangeName: this.params.method.context.exchangeName,
8686
8761
  frameName: this.params.method.context.frameName,
@@ -9136,7 +9211,7 @@ class ClientStrategy {
9136
9211
  });
9137
9212
  // Call onWrite callback for testing persist storage
9138
9213
  if (this.params.callbacks?.onWrite) {
9139
- this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice), backtest);
9214
+ this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice), backtest);
9140
9215
  }
9141
9216
  if (!backtest) {
9142
9217
  await PersistSignalAdapter.writeSignalData(this._pendingSignal, this.params.execution.context.symbol, this.params.strategyName, this.params.exchangeName);
@@ -9319,7 +9394,7 @@ class ClientStrategy {
9319
9394
  });
9320
9395
  // Call onWrite callback for testing persist storage
9321
9396
  if (this.params.callbacks?.onWrite) {
9322
- this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice), backtest);
9397
+ this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice), backtest);
9323
9398
  }
9324
9399
  if (!backtest) {
9325
9400
  await PersistSignalAdapter.writeSignalData(this._pendingSignal, this.params.execution.context.symbol, this.params.strategyName, this.params.exchangeName);
@@ -9517,7 +9592,7 @@ class ClientStrategy {
9517
9592
  });
9518
9593
  // Call onWrite callback for testing persist storage
9519
9594
  if (this.params.callbacks?.onWrite) {
9520
- const publicSignal = TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice);
9595
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice);
9521
9596
  this.params.callbacks.onWrite(this.params.execution.context.symbol, publicSignal, backtest);
9522
9597
  }
9523
9598
  if (!backtest) {
@@ -9766,7 +9841,7 @@ class ClientStrategy {
9766
9841
  });
9767
9842
  // Call onWrite callback for testing persist storage
9768
9843
  if (this.params.callbacks?.onWrite) {
9769
- const publicSignal = TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice);
9844
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice);
9770
9845
  this.params.callbacks.onWrite(this.params.execution.context.symbol, publicSignal, backtest);
9771
9846
  }
9772
9847
  if (!backtest) {
@@ -10002,7 +10077,7 @@ class ClientStrategy {
10002
10077
  });
10003
10078
  // Call onWrite callback for testing persist storage
10004
10079
  if (this.params.callbacks?.onWrite) {
10005
- const publicSignal = TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice);
10080
+ const publicSignal = TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice);
10006
10081
  this.params.callbacks.onWrite(this.params.execution.context.symbol, publicSignal, backtest);
10007
10082
  }
10008
10083
  if (!backtest) {
@@ -10094,7 +10169,7 @@ class ClientStrategy {
10094
10169
  });
10095
10170
  // Call onWrite callback for testing persist storage
10096
10171
  if (this.params.callbacks?.onWrite) {
10097
- this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice), backtest);
10172
+ this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice), backtest);
10098
10173
  }
10099
10174
  if (!backtest) {
10100
10175
  await PersistSignalAdapter.writeSignalData(this._pendingSignal, this.params.execution.context.symbol, this.params.strategyName, this.params.exchangeName);
@@ -12465,12 +12540,15 @@ const alignToInterval = (date, interval) => {
12465
12540
 
12466
12541
  /** Symbol indicating that positions need to be fetched from persistence */
12467
12542
  const POSITION_NEED_FETCH = Symbol("risk-need-fetch");
12543
+ /** Get timestamp from execution context or fallback to aligned current time */
12468
12544
  const GET_CONTEXT_TIMESTAMP_FN = (self) => {
12469
12545
  if (ExecutionContextService.hasContext()) {
12470
12546
  return self.params.execution.context.when.getTime();
12471
12547
  }
12472
12548
  return alignToInterval(new Date(), "1m").getTime();
12473
12549
  };
12550
+ /** Zero PNL constant for scheduled signals (which don't have priceOpen or PNL yet) */
12551
+ const ZERO_PNL = { pnlPercentage: 0, priceOpen: 0, priceClose: 0, pnlCost: 0, pnlEntries: 0 };
12474
12552
  /**
12475
12553
  * Converts signal to risk validation format.
12476
12554
  *
@@ -12513,6 +12591,9 @@ const TO_RISK_SIGNAL = (signal, currentPrice, timestamp) => {
12513
12591
  const partialExecuted = ("_partial" in signal && Array.isArray(signal._partial))
12514
12592
  ? signal._partial.reduce((sum, partial) => sum + partial.percent, 0)
12515
12593
  : 0;
12594
+ const pnl = signal._isScheduled ? ZERO_PNL : toProfitLossDto(signal, currentPrice);
12595
+ const maxDrawdown = signal._isScheduled ? ZERO_PNL : pnl;
12596
+ const peakProfit = signal._isScheduled ? ZERO_PNL : pnl;
12516
12597
  return {
12517
12598
  ...structuredClone(signal),
12518
12599
  cost: signal.cost || GLOBAL_CONFIG.CC_POSITION_ENTRY_COST,
@@ -12526,7 +12607,9 @@ const TO_RISK_SIGNAL = (signal, currentPrice, timestamp) => {
12526
12607
  originalPriceTakeProfit: signal.priceTakeProfit,
12527
12608
  originalPriceOpen: signal.priceOpen ?? currentPrice,
12528
12609
  partialExecuted,
12529
- pnl: toProfitLossDto(signal, currentPrice),
12610
+ pnl,
12611
+ maxDrawdown,
12612
+ peakProfit,
12530
12613
  };
12531
12614
  };
12532
12615
  /** Key generator for active position map */
@@ -18796,7 +18879,9 @@ const backtest_columns = [
18796
18879
  key: "peakPnl",
18797
18880
  label: "Peak PNL",
18798
18881
  format: (data) => {
18799
- const v = data.signal._peak?.pnlPercentage;
18882
+ const v = data.signal.peakProfit?.pnlPercentage;
18883
+ if (v === undefined)
18884
+ return "N/A";
18800
18885
  return `${v > 0 ? "+" : ""}${v.toFixed(2)}%`;
18801
18886
  },
18802
18887
  isVisible: () => true,
@@ -18804,7 +18889,12 @@ const backtest_columns = [
18804
18889
  {
18805
18890
  key: "fallPnl",
18806
18891
  label: "Max DD PNL",
18807
- format: (data) => `${data.signal._fall?.pnlPercentage.toFixed(2)}%`,
18892
+ format: (data) => {
18893
+ const v = data.signal.maxDrawdown?.pnlPercentage;
18894
+ if (v === undefined)
18895
+ return "N/A";
18896
+ return `${v.toFixed(2)}%`;
18897
+ },
18808
18898
  isVisible: () => true,
18809
18899
  },
18810
18900
  ];
@@ -21365,8 +21455,8 @@ let ReportStorage$a = class ReportStorage {
21365
21455
  const tradesPerYear = avgDurationDays > 0 ? 365 / avgDurationDays : 0;
21366
21456
  const expectedYearlyReturns = avgPnl * tradesPerYear;
21367
21457
  // Calculate average peak and fall PNL across all signals
21368
- const avgPeakPnl = this._signalList.reduce((sum, s) => sum + (s.signal._peak?.pnlPercentage ?? 0), 0) / totalSignals;
21369
- const avgFallPnl = this._signalList.reduce((sum, s) => sum + (s.signal._fall?.pnlPercentage ?? 0), 0) / totalSignals;
21458
+ const avgPeakPnl = this._signalList.reduce((sum, s) => sum + (s.signal.peakProfit?.pnlPercentage ?? 0), 0) / totalSignals;
21459
+ const avgFallPnl = this._signalList.reduce((sum, s) => sum + (s.signal.maxDrawdown?.pnlPercentage ?? 0), 0) / totalSignals;
21370
21460
  return {
21371
21461
  signalList: this._signalList,
21372
21462
  totalSignals,
@@ -21895,8 +21985,8 @@ let ReportStorage$9 = class ReportStorage {
21895
21985
  duration: durationMin,
21896
21986
  pendingAt: data.signal.pendingAt,
21897
21987
  scheduledAt: data.signal.scheduledAt,
21898
- peakPnl: data.signal._peak?.pnlPercentage,
21899
- fallPnl: data.signal._fall?.pnlPercentage,
21988
+ peakPnl: data.signal.peakProfit?.pnlPercentage,
21989
+ fallPnl: data.signal.maxDrawdown?.pnlPercentage,
21900
21990
  };
21901
21991
  this._eventList.unshift(newEvent);
21902
21992
  // Trim queue if exceeded GLOBAL_CONFIG.CC_MAX_LIVE_MARKDOWN_ROWS
@@ -24047,8 +24137,8 @@ class HeatmapStorage {
24047
24137
  let avgPeakPnl = null;
24048
24138
  let avgFallPnl = null;
24049
24139
  if (signals.length > 0) {
24050
- avgPeakPnl = signals.reduce((acc, s) => acc + (s.signal._peak?.pnlPercentage ?? 0), 0) / signals.length;
24051
- avgFallPnl = signals.reduce((acc, s) => acc + (s.signal._fall?.pnlPercentage ?? 0), 0) / signals.length;
24140
+ avgPeakPnl = signals.reduce((acc, s) => acc + (s.signal.peakProfit?.pnlPercentage ?? 0), 0) / signals.length;
24141
+ avgFallPnl = signals.reduce((acc, s) => acc + (s.signal.maxDrawdown?.pnlPercentage ?? 0), 0) / signals.length;
24052
24142
  }
24053
24143
  // Apply safe math checks
24054
24144
  if (isUnsafe(winRate))
@@ -28175,8 +28265,16 @@ class BacktestReportService {
28175
28265
  pnlPriceClose: data.pnl.priceClose,
28176
28266
  totalPartials: data.signal?.totalPartials,
28177
28267
  cost: data.signal?.cost,
28178
- peakPnl: data.signal?._peak?.pnlPercentage,
28179
- fallPnl: data.signal?._fall?.pnlPercentage,
28268
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
28269
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
28270
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
28271
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
28272
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
28273
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
28274
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
28275
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
28276
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
28277
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
28180
28278
  }, { ...searchOptions, signalId: data.signal?.id });
28181
28279
  }
28182
28280
  else if (data.action === "closed") {
@@ -28209,8 +28307,16 @@ class BacktestReportService {
28209
28307
  closeReason: data.closeReason,
28210
28308
  closeTime: data.closeTimestamp,
28211
28309
  duration: durationMin,
28212
- peakPnl: data.signal?._peak?.pnlPercentage,
28213
- fallPnl: data.signal?._fall?.pnlPercentage,
28310
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
28311
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
28312
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
28313
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
28314
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
28315
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
28316
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
28317
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
28318
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
28319
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
28214
28320
  }, { ...searchOptions, signalId: data.signal?.id });
28215
28321
  }
28216
28322
  };
@@ -28373,8 +28479,16 @@ class LiveReportService {
28373
28479
  pnlPriceClose: data.pnl.priceClose,
28374
28480
  totalPartials: data.signal?.totalPartials,
28375
28481
  cost: data.signal?.cost,
28376
- peakPnl: data.signal?._peak?.pnlPercentage,
28377
- fallPnl: data.signal?._fall?.pnlPercentage,
28482
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
28483
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
28484
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
28485
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
28486
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
28487
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
28488
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
28489
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
28490
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
28491
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
28378
28492
  }, { ...searchOptions, signalId: data.signal?.id });
28379
28493
  }
28380
28494
  else if (data.action === "opened") {
@@ -28425,8 +28539,16 @@ class LiveReportService {
28425
28539
  pnlPriceClose: data.pnl.priceClose,
28426
28540
  totalPartials: data.signal?.totalPartials,
28427
28541
  cost: data.signal?.cost,
28428
- peakPnl: data.signal?._peak?.pnlPercentage,
28429
- fallPnl: data.signal?._fall?.pnlPercentage,
28542
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
28543
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
28544
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
28545
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
28546
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
28547
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
28548
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
28549
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
28550
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
28551
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
28430
28552
  }, { ...searchOptions, signalId: data.signal?.id });
28431
28553
  }
28432
28554
  else if (data.action === "closed") {
@@ -28459,8 +28581,16 @@ class LiveReportService {
28459
28581
  closeReason: data.closeReason,
28460
28582
  duration: durationMin,
28461
28583
  closeTime: data.closeTimestamp,
28462
- peakPnl: data.signal?._peak?.pnlPercentage,
28463
- fallPnl: data.signal?._fall?.pnlPercentage,
28584
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
28585
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
28586
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
28587
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
28588
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
28589
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
28590
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
28591
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
28592
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
28593
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
28464
28594
  }, { ...searchOptions, signalId: data.signal?.id });
28465
28595
  }
28466
28596
  else if (data.action === "cancelled") {
@@ -29052,8 +29182,16 @@ class HeatReportService {
29052
29182
  openTime: data.signal?.pendingAt,
29053
29183
  scheduledAt: data.signal?.scheduledAt,
29054
29184
  closeTime: data.closeTimestamp,
29055
- peakPnl: data.signal?._peak?.pnlPercentage,
29056
- fallPnl: data.signal?._fall?.pnlPercentage,
29185
+ peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
29186
+ peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
29187
+ peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
29188
+ peakProfitCost: data.signal?.peakProfit?.pnlCost,
29189
+ peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
29190
+ maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
29191
+ maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
29192
+ maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
29193
+ maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
29194
+ maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
29057
29195
  }, {
29058
29196
  symbol: data.symbol,
29059
29197
  strategyName: data.strategyName,
@@ -29187,6 +29325,16 @@ class PartialReportService {
29187
29325
  pnlEntries: data.data.pnl.pnlEntries,
29188
29326
  pnlPriceOpen: data.data.pnl.priceOpen,
29189
29327
  pnlPriceClose: data.data.pnl.priceClose,
29328
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
29329
+ peakProfitCost: data.data.peakProfit.pnlCost,
29330
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
29331
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
29332
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
29333
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
29334
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
29335
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
29336
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
29337
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
29190
29338
  }, {
29191
29339
  symbol: data.symbol,
29192
29340
  strategyName: data.data.strategyName,
@@ -29237,6 +29385,16 @@ class PartialReportService {
29237
29385
  pnlEntries: data.data.pnl.pnlEntries,
29238
29386
  pnlPriceOpen: data.data.pnl.priceOpen,
29239
29387
  pnlPriceClose: data.data.pnl.priceClose,
29388
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
29389
+ peakProfitCost: data.data.peakProfit.pnlCost,
29390
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
29391
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
29392
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
29393
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
29394
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
29395
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
29396
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
29397
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
29240
29398
  }, {
29241
29399
  symbol: data.symbol,
29242
29400
  strategyName: data.data.strategyName,
@@ -29368,6 +29526,16 @@ class BreakevenReportService {
29368
29526
  pnlEntries: data.data.pnl.pnlEntries,
29369
29527
  pnlPriceOpen: data.data.pnl.priceOpen,
29370
29528
  pnlPriceClose: data.data.pnl.priceClose,
29529
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
29530
+ peakProfitCost: data.data.peakProfit.pnlCost,
29531
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
29532
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
29533
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
29534
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
29535
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
29536
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
29537
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
29538
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
29371
29539
  }, {
29372
29540
  symbol: data.symbol,
29373
29541
  strategyName: data.data.strategyName,
@@ -29498,6 +29666,16 @@ class RiskReportService {
29498
29666
  pnlEntries: data.currentSignal?.pnl?.pnlEntries,
29499
29667
  pnlPriceOpen: data.currentSignal?.pnl?.priceOpen,
29500
29668
  pnlPriceClose: data.currentSignal?.pnl?.priceClose,
29669
+ peakProfitPercentage: data.currentSignal?.peakProfit?.pnlPercentage,
29670
+ peakProfitCost: data.currentSignal?.peakProfit?.pnlCost,
29671
+ peakProfitEntries: data.currentSignal?.peakProfit?.pnlEntries,
29672
+ peakProfitPriceOpen: data.currentSignal?.peakProfit?.priceOpen,
29673
+ peakProfitPriceClose: data.currentSignal?.peakProfit?.priceClose,
29674
+ maxDrawdownPercentage: data.currentSignal?.maxDrawdown?.pnlPercentage,
29675
+ maxDrawdownCost: data.currentSignal?.maxDrawdown?.pnlCost,
29676
+ maxDrawdownEntries: data.currentSignal?.maxDrawdown?.pnlEntries,
29677
+ maxDrawdownPriceOpen: data.currentSignal?.maxDrawdown?.priceOpen,
29678
+ maxDrawdownPriceClose: data.currentSignal?.maxDrawdown?.priceClose,
29501
29679
  }, {
29502
29680
  symbol: data.symbol,
29503
29681
  strategyName: data.strategyName,
@@ -29577,7 +29755,7 @@ class StrategyReportService {
29577
29755
  /**
29578
29756
  * Logs a cancel-scheduled event when a scheduled signal is cancelled.
29579
29757
  */
29580
- this.cancelScheduled = async (symbol, isBacktest, context, timestamp, signalId, pnl, totalPartials, cancelId, note) => {
29758
+ this.cancelScheduled = async (symbol, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, cancelId, note) => {
29581
29759
  this.loggerService.log("strategyReportService cancelScheduled", {
29582
29760
  symbol,
29583
29761
  isBacktest,
@@ -29599,6 +29777,16 @@ class StrategyReportService {
29599
29777
  pnlEntries: pnl.pnlEntries,
29600
29778
  pnlPriceOpen: pnl.priceOpen,
29601
29779
  pnlPriceClose: pnl.priceClose,
29780
+ peakProfitPercentage: peakProfit.pnlPercentage,
29781
+ peakProfitCost: peakProfit.pnlCost,
29782
+ peakProfitEntries: peakProfit.pnlEntries,
29783
+ peakProfitPriceOpen: peakProfit.priceOpen,
29784
+ peakProfitPriceClose: peakProfit.priceClose,
29785
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
29786
+ maxDrawdownCost: maxDrawdown.pnlCost,
29787
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
29788
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
29789
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29602
29790
  totalPartials,
29603
29791
  }, {
29604
29792
  signalId,
@@ -29612,7 +29800,7 @@ class StrategyReportService {
29612
29800
  /**
29613
29801
  * Logs a close-pending event when a pending signal is closed.
29614
29802
  */
29615
- this.closePending = async (symbol, isBacktest, context, timestamp, signalId, pnl, totalPartials, closeId, note) => {
29803
+ this.closePending = async (symbol, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, closeId, note) => {
29616
29804
  this.loggerService.log("strategyReportService closePending", {
29617
29805
  symbol,
29618
29806
  isBacktest,
@@ -29634,6 +29822,16 @@ class StrategyReportService {
29634
29822
  pnlEntries: pnl.pnlEntries,
29635
29823
  pnlPriceOpen: pnl.priceOpen,
29636
29824
  pnlPriceClose: pnl.priceClose,
29825
+ peakProfitPercentage: peakProfit.pnlPercentage,
29826
+ peakProfitCost: peakProfit.pnlCost,
29827
+ peakProfitEntries: peakProfit.pnlEntries,
29828
+ peakProfitPriceOpen: peakProfit.priceOpen,
29829
+ peakProfitPriceClose: peakProfit.priceClose,
29830
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
29831
+ maxDrawdownCost: maxDrawdown.pnlCost,
29832
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
29833
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
29834
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29637
29835
  totalPartials,
29638
29836
  }, {
29639
29837
  signalId,
@@ -29647,7 +29845,7 @@ class StrategyReportService {
29647
29845
  /**
29648
29846
  * Logs a partial-profit event when a portion of the position is closed at profit.
29649
29847
  */
29650
- this.partialProfit = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29848
+ this.partialProfit = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29651
29849
  this.loggerService.log("strategyReportService partialProfit", {
29652
29850
  symbol,
29653
29851
  percentToClose,
@@ -29680,6 +29878,16 @@ class StrategyReportService {
29680
29878
  pnlEntries: pnl.pnlEntries,
29681
29879
  pnlPriceOpen: pnl.priceOpen,
29682
29880
  pnlPriceClose: pnl.priceClose,
29881
+ peakProfitPercentage: peakProfit.pnlPercentage,
29882
+ peakProfitCost: peakProfit.pnlCost,
29883
+ peakProfitEntries: peakProfit.pnlEntries,
29884
+ peakProfitPriceOpen: peakProfit.priceOpen,
29885
+ peakProfitPriceClose: peakProfit.priceClose,
29886
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
29887
+ maxDrawdownCost: maxDrawdown.pnlCost,
29888
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
29889
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
29890
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29683
29891
  totalPartials,
29684
29892
  }, {
29685
29893
  signalId,
@@ -29693,7 +29901,7 @@ class StrategyReportService {
29693
29901
  /**
29694
29902
  * Logs a partial-loss event when a portion of the position is closed at loss.
29695
29903
  */
29696
- this.partialLoss = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29904
+ this.partialLoss = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29697
29905
  this.loggerService.log("strategyReportService partialLoss", {
29698
29906
  symbol,
29699
29907
  percentToClose,
@@ -29726,6 +29934,16 @@ class StrategyReportService {
29726
29934
  pnlEntries: pnl.pnlEntries,
29727
29935
  pnlPriceOpen: pnl.priceOpen,
29728
29936
  pnlPriceClose: pnl.priceClose,
29937
+ peakProfitPercentage: peakProfit.pnlPercentage,
29938
+ peakProfitCost: peakProfit.pnlCost,
29939
+ peakProfitEntries: peakProfit.pnlEntries,
29940
+ peakProfitPriceOpen: peakProfit.priceOpen,
29941
+ peakProfitPriceClose: peakProfit.priceClose,
29942
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
29943
+ maxDrawdownCost: maxDrawdown.pnlCost,
29944
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
29945
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
29946
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29729
29947
  totalPartials,
29730
29948
  }, {
29731
29949
  signalId,
@@ -29739,7 +29957,7 @@ class StrategyReportService {
29739
29957
  /**
29740
29958
  * Logs a trailing-stop event when the stop-loss is adjusted.
29741
29959
  */
29742
- this.trailingStop = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29960
+ this.trailingStop = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29743
29961
  this.loggerService.log("strategyReportService trailingStop", {
29744
29962
  symbol,
29745
29963
  percentShift,
@@ -29772,6 +29990,16 @@ class StrategyReportService {
29772
29990
  pnlEntries: pnl.pnlEntries,
29773
29991
  pnlPriceOpen: pnl.priceOpen,
29774
29992
  pnlPriceClose: pnl.priceClose,
29993
+ peakProfitPercentage: peakProfit.pnlPercentage,
29994
+ peakProfitCost: peakProfit.pnlCost,
29995
+ peakProfitEntries: peakProfit.pnlEntries,
29996
+ peakProfitPriceOpen: peakProfit.priceOpen,
29997
+ peakProfitPriceClose: peakProfit.priceClose,
29998
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
29999
+ maxDrawdownCost: maxDrawdown.pnlCost,
30000
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
30001
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
30002
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29775
30003
  totalPartials,
29776
30004
  }, {
29777
30005
  signalId,
@@ -29785,7 +30013,7 @@ class StrategyReportService {
29785
30013
  /**
29786
30014
  * Logs a trailing-take event when the take-profit is adjusted.
29787
30015
  */
29788
- this.trailingTake = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
30016
+ this.trailingTake = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29789
30017
  this.loggerService.log("strategyReportService trailingTake", {
29790
30018
  symbol,
29791
30019
  percentShift,
@@ -29818,6 +30046,16 @@ class StrategyReportService {
29818
30046
  pnlEntries: pnl.pnlEntries,
29819
30047
  pnlPriceOpen: pnl.priceOpen,
29820
30048
  pnlPriceClose: pnl.priceClose,
30049
+ peakProfitPercentage: peakProfit.pnlPercentage,
30050
+ peakProfitCost: peakProfit.pnlCost,
30051
+ peakProfitEntries: peakProfit.pnlEntries,
30052
+ peakProfitPriceOpen: peakProfit.priceOpen,
30053
+ peakProfitPriceClose: peakProfit.priceClose,
30054
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
30055
+ maxDrawdownCost: maxDrawdown.pnlCost,
30056
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
30057
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
30058
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29821
30059
  totalPartials,
29822
30060
  }, {
29823
30061
  signalId,
@@ -29831,7 +30069,7 @@ class StrategyReportService {
29831
30069
  /**
29832
30070
  * Logs a breakeven event when the stop-loss is moved to entry price.
29833
30071
  */
29834
- this.breakeven = async (symbol, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
30072
+ this.breakeven = async (symbol, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
29835
30073
  this.loggerService.log("strategyReportService breakeven", {
29836
30074
  symbol,
29837
30075
  currentPrice,
@@ -29862,6 +30100,16 @@ class StrategyReportService {
29862
30100
  pnlEntries: pnl.pnlEntries,
29863
30101
  pnlPriceOpen: pnl.priceOpen,
29864
30102
  pnlPriceClose: pnl.priceClose,
30103
+ peakProfitPercentage: peakProfit.pnlPercentage,
30104
+ peakProfitCost: peakProfit.pnlCost,
30105
+ peakProfitEntries: peakProfit.pnlEntries,
30106
+ peakProfitPriceOpen: peakProfit.priceOpen,
30107
+ peakProfitPriceClose: peakProfit.priceClose,
30108
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
30109
+ maxDrawdownCost: maxDrawdown.pnlCost,
30110
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
30111
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
30112
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29865
30113
  totalPartials,
29866
30114
  }, {
29867
30115
  signalId,
@@ -29875,7 +30123,7 @@ class StrategyReportService {
29875
30123
  /**
29876
30124
  * Logs an activate-scheduled event when a scheduled signal is activated early.
29877
30125
  */
29878
- this.activateScheduled = async (symbol, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen, activateId, note) => {
30126
+ 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) => {
29879
30127
  this.loggerService.log("strategyReportService activateScheduled", {
29880
30128
  symbol,
29881
30129
  currentPrice,
@@ -29909,6 +30157,16 @@ class StrategyReportService {
29909
30157
  pnlEntries: pnl.pnlEntries,
29910
30158
  pnlPriceOpen: pnl.priceOpen,
29911
30159
  pnlPriceClose: pnl.priceClose,
30160
+ peakProfitPercentage: peakProfit.pnlPercentage,
30161
+ peakProfitCost: peakProfit.pnlCost,
30162
+ peakProfitEntries: peakProfit.pnlEntries,
30163
+ peakProfitPriceOpen: peakProfit.priceOpen,
30164
+ peakProfitPriceClose: peakProfit.priceClose,
30165
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
30166
+ maxDrawdownCost: maxDrawdown.pnlCost,
30167
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
30168
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
30169
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29912
30170
  totalPartials,
29913
30171
  }, {
29914
30172
  signalId,
@@ -29922,7 +30180,7 @@ class StrategyReportService {
29922
30180
  /**
29923
30181
  * Logs an average-buy (DCA) event when a new averaging entry is added to an open position.
29924
30182
  */
29925
- this.averageBuy = async (symbol, currentPrice, effectivePriceOpen, totalEntries, isBacktest, context, timestamp, signalId, pnl, totalPartials, cost, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, originalPriceOpen) => {
30183
+ 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) => {
29926
30184
  this.loggerService.log("strategyReportService averageBuy", {
29927
30185
  symbol,
29928
30186
  currentPrice,
@@ -29956,6 +30214,16 @@ class StrategyReportService {
29956
30214
  pnlEntries: pnl.pnlEntries,
29957
30215
  pnlPriceOpen: pnl.priceOpen,
29958
30216
  pnlPriceClose: pnl.priceClose,
30217
+ peakProfitPercentage: peakProfit.pnlPercentage,
30218
+ peakProfitCost: peakProfit.pnlCost,
30219
+ peakProfitEntries: peakProfit.pnlEntries,
30220
+ peakProfitPriceOpen: peakProfit.priceOpen,
30221
+ peakProfitPriceClose: peakProfit.priceClose,
30222
+ maxDrawdownPercentage: maxDrawdown.pnlPercentage,
30223
+ maxDrawdownCost: maxDrawdown.pnlCost,
30224
+ maxDrawdownEntries: maxDrawdown.pnlEntries,
30225
+ maxDrawdownPriceOpen: maxDrawdown.priceOpen,
30226
+ maxDrawdownPriceClose: maxDrawdown.priceClose,
29959
30227
  totalPartials,
29960
30228
  cost,
29961
30229
  }, {
@@ -29983,63 +30251,63 @@ class StrategyReportService {
29983
30251
  exchangeName: event.exchangeName,
29984
30252
  frameName: event.frameName,
29985
30253
  strategyName: event.strategyName,
29986
- }, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.cancelId, event.note));
30254
+ }, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.cancelId, event.note));
29987
30255
  const unClosePending = strategyCommitSubject
29988
30256
  .filter(({ action }) => action === "close-pending")
29989
30257
  .connect(async (event) => await this.closePending(event.symbol, event.backtest, {
29990
30258
  exchangeName: event.exchangeName,
29991
30259
  frameName: event.frameName,
29992
30260
  strategyName: event.strategyName,
29993
- }, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.closeId, event.note));
30261
+ }, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.closeId, event.note));
29994
30262
  const unPartialProfit = strategyCommitSubject
29995
30263
  .filter(({ action }) => action === "partial-profit")
29996
30264
  .connect(async (event) => await this.partialProfit(event.symbol, event.percentToClose, event.currentPrice, event.backtest, {
29997
30265
  exchangeName: event.exchangeName,
29998
30266
  frameName: event.frameName,
29999
30267
  strategyName: event.strategyName,
30000
- }, 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));
30268
+ }, 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));
30001
30269
  const unPartialLoss = strategyCommitSubject
30002
30270
  .filter(({ action }) => action === "partial-loss")
30003
30271
  .connect(async (event) => await this.partialLoss(event.symbol, event.percentToClose, event.currentPrice, event.backtest, {
30004
30272
  exchangeName: event.exchangeName,
30005
30273
  frameName: event.frameName,
30006
30274
  strategyName: event.strategyName,
30007
- }, 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));
30275
+ }, 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));
30008
30276
  const unTrailingStop = strategyCommitSubject
30009
30277
  .filter(({ action }) => action === "trailing-stop")
30010
30278
  .connect(async (event) => await this.trailingStop(event.symbol, event.percentShift, event.currentPrice, event.backtest, {
30011
30279
  exchangeName: event.exchangeName,
30012
30280
  frameName: event.frameName,
30013
30281
  strategyName: event.strategyName,
30014
- }, 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));
30282
+ }, 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));
30015
30283
  const unTrailingTake = strategyCommitSubject
30016
30284
  .filter(({ action }) => action === "trailing-take")
30017
30285
  .connect(async (event) => await this.trailingTake(event.symbol, event.percentShift, event.currentPrice, event.backtest, {
30018
30286
  exchangeName: event.exchangeName,
30019
30287
  frameName: event.frameName,
30020
30288
  strategyName: event.strategyName,
30021
- }, 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));
30289
+ }, 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));
30022
30290
  const unBreakeven = strategyCommitSubject
30023
30291
  .filter(({ action }) => action === "breakeven")
30024
30292
  .connect(async (event) => await this.breakeven(event.symbol, event.currentPrice, event.backtest, {
30025
30293
  exchangeName: event.exchangeName,
30026
30294
  frameName: event.frameName,
30027
30295
  strategyName: event.strategyName,
30028
- }, 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));
30296
+ }, 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));
30029
30297
  const unActivateScheduled = strategyCommitSubject
30030
30298
  .filter(({ action }) => action === "activate-scheduled")
30031
30299
  .connect(async (event) => await this.activateScheduled(event.symbol, event.currentPrice, event.backtest, {
30032
30300
  exchangeName: event.exchangeName,
30033
30301
  frameName: event.frameName,
30034
30302
  strategyName: event.strategyName,
30035
- }, 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));
30303
+ }, 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));
30036
30304
  const unAverageBuy = strategyCommitSubject
30037
30305
  .filter(({ action }) => action === "average-buy")
30038
30306
  .connect(async (event) => await this.averageBuy(event.symbol, event.currentPrice, event.effectivePriceOpen, event.totalEntries, event.backtest, {
30039
30307
  exchangeName: event.exchangeName,
30040
30308
  frameName: event.frameName,
30041
30309
  strategyName: event.strategyName,
30042
- }, 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));
30310
+ }, 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));
30043
30311
  const disposeFn = compose(() => unCancelSchedule(), () => unClosePending(), () => unPartialProfit(), () => unPartialLoss(), () => unTrailingStop(), () => unTrailingTake(), () => unBreakeven(), () => unActivateScheduled(), () => unAverageBuy());
30044
30312
  return () => {
30045
30313
  disposeFn();
@@ -30138,6 +30406,16 @@ class SyncReportService {
30138
30406
  pnlEntries: data.pnl.pnlEntries,
30139
30407
  pnlPriceOpen: data.pnl.priceOpen,
30140
30408
  pnlPriceClose: data.pnl.priceClose,
30409
+ peakProfitPercentage: data.peakProfit.pnlPercentage,
30410
+ peakProfitCost: data.peakProfit.pnlCost,
30411
+ peakProfitEntries: data.peakProfit.pnlEntries,
30412
+ peakProfitPriceOpen: data.peakProfit.priceOpen,
30413
+ peakProfitPriceClose: data.peakProfit.priceClose,
30414
+ maxDrawdownPercentage: data.maxDrawdown.pnlPercentage,
30415
+ maxDrawdownCost: data.maxDrawdown.pnlCost,
30416
+ maxDrawdownEntries: data.maxDrawdown.pnlEntries,
30417
+ maxDrawdownPriceOpen: data.maxDrawdown.priceOpen,
30418
+ maxDrawdownPriceClose: data.maxDrawdown.priceClose,
30141
30419
  currentPrice: data.currentPrice,
30142
30420
  };
30143
30421
  const searchOptions = {
@@ -30248,6 +30526,16 @@ class HighestProfitReportService {
30248
30526
  priceOpen: data.signal.priceOpen,
30249
30527
  priceTakeProfit: data.signal.priceTakeProfit,
30250
30528
  priceStopLoss: data.signal.priceStopLoss,
30529
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
30530
+ peakProfitCost: data.signal.peakProfit.pnlCost,
30531
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
30532
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
30533
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
30534
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
30535
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
30536
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
30537
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
30538
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
30251
30539
  }, {
30252
30540
  symbol: data.symbol,
30253
30541
  strategyName: data.signal.strategyName,
@@ -31525,7 +31813,9 @@ class SyncMarkdownService {
31525
31813
  pendingAt: data.pendingAt,
31526
31814
  totalEntries: data.totalEntries,
31527
31815
  totalPartials: data.totalPartials,
31528
- pnl: data.pnl,
31816
+ pnl: data.signal.pnl,
31817
+ maxDrawdown: data.signal.maxDrawdown,
31818
+ peakProfit: data.signal.peakProfit,
31529
31819
  closeReason: data.action === "signal-close" ? data.closeReason : undefined,
31530
31820
  backtest: data.backtest,
31531
31821
  createdAt,
@@ -31700,6 +31990,8 @@ let ReportStorage$1 = class ReportStorage {
31700
31990
  signalId: data.id,
31701
31991
  position: data.position,
31702
31992
  pnl: data.pnl,
31993
+ maxDrawdown: data.maxDrawdown,
31994
+ peakProfit: data.peakProfit,
31703
31995
  currentPrice,
31704
31996
  priceOpen: data.priceOpen,
31705
31997
  priceTakeProfit: data.priceTakeProfit,
@@ -32311,6 +32603,16 @@ class MaxDrawdownReportService {
32311
32603
  priceOpen: data.signal.priceOpen,
32312
32604
  priceTakeProfit: data.signal.priceTakeProfit,
32313
32605
  priceStopLoss: data.signal.priceStopLoss,
32606
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
32607
+ peakProfitCost: data.signal.peakProfit.pnlCost,
32608
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
32609
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
32610
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
32611
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
32612
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
32613
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
32614
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
32615
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
32314
32616
  }, {
32315
32617
  symbol: data.symbol,
32316
32618
  strategyName: data.signal.strategyName,
@@ -32403,6 +32705,8 @@ class ReportStorage {
32403
32705
  signalId: data.id,
32404
32706
  position: data.position,
32405
32707
  pnl: data.pnl,
32708
+ maxDrawdown: data.maxDrawdown,
32709
+ peakProfit: data.peakProfit,
32406
32710
  currentPrice,
32407
32711
  priceOpen: data.priceOpen,
32408
32712
  priceTakeProfit: data.priceTakeProfit,
@@ -35354,6 +35658,9 @@ class BrokerAdapter {
35354
35658
  priceTakeProfit: event.signal.priceTakeProfit,
35355
35659
  priceStopLoss: event.signal.priceStopLoss,
35356
35660
  priceOpen: event.signal.priceOpen,
35661
+ pnl: event.signal.pnl,
35662
+ peakProfit: event.signal.peakProfit,
35663
+ maxDrawdown: event.signal.maxDrawdown,
35357
35664
  context: {
35358
35665
  strategyName: event.strategyName,
35359
35666
  exchangeName: event.exchangeName,
@@ -35371,7 +35678,10 @@ class BrokerAdapter {
35371
35678
  currentPrice: event.currentPrice,
35372
35679
  cost: event.signal.cost,
35373
35680
  symbol: event.symbol,
35374
- pnl: event.pnl,
35681
+ pnl: event.signal.pnl,
35682
+ priceOpen: event.signal.priceOpen,
35683
+ peakProfit: event.signal.peakProfit,
35684
+ maxDrawdown: event.signal.maxDrawdown,
35375
35685
  totalEntries: event.totalEntries,
35376
35686
  totalPartials: event.totalPartials,
35377
35687
  priceStopLoss: event.signal.priceStopLoss,
@@ -54413,11 +54723,23 @@ const CREATE_SIGNAL_NOTIFICATION_FN = (data) => {
54413
54723
  totalPartials: data.signal.totalPartials,
54414
54724
  cost: data.signal.cost,
54415
54725
  pnl: data.signal.pnl,
54726
+ maxDrawdown: data.signal.maxDrawdown,
54727
+ peakProfit: data.signal.peakProfit,
54416
54728
  pnlPercentage: data.signal.pnl.pnlPercentage,
54417
54729
  pnlPriceOpen: data.signal.pnl.priceOpen,
54418
54730
  pnlPriceClose: data.signal.pnl.priceClose,
54419
54731
  pnlCost: data.signal.pnl.pnlCost,
54420
54732
  pnlEntries: data.signal.pnl.pnlEntries,
54733
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
54734
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
54735
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
54736
+ peakProfitCost: data.signal.peakProfit.pnlCost,
54737
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
54738
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
54739
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
54740
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
54741
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
54742
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54421
54743
  note: data.signal.note,
54422
54744
  scheduledAt: data.signal.scheduledAt,
54423
54745
  pendingAt: data.signal.pendingAt,
@@ -54447,11 +54769,23 @@ const CREATE_SIGNAL_NOTIFICATION_FN = (data) => {
54447
54769
  totalEntries: data.signal.totalEntries,
54448
54770
  totalPartials: data.signal.totalPartials,
54449
54771
  pnlPercentage: data.pnl.pnlPercentage,
54450
- pnl: data.pnl,
54772
+ pnl: data.signal.pnl,
54773
+ maxDrawdown: data.signal.maxDrawdown,
54774
+ peakProfit: data.signal.peakProfit,
54451
54775
  pnlPriceOpen: data.pnl.priceOpen,
54452
54776
  pnlPriceClose: data.pnl.priceClose,
54453
54777
  pnlCost: data.pnl.pnlCost,
54454
54778
  pnlEntries: data.pnl.pnlEntries,
54779
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
54780
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
54781
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
54782
+ peakProfitCost: data.signal.peakProfit.pnlCost,
54783
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
54784
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
54785
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
54786
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
54787
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
54788
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54455
54789
  closeReason: data.closeReason,
54456
54790
  duration: durationMin,
54457
54791
  note: data.signal.note,
@@ -54481,11 +54815,23 @@ const CREATE_SIGNAL_NOTIFICATION_FN = (data) => {
54481
54815
  totalPartials: data.signal.totalPartials,
54482
54816
  cost: data.signal.cost,
54483
54817
  pnl: data.signal.pnl,
54818
+ maxDrawdown: data.signal.maxDrawdown,
54819
+ peakProfit: data.signal.peakProfit,
54484
54820
  pnlPercentage: data.signal.pnl.pnlPercentage,
54485
54821
  pnlPriceOpen: data.signal.pnl.priceOpen,
54486
54822
  pnlPriceClose: data.signal.pnl.priceClose,
54487
54823
  pnlCost: data.signal.pnl.pnlCost,
54488
54824
  pnlEntries: data.signal.pnl.pnlEntries,
54825
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
54826
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
54827
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
54828
+ peakProfitCost: data.signal.peakProfit.pnlCost,
54829
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
54830
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
54831
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
54832
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
54833
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
54834
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54489
54835
  scheduledAt: data.signal.scheduledAt,
54490
54836
  currentPrice: data.currentPrice,
54491
54837
  note: data.signal.note,
@@ -54550,11 +54896,23 @@ const CREATE_PARTIAL_PROFIT_NOTIFICATION_FN = (data) => ({
54550
54896
  totalEntries: data.data.totalEntries,
54551
54897
  totalPartials: data.data.totalPartials,
54552
54898
  pnl: data.data.pnl,
54899
+ maxDrawdown: data.data.maxDrawdown,
54900
+ peakProfit: data.data.peakProfit,
54553
54901
  pnlPercentage: data.data.pnl.pnlPercentage,
54554
54902
  pnlPriceOpen: data.data.pnl.priceOpen,
54555
54903
  pnlPriceClose: data.data.pnl.priceClose,
54556
54904
  pnlCost: data.data.pnl.pnlCost,
54557
54905
  pnlEntries: data.data.pnl.pnlEntries,
54906
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
54907
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
54908
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
54909
+ peakProfitCost: data.data.peakProfit.pnlCost,
54910
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
54911
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
54912
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
54913
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
54914
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
54915
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
54558
54916
  note: data.data.note,
54559
54917
  scheduledAt: data.data.scheduledAt,
54560
54918
  pendingAt: data.data.pendingAt,
@@ -54586,11 +54944,23 @@ const CREATE_PARTIAL_LOSS_NOTIFICATION_FN = (data) => ({
54586
54944
  totalEntries: data.data.totalEntries,
54587
54945
  totalPartials: data.data.totalPartials,
54588
54946
  pnl: data.data.pnl,
54947
+ maxDrawdown: data.data.maxDrawdown,
54948
+ peakProfit: data.data.peakProfit,
54589
54949
  pnlPercentage: data.data.pnl.pnlPercentage,
54590
54950
  pnlPriceOpen: data.data.pnl.priceOpen,
54591
54951
  pnlPriceClose: data.data.pnl.priceClose,
54592
54952
  pnlCost: data.data.pnl.pnlCost,
54593
54953
  pnlEntries: data.data.pnl.pnlEntries,
54954
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
54955
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
54956
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
54957
+ peakProfitCost: data.data.peakProfit.pnlCost,
54958
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
54959
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
54960
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
54961
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
54962
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
54963
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
54594
54964
  note: data.data.note,
54595
54965
  scheduledAt: data.data.scheduledAt,
54596
54966
  pendingAt: data.data.pendingAt,
@@ -54621,11 +54991,23 @@ const CREATE_BREAKEVEN_NOTIFICATION_FN = (data) => ({
54621
54991
  totalEntries: data.data.totalEntries,
54622
54992
  totalPartials: data.data.totalPartials,
54623
54993
  pnl: data.data.pnl,
54994
+ maxDrawdown: data.data.maxDrawdown,
54995
+ peakProfit: data.data.peakProfit,
54624
54996
  pnlPercentage: data.data.pnl.pnlPercentage,
54625
54997
  pnlPriceOpen: data.data.pnl.priceOpen,
54626
54998
  pnlPriceClose: data.data.pnl.priceClose,
54627
54999
  pnlCost: data.data.pnl.pnlCost,
54628
55000
  pnlEntries: data.data.pnl.pnlEntries,
55001
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
55002
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
55003
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
55004
+ peakProfitCost: data.data.peakProfit.pnlCost,
55005
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
55006
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
55007
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
55008
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
55009
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
55010
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
54629
55011
  note: data.data.note,
54630
55012
  scheduledAt: data.data.scheduledAt,
54631
55013
  pendingAt: data.data.pendingAt,
@@ -54660,12 +55042,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54660
55042
  originalPriceOpen: data.originalPriceOpen,
54661
55043
  totalEntries: data.totalEntries,
54662
55044
  totalPartials: data.totalPartials,
54663
- pnl: data.pnl,
55045
+ pnl: data.signal.pnl,
55046
+ maxDrawdown: data.signal.maxDrawdown,
55047
+ peakProfit: data.signal.peakProfit,
54664
55048
  pnlPercentage: data.pnl.pnlPercentage,
54665
55049
  pnlPriceOpen: data.pnl.priceOpen,
54666
55050
  pnlPriceClose: data.pnl.priceClose,
54667
55051
  pnlCost: data.pnl.pnlCost,
54668
55052
  pnlEntries: data.pnl.pnlEntries,
55053
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55054
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55055
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55056
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55057
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55058
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55059
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55060
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55061
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55062
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54669
55063
  scheduledAt: data.scheduledAt,
54670
55064
  pendingAt: data.pendingAt,
54671
55065
  note: data.note,
@@ -54693,12 +55087,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54693
55087
  originalPriceOpen: data.originalPriceOpen,
54694
55088
  totalEntries: data.totalEntries,
54695
55089
  totalPartials: data.totalPartials,
54696
- pnl: data.pnl,
55090
+ pnl: data.signal.pnl,
55091
+ maxDrawdown: data.signal.maxDrawdown,
55092
+ peakProfit: data.signal.peakProfit,
54697
55093
  pnlPercentage: data.pnl.pnlPercentage,
54698
55094
  pnlPriceOpen: data.pnl.priceOpen,
54699
55095
  pnlPriceClose: data.pnl.priceClose,
54700
55096
  pnlCost: data.pnl.pnlCost,
54701
55097
  pnlEntries: data.pnl.pnlEntries,
55098
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55099
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55100
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55101
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55102
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55103
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55104
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55105
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55106
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55107
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54702
55108
  scheduledAt: data.scheduledAt,
54703
55109
  pendingAt: data.pendingAt,
54704
55110
  note: data.note,
@@ -54725,12 +55131,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54725
55131
  originalPriceOpen: data.originalPriceOpen,
54726
55132
  totalEntries: data.totalEntries,
54727
55133
  totalPartials: data.totalPartials,
54728
- pnl: data.pnl,
55134
+ pnl: data.signal.pnl,
55135
+ maxDrawdown: data.signal.maxDrawdown,
55136
+ peakProfit: data.signal.peakProfit,
54729
55137
  pnlPercentage: data.pnl.pnlPercentage,
54730
55138
  pnlPriceOpen: data.pnl.priceOpen,
54731
55139
  pnlPriceClose: data.pnl.priceClose,
54732
55140
  pnlCost: data.pnl.pnlCost,
54733
55141
  pnlEntries: data.pnl.pnlEntries,
55142
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55143
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55144
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55145
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55146
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55147
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55148
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55149
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55150
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55151
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54734
55152
  scheduledAt: data.scheduledAt,
54735
55153
  pendingAt: data.pendingAt,
54736
55154
  note: data.note,
@@ -54758,12 +55176,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54758
55176
  originalPriceOpen: data.originalPriceOpen,
54759
55177
  totalEntries: data.totalEntries,
54760
55178
  totalPartials: data.totalPartials,
54761
- pnl: data.pnl,
55179
+ pnl: data.signal.pnl,
55180
+ maxDrawdown: data.signal.maxDrawdown,
55181
+ peakProfit: data.signal.peakProfit,
54762
55182
  pnlPercentage: data.pnl.pnlPercentage,
54763
55183
  pnlPriceOpen: data.pnl.priceOpen,
54764
55184
  pnlPriceClose: data.pnl.priceClose,
54765
55185
  pnlCost: data.pnl.pnlCost,
54766
55186
  pnlEntries: data.pnl.pnlEntries,
55187
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55188
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55189
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55190
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55191
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55192
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55193
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55194
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55195
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55196
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54767
55197
  scheduledAt: data.scheduledAt,
54768
55198
  pendingAt: data.pendingAt,
54769
55199
  note: data.note,
@@ -54791,12 +55221,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54791
55221
  originalPriceOpen: data.originalPriceOpen,
54792
55222
  totalEntries: data.totalEntries,
54793
55223
  totalPartials: data.totalPartials,
54794
- pnl: data.pnl,
55224
+ pnl: data.signal.pnl,
55225
+ maxDrawdown: data.signal.maxDrawdown,
55226
+ peakProfit: data.signal.peakProfit,
54795
55227
  pnlPercentage: data.pnl.pnlPercentage,
54796
55228
  pnlPriceOpen: data.pnl.priceOpen,
54797
55229
  pnlPriceClose: data.pnl.priceClose,
54798
55230
  pnlCost: data.pnl.pnlCost,
54799
55231
  pnlEntries: data.pnl.pnlEntries,
55232
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55233
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55234
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55235
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55236
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55237
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55238
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55239
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55240
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55241
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54800
55242
  scheduledAt: data.scheduledAt,
54801
55243
  pendingAt: data.pendingAt,
54802
55244
  note: data.note,
@@ -54824,12 +55266,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54824
55266
  originalPriceOpen: data.originalPriceOpen,
54825
55267
  totalEntries: data.totalEntries,
54826
55268
  totalPartials: data.totalPartials,
54827
- pnl: data.pnl,
55269
+ pnl: data.signal.pnl,
55270
+ maxDrawdown: data.signal.maxDrawdown,
55271
+ peakProfit: data.signal.peakProfit,
54828
55272
  pnlPercentage: data.pnl.pnlPercentage,
54829
55273
  pnlPriceOpen: data.pnl.priceOpen,
54830
55274
  pnlPriceClose: data.pnl.priceClose,
54831
55275
  pnlCost: data.pnl.pnlCost,
54832
55276
  pnlEntries: data.pnl.pnlEntries,
55277
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55278
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55279
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55280
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55281
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55282
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55283
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55284
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55285
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55286
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54833
55287
  scheduledAt: data.scheduledAt,
54834
55288
  pendingAt: data.pendingAt,
54835
55289
  note: data.note,
@@ -54858,12 +55312,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54858
55312
  originalPriceTakeProfit: data.originalPriceTakeProfit,
54859
55313
  originalPriceStopLoss: data.originalPriceStopLoss,
54860
55314
  originalPriceOpen: data.originalPriceOpen,
54861
- pnl: data.pnl,
55315
+ pnl: data.signal.pnl,
55316
+ maxDrawdown: data.signal.maxDrawdown,
55317
+ peakProfit: data.signal.peakProfit,
54862
55318
  pnlPercentage: data.pnl.pnlPercentage,
54863
55319
  pnlPriceOpen: data.pnl.priceOpen,
54864
55320
  pnlPriceClose: data.pnl.priceClose,
54865
55321
  pnlCost: data.pnl.pnlCost,
54866
55322
  pnlEntries: data.pnl.pnlEntries,
55323
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55324
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55325
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55326
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55327
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55328
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55329
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55330
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55331
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55332
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54867
55333
  scheduledAt: data.scheduledAt,
54868
55334
  pendingAt: data.pendingAt,
54869
55335
  note: data.note,
@@ -54884,12 +55350,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54884
55350
  totalEntries: data.totalEntries,
54885
55351
  totalPartials: data.totalPartials,
54886
55352
  originalPriceOpen: data.originalPriceOpen,
54887
- pnl: data.pnl,
55353
+ pnl: data.signal.pnl,
55354
+ maxDrawdown: data.signal.maxDrawdown,
55355
+ peakProfit: data.signal.peakProfit,
54888
55356
  pnlPercentage: data.pnl.pnlPercentage,
54889
55357
  pnlPriceOpen: data.pnl.priceOpen,
54890
55358
  pnlPriceClose: data.pnl.priceClose,
54891
55359
  pnlCost: data.pnl.pnlCost,
54892
55360
  pnlEntries: data.pnl.pnlEntries,
55361
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55362
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55363
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55364
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55365
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55366
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55367
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55368
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55369
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55370
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54893
55371
  note: data.note,
54894
55372
  createdAt: data.timestamp,
54895
55373
  };
@@ -54908,12 +55386,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
54908
55386
  totalEntries: data.totalEntries,
54909
55387
  totalPartials: data.totalPartials,
54910
55388
  originalPriceOpen: data.originalPriceOpen,
54911
- pnl: data.pnl,
55389
+ pnl: data.signal.pnl,
55390
+ maxDrawdown: data.signal.maxDrawdown,
55391
+ peakProfit: data.signal.peakProfit,
54912
55392
  pnlPercentage: data.pnl.pnlPercentage,
54913
55393
  pnlPriceOpen: data.pnl.priceOpen,
54914
55394
  pnlPriceClose: data.pnl.priceClose,
54915
55395
  pnlCost: data.pnl.pnlCost,
54916
55396
  pnlEntries: data.pnl.pnlEntries,
55397
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55398
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55399
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55400
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55401
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55402
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55403
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55404
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55405
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55406
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54917
55407
  note: data.note,
54918
55408
  createdAt: data.timestamp,
54919
55409
  };
@@ -54938,12 +55428,24 @@ const CREATE_SIGNAL_SYNC_NOTIFICATION_FN = (data) => {
54938
55428
  exchangeName: data.exchangeName,
54939
55429
  signalId: data.signalId,
54940
55430
  currentPrice: data.currentPrice,
54941
- pnl: data.pnl,
55431
+ pnl: data.signal.pnl,
55432
+ maxDrawdown: data.signal.maxDrawdown,
55433
+ peakProfit: data.signal.peakProfit,
54942
55434
  pnlPercentage: data.pnl.pnlPercentage,
54943
55435
  pnlPriceOpen: data.pnl.priceOpen,
54944
55436
  pnlPriceClose: data.pnl.priceClose,
54945
55437
  pnlCost: data.pnl.pnlCost,
54946
55438
  pnlEntries: data.pnl.pnlEntries,
55439
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55440
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55441
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55442
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55443
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55444
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55445
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55446
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55447
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55448
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54947
55449
  cost: data.cost,
54948
55450
  position: data.position,
54949
55451
  priceOpen: data.priceOpen,
@@ -54971,12 +55473,24 @@ const CREATE_SIGNAL_SYNC_NOTIFICATION_FN = (data) => {
54971
55473
  exchangeName: data.exchangeName,
54972
55474
  signalId: data.signalId,
54973
55475
  currentPrice: data.currentPrice,
54974
- pnl: data.pnl,
55476
+ pnl: data.signal.pnl,
55477
+ maxDrawdown: data.signal.maxDrawdown,
55478
+ peakProfit: data.signal.peakProfit,
54975
55479
  pnlPercentage: data.pnl.pnlPercentage,
54976
55480
  pnlPriceOpen: data.pnl.priceOpen,
54977
55481
  pnlPriceClose: data.pnl.priceClose,
54978
55482
  pnlCost: data.pnl.pnlCost,
54979
55483
  pnlEntries: data.pnl.pnlEntries,
55484
+ peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
55485
+ peakProfitPriceClose: data.signal.peakProfit.priceClose,
55486
+ peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
55487
+ peakProfitCost: data.signal.peakProfit.pnlCost,
55488
+ peakProfitEntries: data.signal.peakProfit.pnlEntries,
55489
+ maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
55490
+ maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
55491
+ maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
55492
+ maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
55493
+ maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
54980
55494
  position: data.position,
54981
55495
  priceOpen: data.priceOpen,
54982
55496
  priceTakeProfit: data.priceTakeProfit,
@@ -55082,11 +55596,23 @@ const CREATE_SIGNAL_INFO_NOTIFICATION_FN = (data) => ({
55082
55596
  totalEntries: data.data.totalEntries,
55083
55597
  totalPartials: data.data.totalPartials,
55084
55598
  pnl: data.data.pnl,
55599
+ maxDrawdown: data.data.maxDrawdown,
55600
+ peakProfit: data.data.peakProfit,
55085
55601
  pnlPercentage: data.data.pnl.pnlPercentage,
55086
55602
  pnlPriceOpen: data.data.pnl.priceOpen,
55087
55603
  pnlPriceClose: data.data.pnl.priceClose,
55088
55604
  pnlCost: data.data.pnl.pnlCost,
55089
55605
  pnlEntries: data.data.pnl.pnlEntries,
55606
+ peakProfitPriceOpen: data.data.peakProfit.priceOpen,
55607
+ peakProfitPriceClose: data.data.peakProfit.priceClose,
55608
+ peakProfitPercentage: data.data.peakProfit.pnlPercentage,
55609
+ peakProfitCost: data.data.peakProfit.pnlCost,
55610
+ peakProfitEntries: data.data.peakProfit.pnlEntries,
55611
+ maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
55612
+ maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
55613
+ maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
55614
+ maxDrawdownCost: data.data.maxDrawdown.pnlCost,
55615
+ maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
55090
55616
  note: data.note,
55091
55617
  notificationId: data.notificationId,
55092
55618
  scheduledAt: data.data.scheduledAt,