backtest-kit 2.0.11 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.cjs +423 -90
- package/build/index.mjs +421 -89
- package/package.json +1 -1
- package/types.d.ts +187 -33
package/build/index.mjs
CHANGED
|
@@ -4389,6 +4389,7 @@ class ClientStrategy {
|
|
|
4389
4389
|
this._lastSignalTimestamp = null;
|
|
4390
4390
|
this._scheduledSignal = null;
|
|
4391
4391
|
this._cancelledSignal = null;
|
|
4392
|
+
this._closedSignal = null;
|
|
4392
4393
|
/**
|
|
4393
4394
|
* Initializes strategy state by loading persisted signal from disk.
|
|
4394
4395
|
*
|
|
@@ -4665,6 +4666,41 @@ class ClientStrategy {
|
|
|
4665
4666
|
reason: "user",
|
|
4666
4667
|
cancelId: cancelledSignal.cancelId,
|
|
4667
4668
|
};
|
|
4669
|
+
await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, result, currentTime, this.params.execution.context.backtest);
|
|
4670
|
+
return result;
|
|
4671
|
+
}
|
|
4672
|
+
// Check if pending signal was closed - emit closed event once
|
|
4673
|
+
if (this._closedSignal) {
|
|
4674
|
+
const currentPrice = await this.params.exchange.getAveragePrice(this.params.execution.context.symbol);
|
|
4675
|
+
const closedSignal = this._closedSignal;
|
|
4676
|
+
this._closedSignal = null; // Clear after emitting
|
|
4677
|
+
this.params.logger.info("ClientStrategy tick: pending signal was closed", {
|
|
4678
|
+
symbol: this.params.execution.context.symbol,
|
|
4679
|
+
signalId: closedSignal.id,
|
|
4680
|
+
});
|
|
4681
|
+
// Call onClose callback
|
|
4682
|
+
await CALL_CLOSE_CALLBACKS_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, currentTime, this.params.execution.context.backtest);
|
|
4683
|
+
// КРИТИЧНО: Очищаем состояние ClientPartial при закрытии позиции
|
|
4684
|
+
await CALL_PARTIAL_CLEAR_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, currentTime, this.params.execution.context.backtest);
|
|
4685
|
+
// КРИТИЧНО: Очищаем состояние ClientBreakeven при закрытии позиции
|
|
4686
|
+
await CALL_BREAKEVEN_CLEAR_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, currentTime, this.params.execution.context.backtest);
|
|
4687
|
+
await CALL_RISK_REMOVE_SIGNAL_FN(this, this.params.execution.context.symbol, currentTime, this.params.execution.context.backtest);
|
|
4688
|
+
const pnl = toProfitLossDto(closedSignal, currentPrice);
|
|
4689
|
+
const result = {
|
|
4690
|
+
action: "closed",
|
|
4691
|
+
signal: TO_PUBLIC_SIGNAL(closedSignal),
|
|
4692
|
+
currentPrice,
|
|
4693
|
+
closeReason: "closed",
|
|
4694
|
+
closeTimestamp: currentTime,
|
|
4695
|
+
pnl,
|
|
4696
|
+
strategyName: this.params.method.context.strategyName,
|
|
4697
|
+
exchangeName: this.params.method.context.exchangeName,
|
|
4698
|
+
frameName: this.params.method.context.frameName,
|
|
4699
|
+
symbol: this.params.execution.context.symbol,
|
|
4700
|
+
backtest: this.params.execution.context.backtest,
|
|
4701
|
+
closeId: closedSignal.closeId,
|
|
4702
|
+
};
|
|
4703
|
+
await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, result, currentTime, this.params.execution.context.backtest);
|
|
4668
4704
|
return result;
|
|
4669
4705
|
}
|
|
4670
4706
|
// Monitor scheduled signal
|
|
@@ -4778,8 +4814,40 @@ class ClientStrategy {
|
|
|
4778
4814
|
reason: "user",
|
|
4779
4815
|
cancelId: cancelledSignal.cancelId,
|
|
4780
4816
|
};
|
|
4817
|
+
await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, cancelledResult, closeTimestamp, this.params.execution.context.backtest);
|
|
4781
4818
|
return cancelledResult;
|
|
4782
4819
|
}
|
|
4820
|
+
// If signal was closed - return closed
|
|
4821
|
+
if (this._closedSignal) {
|
|
4822
|
+
this.params.logger.debug("ClientStrategy backtest: pending signal was closed");
|
|
4823
|
+
const currentPrice = await this.params.exchange.getAveragePrice(symbol);
|
|
4824
|
+
const closedSignal = this._closedSignal;
|
|
4825
|
+
this._closedSignal = null; // Clear after using
|
|
4826
|
+
const closeTimestamp = this.params.execution.context.when.getTime();
|
|
4827
|
+
await CALL_CLOSE_CALLBACKS_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
|
|
4828
|
+
// КРИТИЧНО: Очищаем состояние ClientPartial при закрытии позиции
|
|
4829
|
+
await CALL_PARTIAL_CLEAR_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
|
|
4830
|
+
// КРИТИЧНО: Очищаем состояние ClientBreakeven при закрытии позиции
|
|
4831
|
+
await CALL_BREAKEVEN_CLEAR_FN(this, this.params.execution.context.symbol, closedSignal, currentPrice, closeTimestamp, this.params.execution.context.backtest);
|
|
4832
|
+
await CALL_RISK_REMOVE_SIGNAL_FN(this, this.params.execution.context.symbol, closeTimestamp, this.params.execution.context.backtest);
|
|
4833
|
+
const pnl = toProfitLossDto(closedSignal, currentPrice);
|
|
4834
|
+
const closedResult = {
|
|
4835
|
+
action: "closed",
|
|
4836
|
+
signal: TO_PUBLIC_SIGNAL(closedSignal),
|
|
4837
|
+
currentPrice,
|
|
4838
|
+
closeReason: "closed",
|
|
4839
|
+
closeTimestamp: closeTimestamp,
|
|
4840
|
+
pnl,
|
|
4841
|
+
strategyName: this.params.method.context.strategyName,
|
|
4842
|
+
exchangeName: this.params.method.context.exchangeName,
|
|
4843
|
+
frameName: this.params.method.context.frameName,
|
|
4844
|
+
symbol: this.params.execution.context.symbol,
|
|
4845
|
+
backtest: true,
|
|
4846
|
+
closeId: closedSignal.closeId,
|
|
4847
|
+
};
|
|
4848
|
+
await CALL_TICK_CALLBACKS_FN(this, this.params.execution.context.symbol, closedResult, closeTimestamp, this.params.execution.context.backtest);
|
|
4849
|
+
return closedResult;
|
|
4850
|
+
}
|
|
4783
4851
|
if (!this._pendingSignal && !this._scheduledSignal) {
|
|
4784
4852
|
throw new Error("ClientStrategy backtest: no pending or scheduled signal");
|
|
4785
4853
|
}
|
|
@@ -4906,12 +4974,12 @@ class ClientStrategy {
|
|
|
4906
4974
|
* @example
|
|
4907
4975
|
* ```typescript
|
|
4908
4976
|
* // In Live.background() cancellation
|
|
4909
|
-
* await strategy.
|
|
4977
|
+
* await strategy.stopStrategy();
|
|
4910
4978
|
* // Existing signal will continue until natural close
|
|
4911
4979
|
* ```
|
|
4912
4980
|
*/
|
|
4913
|
-
async
|
|
4914
|
-
this.params.logger.debug("ClientStrategy
|
|
4981
|
+
async stopStrategy(symbol, backtest) {
|
|
4982
|
+
this.params.logger.debug("ClientStrategy stopStrategy", {
|
|
4915
4983
|
symbol,
|
|
4916
4984
|
hasPendingSignal: this._pendingSignal !== null,
|
|
4917
4985
|
hasScheduledSignal: this._scheduledSignal !== null,
|
|
@@ -4944,12 +5012,12 @@ class ClientStrategy {
|
|
|
4944
5012
|
* @example
|
|
4945
5013
|
* ```typescript
|
|
4946
5014
|
* // Cancel scheduled signal without stopping strategy
|
|
4947
|
-
* await strategy.
|
|
5015
|
+
* await strategy.cancelScheduled("BTCUSDT", "my-strategy", false);
|
|
4948
5016
|
* // Strategy continues, can generate new signals
|
|
4949
5017
|
* ```
|
|
4950
5018
|
*/
|
|
4951
|
-
async
|
|
4952
|
-
this.params.logger.debug("ClientStrategy
|
|
5019
|
+
async cancelScheduled(symbol, backtest, cancelId) {
|
|
5020
|
+
this.params.logger.debug("ClientStrategy cancelScheduled", {
|
|
4953
5021
|
symbol,
|
|
4954
5022
|
hasScheduledSignal: this._scheduledSignal !== null,
|
|
4955
5023
|
cancelId,
|
|
@@ -4966,6 +5034,45 @@ class ClientStrategy {
|
|
|
4966
5034
|
}
|
|
4967
5035
|
await PersistScheduleAdapter.writeScheduleData(this._scheduledSignal, symbol, this.params.method.context.strategyName, this.params.method.context.exchangeName);
|
|
4968
5036
|
}
|
|
5037
|
+
/**
|
|
5038
|
+
* Closes the pending signal without stopping the strategy.
|
|
5039
|
+
*
|
|
5040
|
+
* Clears the pending signal (active position).
|
|
5041
|
+
* Does NOT affect scheduled signals or strategy operation.
|
|
5042
|
+
* Does NOT set stop flag - strategy can continue generating new signals.
|
|
5043
|
+
*
|
|
5044
|
+
* Use case: Close an active position that is no longer desired without stopping the entire strategy.
|
|
5045
|
+
*
|
|
5046
|
+
* @param symbol - Trading pair symbol (e.g., "BTCUSDT")
|
|
5047
|
+
* @param backtest - Whether running in backtest mode
|
|
5048
|
+
* @param closeId - Optional identifier for this close operation
|
|
5049
|
+
* @returns Promise that resolves when pending signal is cleared
|
|
5050
|
+
*
|
|
5051
|
+
* @example
|
|
5052
|
+
* ```typescript
|
|
5053
|
+
* // Close pending signal without stopping strategy
|
|
5054
|
+
* await strategy.closePending("BTCUSDT", false, "user-close-123");
|
|
5055
|
+
* // Strategy continues, can generate new signals
|
|
5056
|
+
* ```
|
|
5057
|
+
*/
|
|
5058
|
+
async closePending(symbol, backtest, closeId) {
|
|
5059
|
+
this.params.logger.debug("ClientStrategy closePending", {
|
|
5060
|
+
symbol,
|
|
5061
|
+
hasPendingSignal: this._pendingSignal !== null,
|
|
5062
|
+
closeId,
|
|
5063
|
+
});
|
|
5064
|
+
// Save closed signal for next tick to emit closed event
|
|
5065
|
+
if (this._pendingSignal) {
|
|
5066
|
+
this._closedSignal = Object.assign({}, this._pendingSignal, {
|
|
5067
|
+
closeId,
|
|
5068
|
+
});
|
|
5069
|
+
this._pendingSignal = null;
|
|
5070
|
+
}
|
|
5071
|
+
if (backtest) {
|
|
5072
|
+
return;
|
|
5073
|
+
}
|
|
5074
|
+
await PersistSignalAdapter.writeSignalData(this._pendingSignal, symbol, this.params.strategyName, this.params.exchangeName);
|
|
5075
|
+
}
|
|
4969
5076
|
/**
|
|
4970
5077
|
* Executes partial close at profit level (moving toward TP).
|
|
4971
5078
|
*
|
|
@@ -6418,7 +6525,7 @@ class StrategyConnectionService {
|
|
|
6418
6525
|
/**
|
|
6419
6526
|
* Stops the specified strategy from generating new signals.
|
|
6420
6527
|
*
|
|
6421
|
-
* Delegates to ClientStrategy.
|
|
6528
|
+
* Delegates to ClientStrategy.stopStrategy() which sets internal flag to prevent
|
|
6422
6529
|
* getSignal from being called on subsequent ticks.
|
|
6423
6530
|
*
|
|
6424
6531
|
* @param backtest - Whether running in backtest mode
|
|
@@ -6426,13 +6533,13 @@ class StrategyConnectionService {
|
|
|
6426
6533
|
* @param ctx - Context with strategyName, exchangeName, frameName
|
|
6427
6534
|
* @returns Promise that resolves when stop flag is set
|
|
6428
6535
|
*/
|
|
6429
|
-
this.
|
|
6430
|
-
this.loggerService.log("strategyConnectionService
|
|
6536
|
+
this.stopStrategy = async (backtest, symbol, context) => {
|
|
6537
|
+
this.loggerService.log("strategyConnectionService stopStrategy", {
|
|
6431
6538
|
symbol,
|
|
6432
6539
|
context,
|
|
6433
6540
|
});
|
|
6434
6541
|
const strategy = this.getStrategy(symbol, context.strategyName, context.exchangeName, context.frameName, backtest);
|
|
6435
|
-
await strategy.
|
|
6542
|
+
await strategy.stopStrategy(symbol, backtest);
|
|
6436
6543
|
};
|
|
6437
6544
|
/**
|
|
6438
6545
|
* Disposes the ClientStrategy instance for the given context.
|
|
@@ -6484,7 +6591,7 @@ class StrategyConnectionService {
|
|
|
6484
6591
|
/**
|
|
6485
6592
|
* Cancels the scheduled signal for the specified strategy.
|
|
6486
6593
|
*
|
|
6487
|
-
* Delegates to ClientStrategy.
|
|
6594
|
+
* Delegates to ClientStrategy.cancelScheduled() which clears the scheduled signal
|
|
6488
6595
|
* without stopping the strategy or affecting pending signals.
|
|
6489
6596
|
*
|
|
6490
6597
|
* Note: Cancelled event will be emitted on next tick() call when strategy
|
|
@@ -6496,14 +6603,39 @@ class StrategyConnectionService {
|
|
|
6496
6603
|
* @param cancelId - Optional cancellation ID for user-initiated cancellations
|
|
6497
6604
|
* @returns Promise that resolves when scheduled signal is cancelled
|
|
6498
6605
|
*/
|
|
6499
|
-
this.
|
|
6500
|
-
this.loggerService.log("strategyConnectionService
|
|
6606
|
+
this.cancelScheduled = async (backtest, symbol, context, cancelId) => {
|
|
6607
|
+
this.loggerService.log("strategyConnectionService cancelScheduled", {
|
|
6501
6608
|
symbol,
|
|
6502
6609
|
context,
|
|
6503
6610
|
cancelId,
|
|
6504
6611
|
});
|
|
6505
6612
|
const strategy = this.getStrategy(symbol, context.strategyName, context.exchangeName, context.frameName, backtest);
|
|
6506
|
-
await strategy.
|
|
6613
|
+
await strategy.cancelScheduled(symbol, backtest, cancelId);
|
|
6614
|
+
};
|
|
6615
|
+
/**
|
|
6616
|
+
* Closes the pending signal without stopping the strategy.
|
|
6617
|
+
*
|
|
6618
|
+
* Clears the pending signal (active position).
|
|
6619
|
+
* Does NOT affect scheduled signals or strategy operation.
|
|
6620
|
+
* Does NOT set stop flag - strategy can continue generating new signals.
|
|
6621
|
+
*
|
|
6622
|
+
* Note: Closed event will be emitted on next tick() call when strategy
|
|
6623
|
+
* detects the pending signal was closed.
|
|
6624
|
+
*
|
|
6625
|
+
* @param backtest - Whether running in backtest mode
|
|
6626
|
+
* @param symbol - Trading pair symbol
|
|
6627
|
+
* @param context - Context with strategyName, exchangeName, frameName
|
|
6628
|
+
* @param closeId - Optional close ID for user-initiated closes
|
|
6629
|
+
* @returns Promise that resolves when pending signal is closed
|
|
6630
|
+
*/
|
|
6631
|
+
this.closePending = async (backtest, symbol, context, closeId) => {
|
|
6632
|
+
this.loggerService.log("strategyConnectionService closePending", {
|
|
6633
|
+
symbol,
|
|
6634
|
+
context,
|
|
6635
|
+
closeId,
|
|
6636
|
+
});
|
|
6637
|
+
const strategy = this.getStrategy(symbol, context.strategyName, context.exchangeName, context.frameName, backtest);
|
|
6638
|
+
await strategy.closePending(symbol, backtest, closeId);
|
|
6507
6639
|
};
|
|
6508
6640
|
/**
|
|
6509
6641
|
* Executes partial close at profit level (moving toward TP).
|
|
@@ -9690,19 +9822,19 @@ class StrategyCoreService {
|
|
|
9690
9822
|
* @param ctx - Context with strategyName, exchangeName, frameName
|
|
9691
9823
|
* @returns Promise that resolves when stop flag is set
|
|
9692
9824
|
*/
|
|
9693
|
-
this.
|
|
9694
|
-
this.loggerService.log("strategyCoreService
|
|
9825
|
+
this.stopStrategy = async (backtest, symbol, context) => {
|
|
9826
|
+
this.loggerService.log("strategyCoreService stopStrategy", {
|
|
9695
9827
|
symbol,
|
|
9696
9828
|
context,
|
|
9697
9829
|
backtest,
|
|
9698
9830
|
});
|
|
9699
9831
|
await this.validate(context);
|
|
9700
|
-
return await this.strategyConnectionService.
|
|
9832
|
+
return await this.strategyConnectionService.stopStrategy(backtest, symbol, context);
|
|
9701
9833
|
};
|
|
9702
9834
|
/**
|
|
9703
9835
|
* Cancels the scheduled signal without stopping the strategy.
|
|
9704
9836
|
*
|
|
9705
|
-
* Delegates to StrategyConnectionService.
|
|
9837
|
+
* Delegates to StrategyConnectionService.cancelScheduled() to clear scheduled signal
|
|
9706
9838
|
* and emit cancelled event through emitters.
|
|
9707
9839
|
* Does not require execution context.
|
|
9708
9840
|
*
|
|
@@ -9712,15 +9844,42 @@ class StrategyCoreService {
|
|
|
9712
9844
|
* @param cancelId - Optional cancellation ID for user-initiated cancellations
|
|
9713
9845
|
* @returns Promise that resolves when scheduled signal is cancelled
|
|
9714
9846
|
*/
|
|
9715
|
-
this.
|
|
9716
|
-
this.loggerService.log("strategyCoreService
|
|
9847
|
+
this.cancelScheduled = async (backtest, symbol, context, cancelId) => {
|
|
9848
|
+
this.loggerService.log("strategyCoreService cancelScheduled", {
|
|
9717
9849
|
symbol,
|
|
9718
9850
|
context,
|
|
9719
9851
|
backtest,
|
|
9720
9852
|
cancelId,
|
|
9721
9853
|
});
|
|
9722
9854
|
await this.validate(context);
|
|
9723
|
-
return await this.strategyConnectionService.
|
|
9855
|
+
return await this.strategyConnectionService.cancelScheduled(backtest, symbol, context, cancelId);
|
|
9856
|
+
};
|
|
9857
|
+
/**
|
|
9858
|
+
* Closes the pending signal without stopping the strategy.
|
|
9859
|
+
*
|
|
9860
|
+
* Clears the pending signal (active position).
|
|
9861
|
+
* Does NOT affect scheduled signals or strategy operation.
|
|
9862
|
+
* Does NOT set stop flag - strategy can continue generating new signals.
|
|
9863
|
+
*
|
|
9864
|
+
* Delegates to StrategyConnectionService.closePending() to clear pending signal
|
|
9865
|
+
* and emit closed event through emitters.
|
|
9866
|
+
* Does not require execution context.
|
|
9867
|
+
*
|
|
9868
|
+
* @param backtest - Whether running in backtest mode
|
|
9869
|
+
* @param symbol - Trading pair symbol
|
|
9870
|
+
* @param context - Context with strategyName, exchangeName, frameName
|
|
9871
|
+
* @param closeId - Optional close ID for user-initiated closes
|
|
9872
|
+
* @returns Promise that resolves when pending signal is closed
|
|
9873
|
+
*/
|
|
9874
|
+
this.closePending = async (backtest, symbol, context, closeId) => {
|
|
9875
|
+
this.loggerService.log("strategyCoreService closePending", {
|
|
9876
|
+
symbol,
|
|
9877
|
+
context,
|
|
9878
|
+
backtest,
|
|
9879
|
+
closeId,
|
|
9880
|
+
});
|
|
9881
|
+
await this.validate(context);
|
|
9882
|
+
return await this.strategyConnectionService.closePending(backtest, symbol, context, closeId);
|
|
9724
9883
|
};
|
|
9725
9884
|
/**
|
|
9726
9885
|
* Disposes the ClientStrategy instance for the given context.
|
|
@@ -25006,7 +25165,8 @@ async function getOrderBook(symbol, depth) {
|
|
|
25006
25165
|
return await bt.exchangeConnectionService.getOrderBook(symbol, depth);
|
|
25007
25166
|
}
|
|
25008
25167
|
|
|
25009
|
-
const
|
|
25168
|
+
const CANCEL_SCHEDULED_METHOD_NAME = "strategy.commitCancelScheduled";
|
|
25169
|
+
const CLOSE_PENDING_METHOD_NAME = "strategy.commitClosePending";
|
|
25010
25170
|
const PARTIAL_PROFIT_METHOD_NAME = "strategy.commitPartialProfit";
|
|
25011
25171
|
const PARTIAL_LOSS_METHOD_NAME = "strategy.commitPartialLoss";
|
|
25012
25172
|
const TRAILING_STOP_METHOD_NAME = "strategy.commitTrailingStop";
|
|
@@ -25028,26 +25188,62 @@ const BREAKEVEN_METHOD_NAME = "strategy.commitBreakeven";
|
|
|
25028
25188
|
*
|
|
25029
25189
|
* @example
|
|
25030
25190
|
* ```typescript
|
|
25031
|
-
* import {
|
|
25191
|
+
* import { commitCancelScheduled } from "backtest-kit";
|
|
25032
25192
|
*
|
|
25033
25193
|
* // Cancel scheduled signal with custom ID
|
|
25034
|
-
* await
|
|
25194
|
+
* await commitCancelScheduled("BTCUSDT", "manual-cancel-001");
|
|
25035
25195
|
* ```
|
|
25036
25196
|
*/
|
|
25037
|
-
async function
|
|
25038
|
-
bt.loggerService.info(
|
|
25197
|
+
async function commitCancelScheduled(symbol, cancelId) {
|
|
25198
|
+
bt.loggerService.info(CANCEL_SCHEDULED_METHOD_NAME, {
|
|
25039
25199
|
symbol,
|
|
25040
25200
|
cancelId,
|
|
25041
25201
|
});
|
|
25042
25202
|
if (!ExecutionContextService.hasContext()) {
|
|
25043
|
-
throw new Error("
|
|
25203
|
+
throw new Error("commitCancelScheduled requires an execution context");
|
|
25044
25204
|
}
|
|
25045
25205
|
if (!MethodContextService.hasContext()) {
|
|
25046
|
-
throw new Error("
|
|
25206
|
+
throw new Error("commitCancelScheduled requires a method context");
|
|
25047
25207
|
}
|
|
25048
25208
|
const { backtest: isBacktest } = bt.executionContextService.context;
|
|
25049
25209
|
const { exchangeName, frameName, strategyName } = bt.methodContextService.context;
|
|
25050
|
-
await bt.strategyCoreService.
|
|
25210
|
+
await bt.strategyCoreService.cancelScheduled(isBacktest, symbol, { exchangeName, frameName, strategyName }, cancelId);
|
|
25211
|
+
}
|
|
25212
|
+
/**
|
|
25213
|
+
* Closes the pending signal without stopping the strategy.
|
|
25214
|
+
*
|
|
25215
|
+
* Clears the pending signal (active position).
|
|
25216
|
+
* Does NOT affect scheduled signals or strategy operation.
|
|
25217
|
+
* Does NOT set stop flag - strategy can continue generating new signals.
|
|
25218
|
+
*
|
|
25219
|
+
* Automatically detects backtest/live mode from execution context.
|
|
25220
|
+
*
|
|
25221
|
+
* @param symbol - Trading pair symbol
|
|
25222
|
+
* @param closeId - Optional close ID for tracking user-initiated closes
|
|
25223
|
+
* @returns Promise that resolves when pending signal is closed
|
|
25224
|
+
*
|
|
25225
|
+
* @example
|
|
25226
|
+
* ```typescript
|
|
25227
|
+
* import { commitClosePending } from "backtest-kit";
|
|
25228
|
+
*
|
|
25229
|
+
* // Close pending signal with custom ID
|
|
25230
|
+
* await commitClosePending("BTCUSDT", "manual-close-001");
|
|
25231
|
+
* ```
|
|
25232
|
+
*/
|
|
25233
|
+
async function commitClosePending(symbol, closeId) {
|
|
25234
|
+
bt.loggerService.info(CLOSE_PENDING_METHOD_NAME, {
|
|
25235
|
+
symbol,
|
|
25236
|
+
closeId,
|
|
25237
|
+
});
|
|
25238
|
+
if (!ExecutionContextService.hasContext()) {
|
|
25239
|
+
throw new Error("commitClosePending requires an execution context");
|
|
25240
|
+
}
|
|
25241
|
+
if (!MethodContextService.hasContext()) {
|
|
25242
|
+
throw new Error("commitClosePending requires a method context");
|
|
25243
|
+
}
|
|
25244
|
+
const { backtest: isBacktest } = bt.executionContextService.context;
|
|
25245
|
+
const { exchangeName, frameName, strategyName } = bt.methodContextService.context;
|
|
25246
|
+
await bt.strategyCoreService.closePending(isBacktest, symbol, { exchangeName, frameName, strategyName }, closeId);
|
|
25051
25247
|
}
|
|
25052
25248
|
/**
|
|
25053
25249
|
* Executes partial close at profit level (moving toward TP).
|
|
@@ -25294,7 +25490,7 @@ async function commitBreakeven(symbol) {
|
|
|
25294
25490
|
return await bt.strategyCoreService.breakeven(isBacktest, symbol, currentPrice, { exchangeName, frameName, strategyName });
|
|
25295
25491
|
}
|
|
25296
25492
|
|
|
25297
|
-
const
|
|
25493
|
+
const STOP_STRATEGY_METHOD_NAME = "control.stopStrategy";
|
|
25298
25494
|
/**
|
|
25299
25495
|
* Stops the strategy from generating new signals.
|
|
25300
25496
|
*
|
|
@@ -25316,8 +25512,8 @@ const STOP_METHOD_NAME = "control.stop";
|
|
|
25316
25512
|
* await stop("BTCUSDT", "my-strategy");
|
|
25317
25513
|
* ```
|
|
25318
25514
|
*/
|
|
25319
|
-
async function
|
|
25320
|
-
bt.loggerService.info(
|
|
25515
|
+
async function stopStrategy(symbol) {
|
|
25516
|
+
bt.loggerService.info(STOP_STRATEGY_METHOD_NAME, {
|
|
25321
25517
|
symbol,
|
|
25322
25518
|
});
|
|
25323
25519
|
if (!ExecutionContextService.hasContext()) {
|
|
@@ -25328,7 +25524,7 @@ async function stop(symbol) {
|
|
|
25328
25524
|
}
|
|
25329
25525
|
const { backtest: isBacktest } = bt.executionContextService.context;
|
|
25330
25526
|
const { exchangeName, frameName, strategyName } = bt.methodContextService.context;
|
|
25331
|
-
await bt.strategyCoreService.
|
|
25527
|
+
await bt.strategyCoreService.stopStrategy(isBacktest, symbol, {
|
|
25332
25528
|
exchangeName,
|
|
25333
25529
|
frameName,
|
|
25334
25530
|
strategyName,
|
|
@@ -27715,7 +27911,8 @@ const BACKTEST_METHOD_NAME_GET_PENDING_SIGNAL = "BacktestUtils.getPendingSignal"
|
|
|
27715
27911
|
const BACKTEST_METHOD_NAME_GET_SCHEDULED_SIGNAL = "BacktestUtils.getScheduledSignal";
|
|
27716
27912
|
const BACKTEST_METHOD_NAME_GET_BREAKEVEN = "BacktestUtils.getBreakeven";
|
|
27717
27913
|
const BACKTEST_METHOD_NAME_BREAKEVEN = "Backtest.commitBreakeven";
|
|
27718
|
-
const
|
|
27914
|
+
const BACKTEST_METHOD_NAME_CANCEL_SCHEDULED = "Backtest.commitCancelScheduled";
|
|
27915
|
+
const BACKTEST_METHOD_NAME_CLOSE_PENDING = "Backtest.commitClosePending";
|
|
27719
27916
|
const BACKTEST_METHOD_NAME_PARTIAL_PROFIT = "BacktestUtils.commitPartialProfit";
|
|
27720
27917
|
const BACKTEST_METHOD_NAME_PARTIAL_LOSS = "BacktestUtils.commitPartialLoss";
|
|
27721
27918
|
const BACKTEST_METHOD_NAME_TRAILING_STOP = "BacktestUtils.commitTrailingStop";
|
|
@@ -27957,7 +28154,7 @@ class BacktestInstance {
|
|
|
27957
28154
|
}
|
|
27958
28155
|
this.task(symbol, context).catch((error) => exitEmitter.next(new Error(getErrorMessage(error))));
|
|
27959
28156
|
return () => {
|
|
27960
|
-
bt.strategyCoreService.
|
|
28157
|
+
bt.strategyCoreService.stopStrategy(true, symbol, {
|
|
27961
28158
|
strategyName: context.strategyName,
|
|
27962
28159
|
exchangeName: context.exchangeName,
|
|
27963
28160
|
frameName: context.frameName,
|
|
@@ -28225,7 +28422,7 @@ class BacktestUtils {
|
|
|
28225
28422
|
actions &&
|
|
28226
28423
|
actions.forEach((actionName) => bt.actionValidationService.validate(actionName, BACKTEST_METHOD_NAME_STOP));
|
|
28227
28424
|
}
|
|
28228
|
-
await bt.strategyCoreService.
|
|
28425
|
+
await bt.strategyCoreService.stopStrategy(true, symbol, context);
|
|
28229
28426
|
};
|
|
28230
28427
|
/**
|
|
28231
28428
|
* Cancels the scheduled signal without stopping the strategy.
|
|
@@ -28250,24 +28447,65 @@ class BacktestUtils {
|
|
|
28250
28447
|
* }, "manual-cancel-001");
|
|
28251
28448
|
* ```
|
|
28252
28449
|
*/
|
|
28253
|
-
this.
|
|
28254
|
-
bt.loggerService.info(
|
|
28450
|
+
this.commitCancelScheduled = async (symbol, context, cancelId) => {
|
|
28451
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_CANCEL_SCHEDULED, {
|
|
28255
28452
|
symbol,
|
|
28256
28453
|
context,
|
|
28257
28454
|
cancelId,
|
|
28258
28455
|
});
|
|
28259
|
-
bt.strategyValidationService.validate(context.strategyName,
|
|
28260
|
-
bt.exchangeValidationService.validate(context.exchangeName,
|
|
28456
|
+
bt.strategyValidationService.validate(context.strategyName, BACKTEST_METHOD_NAME_CANCEL_SCHEDULED);
|
|
28457
|
+
bt.exchangeValidationService.validate(context.exchangeName, BACKTEST_METHOD_NAME_CANCEL_SCHEDULED);
|
|
28261
28458
|
{
|
|
28262
28459
|
const { riskName, riskList, actions } = bt.strategySchemaService.get(context.strategyName);
|
|
28263
28460
|
riskName &&
|
|
28264
|
-
bt.riskValidationService.validate(riskName,
|
|
28461
|
+
bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_CANCEL_SCHEDULED);
|
|
28265
28462
|
riskList &&
|
|
28266
|
-
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName,
|
|
28463
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_CANCEL_SCHEDULED));
|
|
28267
28464
|
actions &&
|
|
28268
|
-
actions.forEach((actionName) => bt.actionValidationService.validate(actionName,
|
|
28465
|
+
actions.forEach((actionName) => bt.actionValidationService.validate(actionName, BACKTEST_METHOD_NAME_CANCEL_SCHEDULED));
|
|
28269
28466
|
}
|
|
28270
|
-
await bt.strategyCoreService.
|
|
28467
|
+
await bt.strategyCoreService.cancelScheduled(true, symbol, context, cancelId);
|
|
28468
|
+
};
|
|
28469
|
+
/**
|
|
28470
|
+
* Closes the pending signal without stopping the strategy.
|
|
28471
|
+
*
|
|
28472
|
+
* Clears the pending signal (active position).
|
|
28473
|
+
* Does NOT affect scheduled signals or strategy operation.
|
|
28474
|
+
* Does NOT set stop flag - strategy can continue generating new signals.
|
|
28475
|
+
*
|
|
28476
|
+
* @param symbol - Trading pair symbol
|
|
28477
|
+
* @param context - Execution context with strategyName, exchangeName, and frameName
|
|
28478
|
+
* @param closeId - Optional close ID for user-initiated closes
|
|
28479
|
+
* @returns Promise that resolves when pending signal is closed
|
|
28480
|
+
*
|
|
28481
|
+
* @example
|
|
28482
|
+
* ```typescript
|
|
28483
|
+
* // Close pending signal with custom ID
|
|
28484
|
+
* await Backtest.commitClose("BTCUSDT", {
|
|
28485
|
+
* exchangeName: "binance",
|
|
28486
|
+
* strategyName: "my-strategy",
|
|
28487
|
+
* frameName: "1m"
|
|
28488
|
+
* }, "manual-close-001");
|
|
28489
|
+
* ```
|
|
28490
|
+
*/
|
|
28491
|
+
this.commitClosePending = async (symbol, context, closeId) => {
|
|
28492
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_CLOSE_PENDING, {
|
|
28493
|
+
symbol,
|
|
28494
|
+
context,
|
|
28495
|
+
closeId,
|
|
28496
|
+
});
|
|
28497
|
+
bt.strategyValidationService.validate(context.strategyName, BACKTEST_METHOD_NAME_CLOSE_PENDING);
|
|
28498
|
+
bt.exchangeValidationService.validate(context.exchangeName, BACKTEST_METHOD_NAME_CLOSE_PENDING);
|
|
28499
|
+
{
|
|
28500
|
+
const { riskName, riskList, actions } = bt.strategySchemaService.get(context.strategyName);
|
|
28501
|
+
riskName &&
|
|
28502
|
+
bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_CLOSE_PENDING);
|
|
28503
|
+
riskList &&
|
|
28504
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_CLOSE_PENDING));
|
|
28505
|
+
actions &&
|
|
28506
|
+
actions.forEach((actionName) => bt.actionValidationService.validate(actionName, BACKTEST_METHOD_NAME_CLOSE_PENDING));
|
|
28507
|
+
}
|
|
28508
|
+
await bt.strategyCoreService.closePending(true, symbol, context, closeId);
|
|
28271
28509
|
};
|
|
28272
28510
|
/**
|
|
28273
28511
|
* Executes partial close at profit level (moving toward TP).
|
|
@@ -28704,7 +28942,8 @@ const LIVE_METHOD_NAME_GET_PENDING_SIGNAL = "LiveUtils.getPendingSignal";
|
|
|
28704
28942
|
const LIVE_METHOD_NAME_GET_SCHEDULED_SIGNAL = "LiveUtils.getScheduledSignal";
|
|
28705
28943
|
const LIVE_METHOD_NAME_GET_BREAKEVEN = "LiveUtils.getBreakeven";
|
|
28706
28944
|
const LIVE_METHOD_NAME_BREAKEVEN = "Live.commitBreakeven";
|
|
28707
|
-
const
|
|
28945
|
+
const LIVE_METHOD_NAME_CANCEL_SCHEDULED = "Live.cancelScheduled";
|
|
28946
|
+
const LIVE_METHOD_NAME_CLOSE_PENDING = "Live.closePending";
|
|
28708
28947
|
const LIVE_METHOD_NAME_PARTIAL_PROFIT = "LiveUtils.commitPartialProfit";
|
|
28709
28948
|
const LIVE_METHOD_NAME_PARTIAL_LOSS = "LiveUtils.commitPartialLoss";
|
|
28710
28949
|
const LIVE_METHOD_NAME_TRAILING_STOP = "LiveUtils.commitTrailingStop";
|
|
@@ -28909,7 +29148,7 @@ class LiveInstance {
|
|
|
28909
29148
|
}
|
|
28910
29149
|
this.task(symbol, context).catch((error) => exitEmitter.next(new Error(getErrorMessage(error))));
|
|
28911
29150
|
return () => {
|
|
28912
|
-
bt.strategyCoreService.
|
|
29151
|
+
bt.strategyCoreService.stopStrategy(false, symbol, {
|
|
28913
29152
|
strategyName: context.strategyName,
|
|
28914
29153
|
exchangeName: context.exchangeName,
|
|
28915
29154
|
frameName: ""
|
|
@@ -29176,7 +29415,7 @@ class LiveUtils {
|
|
|
29176
29415
|
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_STOP));
|
|
29177
29416
|
actions && actions.forEach((actionName) => bt.actionValidationService.validate(actionName, LIVE_METHOD_NAME_STOP));
|
|
29178
29417
|
}
|
|
29179
|
-
await bt.strategyCoreService.
|
|
29418
|
+
await bt.strategyCoreService.stopStrategy(false, symbol, {
|
|
29180
29419
|
strategyName: context.strategyName,
|
|
29181
29420
|
exchangeName: context.exchangeName,
|
|
29182
29421
|
frameName: "",
|
|
@@ -29205,26 +29444,67 @@ class LiveUtils {
|
|
|
29205
29444
|
* }, "manual-cancel-001");
|
|
29206
29445
|
* ```
|
|
29207
29446
|
*/
|
|
29208
|
-
this.
|
|
29209
|
-
bt.loggerService.info(
|
|
29447
|
+
this.commitCancelScheduled = async (symbol, context, cancelId) => {
|
|
29448
|
+
bt.loggerService.info(LIVE_METHOD_NAME_CANCEL_SCHEDULED, {
|
|
29210
29449
|
symbol,
|
|
29211
29450
|
context,
|
|
29212
29451
|
cancelId,
|
|
29213
29452
|
});
|
|
29214
|
-
bt.strategyValidationService.validate(context.strategyName,
|
|
29215
|
-
bt.exchangeValidationService.validate(context.exchangeName,
|
|
29453
|
+
bt.strategyValidationService.validate(context.strategyName, LIVE_METHOD_NAME_CANCEL_SCHEDULED);
|
|
29454
|
+
bt.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_CANCEL_SCHEDULED);
|
|
29216
29455
|
{
|
|
29217
29456
|
const { riskName, riskList, actions } = bt.strategySchemaService.get(context.strategyName);
|
|
29218
|
-
riskName && bt.riskValidationService.validate(riskName,
|
|
29219
|
-
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName,
|
|
29220
|
-
actions && actions.forEach((actionName) => bt.actionValidationService.validate(actionName,
|
|
29457
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_CANCEL_SCHEDULED);
|
|
29458
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_CANCEL_SCHEDULED));
|
|
29459
|
+
actions && actions.forEach((actionName) => bt.actionValidationService.validate(actionName, LIVE_METHOD_NAME_CANCEL_SCHEDULED));
|
|
29221
29460
|
}
|
|
29222
|
-
await bt.strategyCoreService.
|
|
29461
|
+
await bt.strategyCoreService.cancelScheduled(false, symbol, {
|
|
29223
29462
|
strategyName: context.strategyName,
|
|
29224
29463
|
exchangeName: context.exchangeName,
|
|
29225
29464
|
frameName: "",
|
|
29226
29465
|
}, cancelId);
|
|
29227
29466
|
};
|
|
29467
|
+
/**
|
|
29468
|
+
* Closes the pending signal without stopping the strategy.
|
|
29469
|
+
*
|
|
29470
|
+
* Clears the pending signal (active position).
|
|
29471
|
+
* Does NOT affect scheduled signals or strategy operation.
|
|
29472
|
+
* Does NOT set stop flag - strategy can continue generating new signals.
|
|
29473
|
+
*
|
|
29474
|
+
* @param symbol - Trading pair symbol
|
|
29475
|
+
* @param context - Execution context with strategyName and exchangeName
|
|
29476
|
+
* @param closeId - Optional close ID for user-initiated closes
|
|
29477
|
+
* @returns Promise that resolves when pending signal is closed
|
|
29478
|
+
*
|
|
29479
|
+
* @example
|
|
29480
|
+
* ```typescript
|
|
29481
|
+
* // Close pending signal with custom ID
|
|
29482
|
+
* await Live.commitClose("BTCUSDT", {
|
|
29483
|
+
* exchangeName: "binance",
|
|
29484
|
+
* strategyName: "my-strategy"
|
|
29485
|
+
* }, "manual-close-001");
|
|
29486
|
+
* ```
|
|
29487
|
+
*/
|
|
29488
|
+
this.commitClosePending = async (symbol, context, closeId) => {
|
|
29489
|
+
bt.loggerService.info(LIVE_METHOD_NAME_CLOSE_PENDING, {
|
|
29490
|
+
symbol,
|
|
29491
|
+
context,
|
|
29492
|
+
closeId,
|
|
29493
|
+
});
|
|
29494
|
+
bt.strategyValidationService.validate(context.strategyName, LIVE_METHOD_NAME_CLOSE_PENDING);
|
|
29495
|
+
bt.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_CLOSE_PENDING);
|
|
29496
|
+
{
|
|
29497
|
+
const { riskName, riskList, actions } = bt.strategySchemaService.get(context.strategyName);
|
|
29498
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_CLOSE_PENDING);
|
|
29499
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_CLOSE_PENDING));
|
|
29500
|
+
actions && actions.forEach((actionName) => bt.actionValidationService.validate(actionName, LIVE_METHOD_NAME_CLOSE_PENDING));
|
|
29501
|
+
}
|
|
29502
|
+
await bt.strategyCoreService.closePending(false, symbol, {
|
|
29503
|
+
strategyName: context.strategyName,
|
|
29504
|
+
exchangeName: context.exchangeName,
|
|
29505
|
+
frameName: "",
|
|
29506
|
+
}, closeId);
|
|
29507
|
+
};
|
|
29228
29508
|
/**
|
|
29229
29509
|
* Executes partial close at profit level (moving toward TP).
|
|
29230
29510
|
*
|
|
@@ -30141,7 +30421,7 @@ class WalkerInstance {
|
|
|
30141
30421
|
this.task(symbol, context).catch((error) => exitEmitter.next(new Error(getErrorMessage(error))));
|
|
30142
30422
|
return () => {
|
|
30143
30423
|
for (const strategyName of walkerSchema.strategies) {
|
|
30144
|
-
bt.strategyCoreService.
|
|
30424
|
+
bt.strategyCoreService.stopStrategy(true, symbol, {
|
|
30145
30425
|
strategyName,
|
|
30146
30426
|
exchangeName: walkerSchema.exchangeName,
|
|
30147
30427
|
frameName: walkerSchema.frameName
|
|
@@ -30297,7 +30577,7 @@ class WalkerUtils {
|
|
|
30297
30577
|
}
|
|
30298
30578
|
for (const strategyName of walkerSchema.strategies) {
|
|
30299
30579
|
await walkerStopSubject.next({ symbol, strategyName, walkerName: context.walkerName });
|
|
30300
|
-
await bt.strategyCoreService.
|
|
30580
|
+
await bt.strategyCoreService.stopStrategy(true, symbol, {
|
|
30301
30581
|
strategyName,
|
|
30302
30582
|
exchangeName: walkerSchema.exchangeName,
|
|
30303
30583
|
frameName: walkerSchema.frameName
|
|
@@ -32134,33 +32414,35 @@ class NotificationInstance {
|
|
|
32134
32414
|
});
|
|
32135
32415
|
};
|
|
32136
32416
|
/**
|
|
32137
|
-
*
|
|
32138
|
-
*
|
|
32139
|
-
*
|
|
32417
|
+
* Subscribes to all notification emitters and returns an unsubscribe function.
|
|
32418
|
+
* Protected against multiple subscriptions using singleshot.
|
|
32419
|
+
*
|
|
32420
|
+
* @returns Unsubscribe function to stop receiving all notification events
|
|
32421
|
+
*
|
|
32422
|
+
* @example
|
|
32423
|
+
* ```typescript
|
|
32424
|
+
* const instance = new NotificationInstance();
|
|
32425
|
+
* const unsubscribe = instance.subscribe();
|
|
32426
|
+
* // ... later
|
|
32427
|
+
* unsubscribe();
|
|
32428
|
+
* ```
|
|
32140
32429
|
*/
|
|
32141
|
-
this.
|
|
32142
|
-
|
|
32143
|
-
this.
|
|
32144
|
-
|
|
32145
|
-
|
|
32146
|
-
|
|
32147
|
-
|
|
32148
|
-
|
|
32149
|
-
|
|
32150
|
-
|
|
32151
|
-
|
|
32152
|
-
|
|
32153
|
-
|
|
32154
|
-
|
|
32155
|
-
|
|
32156
|
-
|
|
32157
|
-
doneBacktestSubject.subscribe(this._handleDoneBacktest);
|
|
32158
|
-
// Error events
|
|
32159
|
-
errorEmitter.subscribe(this._handleError);
|
|
32160
|
-
exitEmitter.subscribe(this._handleCriticalError);
|
|
32161
|
-
validationSubject.subscribe(this._handleValidationError);
|
|
32162
|
-
// Progress events
|
|
32163
|
-
progressBacktestEmitter.subscribe(this._handleProgressBacktest);
|
|
32430
|
+
this.enable = singleshot(() => {
|
|
32431
|
+
const unSignal = signalEmitter.subscribe(this._handleSignal);
|
|
32432
|
+
const unProfit = partialProfitSubject.subscribe(this._handlePartialProfit);
|
|
32433
|
+
const unLoss = partialLossSubject.subscribe(this._handlePartialLoss);
|
|
32434
|
+
const unRisk = riskSubject.subscribe(this._handleRisk);
|
|
32435
|
+
const unDoneLine = doneLiveSubject.subscribe(this._handleDoneLive);
|
|
32436
|
+
const unDoneBacktest = doneBacktestSubject.subscribe(this._handleDoneBacktest);
|
|
32437
|
+
const unError = errorEmitter.subscribe(this._handleError);
|
|
32438
|
+
const unExit = exitEmitter.subscribe(this._handleCriticalError);
|
|
32439
|
+
const unValidation = validationSubject.subscribe(this._handleValidationError);
|
|
32440
|
+
const unProgressBacktest = progressBacktestEmitter.subscribe(this._handleProgressBacktest);
|
|
32441
|
+
const disposeFn = compose(() => unSignal(), () => unProfit(), () => unLoss(), () => unRisk(), () => unDoneLine(), () => unDoneBacktest(), () => unError(), () => unExit(), () => unValidation(), () => unProgressBacktest());
|
|
32442
|
+
return () => {
|
|
32443
|
+
disposeFn();
|
|
32444
|
+
this.enable.clear();
|
|
32445
|
+
};
|
|
32164
32446
|
});
|
|
32165
32447
|
}
|
|
32166
32448
|
/**
|
|
@@ -32210,18 +32492,36 @@ class NotificationInstance {
|
|
|
32210
32492
|
clear() {
|
|
32211
32493
|
this._notifications = [];
|
|
32212
32494
|
}
|
|
32495
|
+
/**
|
|
32496
|
+
* Unsubscribes from all notification emitters to stop receiving events.
|
|
32497
|
+
* Calls the unsubscribe function returned by subscribe().
|
|
32498
|
+
* If not subscribed, does nothing.
|
|
32499
|
+
*
|
|
32500
|
+
* @example
|
|
32501
|
+
* ```typescript
|
|
32502
|
+
* const instance = new NotificationInstance();
|
|
32503
|
+
* instance.subscribe();
|
|
32504
|
+
* // ... later
|
|
32505
|
+
* instance.unsubscribe();
|
|
32506
|
+
* ```
|
|
32507
|
+
*/
|
|
32508
|
+
disable() {
|
|
32509
|
+
if (this.enable.hasValue()) {
|
|
32510
|
+
const unsubscribeFn = this.enable();
|
|
32511
|
+
unsubscribeFn();
|
|
32512
|
+
}
|
|
32513
|
+
}
|
|
32213
32514
|
}
|
|
32214
32515
|
/**
|
|
32215
32516
|
* Public facade for notification operations.
|
|
32216
32517
|
*
|
|
32217
|
-
* Automatically
|
|
32218
|
-
* Provides simplified access to notification instance methods.
|
|
32518
|
+
* Automatically subscribes on first use and provides simplified access to notification instance methods.
|
|
32219
32519
|
*
|
|
32220
32520
|
* @example
|
|
32221
32521
|
* ```typescript
|
|
32222
32522
|
* import { Notification } from "./classes/Notification";
|
|
32223
32523
|
*
|
|
32224
|
-
* // Get all notifications
|
|
32524
|
+
* // Get all notifications (auto-subscribes if not subscribed)
|
|
32225
32525
|
* const all = await Notification.getData();
|
|
32226
32526
|
*
|
|
32227
32527
|
* // Process notifications with type discrimination
|
|
@@ -32243,6 +32543,9 @@ class NotificationInstance {
|
|
|
32243
32543
|
*
|
|
32244
32544
|
* // Clear history
|
|
32245
32545
|
* await Notification.clear();
|
|
32546
|
+
*
|
|
32547
|
+
* // Unsubscribe when done
|
|
32548
|
+
* await Notification.unsubscribe();
|
|
32246
32549
|
* ```
|
|
32247
32550
|
*/
|
|
32248
32551
|
class NotificationUtils {
|
|
@@ -32252,6 +32555,7 @@ class NotificationUtils {
|
|
|
32252
32555
|
}
|
|
32253
32556
|
/**
|
|
32254
32557
|
* Returns all notifications in chronological order (newest first).
|
|
32558
|
+
* Automatically subscribes to emitters if not already subscribed.
|
|
32255
32559
|
*
|
|
32256
32560
|
* @returns Array of strongly-typed notification objects
|
|
32257
32561
|
*
|
|
@@ -32274,11 +32578,14 @@ class NotificationUtils {
|
|
|
32274
32578
|
* ```
|
|
32275
32579
|
*/
|
|
32276
32580
|
async getData() {
|
|
32277
|
-
|
|
32581
|
+
if (!this._instance.enable.hasValue()) {
|
|
32582
|
+
throw new Error("Notification not initialized. Call enable() before getting data.");
|
|
32583
|
+
}
|
|
32278
32584
|
return this._instance.getData();
|
|
32279
32585
|
}
|
|
32280
32586
|
/**
|
|
32281
32587
|
* Clears all notification history.
|
|
32588
|
+
* Automatically subscribes to emitters if not already subscribed.
|
|
32282
32589
|
*
|
|
32283
32590
|
* @example
|
|
32284
32591
|
* ```typescript
|
|
@@ -32286,9 +32593,34 @@ class NotificationUtils {
|
|
|
32286
32593
|
* ```
|
|
32287
32594
|
*/
|
|
32288
32595
|
async clear() {
|
|
32289
|
-
|
|
32596
|
+
if (!this._instance.enable.hasValue()) {
|
|
32597
|
+
throw new Error("Notification not initialized. Call enable() before clearing data.");
|
|
32598
|
+
}
|
|
32290
32599
|
this._instance.clear();
|
|
32291
32600
|
}
|
|
32601
|
+
/**
|
|
32602
|
+
* Unsubscribes from all notification emitters.
|
|
32603
|
+
* Call this when you no longer need to collect notifications.
|
|
32604
|
+
*
|
|
32605
|
+
* @example
|
|
32606
|
+
* ```typescript
|
|
32607
|
+
* await Notification.unsubscribe();
|
|
32608
|
+
* ```
|
|
32609
|
+
*/
|
|
32610
|
+
async enable() {
|
|
32611
|
+
this._instance.enable();
|
|
32612
|
+
}
|
|
32613
|
+
/**
|
|
32614
|
+
* Unsubscribes from all notification emitters.
|
|
32615
|
+
* Call this when you no longer need to collect notifications.
|
|
32616
|
+
* @example
|
|
32617
|
+
* ```typescript
|
|
32618
|
+
* await Notification.unsubscribe();
|
|
32619
|
+
* ```
|
|
32620
|
+
*/
|
|
32621
|
+
async disable() {
|
|
32622
|
+
this._instance.disable();
|
|
32623
|
+
}
|
|
32292
32624
|
}
|
|
32293
32625
|
/**
|
|
32294
32626
|
* Singleton instance of NotificationUtils for convenient notification access.
|
|
@@ -32628,4 +32960,4 @@ const set = (object, path, value) => {
|
|
|
32628
32960
|
}
|
|
32629
32961
|
};
|
|
32630
32962
|
|
|
32631
|
-
export { ActionBase, Backtest, Breakeven, Cache, Constant, Exchange, ExecutionContextService, Heat, Live, Markdown, MarkdownFileBase, MarkdownFolderBase, MethodContextService, Notification, Optimizer, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PositionSize, Report, ReportBase, Risk, Schedule, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addOptimizerSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, commitBreakeven,
|
|
32963
|
+
export { ActionBase, Backtest, Breakeven, Cache, Constant, Exchange, ExecutionContextService, Heat, Live, Markdown, MarkdownFileBase, MarkdownFolderBase, MethodContextService, Notification, Optimizer, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PositionSize, Report, ReportBase, Risk, Schedule, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addOptimizerSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialProfit, commitSignalPromptHistory, commitTrailingStop, commitTrailingTake, dumpSignalData, emitters, formatPrice, formatQuantity, get, getActionSchema, getAveragePrice, getBacktestTimeframe, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getExchangeSchema, getFrameSchema, getMode, getOptimizerSchema, getOrderBook, getRiskSchema, getSizingSchema, getStrategySchema, getSymbol, getWalkerSchema, hasTradeContext, backtest as lib, listExchangeSchema, listFrameSchema, listOptimizerSchema, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenOptimizerProgress, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideOptimizerSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, roundTicks, set, setColumns, setConfig, setLogger, stopStrategy, validate };
|