backtest-kit 1.6.4 → 1.6.6
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 +487 -42
- package/build/index.mjs +487 -43
- package/package.json +1 -1
- package/types.d.ts +330 -1
package/build/index.mjs
CHANGED
|
@@ -3732,11 +3732,22 @@ class RiskUtils {
|
|
|
3732
3732
|
*/
|
|
3733
3733
|
const Risk = new RiskUtils();
|
|
3734
3734
|
|
|
3735
|
+
/**
|
|
3736
|
+
* No-operation IRisk implementation.
|
|
3737
|
+
* Always allows signals and performs no actions.
|
|
3738
|
+
*/
|
|
3735
3739
|
const NOOP_RISK = {
|
|
3736
3740
|
checkSignal: () => Promise.resolve(true),
|
|
3737
3741
|
addSignal: () => Promise.resolve(),
|
|
3738
3742
|
removeSignal: () => Promise.resolve(),
|
|
3739
3743
|
};
|
|
3744
|
+
/**
|
|
3745
|
+
* Determines the appropriate IRisk instance based on provided riskName and riskList.
|
|
3746
|
+
* @param dto - Object containing riskName and riskList
|
|
3747
|
+
* @param backtest - Whether running in backtest mode
|
|
3748
|
+
* @param self - Reference to StrategyConnectionService instance
|
|
3749
|
+
* @returns Configured IRisk instance (single or merged)
|
|
3750
|
+
*/
|
|
3740
3751
|
const GET_RISK_FN = (dto, backtest, self) => {
|
|
3741
3752
|
const hasRiskName = !!dto.riskName;
|
|
3742
3753
|
const hasRiskList = !!dto.riskList?.length;
|
|
@@ -3766,7 +3777,7 @@ const GET_RISK_FN = (dto, backtest, self) => {
|
|
|
3766
3777
|
* @param backtest - Whether running in backtest mode
|
|
3767
3778
|
* @returns Unique string key for memoization
|
|
3768
3779
|
*/
|
|
3769
|
-
const CREATE_KEY_FN$
|
|
3780
|
+
const CREATE_KEY_FN$b = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
3770
3781
|
/**
|
|
3771
3782
|
* Callback function for emitting ping events to pingSubject.
|
|
3772
3783
|
*
|
|
@@ -3827,7 +3838,7 @@ class StrategyConnectionService {
|
|
|
3827
3838
|
* @param strategyName - Name of registered strategy schema
|
|
3828
3839
|
* @returns Configured ClientStrategy instance
|
|
3829
3840
|
*/
|
|
3830
|
-
this.getStrategy = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$
|
|
3841
|
+
this.getStrategy = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$b(symbol, strategyName, backtest), (symbol, strategyName, backtest) => {
|
|
3831
3842
|
const { riskName = "", riskList = [], getSignal, interval, callbacks, } = this.strategySchemaService.get(strategyName);
|
|
3832
3843
|
return new ClientStrategy({
|
|
3833
3844
|
symbol,
|
|
@@ -3994,7 +4005,7 @@ class StrategyConnectionService {
|
|
|
3994
4005
|
ctx,
|
|
3995
4006
|
});
|
|
3996
4007
|
if (ctx) {
|
|
3997
|
-
const key = CREATE_KEY_FN$
|
|
4008
|
+
const key = CREATE_KEY_FN$b(ctx.symbol, ctx.strategyName, backtest);
|
|
3998
4009
|
this.getStrategy.clear(key);
|
|
3999
4010
|
}
|
|
4000
4011
|
else {
|
|
@@ -4604,7 +4615,7 @@ class ClientRisk {
|
|
|
4604
4615
|
* @param backtest - Whether running in backtest mode
|
|
4605
4616
|
* @returns Unique string key for memoization
|
|
4606
4617
|
*/
|
|
4607
|
-
const CREATE_KEY_FN$
|
|
4618
|
+
const CREATE_KEY_FN$a = (riskName, backtest) => `${riskName}:${backtest ? "backtest" : "live"}`;
|
|
4608
4619
|
/**
|
|
4609
4620
|
* Callback function for emitting risk rejection events to riskSubject.
|
|
4610
4621
|
*
|
|
@@ -4676,7 +4687,7 @@ class RiskConnectionService {
|
|
|
4676
4687
|
* @param backtest - True if backtest mode, false if live mode
|
|
4677
4688
|
* @returns Configured ClientRisk instance
|
|
4678
4689
|
*/
|
|
4679
|
-
this.getRisk = memoize(([riskName, backtest]) => CREATE_KEY_FN$
|
|
4690
|
+
this.getRisk = memoize(([riskName, backtest]) => CREATE_KEY_FN$a(riskName, backtest), (riskName, backtest) => {
|
|
4680
4691
|
const schema = this.riskSchemaService.get(riskName);
|
|
4681
4692
|
return new ClientRisk({
|
|
4682
4693
|
...schema,
|
|
@@ -4743,7 +4754,7 @@ class RiskConnectionService {
|
|
|
4743
4754
|
backtest,
|
|
4744
4755
|
});
|
|
4745
4756
|
if (ctx) {
|
|
4746
|
-
const key = CREATE_KEY_FN$
|
|
4757
|
+
const key = CREATE_KEY_FN$a(ctx.riskName, backtest);
|
|
4747
4758
|
this.getRisk.clear(key);
|
|
4748
4759
|
}
|
|
4749
4760
|
else {
|
|
@@ -4976,9 +4987,6 @@ class StrategyCoreService {
|
|
|
4976
4987
|
symbol,
|
|
4977
4988
|
strategyName,
|
|
4978
4989
|
});
|
|
4979
|
-
if (!MethodContextService.hasContext()) {
|
|
4980
|
-
throw new Error("strategyCoreService getPendingSignal requires a method context");
|
|
4981
|
-
}
|
|
4982
4990
|
await this.validate(symbol, strategyName);
|
|
4983
4991
|
return await this.strategyConnectionService.getPendingSignal(backtest, symbol, strategyName);
|
|
4984
4992
|
};
|
|
@@ -4996,9 +5004,6 @@ class StrategyCoreService {
|
|
|
4996
5004
|
symbol,
|
|
4997
5005
|
strategyName,
|
|
4998
5006
|
});
|
|
4999
|
-
if (!MethodContextService.hasContext()) {
|
|
5000
|
-
throw new Error("strategyCoreService getScheduledSignal requires a method context");
|
|
5001
|
-
}
|
|
5002
5007
|
await this.validate(symbol, strategyName);
|
|
5003
5008
|
return await this.strategyConnectionService.getScheduledSignal(backtest, symbol, strategyName);
|
|
5004
5009
|
};
|
|
@@ -5018,9 +5023,6 @@ class StrategyCoreService {
|
|
|
5018
5023
|
strategyName,
|
|
5019
5024
|
backtest,
|
|
5020
5025
|
});
|
|
5021
|
-
if (!MethodContextService.hasContext()) {
|
|
5022
|
-
throw new Error("strategyCoreService getStopped requires a method context");
|
|
5023
|
-
}
|
|
5024
5026
|
await this.validate(symbol, strategyName);
|
|
5025
5027
|
return await this.strategyConnectionService.getStopped(backtest, symbol, strategyName);
|
|
5026
5028
|
};
|
|
@@ -7791,7 +7793,7 @@ const DEFAULT_COLUMNS = Object.freeze({ ...COLUMN_CONFIG });
|
|
|
7791
7793
|
* @param backtest - Whether running in backtest mode
|
|
7792
7794
|
* @returns Unique string key for memoization
|
|
7793
7795
|
*/
|
|
7794
|
-
const CREATE_KEY_FN$
|
|
7796
|
+
const CREATE_KEY_FN$9 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
7795
7797
|
/**
|
|
7796
7798
|
* Checks if a value is unsafe for display (not a number, NaN, or Infinity).
|
|
7797
7799
|
*
|
|
@@ -8000,7 +8002,7 @@ class BacktestMarkdownService {
|
|
|
8000
8002
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
8001
8003
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8002
8004
|
*/
|
|
8003
|
-
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$
|
|
8005
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$9(symbol, strategyName, backtest), () => new ReportStorage$5());
|
|
8004
8006
|
/**
|
|
8005
8007
|
* Processes tick events and accumulates closed signals.
|
|
8006
8008
|
* Should be called from IStrategyCallbacks.onTick.
|
|
@@ -8138,7 +8140,7 @@ class BacktestMarkdownService {
|
|
|
8138
8140
|
ctx,
|
|
8139
8141
|
});
|
|
8140
8142
|
if (ctx) {
|
|
8141
|
-
const key = CREATE_KEY_FN$
|
|
8143
|
+
const key = CREATE_KEY_FN$9(ctx.symbol, ctx.strategyName, backtest);
|
|
8142
8144
|
this.getStorage.clear(key);
|
|
8143
8145
|
}
|
|
8144
8146
|
else {
|
|
@@ -8171,7 +8173,7 @@ class BacktestMarkdownService {
|
|
|
8171
8173
|
* @param backtest - Whether running in backtest mode
|
|
8172
8174
|
* @returns Unique string key for memoization
|
|
8173
8175
|
*/
|
|
8174
|
-
const CREATE_KEY_FN$
|
|
8176
|
+
const CREATE_KEY_FN$8 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8175
8177
|
/**
|
|
8176
8178
|
* Checks if a value is unsafe for display (not a number, NaN, or Infinity).
|
|
8177
8179
|
*
|
|
@@ -8501,7 +8503,7 @@ class LiveMarkdownService {
|
|
|
8501
8503
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
8502
8504
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8503
8505
|
*/
|
|
8504
|
-
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$
|
|
8506
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$8(symbol, strategyName, backtest), () => new ReportStorage$4());
|
|
8505
8507
|
/**
|
|
8506
8508
|
* Processes tick events and accumulates all event types.
|
|
8507
8509
|
* Should be called from IStrategyCallbacks.onTick.
|
|
@@ -8649,7 +8651,7 @@ class LiveMarkdownService {
|
|
|
8649
8651
|
ctx,
|
|
8650
8652
|
});
|
|
8651
8653
|
if (ctx) {
|
|
8652
|
-
const key = CREATE_KEY_FN$
|
|
8654
|
+
const key = CREATE_KEY_FN$8(ctx.symbol, ctx.strategyName, backtest);
|
|
8653
8655
|
this.getStorage.clear(key);
|
|
8654
8656
|
}
|
|
8655
8657
|
else {
|
|
@@ -8682,7 +8684,7 @@ class LiveMarkdownService {
|
|
|
8682
8684
|
* @param backtest - Whether running in backtest mode
|
|
8683
8685
|
* @returns Unique string key for memoization
|
|
8684
8686
|
*/
|
|
8685
|
-
const CREATE_KEY_FN$
|
|
8687
|
+
const CREATE_KEY_FN$7 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8686
8688
|
/** Maximum number of events to store in schedule reports */
|
|
8687
8689
|
const MAX_EVENTS$4 = 250;
|
|
8688
8690
|
/**
|
|
@@ -8918,7 +8920,7 @@ class ScheduleMarkdownService {
|
|
|
8918
8920
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
8919
8921
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8920
8922
|
*/
|
|
8921
|
-
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$
|
|
8923
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$7(symbol, strategyName, backtest), () => new ReportStorage$3());
|
|
8922
8924
|
/**
|
|
8923
8925
|
* Processes tick events and accumulates scheduled/opened/cancelled events.
|
|
8924
8926
|
* Should be called from signalEmitter subscription.
|
|
@@ -9060,7 +9062,7 @@ class ScheduleMarkdownService {
|
|
|
9060
9062
|
ctx,
|
|
9061
9063
|
});
|
|
9062
9064
|
if (ctx) {
|
|
9063
|
-
const key = CREATE_KEY_FN$
|
|
9065
|
+
const key = CREATE_KEY_FN$7(ctx.symbol, ctx.strategyName, backtest);
|
|
9064
9066
|
this.getStorage.clear(key);
|
|
9065
9067
|
}
|
|
9066
9068
|
else {
|
|
@@ -9093,7 +9095,7 @@ class ScheduleMarkdownService {
|
|
|
9093
9095
|
* @param backtest - Whether running in backtest mode
|
|
9094
9096
|
* @returns Unique string key for memoization
|
|
9095
9097
|
*/
|
|
9096
|
-
const CREATE_KEY_FN$
|
|
9098
|
+
const CREATE_KEY_FN$6 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
9097
9099
|
/**
|
|
9098
9100
|
* Calculates percentile value from sorted array.
|
|
9099
9101
|
*/
|
|
@@ -9311,7 +9313,7 @@ class PerformanceMarkdownService {
|
|
|
9311
9313
|
* Memoized function to get or create PerformanceStorage for a symbol-strategy-backtest triple.
|
|
9312
9314
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
9313
9315
|
*/
|
|
9314
|
-
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$
|
|
9316
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$6(symbol, strategyName, backtest), () => new PerformanceStorage());
|
|
9315
9317
|
/**
|
|
9316
9318
|
* Processes performance events and accumulates metrics.
|
|
9317
9319
|
* Should be called from performance tracking code.
|
|
@@ -9416,7 +9418,7 @@ class PerformanceMarkdownService {
|
|
|
9416
9418
|
ctx,
|
|
9417
9419
|
});
|
|
9418
9420
|
if (ctx) {
|
|
9419
|
-
const key = CREATE_KEY_FN$
|
|
9421
|
+
const key = CREATE_KEY_FN$6(ctx.symbol, ctx.strategyName, backtest);
|
|
9420
9422
|
this.getStorage.clear(key);
|
|
9421
9423
|
}
|
|
9422
9424
|
else {
|
|
@@ -9850,7 +9852,7 @@ class WalkerMarkdownService {
|
|
|
9850
9852
|
* @param backtest - Whether running in backtest mode
|
|
9851
9853
|
* @returns Unique string key for memoization
|
|
9852
9854
|
*/
|
|
9853
|
-
const CREATE_KEY_FN$
|
|
9855
|
+
const CREATE_KEY_FN$5 = (strategyName, backtest) => `${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
9854
9856
|
const HEATMAP_METHOD_NAME_GET_DATA = "HeatMarkdownService.getData";
|
|
9855
9857
|
const HEATMAP_METHOD_NAME_GET_REPORT = "HeatMarkdownService.getReport";
|
|
9856
9858
|
const HEATMAP_METHOD_NAME_DUMP = "HeatMarkdownService.dump";
|
|
@@ -10194,7 +10196,7 @@ class HeatMarkdownService {
|
|
|
10194
10196
|
* Memoized function to get or create HeatmapStorage for a strategy and backtest mode.
|
|
10195
10197
|
* Each strategy + backtest mode combination gets its own isolated heatmap storage instance.
|
|
10196
10198
|
*/
|
|
10197
|
-
this.getStorage = memoize(([strategyName, backtest]) => CREATE_KEY_FN$
|
|
10199
|
+
this.getStorage = memoize(([strategyName, backtest]) => CREATE_KEY_FN$5(strategyName, backtest), () => new HeatmapStorage());
|
|
10198
10200
|
/**
|
|
10199
10201
|
* Processes tick events and accumulates closed signals.
|
|
10200
10202
|
* Should be called from signal emitter subscription.
|
|
@@ -10330,7 +10332,7 @@ class HeatMarkdownService {
|
|
|
10330
10332
|
ctx,
|
|
10331
10333
|
});
|
|
10332
10334
|
if (ctx) {
|
|
10333
|
-
const key = CREATE_KEY_FN$
|
|
10335
|
+
const key = CREATE_KEY_FN$5(ctx.strategyName, backtest);
|
|
10334
10336
|
this.getStorage.clear(key);
|
|
10335
10337
|
}
|
|
10336
10338
|
else {
|
|
@@ -12548,7 +12550,7 @@ class ClientPartial {
|
|
|
12548
12550
|
* @param backtest - Whether running in backtest mode
|
|
12549
12551
|
* @returns Unique string key for memoization
|
|
12550
12552
|
*/
|
|
12551
|
-
const CREATE_KEY_FN$
|
|
12553
|
+
const CREATE_KEY_FN$4 = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
|
|
12552
12554
|
/**
|
|
12553
12555
|
* Callback function for emitting profit events to partialProfitSubject.
|
|
12554
12556
|
*
|
|
@@ -12646,7 +12648,7 @@ class PartialConnectionService {
|
|
|
12646
12648
|
* Key format: "signalId:backtest" or "signalId:live"
|
|
12647
12649
|
* Value: ClientPartial instance with logger and event emitters
|
|
12648
12650
|
*/
|
|
12649
|
-
this.getPartial = memoize(([signalId, backtest]) => CREATE_KEY_FN$
|
|
12651
|
+
this.getPartial = memoize(([signalId, backtest]) => CREATE_KEY_FN$4(signalId, backtest), (signalId, backtest) => {
|
|
12650
12652
|
return new ClientPartial({
|
|
12651
12653
|
signalId,
|
|
12652
12654
|
logger: this.loggerService,
|
|
@@ -12736,7 +12738,7 @@ class PartialConnectionService {
|
|
|
12736
12738
|
const partial = this.getPartial(data.id, backtest);
|
|
12737
12739
|
await partial.waitForInit(symbol, data.strategyName);
|
|
12738
12740
|
await partial.clear(symbol, data, priceClose, backtest);
|
|
12739
|
-
const key = CREATE_KEY_FN$
|
|
12741
|
+
const key = CREATE_KEY_FN$4(data.id, backtest);
|
|
12740
12742
|
this.getPartial.clear(key);
|
|
12741
12743
|
};
|
|
12742
12744
|
}
|
|
@@ -12748,7 +12750,7 @@ class PartialConnectionService {
|
|
|
12748
12750
|
* @param param0 - Tuple of symbol, strategyName and backtest boolean
|
|
12749
12751
|
* @returns Unique string key for memoization
|
|
12750
12752
|
*/
|
|
12751
|
-
const CREATE_KEY_FN$
|
|
12753
|
+
const CREATE_KEY_FN$3 = ([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
12752
12754
|
/** Maximum number of events to store in partial reports */
|
|
12753
12755
|
const MAX_EVENTS$1 = 250;
|
|
12754
12756
|
/**
|
|
@@ -12923,7 +12925,7 @@ class PartialMarkdownService {
|
|
|
12923
12925
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
12924
12926
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
12925
12927
|
*/
|
|
12926
|
-
this.getStorage = memoize(CREATE_KEY_FN$
|
|
12928
|
+
this.getStorage = memoize(CREATE_KEY_FN$3, () => new ReportStorage$1());
|
|
12927
12929
|
/**
|
|
12928
12930
|
* Processes profit events and accumulates them.
|
|
12929
12931
|
* Should be called from partialProfitSubject subscription.
|
|
@@ -13070,7 +13072,7 @@ class PartialMarkdownService {
|
|
|
13070
13072
|
ctx,
|
|
13071
13073
|
});
|
|
13072
13074
|
if (ctx) {
|
|
13073
|
-
const key = CREATE_KEY_FN$
|
|
13075
|
+
const key = CREATE_KEY_FN$3([ctx.symbol, ctx.strategyName, backtest]);
|
|
13074
13076
|
this.getStorage.clear(key);
|
|
13075
13077
|
}
|
|
13076
13078
|
else {
|
|
@@ -13513,7 +13515,7 @@ class ConfigValidationService {
|
|
|
13513
13515
|
* @param backtest - Whether running in backtest mode
|
|
13514
13516
|
* @returns Unique string key for memoization
|
|
13515
13517
|
*/
|
|
13516
|
-
const CREATE_KEY_FN = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
13518
|
+
const CREATE_KEY_FN$2 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
13517
13519
|
/** Maximum number of events to store in risk reports */
|
|
13518
13520
|
const MAX_EVENTS = 250;
|
|
13519
13521
|
/**
|
|
@@ -13658,7 +13660,7 @@ class RiskMarkdownService {
|
|
|
13658
13660
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
13659
13661
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
13660
13662
|
*/
|
|
13661
|
-
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN(symbol, strategyName, backtest), () => new ReportStorage());
|
|
13663
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$2(symbol, strategyName, backtest), () => new ReportStorage());
|
|
13662
13664
|
/**
|
|
13663
13665
|
* Processes risk rejection events and accumulates them.
|
|
13664
13666
|
* Should be called from riskSubject subscription.
|
|
@@ -13786,7 +13788,7 @@ class RiskMarkdownService {
|
|
|
13786
13788
|
ctx,
|
|
13787
13789
|
});
|
|
13788
13790
|
if (ctx) {
|
|
13789
|
-
const key = CREATE_KEY_FN(ctx.symbol, ctx.strategyName, backtest);
|
|
13791
|
+
const key = CREATE_KEY_FN$2(ctx.symbol, ctx.strategyName, backtest);
|
|
13790
13792
|
this.getStorage.clear(key);
|
|
13791
13793
|
}
|
|
13792
13794
|
else {
|
|
@@ -19498,7 +19500,15 @@ const INTERVAL_MINUTES = {
|
|
|
19498
19500
|
"6h": 360,
|
|
19499
19501
|
"8h": 480,
|
|
19500
19502
|
};
|
|
19501
|
-
|
|
19503
|
+
/**
|
|
19504
|
+
* Create a cache key string from strategy name, exchange name, and backtest mode.
|
|
19505
|
+
*
|
|
19506
|
+
* @param strategyName - Name of the strategy
|
|
19507
|
+
* @param exchangeName - Name of the exchange
|
|
19508
|
+
* @param backtest - Whether running in backtest mode
|
|
19509
|
+
* @returns Cache key string
|
|
19510
|
+
*/
|
|
19511
|
+
const CREATE_KEY_FN$1 = (strategyName, exchangeName, backtest) => `${strategyName}:${exchangeName}:${backtest ? "backtest" : "live"}`;
|
|
19502
19512
|
/**
|
|
19503
19513
|
* Instance class for caching function results with timeframe-based invalidation.
|
|
19504
19514
|
*
|
|
@@ -19574,7 +19584,7 @@ class CacheInstance {
|
|
|
19574
19584
|
throw new Error(`CacheInstance unknown cache ttl interval=${this.interval}`);
|
|
19575
19585
|
}
|
|
19576
19586
|
}
|
|
19577
|
-
const key =
|
|
19587
|
+
const key = CREATE_KEY_FN$1(backtest$1.methodContextService.context.strategyName, backtest$1.methodContextService.context.exchangeName, backtest$1.executionContextService.context.backtest);
|
|
19578
19588
|
const currentWhen = backtest$1.executionContextService.context.when;
|
|
19579
19589
|
const cached = this._cacheMap.get(key);
|
|
19580
19590
|
if (cached) {
|
|
@@ -19612,7 +19622,7 @@ class CacheInstance {
|
|
|
19612
19622
|
* ```
|
|
19613
19623
|
*/
|
|
19614
19624
|
this.clear = () => {
|
|
19615
|
-
const key =
|
|
19625
|
+
const key = CREATE_KEY_FN$1(backtest$1.methodContextService.context.strategyName, backtest$1.methodContextService.context.exchangeName, backtest$1.executionContextService.context.backtest);
|
|
19616
19626
|
this._cacheMap.delete(key);
|
|
19617
19627
|
};
|
|
19618
19628
|
}
|
|
@@ -19760,4 +19770,438 @@ class CacheUtils {
|
|
|
19760
19770
|
*/
|
|
19761
19771
|
const Cache = new CacheUtils();
|
|
19762
19772
|
|
|
19763
|
-
|
|
19773
|
+
/** Maximum number of notifications to store in history */
|
|
19774
|
+
const MAX_NOTIFICATIONS = 250;
|
|
19775
|
+
/** Function to create unique notification IDs */
|
|
19776
|
+
const CREATE_KEY_FN = () => randomString();
|
|
19777
|
+
/**
|
|
19778
|
+
* Instance class for notification history management.
|
|
19779
|
+
*
|
|
19780
|
+
* Contains all business logic for notification collection from emitters/subjects.
|
|
19781
|
+
* Stores notifications in chronological order with automatic limit management.
|
|
19782
|
+
*
|
|
19783
|
+
* @example
|
|
19784
|
+
* ```typescript
|
|
19785
|
+
* const instance = new NotificationInstance();
|
|
19786
|
+
* await instance.waitForInit();
|
|
19787
|
+
*
|
|
19788
|
+
* // Get all notifications
|
|
19789
|
+
* const all = instance.getData();
|
|
19790
|
+
*
|
|
19791
|
+
* // Process notifications with type discrimination
|
|
19792
|
+
* all.forEach(notification => {
|
|
19793
|
+
* switch (notification.type) {
|
|
19794
|
+
* case "signal.closed":
|
|
19795
|
+
* console.log(`Closed: ${notification.pnlPercentage}%`);
|
|
19796
|
+
* break;
|
|
19797
|
+
* case "partial.loss":
|
|
19798
|
+
* if (notification.level >= 30) {
|
|
19799
|
+
* alert("High loss!");
|
|
19800
|
+
* }
|
|
19801
|
+
* break;
|
|
19802
|
+
* case "risk.rejection":
|
|
19803
|
+
* console.warn(notification.rejectionNote);
|
|
19804
|
+
* break;
|
|
19805
|
+
* }
|
|
19806
|
+
* });
|
|
19807
|
+
*
|
|
19808
|
+
* // Clear history
|
|
19809
|
+
* instance.clear();
|
|
19810
|
+
* ```
|
|
19811
|
+
*/
|
|
19812
|
+
class NotificationInstance {
|
|
19813
|
+
constructor() {
|
|
19814
|
+
/** Internal notification history storage (newest first) */
|
|
19815
|
+
this._notifications = [];
|
|
19816
|
+
/**
|
|
19817
|
+
* Processes signal events and creates appropriate notifications.
|
|
19818
|
+
*/
|
|
19819
|
+
this._handleSignal = async (data) => {
|
|
19820
|
+
if (data.action === "opened") {
|
|
19821
|
+
this._addNotification({
|
|
19822
|
+
type: "signal.opened",
|
|
19823
|
+
id: CREATE_KEY_FN(),
|
|
19824
|
+
timestamp: data.signal.pendingAt,
|
|
19825
|
+
backtest: data.backtest,
|
|
19826
|
+
symbol: data.symbol,
|
|
19827
|
+
strategyName: data.strategyName,
|
|
19828
|
+
exchangeName: data.exchangeName,
|
|
19829
|
+
signalId: data.signal.id,
|
|
19830
|
+
position: data.signal.position,
|
|
19831
|
+
priceOpen: data.signal.priceOpen,
|
|
19832
|
+
priceTakeProfit: data.signal.priceTakeProfit,
|
|
19833
|
+
priceStopLoss: data.signal.priceStopLoss,
|
|
19834
|
+
note: data.signal.note,
|
|
19835
|
+
});
|
|
19836
|
+
}
|
|
19837
|
+
else if (data.action === "closed") {
|
|
19838
|
+
const durationMs = data.closeTimestamp - data.signal.pendingAt;
|
|
19839
|
+
const durationMin = Math.round(durationMs / 60000);
|
|
19840
|
+
this._addNotification({
|
|
19841
|
+
type: "signal.closed",
|
|
19842
|
+
id: CREATE_KEY_FN(),
|
|
19843
|
+
timestamp: data.closeTimestamp,
|
|
19844
|
+
backtest: data.backtest,
|
|
19845
|
+
symbol: data.symbol,
|
|
19846
|
+
strategyName: data.strategyName,
|
|
19847
|
+
exchangeName: data.exchangeName,
|
|
19848
|
+
signalId: data.signal.id,
|
|
19849
|
+
position: data.signal.position,
|
|
19850
|
+
priceOpen: data.signal.priceOpen,
|
|
19851
|
+
priceClose: data.currentPrice,
|
|
19852
|
+
pnlPercentage: data.pnl.pnlPercentage,
|
|
19853
|
+
closeReason: data.closeReason,
|
|
19854
|
+
duration: durationMin,
|
|
19855
|
+
note: data.signal.note,
|
|
19856
|
+
});
|
|
19857
|
+
}
|
|
19858
|
+
else if (data.action === "scheduled") {
|
|
19859
|
+
this._addNotification({
|
|
19860
|
+
type: "signal.scheduled",
|
|
19861
|
+
id: CREATE_KEY_FN(),
|
|
19862
|
+
timestamp: data.signal.scheduledAt,
|
|
19863
|
+
backtest: data.backtest,
|
|
19864
|
+
symbol: data.symbol,
|
|
19865
|
+
strategyName: data.strategyName,
|
|
19866
|
+
exchangeName: data.exchangeName,
|
|
19867
|
+
signalId: data.signal.id,
|
|
19868
|
+
position: data.signal.position,
|
|
19869
|
+
priceOpen: data.signal.priceOpen,
|
|
19870
|
+
scheduledAt: data.signal.scheduledAt,
|
|
19871
|
+
currentPrice: data.currentPrice,
|
|
19872
|
+
});
|
|
19873
|
+
}
|
|
19874
|
+
else if (data.action === "cancelled") {
|
|
19875
|
+
const durationMs = data.closeTimestamp - data.signal.scheduledAt;
|
|
19876
|
+
const durationMin = Math.round(durationMs / 60000);
|
|
19877
|
+
this._addNotification({
|
|
19878
|
+
type: "signal.cancelled",
|
|
19879
|
+
id: CREATE_KEY_FN(),
|
|
19880
|
+
timestamp: data.closeTimestamp,
|
|
19881
|
+
backtest: data.backtest,
|
|
19882
|
+
symbol: data.symbol,
|
|
19883
|
+
strategyName: data.strategyName,
|
|
19884
|
+
exchangeName: data.exchangeName,
|
|
19885
|
+
signalId: data.signal.id,
|
|
19886
|
+
position: data.signal.position,
|
|
19887
|
+
cancelReason: data.reason,
|
|
19888
|
+
cancelId: data.cancelId,
|
|
19889
|
+
duration: durationMin,
|
|
19890
|
+
});
|
|
19891
|
+
}
|
|
19892
|
+
};
|
|
19893
|
+
/**
|
|
19894
|
+
* Processes partial profit events.
|
|
19895
|
+
*/
|
|
19896
|
+
this._handlePartialProfit = async (data) => {
|
|
19897
|
+
this._addNotification({
|
|
19898
|
+
type: "partial.profit",
|
|
19899
|
+
id: CREATE_KEY_FN(),
|
|
19900
|
+
timestamp: data.timestamp,
|
|
19901
|
+
backtest: data.backtest,
|
|
19902
|
+
symbol: data.symbol,
|
|
19903
|
+
strategyName: data.strategyName,
|
|
19904
|
+
exchangeName: data.exchangeName,
|
|
19905
|
+
signalId: data.data.id,
|
|
19906
|
+
level: data.level,
|
|
19907
|
+
currentPrice: data.currentPrice,
|
|
19908
|
+
priceOpen: data.data.priceOpen,
|
|
19909
|
+
position: data.data.position,
|
|
19910
|
+
});
|
|
19911
|
+
};
|
|
19912
|
+
/**
|
|
19913
|
+
* Processes partial loss events.
|
|
19914
|
+
*/
|
|
19915
|
+
this._handlePartialLoss = async (data) => {
|
|
19916
|
+
this._addNotification({
|
|
19917
|
+
type: "partial.loss",
|
|
19918
|
+
id: CREATE_KEY_FN(),
|
|
19919
|
+
timestamp: data.timestamp,
|
|
19920
|
+
backtest: data.backtest,
|
|
19921
|
+
symbol: data.symbol,
|
|
19922
|
+
strategyName: data.strategyName,
|
|
19923
|
+
exchangeName: data.exchangeName,
|
|
19924
|
+
signalId: data.data.id,
|
|
19925
|
+
level: data.level,
|
|
19926
|
+
currentPrice: data.currentPrice,
|
|
19927
|
+
priceOpen: data.data.priceOpen,
|
|
19928
|
+
position: data.data.position,
|
|
19929
|
+
});
|
|
19930
|
+
};
|
|
19931
|
+
/**
|
|
19932
|
+
* Processes risk rejection events.
|
|
19933
|
+
*/
|
|
19934
|
+
this._handleRisk = async (data) => {
|
|
19935
|
+
this._addNotification({
|
|
19936
|
+
type: "risk.rejection",
|
|
19937
|
+
id: CREATE_KEY_FN(),
|
|
19938
|
+
timestamp: data.timestamp,
|
|
19939
|
+
backtest: data.backtest,
|
|
19940
|
+
symbol: data.symbol,
|
|
19941
|
+
strategyName: data.strategyName,
|
|
19942
|
+
exchangeName: data.exchangeName,
|
|
19943
|
+
rejectionNote: data.rejectionNote,
|
|
19944
|
+
rejectionId: data.rejectionId,
|
|
19945
|
+
activePositionCount: data.activePositionCount,
|
|
19946
|
+
currentPrice: data.currentPrice,
|
|
19947
|
+
pendingSignal: data.pendingSignal,
|
|
19948
|
+
});
|
|
19949
|
+
};
|
|
19950
|
+
/**
|
|
19951
|
+
* Processes done events (live/backtest).
|
|
19952
|
+
*/
|
|
19953
|
+
this._handleDoneLive = async (data) => {
|
|
19954
|
+
this._addNotification({
|
|
19955
|
+
type: "live.done",
|
|
19956
|
+
id: CREATE_KEY_FN(),
|
|
19957
|
+
timestamp: Date.now(),
|
|
19958
|
+
backtest: false,
|
|
19959
|
+
symbol: data.symbol,
|
|
19960
|
+
strategyName: data.strategyName,
|
|
19961
|
+
exchangeName: data.exchangeName,
|
|
19962
|
+
});
|
|
19963
|
+
};
|
|
19964
|
+
/**
|
|
19965
|
+
* Processes done events (backtest).
|
|
19966
|
+
*/
|
|
19967
|
+
this._handleDoneBacktest = async (data) => {
|
|
19968
|
+
this._addNotification({
|
|
19969
|
+
type: "backtest.done",
|
|
19970
|
+
id: CREATE_KEY_FN(),
|
|
19971
|
+
timestamp: Date.now(),
|
|
19972
|
+
backtest: true,
|
|
19973
|
+
symbol: data.symbol,
|
|
19974
|
+
strategyName: data.strategyName,
|
|
19975
|
+
exchangeName: data.exchangeName,
|
|
19976
|
+
});
|
|
19977
|
+
};
|
|
19978
|
+
/**
|
|
19979
|
+
* Processes error events.
|
|
19980
|
+
*/
|
|
19981
|
+
this._handleError = async (error) => {
|
|
19982
|
+
this._addNotification({
|
|
19983
|
+
type: "error.info",
|
|
19984
|
+
id: CREATE_KEY_FN(),
|
|
19985
|
+
timestamp: Date.now(),
|
|
19986
|
+
error: errorData(error),
|
|
19987
|
+
message: getErrorMessage(error),
|
|
19988
|
+
backtest: false,
|
|
19989
|
+
});
|
|
19990
|
+
};
|
|
19991
|
+
/**
|
|
19992
|
+
* Processes critical error events.
|
|
19993
|
+
*/
|
|
19994
|
+
this._handleCriticalError = async (error) => {
|
|
19995
|
+
this._addNotification({
|
|
19996
|
+
type: "error.critical",
|
|
19997
|
+
id: CREATE_KEY_FN(),
|
|
19998
|
+
timestamp: Date.now(),
|
|
19999
|
+
error: errorData(error),
|
|
20000
|
+
message: getErrorMessage(error),
|
|
20001
|
+
backtest: false,
|
|
20002
|
+
});
|
|
20003
|
+
};
|
|
20004
|
+
/**
|
|
20005
|
+
* Processes validation error events.
|
|
20006
|
+
*/
|
|
20007
|
+
this._handleValidationError = async (error) => {
|
|
20008
|
+
this._addNotification({
|
|
20009
|
+
type: "error.validation",
|
|
20010
|
+
id: CREATE_KEY_FN(),
|
|
20011
|
+
timestamp: Date.now(),
|
|
20012
|
+
error: errorData(error),
|
|
20013
|
+
message: getErrorMessage(error),
|
|
20014
|
+
backtest: false,
|
|
20015
|
+
});
|
|
20016
|
+
};
|
|
20017
|
+
/**
|
|
20018
|
+
* Processes progress events.
|
|
20019
|
+
*/
|
|
20020
|
+
this._handleProgressBacktest = async (data) => {
|
|
20021
|
+
this._addNotification({
|
|
20022
|
+
type: "progress.backtest",
|
|
20023
|
+
id: CREATE_KEY_FN(),
|
|
20024
|
+
timestamp: Date.now(),
|
|
20025
|
+
backtest: true,
|
|
20026
|
+
exchangeName: data.exchangeName,
|
|
20027
|
+
strategyName: data.strategyName,
|
|
20028
|
+
symbol: data.symbol,
|
|
20029
|
+
totalFrames: data.totalFrames,
|
|
20030
|
+
processedFrames: data.processedFrames,
|
|
20031
|
+
progress: data.progress,
|
|
20032
|
+
});
|
|
20033
|
+
};
|
|
20034
|
+
/**
|
|
20035
|
+
* Initializes notification system by subscribing to all emitters.
|
|
20036
|
+
* Uses singleshot to ensure initialization happens only once.
|
|
20037
|
+
* Automatically called on first use.
|
|
20038
|
+
*/
|
|
20039
|
+
this.waitForInit = singleshot(async () => {
|
|
20040
|
+
// Signal events
|
|
20041
|
+
signalEmitter.subscribe(this._handleSignal);
|
|
20042
|
+
// Partial profit/loss events
|
|
20043
|
+
partialProfitSubject.subscribe(this._handlePartialProfit);
|
|
20044
|
+
partialLossSubject.subscribe(this._handlePartialLoss);
|
|
20045
|
+
// Risk events
|
|
20046
|
+
riskSubject.subscribe(this._handleRisk);
|
|
20047
|
+
// Done events
|
|
20048
|
+
doneLiveSubject.subscribe(this._handleDoneLive);
|
|
20049
|
+
doneBacktestSubject.subscribe(this._handleDoneBacktest);
|
|
20050
|
+
// Error events
|
|
20051
|
+
errorEmitter.subscribe(this._handleError);
|
|
20052
|
+
exitEmitter.subscribe(this._handleCriticalError);
|
|
20053
|
+
validationSubject.subscribe(this._handleValidationError);
|
|
20054
|
+
// Progress events
|
|
20055
|
+
progressBacktestEmitter.subscribe(this._handleProgressBacktest);
|
|
20056
|
+
});
|
|
20057
|
+
}
|
|
20058
|
+
/**
|
|
20059
|
+
* Adds notification to history with automatic limit management.
|
|
20060
|
+
*/
|
|
20061
|
+
_addNotification(notification) {
|
|
20062
|
+
this._notifications.unshift(notification);
|
|
20063
|
+
// Trim history if exceeded MAX_NOTIFICATIONS
|
|
20064
|
+
if (this._notifications.length > MAX_NOTIFICATIONS) {
|
|
20065
|
+
this._notifications.pop();
|
|
20066
|
+
}
|
|
20067
|
+
}
|
|
20068
|
+
/**
|
|
20069
|
+
* Returns all notifications in chronological order (newest first).
|
|
20070
|
+
*
|
|
20071
|
+
* @returns Array of strongly-typed notification objects
|
|
20072
|
+
*
|
|
20073
|
+
* @example
|
|
20074
|
+
* ```typescript
|
|
20075
|
+
* const notifications = instance.getData();
|
|
20076
|
+
*
|
|
20077
|
+
* notifications.forEach(notification => {
|
|
20078
|
+
* switch (notification.type) {
|
|
20079
|
+
* case "signal.closed":
|
|
20080
|
+
* console.log(`${notification.symbol}: ${notification.pnlPercentage}%`);
|
|
20081
|
+
* break;
|
|
20082
|
+
* case "partial.loss":
|
|
20083
|
+
* if (notification.level >= 30) {
|
|
20084
|
+
* console.warn(`High loss: ${notification.symbol}`);
|
|
20085
|
+
* }
|
|
20086
|
+
* break;
|
|
20087
|
+
* }
|
|
20088
|
+
* });
|
|
20089
|
+
* ```
|
|
20090
|
+
*/
|
|
20091
|
+
getData() {
|
|
20092
|
+
return [...this._notifications];
|
|
20093
|
+
}
|
|
20094
|
+
/**
|
|
20095
|
+
* Clears all notification history.
|
|
20096
|
+
*
|
|
20097
|
+
* @example
|
|
20098
|
+
* ```typescript
|
|
20099
|
+
* instance.clear();
|
|
20100
|
+
* ```
|
|
20101
|
+
*/
|
|
20102
|
+
clear() {
|
|
20103
|
+
this._notifications = [];
|
|
20104
|
+
}
|
|
20105
|
+
}
|
|
20106
|
+
/**
|
|
20107
|
+
* Public facade for notification operations.
|
|
20108
|
+
*
|
|
20109
|
+
* Automatically calls waitForInit on each userspace method call.
|
|
20110
|
+
* Provides simplified access to notification instance methods.
|
|
20111
|
+
*
|
|
20112
|
+
* @example
|
|
20113
|
+
* ```typescript
|
|
20114
|
+
* import { Notification } from "./classes/Notification";
|
|
20115
|
+
*
|
|
20116
|
+
* // Get all notifications
|
|
20117
|
+
* const all = await Notification.getData();
|
|
20118
|
+
*
|
|
20119
|
+
* // Process notifications with type discrimination
|
|
20120
|
+
* all.forEach(notification => {
|
|
20121
|
+
* switch (notification.type) {
|
|
20122
|
+
* case "signal.closed":
|
|
20123
|
+
* console.log(`Closed: ${notification.pnlPercentage}%`);
|
|
20124
|
+
* break;
|
|
20125
|
+
* case "partial.loss":
|
|
20126
|
+
* if (notification.level >= 30) {
|
|
20127
|
+
* alert("High loss!");
|
|
20128
|
+
* }
|
|
20129
|
+
* break;
|
|
20130
|
+
* case "risk.rejection":
|
|
20131
|
+
* console.warn(notification.rejectionNote);
|
|
20132
|
+
* break;
|
|
20133
|
+
* }
|
|
20134
|
+
* });
|
|
20135
|
+
*
|
|
20136
|
+
* // Clear history
|
|
20137
|
+
* await Notification.clear();
|
|
20138
|
+
* ```
|
|
20139
|
+
*/
|
|
20140
|
+
class NotificationUtils {
|
|
20141
|
+
constructor() {
|
|
20142
|
+
/** Internal instance containing business logic */
|
|
20143
|
+
this._instance = new NotificationInstance();
|
|
20144
|
+
}
|
|
20145
|
+
/**
|
|
20146
|
+
* Returns all notifications in chronological order (newest first).
|
|
20147
|
+
*
|
|
20148
|
+
* @returns Array of strongly-typed notification objects
|
|
20149
|
+
*
|
|
20150
|
+
* @example
|
|
20151
|
+
* ```typescript
|
|
20152
|
+
* const notifications = await Notification.getData();
|
|
20153
|
+
*
|
|
20154
|
+
* notifications.forEach(notification => {
|
|
20155
|
+
* switch (notification.type) {
|
|
20156
|
+
* case "signal.closed":
|
|
20157
|
+
* console.log(`${notification.symbol}: ${notification.pnlPercentage}%`);
|
|
20158
|
+
* break;
|
|
20159
|
+
* case "partial.loss":
|
|
20160
|
+
* if (notification.level >= 30) {
|
|
20161
|
+
* console.warn(`High loss: ${notification.symbol}`);
|
|
20162
|
+
* }
|
|
20163
|
+
* break;
|
|
20164
|
+
* }
|
|
20165
|
+
* });
|
|
20166
|
+
* ```
|
|
20167
|
+
*/
|
|
20168
|
+
async getData() {
|
|
20169
|
+
await this._instance.waitForInit();
|
|
20170
|
+
return this._instance.getData();
|
|
20171
|
+
}
|
|
20172
|
+
/**
|
|
20173
|
+
* Clears all notification history.
|
|
20174
|
+
*
|
|
20175
|
+
* @example
|
|
20176
|
+
* ```typescript
|
|
20177
|
+
* await Notification.clear();
|
|
20178
|
+
* ```
|
|
20179
|
+
*/
|
|
20180
|
+
async clear() {
|
|
20181
|
+
await this._instance.waitForInit();
|
|
20182
|
+
this._instance.clear();
|
|
20183
|
+
}
|
|
20184
|
+
}
|
|
20185
|
+
/**
|
|
20186
|
+
* Singleton instance of NotificationUtils for convenient notification access.
|
|
20187
|
+
*
|
|
20188
|
+
* @example
|
|
20189
|
+
* ```typescript
|
|
20190
|
+
* import { Notification } from "./classes/Notification";
|
|
20191
|
+
*
|
|
20192
|
+
* // Get all notifications
|
|
20193
|
+
* const all = await Notification.getData();
|
|
20194
|
+
*
|
|
20195
|
+
* // Filter by type using type discrimination
|
|
20196
|
+
* const closedSignals = all.filter(n => n.type === "signal.closed");
|
|
20197
|
+
* const highLosses = all.filter(n =>
|
|
20198
|
+
* n.type === "partial.loss" && n.level >= 30
|
|
20199
|
+
* );
|
|
20200
|
+
*
|
|
20201
|
+
* // Clear history
|
|
20202
|
+
* await Notification.clear();
|
|
20203
|
+
* ```
|
|
20204
|
+
*/
|
|
20205
|
+
const Notification = new NotificationUtils();
|
|
20206
|
+
|
|
20207
|
+
export { Backtest, Cache, Constant, Exchange, ExecutionContextService, Heat, Live, MethodContextService, Notification, Optimizer, Partial, Performance, PersistBase, PersistPartialAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PositionSize, Risk, Schedule, Walker, addExchange, addFrame, addOptimizer, addRisk, addSizing, addStrategy, addWalker, cancel, dumpSignal, emitters, formatPrice, formatQuantity, getAveragePrice, getCandles, getColumns, getConfig, getDate, getDefaultColumns, getDefaultConfig, getMode, hasTradeContext, backtest as lib, listExchanges, listFrames, listOptimizers, listRisks, listSizings, listStrategies, listWalkers, listenBacktestProgress, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenOptimizerProgress, listenPartialLoss, listenPartialLossOnce, listenPartialProfit, listenPartialProfitOnce, listenPerformance, listenPing, listenPingOnce, listenRisk, listenRiskOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, setColumns, setConfig, setLogger, stop, validate };
|