backtest-kit 7.1.0 → 7.3.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/README.md +47 -2
- package/build/index.cjs +736 -202
- package/build/index.mjs +736 -202
- package/package.json +2 -2
- package/types.d.ts +591 -83
package/build/index.cjs
CHANGED
|
@@ -4770,8 +4770,7 @@ const TIMEOUT_SYMBOL = Symbol('timeout');
|
|
|
4770
4770
|
* The framework will retry on the next tick.
|
|
4771
4771
|
*/
|
|
4772
4772
|
const CALL_SIGNAL_SYNC_OPEN_FN = functoolsKit.trycatch(async (timestamp, currentPrice, pendingSignal, self) => {
|
|
4773
|
-
const publicSignal = TO_PUBLIC_SIGNAL(pendingSignal, currentPrice);
|
|
4774
|
-
const pnl = toProfitLossDto(pendingSignal, currentPrice);
|
|
4773
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", pendingSignal, currentPrice);
|
|
4775
4774
|
return await self.params.onSignalSync({
|
|
4776
4775
|
action: "signal-open",
|
|
4777
4776
|
symbol: self.params.execution.context.symbol,
|
|
@@ -4782,10 +4781,12 @@ const CALL_SIGNAL_SYNC_OPEN_FN = functoolsKit.trycatch(async (timestamp, current
|
|
|
4782
4781
|
signalId: pendingSignal.id,
|
|
4783
4782
|
timestamp,
|
|
4784
4783
|
signal: publicSignal,
|
|
4784
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
4785
|
+
peakProfit: publicSignal.peakProfit,
|
|
4785
4786
|
cost: pendingSignal.cost,
|
|
4786
4787
|
currentPrice,
|
|
4787
4788
|
position: publicSignal.position,
|
|
4788
|
-
pnl,
|
|
4789
|
+
pnl: publicSignal.pnl,
|
|
4789
4790
|
priceOpen: publicSignal.priceOpen,
|
|
4790
4791
|
priceTakeProfit: publicSignal.priceTakeProfit,
|
|
4791
4792
|
priceStopLoss: publicSignal.priceStopLoss,
|
|
@@ -4809,8 +4810,7 @@ const CALL_SIGNAL_SYNC_OPEN_FN = functoolsKit.trycatch(async (timestamp, current
|
|
|
4809
4810
|
* strategy state is NOT mutated. The framework will retry on the next tick.
|
|
4810
4811
|
*/
|
|
4811
4812
|
const CALL_SIGNAL_SYNC_CLOSE_FN = functoolsKit.trycatch(async (timestamp, currentPrice, closeReason, signal, self) => {
|
|
4812
|
-
const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
4813
|
-
const pnl = toProfitLossDto(signal, currentPrice);
|
|
4813
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
4814
4814
|
return await self.params.onSignalSync({
|
|
4815
4815
|
action: "signal-close",
|
|
4816
4816
|
symbol: self.params.execution.context.symbol,
|
|
@@ -4821,8 +4821,10 @@ const CALL_SIGNAL_SYNC_CLOSE_FN = functoolsKit.trycatch(async (timestamp, curren
|
|
|
4821
4821
|
signalId: signal.id,
|
|
4822
4822
|
timestamp,
|
|
4823
4823
|
signal: publicSignal,
|
|
4824
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
4825
|
+
peakProfit: publicSignal.peakProfit,
|
|
4824
4826
|
currentPrice,
|
|
4825
|
-
pnl,
|
|
4827
|
+
pnl: publicSignal.pnl,
|
|
4826
4828
|
position: publicSignal.position,
|
|
4827
4829
|
priceOpen: publicSignal.priceOpen,
|
|
4828
4830
|
priceTakeProfit: publicSignal.priceTakeProfit,
|
|
@@ -4883,10 +4885,9 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
4883
4885
|
if (!self._pendingSignal) {
|
|
4884
4886
|
return;
|
|
4885
4887
|
}
|
|
4886
|
-
// Get public signal data for commit events (contains effective and original SL/TP)
|
|
4887
|
-
const publicSignal = TO_PUBLIC_SIGNAL(self._pendingSignal, currentPrice);
|
|
4888
4888
|
for (const commit of queue) {
|
|
4889
4889
|
if (commit.action === "partial-profit") {
|
|
4890
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
|
|
4890
4891
|
await CALL_COMMIT_FN(self, {
|
|
4891
4892
|
action: "partial-profit",
|
|
4892
4893
|
symbol: commit.symbol,
|
|
@@ -4896,7 +4897,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
4896
4897
|
backtest: commit.backtest,
|
|
4897
4898
|
percentToClose: commit.percentToClose,
|
|
4898
4899
|
currentPrice: commit.currentPrice,
|
|
4899
|
-
pnl:
|
|
4900
|
+
pnl: publicSignal.pnl,
|
|
4901
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
4902
|
+
peakProfit: publicSignal.peakProfit,
|
|
4903
|
+
signal: publicSignal,
|
|
4900
4904
|
timestamp,
|
|
4901
4905
|
totalEntries: publicSignal.totalEntries,
|
|
4902
4906
|
totalPartials: publicSignal.totalPartials,
|
|
@@ -4915,6 +4919,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
4915
4919
|
continue;
|
|
4916
4920
|
}
|
|
4917
4921
|
if (commit.action === "partial-loss") {
|
|
4922
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
|
|
4918
4923
|
await CALL_COMMIT_FN(self, {
|
|
4919
4924
|
action: "partial-loss",
|
|
4920
4925
|
symbol: commit.symbol,
|
|
@@ -4924,7 +4929,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
4924
4929
|
backtest: commit.backtest,
|
|
4925
4930
|
percentToClose: commit.percentToClose,
|
|
4926
4931
|
currentPrice: commit.currentPrice,
|
|
4927
|
-
pnl:
|
|
4932
|
+
pnl: publicSignal.pnl,
|
|
4933
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
4934
|
+
peakProfit: publicSignal.peakProfit,
|
|
4935
|
+
signal: publicSignal,
|
|
4928
4936
|
timestamp,
|
|
4929
4937
|
totalEntries: publicSignal.totalEntries,
|
|
4930
4938
|
totalPartials: publicSignal.totalPartials,
|
|
@@ -4943,6 +4951,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
4943
4951
|
continue;
|
|
4944
4952
|
}
|
|
4945
4953
|
if (commit.action === "breakeven") {
|
|
4954
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
|
|
4946
4955
|
await CALL_COMMIT_FN(self, {
|
|
4947
4956
|
action: "breakeven",
|
|
4948
4957
|
symbol: commit.symbol,
|
|
@@ -4951,7 +4960,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
4951
4960
|
frameName: self.params.frameName,
|
|
4952
4961
|
backtest: commit.backtest,
|
|
4953
4962
|
currentPrice: commit.currentPrice,
|
|
4954
|
-
pnl:
|
|
4963
|
+
pnl: publicSignal.pnl,
|
|
4964
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
4965
|
+
peakProfit: publicSignal.peakProfit,
|
|
4966
|
+
signal: publicSignal,
|
|
4955
4967
|
timestamp,
|
|
4956
4968
|
totalEntries: publicSignal.totalEntries,
|
|
4957
4969
|
totalPartials: publicSignal.totalPartials,
|
|
@@ -4970,6 +4982,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
4970
4982
|
continue;
|
|
4971
4983
|
}
|
|
4972
4984
|
if (commit.action === "trailing-stop") {
|
|
4985
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
|
|
4973
4986
|
await CALL_COMMIT_FN(self, {
|
|
4974
4987
|
action: "trailing-stop",
|
|
4975
4988
|
symbol: commit.symbol,
|
|
@@ -4979,7 +4992,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
4979
4992
|
backtest: commit.backtest,
|
|
4980
4993
|
percentShift: commit.percentShift,
|
|
4981
4994
|
currentPrice: commit.currentPrice,
|
|
4982
|
-
pnl:
|
|
4995
|
+
pnl: publicSignal.pnl,
|
|
4996
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
4997
|
+
peakProfit: publicSignal.peakProfit,
|
|
4998
|
+
signal: publicSignal,
|
|
4983
4999
|
timestamp,
|
|
4984
5000
|
totalEntries: publicSignal.totalEntries,
|
|
4985
5001
|
totalPartials: publicSignal.totalPartials,
|
|
@@ -4998,6 +5014,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
4998
5014
|
continue;
|
|
4999
5015
|
}
|
|
5000
5016
|
if (commit.action === "trailing-take") {
|
|
5017
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
|
|
5001
5018
|
await CALL_COMMIT_FN(self, {
|
|
5002
5019
|
action: "trailing-take",
|
|
5003
5020
|
symbol: commit.symbol,
|
|
@@ -5007,7 +5024,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
5007
5024
|
backtest: commit.backtest,
|
|
5008
5025
|
percentShift: commit.percentShift,
|
|
5009
5026
|
currentPrice: commit.currentPrice,
|
|
5010
|
-
pnl:
|
|
5027
|
+
pnl: publicSignal.pnl,
|
|
5028
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
5029
|
+
peakProfit: publicSignal.peakProfit,
|
|
5030
|
+
signal: publicSignal,
|
|
5011
5031
|
timestamp,
|
|
5012
5032
|
totalEntries: publicSignal.totalEntries,
|
|
5013
5033
|
totalPartials: publicSignal.totalPartials,
|
|
@@ -5026,6 +5046,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
5026
5046
|
continue;
|
|
5027
5047
|
}
|
|
5028
5048
|
if (commit.action === "average-buy") {
|
|
5049
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", self._pendingSignal, commit.currentPrice);
|
|
5029
5050
|
const effectivePriceOpen = getEffectivePriceOpen(self._pendingSignal);
|
|
5030
5051
|
await CALL_COMMIT_FN(self, {
|
|
5031
5052
|
action: "average-buy",
|
|
@@ -5037,7 +5058,10 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
5037
5058
|
currentPrice: commit.currentPrice,
|
|
5038
5059
|
cost: commit.cost,
|
|
5039
5060
|
effectivePriceOpen,
|
|
5040
|
-
pnl:
|
|
5061
|
+
pnl: publicSignal.pnl,
|
|
5062
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
5063
|
+
peakProfit: publicSignal.peakProfit,
|
|
5064
|
+
signal: publicSignal,
|
|
5041
5065
|
timestamp,
|
|
5042
5066
|
totalEntries: publicSignal.totalEntries,
|
|
5043
5067
|
totalPartials: publicSignal.totalPartials,
|
|
@@ -5057,6 +5081,8 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
5057
5081
|
}
|
|
5058
5082
|
}
|
|
5059
5083
|
};
|
|
5084
|
+
/** Zero PNL constant for scheduled signals (which don't have priceOpen or PNL yet) */
|
|
5085
|
+
const ZERO_PNL$1 = { pnlPercentage: 0, priceOpen: 0, priceClose: 0, pnlCost: 0, pnlEntries: 0 };
|
|
5060
5086
|
/**
|
|
5061
5087
|
* Converts internal signal to public API format.
|
|
5062
5088
|
*
|
|
@@ -5104,7 +5130,7 @@ const PROCESS_COMMIT_QUEUE_FN = async (self, currentPrice, timestamp) => {
|
|
|
5104
5130
|
* // publicSignal._trailingPriceTakeProfit = undefined (hidden from external API)
|
|
5105
5131
|
* ```
|
|
5106
5132
|
*/
|
|
5107
|
-
const TO_PUBLIC_SIGNAL = (signal, currentPrice) => {
|
|
5133
|
+
const TO_PUBLIC_SIGNAL = (type, signal, currentPrice) => {
|
|
5108
5134
|
const hasTrailingSL = "_trailingPriceStopLoss" in signal && signal._trailingPriceStopLoss !== undefined;
|
|
5109
5135
|
const hasTrailingTP = "_trailingPriceTakeProfit" in signal && signal._trailingPriceTakeProfit !== undefined;
|
|
5110
5136
|
const partialExecuted = "_partial" in signal
|
|
@@ -5112,11 +5138,14 @@ const TO_PUBLIC_SIGNAL = (signal, currentPrice) => {
|
|
|
5112
5138
|
: 0;
|
|
5113
5139
|
const totalEntries = ("_entry" in signal && Array.isArray(signal._entry))
|
|
5114
5140
|
? signal._entry.length
|
|
5115
|
-
: 1;
|
|
5141
|
+
: type === "scheduled" ? 0 : 1;
|
|
5116
5142
|
const totalPartials = ("_partial" in signal && Array.isArray(signal._partial))
|
|
5117
5143
|
? signal._partial.length
|
|
5118
5144
|
: 0;
|
|
5119
|
-
const
|
|
5145
|
+
const pnl = type === "scheduled" ? ZERO_PNL$1 : toProfitLossDto(signal, currentPrice);
|
|
5146
|
+
const maxDrawdown = type === "scheduled" ? ZERO_PNL$1 : ("_fall" in signal ? !!signal["_fall"] ? ({ ...signal._fall }) : ZERO_PNL$1 : ZERO_PNL$1);
|
|
5147
|
+
const peakProfit = type === "scheduled" ? ZERO_PNL$1 : ("_peak" in signal ? signal["_peak"] ? ({ ...signal._peak }) : ZERO_PNL$1 : ZERO_PNL$1);
|
|
5148
|
+
const effectivePriceOpen = type === "scheduled" ? signal.priceOpen : "_entry" in signal ? signal["_entry"] ? getEffectivePriceOpen(signal) : signal.priceOpen : signal.priceOpen;
|
|
5120
5149
|
return {
|
|
5121
5150
|
...structuredClone(signal),
|
|
5122
5151
|
priceOpen: effectivePriceOpen,
|
|
@@ -5125,10 +5154,12 @@ const TO_PUBLIC_SIGNAL = (signal, currentPrice) => {
|
|
|
5125
5154
|
originalPriceOpen: signal.priceOpen,
|
|
5126
5155
|
originalPriceStopLoss: signal.priceStopLoss,
|
|
5127
5156
|
originalPriceTakeProfit: signal.priceTakeProfit,
|
|
5157
|
+
maxDrawdown,
|
|
5158
|
+
peakProfit,
|
|
5128
5159
|
partialExecuted,
|
|
5129
5160
|
totalEntries,
|
|
5130
5161
|
totalPartials,
|
|
5131
|
-
pnl
|
|
5162
|
+
pnl,
|
|
5132
5163
|
};
|
|
5133
5164
|
};
|
|
5134
5165
|
const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
|
|
@@ -5193,8 +5224,8 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
|
|
|
5193
5224
|
timestamp: currentTime,
|
|
5194
5225
|
_isScheduled: false,
|
|
5195
5226
|
_entry: [{ price: signal.priceOpen, cost: signal.cost ?? GLOBAL_CONFIG.CC_POSITION_ENTRY_COST, timestamp: currentTime }],
|
|
5196
|
-
_peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
|
|
5197
|
-
_fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
|
|
5227
|
+
_peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
|
|
5228
|
+
_fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
|
|
5198
5229
|
};
|
|
5199
5230
|
// Валидируем сигнал перед возвратом
|
|
5200
5231
|
validatePendingSignal(signalRow, currentPrice);
|
|
@@ -5219,8 +5250,8 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
|
|
|
5219
5250
|
timestamp: currentTime,
|
|
5220
5251
|
_isScheduled: true,
|
|
5221
5252
|
_entry: [{ price: signal.priceOpen, cost: signal.cost ?? GLOBAL_CONFIG.CC_POSITION_ENTRY_COST, timestamp: currentTime }],
|
|
5222
|
-
_peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
|
|
5223
|
-
_fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
|
|
5253
|
+
_peak: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
|
|
5254
|
+
_fall: { price: signal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
|
|
5224
5255
|
};
|
|
5225
5256
|
// Валидируем сигнал перед возвратом
|
|
5226
5257
|
validateScheduledSignal(scheduledSignalRow, currentPrice);
|
|
@@ -5242,8 +5273,8 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
|
|
|
5242
5273
|
timestamp: currentTime,
|
|
5243
5274
|
_isScheduled: false,
|
|
5244
5275
|
_entry: [{ price: currentPrice, cost: signal.cost ?? GLOBAL_CONFIG.CC_POSITION_ENTRY_COST, timestamp: currentTime }],
|
|
5245
|
-
_peak: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
|
|
5246
|
-
_fall: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
|
|
5276
|
+
_peak: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
|
|
5277
|
+
_fall: { price: currentPrice, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
|
|
5247
5278
|
};
|
|
5248
5279
|
// Валидируем сигнал перед возвратом
|
|
5249
5280
|
validatePendingSignal(signalRow, currentPrice);
|
|
@@ -5847,7 +5878,7 @@ const CHECK_SCHEDULED_SIGNAL_TIMEOUT_FN = async (self, scheduled, currentPrice)
|
|
|
5847
5878
|
await CALL_CANCEL_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, currentPrice, currentTime, self.params.execution.context.backtest);
|
|
5848
5879
|
const result = {
|
|
5849
5880
|
action: "cancelled",
|
|
5850
|
-
signal: TO_PUBLIC_SIGNAL(scheduled, currentPrice),
|
|
5881
|
+
signal: TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice),
|
|
5851
5882
|
currentPrice: currentPrice,
|
|
5852
5883
|
closeTimestamp: currentTime,
|
|
5853
5884
|
strategyName: self.params.method.context.strategyName,
|
|
@@ -5903,7 +5934,7 @@ const CANCEL_SCHEDULED_SIGNAL_BY_STOPLOSS_FN = async (self, scheduled, currentPr
|
|
|
5903
5934
|
await CALL_CANCEL_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, currentPrice, currentTime, self.params.execution.context.backtest);
|
|
5904
5935
|
const result = {
|
|
5905
5936
|
action: "cancelled",
|
|
5906
|
-
signal: TO_PUBLIC_SIGNAL(scheduled, currentPrice),
|
|
5937
|
+
signal: TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice),
|
|
5907
5938
|
currentPrice: currentPrice,
|
|
5908
5939
|
closeTimestamp: currentTime,
|
|
5909
5940
|
strategyName: self.params.method.context.strategyName,
|
|
@@ -5954,8 +5985,8 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
|
|
|
5954
5985
|
...scheduled,
|
|
5955
5986
|
pendingAt: activationTime,
|
|
5956
5987
|
_isScheduled: false,
|
|
5957
|
-
_peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
|
|
5958
|
-
_fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
|
|
5988
|
+
_peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
|
|
5989
|
+
_fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
|
|
5959
5990
|
};
|
|
5960
5991
|
// Sync open: if external system rejects — cancel scheduled signal instead of opening
|
|
5961
5992
|
const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(activationTime, activatedSignal.priceOpen, activatedSignal, self);
|
|
@@ -5965,6 +5996,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
|
|
|
5965
5996
|
signalId: scheduled.id,
|
|
5966
5997
|
});
|
|
5967
5998
|
await self.setScheduledSignal(null);
|
|
5999
|
+
const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, scheduled.priceOpen);
|
|
5968
6000
|
await CALL_COMMIT_FN(self, {
|
|
5969
6001
|
action: "cancel-scheduled",
|
|
5970
6002
|
symbol: self.params.execution.context.symbol,
|
|
@@ -5977,7 +6009,10 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
|
|
|
5977
6009
|
totalEntries: scheduled._entry?.length ?? 1,
|
|
5978
6010
|
totalPartials: scheduled._partial?.length ?? 0,
|
|
5979
6011
|
originalPriceOpen: scheduled.priceOpen,
|
|
5980
|
-
pnl:
|
|
6012
|
+
pnl: publicSignal.pnl,
|
|
6013
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
6014
|
+
peakProfit: publicSignal.peakProfit,
|
|
6015
|
+
signal: publicSignal,
|
|
5981
6016
|
note: scheduled.note,
|
|
5982
6017
|
});
|
|
5983
6018
|
return null;
|
|
@@ -5988,7 +6023,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
|
|
|
5988
6023
|
await CALL_OPEN_CALLBACKS_FN(self, self.params.execution.context.symbol, self._pendingSignal, self._pendingSignal.priceOpen, activationTime, self.params.execution.context.backtest);
|
|
5989
6024
|
const result = {
|
|
5990
6025
|
action: "opened",
|
|
5991
|
-
signal: TO_PUBLIC_SIGNAL(self._pendingSignal, self._pendingSignal.priceOpen),
|
|
6026
|
+
signal: TO_PUBLIC_SIGNAL("pending", self._pendingSignal, self._pendingSignal.priceOpen),
|
|
5992
6027
|
strategyName: self.params.method.context.strategyName,
|
|
5993
6028
|
exchangeName: self.params.method.context.exchangeName,
|
|
5994
6029
|
frameName: self.params.method.context.frameName,
|
|
@@ -6002,7 +6037,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
|
|
|
6002
6037
|
};
|
|
6003
6038
|
const CALL_SCHEDULE_PING_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, scheduled, timestamp, backtest, currentPrice) => {
|
|
6004
6039
|
await ExecutionContextService.runInContext(async () => {
|
|
6005
|
-
const publicSignal = TO_PUBLIC_SIGNAL(scheduled, currentPrice);
|
|
6040
|
+
const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice);
|
|
6006
6041
|
// Call system onSchedulePing callback first (emits to pingSubject)
|
|
6007
6042
|
await self.params.onSchedulePing(self.params.execution.context.symbol, self.params.method.context.strategyName, self.params.method.context.exchangeName, publicSignal, currentPrice, self.params.execution.context.backtest, timestamp);
|
|
6008
6043
|
// Call user onSchedulePing callback only if signal is still active (not cancelled, not activated)
|
|
@@ -6028,7 +6063,7 @@ const CALL_SCHEDULE_PING_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (s
|
|
|
6028
6063
|
});
|
|
6029
6064
|
const CALL_ACTIVE_PING_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, pending, timestamp, backtest, currentPrice) => {
|
|
6030
6065
|
await ExecutionContextService.runInContext(async () => {
|
|
6031
|
-
const publicSignal = TO_PUBLIC_SIGNAL(pending, currentPrice);
|
|
6066
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", pending, currentPrice);
|
|
6032
6067
|
// Call system onActivePing callback first (emits to activePingSubject)
|
|
6033
6068
|
await self.params.onActivePing(self.params.execution.context.symbol, self.params.method.context.strategyName, self.params.method.context.exchangeName, publicSignal, currentPrice, self.params.execution.context.backtest, timestamp);
|
|
6034
6069
|
// Call user onActivePing callback only if signal is still active (not closed)
|
|
@@ -6076,7 +6111,7 @@ const CALL_IDLE_PING_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self,
|
|
|
6076
6111
|
const CALL_ACTIVE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
6077
6112
|
await ExecutionContextService.runInContext(async () => {
|
|
6078
6113
|
if (self.params.callbacks?.onActive) {
|
|
6079
|
-
const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6114
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6080
6115
|
await self.params.callbacks.onActive(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
|
|
6081
6116
|
}
|
|
6082
6117
|
}, {
|
|
@@ -6099,7 +6134,7 @@ const CALL_ACTIVE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, sy
|
|
|
6099
6134
|
const CALL_SCHEDULE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
6100
6135
|
await ExecutionContextService.runInContext(async () => {
|
|
6101
6136
|
if (self.params.callbacks?.onSchedule) {
|
|
6102
|
-
const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6137
|
+
const publicSignal = TO_PUBLIC_SIGNAL("scheduled", signal, currentPrice);
|
|
6103
6138
|
await self.params.callbacks.onSchedule(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
|
|
6104
6139
|
}
|
|
6105
6140
|
}, {
|
|
@@ -6122,7 +6157,7 @@ const CALL_SCHEDULE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self,
|
|
|
6122
6157
|
const CALL_CANCEL_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
6123
6158
|
await ExecutionContextService.runInContext(async () => {
|
|
6124
6159
|
if (self.params.callbacks?.onCancel) {
|
|
6125
|
-
const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6160
|
+
const publicSignal = TO_PUBLIC_SIGNAL("scheduled", signal, currentPrice);
|
|
6126
6161
|
await self.params.callbacks.onCancel(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
|
|
6127
6162
|
}
|
|
6128
6163
|
}, {
|
|
@@ -6145,7 +6180,7 @@ const CALL_CANCEL_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, sy
|
|
|
6145
6180
|
const CALL_OPEN_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, priceOpen, timestamp, backtest) => {
|
|
6146
6181
|
await ExecutionContextService.runInContext(async () => {
|
|
6147
6182
|
if (self.params.callbacks?.onOpen) {
|
|
6148
|
-
const publicSignal = TO_PUBLIC_SIGNAL(signal, priceOpen);
|
|
6183
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, priceOpen);
|
|
6149
6184
|
await self.params.callbacks.onOpen(self.params.execution.context.symbol, publicSignal, priceOpen, self.params.execution.context.backtest);
|
|
6150
6185
|
}
|
|
6151
6186
|
}, {
|
|
@@ -6168,7 +6203,7 @@ const CALL_OPEN_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symb
|
|
|
6168
6203
|
const CALL_CLOSE_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
6169
6204
|
await ExecutionContextService.runInContext(async () => {
|
|
6170
6205
|
if (self.params.callbacks?.onClose) {
|
|
6171
|
-
const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6206
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6172
6207
|
await self.params.callbacks.onClose(self.params.execution.context.symbol, publicSignal, currentPrice, self.params.execution.context.backtest);
|
|
6173
6208
|
}
|
|
6174
6209
|
}, {
|
|
@@ -6291,7 +6326,7 @@ const CALL_RISK_REMOVE_SIGNAL_FN = functoolsKit.trycatch(beginTime(async (self,
|
|
|
6291
6326
|
});
|
|
6292
6327
|
const CALL_PARTIAL_CLEAR_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
6293
6328
|
await ExecutionContextService.runInContext(async () => {
|
|
6294
|
-
const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6329
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6295
6330
|
await self.params.partial.clear(symbol, publicSignal, currentPrice, backtest);
|
|
6296
6331
|
}, {
|
|
6297
6332
|
when: new Date(timestamp),
|
|
@@ -6313,7 +6348,7 @@ const CALL_PARTIAL_CLEAR_FN = functoolsKit.trycatch(beginTime(async (self, symbo
|
|
|
6313
6348
|
const CALL_RISK_CHECK_SIGNAL_FN = functoolsKit.trycatch(beginTime(async (self, symbol, pendingSignal, currentPrice, timestamp, backtest) => {
|
|
6314
6349
|
return await ExecutionContextService.runInContext(async () => {
|
|
6315
6350
|
return await self.params.risk.checkSignal({
|
|
6316
|
-
currentSignal: TO_PUBLIC_SIGNAL(pendingSignal, currentPrice),
|
|
6351
|
+
currentSignal: TO_PUBLIC_SIGNAL("scheduled", pendingSignal, currentPrice),
|
|
6317
6352
|
symbol: symbol,
|
|
6318
6353
|
strategyName: self.params.method.context.strategyName,
|
|
6319
6354
|
exchangeName: self.params.method.context.exchangeName,
|
|
@@ -6342,7 +6377,7 @@ const CALL_RISK_CHECK_SIGNAL_FN = functoolsKit.trycatch(beginTime(async (self, s
|
|
|
6342
6377
|
});
|
|
6343
6378
|
const CALL_PARTIAL_PROFIT_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, percentTp, timestamp, backtest) => {
|
|
6344
6379
|
await ExecutionContextService.runInContext(async () => {
|
|
6345
|
-
const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6380
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6346
6381
|
await self.params.partial.profit(symbol, publicSignal, currentPrice, percentTp, backtest, new Date(timestamp));
|
|
6347
6382
|
if (self.params.callbacks?.onPartialProfit) {
|
|
6348
6383
|
await self.params.callbacks.onPartialProfit(symbol, publicSignal, currentPrice, percentTp, backtest);
|
|
@@ -6366,7 +6401,7 @@ const CALL_PARTIAL_PROFIT_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (
|
|
|
6366
6401
|
});
|
|
6367
6402
|
const CALL_PARTIAL_LOSS_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, percentSl, timestamp, backtest) => {
|
|
6368
6403
|
await ExecutionContextService.runInContext(async () => {
|
|
6369
|
-
const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6404
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6370
6405
|
await self.params.partial.loss(symbol, publicSignal, currentPrice, percentSl, backtest, new Date(timestamp));
|
|
6371
6406
|
if (self.params.callbacks?.onPartialLoss) {
|
|
6372
6407
|
await self.params.callbacks.onPartialLoss(symbol, publicSignal, currentPrice, percentSl, backtest);
|
|
@@ -6390,7 +6425,7 @@ const CALL_PARTIAL_LOSS_CALLBACKS_FN = functoolsKit.trycatch(beginTime(async (se
|
|
|
6390
6425
|
});
|
|
6391
6426
|
const CALL_BREAKEVEN_CHECK_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
6392
6427
|
await ExecutionContextService.runInContext(async () => {
|
|
6393
|
-
const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6428
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6394
6429
|
const isBreakeven = await self.params.breakeven.check(symbol, publicSignal, currentPrice, backtest, new Date(timestamp));
|
|
6395
6430
|
if (self.params.callbacks?.onBreakeven) {
|
|
6396
6431
|
isBreakeven && await self.params.callbacks.onBreakeven(symbol, publicSignal, currentPrice, backtest);
|
|
@@ -6414,7 +6449,7 @@ const CALL_BREAKEVEN_CHECK_FN = functoolsKit.trycatch(beginTime(async (self, sym
|
|
|
6414
6449
|
});
|
|
6415
6450
|
const CALL_BREAKEVEN_CLEAR_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, currentPrice, timestamp, backtest) => {
|
|
6416
6451
|
await ExecutionContextService.runInContext(async () => {
|
|
6417
|
-
const publicSignal = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6452
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6418
6453
|
await self.params.breakeven.clear(symbol, publicSignal, currentPrice, backtest);
|
|
6419
6454
|
}, {
|
|
6420
6455
|
when: new Date(timestamp),
|
|
@@ -6437,7 +6472,7 @@ const CALL_BACKTEST_SCHEDULE_OPEN_FN = functoolsKit.trycatch(beginTime(async (se
|
|
|
6437
6472
|
await ExecutionContextService.runInContext(async () => {
|
|
6438
6473
|
backtestScheduleOpenSubject.next({
|
|
6439
6474
|
action: "opened",
|
|
6440
|
-
signal: TO_PUBLIC_SIGNAL(signal, signal.priceOpen),
|
|
6475
|
+
signal: TO_PUBLIC_SIGNAL("pending", signal, signal.priceOpen),
|
|
6441
6476
|
strategyName: self.params.method.context.strategyName,
|
|
6442
6477
|
exchangeName: self.params.method.context.exchangeName,
|
|
6443
6478
|
frameName: self.params.method.context.frameName,
|
|
@@ -6466,10 +6501,10 @@ const CALL_BACKTEST_SCHEDULE_OPEN_FN = functoolsKit.trycatch(beginTime(async (se
|
|
|
6466
6501
|
const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice) => {
|
|
6467
6502
|
const currentTime = self.params.execution.context.when.getTime();
|
|
6468
6503
|
await CALL_SCHEDULE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, currentTime, self.params.execution.context.backtest, currentPrice);
|
|
6469
|
-
const
|
|
6504
|
+
const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, currentPrice);
|
|
6470
6505
|
const result = {
|
|
6471
6506
|
action: "waiting",
|
|
6472
|
-
signal:
|
|
6507
|
+
signal: publicSignal,
|
|
6473
6508
|
currentPrice: currentPrice,
|
|
6474
6509
|
strategyName: self.params.method.context.strategyName,
|
|
6475
6510
|
exchangeName: self.params.method.context.exchangeName,
|
|
@@ -6477,7 +6512,7 @@ const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice)
|
|
|
6477
6512
|
symbol: self.params.execution.context.symbol,
|
|
6478
6513
|
percentTp: 0,
|
|
6479
6514
|
percentSl: 0,
|
|
6480
|
-
pnl,
|
|
6515
|
+
pnl: publicSignal.pnl,
|
|
6481
6516
|
backtest: self.params.execution.context.backtest,
|
|
6482
6517
|
createdAt: currentTime,
|
|
6483
6518
|
};
|
|
@@ -6497,7 +6532,7 @@ const OPEN_NEW_SCHEDULED_SIGNAL_FN = async (self, signal) => {
|
|
|
6497
6532
|
await CALL_SCHEDULE_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, currentTime, self.params.execution.context.backtest);
|
|
6498
6533
|
const result = {
|
|
6499
6534
|
action: "scheduled",
|
|
6500
|
-
signal: TO_PUBLIC_SIGNAL(signal, currentPrice),
|
|
6535
|
+
signal: TO_PUBLIC_SIGNAL("scheduled", signal, currentPrice),
|
|
6501
6536
|
strategyName: self.params.method.context.strategyName,
|
|
6502
6537
|
exchangeName: self.params.method.context.exchangeName,
|
|
6503
6538
|
frameName: self.params.method.context.frameName,
|
|
@@ -6527,7 +6562,7 @@ const OPEN_NEW_PENDING_SIGNAL_FN = async (self, signal) => {
|
|
|
6527
6562
|
await CALL_OPEN_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, signal.priceOpen, currentTime, self.params.execution.context.backtest);
|
|
6528
6563
|
const result = {
|
|
6529
6564
|
action: "opened",
|
|
6530
|
-
signal: TO_PUBLIC_SIGNAL(signal, signal.priceOpen),
|
|
6565
|
+
signal: TO_PUBLIC_SIGNAL("pending", signal, signal.priceOpen),
|
|
6531
6566
|
strategyName: self.params.method.context.strategyName,
|
|
6532
6567
|
exchangeName: self.params.method.context.exchangeName,
|
|
6533
6568
|
frameName: self.params.method.context.frameName,
|
|
@@ -6582,13 +6617,13 @@ const CLOSE_PENDING_SIGNAL_FN = async (self, signal, currentPrice, closeReason)
|
|
|
6582
6617
|
});
|
|
6583
6618
|
return null;
|
|
6584
6619
|
}
|
|
6585
|
-
const
|
|
6620
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6586
6621
|
self.params.logger.info(`ClientStrategy signal ${closeReason}`, {
|
|
6587
6622
|
symbol: self.params.execution.context.symbol,
|
|
6588
6623
|
signalId: signal.id,
|
|
6589
6624
|
closeReason,
|
|
6590
6625
|
priceClose: currentPrice,
|
|
6591
|
-
pnlPercentage: pnl.pnlPercentage,
|
|
6626
|
+
pnlPercentage: publicSignal.pnl.pnlPercentage,
|
|
6592
6627
|
});
|
|
6593
6628
|
await CALL_CLOSE_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, currentTime, self.params.execution.context.backtest);
|
|
6594
6629
|
// КРИТИЧНО: Очищаем состояние ClientPartial при закрытии позиции
|
|
@@ -6599,11 +6634,11 @@ const CLOSE_PENDING_SIGNAL_FN = async (self, signal, currentPrice, closeReason)
|
|
|
6599
6634
|
await self.setPendingSignal(null);
|
|
6600
6635
|
const result = {
|
|
6601
6636
|
action: "closed",
|
|
6602
|
-
signal:
|
|
6637
|
+
signal: publicSignal,
|
|
6603
6638
|
currentPrice: currentPrice,
|
|
6604
6639
|
closeReason: closeReason,
|
|
6605
6640
|
closeTimestamp: currentTime,
|
|
6606
|
-
pnl: pnl,
|
|
6641
|
+
pnl: publicSignal.pnl,
|
|
6607
6642
|
strategyName: self.params.method.context.strategyName,
|
|
6608
6643
|
exchangeName: self.params.method.context.exchangeName,
|
|
6609
6644
|
frameName: self.params.method.context.frameName,
|
|
@@ -6618,17 +6653,12 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
|
|
|
6618
6653
|
let percentTp = 0;
|
|
6619
6654
|
let percentSl = 0;
|
|
6620
6655
|
const currentTime = self.params.execution.context.when.getTime();
|
|
6621
|
-
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentTime, self.params.execution.context.backtest, currentPrice);
|
|
6622
6656
|
// Calculate percentage of path to TP/SL for partial fill/loss callbacks
|
|
6623
6657
|
{
|
|
6624
6658
|
const effectivePriceOpen = getEffectivePriceOpen(signal);
|
|
6625
6659
|
if (signal.position === "long") {
|
|
6626
6660
|
// For long: calculate progress towards TP or SL
|
|
6627
6661
|
const currentDistance = currentPrice - effectivePriceOpen;
|
|
6628
|
-
if (currentDistance > 0) {
|
|
6629
|
-
// Check if breakeven should be triggered
|
|
6630
|
-
await CALL_BREAKEVEN_CHECK_FN(self, self.params.execution.context.symbol, signal, currentPrice, currentTime, self.params.execution.context.backtest);
|
|
6631
|
-
}
|
|
6632
6662
|
if (currentDistance > 0) {
|
|
6633
6663
|
// Moving towards TP (use trailing TP if set)
|
|
6634
6664
|
const effectiveTakeProfit = signal._trailingPriceTakeProfit ?? signal.priceTakeProfit;
|
|
@@ -6636,14 +6666,17 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
|
|
|
6636
6666
|
const progressPercent = (currentDistance / tpDistance) * 100;
|
|
6637
6667
|
percentTp = Math.min(progressPercent, 100);
|
|
6638
6668
|
if (currentPrice > signal._peak.price) {
|
|
6639
|
-
const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6640
|
-
signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
|
|
6669
|
+
const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6670
|
+
signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
|
|
6641
6671
|
if (self.params.callbacks?.onWrite) {
|
|
6642
6672
|
self.params.callbacks.onWrite(signal.symbol, signal, backtest);
|
|
6643
6673
|
}
|
|
6644
6674
|
!backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
|
|
6645
|
-
await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
|
|
6675
|
+
await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
|
|
6646
6676
|
}
|
|
6677
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentTime, self.params.execution.context.backtest, currentPrice);
|
|
6678
|
+
// Check if breakeven should be triggered
|
|
6679
|
+
await CALL_BREAKEVEN_CHECK_FN(self, self.params.execution.context.symbol, signal, currentPrice, currentTime, self.params.execution.context.backtest);
|
|
6647
6680
|
await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentTp, currentTime, self.params.execution.context.backtest);
|
|
6648
6681
|
}
|
|
6649
6682
|
else if (currentDistance < 0) {
|
|
@@ -6653,24 +6686,24 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
|
|
|
6653
6686
|
const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
|
|
6654
6687
|
percentSl = Math.min(progressPercent, 100);
|
|
6655
6688
|
if (currentPrice < signal._fall.price) {
|
|
6656
|
-
const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6657
|
-
signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
|
|
6689
|
+
const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6690
|
+
signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
|
|
6658
6691
|
if (self.params.callbacks?.onWrite) {
|
|
6659
6692
|
self.params.callbacks.onWrite(signal.symbol, signal, backtest);
|
|
6660
6693
|
}
|
|
6661
6694
|
!backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
|
|
6662
|
-
await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
|
|
6695
|
+
await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
|
|
6663
6696
|
}
|
|
6697
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentTime, self.params.execution.context.backtest, currentPrice);
|
|
6664
6698
|
await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentSl, currentTime, self.params.execution.context.backtest);
|
|
6665
6699
|
}
|
|
6700
|
+
else {
|
|
6701
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentTime, self.params.execution.context.backtest, currentPrice);
|
|
6702
|
+
}
|
|
6666
6703
|
}
|
|
6667
6704
|
else if (signal.position === "short") {
|
|
6668
6705
|
// For short: calculate progress towards TP or SL
|
|
6669
6706
|
const currentDistance = effectivePriceOpen - currentPrice;
|
|
6670
|
-
if (currentDistance > 0) {
|
|
6671
|
-
// Check if breakeven should be triggered
|
|
6672
|
-
await CALL_BREAKEVEN_CHECK_FN(self, self.params.execution.context.symbol, signal, currentPrice, currentTime, self.params.execution.context.backtest);
|
|
6673
|
-
}
|
|
6674
6707
|
if (currentDistance > 0) {
|
|
6675
6708
|
// Moving towards TP (use trailing TP if set)
|
|
6676
6709
|
const effectiveTakeProfit = signal._trailingPriceTakeProfit ?? signal.priceTakeProfit;
|
|
@@ -6678,39 +6711,46 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
|
|
|
6678
6711
|
const progressPercent = (currentDistance / tpDistance) * 100;
|
|
6679
6712
|
percentTp = Math.min(progressPercent, 100);
|
|
6680
6713
|
if (currentPrice < signal._peak.price) {
|
|
6681
|
-
const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6682
|
-
signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
|
|
6714
|
+
const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6715
|
+
signal._peak = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
|
|
6683
6716
|
if (self.params.callbacks?.onWrite) {
|
|
6684
6717
|
self.params.callbacks.onWrite(signal.symbol, signal, backtest);
|
|
6685
6718
|
}
|
|
6686
6719
|
!backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
|
|
6687
|
-
await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
|
|
6720
|
+
await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
|
|
6688
6721
|
}
|
|
6722
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentTime, self.params.execution.context.backtest, currentPrice);
|
|
6723
|
+
// Check if breakeven should be triggered
|
|
6724
|
+
await CALL_BREAKEVEN_CHECK_FN(self, self.params.execution.context.symbol, signal, currentPrice, currentTime, self.params.execution.context.backtest);
|
|
6689
6725
|
await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentTp, currentTime, self.params.execution.context.backtest);
|
|
6690
6726
|
}
|
|
6691
|
-
if (currentDistance < 0) {
|
|
6727
|
+
else if (currentDistance < 0) {
|
|
6692
6728
|
// Moving towards SL (use trailing SL if set)
|
|
6693
6729
|
const effectiveStopLoss = signal._trailingPriceStopLoss ?? signal.priceStopLoss;
|
|
6694
6730
|
const slDistance = effectiveStopLoss - effectivePriceOpen;
|
|
6695
6731
|
const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
|
|
6696
6732
|
percentSl = Math.min(progressPercent, 100);
|
|
6697
6733
|
if (currentPrice > signal._fall.price) {
|
|
6698
|
-
const { pnl } = TO_PUBLIC_SIGNAL(signal, currentPrice);
|
|
6699
|
-
signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
|
|
6734
|
+
const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6735
|
+
signal._fall = { price: currentPrice, timestamp: currentTime, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceClose: pnl.priceClose, priceOpen: pnl.priceOpen };
|
|
6700
6736
|
if (self.params.callbacks?.onWrite) {
|
|
6701
6737
|
self.params.callbacks.onWrite(signal.symbol, signal, backtest);
|
|
6702
6738
|
}
|
|
6703
6739
|
!backtest && await PersistSignalAdapter.writeSignalData(signal, self.params.execution.context.symbol, self.params.strategyName, self.params.exchangeName);
|
|
6704
|
-
await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, currentPrice), currentPrice, currentTime);
|
|
6740
|
+
await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, currentPrice), currentPrice, currentTime);
|
|
6705
6741
|
}
|
|
6742
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentTime, self.params.execution.context.backtest, currentPrice);
|
|
6706
6743
|
await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentPrice, percentSl, currentTime, self.params.execution.context.backtest);
|
|
6707
6744
|
}
|
|
6745
|
+
else {
|
|
6746
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentTime, self.params.execution.context.backtest, currentPrice);
|
|
6747
|
+
}
|
|
6708
6748
|
}
|
|
6709
6749
|
}
|
|
6710
|
-
const
|
|
6750
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, currentPrice);
|
|
6711
6751
|
const result = {
|
|
6712
6752
|
action: "active",
|
|
6713
|
-
signal:
|
|
6753
|
+
signal: publicSignal,
|
|
6714
6754
|
currentPrice: currentPrice,
|
|
6715
6755
|
strategyName: self.params.method.context.strategyName,
|
|
6716
6756
|
exchangeName: self.params.method.context.exchangeName,
|
|
@@ -6718,7 +6758,7 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice, backt
|
|
|
6718
6758
|
symbol: self.params.execution.context.symbol,
|
|
6719
6759
|
percentTp,
|
|
6720
6760
|
percentSl,
|
|
6721
|
-
pnl,
|
|
6761
|
+
pnl: publicSignal.pnl,
|
|
6722
6762
|
backtest: self.params.execution.context.backtest,
|
|
6723
6763
|
createdAt: currentTime,
|
|
6724
6764
|
_backtestLastTimestamp: currentTime,
|
|
@@ -6754,6 +6794,7 @@ const CANCEL_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, averagePr
|
|
|
6754
6794
|
reason,
|
|
6755
6795
|
});
|
|
6756
6796
|
await self.setScheduledSignal(null);
|
|
6797
|
+
const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, averagePrice);
|
|
6757
6798
|
if (reason === "user") {
|
|
6758
6799
|
await CALL_COMMIT_FN(self, {
|
|
6759
6800
|
action: "cancel-scheduled",
|
|
@@ -6768,14 +6809,17 @@ const CANCEL_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, averagePr
|
|
|
6768
6809
|
totalEntries: scheduled._entry?.length ?? 1,
|
|
6769
6810
|
totalPartials: scheduled._partial?.length ?? 0,
|
|
6770
6811
|
originalPriceOpen: scheduled.priceOpen,
|
|
6771
|
-
pnl:
|
|
6812
|
+
pnl: publicSignal.pnl,
|
|
6813
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
6814
|
+
peakProfit: publicSignal.peakProfit,
|
|
6815
|
+
signal: publicSignal,
|
|
6772
6816
|
note: cancelNote ?? scheduled.note,
|
|
6773
6817
|
});
|
|
6774
6818
|
}
|
|
6775
6819
|
await CALL_CANCEL_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, averagePrice, closeTimestamp, self.params.execution.context.backtest);
|
|
6776
6820
|
const result = {
|
|
6777
6821
|
action: "cancelled",
|
|
6778
|
-
signal:
|
|
6822
|
+
signal: publicSignal,
|
|
6779
6823
|
currentPrice: averagePrice,
|
|
6780
6824
|
closeTimestamp: closeTimestamp,
|
|
6781
6825
|
strategyName: self.params.method.context.strategyName,
|
|
@@ -6824,8 +6868,8 @@ const ACTIVATE_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, activat
|
|
|
6824
6868
|
...scheduled,
|
|
6825
6869
|
pendingAt: activationTime,
|
|
6826
6870
|
_isScheduled: false,
|
|
6827
|
-
_peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
|
|
6828
|
-
_fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0 },
|
|
6871
|
+
_peak: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
|
|
6872
|
+
_fall: { price: scheduled.priceOpen, timestamp: activationTime, pnlPercentage: 0, pnlCost: 0, pnlEntries: 0, priceClose: 0, priceOpen: 0 },
|
|
6829
6873
|
};
|
|
6830
6874
|
// Sync open: if external system rejects — cancel scheduled signal instead of opening
|
|
6831
6875
|
const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(activationTime, activatedSignal.priceOpen, activatedSignal, self);
|
|
@@ -6835,6 +6879,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, activat
|
|
|
6835
6879
|
signalId: scheduled.id,
|
|
6836
6880
|
});
|
|
6837
6881
|
await self.setScheduledSignal(null);
|
|
6882
|
+
const publicSignal = TO_PUBLIC_SIGNAL("scheduled", scheduled, scheduled.priceOpen);
|
|
6838
6883
|
await CALL_COMMIT_FN(self, {
|
|
6839
6884
|
action: "cancel-scheduled",
|
|
6840
6885
|
symbol: self.params.execution.context.symbol,
|
|
@@ -6847,7 +6892,10 @@ const ACTIVATE_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, activat
|
|
|
6847
6892
|
totalEntries: scheduled._entry?.length ?? 1,
|
|
6848
6893
|
totalPartials: scheduled._partial?.length ?? 0,
|
|
6849
6894
|
originalPriceOpen: scheduled.priceOpen,
|
|
6850
|
-
pnl:
|
|
6895
|
+
pnl: publicSignal.pnl,
|
|
6896
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
6897
|
+
peakProfit: publicSignal.peakProfit,
|
|
6898
|
+
signal: publicSignal,
|
|
6851
6899
|
note: scheduled.note,
|
|
6852
6900
|
});
|
|
6853
6901
|
return false;
|
|
@@ -6870,20 +6918,20 @@ const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, c
|
|
|
6870
6918
|
});
|
|
6871
6919
|
return null;
|
|
6872
6920
|
}
|
|
6873
|
-
const
|
|
6921
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
|
|
6874
6922
|
self.params.logger.debug(`ClientStrategy backtest ${closeReason}`, {
|
|
6875
6923
|
symbol: self.params.execution.context.symbol,
|
|
6876
6924
|
signalId: signal.id,
|
|
6877
6925
|
reason: closeReason,
|
|
6878
6926
|
priceClose: averagePrice,
|
|
6879
6927
|
closeTimestamp,
|
|
6880
|
-
pnlPercentage: pnl.pnlPercentage,
|
|
6928
|
+
pnlPercentage: publicSignal.pnl.pnlPercentage,
|
|
6881
6929
|
});
|
|
6882
6930
|
if (closeReason === "stop_loss") {
|
|
6883
|
-
self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (stop_loss), PNL: ${pnl.pnlPercentage.toFixed(2)}%`);
|
|
6931
|
+
self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (stop_loss), PNL: ${publicSignal.pnl.pnlPercentage.toFixed(2)}%`);
|
|
6884
6932
|
}
|
|
6885
|
-
if (closeReason === "time_expired" && pnl.pnlPercentage < 0) {
|
|
6886
|
-
self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (time_expired), PNL: ${pnl.pnlPercentage.toFixed(2)}%`);
|
|
6933
|
+
if (closeReason === "time_expired" && publicSignal.pnl.pnlPercentage < 0) {
|
|
6934
|
+
self.params.logger.warn(`ClientStrategy backtest: Signal closed with loss (time_expired), PNL: ${publicSignal.pnl.pnlPercentage.toFixed(2)}%`);
|
|
6887
6935
|
}
|
|
6888
6936
|
await CALL_CLOSE_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
|
|
6889
6937
|
// КРИТИЧНО: Очищаем состояние ClientPartial при закрытии позиции
|
|
@@ -6894,11 +6942,11 @@ const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, c
|
|
|
6894
6942
|
await self.setPendingSignal(null);
|
|
6895
6943
|
const result = {
|
|
6896
6944
|
action: "closed",
|
|
6897
|
-
signal:
|
|
6945
|
+
signal: publicSignal,
|
|
6898
6946
|
currentPrice: averagePrice,
|
|
6899
6947
|
closeReason: closeReason,
|
|
6900
6948
|
closeTimestamp: closeTimestamp,
|
|
6901
|
-
pnl: pnl,
|
|
6949
|
+
pnl: publicSignal.pnl,
|
|
6902
6950
|
strategyName: self.params.method.context.strategyName,
|
|
6903
6951
|
exchangeName: self.params.method.context.exchangeName,
|
|
6904
6952
|
frameName: self.params.method.context.frameName,
|
|
@@ -6922,6 +6970,7 @@ const CLOSE_USER_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, closedSignal, aver
|
|
|
6922
6970
|
`Retry backtest() with new candle data.`);
|
|
6923
6971
|
}
|
|
6924
6972
|
self._closedSignal = null;
|
|
6973
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", closedSignal, averagePrice);
|
|
6925
6974
|
await CALL_COMMIT_FN(self, {
|
|
6926
6975
|
action: "close-pending",
|
|
6927
6976
|
symbol: self.params.execution.context.symbol,
|
|
@@ -6935,21 +6984,23 @@ const CLOSE_USER_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, closedSignal, aver
|
|
|
6935
6984
|
totalEntries: closedSignal._entry?.length ?? 1,
|
|
6936
6985
|
totalPartials: closedSignal._partial?.length ?? 0,
|
|
6937
6986
|
originalPriceOpen: closedSignal.priceOpen,
|
|
6938
|
-
pnl:
|
|
6987
|
+
pnl: publicSignal.pnl,
|
|
6988
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
6989
|
+
peakProfit: publicSignal.peakProfit,
|
|
6990
|
+
signal: publicSignal,
|
|
6939
6991
|
note: closedSignal.closeNote ?? closedSignal.note,
|
|
6940
6992
|
});
|
|
6941
6993
|
await CALL_CLOSE_CALLBACKS_FN(self, self.params.execution.context.symbol, closedSignal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
|
|
6942
6994
|
await CALL_PARTIAL_CLEAR_FN(self, self.params.execution.context.symbol, closedSignal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
|
|
6943
6995
|
await CALL_BREAKEVEN_CLEAR_FN(self, self.params.execution.context.symbol, closedSignal, averagePrice, closeTimestamp, self.params.execution.context.backtest);
|
|
6944
6996
|
await CALL_RISK_REMOVE_SIGNAL_FN(self, self.params.execution.context.symbol, closeTimestamp, self.params.execution.context.backtest);
|
|
6945
|
-
const pnl = toProfitLossDto(closedSignal, averagePrice);
|
|
6946
6997
|
const result = {
|
|
6947
6998
|
action: "closed",
|
|
6948
|
-
signal:
|
|
6999
|
+
signal: publicSignal,
|
|
6949
7000
|
currentPrice: averagePrice,
|
|
6950
7001
|
closeReason: "closed",
|
|
6951
7002
|
closeTimestamp,
|
|
6952
|
-
pnl,
|
|
7003
|
+
pnl: publicSignal.pnl,
|
|
6953
7004
|
strategyName: self.params.method.context.strategyName,
|
|
6954
7005
|
exchangeName: self.params.method.context.exchangeName,
|
|
6955
7006
|
frameName: self.params.method.context.frameName,
|
|
@@ -7014,8 +7065,8 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
|
|
|
7014
7065
|
...activatedSignal,
|
|
7015
7066
|
pendingAt: candle.timestamp,
|
|
7016
7067
|
_isScheduled: false,
|
|
7017
|
-
_peak: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0 },
|
|
7018
|
-
_fall: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0 },
|
|
7068
|
+
_peak: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
|
|
7069
|
+
_fall: { price: activatedSignal.priceOpen, timestamp: candle.timestamp, pnlPercentage: 0, pnlCost: 0, priceClose: 0, priceOpen: 0, pnlEntries: 0 },
|
|
7019
7070
|
};
|
|
7020
7071
|
// Sync open: if external system rejects — cancel scheduled signal instead of opening
|
|
7021
7072
|
const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(candle.timestamp, pendingSignal.priceOpen, pendingSignal, self);
|
|
@@ -7025,6 +7076,7 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
|
|
|
7025
7076
|
signalId: activatedSignal.id,
|
|
7026
7077
|
});
|
|
7027
7078
|
await self.setScheduledSignal(null);
|
|
7079
|
+
const publicSignal = TO_PUBLIC_SIGNAL("scheduled", activatedSignal, averagePrice);
|
|
7028
7080
|
await CALL_COMMIT_FN(self, {
|
|
7029
7081
|
action: "cancel-scheduled",
|
|
7030
7082
|
symbol: self.params.execution.context.symbol,
|
|
@@ -7037,7 +7089,10 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
|
|
|
7037
7089
|
totalEntries: activatedSignal._entry?.length ?? 1,
|
|
7038
7090
|
totalPartials: activatedSignal._partial?.length ?? 0,
|
|
7039
7091
|
originalPriceOpen: activatedSignal.priceOpen,
|
|
7040
|
-
pnl:
|
|
7092
|
+
pnl: publicSignal.pnl,
|
|
7093
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
7094
|
+
peakProfit: publicSignal.peakProfit,
|
|
7095
|
+
signal: publicSignal,
|
|
7041
7096
|
note: activatedSignal.activateNote ?? activatedSignal.note,
|
|
7042
7097
|
});
|
|
7043
7098
|
return { outcome: "pending" };
|
|
@@ -7046,7 +7101,7 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
|
|
|
7046
7101
|
await self.setPendingSignal(pendingSignal);
|
|
7047
7102
|
await CALL_RISK_ADD_SIGNAL_FN(self, self.params.execution.context.symbol, pendingSignal, candle.timestamp, self.params.execution.context.backtest);
|
|
7048
7103
|
// Emit commit AFTER successful risk check
|
|
7049
|
-
const publicSignalForCommit = TO_PUBLIC_SIGNAL(pendingSignal, averagePrice);
|
|
7104
|
+
const publicSignalForCommit = TO_PUBLIC_SIGNAL("pending", pendingSignal, averagePrice);
|
|
7050
7105
|
await CALL_COMMIT_FN(self, {
|
|
7051
7106
|
action: "activate-scheduled",
|
|
7052
7107
|
symbol: self.params.execution.context.symbol,
|
|
@@ -7058,7 +7113,10 @@ const PROCESS_SCHEDULED_SIGNAL_CANDLES_FN = async (self, scheduled, candles, fra
|
|
|
7058
7113
|
activateId: activatedSignal.activateId,
|
|
7059
7114
|
timestamp: candle.timestamp,
|
|
7060
7115
|
currentPrice: averagePrice,
|
|
7061
|
-
pnl:
|
|
7116
|
+
pnl: publicSignalForCommit.pnl,
|
|
7117
|
+
maxDrawdown: publicSignalForCommit.maxDrawdown,
|
|
7118
|
+
peakProfit: publicSignalForCommit.peakProfit,
|
|
7119
|
+
signal: publicSignalForCommit,
|
|
7062
7120
|
position: publicSignalForCommit.position,
|
|
7063
7121
|
priceOpen: publicSignalForCommit.priceOpen,
|
|
7064
7122
|
priceTakeProfit: publicSignalForCommit.priceTakeProfit,
|
|
@@ -7159,7 +7217,6 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
|
|
|
7159
7217
|
if (self._closedSignal) {
|
|
7160
7218
|
return await CLOSE_USER_PENDING_SIGNAL_IN_BACKTEST_FN(self, self._closedSignal, averagePrice, currentCandleTimestamp);
|
|
7161
7219
|
}
|
|
7162
|
-
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentCandleTimestamp, true, averagePrice);
|
|
7163
7220
|
let shouldClose = false;
|
|
7164
7221
|
let closeReason;
|
|
7165
7222
|
// Check time expiration FIRST (КРИТИЧНО!)
|
|
@@ -7218,23 +7275,21 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
|
|
|
7218
7275
|
if (signal.position === "long") {
|
|
7219
7276
|
// For long: calculate progress towards TP or SL
|
|
7220
7277
|
const currentDistance = averagePrice - effectivePriceOpen;
|
|
7221
|
-
if (currentDistance > 0) {
|
|
7222
|
-
// Check if breakeven should be triggered
|
|
7223
|
-
await CALL_BREAKEVEN_CHECK_FN(self, self.params.execution.context.symbol, signal, averagePrice, currentCandleTimestamp, self.params.execution.context.backtest);
|
|
7224
|
-
}
|
|
7225
7278
|
if (currentDistance > 0) {
|
|
7226
7279
|
// Moving towards TP (use trailing TP if set)
|
|
7227
7280
|
const effectiveTakeProfit = signal._trailingPriceTakeProfit ?? signal.priceTakeProfit;
|
|
7228
7281
|
const tpDistance = effectiveTakeProfit - effectivePriceOpen;
|
|
7229
7282
|
const progressPercent = (currentDistance / tpDistance) * 100;
|
|
7230
7283
|
if (averagePrice > signal._peak.price) {
|
|
7231
|
-
const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
|
|
7232
|
-
signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
|
|
7284
|
+
const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
|
|
7285
|
+
signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
|
|
7233
7286
|
if (self.params.callbacks?.onWrite) {
|
|
7234
7287
|
self.params.callbacks.onWrite(signal.symbol, signal, true);
|
|
7235
7288
|
}
|
|
7236
|
-
await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
|
|
7289
|
+
await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
|
|
7237
7290
|
}
|
|
7291
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentCandleTimestamp, true, averagePrice);
|
|
7292
|
+
await CALL_BREAKEVEN_CHECK_FN(self, self.params.execution.context.symbol, signal, averagePrice, currentCandleTimestamp, self.params.execution.context.backtest);
|
|
7238
7293
|
await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
|
|
7239
7294
|
}
|
|
7240
7295
|
else if (currentDistance < 0) {
|
|
@@ -7243,53 +7298,59 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
|
|
|
7243
7298
|
const slDistance = effectivePriceOpen - effectiveStopLoss;
|
|
7244
7299
|
const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
|
|
7245
7300
|
if (averagePrice < signal._fall.price) {
|
|
7246
|
-
const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
|
|
7247
|
-
signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
|
|
7301
|
+
const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
|
|
7302
|
+
signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
|
|
7248
7303
|
if (self.params.callbacks?.onWrite) {
|
|
7249
7304
|
self.params.callbacks.onWrite(signal.symbol, signal, true);
|
|
7250
7305
|
}
|
|
7251
|
-
await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
|
|
7306
|
+
await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
|
|
7252
7307
|
}
|
|
7308
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentCandleTimestamp, true, averagePrice);
|
|
7253
7309
|
await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
|
|
7254
7310
|
}
|
|
7311
|
+
else {
|
|
7312
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentCandleTimestamp, true, averagePrice);
|
|
7313
|
+
}
|
|
7255
7314
|
}
|
|
7256
7315
|
else if (signal.position === "short") {
|
|
7257
7316
|
// For short: calculate progress towards TP or SL
|
|
7258
7317
|
const currentDistance = effectivePriceOpen - averagePrice;
|
|
7259
|
-
if (currentDistance > 0) {
|
|
7260
|
-
// Check if breakeven should be triggered
|
|
7261
|
-
await CALL_BREAKEVEN_CHECK_FN(self, self.params.execution.context.symbol, signal, averagePrice, currentCandleTimestamp, self.params.execution.context.backtest);
|
|
7262
|
-
}
|
|
7263
7318
|
if (currentDistance > 0) {
|
|
7264
7319
|
// Moving towards TP (use trailing TP if set)
|
|
7265
7320
|
const effectiveTakeProfit = signal._trailingPriceTakeProfit ?? signal.priceTakeProfit;
|
|
7266
7321
|
const tpDistance = effectivePriceOpen - effectiveTakeProfit;
|
|
7267
7322
|
const progressPercent = (currentDistance / tpDistance) * 100;
|
|
7268
7323
|
if (averagePrice < signal._peak.price) {
|
|
7269
|
-
const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
|
|
7270
|
-
signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
|
|
7324
|
+
const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
|
|
7325
|
+
signal._peak = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
|
|
7271
7326
|
if (self.params.callbacks?.onWrite) {
|
|
7272
7327
|
self.params.callbacks.onWrite(signal.symbol, signal, true);
|
|
7273
7328
|
}
|
|
7274
|
-
await self.params.onHighestProfit(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
|
|
7329
|
+
await self.params.onHighestProfit(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
|
|
7275
7330
|
}
|
|
7331
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentCandleTimestamp, true, averagePrice);
|
|
7332
|
+
await CALL_BREAKEVEN_CHECK_FN(self, self.params.execution.context.symbol, signal, averagePrice, currentCandleTimestamp, self.params.execution.context.backtest);
|
|
7276
7333
|
await CALL_PARTIAL_PROFIT_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
|
|
7277
7334
|
}
|
|
7278
|
-
if (currentDistance < 0) {
|
|
7335
|
+
else if (currentDistance < 0) {
|
|
7279
7336
|
// Moving towards SL (use trailing SL if set)
|
|
7280
7337
|
const effectiveStopLoss = signal._trailingPriceStopLoss ?? signal.priceStopLoss;
|
|
7281
7338
|
const slDistance = effectiveStopLoss - effectivePriceOpen;
|
|
7282
7339
|
const progressPercent = (Math.abs(currentDistance) / slDistance) * 100;
|
|
7283
7340
|
if (averagePrice > signal._fall.price) {
|
|
7284
|
-
const { pnl } = TO_PUBLIC_SIGNAL(signal, averagePrice);
|
|
7285
|
-
signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage };
|
|
7341
|
+
const { pnl } = TO_PUBLIC_SIGNAL("pending", signal, averagePrice);
|
|
7342
|
+
signal._fall = { price: averagePrice, timestamp: currentCandleTimestamp, pnlCost: pnl.pnlCost, pnlPercentage: pnl.pnlPercentage, pnlEntries: pnl.pnlEntries, priceOpen: pnl.priceOpen, priceClose: pnl.priceClose };
|
|
7286
7343
|
if (self.params.callbacks?.onWrite) {
|
|
7287
7344
|
self.params.callbacks.onWrite(signal.symbol, signal, true);
|
|
7288
7345
|
}
|
|
7289
|
-
await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL(signal, averagePrice), averagePrice, currentCandleTimestamp);
|
|
7346
|
+
await self.params.onMaxDrawdown(TO_PUBLIC_SIGNAL("pending", signal, averagePrice), averagePrice, currentCandleTimestamp);
|
|
7290
7347
|
}
|
|
7348
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentCandleTimestamp, true, averagePrice);
|
|
7291
7349
|
await CALL_PARTIAL_LOSS_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, averagePrice, Math.min(progressPercent, 100), currentCandleTimestamp, self.params.execution.context.backtest);
|
|
7292
7350
|
}
|
|
7351
|
+
else {
|
|
7352
|
+
await CALL_ACTIVE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, signal, currentCandleTimestamp, true, averagePrice);
|
|
7353
|
+
}
|
|
7293
7354
|
}
|
|
7294
7355
|
}
|
|
7295
7356
|
// Process queued commit events with candle timestamp
|
|
@@ -7300,9 +7361,10 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
|
|
|
7300
7361
|
const lastPrice = GET_AVG_PRICE_FN(lastCandles);
|
|
7301
7362
|
const closeTimestamp = lastCandles[lastCandles.length - 1].timestamp;
|
|
7302
7363
|
if (signal.minuteEstimatedTime === Infinity) {
|
|
7364
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", signal, lastPrice);
|
|
7303
7365
|
const result = {
|
|
7304
7366
|
action: "active",
|
|
7305
|
-
signal:
|
|
7367
|
+
signal: publicSignal,
|
|
7306
7368
|
currentPrice: lastPrice,
|
|
7307
7369
|
strategyName: self.params.method.context.strategyName,
|
|
7308
7370
|
exchangeName: self.params.method.context.exchangeName,
|
|
@@ -7310,7 +7372,7 @@ const PROCESS_PENDING_SIGNAL_CANDLES_FN = async (self, signal, candles, frameEnd
|
|
|
7310
7372
|
symbol: self.params.execution.context.symbol,
|
|
7311
7373
|
percentTp: 0,
|
|
7312
7374
|
percentSl: 0,
|
|
7313
|
-
pnl:
|
|
7375
|
+
pnl: publicSignal.pnl,
|
|
7314
7376
|
backtest: self.params.execution.context.backtest,
|
|
7315
7377
|
createdAt: closeTimestamp,
|
|
7316
7378
|
_backtestLastTimestamp: closeTimestamp,
|
|
@@ -7493,7 +7555,7 @@ class ClientStrategy {
|
|
|
7493
7555
|
this.params.logger.debug("ClientStrategy getPendingSignal", {
|
|
7494
7556
|
symbol,
|
|
7495
7557
|
});
|
|
7496
|
-
return this._pendingSignal ? TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice) : null;
|
|
7558
|
+
return this._pendingSignal ? TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice) : null;
|
|
7497
7559
|
}
|
|
7498
7560
|
/**
|
|
7499
7561
|
* Retrieves the current scheduled signal.
|
|
@@ -7504,7 +7566,7 @@ class ClientStrategy {
|
|
|
7504
7566
|
this.params.logger.debug("ClientStrategy getScheduledSignal", {
|
|
7505
7567
|
symbol,
|
|
7506
7568
|
});
|
|
7507
|
-
return this._scheduledSignal ? TO_PUBLIC_SIGNAL(this._scheduledSignal, currentPrice) : null;
|
|
7569
|
+
return this._scheduledSignal ? TO_PUBLIC_SIGNAL("scheduled", this._scheduledSignal, currentPrice) : null;
|
|
7508
7570
|
}
|
|
7509
7571
|
/**
|
|
7510
7572
|
* Checks if breakeven threshold has been reached for the current pending signal.
|
|
@@ -8313,6 +8375,7 @@ class ClientStrategy {
|
|
|
8313
8375
|
signalId: cancelledSignal.id,
|
|
8314
8376
|
});
|
|
8315
8377
|
// Emit commit with correct timestamp from tick context
|
|
8378
|
+
const publicSignal = TO_PUBLIC_SIGNAL("scheduled", cancelledSignal, currentPrice);
|
|
8316
8379
|
await CALL_COMMIT_FN(this, {
|
|
8317
8380
|
action: "cancel-scheduled",
|
|
8318
8381
|
symbol: this.params.execution.context.symbol,
|
|
@@ -8326,14 +8389,17 @@ class ClientStrategy {
|
|
|
8326
8389
|
totalEntries: cancelledSignal._entry?.length ?? 1,
|
|
8327
8390
|
totalPartials: cancelledSignal._partial?.length ?? 0,
|
|
8328
8391
|
originalPriceOpen: cancelledSignal.priceOpen,
|
|
8329
|
-
pnl:
|
|
8392
|
+
pnl: publicSignal.pnl,
|
|
8393
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
8394
|
+
peakProfit: publicSignal.peakProfit,
|
|
8395
|
+
signal: publicSignal,
|
|
8330
8396
|
note: cancelledSignal.cancelNote ?? cancelledSignal.note,
|
|
8331
8397
|
});
|
|
8332
8398
|
// Call onCancel callback
|
|
8333
8399
|
await CALL_CANCEL_CALLBACKS_FN(this, this.params.execution.context.symbol, cancelledSignal, currentPrice, currentTime, this.params.execution.context.backtest);
|
|
8334
8400
|
const result = {
|
|
8335
8401
|
action: "cancelled",
|
|
8336
|
-
signal:
|
|
8402
|
+
signal: publicSignal,
|
|
8337
8403
|
currentPrice,
|
|
8338
8404
|
closeTimestamp: currentTime,
|
|
8339
8405
|
strategyName: this.params.method.context.strategyName,
|
|
@@ -8367,6 +8433,7 @@ class ClientStrategy {
|
|
|
8367
8433
|
signalId: closedSignal.id,
|
|
8368
8434
|
});
|
|
8369
8435
|
// Emit commit with correct timestamp from tick context
|
|
8436
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", closedSignal, currentPrice);
|
|
8370
8437
|
await CALL_COMMIT_FN(this, {
|
|
8371
8438
|
action: "close-pending",
|
|
8372
8439
|
symbol: this.params.execution.context.symbol,
|
|
@@ -8380,7 +8447,10 @@ class ClientStrategy {
|
|
|
8380
8447
|
totalEntries: closedSignal._entry?.length ?? 1,
|
|
8381
8448
|
totalPartials: closedSignal._partial?.length ?? 0,
|
|
8382
8449
|
originalPriceOpen: closedSignal.priceOpen,
|
|
8383
|
-
pnl:
|
|
8450
|
+
pnl: publicSignal.pnl,
|
|
8451
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
8452
|
+
peakProfit: publicSignal.peakProfit,
|
|
8453
|
+
signal: publicSignal,
|
|
8384
8454
|
note: closedSignal.closeNote ?? closedSignal.note,
|
|
8385
8455
|
});
|
|
8386
8456
|
// Call onClose callback
|
|
@@ -8390,14 +8460,13 @@ class ClientStrategy {
|
|
|
8390
8460
|
// КРИТИЧНО: Очищаем состояние ClientBreakeven при закрытии позиции
|
|
8391
8461
|
await CALL_BREAKEVEN_CLEAR_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, currentTime, this.params.execution.context.backtest);
|
|
8392
8462
|
await CALL_RISK_REMOVE_SIGNAL_FN(this, this.params.execution.context.symbol, currentTime, this.params.execution.context.backtest);
|
|
8393
|
-
const pnl = toProfitLossDto(closedSignal, currentPrice);
|
|
8394
8463
|
const result = {
|
|
8395
8464
|
action: "closed",
|
|
8396
|
-
signal:
|
|
8465
|
+
signal: publicSignal,
|
|
8397
8466
|
currentPrice,
|
|
8398
8467
|
closeReason: "closed",
|
|
8399
8468
|
closeTimestamp: currentTime,
|
|
8400
|
-
pnl,
|
|
8469
|
+
pnl: publicSignal.pnl,
|
|
8401
8470
|
strategyName: this.params.method.context.strategyName,
|
|
8402
8471
|
exchangeName: this.params.method.context.exchangeName,
|
|
8403
8472
|
frameName: this.params.method.context.frameName,
|
|
@@ -8440,8 +8509,8 @@ class ClientStrategy {
|
|
|
8440
8509
|
...activatedSignal,
|
|
8441
8510
|
pendingAt: currentTime,
|
|
8442
8511
|
_isScheduled: false,
|
|
8443
|
-
_peak: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
|
|
8444
|
-
_fall: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0 },
|
|
8512
|
+
_peak: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, pnlEntries: 0, priceOpen: 0 },
|
|
8513
|
+
_fall: { price: activatedSignal.priceOpen, timestamp: currentTime, pnlPercentage: 0, pnlCost: 0, priceClose: 0, pnlEntries: 0, priceOpen: 0 },
|
|
8445
8514
|
};
|
|
8446
8515
|
const syncOpenAllowed = await CALL_SIGNAL_SYNC_OPEN_FN(currentTime, currentPrice, pendingSignal, this);
|
|
8447
8516
|
if (!syncOpenAllowed) {
|
|
@@ -8450,6 +8519,7 @@ class ClientStrategy {
|
|
|
8450
8519
|
signalId: activatedSignal.id,
|
|
8451
8520
|
});
|
|
8452
8521
|
await this.setScheduledSignal(null);
|
|
8522
|
+
const publicSignal = TO_PUBLIC_SIGNAL("scheduled", activatedSignal, currentPrice);
|
|
8453
8523
|
await CALL_COMMIT_FN(this, {
|
|
8454
8524
|
action: "cancel-scheduled",
|
|
8455
8525
|
symbol: this.params.execution.context.symbol,
|
|
@@ -8462,7 +8532,10 @@ class ClientStrategy {
|
|
|
8462
8532
|
totalEntries: activatedSignal._entry?.length ?? 1,
|
|
8463
8533
|
totalPartials: activatedSignal._partial?.length ?? 0,
|
|
8464
8534
|
originalPriceOpen: activatedSignal.priceOpen,
|
|
8465
|
-
pnl:
|
|
8535
|
+
pnl: publicSignal.pnl,
|
|
8536
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
8537
|
+
peakProfit: publicSignal.peakProfit,
|
|
8538
|
+
signal: publicSignal,
|
|
8466
8539
|
note: activatedSignal.activateNote ?? activatedSignal.note,
|
|
8467
8540
|
});
|
|
8468
8541
|
return await RETURN_IDLE_FN(this, currentPrice);
|
|
@@ -8470,7 +8543,7 @@ class ClientStrategy {
|
|
|
8470
8543
|
await this.setPendingSignal(pendingSignal);
|
|
8471
8544
|
await CALL_RISK_ADD_SIGNAL_FN(this, this.params.execution.context.symbol, pendingSignal, currentTime, this.params.execution.context.backtest);
|
|
8472
8545
|
// Emit commit AFTER successful risk check
|
|
8473
|
-
const publicSignalForCommit = TO_PUBLIC_SIGNAL(pendingSignal, currentPrice);
|
|
8546
|
+
const publicSignalForCommit = TO_PUBLIC_SIGNAL("pending", pendingSignal, currentPrice);
|
|
8474
8547
|
await CALL_COMMIT_FN(this, {
|
|
8475
8548
|
action: "activate-scheduled",
|
|
8476
8549
|
symbol: this.params.execution.context.symbol,
|
|
@@ -8482,7 +8555,10 @@ class ClientStrategy {
|
|
|
8482
8555
|
activateId: activatedSignal.activateId,
|
|
8483
8556
|
timestamp: currentTime,
|
|
8484
8557
|
currentPrice,
|
|
8485
|
-
pnl:
|
|
8558
|
+
pnl: publicSignalForCommit.pnl,
|
|
8559
|
+
maxDrawdown: publicSignalForCommit.maxDrawdown,
|
|
8560
|
+
peakProfit: publicSignalForCommit.peakProfit,
|
|
8561
|
+
signal: publicSignalForCommit,
|
|
8486
8562
|
position: publicSignalForCommit.position,
|
|
8487
8563
|
priceOpen: publicSignalForCommit.priceOpen,
|
|
8488
8564
|
priceTakeProfit: publicSignalForCommit.priceTakeProfit,
|
|
@@ -8500,7 +8576,7 @@ class ClientStrategy {
|
|
|
8500
8576
|
await CALL_OPEN_CALLBACKS_FN(this, this.params.execution.context.symbol, pendingSignal, currentPrice, currentTime, this.params.execution.context.backtest);
|
|
8501
8577
|
const result = {
|
|
8502
8578
|
action: "opened",
|
|
8503
|
-
signal:
|
|
8579
|
+
signal: publicSignalForCommit,
|
|
8504
8580
|
strategyName: this.params.method.context.strategyName,
|
|
8505
8581
|
exchangeName: this.params.method.context.exchangeName,
|
|
8506
8582
|
frameName: this.params.method.context.frameName,
|
|
@@ -8616,6 +8692,7 @@ class ClientStrategy {
|
|
|
8616
8692
|
this._cancelledSignal = null; // Clear after using
|
|
8617
8693
|
const closeTimestamp = this.params.execution.context.when.getTime();
|
|
8618
8694
|
// Emit commit with correct timestamp from backtest context
|
|
8695
|
+
const publicSignal = TO_PUBLIC_SIGNAL("scheduled", cancelledSignal, currentPrice);
|
|
8619
8696
|
await CALL_COMMIT_FN(this, {
|
|
8620
8697
|
action: "cancel-scheduled",
|
|
8621
8698
|
symbol: this.params.execution.context.symbol,
|
|
@@ -8629,13 +8706,16 @@ class ClientStrategy {
|
|
|
8629
8706
|
totalEntries: cancelledSignal._entry?.length ?? 1,
|
|
8630
8707
|
totalPartials: cancelledSignal._partial?.length ?? 0,
|
|
8631
8708
|
originalPriceOpen: cancelledSignal.priceOpen,
|
|
8632
|
-
pnl:
|
|
8709
|
+
pnl: publicSignal.pnl,
|
|
8710
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
8711
|
+
peakProfit: publicSignal.peakProfit,
|
|
8712
|
+
signal: publicSignal,
|
|
8633
8713
|
note: cancelledSignal.cancelNote ?? cancelledSignal.note,
|
|
8634
8714
|
});
|
|
8635
8715
|
await CALL_CANCEL_CALLBACKS_FN(this, this.params.execution.context.symbol, cancelledSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
|
|
8636
8716
|
const cancelledResult = {
|
|
8637
8717
|
action: "cancelled",
|
|
8638
|
-
signal:
|
|
8718
|
+
signal: publicSignal,
|
|
8639
8719
|
currentPrice,
|
|
8640
8720
|
closeTimestamp: closeTimestamp,
|
|
8641
8721
|
strategyName: this.params.method.context.strategyName,
|
|
@@ -8671,6 +8751,7 @@ class ClientStrategy {
|
|
|
8671
8751
|
}
|
|
8672
8752
|
this._closedSignal = null; // Clear only after sync confirmed
|
|
8673
8753
|
// Emit commit with correct timestamp from backtest context
|
|
8754
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", closedSignal, currentPrice);
|
|
8674
8755
|
await CALL_COMMIT_FN(this, {
|
|
8675
8756
|
action: "close-pending",
|
|
8676
8757
|
symbol: this.params.execution.context.symbol,
|
|
@@ -8684,7 +8765,10 @@ class ClientStrategy {
|
|
|
8684
8765
|
totalEntries: closedSignal._entry?.length ?? 1,
|
|
8685
8766
|
totalPartials: closedSignal._partial?.length ?? 0,
|
|
8686
8767
|
originalPriceOpen: closedSignal.priceOpen,
|
|
8687
|
-
pnl:
|
|
8768
|
+
pnl: publicSignal.pnl,
|
|
8769
|
+
maxDrawdown: publicSignal.maxDrawdown,
|
|
8770
|
+
peakProfit: publicSignal.peakProfit,
|
|
8771
|
+
signal: publicSignal,
|
|
8688
8772
|
note: closedSignal.closeNote ?? closedSignal.note,
|
|
8689
8773
|
});
|
|
8690
8774
|
await CALL_CLOSE_CALLBACKS_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
|
|
@@ -8693,14 +8777,13 @@ class ClientStrategy {
|
|
|
8693
8777
|
// КРИТИЧНО: Очищаем состояние ClientBreakeven при закрытии позиции
|
|
8694
8778
|
await CALL_BREAKEVEN_CLEAR_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
|
|
8695
8779
|
await CALL_RISK_REMOVE_SIGNAL_FN(this, this.params.execution.context.symbol, closeTimestamp, this.params.execution.context.backtest);
|
|
8696
|
-
const pnl = toProfitLossDto(closedSignal, currentPrice);
|
|
8697
8780
|
const closedResult = {
|
|
8698
8781
|
action: "closed",
|
|
8699
|
-
signal:
|
|
8782
|
+
signal: publicSignal,
|
|
8700
8783
|
currentPrice,
|
|
8701
8784
|
closeReason: "closed",
|
|
8702
8785
|
closeTimestamp: closeTimestamp,
|
|
8703
|
-
pnl,
|
|
8786
|
+
pnl: publicSignal.pnl,
|
|
8704
8787
|
strategyName: this.params.method.context.strategyName,
|
|
8705
8788
|
exchangeName: this.params.method.context.exchangeName,
|
|
8706
8789
|
frameName: this.params.method.context.frameName,
|
|
@@ -9156,7 +9239,7 @@ class ClientStrategy {
|
|
|
9156
9239
|
});
|
|
9157
9240
|
// Call onWrite callback for testing persist storage
|
|
9158
9241
|
if (this.params.callbacks?.onWrite) {
|
|
9159
|
-
this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice), backtest);
|
|
9242
|
+
this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice), backtest);
|
|
9160
9243
|
}
|
|
9161
9244
|
if (!backtest) {
|
|
9162
9245
|
await PersistSignalAdapter.writeSignalData(this._pendingSignal, this.params.execution.context.symbol, this.params.strategyName, this.params.exchangeName);
|
|
@@ -9339,7 +9422,7 @@ class ClientStrategy {
|
|
|
9339
9422
|
});
|
|
9340
9423
|
// Call onWrite callback for testing persist storage
|
|
9341
9424
|
if (this.params.callbacks?.onWrite) {
|
|
9342
|
-
this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice), backtest);
|
|
9425
|
+
this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice), backtest);
|
|
9343
9426
|
}
|
|
9344
9427
|
if (!backtest) {
|
|
9345
9428
|
await PersistSignalAdapter.writeSignalData(this._pendingSignal, this.params.execution.context.symbol, this.params.strategyName, this.params.exchangeName);
|
|
@@ -9537,7 +9620,7 @@ class ClientStrategy {
|
|
|
9537
9620
|
});
|
|
9538
9621
|
// Call onWrite callback for testing persist storage
|
|
9539
9622
|
if (this.params.callbacks?.onWrite) {
|
|
9540
|
-
const publicSignal = TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice);
|
|
9623
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice);
|
|
9541
9624
|
this.params.callbacks.onWrite(this.params.execution.context.symbol, publicSignal, backtest);
|
|
9542
9625
|
}
|
|
9543
9626
|
if (!backtest) {
|
|
@@ -9786,7 +9869,7 @@ class ClientStrategy {
|
|
|
9786
9869
|
});
|
|
9787
9870
|
// Call onWrite callback for testing persist storage
|
|
9788
9871
|
if (this.params.callbacks?.onWrite) {
|
|
9789
|
-
const publicSignal = TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice);
|
|
9872
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice);
|
|
9790
9873
|
this.params.callbacks.onWrite(this.params.execution.context.symbol, publicSignal, backtest);
|
|
9791
9874
|
}
|
|
9792
9875
|
if (!backtest) {
|
|
@@ -10022,7 +10105,7 @@ class ClientStrategy {
|
|
|
10022
10105
|
});
|
|
10023
10106
|
// Call onWrite callback for testing persist storage
|
|
10024
10107
|
if (this.params.callbacks?.onWrite) {
|
|
10025
|
-
const publicSignal = TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice);
|
|
10108
|
+
const publicSignal = TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice);
|
|
10026
10109
|
this.params.callbacks.onWrite(this.params.execution.context.symbol, publicSignal, backtest);
|
|
10027
10110
|
}
|
|
10028
10111
|
if (!backtest) {
|
|
@@ -10114,7 +10197,7 @@ class ClientStrategy {
|
|
|
10114
10197
|
});
|
|
10115
10198
|
// Call onWrite callback for testing persist storage
|
|
10116
10199
|
if (this.params.callbacks?.onWrite) {
|
|
10117
|
-
this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL(this._pendingSignal, currentPrice), backtest);
|
|
10200
|
+
this.params.callbacks.onWrite(this.params.execution.context.symbol, TO_PUBLIC_SIGNAL("pending", this._pendingSignal, currentPrice), backtest);
|
|
10118
10201
|
}
|
|
10119
10202
|
if (!backtest) {
|
|
10120
10203
|
await PersistSignalAdapter.writeSignalData(this._pendingSignal, this.params.execution.context.symbol, this.params.strategyName, this.params.exchangeName);
|
|
@@ -12485,12 +12568,15 @@ const alignToInterval = (date, interval) => {
|
|
|
12485
12568
|
|
|
12486
12569
|
/** Symbol indicating that positions need to be fetched from persistence */
|
|
12487
12570
|
const POSITION_NEED_FETCH = Symbol("risk-need-fetch");
|
|
12571
|
+
/** Get timestamp from execution context or fallback to aligned current time */
|
|
12488
12572
|
const GET_CONTEXT_TIMESTAMP_FN = (self) => {
|
|
12489
12573
|
if (ExecutionContextService.hasContext()) {
|
|
12490
12574
|
return self.params.execution.context.when.getTime();
|
|
12491
12575
|
}
|
|
12492
12576
|
return alignToInterval(new Date(), "1m").getTime();
|
|
12493
12577
|
};
|
|
12578
|
+
/** Zero PNL constant for scheduled signals (which don't have priceOpen or PNL yet) */
|
|
12579
|
+
const ZERO_PNL = { pnlPercentage: 0, priceOpen: 0, priceClose: 0, pnlCost: 0, pnlEntries: 0 };
|
|
12494
12580
|
/**
|
|
12495
12581
|
* Converts signal to risk validation format.
|
|
12496
12582
|
*
|
|
@@ -12533,6 +12619,9 @@ const TO_RISK_SIGNAL = (signal, currentPrice, timestamp) => {
|
|
|
12533
12619
|
const partialExecuted = ("_partial" in signal && Array.isArray(signal._partial))
|
|
12534
12620
|
? signal._partial.reduce((sum, partial) => sum + partial.percent, 0)
|
|
12535
12621
|
: 0;
|
|
12622
|
+
const pnl = signal._isScheduled ? ZERO_PNL : toProfitLossDto(signal, currentPrice);
|
|
12623
|
+
const maxDrawdown = signal._isScheduled ? ZERO_PNL : pnl;
|
|
12624
|
+
const peakProfit = signal._isScheduled ? ZERO_PNL : pnl;
|
|
12536
12625
|
return {
|
|
12537
12626
|
...structuredClone(signal),
|
|
12538
12627
|
cost: signal.cost || GLOBAL_CONFIG.CC_POSITION_ENTRY_COST,
|
|
@@ -12546,7 +12635,9 @@ const TO_RISK_SIGNAL = (signal, currentPrice, timestamp) => {
|
|
|
12546
12635
|
originalPriceTakeProfit: signal.priceTakeProfit,
|
|
12547
12636
|
originalPriceOpen: signal.priceOpen ?? currentPrice,
|
|
12548
12637
|
partialExecuted,
|
|
12549
|
-
pnl
|
|
12638
|
+
pnl,
|
|
12639
|
+
maxDrawdown,
|
|
12640
|
+
peakProfit,
|
|
12550
12641
|
};
|
|
12551
12642
|
};
|
|
12552
12643
|
/** Key generator for active position map */
|
|
@@ -18816,7 +18907,9 @@ const backtest_columns = [
|
|
|
18816
18907
|
key: "peakPnl",
|
|
18817
18908
|
label: "Peak PNL",
|
|
18818
18909
|
format: (data) => {
|
|
18819
|
-
const v = data.signal.
|
|
18910
|
+
const v = data.signal.peakProfit?.pnlPercentage;
|
|
18911
|
+
if (v === undefined)
|
|
18912
|
+
return "N/A";
|
|
18820
18913
|
return `${v > 0 ? "+" : ""}${v.toFixed(2)}%`;
|
|
18821
18914
|
},
|
|
18822
18915
|
isVisible: () => true,
|
|
@@ -18824,7 +18917,12 @@ const backtest_columns = [
|
|
|
18824
18917
|
{
|
|
18825
18918
|
key: "fallPnl",
|
|
18826
18919
|
label: "Max DD PNL",
|
|
18827
|
-
format: (data) =>
|
|
18920
|
+
format: (data) => {
|
|
18921
|
+
const v = data.signal.maxDrawdown?.pnlPercentage;
|
|
18922
|
+
if (v === undefined)
|
|
18923
|
+
return "N/A";
|
|
18924
|
+
return `${v.toFixed(2)}%`;
|
|
18925
|
+
},
|
|
18828
18926
|
isVisible: () => true,
|
|
18829
18927
|
},
|
|
18830
18928
|
];
|
|
@@ -21385,8 +21483,8 @@ let ReportStorage$a = class ReportStorage {
|
|
|
21385
21483
|
const tradesPerYear = avgDurationDays > 0 ? 365 / avgDurationDays : 0;
|
|
21386
21484
|
const expectedYearlyReturns = avgPnl * tradesPerYear;
|
|
21387
21485
|
// Calculate average peak and fall PNL across all signals
|
|
21388
|
-
const avgPeakPnl = this._signalList.reduce((sum, s) => sum + (s.signal.
|
|
21389
|
-
const avgFallPnl = this._signalList.reduce((sum, s) => sum + (s.signal.
|
|
21486
|
+
const avgPeakPnl = this._signalList.reduce((sum, s) => sum + (s.signal.peakProfit?.pnlPercentage ?? 0), 0) / totalSignals;
|
|
21487
|
+
const avgFallPnl = this._signalList.reduce((sum, s) => sum + (s.signal.maxDrawdown?.pnlPercentage ?? 0), 0) / totalSignals;
|
|
21390
21488
|
return {
|
|
21391
21489
|
signalList: this._signalList,
|
|
21392
21490
|
totalSignals,
|
|
@@ -21915,8 +22013,8 @@ let ReportStorage$9 = class ReportStorage {
|
|
|
21915
22013
|
duration: durationMin,
|
|
21916
22014
|
pendingAt: data.signal.pendingAt,
|
|
21917
22015
|
scheduledAt: data.signal.scheduledAt,
|
|
21918
|
-
peakPnl: data.signal.
|
|
21919
|
-
fallPnl: data.signal.
|
|
22016
|
+
peakPnl: data.signal.peakProfit?.pnlPercentage,
|
|
22017
|
+
fallPnl: data.signal.maxDrawdown?.pnlPercentage,
|
|
21920
22018
|
};
|
|
21921
22019
|
this._eventList.unshift(newEvent);
|
|
21922
22020
|
// Trim queue if exceeded GLOBAL_CONFIG.CC_MAX_LIVE_MARKDOWN_ROWS
|
|
@@ -24067,8 +24165,8 @@ class HeatmapStorage {
|
|
|
24067
24165
|
let avgPeakPnl = null;
|
|
24068
24166
|
let avgFallPnl = null;
|
|
24069
24167
|
if (signals.length > 0) {
|
|
24070
|
-
avgPeakPnl = signals.reduce((acc, s) => acc + (s.signal.
|
|
24071
|
-
avgFallPnl = signals.reduce((acc, s) => acc + (s.signal.
|
|
24168
|
+
avgPeakPnl = signals.reduce((acc, s) => acc + (s.signal.peakProfit?.pnlPercentage ?? 0), 0) / signals.length;
|
|
24169
|
+
avgFallPnl = signals.reduce((acc, s) => acc + (s.signal.maxDrawdown?.pnlPercentage ?? 0), 0) / signals.length;
|
|
24072
24170
|
}
|
|
24073
24171
|
// Apply safe math checks
|
|
24074
24172
|
if (isUnsafe(winRate))
|
|
@@ -28195,8 +28293,16 @@ class BacktestReportService {
|
|
|
28195
28293
|
pnlPriceClose: data.pnl.priceClose,
|
|
28196
28294
|
totalPartials: data.signal?.totalPartials,
|
|
28197
28295
|
cost: data.signal?.cost,
|
|
28198
|
-
|
|
28199
|
-
|
|
28296
|
+
peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
|
|
28297
|
+
peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
|
|
28298
|
+
peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
|
|
28299
|
+
peakProfitCost: data.signal?.peakProfit?.pnlCost,
|
|
28300
|
+
peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
|
|
28301
|
+
maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
|
|
28302
|
+
maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
|
|
28303
|
+
maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
|
|
28304
|
+
maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
|
|
28305
|
+
maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
|
|
28200
28306
|
}, { ...searchOptions, signalId: data.signal?.id });
|
|
28201
28307
|
}
|
|
28202
28308
|
else if (data.action === "closed") {
|
|
@@ -28229,8 +28335,16 @@ class BacktestReportService {
|
|
|
28229
28335
|
closeReason: data.closeReason,
|
|
28230
28336
|
closeTime: data.closeTimestamp,
|
|
28231
28337
|
duration: durationMin,
|
|
28232
|
-
|
|
28233
|
-
|
|
28338
|
+
peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
|
|
28339
|
+
peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
|
|
28340
|
+
peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
|
|
28341
|
+
peakProfitCost: data.signal?.peakProfit?.pnlCost,
|
|
28342
|
+
peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
|
|
28343
|
+
maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
|
|
28344
|
+
maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
|
|
28345
|
+
maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
|
|
28346
|
+
maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
|
|
28347
|
+
maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
|
|
28234
28348
|
}, { ...searchOptions, signalId: data.signal?.id });
|
|
28235
28349
|
}
|
|
28236
28350
|
};
|
|
@@ -28393,8 +28507,16 @@ class LiveReportService {
|
|
|
28393
28507
|
pnlPriceClose: data.pnl.priceClose,
|
|
28394
28508
|
totalPartials: data.signal?.totalPartials,
|
|
28395
28509
|
cost: data.signal?.cost,
|
|
28396
|
-
|
|
28397
|
-
|
|
28510
|
+
peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
|
|
28511
|
+
peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
|
|
28512
|
+
peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
|
|
28513
|
+
peakProfitCost: data.signal?.peakProfit?.pnlCost,
|
|
28514
|
+
peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
|
|
28515
|
+
maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
|
|
28516
|
+
maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
|
|
28517
|
+
maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
|
|
28518
|
+
maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
|
|
28519
|
+
maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
|
|
28398
28520
|
}, { ...searchOptions, signalId: data.signal?.id });
|
|
28399
28521
|
}
|
|
28400
28522
|
else if (data.action === "opened") {
|
|
@@ -28445,8 +28567,16 @@ class LiveReportService {
|
|
|
28445
28567
|
pnlPriceClose: data.pnl.priceClose,
|
|
28446
28568
|
totalPartials: data.signal?.totalPartials,
|
|
28447
28569
|
cost: data.signal?.cost,
|
|
28448
|
-
|
|
28449
|
-
|
|
28570
|
+
peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
|
|
28571
|
+
peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
|
|
28572
|
+
peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
|
|
28573
|
+
peakProfitCost: data.signal?.peakProfit?.pnlCost,
|
|
28574
|
+
peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
|
|
28575
|
+
maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
|
|
28576
|
+
maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
|
|
28577
|
+
maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
|
|
28578
|
+
maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
|
|
28579
|
+
maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
|
|
28450
28580
|
}, { ...searchOptions, signalId: data.signal?.id });
|
|
28451
28581
|
}
|
|
28452
28582
|
else if (data.action === "closed") {
|
|
@@ -28479,8 +28609,16 @@ class LiveReportService {
|
|
|
28479
28609
|
closeReason: data.closeReason,
|
|
28480
28610
|
duration: durationMin,
|
|
28481
28611
|
closeTime: data.closeTimestamp,
|
|
28482
|
-
|
|
28483
|
-
|
|
28612
|
+
peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
|
|
28613
|
+
peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
|
|
28614
|
+
peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
|
|
28615
|
+
peakProfitCost: data.signal?.peakProfit?.pnlCost,
|
|
28616
|
+
peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
|
|
28617
|
+
maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
|
|
28618
|
+
maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
|
|
28619
|
+
maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
|
|
28620
|
+
maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
|
|
28621
|
+
maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
|
|
28484
28622
|
}, { ...searchOptions, signalId: data.signal?.id });
|
|
28485
28623
|
}
|
|
28486
28624
|
else if (data.action === "cancelled") {
|
|
@@ -29072,8 +29210,16 @@ class HeatReportService {
|
|
|
29072
29210
|
openTime: data.signal?.pendingAt,
|
|
29073
29211
|
scheduledAt: data.signal?.scheduledAt,
|
|
29074
29212
|
closeTime: data.closeTimestamp,
|
|
29075
|
-
|
|
29076
|
-
|
|
29213
|
+
peakProfitPriceOpen: data.signal?.peakProfit?.priceOpen,
|
|
29214
|
+
peakProfitPriceClose: data.signal?.peakProfit?.priceClose,
|
|
29215
|
+
peakProfitPercentage: data.signal?.peakProfit?.pnlPercentage,
|
|
29216
|
+
peakProfitCost: data.signal?.peakProfit?.pnlCost,
|
|
29217
|
+
peakProfitEntries: data.signal?.peakProfit?.pnlEntries,
|
|
29218
|
+
maxDrawdownPriceOpen: data.signal?.maxDrawdown?.priceOpen,
|
|
29219
|
+
maxDrawdownPriceClose: data.signal?.maxDrawdown?.priceClose,
|
|
29220
|
+
maxDrawdownPercentage: data.signal?.maxDrawdown?.pnlPercentage,
|
|
29221
|
+
maxDrawdownCost: data.signal?.maxDrawdown?.pnlCost,
|
|
29222
|
+
maxDrawdownEntries: data.signal?.maxDrawdown?.pnlEntries,
|
|
29077
29223
|
}, {
|
|
29078
29224
|
symbol: data.symbol,
|
|
29079
29225
|
strategyName: data.strategyName,
|
|
@@ -29207,6 +29353,16 @@ class PartialReportService {
|
|
|
29207
29353
|
pnlEntries: data.data.pnl.pnlEntries,
|
|
29208
29354
|
pnlPriceOpen: data.data.pnl.priceOpen,
|
|
29209
29355
|
pnlPriceClose: data.data.pnl.priceClose,
|
|
29356
|
+
peakProfitPercentage: data.data.peakProfit.pnlPercentage,
|
|
29357
|
+
peakProfitCost: data.data.peakProfit.pnlCost,
|
|
29358
|
+
peakProfitEntries: data.data.peakProfit.pnlEntries,
|
|
29359
|
+
peakProfitPriceOpen: data.data.peakProfit.priceOpen,
|
|
29360
|
+
peakProfitPriceClose: data.data.peakProfit.priceClose,
|
|
29361
|
+
maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
|
|
29362
|
+
maxDrawdownCost: data.data.maxDrawdown.pnlCost,
|
|
29363
|
+
maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
|
|
29364
|
+
maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
|
|
29365
|
+
maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
|
|
29210
29366
|
}, {
|
|
29211
29367
|
symbol: data.symbol,
|
|
29212
29368
|
strategyName: data.data.strategyName,
|
|
@@ -29257,6 +29413,16 @@ class PartialReportService {
|
|
|
29257
29413
|
pnlEntries: data.data.pnl.pnlEntries,
|
|
29258
29414
|
pnlPriceOpen: data.data.pnl.priceOpen,
|
|
29259
29415
|
pnlPriceClose: data.data.pnl.priceClose,
|
|
29416
|
+
peakProfitPercentage: data.data.peakProfit.pnlPercentage,
|
|
29417
|
+
peakProfitCost: data.data.peakProfit.pnlCost,
|
|
29418
|
+
peakProfitEntries: data.data.peakProfit.pnlEntries,
|
|
29419
|
+
peakProfitPriceOpen: data.data.peakProfit.priceOpen,
|
|
29420
|
+
peakProfitPriceClose: data.data.peakProfit.priceClose,
|
|
29421
|
+
maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
|
|
29422
|
+
maxDrawdownCost: data.data.maxDrawdown.pnlCost,
|
|
29423
|
+
maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
|
|
29424
|
+
maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
|
|
29425
|
+
maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
|
|
29260
29426
|
}, {
|
|
29261
29427
|
symbol: data.symbol,
|
|
29262
29428
|
strategyName: data.data.strategyName,
|
|
@@ -29388,6 +29554,16 @@ class BreakevenReportService {
|
|
|
29388
29554
|
pnlEntries: data.data.pnl.pnlEntries,
|
|
29389
29555
|
pnlPriceOpen: data.data.pnl.priceOpen,
|
|
29390
29556
|
pnlPriceClose: data.data.pnl.priceClose,
|
|
29557
|
+
peakProfitPercentage: data.data.peakProfit.pnlPercentage,
|
|
29558
|
+
peakProfitCost: data.data.peakProfit.pnlCost,
|
|
29559
|
+
peakProfitEntries: data.data.peakProfit.pnlEntries,
|
|
29560
|
+
peakProfitPriceOpen: data.data.peakProfit.priceOpen,
|
|
29561
|
+
peakProfitPriceClose: data.data.peakProfit.priceClose,
|
|
29562
|
+
maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
|
|
29563
|
+
maxDrawdownCost: data.data.maxDrawdown.pnlCost,
|
|
29564
|
+
maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
|
|
29565
|
+
maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
|
|
29566
|
+
maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
|
|
29391
29567
|
}, {
|
|
29392
29568
|
symbol: data.symbol,
|
|
29393
29569
|
strategyName: data.data.strategyName,
|
|
@@ -29518,6 +29694,16 @@ class RiskReportService {
|
|
|
29518
29694
|
pnlEntries: data.currentSignal?.pnl?.pnlEntries,
|
|
29519
29695
|
pnlPriceOpen: data.currentSignal?.pnl?.priceOpen,
|
|
29520
29696
|
pnlPriceClose: data.currentSignal?.pnl?.priceClose,
|
|
29697
|
+
peakProfitPercentage: data.currentSignal?.peakProfit?.pnlPercentage,
|
|
29698
|
+
peakProfitCost: data.currentSignal?.peakProfit?.pnlCost,
|
|
29699
|
+
peakProfitEntries: data.currentSignal?.peakProfit?.pnlEntries,
|
|
29700
|
+
peakProfitPriceOpen: data.currentSignal?.peakProfit?.priceOpen,
|
|
29701
|
+
peakProfitPriceClose: data.currentSignal?.peakProfit?.priceClose,
|
|
29702
|
+
maxDrawdownPercentage: data.currentSignal?.maxDrawdown?.pnlPercentage,
|
|
29703
|
+
maxDrawdownCost: data.currentSignal?.maxDrawdown?.pnlCost,
|
|
29704
|
+
maxDrawdownEntries: data.currentSignal?.maxDrawdown?.pnlEntries,
|
|
29705
|
+
maxDrawdownPriceOpen: data.currentSignal?.maxDrawdown?.priceOpen,
|
|
29706
|
+
maxDrawdownPriceClose: data.currentSignal?.maxDrawdown?.priceClose,
|
|
29521
29707
|
}, {
|
|
29522
29708
|
symbol: data.symbol,
|
|
29523
29709
|
strategyName: data.strategyName,
|
|
@@ -29597,7 +29783,7 @@ class StrategyReportService {
|
|
|
29597
29783
|
/**
|
|
29598
29784
|
* Logs a cancel-scheduled event when a scheduled signal is cancelled.
|
|
29599
29785
|
*/
|
|
29600
|
-
this.cancelScheduled = async (symbol, isBacktest, context, timestamp, signalId, pnl, totalPartials, cancelId, note) => {
|
|
29786
|
+
this.cancelScheduled = async (symbol, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, cancelId, note) => {
|
|
29601
29787
|
this.loggerService.log("strategyReportService cancelScheduled", {
|
|
29602
29788
|
symbol,
|
|
29603
29789
|
isBacktest,
|
|
@@ -29619,6 +29805,16 @@ class StrategyReportService {
|
|
|
29619
29805
|
pnlEntries: pnl.pnlEntries,
|
|
29620
29806
|
pnlPriceOpen: pnl.priceOpen,
|
|
29621
29807
|
pnlPriceClose: pnl.priceClose,
|
|
29808
|
+
peakProfitPercentage: peakProfit.pnlPercentage,
|
|
29809
|
+
peakProfitCost: peakProfit.pnlCost,
|
|
29810
|
+
peakProfitEntries: peakProfit.pnlEntries,
|
|
29811
|
+
peakProfitPriceOpen: peakProfit.priceOpen,
|
|
29812
|
+
peakProfitPriceClose: peakProfit.priceClose,
|
|
29813
|
+
maxDrawdownPercentage: maxDrawdown.pnlPercentage,
|
|
29814
|
+
maxDrawdownCost: maxDrawdown.pnlCost,
|
|
29815
|
+
maxDrawdownEntries: maxDrawdown.pnlEntries,
|
|
29816
|
+
maxDrawdownPriceOpen: maxDrawdown.priceOpen,
|
|
29817
|
+
maxDrawdownPriceClose: maxDrawdown.priceClose,
|
|
29622
29818
|
totalPartials,
|
|
29623
29819
|
}, {
|
|
29624
29820
|
signalId,
|
|
@@ -29632,7 +29828,7 @@ class StrategyReportService {
|
|
|
29632
29828
|
/**
|
|
29633
29829
|
* Logs a close-pending event when a pending signal is closed.
|
|
29634
29830
|
*/
|
|
29635
|
-
this.closePending = async (symbol, isBacktest, context, timestamp, signalId, pnl, totalPartials, closeId, note) => {
|
|
29831
|
+
this.closePending = async (symbol, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, closeId, note) => {
|
|
29636
29832
|
this.loggerService.log("strategyReportService closePending", {
|
|
29637
29833
|
symbol,
|
|
29638
29834
|
isBacktest,
|
|
@@ -29654,6 +29850,16 @@ class StrategyReportService {
|
|
|
29654
29850
|
pnlEntries: pnl.pnlEntries,
|
|
29655
29851
|
pnlPriceOpen: pnl.priceOpen,
|
|
29656
29852
|
pnlPriceClose: pnl.priceClose,
|
|
29853
|
+
peakProfitPercentage: peakProfit.pnlPercentage,
|
|
29854
|
+
peakProfitCost: peakProfit.pnlCost,
|
|
29855
|
+
peakProfitEntries: peakProfit.pnlEntries,
|
|
29856
|
+
peakProfitPriceOpen: peakProfit.priceOpen,
|
|
29857
|
+
peakProfitPriceClose: peakProfit.priceClose,
|
|
29858
|
+
maxDrawdownPercentage: maxDrawdown.pnlPercentage,
|
|
29859
|
+
maxDrawdownCost: maxDrawdown.pnlCost,
|
|
29860
|
+
maxDrawdownEntries: maxDrawdown.pnlEntries,
|
|
29861
|
+
maxDrawdownPriceOpen: maxDrawdown.priceOpen,
|
|
29862
|
+
maxDrawdownPriceClose: maxDrawdown.priceClose,
|
|
29657
29863
|
totalPartials,
|
|
29658
29864
|
}, {
|
|
29659
29865
|
signalId,
|
|
@@ -29667,7 +29873,7 @@ class StrategyReportService {
|
|
|
29667
29873
|
/**
|
|
29668
29874
|
* Logs a partial-profit event when a portion of the position is closed at profit.
|
|
29669
29875
|
*/
|
|
29670
|
-
this.partialProfit = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
|
|
29876
|
+
this.partialProfit = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
|
|
29671
29877
|
this.loggerService.log("strategyReportService partialProfit", {
|
|
29672
29878
|
symbol,
|
|
29673
29879
|
percentToClose,
|
|
@@ -29700,6 +29906,16 @@ class StrategyReportService {
|
|
|
29700
29906
|
pnlEntries: pnl.pnlEntries,
|
|
29701
29907
|
pnlPriceOpen: pnl.priceOpen,
|
|
29702
29908
|
pnlPriceClose: pnl.priceClose,
|
|
29909
|
+
peakProfitPercentage: peakProfit.pnlPercentage,
|
|
29910
|
+
peakProfitCost: peakProfit.pnlCost,
|
|
29911
|
+
peakProfitEntries: peakProfit.pnlEntries,
|
|
29912
|
+
peakProfitPriceOpen: peakProfit.priceOpen,
|
|
29913
|
+
peakProfitPriceClose: peakProfit.priceClose,
|
|
29914
|
+
maxDrawdownPercentage: maxDrawdown.pnlPercentage,
|
|
29915
|
+
maxDrawdownCost: maxDrawdown.pnlCost,
|
|
29916
|
+
maxDrawdownEntries: maxDrawdown.pnlEntries,
|
|
29917
|
+
maxDrawdownPriceOpen: maxDrawdown.priceOpen,
|
|
29918
|
+
maxDrawdownPriceClose: maxDrawdown.priceClose,
|
|
29703
29919
|
totalPartials,
|
|
29704
29920
|
}, {
|
|
29705
29921
|
signalId,
|
|
@@ -29713,7 +29929,7 @@ class StrategyReportService {
|
|
|
29713
29929
|
/**
|
|
29714
29930
|
* Logs a partial-loss event when a portion of the position is closed at loss.
|
|
29715
29931
|
*/
|
|
29716
|
-
this.partialLoss = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
|
|
29932
|
+
this.partialLoss = async (symbol, percentToClose, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
|
|
29717
29933
|
this.loggerService.log("strategyReportService partialLoss", {
|
|
29718
29934
|
symbol,
|
|
29719
29935
|
percentToClose,
|
|
@@ -29746,6 +29962,16 @@ class StrategyReportService {
|
|
|
29746
29962
|
pnlEntries: pnl.pnlEntries,
|
|
29747
29963
|
pnlPriceOpen: pnl.priceOpen,
|
|
29748
29964
|
pnlPriceClose: pnl.priceClose,
|
|
29965
|
+
peakProfitPercentage: peakProfit.pnlPercentage,
|
|
29966
|
+
peakProfitCost: peakProfit.pnlCost,
|
|
29967
|
+
peakProfitEntries: peakProfit.pnlEntries,
|
|
29968
|
+
peakProfitPriceOpen: peakProfit.priceOpen,
|
|
29969
|
+
peakProfitPriceClose: peakProfit.priceClose,
|
|
29970
|
+
maxDrawdownPercentage: maxDrawdown.pnlPercentage,
|
|
29971
|
+
maxDrawdownCost: maxDrawdown.pnlCost,
|
|
29972
|
+
maxDrawdownEntries: maxDrawdown.pnlEntries,
|
|
29973
|
+
maxDrawdownPriceOpen: maxDrawdown.priceOpen,
|
|
29974
|
+
maxDrawdownPriceClose: maxDrawdown.priceClose,
|
|
29749
29975
|
totalPartials,
|
|
29750
29976
|
}, {
|
|
29751
29977
|
signalId,
|
|
@@ -29759,7 +29985,7 @@ class StrategyReportService {
|
|
|
29759
29985
|
/**
|
|
29760
29986
|
* Logs a trailing-stop event when the stop-loss is adjusted.
|
|
29761
29987
|
*/
|
|
29762
|
-
this.trailingStop = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
|
|
29988
|
+
this.trailingStop = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
|
|
29763
29989
|
this.loggerService.log("strategyReportService trailingStop", {
|
|
29764
29990
|
symbol,
|
|
29765
29991
|
percentShift,
|
|
@@ -29792,6 +30018,16 @@ class StrategyReportService {
|
|
|
29792
30018
|
pnlEntries: pnl.pnlEntries,
|
|
29793
30019
|
pnlPriceOpen: pnl.priceOpen,
|
|
29794
30020
|
pnlPriceClose: pnl.priceClose,
|
|
30021
|
+
peakProfitPercentage: peakProfit.pnlPercentage,
|
|
30022
|
+
peakProfitCost: peakProfit.pnlCost,
|
|
30023
|
+
peakProfitEntries: peakProfit.pnlEntries,
|
|
30024
|
+
peakProfitPriceOpen: peakProfit.priceOpen,
|
|
30025
|
+
peakProfitPriceClose: peakProfit.priceClose,
|
|
30026
|
+
maxDrawdownPercentage: maxDrawdown.pnlPercentage,
|
|
30027
|
+
maxDrawdownCost: maxDrawdown.pnlCost,
|
|
30028
|
+
maxDrawdownEntries: maxDrawdown.pnlEntries,
|
|
30029
|
+
maxDrawdownPriceOpen: maxDrawdown.priceOpen,
|
|
30030
|
+
maxDrawdownPriceClose: maxDrawdown.priceClose,
|
|
29795
30031
|
totalPartials,
|
|
29796
30032
|
}, {
|
|
29797
30033
|
signalId,
|
|
@@ -29805,7 +30041,7 @@ class StrategyReportService {
|
|
|
29805
30041
|
/**
|
|
29806
30042
|
* Logs a trailing-take event when the take-profit is adjusted.
|
|
29807
30043
|
*/
|
|
29808
|
-
this.trailingTake = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
|
|
30044
|
+
this.trailingTake = async (symbol, percentShift, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
|
|
29809
30045
|
this.loggerService.log("strategyReportService trailingTake", {
|
|
29810
30046
|
symbol,
|
|
29811
30047
|
percentShift,
|
|
@@ -29838,6 +30074,16 @@ class StrategyReportService {
|
|
|
29838
30074
|
pnlEntries: pnl.pnlEntries,
|
|
29839
30075
|
pnlPriceOpen: pnl.priceOpen,
|
|
29840
30076
|
pnlPriceClose: pnl.priceClose,
|
|
30077
|
+
peakProfitPercentage: peakProfit.pnlPercentage,
|
|
30078
|
+
peakProfitCost: peakProfit.pnlCost,
|
|
30079
|
+
peakProfitEntries: peakProfit.pnlEntries,
|
|
30080
|
+
peakProfitPriceOpen: peakProfit.priceOpen,
|
|
30081
|
+
peakProfitPriceClose: peakProfit.priceClose,
|
|
30082
|
+
maxDrawdownPercentage: maxDrawdown.pnlPercentage,
|
|
30083
|
+
maxDrawdownCost: maxDrawdown.pnlCost,
|
|
30084
|
+
maxDrawdownEntries: maxDrawdown.pnlEntries,
|
|
30085
|
+
maxDrawdownPriceOpen: maxDrawdown.priceOpen,
|
|
30086
|
+
maxDrawdownPriceClose: maxDrawdown.priceClose,
|
|
29841
30087
|
totalPartials,
|
|
29842
30088
|
}, {
|
|
29843
30089
|
signalId,
|
|
@@ -29851,7 +30097,7 @@ class StrategyReportService {
|
|
|
29851
30097
|
/**
|
|
29852
30098
|
* Logs a breakeven event when the stop-loss is moved to entry price.
|
|
29853
30099
|
*/
|
|
29854
|
-
this.breakeven = async (symbol, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
|
|
30100
|
+
this.breakeven = async (symbol, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen) => {
|
|
29855
30101
|
this.loggerService.log("strategyReportService breakeven", {
|
|
29856
30102
|
symbol,
|
|
29857
30103
|
currentPrice,
|
|
@@ -29882,6 +30128,16 @@ class StrategyReportService {
|
|
|
29882
30128
|
pnlEntries: pnl.pnlEntries,
|
|
29883
30129
|
pnlPriceOpen: pnl.priceOpen,
|
|
29884
30130
|
pnlPriceClose: pnl.priceClose,
|
|
30131
|
+
peakProfitPercentage: peakProfit.pnlPercentage,
|
|
30132
|
+
peakProfitCost: peakProfit.pnlCost,
|
|
30133
|
+
peakProfitEntries: peakProfit.pnlEntries,
|
|
30134
|
+
peakProfitPriceOpen: peakProfit.priceOpen,
|
|
30135
|
+
peakProfitPriceClose: peakProfit.priceClose,
|
|
30136
|
+
maxDrawdownPercentage: maxDrawdown.pnlPercentage,
|
|
30137
|
+
maxDrawdownCost: maxDrawdown.pnlCost,
|
|
30138
|
+
maxDrawdownEntries: maxDrawdown.pnlEntries,
|
|
30139
|
+
maxDrawdownPriceOpen: maxDrawdown.priceOpen,
|
|
30140
|
+
maxDrawdownPriceClose: maxDrawdown.priceClose,
|
|
29885
30141
|
totalPartials,
|
|
29886
30142
|
}, {
|
|
29887
30143
|
signalId,
|
|
@@ -29895,7 +30151,7 @@ class StrategyReportService {
|
|
|
29895
30151
|
/**
|
|
29896
30152
|
* Logs an activate-scheduled event when a scheduled signal is activated early.
|
|
29897
30153
|
*/
|
|
29898
|
-
this.activateScheduled = async (symbol, currentPrice, isBacktest, context, timestamp, signalId, pnl, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen, activateId, note) => {
|
|
30154
|
+
this.activateScheduled = async (symbol, currentPrice, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, totalEntries, originalPriceOpen, activateId, note) => {
|
|
29899
30155
|
this.loggerService.log("strategyReportService activateScheduled", {
|
|
29900
30156
|
symbol,
|
|
29901
30157
|
currentPrice,
|
|
@@ -29929,6 +30185,16 @@ class StrategyReportService {
|
|
|
29929
30185
|
pnlEntries: pnl.pnlEntries,
|
|
29930
30186
|
pnlPriceOpen: pnl.priceOpen,
|
|
29931
30187
|
pnlPriceClose: pnl.priceClose,
|
|
30188
|
+
peakProfitPercentage: peakProfit.pnlPercentage,
|
|
30189
|
+
peakProfitCost: peakProfit.pnlCost,
|
|
30190
|
+
peakProfitEntries: peakProfit.pnlEntries,
|
|
30191
|
+
peakProfitPriceOpen: peakProfit.priceOpen,
|
|
30192
|
+
peakProfitPriceClose: peakProfit.priceClose,
|
|
30193
|
+
maxDrawdownPercentage: maxDrawdown.pnlPercentage,
|
|
30194
|
+
maxDrawdownCost: maxDrawdown.pnlCost,
|
|
30195
|
+
maxDrawdownEntries: maxDrawdown.pnlEntries,
|
|
30196
|
+
maxDrawdownPriceOpen: maxDrawdown.priceOpen,
|
|
30197
|
+
maxDrawdownPriceClose: maxDrawdown.priceClose,
|
|
29932
30198
|
totalPartials,
|
|
29933
30199
|
}, {
|
|
29934
30200
|
signalId,
|
|
@@ -29942,7 +30208,7 @@ class StrategyReportService {
|
|
|
29942
30208
|
/**
|
|
29943
30209
|
* Logs an average-buy (DCA) event when a new averaging entry is added to an open position.
|
|
29944
30210
|
*/
|
|
29945
|
-
this.averageBuy = async (symbol, currentPrice, effectivePriceOpen, totalEntries, isBacktest, context, timestamp, signalId, pnl, totalPartials, cost, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, originalPriceOpen) => {
|
|
30211
|
+
this.averageBuy = async (symbol, currentPrice, effectivePriceOpen, totalEntries, isBacktest, context, timestamp, signalId, pnl, peakProfit, maxDrawdown, totalPartials, cost, position, priceOpen, priceTakeProfit, priceStopLoss, originalPriceTakeProfit, originalPriceStopLoss, scheduledAt, pendingAt, originalPriceOpen) => {
|
|
29946
30212
|
this.loggerService.log("strategyReportService averageBuy", {
|
|
29947
30213
|
symbol,
|
|
29948
30214
|
currentPrice,
|
|
@@ -29976,6 +30242,16 @@ class StrategyReportService {
|
|
|
29976
30242
|
pnlEntries: pnl.pnlEntries,
|
|
29977
30243
|
pnlPriceOpen: pnl.priceOpen,
|
|
29978
30244
|
pnlPriceClose: pnl.priceClose,
|
|
30245
|
+
peakProfitPercentage: peakProfit.pnlPercentage,
|
|
30246
|
+
peakProfitCost: peakProfit.pnlCost,
|
|
30247
|
+
peakProfitEntries: peakProfit.pnlEntries,
|
|
30248
|
+
peakProfitPriceOpen: peakProfit.priceOpen,
|
|
30249
|
+
peakProfitPriceClose: peakProfit.priceClose,
|
|
30250
|
+
maxDrawdownPercentage: maxDrawdown.pnlPercentage,
|
|
30251
|
+
maxDrawdownCost: maxDrawdown.pnlCost,
|
|
30252
|
+
maxDrawdownEntries: maxDrawdown.pnlEntries,
|
|
30253
|
+
maxDrawdownPriceOpen: maxDrawdown.priceOpen,
|
|
30254
|
+
maxDrawdownPriceClose: maxDrawdown.priceClose,
|
|
29979
30255
|
totalPartials,
|
|
29980
30256
|
cost,
|
|
29981
30257
|
}, {
|
|
@@ -30003,63 +30279,63 @@ class StrategyReportService {
|
|
|
30003
30279
|
exchangeName: event.exchangeName,
|
|
30004
30280
|
frameName: event.frameName,
|
|
30005
30281
|
strategyName: event.strategyName,
|
|
30006
|
-
}, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.cancelId, event.note));
|
|
30282
|
+
}, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.cancelId, event.note));
|
|
30007
30283
|
const unClosePending = strategyCommitSubject
|
|
30008
30284
|
.filter(({ action }) => action === "close-pending")
|
|
30009
30285
|
.connect(async (event) => await this.closePending(event.symbol, event.backtest, {
|
|
30010
30286
|
exchangeName: event.exchangeName,
|
|
30011
30287
|
frameName: event.frameName,
|
|
30012
30288
|
strategyName: event.strategyName,
|
|
30013
|
-
}, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.closeId, event.note));
|
|
30289
|
+
}, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.closeId, event.note));
|
|
30014
30290
|
const unPartialProfit = strategyCommitSubject
|
|
30015
30291
|
.filter(({ action }) => action === "partial-profit")
|
|
30016
30292
|
.connect(async (event) => await this.partialProfit(event.symbol, event.percentToClose, event.currentPrice, event.backtest, {
|
|
30017
30293
|
exchangeName: event.exchangeName,
|
|
30018
30294
|
frameName: event.frameName,
|
|
30019
30295
|
strategyName: event.strategyName,
|
|
30020
|
-
}, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
|
|
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));
|
|
30021
30297
|
const unPartialLoss = strategyCommitSubject
|
|
30022
30298
|
.filter(({ action }) => action === "partial-loss")
|
|
30023
30299
|
.connect(async (event) => await this.partialLoss(event.symbol, event.percentToClose, event.currentPrice, event.backtest, {
|
|
30024
30300
|
exchangeName: event.exchangeName,
|
|
30025
30301
|
frameName: event.frameName,
|
|
30026
30302
|
strategyName: event.strategyName,
|
|
30027
|
-
}, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
|
|
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));
|
|
30028
30304
|
const unTrailingStop = strategyCommitSubject
|
|
30029
30305
|
.filter(({ action }) => action === "trailing-stop")
|
|
30030
30306
|
.connect(async (event) => await this.trailingStop(event.symbol, event.percentShift, event.currentPrice, event.backtest, {
|
|
30031
30307
|
exchangeName: event.exchangeName,
|
|
30032
30308
|
frameName: event.frameName,
|
|
30033
30309
|
strategyName: event.strategyName,
|
|
30034
|
-
}, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
|
|
30310
|
+
}, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
|
|
30035
30311
|
const unTrailingTake = strategyCommitSubject
|
|
30036
30312
|
.filter(({ action }) => action === "trailing-take")
|
|
30037
30313
|
.connect(async (event) => await this.trailingTake(event.symbol, event.percentShift, event.currentPrice, event.backtest, {
|
|
30038
30314
|
exchangeName: event.exchangeName,
|
|
30039
30315
|
frameName: event.frameName,
|
|
30040
30316
|
strategyName: event.strategyName,
|
|
30041
|
-
}, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
|
|
30317
|
+
}, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
|
|
30042
30318
|
const unBreakeven = strategyCommitSubject
|
|
30043
30319
|
.filter(({ action }) => action === "breakeven")
|
|
30044
30320
|
.connect(async (event) => await this.breakeven(event.symbol, event.currentPrice, event.backtest, {
|
|
30045
30321
|
exchangeName: event.exchangeName,
|
|
30046
30322
|
frameName: event.frameName,
|
|
30047
30323
|
strategyName: event.strategyName,
|
|
30048
|
-
}, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
|
|
30324
|
+
}, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen));
|
|
30049
30325
|
const unActivateScheduled = strategyCommitSubject
|
|
30050
30326
|
.filter(({ action }) => action === "activate-scheduled")
|
|
30051
30327
|
.connect(async (event) => await this.activateScheduled(event.symbol, event.currentPrice, event.backtest, {
|
|
30052
30328
|
exchangeName: event.exchangeName,
|
|
30053
30329
|
frameName: event.frameName,
|
|
30054
30330
|
strategyName: event.strategyName,
|
|
30055
|
-
}, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen, event.activateId, event.note));
|
|
30331
|
+
}, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.totalEntries, event.originalPriceOpen, event.activateId, event.note));
|
|
30056
30332
|
const unAverageBuy = strategyCommitSubject
|
|
30057
30333
|
.filter(({ action }) => action === "average-buy")
|
|
30058
30334
|
.connect(async (event) => await this.averageBuy(event.symbol, event.currentPrice, event.effectivePriceOpen, event.totalEntries, event.backtest, {
|
|
30059
30335
|
exchangeName: event.exchangeName,
|
|
30060
30336
|
frameName: event.frameName,
|
|
30061
30337
|
strategyName: event.strategyName,
|
|
30062
|
-
}, event.timestamp, event.signalId, event.pnl, event.totalPartials, event.cost, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.originalPriceOpen));
|
|
30338
|
+
}, event.timestamp, event.signalId, event.pnl, event.peakProfit, event.maxDrawdown, event.totalPartials, event.cost, event.position, event.priceOpen, event.priceTakeProfit, event.priceStopLoss, event.originalPriceTakeProfit, event.originalPriceStopLoss, event.scheduledAt, event.pendingAt, event.originalPriceOpen));
|
|
30063
30339
|
const disposeFn = functoolsKit.compose(() => unCancelSchedule(), () => unClosePending(), () => unPartialProfit(), () => unPartialLoss(), () => unTrailingStop(), () => unTrailingTake(), () => unBreakeven(), () => unActivateScheduled(), () => unAverageBuy());
|
|
30064
30340
|
return () => {
|
|
30065
30341
|
disposeFn();
|
|
@@ -30158,6 +30434,16 @@ class SyncReportService {
|
|
|
30158
30434
|
pnlEntries: data.pnl.pnlEntries,
|
|
30159
30435
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
30160
30436
|
pnlPriceClose: data.pnl.priceClose,
|
|
30437
|
+
peakProfitPercentage: data.peakProfit.pnlPercentage,
|
|
30438
|
+
peakProfitCost: data.peakProfit.pnlCost,
|
|
30439
|
+
peakProfitEntries: data.peakProfit.pnlEntries,
|
|
30440
|
+
peakProfitPriceOpen: data.peakProfit.priceOpen,
|
|
30441
|
+
peakProfitPriceClose: data.peakProfit.priceClose,
|
|
30442
|
+
maxDrawdownPercentage: data.maxDrawdown.pnlPercentage,
|
|
30443
|
+
maxDrawdownCost: data.maxDrawdown.pnlCost,
|
|
30444
|
+
maxDrawdownEntries: data.maxDrawdown.pnlEntries,
|
|
30445
|
+
maxDrawdownPriceOpen: data.maxDrawdown.priceOpen,
|
|
30446
|
+
maxDrawdownPriceClose: data.maxDrawdown.priceClose,
|
|
30161
30447
|
currentPrice: data.currentPrice,
|
|
30162
30448
|
};
|
|
30163
30449
|
const searchOptions = {
|
|
@@ -30268,6 +30554,16 @@ class HighestProfitReportService {
|
|
|
30268
30554
|
priceOpen: data.signal.priceOpen,
|
|
30269
30555
|
priceTakeProfit: data.signal.priceTakeProfit,
|
|
30270
30556
|
priceStopLoss: data.signal.priceStopLoss,
|
|
30557
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
30558
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
30559
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
30560
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
30561
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
30562
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
30563
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
30564
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
30565
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
30566
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
30271
30567
|
}, {
|
|
30272
30568
|
symbol: data.symbol,
|
|
30273
30569
|
strategyName: data.signal.strategyName,
|
|
@@ -31545,7 +31841,9 @@ class SyncMarkdownService {
|
|
|
31545
31841
|
pendingAt: data.pendingAt,
|
|
31546
31842
|
totalEntries: data.totalEntries,
|
|
31547
31843
|
totalPartials: data.totalPartials,
|
|
31548
|
-
pnl: data.pnl,
|
|
31844
|
+
pnl: data.signal.pnl,
|
|
31845
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
31846
|
+
peakProfit: data.signal.peakProfit,
|
|
31549
31847
|
closeReason: data.action === "signal-close" ? data.closeReason : undefined,
|
|
31550
31848
|
backtest: data.backtest,
|
|
31551
31849
|
createdAt,
|
|
@@ -31720,6 +32018,8 @@ let ReportStorage$1 = class ReportStorage {
|
|
|
31720
32018
|
signalId: data.id,
|
|
31721
32019
|
position: data.position,
|
|
31722
32020
|
pnl: data.pnl,
|
|
32021
|
+
maxDrawdown: data.maxDrawdown,
|
|
32022
|
+
peakProfit: data.peakProfit,
|
|
31723
32023
|
currentPrice,
|
|
31724
32024
|
priceOpen: data.priceOpen,
|
|
31725
32025
|
priceTakeProfit: data.priceTakeProfit,
|
|
@@ -32331,6 +32631,16 @@ class MaxDrawdownReportService {
|
|
|
32331
32631
|
priceOpen: data.signal.priceOpen,
|
|
32332
32632
|
priceTakeProfit: data.signal.priceTakeProfit,
|
|
32333
32633
|
priceStopLoss: data.signal.priceStopLoss,
|
|
32634
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
32635
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
32636
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
32637
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
32638
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
32639
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
32640
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
32641
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
32642
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
32643
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
32334
32644
|
}, {
|
|
32335
32645
|
symbol: data.symbol,
|
|
32336
32646
|
strategyName: data.signal.strategyName,
|
|
@@ -32423,6 +32733,8 @@ class ReportStorage {
|
|
|
32423
32733
|
signalId: data.id,
|
|
32424
32734
|
position: data.position,
|
|
32425
32735
|
pnl: data.pnl,
|
|
32736
|
+
maxDrawdown: data.maxDrawdown,
|
|
32737
|
+
peakProfit: data.peakProfit,
|
|
32426
32738
|
currentPrice,
|
|
32427
32739
|
priceOpen: data.priceOpen,
|
|
32428
32740
|
priceTakeProfit: data.priceTakeProfit,
|
|
@@ -35374,6 +35686,9 @@ class BrokerAdapter {
|
|
|
35374
35686
|
priceTakeProfit: event.signal.priceTakeProfit,
|
|
35375
35687
|
priceStopLoss: event.signal.priceStopLoss,
|
|
35376
35688
|
priceOpen: event.signal.priceOpen,
|
|
35689
|
+
pnl: event.signal.pnl,
|
|
35690
|
+
peakProfit: event.signal.peakProfit,
|
|
35691
|
+
maxDrawdown: event.signal.maxDrawdown,
|
|
35377
35692
|
context: {
|
|
35378
35693
|
strategyName: event.strategyName,
|
|
35379
35694
|
exchangeName: event.exchangeName,
|
|
@@ -35391,7 +35706,10 @@ class BrokerAdapter {
|
|
|
35391
35706
|
currentPrice: event.currentPrice,
|
|
35392
35707
|
cost: event.signal.cost,
|
|
35393
35708
|
symbol: event.symbol,
|
|
35394
|
-
pnl: event.pnl,
|
|
35709
|
+
pnl: event.signal.pnl,
|
|
35710
|
+
priceOpen: event.signal.priceOpen,
|
|
35711
|
+
peakProfit: event.signal.peakProfit,
|
|
35712
|
+
maxDrawdown: event.signal.maxDrawdown,
|
|
35395
35713
|
totalEntries: event.totalEntries,
|
|
35396
35714
|
totalPartials: event.totalPartials,
|
|
35397
35715
|
priceStopLoss: event.signal.priceStopLoss,
|
|
@@ -54433,11 +54751,23 @@ const CREATE_SIGNAL_NOTIFICATION_FN = (data) => {
|
|
|
54433
54751
|
totalPartials: data.signal.totalPartials,
|
|
54434
54752
|
cost: data.signal.cost,
|
|
54435
54753
|
pnl: data.signal.pnl,
|
|
54754
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
54755
|
+
peakProfit: data.signal.peakProfit,
|
|
54436
54756
|
pnlPercentage: data.signal.pnl.pnlPercentage,
|
|
54437
54757
|
pnlPriceOpen: data.signal.pnl.priceOpen,
|
|
54438
54758
|
pnlPriceClose: data.signal.pnl.priceClose,
|
|
54439
54759
|
pnlCost: data.signal.pnl.pnlCost,
|
|
54440
54760
|
pnlEntries: data.signal.pnl.pnlEntries,
|
|
54761
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
54762
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
54763
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
54764
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
54765
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
54766
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
54767
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
54768
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
54769
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
54770
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54441
54771
|
note: data.signal.note,
|
|
54442
54772
|
scheduledAt: data.signal.scheduledAt,
|
|
54443
54773
|
pendingAt: data.signal.pendingAt,
|
|
@@ -54467,11 +54797,23 @@ const CREATE_SIGNAL_NOTIFICATION_FN = (data) => {
|
|
|
54467
54797
|
totalEntries: data.signal.totalEntries,
|
|
54468
54798
|
totalPartials: data.signal.totalPartials,
|
|
54469
54799
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54470
|
-
pnl: data.pnl,
|
|
54800
|
+
pnl: data.signal.pnl,
|
|
54801
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
54802
|
+
peakProfit: data.signal.peakProfit,
|
|
54471
54803
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54472
54804
|
pnlPriceClose: data.pnl.priceClose,
|
|
54473
54805
|
pnlCost: data.pnl.pnlCost,
|
|
54474
54806
|
pnlEntries: data.pnl.pnlEntries,
|
|
54807
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
54808
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
54809
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
54810
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
54811
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
54812
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
54813
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
54814
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
54815
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
54816
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54475
54817
|
closeReason: data.closeReason,
|
|
54476
54818
|
duration: durationMin,
|
|
54477
54819
|
note: data.signal.note,
|
|
@@ -54501,11 +54843,23 @@ const CREATE_SIGNAL_NOTIFICATION_FN = (data) => {
|
|
|
54501
54843
|
totalPartials: data.signal.totalPartials,
|
|
54502
54844
|
cost: data.signal.cost,
|
|
54503
54845
|
pnl: data.signal.pnl,
|
|
54846
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
54847
|
+
peakProfit: data.signal.peakProfit,
|
|
54504
54848
|
pnlPercentage: data.signal.pnl.pnlPercentage,
|
|
54505
54849
|
pnlPriceOpen: data.signal.pnl.priceOpen,
|
|
54506
54850
|
pnlPriceClose: data.signal.pnl.priceClose,
|
|
54507
54851
|
pnlCost: data.signal.pnl.pnlCost,
|
|
54508
54852
|
pnlEntries: data.signal.pnl.pnlEntries,
|
|
54853
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
54854
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
54855
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
54856
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
54857
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
54858
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
54859
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
54860
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
54861
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
54862
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54509
54863
|
scheduledAt: data.signal.scheduledAt,
|
|
54510
54864
|
currentPrice: data.currentPrice,
|
|
54511
54865
|
note: data.signal.note,
|
|
@@ -54570,11 +54924,23 @@ const CREATE_PARTIAL_PROFIT_NOTIFICATION_FN = (data) => ({
|
|
|
54570
54924
|
totalEntries: data.data.totalEntries,
|
|
54571
54925
|
totalPartials: data.data.totalPartials,
|
|
54572
54926
|
pnl: data.data.pnl,
|
|
54927
|
+
maxDrawdown: data.data.maxDrawdown,
|
|
54928
|
+
peakProfit: data.data.peakProfit,
|
|
54573
54929
|
pnlPercentage: data.data.pnl.pnlPercentage,
|
|
54574
54930
|
pnlPriceOpen: data.data.pnl.priceOpen,
|
|
54575
54931
|
pnlPriceClose: data.data.pnl.priceClose,
|
|
54576
54932
|
pnlCost: data.data.pnl.pnlCost,
|
|
54577
54933
|
pnlEntries: data.data.pnl.pnlEntries,
|
|
54934
|
+
peakProfitPriceOpen: data.data.peakProfit.priceOpen,
|
|
54935
|
+
peakProfitPriceClose: data.data.peakProfit.priceClose,
|
|
54936
|
+
peakProfitPercentage: data.data.peakProfit.pnlPercentage,
|
|
54937
|
+
peakProfitCost: data.data.peakProfit.pnlCost,
|
|
54938
|
+
peakProfitEntries: data.data.peakProfit.pnlEntries,
|
|
54939
|
+
maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
|
|
54940
|
+
maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
|
|
54941
|
+
maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
|
|
54942
|
+
maxDrawdownCost: data.data.maxDrawdown.pnlCost,
|
|
54943
|
+
maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
|
|
54578
54944
|
note: data.data.note,
|
|
54579
54945
|
scheduledAt: data.data.scheduledAt,
|
|
54580
54946
|
pendingAt: data.data.pendingAt,
|
|
@@ -54606,11 +54972,23 @@ const CREATE_PARTIAL_LOSS_NOTIFICATION_FN = (data) => ({
|
|
|
54606
54972
|
totalEntries: data.data.totalEntries,
|
|
54607
54973
|
totalPartials: data.data.totalPartials,
|
|
54608
54974
|
pnl: data.data.pnl,
|
|
54975
|
+
maxDrawdown: data.data.maxDrawdown,
|
|
54976
|
+
peakProfit: data.data.peakProfit,
|
|
54609
54977
|
pnlPercentage: data.data.pnl.pnlPercentage,
|
|
54610
54978
|
pnlPriceOpen: data.data.pnl.priceOpen,
|
|
54611
54979
|
pnlPriceClose: data.data.pnl.priceClose,
|
|
54612
54980
|
pnlCost: data.data.pnl.pnlCost,
|
|
54613
54981
|
pnlEntries: data.data.pnl.pnlEntries,
|
|
54982
|
+
peakProfitPriceOpen: data.data.peakProfit.priceOpen,
|
|
54983
|
+
peakProfitPriceClose: data.data.peakProfit.priceClose,
|
|
54984
|
+
peakProfitPercentage: data.data.peakProfit.pnlPercentage,
|
|
54985
|
+
peakProfitCost: data.data.peakProfit.pnlCost,
|
|
54986
|
+
peakProfitEntries: data.data.peakProfit.pnlEntries,
|
|
54987
|
+
maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
|
|
54988
|
+
maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
|
|
54989
|
+
maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
|
|
54990
|
+
maxDrawdownCost: data.data.maxDrawdown.pnlCost,
|
|
54991
|
+
maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
|
|
54614
54992
|
note: data.data.note,
|
|
54615
54993
|
scheduledAt: data.data.scheduledAt,
|
|
54616
54994
|
pendingAt: data.data.pendingAt,
|
|
@@ -54641,11 +55019,23 @@ const CREATE_BREAKEVEN_NOTIFICATION_FN = (data) => ({
|
|
|
54641
55019
|
totalEntries: data.data.totalEntries,
|
|
54642
55020
|
totalPartials: data.data.totalPartials,
|
|
54643
55021
|
pnl: data.data.pnl,
|
|
55022
|
+
maxDrawdown: data.data.maxDrawdown,
|
|
55023
|
+
peakProfit: data.data.peakProfit,
|
|
54644
55024
|
pnlPercentage: data.data.pnl.pnlPercentage,
|
|
54645
55025
|
pnlPriceOpen: data.data.pnl.priceOpen,
|
|
54646
55026
|
pnlPriceClose: data.data.pnl.priceClose,
|
|
54647
55027
|
pnlCost: data.data.pnl.pnlCost,
|
|
54648
55028
|
pnlEntries: data.data.pnl.pnlEntries,
|
|
55029
|
+
peakProfitPriceOpen: data.data.peakProfit.priceOpen,
|
|
55030
|
+
peakProfitPriceClose: data.data.peakProfit.priceClose,
|
|
55031
|
+
peakProfitPercentage: data.data.peakProfit.pnlPercentage,
|
|
55032
|
+
peakProfitCost: data.data.peakProfit.pnlCost,
|
|
55033
|
+
peakProfitEntries: data.data.peakProfit.pnlEntries,
|
|
55034
|
+
maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
|
|
55035
|
+
maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
|
|
55036
|
+
maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
|
|
55037
|
+
maxDrawdownCost: data.data.maxDrawdown.pnlCost,
|
|
55038
|
+
maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
|
|
54649
55039
|
note: data.data.note,
|
|
54650
55040
|
scheduledAt: data.data.scheduledAt,
|
|
54651
55041
|
pendingAt: data.data.pendingAt,
|
|
@@ -54680,12 +55070,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
|
|
|
54680
55070
|
originalPriceOpen: data.originalPriceOpen,
|
|
54681
55071
|
totalEntries: data.totalEntries,
|
|
54682
55072
|
totalPartials: data.totalPartials,
|
|
54683
|
-
pnl: data.pnl,
|
|
55073
|
+
pnl: data.signal.pnl,
|
|
55074
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
55075
|
+
peakProfit: data.signal.peakProfit,
|
|
54684
55076
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54685
55077
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54686
55078
|
pnlPriceClose: data.pnl.priceClose,
|
|
54687
55079
|
pnlCost: data.pnl.pnlCost,
|
|
54688
55080
|
pnlEntries: data.pnl.pnlEntries,
|
|
55081
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
55082
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
55083
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
55084
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
55085
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
55086
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
55087
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
55088
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
55089
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
55090
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54689
55091
|
scheduledAt: data.scheduledAt,
|
|
54690
55092
|
pendingAt: data.pendingAt,
|
|
54691
55093
|
note: data.note,
|
|
@@ -54713,12 +55115,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
|
|
|
54713
55115
|
originalPriceOpen: data.originalPriceOpen,
|
|
54714
55116
|
totalEntries: data.totalEntries,
|
|
54715
55117
|
totalPartials: data.totalPartials,
|
|
54716
|
-
pnl: data.pnl,
|
|
55118
|
+
pnl: data.signal.pnl,
|
|
55119
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
55120
|
+
peakProfit: data.signal.peakProfit,
|
|
54717
55121
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54718
55122
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54719
55123
|
pnlPriceClose: data.pnl.priceClose,
|
|
54720
55124
|
pnlCost: data.pnl.pnlCost,
|
|
54721
55125
|
pnlEntries: data.pnl.pnlEntries,
|
|
55126
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
55127
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
55128
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
55129
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
55130
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
55131
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
55132
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
55133
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
55134
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
55135
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54722
55136
|
scheduledAt: data.scheduledAt,
|
|
54723
55137
|
pendingAt: data.pendingAt,
|
|
54724
55138
|
note: data.note,
|
|
@@ -54745,12 +55159,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
|
|
|
54745
55159
|
originalPriceOpen: data.originalPriceOpen,
|
|
54746
55160
|
totalEntries: data.totalEntries,
|
|
54747
55161
|
totalPartials: data.totalPartials,
|
|
54748
|
-
pnl: data.pnl,
|
|
55162
|
+
pnl: data.signal.pnl,
|
|
55163
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
55164
|
+
peakProfit: data.signal.peakProfit,
|
|
54749
55165
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54750
55166
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54751
55167
|
pnlPriceClose: data.pnl.priceClose,
|
|
54752
55168
|
pnlCost: data.pnl.pnlCost,
|
|
54753
55169
|
pnlEntries: data.pnl.pnlEntries,
|
|
55170
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
55171
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
55172
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
55173
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
55174
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
55175
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
55176
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
55177
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
55178
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
55179
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54754
55180
|
scheduledAt: data.scheduledAt,
|
|
54755
55181
|
pendingAt: data.pendingAt,
|
|
54756
55182
|
note: data.note,
|
|
@@ -54778,12 +55204,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
|
|
|
54778
55204
|
originalPriceOpen: data.originalPriceOpen,
|
|
54779
55205
|
totalEntries: data.totalEntries,
|
|
54780
55206
|
totalPartials: data.totalPartials,
|
|
54781
|
-
pnl: data.pnl,
|
|
55207
|
+
pnl: data.signal.pnl,
|
|
55208
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
55209
|
+
peakProfit: data.signal.peakProfit,
|
|
54782
55210
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54783
55211
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54784
55212
|
pnlPriceClose: data.pnl.priceClose,
|
|
54785
55213
|
pnlCost: data.pnl.pnlCost,
|
|
54786
55214
|
pnlEntries: data.pnl.pnlEntries,
|
|
55215
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
55216
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
55217
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
55218
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
55219
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
55220
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
55221
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
55222
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
55223
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
55224
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54787
55225
|
scheduledAt: data.scheduledAt,
|
|
54788
55226
|
pendingAt: data.pendingAt,
|
|
54789
55227
|
note: data.note,
|
|
@@ -54811,12 +55249,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
|
|
|
54811
55249
|
originalPriceOpen: data.originalPriceOpen,
|
|
54812
55250
|
totalEntries: data.totalEntries,
|
|
54813
55251
|
totalPartials: data.totalPartials,
|
|
54814
|
-
pnl: data.pnl,
|
|
55252
|
+
pnl: data.signal.pnl,
|
|
55253
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
55254
|
+
peakProfit: data.signal.peakProfit,
|
|
54815
55255
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54816
55256
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54817
55257
|
pnlPriceClose: data.pnl.priceClose,
|
|
54818
55258
|
pnlCost: data.pnl.pnlCost,
|
|
54819
55259
|
pnlEntries: data.pnl.pnlEntries,
|
|
55260
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
55261
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
55262
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
55263
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
55264
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
55265
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
55266
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
55267
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
55268
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
55269
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54820
55270
|
scheduledAt: data.scheduledAt,
|
|
54821
55271
|
pendingAt: data.pendingAt,
|
|
54822
55272
|
note: data.note,
|
|
@@ -54844,12 +55294,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
|
|
|
54844
55294
|
originalPriceOpen: data.originalPriceOpen,
|
|
54845
55295
|
totalEntries: data.totalEntries,
|
|
54846
55296
|
totalPartials: data.totalPartials,
|
|
54847
|
-
pnl: data.pnl,
|
|
55297
|
+
pnl: data.signal.pnl,
|
|
55298
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
55299
|
+
peakProfit: data.signal.peakProfit,
|
|
54848
55300
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54849
55301
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54850
55302
|
pnlPriceClose: data.pnl.priceClose,
|
|
54851
55303
|
pnlCost: data.pnl.pnlCost,
|
|
54852
55304
|
pnlEntries: data.pnl.pnlEntries,
|
|
55305
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
55306
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
55307
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
55308
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
55309
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
55310
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
55311
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
55312
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
55313
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
55314
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54853
55315
|
scheduledAt: data.scheduledAt,
|
|
54854
55316
|
pendingAt: data.pendingAt,
|
|
54855
55317
|
note: data.note,
|
|
@@ -54878,12 +55340,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
|
|
|
54878
55340
|
originalPriceTakeProfit: data.originalPriceTakeProfit,
|
|
54879
55341
|
originalPriceStopLoss: data.originalPriceStopLoss,
|
|
54880
55342
|
originalPriceOpen: data.originalPriceOpen,
|
|
54881
|
-
pnl: data.pnl,
|
|
55343
|
+
pnl: data.signal.pnl,
|
|
55344
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
55345
|
+
peakProfit: data.signal.peakProfit,
|
|
54882
55346
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54883
55347
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54884
55348
|
pnlPriceClose: data.pnl.priceClose,
|
|
54885
55349
|
pnlCost: data.pnl.pnlCost,
|
|
54886
55350
|
pnlEntries: data.pnl.pnlEntries,
|
|
55351
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
55352
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
55353
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
55354
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
55355
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
55356
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
55357
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
55358
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
55359
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
55360
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54887
55361
|
scheduledAt: data.scheduledAt,
|
|
54888
55362
|
pendingAt: data.pendingAt,
|
|
54889
55363
|
note: data.note,
|
|
@@ -54904,12 +55378,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
|
|
|
54904
55378
|
totalEntries: data.totalEntries,
|
|
54905
55379
|
totalPartials: data.totalPartials,
|
|
54906
55380
|
originalPriceOpen: data.originalPriceOpen,
|
|
54907
|
-
pnl: data.pnl,
|
|
55381
|
+
pnl: data.signal.pnl,
|
|
55382
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
55383
|
+
peakProfit: data.signal.peakProfit,
|
|
54908
55384
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54909
55385
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54910
55386
|
pnlPriceClose: data.pnl.priceClose,
|
|
54911
55387
|
pnlCost: data.pnl.pnlCost,
|
|
54912
55388
|
pnlEntries: data.pnl.pnlEntries,
|
|
55389
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
55390
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
55391
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
55392
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
55393
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
55394
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
55395
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
55396
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
55397
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
55398
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54913
55399
|
note: data.note,
|
|
54914
55400
|
createdAt: data.timestamp,
|
|
54915
55401
|
};
|
|
@@ -54928,12 +55414,24 @@ const CREATE_STRATEGY_COMMIT_NOTIFICATION_FN = (data) => {
|
|
|
54928
55414
|
totalEntries: data.totalEntries,
|
|
54929
55415
|
totalPartials: data.totalPartials,
|
|
54930
55416
|
originalPriceOpen: data.originalPriceOpen,
|
|
54931
|
-
pnl: data.pnl,
|
|
55417
|
+
pnl: data.signal.pnl,
|
|
55418
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
55419
|
+
peakProfit: data.signal.peakProfit,
|
|
54932
55420
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54933
55421
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54934
55422
|
pnlPriceClose: data.pnl.priceClose,
|
|
54935
55423
|
pnlCost: data.pnl.pnlCost,
|
|
54936
55424
|
pnlEntries: data.pnl.pnlEntries,
|
|
55425
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
55426
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
55427
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
55428
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
55429
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
55430
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
55431
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
55432
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
55433
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
55434
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54937
55435
|
note: data.note,
|
|
54938
55436
|
createdAt: data.timestamp,
|
|
54939
55437
|
};
|
|
@@ -54958,12 +55456,24 @@ const CREATE_SIGNAL_SYNC_NOTIFICATION_FN = (data) => {
|
|
|
54958
55456
|
exchangeName: data.exchangeName,
|
|
54959
55457
|
signalId: data.signalId,
|
|
54960
55458
|
currentPrice: data.currentPrice,
|
|
54961
|
-
pnl: data.pnl,
|
|
55459
|
+
pnl: data.signal.pnl,
|
|
55460
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
55461
|
+
peakProfit: data.signal.peakProfit,
|
|
54962
55462
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54963
55463
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54964
55464
|
pnlPriceClose: data.pnl.priceClose,
|
|
54965
55465
|
pnlCost: data.pnl.pnlCost,
|
|
54966
55466
|
pnlEntries: data.pnl.pnlEntries,
|
|
55467
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
55468
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
55469
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
55470
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
55471
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
55472
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
55473
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
55474
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
55475
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
55476
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
54967
55477
|
cost: data.cost,
|
|
54968
55478
|
position: data.position,
|
|
54969
55479
|
priceOpen: data.priceOpen,
|
|
@@ -54991,12 +55501,24 @@ const CREATE_SIGNAL_SYNC_NOTIFICATION_FN = (data) => {
|
|
|
54991
55501
|
exchangeName: data.exchangeName,
|
|
54992
55502
|
signalId: data.signalId,
|
|
54993
55503
|
currentPrice: data.currentPrice,
|
|
54994
|
-
pnl: data.pnl,
|
|
55504
|
+
pnl: data.signal.pnl,
|
|
55505
|
+
maxDrawdown: data.signal.maxDrawdown,
|
|
55506
|
+
peakProfit: data.signal.peakProfit,
|
|
54995
55507
|
pnlPercentage: data.pnl.pnlPercentage,
|
|
54996
55508
|
pnlPriceOpen: data.pnl.priceOpen,
|
|
54997
55509
|
pnlPriceClose: data.pnl.priceClose,
|
|
54998
55510
|
pnlCost: data.pnl.pnlCost,
|
|
54999
55511
|
pnlEntries: data.pnl.pnlEntries,
|
|
55512
|
+
peakProfitPriceOpen: data.signal.peakProfit.priceOpen,
|
|
55513
|
+
peakProfitPriceClose: data.signal.peakProfit.priceClose,
|
|
55514
|
+
peakProfitPercentage: data.signal.peakProfit.pnlPercentage,
|
|
55515
|
+
peakProfitCost: data.signal.peakProfit.pnlCost,
|
|
55516
|
+
peakProfitEntries: data.signal.peakProfit.pnlEntries,
|
|
55517
|
+
maxDrawdownPriceOpen: data.signal.maxDrawdown.priceOpen,
|
|
55518
|
+
maxDrawdownPriceClose: data.signal.maxDrawdown.priceClose,
|
|
55519
|
+
maxDrawdownPercentage: data.signal.maxDrawdown.pnlPercentage,
|
|
55520
|
+
maxDrawdownCost: data.signal.maxDrawdown.pnlCost,
|
|
55521
|
+
maxDrawdownEntries: data.signal.maxDrawdown.pnlEntries,
|
|
55000
55522
|
position: data.position,
|
|
55001
55523
|
priceOpen: data.priceOpen,
|
|
55002
55524
|
priceTakeProfit: data.priceTakeProfit,
|
|
@@ -55102,11 +55624,23 @@ const CREATE_SIGNAL_INFO_NOTIFICATION_FN = (data) => ({
|
|
|
55102
55624
|
totalEntries: data.data.totalEntries,
|
|
55103
55625
|
totalPartials: data.data.totalPartials,
|
|
55104
55626
|
pnl: data.data.pnl,
|
|
55627
|
+
maxDrawdown: data.data.maxDrawdown,
|
|
55628
|
+
peakProfit: data.data.peakProfit,
|
|
55105
55629
|
pnlPercentage: data.data.pnl.pnlPercentage,
|
|
55106
55630
|
pnlPriceOpen: data.data.pnl.priceOpen,
|
|
55107
55631
|
pnlPriceClose: data.data.pnl.priceClose,
|
|
55108
55632
|
pnlCost: data.data.pnl.pnlCost,
|
|
55109
55633
|
pnlEntries: data.data.pnl.pnlEntries,
|
|
55634
|
+
peakProfitPriceOpen: data.data.peakProfit.priceOpen,
|
|
55635
|
+
peakProfitPriceClose: data.data.peakProfit.priceClose,
|
|
55636
|
+
peakProfitPercentage: data.data.peakProfit.pnlPercentage,
|
|
55637
|
+
peakProfitCost: data.data.peakProfit.pnlCost,
|
|
55638
|
+
peakProfitEntries: data.data.peakProfit.pnlEntries,
|
|
55639
|
+
maxDrawdownPriceOpen: data.data.maxDrawdown.priceOpen,
|
|
55640
|
+
maxDrawdownPriceClose: data.data.maxDrawdown.priceClose,
|
|
55641
|
+
maxDrawdownPercentage: data.data.maxDrawdown.pnlPercentage,
|
|
55642
|
+
maxDrawdownCost: data.data.maxDrawdown.pnlCost,
|
|
55643
|
+
maxDrawdownEntries: data.data.maxDrawdown.pnlEntries,
|
|
55110
55644
|
note: data.note,
|
|
55111
55645
|
notificationId: data.notificationId,
|
|
55112
55646
|
scheduledAt: data.data.scheduledAt,
|