backtest-kit 1.6.3 → 1.6.5
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 +1 -1
- package/build/index.cjs +142 -47
- package/build/index.mjs +142 -47
- package/package.json +1 -1
- package/types.d.ts +13 -7
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# 🧿 Backtest Kit
|
|
4
4
|
|
|
5
|
-
> A TypeScript framework for backtesting and live trading strategies on multi-asset, crypto or
|
|
5
|
+
> A TypeScript framework for backtesting and live trading strategies on multi-asset, crypto, forex or [DEX (peer-to-peer marketplace)](https://en.wikipedia.org/wiki/Decentralized_finance#Decentralized_exchanges) with crash-safe persistence, signal validation, and AI optimization.
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
|
package/build/index.cjs
CHANGED
|
@@ -3734,11 +3734,22 @@ class RiskUtils {
|
|
|
3734
3734
|
*/
|
|
3735
3735
|
const Risk = new RiskUtils();
|
|
3736
3736
|
|
|
3737
|
+
/**
|
|
3738
|
+
* No-operation IRisk implementation.
|
|
3739
|
+
* Always allows signals and performs no actions.
|
|
3740
|
+
*/
|
|
3737
3741
|
const NOOP_RISK = {
|
|
3738
3742
|
checkSignal: () => Promise.resolve(true),
|
|
3739
3743
|
addSignal: () => Promise.resolve(),
|
|
3740
3744
|
removeSignal: () => Promise.resolve(),
|
|
3741
3745
|
};
|
|
3746
|
+
/**
|
|
3747
|
+
* Determines the appropriate IRisk instance based on provided riskName and riskList.
|
|
3748
|
+
* @param dto - Object containing riskName and riskList
|
|
3749
|
+
* @param backtest - Whether running in backtest mode
|
|
3750
|
+
* @param self - Reference to StrategyConnectionService instance
|
|
3751
|
+
* @returns Configured IRisk instance (single or merged)
|
|
3752
|
+
*/
|
|
3742
3753
|
const GET_RISK_FN = (dto, backtest, self) => {
|
|
3743
3754
|
const hasRiskName = !!dto.riskName;
|
|
3744
3755
|
const hasRiskList = !!dto.riskList?.length;
|
|
@@ -3760,6 +3771,15 @@ const GET_RISK_FN = (dto, backtest, self) => {
|
|
|
3760
3771
|
...dto.riskList.map((riskName) => self.riskConnectionService.getRisk(riskName, backtest)),
|
|
3761
3772
|
]);
|
|
3762
3773
|
};
|
|
3774
|
+
/**
|
|
3775
|
+
* Creates a unique key for memoizing ClientStrategy instances.
|
|
3776
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
3777
|
+
* @param symbol - Trading pair symbol
|
|
3778
|
+
* @param strategyName - Name of the strategy
|
|
3779
|
+
* @param backtest - Whether running in backtest mode
|
|
3780
|
+
* @returns Unique string key for memoization
|
|
3781
|
+
*/
|
|
3782
|
+
const CREATE_KEY_FN$9 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
3763
3783
|
/**
|
|
3764
3784
|
* Callback function for emitting ping events to pingSubject.
|
|
3765
3785
|
*
|
|
@@ -3820,7 +3840,7 @@ class StrategyConnectionService {
|
|
|
3820
3840
|
* @param strategyName - Name of registered strategy schema
|
|
3821
3841
|
* @returns Configured ClientStrategy instance
|
|
3822
3842
|
*/
|
|
3823
|
-
this.getStrategy = functoolsKit.memoize(([symbol, strategyName, backtest]) =>
|
|
3843
|
+
this.getStrategy = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$9(symbol, strategyName, backtest), (symbol, strategyName, backtest) => {
|
|
3824
3844
|
const { riskName = "", riskList = [], getSignal, interval, callbacks, } = this.strategySchemaService.get(strategyName);
|
|
3825
3845
|
return new ClientStrategy({
|
|
3826
3846
|
symbol,
|
|
@@ -3987,7 +4007,7 @@ class StrategyConnectionService {
|
|
|
3987
4007
|
ctx,
|
|
3988
4008
|
});
|
|
3989
4009
|
if (ctx) {
|
|
3990
|
-
const key =
|
|
4010
|
+
const key = CREATE_KEY_FN$9(ctx.symbol, ctx.strategyName, backtest);
|
|
3991
4011
|
this.getStrategy.clear(key);
|
|
3992
4012
|
}
|
|
3993
4013
|
else {
|
|
@@ -4590,6 +4610,14 @@ class ClientRisk {
|
|
|
4590
4610
|
}
|
|
4591
4611
|
}
|
|
4592
4612
|
|
|
4613
|
+
/**
|
|
4614
|
+
* Creates a unique key for memoizing ClientRisk instances.
|
|
4615
|
+
* Key format: "riskName:backtest" or "riskName:live"
|
|
4616
|
+
* @param riskName - Name of the risk schema
|
|
4617
|
+
* @param backtest - Whether running in backtest mode
|
|
4618
|
+
* @returns Unique string key for memoization
|
|
4619
|
+
*/
|
|
4620
|
+
const CREATE_KEY_FN$8 = (riskName, backtest) => `${riskName}:${backtest ? "backtest" : "live"}`;
|
|
4593
4621
|
/**
|
|
4594
4622
|
* Callback function for emitting risk rejection events to riskSubject.
|
|
4595
4623
|
*
|
|
@@ -4661,7 +4689,7 @@ class RiskConnectionService {
|
|
|
4661
4689
|
* @param backtest - True if backtest mode, false if live mode
|
|
4662
4690
|
* @returns Configured ClientRisk instance
|
|
4663
4691
|
*/
|
|
4664
|
-
this.getRisk = functoolsKit.memoize(([riskName, backtest]) =>
|
|
4692
|
+
this.getRisk = functoolsKit.memoize(([riskName, backtest]) => CREATE_KEY_FN$8(riskName, backtest), (riskName, backtest) => {
|
|
4665
4693
|
const schema = this.riskSchemaService.get(riskName);
|
|
4666
4694
|
return new ClientRisk({
|
|
4667
4695
|
...schema,
|
|
@@ -4719,15 +4747,21 @@ class RiskConnectionService {
|
|
|
4719
4747
|
/**
|
|
4720
4748
|
* Clears the cached ClientRisk instance for the given risk name.
|
|
4721
4749
|
*
|
|
4722
|
-
* @param
|
|
4750
|
+
* @param backtest - Whether running in backtest mode
|
|
4751
|
+
* @param ctx - Optional context with riskName (clears all if not provided)
|
|
4723
4752
|
*/
|
|
4724
|
-
this.clear = async (backtest,
|
|
4753
|
+
this.clear = async (backtest, ctx) => {
|
|
4725
4754
|
this.loggerService.log("riskConnectionService clear", {
|
|
4726
|
-
|
|
4755
|
+
ctx,
|
|
4727
4756
|
backtest,
|
|
4728
4757
|
});
|
|
4729
|
-
|
|
4730
|
-
|
|
4758
|
+
if (ctx) {
|
|
4759
|
+
const key = CREATE_KEY_FN$8(ctx.riskName, backtest);
|
|
4760
|
+
this.getRisk.clear(key);
|
|
4761
|
+
}
|
|
4762
|
+
else {
|
|
4763
|
+
this.getRisk.clear();
|
|
4764
|
+
}
|
|
4731
4765
|
};
|
|
4732
4766
|
}
|
|
4733
4767
|
}
|
|
@@ -4955,9 +4989,6 @@ class StrategyCoreService {
|
|
|
4955
4989
|
symbol,
|
|
4956
4990
|
strategyName,
|
|
4957
4991
|
});
|
|
4958
|
-
if (!MethodContextService.hasContext()) {
|
|
4959
|
-
throw new Error("strategyCoreService getPendingSignal requires a method context");
|
|
4960
|
-
}
|
|
4961
4992
|
await this.validate(symbol, strategyName);
|
|
4962
4993
|
return await this.strategyConnectionService.getPendingSignal(backtest, symbol, strategyName);
|
|
4963
4994
|
};
|
|
@@ -4975,9 +5006,6 @@ class StrategyCoreService {
|
|
|
4975
5006
|
symbol,
|
|
4976
5007
|
strategyName,
|
|
4977
5008
|
});
|
|
4978
|
-
if (!MethodContextService.hasContext()) {
|
|
4979
|
-
throw new Error("strategyCoreService getScheduledSignal requires a method context");
|
|
4980
|
-
}
|
|
4981
5009
|
await this.validate(symbol, strategyName);
|
|
4982
5010
|
return await this.strategyConnectionService.getScheduledSignal(backtest, symbol, strategyName);
|
|
4983
5011
|
};
|
|
@@ -4997,9 +5025,6 @@ class StrategyCoreService {
|
|
|
4997
5025
|
strategyName,
|
|
4998
5026
|
backtest,
|
|
4999
5027
|
});
|
|
5000
|
-
if (!MethodContextService.hasContext()) {
|
|
5001
|
-
throw new Error("strategyCoreService getStopped requires a method context");
|
|
5002
|
-
}
|
|
5003
5028
|
await this.validate(symbol, strategyName);
|
|
5004
5029
|
return await this.strategyConnectionService.getStopped(backtest, symbol, strategyName);
|
|
5005
5030
|
};
|
|
@@ -5256,19 +5281,20 @@ class RiskGlobalService {
|
|
|
5256
5281
|
};
|
|
5257
5282
|
/**
|
|
5258
5283
|
* Clears risk data.
|
|
5259
|
-
* If
|
|
5260
|
-
* If no
|
|
5261
|
-
* @param
|
|
5284
|
+
* If ctx is provided, clears data for that specific risk instance.
|
|
5285
|
+
* If no ctx is provided, clears all risk data.
|
|
5286
|
+
* @param backtest - Whether running in backtest mode
|
|
5287
|
+
* @param ctx - Optional context with riskName (clears all if not provided)
|
|
5262
5288
|
*/
|
|
5263
|
-
this.clear = async (backtest,
|
|
5289
|
+
this.clear = async (backtest, ctx) => {
|
|
5264
5290
|
this.loggerService.log("riskGlobalService clear", {
|
|
5265
|
-
|
|
5291
|
+
ctx,
|
|
5266
5292
|
backtest,
|
|
5267
5293
|
});
|
|
5268
|
-
if (
|
|
5269
|
-
await this.validate(riskName);
|
|
5294
|
+
if (ctx) {
|
|
5295
|
+
await this.validate(ctx.riskName);
|
|
5270
5296
|
}
|
|
5271
|
-
return await this.riskConnectionService.clear(backtest,
|
|
5297
|
+
return await this.riskConnectionService.clear(backtest, ctx);
|
|
5272
5298
|
};
|
|
5273
5299
|
}
|
|
5274
5300
|
}
|
|
@@ -7761,6 +7787,15 @@ const COLUMN_CONFIG = {
|
|
|
7761
7787
|
*/
|
|
7762
7788
|
const DEFAULT_COLUMNS = Object.freeze({ ...COLUMN_CONFIG });
|
|
7763
7789
|
|
|
7790
|
+
/**
|
|
7791
|
+
* Creates a unique key for memoizing ReportStorage instances.
|
|
7792
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
7793
|
+
* @param symbol - Trading pair symbol
|
|
7794
|
+
* @param strategyName - Name of the strategy
|
|
7795
|
+
* @param backtest - Whether running in backtest mode
|
|
7796
|
+
* @returns Unique string key for memoization
|
|
7797
|
+
*/
|
|
7798
|
+
const CREATE_KEY_FN$7 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
7764
7799
|
/**
|
|
7765
7800
|
* Checks if a value is unsafe for display (not a number, NaN, or Infinity).
|
|
7766
7801
|
*
|
|
@@ -7969,7 +8004,7 @@ class BacktestMarkdownService {
|
|
|
7969
8004
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
7970
8005
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
7971
8006
|
*/
|
|
7972
|
-
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) =>
|
|
8007
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$7(symbol, strategyName, backtest), () => new ReportStorage$5());
|
|
7973
8008
|
/**
|
|
7974
8009
|
* Processes tick events and accumulates closed signals.
|
|
7975
8010
|
* Should be called from IStrategyCallbacks.onTick.
|
|
@@ -8107,7 +8142,7 @@ class BacktestMarkdownService {
|
|
|
8107
8142
|
ctx,
|
|
8108
8143
|
});
|
|
8109
8144
|
if (ctx) {
|
|
8110
|
-
const key =
|
|
8145
|
+
const key = CREATE_KEY_FN$7(ctx.symbol, ctx.strategyName, backtest);
|
|
8111
8146
|
this.getStorage.clear(key);
|
|
8112
8147
|
}
|
|
8113
8148
|
else {
|
|
@@ -8132,6 +8167,15 @@ class BacktestMarkdownService {
|
|
|
8132
8167
|
}
|
|
8133
8168
|
}
|
|
8134
8169
|
|
|
8170
|
+
/**
|
|
8171
|
+
* Creates a unique key for memoizing ReportStorage instances.
|
|
8172
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
8173
|
+
* @param symbol - Trading pair symbol
|
|
8174
|
+
* @param strategyName - Name of the strategy
|
|
8175
|
+
* @param backtest - Whether running in backtest mode
|
|
8176
|
+
* @returns Unique string key for memoization
|
|
8177
|
+
*/
|
|
8178
|
+
const CREATE_KEY_FN$6 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8135
8179
|
/**
|
|
8136
8180
|
* Checks if a value is unsafe for display (not a number, NaN, or Infinity).
|
|
8137
8181
|
*
|
|
@@ -8461,7 +8505,7 @@ class LiveMarkdownService {
|
|
|
8461
8505
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
8462
8506
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8463
8507
|
*/
|
|
8464
|
-
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) =>
|
|
8508
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$6(symbol, strategyName, backtest), () => new ReportStorage$4());
|
|
8465
8509
|
/**
|
|
8466
8510
|
* Processes tick events and accumulates all event types.
|
|
8467
8511
|
* Should be called from IStrategyCallbacks.onTick.
|
|
@@ -8609,7 +8653,7 @@ class LiveMarkdownService {
|
|
|
8609
8653
|
ctx,
|
|
8610
8654
|
});
|
|
8611
8655
|
if (ctx) {
|
|
8612
|
-
const key =
|
|
8656
|
+
const key = CREATE_KEY_FN$6(ctx.symbol, ctx.strategyName, backtest);
|
|
8613
8657
|
this.getStorage.clear(key);
|
|
8614
8658
|
}
|
|
8615
8659
|
else {
|
|
@@ -8634,6 +8678,15 @@ class LiveMarkdownService {
|
|
|
8634
8678
|
}
|
|
8635
8679
|
}
|
|
8636
8680
|
|
|
8681
|
+
/**
|
|
8682
|
+
* Creates a unique key for memoizing ReportStorage instances.
|
|
8683
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
8684
|
+
* @param symbol - Trading pair symbol
|
|
8685
|
+
* @param strategyName - Name of the strategy
|
|
8686
|
+
* @param backtest - Whether running in backtest mode
|
|
8687
|
+
* @returns Unique string key for memoization
|
|
8688
|
+
*/
|
|
8689
|
+
const CREATE_KEY_FN$5 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8637
8690
|
/** Maximum number of events to store in schedule reports */
|
|
8638
8691
|
const MAX_EVENTS$4 = 250;
|
|
8639
8692
|
/**
|
|
@@ -8869,7 +8922,7 @@ class ScheduleMarkdownService {
|
|
|
8869
8922
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
8870
8923
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8871
8924
|
*/
|
|
8872
|
-
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) =>
|
|
8925
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$5(symbol, strategyName, backtest), () => new ReportStorage$3());
|
|
8873
8926
|
/**
|
|
8874
8927
|
* Processes tick events and accumulates scheduled/opened/cancelled events.
|
|
8875
8928
|
* Should be called from signalEmitter subscription.
|
|
@@ -9011,7 +9064,7 @@ class ScheduleMarkdownService {
|
|
|
9011
9064
|
ctx,
|
|
9012
9065
|
});
|
|
9013
9066
|
if (ctx) {
|
|
9014
|
-
const key =
|
|
9067
|
+
const key = CREATE_KEY_FN$5(ctx.symbol, ctx.strategyName, backtest);
|
|
9015
9068
|
this.getStorage.clear(key);
|
|
9016
9069
|
}
|
|
9017
9070
|
else {
|
|
@@ -9036,6 +9089,15 @@ class ScheduleMarkdownService {
|
|
|
9036
9089
|
}
|
|
9037
9090
|
}
|
|
9038
9091
|
|
|
9092
|
+
/**
|
|
9093
|
+
* Creates a unique key for memoizing PerformanceStorage instances.
|
|
9094
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
9095
|
+
* @param symbol - Trading pair symbol
|
|
9096
|
+
* @param strategyName - Name of the strategy
|
|
9097
|
+
* @param backtest - Whether running in backtest mode
|
|
9098
|
+
* @returns Unique string key for memoization
|
|
9099
|
+
*/
|
|
9100
|
+
const CREATE_KEY_FN$4 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
9039
9101
|
/**
|
|
9040
9102
|
* Calculates percentile value from sorted array.
|
|
9041
9103
|
*/
|
|
@@ -9253,7 +9315,7 @@ class PerformanceMarkdownService {
|
|
|
9253
9315
|
* Memoized function to get or create PerformanceStorage for a symbol-strategy-backtest triple.
|
|
9254
9316
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
9255
9317
|
*/
|
|
9256
|
-
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) =>
|
|
9318
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$4(symbol, strategyName, backtest), () => new PerformanceStorage());
|
|
9257
9319
|
/**
|
|
9258
9320
|
* Processes performance events and accumulates metrics.
|
|
9259
9321
|
* Should be called from performance tracking code.
|
|
@@ -9358,7 +9420,7 @@ class PerformanceMarkdownService {
|
|
|
9358
9420
|
ctx,
|
|
9359
9421
|
});
|
|
9360
9422
|
if (ctx) {
|
|
9361
|
-
const key =
|
|
9423
|
+
const key = CREATE_KEY_FN$4(ctx.symbol, ctx.strategyName, backtest);
|
|
9362
9424
|
this.getStorage.clear(key);
|
|
9363
9425
|
}
|
|
9364
9426
|
else {
|
|
@@ -9785,6 +9847,14 @@ class WalkerMarkdownService {
|
|
|
9785
9847
|
}
|
|
9786
9848
|
}
|
|
9787
9849
|
|
|
9850
|
+
/**
|
|
9851
|
+
* Creates a unique key for memoizing HeatmapStorage instances.
|
|
9852
|
+
* Key format: "strategyName:backtest" or "strategyName:live"
|
|
9853
|
+
* @param strategyName - Name of the strategy
|
|
9854
|
+
* @param backtest - Whether running in backtest mode
|
|
9855
|
+
* @returns Unique string key for memoization
|
|
9856
|
+
*/
|
|
9857
|
+
const CREATE_KEY_FN$3 = (strategyName, backtest) => `${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
9788
9858
|
const HEATMAP_METHOD_NAME_GET_DATA = "HeatMarkdownService.getData";
|
|
9789
9859
|
const HEATMAP_METHOD_NAME_GET_REPORT = "HeatMarkdownService.getReport";
|
|
9790
9860
|
const HEATMAP_METHOD_NAME_DUMP = "HeatMarkdownService.dump";
|
|
@@ -10128,7 +10198,7 @@ class HeatMarkdownService {
|
|
|
10128
10198
|
* Memoized function to get or create HeatmapStorage for a strategy and backtest mode.
|
|
10129
10199
|
* Each strategy + backtest mode combination gets its own isolated heatmap storage instance.
|
|
10130
10200
|
*/
|
|
10131
|
-
this.getStorage = functoolsKit.memoize(([strategyName, backtest]) =>
|
|
10201
|
+
this.getStorage = functoolsKit.memoize(([strategyName, backtest]) => CREATE_KEY_FN$3(strategyName, backtest), () => new HeatmapStorage());
|
|
10132
10202
|
/**
|
|
10133
10203
|
* Processes tick events and accumulates closed signals.
|
|
10134
10204
|
* Should be called from signal emitter subscription.
|
|
@@ -10264,7 +10334,7 @@ class HeatMarkdownService {
|
|
|
10264
10334
|
ctx,
|
|
10265
10335
|
});
|
|
10266
10336
|
if (ctx) {
|
|
10267
|
-
const key =
|
|
10337
|
+
const key = CREATE_KEY_FN$3(ctx.strategyName, backtest);
|
|
10268
10338
|
this.getStorage.clear(key);
|
|
10269
10339
|
}
|
|
10270
10340
|
else {
|
|
@@ -12474,6 +12544,15 @@ class ClientPartial {
|
|
|
12474
12544
|
}
|
|
12475
12545
|
}
|
|
12476
12546
|
|
|
12547
|
+
/**
|
|
12548
|
+
* Creates a unique key for memoizing ClientPartial instances.
|
|
12549
|
+
* Key format: "signalId:backtest" or "signalId:live"
|
|
12550
|
+
*
|
|
12551
|
+
* @param signalId - Signal ID
|
|
12552
|
+
* @param backtest - Whether running in backtest mode
|
|
12553
|
+
* @returns Unique string key for memoization
|
|
12554
|
+
*/
|
|
12555
|
+
const CREATE_KEY_FN$2 = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
|
|
12477
12556
|
/**
|
|
12478
12557
|
* Callback function for emitting profit events to partialProfitSubject.
|
|
12479
12558
|
*
|
|
@@ -12571,7 +12650,7 @@ class PartialConnectionService {
|
|
|
12571
12650
|
* Key format: "signalId:backtest" or "signalId:live"
|
|
12572
12651
|
* Value: ClientPartial instance with logger and event emitters
|
|
12573
12652
|
*/
|
|
12574
|
-
this.getPartial = functoolsKit.memoize(([signalId, backtest]) =>
|
|
12653
|
+
this.getPartial = functoolsKit.memoize(([signalId, backtest]) => CREATE_KEY_FN$2(signalId, backtest), (signalId, backtest) => {
|
|
12575
12654
|
return new ClientPartial({
|
|
12576
12655
|
signalId,
|
|
12577
12656
|
logger: this.loggerService,
|
|
@@ -12661,12 +12740,19 @@ class PartialConnectionService {
|
|
|
12661
12740
|
const partial = this.getPartial(data.id, backtest);
|
|
12662
12741
|
await partial.waitForInit(symbol, data.strategyName);
|
|
12663
12742
|
await partial.clear(symbol, data, priceClose, backtest);
|
|
12664
|
-
const key =
|
|
12743
|
+
const key = CREATE_KEY_FN$2(data.id, backtest);
|
|
12665
12744
|
this.getPartial.clear(key);
|
|
12666
12745
|
};
|
|
12667
12746
|
}
|
|
12668
12747
|
}
|
|
12669
12748
|
|
|
12749
|
+
/**
|
|
12750
|
+
* Creates a unique key for memoizing ReportStorage instances.
|
|
12751
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
12752
|
+
* @param param0 - Tuple of symbol, strategyName and backtest boolean
|
|
12753
|
+
* @returns Unique string key for memoization
|
|
12754
|
+
*/
|
|
12755
|
+
const CREATE_KEY_FN$1 = ([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
12670
12756
|
/** Maximum number of events to store in partial reports */
|
|
12671
12757
|
const MAX_EVENTS$1 = 250;
|
|
12672
12758
|
/**
|
|
@@ -12841,7 +12927,7 @@ class PartialMarkdownService {
|
|
|
12841
12927
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
12842
12928
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
12843
12929
|
*/
|
|
12844
|
-
this.getStorage = functoolsKit.memoize(
|
|
12930
|
+
this.getStorage = functoolsKit.memoize(CREATE_KEY_FN$1, () => new ReportStorage$1());
|
|
12845
12931
|
/**
|
|
12846
12932
|
* Processes profit events and accumulates them.
|
|
12847
12933
|
* Should be called from partialProfitSubject subscription.
|
|
@@ -12988,7 +13074,7 @@ class PartialMarkdownService {
|
|
|
12988
13074
|
ctx,
|
|
12989
13075
|
});
|
|
12990
13076
|
if (ctx) {
|
|
12991
|
-
const key =
|
|
13077
|
+
const key = CREATE_KEY_FN$1([ctx.symbol, ctx.strategyName, backtest]);
|
|
12992
13078
|
this.getStorage.clear(key);
|
|
12993
13079
|
}
|
|
12994
13080
|
else {
|
|
@@ -13423,6 +13509,15 @@ class ConfigValidationService {
|
|
|
13423
13509
|
}
|
|
13424
13510
|
}
|
|
13425
13511
|
|
|
13512
|
+
/**
|
|
13513
|
+
* Creates a unique key for memoizing ReportStorage instances.
|
|
13514
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
13515
|
+
* @param symbol - Trading pair symbol
|
|
13516
|
+
* @param strategyName - Name of the strategy
|
|
13517
|
+
* @param backtest - Whether running in backtest mode
|
|
13518
|
+
* @returns Unique string key for memoization
|
|
13519
|
+
*/
|
|
13520
|
+
const CREATE_KEY_FN = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
13426
13521
|
/** Maximum number of events to store in risk reports */
|
|
13427
13522
|
const MAX_EVENTS = 250;
|
|
13428
13523
|
/**
|
|
@@ -13567,7 +13662,7 @@ class RiskMarkdownService {
|
|
|
13567
13662
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
13568
13663
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
13569
13664
|
*/
|
|
13570
|
-
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) =>
|
|
13665
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN(symbol, strategyName, backtest), () => new ReportStorage());
|
|
13571
13666
|
/**
|
|
13572
13667
|
* Processes risk rejection events and accumulates them.
|
|
13573
13668
|
* Should be called from riskSubject subscription.
|
|
@@ -13695,7 +13790,7 @@ class RiskMarkdownService {
|
|
|
13695
13790
|
ctx,
|
|
13696
13791
|
});
|
|
13697
13792
|
if (ctx) {
|
|
13698
|
-
const key =
|
|
13793
|
+
const key = CREATE_KEY_FN(ctx.symbol, ctx.strategyName, backtest);
|
|
13699
13794
|
this.getStorage.clear(key);
|
|
13700
13795
|
}
|
|
13701
13796
|
else {
|
|
@@ -16407,8 +16502,8 @@ class BacktestInstance {
|
|
|
16407
16502
|
}
|
|
16408
16503
|
{
|
|
16409
16504
|
const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
|
|
16410
|
-
riskName && backtest$1.riskGlobalService.clear(true, riskName);
|
|
16411
|
-
riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, riskName));
|
|
16505
|
+
riskName && backtest$1.riskGlobalService.clear(true, { riskName });
|
|
16506
|
+
riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, { riskName }));
|
|
16412
16507
|
}
|
|
16413
16508
|
return backtest$1.backtestCommandService.run(symbol, context);
|
|
16414
16509
|
};
|
|
@@ -17081,8 +17176,8 @@ class LiveInstance {
|
|
|
17081
17176
|
}
|
|
17082
17177
|
{
|
|
17083
17178
|
const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
|
|
17084
|
-
riskName && backtest$1.riskGlobalService.clear(false, riskName);
|
|
17085
|
-
riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(false, riskName));
|
|
17179
|
+
riskName && backtest$1.riskGlobalService.clear(false, { riskName });
|
|
17180
|
+
riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(false, { riskName }));
|
|
17086
17181
|
}
|
|
17087
17182
|
return backtest$1.liveCommandService.run(symbol, context);
|
|
17088
17183
|
};
|
|
@@ -18033,9 +18128,9 @@ class WalkerInstance {
|
|
|
18033
18128
|
}
|
|
18034
18129
|
{
|
|
18035
18130
|
const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
|
|
18036
|
-
riskName && backtest$1.riskGlobalService.clear(true, riskName);
|
|
18131
|
+
riskName && backtest$1.riskGlobalService.clear(true, { riskName });
|
|
18037
18132
|
riskList &&
|
|
18038
|
-
riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, riskName));
|
|
18133
|
+
riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, { riskName }));
|
|
18039
18134
|
}
|
|
18040
18135
|
}
|
|
18041
18136
|
return backtest$1.walkerCommandService.run(symbol, {
|
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;
|
|
@@ -3758,6 +3769,15 @@ const GET_RISK_FN = (dto, backtest, self) => {
|
|
|
3758
3769
|
...dto.riskList.map((riskName) => self.riskConnectionService.getRisk(riskName, backtest)),
|
|
3759
3770
|
]);
|
|
3760
3771
|
};
|
|
3772
|
+
/**
|
|
3773
|
+
* Creates a unique key for memoizing ClientStrategy instances.
|
|
3774
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
3775
|
+
* @param symbol - Trading pair symbol
|
|
3776
|
+
* @param strategyName - Name of the strategy
|
|
3777
|
+
* @param backtest - Whether running in backtest mode
|
|
3778
|
+
* @returns Unique string key for memoization
|
|
3779
|
+
*/
|
|
3780
|
+
const CREATE_KEY_FN$9 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
3761
3781
|
/**
|
|
3762
3782
|
* Callback function for emitting ping events to pingSubject.
|
|
3763
3783
|
*
|
|
@@ -3818,7 +3838,7 @@ class StrategyConnectionService {
|
|
|
3818
3838
|
* @param strategyName - Name of registered strategy schema
|
|
3819
3839
|
* @returns Configured ClientStrategy instance
|
|
3820
3840
|
*/
|
|
3821
|
-
this.getStrategy = memoize(([symbol, strategyName, backtest]) =>
|
|
3841
|
+
this.getStrategy = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$9(symbol, strategyName, backtest), (symbol, strategyName, backtest) => {
|
|
3822
3842
|
const { riskName = "", riskList = [], getSignal, interval, callbacks, } = this.strategySchemaService.get(strategyName);
|
|
3823
3843
|
return new ClientStrategy({
|
|
3824
3844
|
symbol,
|
|
@@ -3985,7 +4005,7 @@ class StrategyConnectionService {
|
|
|
3985
4005
|
ctx,
|
|
3986
4006
|
});
|
|
3987
4007
|
if (ctx) {
|
|
3988
|
-
const key =
|
|
4008
|
+
const key = CREATE_KEY_FN$9(ctx.symbol, ctx.strategyName, backtest);
|
|
3989
4009
|
this.getStrategy.clear(key);
|
|
3990
4010
|
}
|
|
3991
4011
|
else {
|
|
@@ -4588,6 +4608,14 @@ class ClientRisk {
|
|
|
4588
4608
|
}
|
|
4589
4609
|
}
|
|
4590
4610
|
|
|
4611
|
+
/**
|
|
4612
|
+
* Creates a unique key for memoizing ClientRisk instances.
|
|
4613
|
+
* Key format: "riskName:backtest" or "riskName:live"
|
|
4614
|
+
* @param riskName - Name of the risk schema
|
|
4615
|
+
* @param backtest - Whether running in backtest mode
|
|
4616
|
+
* @returns Unique string key for memoization
|
|
4617
|
+
*/
|
|
4618
|
+
const CREATE_KEY_FN$8 = (riskName, backtest) => `${riskName}:${backtest ? "backtest" : "live"}`;
|
|
4591
4619
|
/**
|
|
4592
4620
|
* Callback function for emitting risk rejection events to riskSubject.
|
|
4593
4621
|
*
|
|
@@ -4659,7 +4687,7 @@ class RiskConnectionService {
|
|
|
4659
4687
|
* @param backtest - True if backtest mode, false if live mode
|
|
4660
4688
|
* @returns Configured ClientRisk instance
|
|
4661
4689
|
*/
|
|
4662
|
-
this.getRisk = memoize(([riskName, backtest]) =>
|
|
4690
|
+
this.getRisk = memoize(([riskName, backtest]) => CREATE_KEY_FN$8(riskName, backtest), (riskName, backtest) => {
|
|
4663
4691
|
const schema = this.riskSchemaService.get(riskName);
|
|
4664
4692
|
return new ClientRisk({
|
|
4665
4693
|
...schema,
|
|
@@ -4717,15 +4745,21 @@ class RiskConnectionService {
|
|
|
4717
4745
|
/**
|
|
4718
4746
|
* Clears the cached ClientRisk instance for the given risk name.
|
|
4719
4747
|
*
|
|
4720
|
-
* @param
|
|
4748
|
+
* @param backtest - Whether running in backtest mode
|
|
4749
|
+
* @param ctx - Optional context with riskName (clears all if not provided)
|
|
4721
4750
|
*/
|
|
4722
|
-
this.clear = async (backtest,
|
|
4751
|
+
this.clear = async (backtest, ctx) => {
|
|
4723
4752
|
this.loggerService.log("riskConnectionService clear", {
|
|
4724
|
-
|
|
4753
|
+
ctx,
|
|
4725
4754
|
backtest,
|
|
4726
4755
|
});
|
|
4727
|
-
|
|
4728
|
-
|
|
4756
|
+
if (ctx) {
|
|
4757
|
+
const key = CREATE_KEY_FN$8(ctx.riskName, backtest);
|
|
4758
|
+
this.getRisk.clear(key);
|
|
4759
|
+
}
|
|
4760
|
+
else {
|
|
4761
|
+
this.getRisk.clear();
|
|
4762
|
+
}
|
|
4729
4763
|
};
|
|
4730
4764
|
}
|
|
4731
4765
|
}
|
|
@@ -4953,9 +4987,6 @@ class StrategyCoreService {
|
|
|
4953
4987
|
symbol,
|
|
4954
4988
|
strategyName,
|
|
4955
4989
|
});
|
|
4956
|
-
if (!MethodContextService.hasContext()) {
|
|
4957
|
-
throw new Error("strategyCoreService getPendingSignal requires a method context");
|
|
4958
|
-
}
|
|
4959
4990
|
await this.validate(symbol, strategyName);
|
|
4960
4991
|
return await this.strategyConnectionService.getPendingSignal(backtest, symbol, strategyName);
|
|
4961
4992
|
};
|
|
@@ -4973,9 +5004,6 @@ class StrategyCoreService {
|
|
|
4973
5004
|
symbol,
|
|
4974
5005
|
strategyName,
|
|
4975
5006
|
});
|
|
4976
|
-
if (!MethodContextService.hasContext()) {
|
|
4977
|
-
throw new Error("strategyCoreService getScheduledSignal requires a method context");
|
|
4978
|
-
}
|
|
4979
5007
|
await this.validate(symbol, strategyName);
|
|
4980
5008
|
return await this.strategyConnectionService.getScheduledSignal(backtest, symbol, strategyName);
|
|
4981
5009
|
};
|
|
@@ -4995,9 +5023,6 @@ class StrategyCoreService {
|
|
|
4995
5023
|
strategyName,
|
|
4996
5024
|
backtest,
|
|
4997
5025
|
});
|
|
4998
|
-
if (!MethodContextService.hasContext()) {
|
|
4999
|
-
throw new Error("strategyCoreService getStopped requires a method context");
|
|
5000
|
-
}
|
|
5001
5026
|
await this.validate(symbol, strategyName);
|
|
5002
5027
|
return await this.strategyConnectionService.getStopped(backtest, symbol, strategyName);
|
|
5003
5028
|
};
|
|
@@ -5254,19 +5279,20 @@ class RiskGlobalService {
|
|
|
5254
5279
|
};
|
|
5255
5280
|
/**
|
|
5256
5281
|
* Clears risk data.
|
|
5257
|
-
* If
|
|
5258
|
-
* If no
|
|
5259
|
-
* @param
|
|
5282
|
+
* If ctx is provided, clears data for that specific risk instance.
|
|
5283
|
+
* If no ctx is provided, clears all risk data.
|
|
5284
|
+
* @param backtest - Whether running in backtest mode
|
|
5285
|
+
* @param ctx - Optional context with riskName (clears all if not provided)
|
|
5260
5286
|
*/
|
|
5261
|
-
this.clear = async (backtest,
|
|
5287
|
+
this.clear = async (backtest, ctx) => {
|
|
5262
5288
|
this.loggerService.log("riskGlobalService clear", {
|
|
5263
|
-
|
|
5289
|
+
ctx,
|
|
5264
5290
|
backtest,
|
|
5265
5291
|
});
|
|
5266
|
-
if (
|
|
5267
|
-
await this.validate(riskName);
|
|
5292
|
+
if (ctx) {
|
|
5293
|
+
await this.validate(ctx.riskName);
|
|
5268
5294
|
}
|
|
5269
|
-
return await this.riskConnectionService.clear(backtest,
|
|
5295
|
+
return await this.riskConnectionService.clear(backtest, ctx);
|
|
5270
5296
|
};
|
|
5271
5297
|
}
|
|
5272
5298
|
}
|
|
@@ -7759,6 +7785,15 @@ const COLUMN_CONFIG = {
|
|
|
7759
7785
|
*/
|
|
7760
7786
|
const DEFAULT_COLUMNS = Object.freeze({ ...COLUMN_CONFIG });
|
|
7761
7787
|
|
|
7788
|
+
/**
|
|
7789
|
+
* Creates a unique key for memoizing ReportStorage instances.
|
|
7790
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
7791
|
+
* @param symbol - Trading pair symbol
|
|
7792
|
+
* @param strategyName - Name of the strategy
|
|
7793
|
+
* @param backtest - Whether running in backtest mode
|
|
7794
|
+
* @returns Unique string key for memoization
|
|
7795
|
+
*/
|
|
7796
|
+
const CREATE_KEY_FN$7 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
7762
7797
|
/**
|
|
7763
7798
|
* Checks if a value is unsafe for display (not a number, NaN, or Infinity).
|
|
7764
7799
|
*
|
|
@@ -7967,7 +8002,7 @@ class BacktestMarkdownService {
|
|
|
7967
8002
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
7968
8003
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
7969
8004
|
*/
|
|
7970
|
-
this.getStorage = memoize(([symbol, strategyName, backtest]) =>
|
|
8005
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$7(symbol, strategyName, backtest), () => new ReportStorage$5());
|
|
7971
8006
|
/**
|
|
7972
8007
|
* Processes tick events and accumulates closed signals.
|
|
7973
8008
|
* Should be called from IStrategyCallbacks.onTick.
|
|
@@ -8105,7 +8140,7 @@ class BacktestMarkdownService {
|
|
|
8105
8140
|
ctx,
|
|
8106
8141
|
});
|
|
8107
8142
|
if (ctx) {
|
|
8108
|
-
const key =
|
|
8143
|
+
const key = CREATE_KEY_FN$7(ctx.symbol, ctx.strategyName, backtest);
|
|
8109
8144
|
this.getStorage.clear(key);
|
|
8110
8145
|
}
|
|
8111
8146
|
else {
|
|
@@ -8130,6 +8165,15 @@ class BacktestMarkdownService {
|
|
|
8130
8165
|
}
|
|
8131
8166
|
}
|
|
8132
8167
|
|
|
8168
|
+
/**
|
|
8169
|
+
* Creates a unique key for memoizing ReportStorage instances.
|
|
8170
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
8171
|
+
* @param symbol - Trading pair symbol
|
|
8172
|
+
* @param strategyName - Name of the strategy
|
|
8173
|
+
* @param backtest - Whether running in backtest mode
|
|
8174
|
+
* @returns Unique string key for memoization
|
|
8175
|
+
*/
|
|
8176
|
+
const CREATE_KEY_FN$6 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8133
8177
|
/**
|
|
8134
8178
|
* Checks if a value is unsafe for display (not a number, NaN, or Infinity).
|
|
8135
8179
|
*
|
|
@@ -8459,7 +8503,7 @@ class LiveMarkdownService {
|
|
|
8459
8503
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
8460
8504
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8461
8505
|
*/
|
|
8462
|
-
this.getStorage = memoize(([symbol, strategyName, backtest]) =>
|
|
8506
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$6(symbol, strategyName, backtest), () => new ReportStorage$4());
|
|
8463
8507
|
/**
|
|
8464
8508
|
* Processes tick events and accumulates all event types.
|
|
8465
8509
|
* Should be called from IStrategyCallbacks.onTick.
|
|
@@ -8607,7 +8651,7 @@ class LiveMarkdownService {
|
|
|
8607
8651
|
ctx,
|
|
8608
8652
|
});
|
|
8609
8653
|
if (ctx) {
|
|
8610
|
-
const key =
|
|
8654
|
+
const key = CREATE_KEY_FN$6(ctx.symbol, ctx.strategyName, backtest);
|
|
8611
8655
|
this.getStorage.clear(key);
|
|
8612
8656
|
}
|
|
8613
8657
|
else {
|
|
@@ -8632,6 +8676,15 @@ class LiveMarkdownService {
|
|
|
8632
8676
|
}
|
|
8633
8677
|
}
|
|
8634
8678
|
|
|
8679
|
+
/**
|
|
8680
|
+
* Creates a unique key for memoizing ReportStorage instances.
|
|
8681
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
8682
|
+
* @param symbol - Trading pair symbol
|
|
8683
|
+
* @param strategyName - Name of the strategy
|
|
8684
|
+
* @param backtest - Whether running in backtest mode
|
|
8685
|
+
* @returns Unique string key for memoization
|
|
8686
|
+
*/
|
|
8687
|
+
const CREATE_KEY_FN$5 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8635
8688
|
/** Maximum number of events to store in schedule reports */
|
|
8636
8689
|
const MAX_EVENTS$4 = 250;
|
|
8637
8690
|
/**
|
|
@@ -8867,7 +8920,7 @@ class ScheduleMarkdownService {
|
|
|
8867
8920
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
8868
8921
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8869
8922
|
*/
|
|
8870
|
-
this.getStorage = memoize(([symbol, strategyName, backtest]) =>
|
|
8923
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$5(symbol, strategyName, backtest), () => new ReportStorage$3());
|
|
8871
8924
|
/**
|
|
8872
8925
|
* Processes tick events and accumulates scheduled/opened/cancelled events.
|
|
8873
8926
|
* Should be called from signalEmitter subscription.
|
|
@@ -9009,7 +9062,7 @@ class ScheduleMarkdownService {
|
|
|
9009
9062
|
ctx,
|
|
9010
9063
|
});
|
|
9011
9064
|
if (ctx) {
|
|
9012
|
-
const key =
|
|
9065
|
+
const key = CREATE_KEY_FN$5(ctx.symbol, ctx.strategyName, backtest);
|
|
9013
9066
|
this.getStorage.clear(key);
|
|
9014
9067
|
}
|
|
9015
9068
|
else {
|
|
@@ -9034,6 +9087,15 @@ class ScheduleMarkdownService {
|
|
|
9034
9087
|
}
|
|
9035
9088
|
}
|
|
9036
9089
|
|
|
9090
|
+
/**
|
|
9091
|
+
* Creates a unique key for memoizing PerformanceStorage instances.
|
|
9092
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
9093
|
+
* @param symbol - Trading pair symbol
|
|
9094
|
+
* @param strategyName - Name of the strategy
|
|
9095
|
+
* @param backtest - Whether running in backtest mode
|
|
9096
|
+
* @returns Unique string key for memoization
|
|
9097
|
+
*/
|
|
9098
|
+
const CREATE_KEY_FN$4 = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
9037
9099
|
/**
|
|
9038
9100
|
* Calculates percentile value from sorted array.
|
|
9039
9101
|
*/
|
|
@@ -9251,7 +9313,7 @@ class PerformanceMarkdownService {
|
|
|
9251
9313
|
* Memoized function to get or create PerformanceStorage for a symbol-strategy-backtest triple.
|
|
9252
9314
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
9253
9315
|
*/
|
|
9254
|
-
this.getStorage = memoize(([symbol, strategyName, backtest]) =>
|
|
9316
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN$4(symbol, strategyName, backtest), () => new PerformanceStorage());
|
|
9255
9317
|
/**
|
|
9256
9318
|
* Processes performance events and accumulates metrics.
|
|
9257
9319
|
* Should be called from performance tracking code.
|
|
@@ -9356,7 +9418,7 @@ class PerformanceMarkdownService {
|
|
|
9356
9418
|
ctx,
|
|
9357
9419
|
});
|
|
9358
9420
|
if (ctx) {
|
|
9359
|
-
const key =
|
|
9421
|
+
const key = CREATE_KEY_FN$4(ctx.symbol, ctx.strategyName, backtest);
|
|
9360
9422
|
this.getStorage.clear(key);
|
|
9361
9423
|
}
|
|
9362
9424
|
else {
|
|
@@ -9783,6 +9845,14 @@ class WalkerMarkdownService {
|
|
|
9783
9845
|
}
|
|
9784
9846
|
}
|
|
9785
9847
|
|
|
9848
|
+
/**
|
|
9849
|
+
* Creates a unique key for memoizing HeatmapStorage instances.
|
|
9850
|
+
* Key format: "strategyName:backtest" or "strategyName:live"
|
|
9851
|
+
* @param strategyName - Name of the strategy
|
|
9852
|
+
* @param backtest - Whether running in backtest mode
|
|
9853
|
+
* @returns Unique string key for memoization
|
|
9854
|
+
*/
|
|
9855
|
+
const CREATE_KEY_FN$3 = (strategyName, backtest) => `${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
9786
9856
|
const HEATMAP_METHOD_NAME_GET_DATA = "HeatMarkdownService.getData";
|
|
9787
9857
|
const HEATMAP_METHOD_NAME_GET_REPORT = "HeatMarkdownService.getReport";
|
|
9788
9858
|
const HEATMAP_METHOD_NAME_DUMP = "HeatMarkdownService.dump";
|
|
@@ -10126,7 +10196,7 @@ class HeatMarkdownService {
|
|
|
10126
10196
|
* Memoized function to get or create HeatmapStorage for a strategy and backtest mode.
|
|
10127
10197
|
* Each strategy + backtest mode combination gets its own isolated heatmap storage instance.
|
|
10128
10198
|
*/
|
|
10129
|
-
this.getStorage = memoize(([strategyName, backtest]) =>
|
|
10199
|
+
this.getStorage = memoize(([strategyName, backtest]) => CREATE_KEY_FN$3(strategyName, backtest), () => new HeatmapStorage());
|
|
10130
10200
|
/**
|
|
10131
10201
|
* Processes tick events and accumulates closed signals.
|
|
10132
10202
|
* Should be called from signal emitter subscription.
|
|
@@ -10262,7 +10332,7 @@ class HeatMarkdownService {
|
|
|
10262
10332
|
ctx,
|
|
10263
10333
|
});
|
|
10264
10334
|
if (ctx) {
|
|
10265
|
-
const key =
|
|
10335
|
+
const key = CREATE_KEY_FN$3(ctx.strategyName, backtest);
|
|
10266
10336
|
this.getStorage.clear(key);
|
|
10267
10337
|
}
|
|
10268
10338
|
else {
|
|
@@ -12472,6 +12542,15 @@ class ClientPartial {
|
|
|
12472
12542
|
}
|
|
12473
12543
|
}
|
|
12474
12544
|
|
|
12545
|
+
/**
|
|
12546
|
+
* Creates a unique key for memoizing ClientPartial instances.
|
|
12547
|
+
* Key format: "signalId:backtest" or "signalId:live"
|
|
12548
|
+
*
|
|
12549
|
+
* @param signalId - Signal ID
|
|
12550
|
+
* @param backtest - Whether running in backtest mode
|
|
12551
|
+
* @returns Unique string key for memoization
|
|
12552
|
+
*/
|
|
12553
|
+
const CREATE_KEY_FN$2 = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
|
|
12475
12554
|
/**
|
|
12476
12555
|
* Callback function for emitting profit events to partialProfitSubject.
|
|
12477
12556
|
*
|
|
@@ -12569,7 +12648,7 @@ class PartialConnectionService {
|
|
|
12569
12648
|
* Key format: "signalId:backtest" or "signalId:live"
|
|
12570
12649
|
* Value: ClientPartial instance with logger and event emitters
|
|
12571
12650
|
*/
|
|
12572
|
-
this.getPartial = memoize(([signalId, backtest]) =>
|
|
12651
|
+
this.getPartial = memoize(([signalId, backtest]) => CREATE_KEY_FN$2(signalId, backtest), (signalId, backtest) => {
|
|
12573
12652
|
return new ClientPartial({
|
|
12574
12653
|
signalId,
|
|
12575
12654
|
logger: this.loggerService,
|
|
@@ -12659,12 +12738,19 @@ class PartialConnectionService {
|
|
|
12659
12738
|
const partial = this.getPartial(data.id, backtest);
|
|
12660
12739
|
await partial.waitForInit(symbol, data.strategyName);
|
|
12661
12740
|
await partial.clear(symbol, data, priceClose, backtest);
|
|
12662
|
-
const key =
|
|
12741
|
+
const key = CREATE_KEY_FN$2(data.id, backtest);
|
|
12663
12742
|
this.getPartial.clear(key);
|
|
12664
12743
|
};
|
|
12665
12744
|
}
|
|
12666
12745
|
}
|
|
12667
12746
|
|
|
12747
|
+
/**
|
|
12748
|
+
* Creates a unique key for memoizing ReportStorage instances.
|
|
12749
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
12750
|
+
* @param param0 - Tuple of symbol, strategyName and backtest boolean
|
|
12751
|
+
* @returns Unique string key for memoization
|
|
12752
|
+
*/
|
|
12753
|
+
const CREATE_KEY_FN$1 = ([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
12668
12754
|
/** Maximum number of events to store in partial reports */
|
|
12669
12755
|
const MAX_EVENTS$1 = 250;
|
|
12670
12756
|
/**
|
|
@@ -12839,7 +12925,7 @@ class PartialMarkdownService {
|
|
|
12839
12925
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
12840
12926
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
12841
12927
|
*/
|
|
12842
|
-
this.getStorage = memoize(
|
|
12928
|
+
this.getStorage = memoize(CREATE_KEY_FN$1, () => new ReportStorage$1());
|
|
12843
12929
|
/**
|
|
12844
12930
|
* Processes profit events and accumulates them.
|
|
12845
12931
|
* Should be called from partialProfitSubject subscription.
|
|
@@ -12986,7 +13072,7 @@ class PartialMarkdownService {
|
|
|
12986
13072
|
ctx,
|
|
12987
13073
|
});
|
|
12988
13074
|
if (ctx) {
|
|
12989
|
-
const key =
|
|
13075
|
+
const key = CREATE_KEY_FN$1([ctx.symbol, ctx.strategyName, backtest]);
|
|
12990
13076
|
this.getStorage.clear(key);
|
|
12991
13077
|
}
|
|
12992
13078
|
else {
|
|
@@ -13421,6 +13507,15 @@ class ConfigValidationService {
|
|
|
13421
13507
|
}
|
|
13422
13508
|
}
|
|
13423
13509
|
|
|
13510
|
+
/**
|
|
13511
|
+
* Creates a unique key for memoizing ReportStorage instances.
|
|
13512
|
+
* Key format: "symbol:strategyName:backtest" or "symbol:strategyName:live"
|
|
13513
|
+
* @param symbol - Trading pair symbol
|
|
13514
|
+
* @param strategyName - Name of the strategy
|
|
13515
|
+
* @param backtest - Whether running in backtest mode
|
|
13516
|
+
* @returns Unique string key for memoization
|
|
13517
|
+
*/
|
|
13518
|
+
const CREATE_KEY_FN = (symbol, strategyName, backtest) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`;
|
|
13424
13519
|
/** Maximum number of events to store in risk reports */
|
|
13425
13520
|
const MAX_EVENTS = 250;
|
|
13426
13521
|
/**
|
|
@@ -13565,7 +13660,7 @@ class RiskMarkdownService {
|
|
|
13565
13660
|
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
13566
13661
|
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
13567
13662
|
*/
|
|
13568
|
-
this.getStorage = memoize(([symbol, strategyName, backtest]) =>
|
|
13663
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => CREATE_KEY_FN(symbol, strategyName, backtest), () => new ReportStorage());
|
|
13569
13664
|
/**
|
|
13570
13665
|
* Processes risk rejection events and accumulates them.
|
|
13571
13666
|
* Should be called from riskSubject subscription.
|
|
@@ -13693,7 +13788,7 @@ class RiskMarkdownService {
|
|
|
13693
13788
|
ctx,
|
|
13694
13789
|
});
|
|
13695
13790
|
if (ctx) {
|
|
13696
|
-
const key =
|
|
13791
|
+
const key = CREATE_KEY_FN(ctx.symbol, ctx.strategyName, backtest);
|
|
13697
13792
|
this.getStorage.clear(key);
|
|
13698
13793
|
}
|
|
13699
13794
|
else {
|
|
@@ -16405,8 +16500,8 @@ class BacktestInstance {
|
|
|
16405
16500
|
}
|
|
16406
16501
|
{
|
|
16407
16502
|
const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
|
|
16408
|
-
riskName && backtest$1.riskGlobalService.clear(true, riskName);
|
|
16409
|
-
riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, riskName));
|
|
16503
|
+
riskName && backtest$1.riskGlobalService.clear(true, { riskName });
|
|
16504
|
+
riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, { riskName }));
|
|
16410
16505
|
}
|
|
16411
16506
|
return backtest$1.backtestCommandService.run(symbol, context);
|
|
16412
16507
|
};
|
|
@@ -17079,8 +17174,8 @@ class LiveInstance {
|
|
|
17079
17174
|
}
|
|
17080
17175
|
{
|
|
17081
17176
|
const { riskName, riskList } = backtest$1.strategySchemaService.get(context.strategyName);
|
|
17082
|
-
riskName && backtest$1.riskGlobalService.clear(false, riskName);
|
|
17083
|
-
riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(false, riskName));
|
|
17177
|
+
riskName && backtest$1.riskGlobalService.clear(false, { riskName });
|
|
17178
|
+
riskList && riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(false, { riskName }));
|
|
17084
17179
|
}
|
|
17085
17180
|
return backtest$1.liveCommandService.run(symbol, context);
|
|
17086
17181
|
};
|
|
@@ -18031,9 +18126,9 @@ class WalkerInstance {
|
|
|
18031
18126
|
}
|
|
18032
18127
|
{
|
|
18033
18128
|
const { riskName, riskList } = backtest$1.strategySchemaService.get(strategyName);
|
|
18034
|
-
riskName && backtest$1.riskGlobalService.clear(true, riskName);
|
|
18129
|
+
riskName && backtest$1.riskGlobalService.clear(true, { riskName });
|
|
18035
18130
|
riskList &&
|
|
18036
|
-
riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, riskName));
|
|
18131
|
+
riskList.forEach((riskName) => backtest$1.riskGlobalService.clear(true, { riskName }));
|
|
18037
18132
|
}
|
|
18038
18133
|
}
|
|
18039
18134
|
return backtest$1.walkerCommandService.run(symbol, {
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -8937,7 +8937,7 @@ declare class RiskConnectionService {
|
|
|
8937
8937
|
* @param backtest - True if backtest mode, false if live mode
|
|
8938
8938
|
* @returns Configured ClientRisk instance
|
|
8939
8939
|
*/
|
|
8940
|
-
getRisk: ((riskName: RiskName, backtest: boolean) => ClientRisk) & functools_kit.IClearableMemoize
|
|
8940
|
+
getRisk: ((riskName: RiskName, backtest: boolean) => ClientRisk) & functools_kit.IClearableMemoize<`${string}:backtest` | `${string}:live`> & functools_kit.IControlMemoize<`${string}:backtest` | `${string}:live`, ClientRisk>;
|
|
8941
8941
|
/**
|
|
8942
8942
|
* Checks if a signal should be allowed based on risk limits.
|
|
8943
8943
|
*
|
|
@@ -8980,9 +8980,12 @@ declare class RiskConnectionService {
|
|
|
8980
8980
|
/**
|
|
8981
8981
|
* Clears the cached ClientRisk instance for the given risk name.
|
|
8982
8982
|
*
|
|
8983
|
-
* @param
|
|
8983
|
+
* @param backtest - Whether running in backtest mode
|
|
8984
|
+
* @param ctx - Optional context with riskName (clears all if not provided)
|
|
8984
8985
|
*/
|
|
8985
|
-
clear: (backtest: boolean,
|
|
8986
|
+
clear: (backtest: boolean, ctx?: {
|
|
8987
|
+
riskName: RiskName;
|
|
8988
|
+
}) => Promise<void>;
|
|
8986
8989
|
}
|
|
8987
8990
|
|
|
8988
8991
|
/**
|
|
@@ -9674,11 +9677,14 @@ declare class RiskGlobalService {
|
|
|
9674
9677
|
}) => Promise<void>;
|
|
9675
9678
|
/**
|
|
9676
9679
|
* Clears risk data.
|
|
9677
|
-
* If
|
|
9678
|
-
* If no
|
|
9679
|
-
* @param
|
|
9680
|
+
* If ctx is provided, clears data for that specific risk instance.
|
|
9681
|
+
* If no ctx is provided, clears all risk data.
|
|
9682
|
+
* @param backtest - Whether running in backtest mode
|
|
9683
|
+
* @param ctx - Optional context with riskName (clears all if not provided)
|
|
9680
9684
|
*/
|
|
9681
|
-
clear: (backtest: boolean,
|
|
9685
|
+
clear: (backtest: boolean, ctx?: {
|
|
9686
|
+
riskName: RiskName;
|
|
9687
|
+
}) => Promise<void>;
|
|
9682
9688
|
}
|
|
9683
9689
|
|
|
9684
9690
|
/**
|