backtest-kit 1.5.27 → 1.5.28
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 +657 -540
- package/build/index.mjs +657 -540
- package/package.json +1 -1
- package/types.d.ts +159 -110
package/build/index.cjs
CHANGED
|
@@ -2043,7 +2043,7 @@ const BASE_WAIT_FOR_INIT_FN_METHOD_NAME = "PersistBase.waitForInitFn";
|
|
|
2043
2043
|
const BASE_UNLINK_RETRY_COUNT = 5;
|
|
2044
2044
|
const BASE_UNLINK_RETRY_DELAY = 1000;
|
|
2045
2045
|
const BASE_WAIT_FOR_INIT_FN = async (self) => {
|
|
2046
|
-
|
|
2046
|
+
bt.loggerService.debug(BASE_WAIT_FOR_INIT_FN_METHOD_NAME, {
|
|
2047
2047
|
entityName: self.entityName,
|
|
2048
2048
|
directory: self._directory,
|
|
2049
2049
|
});
|
|
@@ -2101,7 +2101,7 @@ const PersistBase = functoolsKit.makeExtendable(class {
|
|
|
2101
2101
|
this.entityName = entityName;
|
|
2102
2102
|
this.baseDir = baseDir;
|
|
2103
2103
|
this[_a] = functoolsKit.singleshot(async () => await BASE_WAIT_FOR_INIT_FN(this));
|
|
2104
|
-
|
|
2104
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_CTOR, {
|
|
2105
2105
|
entityName: this.entityName,
|
|
2106
2106
|
baseDir,
|
|
2107
2107
|
});
|
|
@@ -2117,7 +2117,7 @@ const PersistBase = functoolsKit.makeExtendable(class {
|
|
|
2117
2117
|
return path.join(this.baseDir, this.entityName, `${entityId}.json`);
|
|
2118
2118
|
}
|
|
2119
2119
|
async waitForInit(initial) {
|
|
2120
|
-
|
|
2120
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_WAIT_FOR_INIT, {
|
|
2121
2121
|
entityName: this.entityName,
|
|
2122
2122
|
initial,
|
|
2123
2123
|
});
|
|
@@ -2134,7 +2134,7 @@ const PersistBase = functoolsKit.makeExtendable(class {
|
|
|
2134
2134
|
return length;
|
|
2135
2135
|
}
|
|
2136
2136
|
async readValue(entityId) {
|
|
2137
|
-
|
|
2137
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_READ_VALUE, {
|
|
2138
2138
|
entityName: this.entityName,
|
|
2139
2139
|
entityId,
|
|
2140
2140
|
});
|
|
@@ -2151,7 +2151,7 @@ const PersistBase = functoolsKit.makeExtendable(class {
|
|
|
2151
2151
|
}
|
|
2152
2152
|
}
|
|
2153
2153
|
async hasValue(entityId) {
|
|
2154
|
-
|
|
2154
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_HAS_VALUE, {
|
|
2155
2155
|
entityName: this.entityName,
|
|
2156
2156
|
entityId,
|
|
2157
2157
|
});
|
|
@@ -2168,7 +2168,7 @@ const PersistBase = functoolsKit.makeExtendable(class {
|
|
|
2168
2168
|
}
|
|
2169
2169
|
}
|
|
2170
2170
|
async writeValue(entityId, entity) {
|
|
2171
|
-
|
|
2171
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_WRITE_VALUE, {
|
|
2172
2172
|
entityName: this.entityName,
|
|
2173
2173
|
entityId,
|
|
2174
2174
|
});
|
|
@@ -2189,7 +2189,7 @@ const PersistBase = functoolsKit.makeExtendable(class {
|
|
|
2189
2189
|
* @throws Error if entity not found or deletion fails
|
|
2190
2190
|
*/
|
|
2191
2191
|
async removeValue(entityId) {
|
|
2192
|
-
|
|
2192
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_REMOVE_VALUE, {
|
|
2193
2193
|
entityName: this.entityName,
|
|
2194
2194
|
entityId,
|
|
2195
2195
|
});
|
|
@@ -2211,7 +2211,7 @@ const PersistBase = functoolsKit.makeExtendable(class {
|
|
|
2211
2211
|
* @throws Error if deletion fails
|
|
2212
2212
|
*/
|
|
2213
2213
|
async removeAll() {
|
|
2214
|
-
|
|
2214
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_REMOVE_ALL, {
|
|
2215
2215
|
entityName: this.entityName,
|
|
2216
2216
|
});
|
|
2217
2217
|
try {
|
|
@@ -2233,7 +2233,7 @@ const PersistBase = functoolsKit.makeExtendable(class {
|
|
|
2233
2233
|
* @throws Error if reading fails
|
|
2234
2234
|
*/
|
|
2235
2235
|
async *values() {
|
|
2236
|
-
|
|
2236
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_VALUES, {
|
|
2237
2237
|
entityName: this.entityName,
|
|
2238
2238
|
});
|
|
2239
2239
|
try {
|
|
@@ -2262,7 +2262,7 @@ const PersistBase = functoolsKit.makeExtendable(class {
|
|
|
2262
2262
|
* @throws Error if reading fails
|
|
2263
2263
|
*/
|
|
2264
2264
|
async *keys() {
|
|
2265
|
-
|
|
2265
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_KEYS, {
|
|
2266
2266
|
entityName: this.entityName,
|
|
2267
2267
|
});
|
|
2268
2268
|
try {
|
|
@@ -2367,7 +2367,7 @@ class PersistSignalUtils {
|
|
|
2367
2367
|
* @returns Promise resolving to signal or null
|
|
2368
2368
|
*/
|
|
2369
2369
|
this.readSignalData = async (symbol, strategyName) => {
|
|
2370
|
-
|
|
2370
|
+
bt.loggerService.info(PERSIST_SIGNAL_UTILS_METHOD_NAME_READ_DATA);
|
|
2371
2371
|
const key = `${symbol}:${strategyName}`;
|
|
2372
2372
|
const isInitial = !this.getSignalStorage.has(key);
|
|
2373
2373
|
const stateStorage = this.getSignalStorage(symbol, strategyName);
|
|
@@ -2389,7 +2389,7 @@ class PersistSignalUtils {
|
|
|
2389
2389
|
* @returns Promise that resolves when write is complete
|
|
2390
2390
|
*/
|
|
2391
2391
|
this.writeSignalData = async (signalRow, symbol, strategyName) => {
|
|
2392
|
-
|
|
2392
|
+
bt.loggerService.info(PERSIST_SIGNAL_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2393
2393
|
const key = `${symbol}:${strategyName}`;
|
|
2394
2394
|
const isInitial = !this.getSignalStorage.has(key);
|
|
2395
2395
|
const stateStorage = this.getSignalStorage(symbol, strategyName);
|
|
@@ -2412,7 +2412,7 @@ class PersistSignalUtils {
|
|
|
2412
2412
|
* ```
|
|
2413
2413
|
*/
|
|
2414
2414
|
usePersistSignalAdapter(Ctor) {
|
|
2415
|
-
|
|
2415
|
+
bt.loggerService.info(PERSIST_SIGNAL_UTILS_METHOD_NAME_USE_PERSIST_SIGNAL_ADAPTER);
|
|
2416
2416
|
this.PersistSignalFactory = Ctor;
|
|
2417
2417
|
}
|
|
2418
2418
|
}
|
|
@@ -2464,7 +2464,7 @@ class PersistRiskUtils {
|
|
|
2464
2464
|
* @returns Promise resolving to Map of active positions
|
|
2465
2465
|
*/
|
|
2466
2466
|
this.readPositionData = async (riskName) => {
|
|
2467
|
-
|
|
2467
|
+
bt.loggerService.info(PERSIST_RISK_UTILS_METHOD_NAME_READ_DATA);
|
|
2468
2468
|
const isInitial = !this.getRiskStorage.has(riskName);
|
|
2469
2469
|
const stateStorage = this.getRiskStorage(riskName);
|
|
2470
2470
|
await stateStorage.waitForInit(isInitial);
|
|
@@ -2485,7 +2485,7 @@ class PersistRiskUtils {
|
|
|
2485
2485
|
* @returns Promise that resolves when write is complete
|
|
2486
2486
|
*/
|
|
2487
2487
|
this.writePositionData = async (riskRow, riskName) => {
|
|
2488
|
-
|
|
2488
|
+
bt.loggerService.info(PERSIST_RISK_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2489
2489
|
const isInitial = !this.getRiskStorage.has(riskName);
|
|
2490
2490
|
const stateStorage = this.getRiskStorage(riskName);
|
|
2491
2491
|
await stateStorage.waitForInit(isInitial);
|
|
@@ -2508,7 +2508,7 @@ class PersistRiskUtils {
|
|
|
2508
2508
|
* ```
|
|
2509
2509
|
*/
|
|
2510
2510
|
usePersistRiskAdapter(Ctor) {
|
|
2511
|
-
|
|
2511
|
+
bt.loggerService.info(PERSIST_RISK_UTILS_METHOD_NAME_USE_PERSIST_RISK_ADAPTER);
|
|
2512
2512
|
this.PersistRiskFactory = Ctor;
|
|
2513
2513
|
}
|
|
2514
2514
|
}
|
|
@@ -2558,7 +2558,7 @@ class PersistScheduleUtils {
|
|
|
2558
2558
|
* @returns Promise resolving to scheduled signal or null
|
|
2559
2559
|
*/
|
|
2560
2560
|
this.readScheduleData = async (symbol, strategyName) => {
|
|
2561
|
-
|
|
2561
|
+
bt.loggerService.info(PERSIST_SCHEDULE_UTILS_METHOD_NAME_READ_DATA);
|
|
2562
2562
|
const key = `${symbol}:${strategyName}`;
|
|
2563
2563
|
const isInitial = !this.getScheduleStorage.has(key);
|
|
2564
2564
|
const stateStorage = this.getScheduleStorage(symbol, strategyName);
|
|
@@ -2580,7 +2580,7 @@ class PersistScheduleUtils {
|
|
|
2580
2580
|
* @returns Promise that resolves when write is complete
|
|
2581
2581
|
*/
|
|
2582
2582
|
this.writeScheduleData = async (scheduledSignalRow, symbol, strategyName) => {
|
|
2583
|
-
|
|
2583
|
+
bt.loggerService.info(PERSIST_SCHEDULE_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2584
2584
|
const key = `${symbol}:${strategyName}`;
|
|
2585
2585
|
const isInitial = !this.getScheduleStorage.has(key);
|
|
2586
2586
|
const stateStorage = this.getScheduleStorage(symbol, strategyName);
|
|
@@ -2603,7 +2603,7 @@ class PersistScheduleUtils {
|
|
|
2603
2603
|
* ```
|
|
2604
2604
|
*/
|
|
2605
2605
|
usePersistScheduleAdapter(Ctor) {
|
|
2606
|
-
|
|
2606
|
+
bt.loggerService.info(PERSIST_SCHEDULE_UTILS_METHOD_NAME_USE_PERSIST_SCHEDULE_ADAPTER);
|
|
2607
2607
|
this.PersistScheduleFactory = Ctor;
|
|
2608
2608
|
}
|
|
2609
2609
|
}
|
|
@@ -2653,7 +2653,7 @@ class PersistPartialUtils {
|
|
|
2653
2653
|
* @returns Promise resolving to partial data record
|
|
2654
2654
|
*/
|
|
2655
2655
|
this.readPartialData = async (symbol, strategyName) => {
|
|
2656
|
-
|
|
2656
|
+
bt.loggerService.info(PERSIST_PARTIAL_UTILS_METHOD_NAME_READ_DATA);
|
|
2657
2657
|
const key = `${symbol}:${strategyName}`;
|
|
2658
2658
|
const isInitial = !this.getPartialStorage.has(key);
|
|
2659
2659
|
const stateStorage = this.getPartialStorage(symbol, strategyName);
|
|
@@ -2676,7 +2676,7 @@ class PersistPartialUtils {
|
|
|
2676
2676
|
* @returns Promise that resolves when write is complete
|
|
2677
2677
|
*/
|
|
2678
2678
|
this.writePartialData = async (partialData, symbol, strategyName) => {
|
|
2679
|
-
|
|
2679
|
+
bt.loggerService.info(PERSIST_PARTIAL_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2680
2680
|
const key = `${symbol}:${strategyName}`;
|
|
2681
2681
|
const isInitial = !this.getPartialStorage.has(key);
|
|
2682
2682
|
const stateStorage = this.getPartialStorage(symbol, strategyName);
|
|
@@ -2700,7 +2700,7 @@ class PersistPartialUtils {
|
|
|
2700
2700
|
* ```
|
|
2701
2701
|
*/
|
|
2702
2702
|
usePersistPartialAdapter(Ctor) {
|
|
2703
|
-
|
|
2703
|
+
bt.loggerService.info(PERSIST_PARTIAL_UTILS_METHOD_NAME_USE_PERSIST_PARTIAL_ADAPTER);
|
|
2704
2704
|
this.PersistPartialFactory = Ctor;
|
|
2705
2705
|
}
|
|
2706
2706
|
}
|
|
@@ -3169,7 +3169,7 @@ const GET_SIGNAL_FN = functoolsKit.trycatch(async (self) => {
|
|
|
3169
3169
|
error: functoolsKit.errorData(error),
|
|
3170
3170
|
message: functoolsKit.getErrorMessage(error),
|
|
3171
3171
|
};
|
|
3172
|
-
|
|
3172
|
+
bt.loggerService.warn(message, payload);
|
|
3173
3173
|
console.warn(message, payload);
|
|
3174
3174
|
errorEmitter.next(error);
|
|
3175
3175
|
},
|
|
@@ -3248,6 +3248,7 @@ const CHECK_SCHEDULED_SIGNAL_TIMEOUT_FN = async (self, scheduled, currentPrice)
|
|
|
3248
3248
|
strategyName: self.params.method.context.strategyName,
|
|
3249
3249
|
exchangeName: self.params.method.context.exchangeName,
|
|
3250
3250
|
symbol: self.params.execution.context.symbol,
|
|
3251
|
+
backtest: self.params.execution.context.backtest,
|
|
3251
3252
|
};
|
|
3252
3253
|
if (self.params.callbacks?.onTick) {
|
|
3253
3254
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3299,6 +3300,7 @@ const CANCEL_SCHEDULED_SIGNAL_BY_STOPLOSS_FN = async (self, scheduled, currentPr
|
|
|
3299
3300
|
exchangeName: self.params.method.context.exchangeName,
|
|
3300
3301
|
symbol: self.params.execution.context.symbol,
|
|
3301
3302
|
currentPrice: currentPrice,
|
|
3303
|
+
backtest: self.params.execution.context.backtest,
|
|
3302
3304
|
};
|
|
3303
3305
|
if (self.params.callbacks?.onTick) {
|
|
3304
3306
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3366,6 +3368,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
|
|
|
3366
3368
|
exchangeName: self.params.method.context.exchangeName,
|
|
3367
3369
|
symbol: self.params.execution.context.symbol,
|
|
3368
3370
|
currentPrice: self._pendingSignal.priceOpen,
|
|
3371
|
+
backtest: self.params.execution.context.backtest,
|
|
3369
3372
|
};
|
|
3370
3373
|
if (self.params.callbacks?.onTick) {
|
|
3371
3374
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3382,6 +3385,7 @@ const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice)
|
|
|
3382
3385
|
symbol: self.params.execution.context.symbol,
|
|
3383
3386
|
percentTp: 0,
|
|
3384
3387
|
percentSl: 0,
|
|
3388
|
+
backtest: self.params.execution.context.backtest,
|
|
3385
3389
|
};
|
|
3386
3390
|
if (self.params.callbacks?.onTick) {
|
|
3387
3391
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3407,6 +3411,7 @@ const OPEN_NEW_SCHEDULED_SIGNAL_FN = async (self, signal) => {
|
|
|
3407
3411
|
exchangeName: self.params.method.context.exchangeName,
|
|
3408
3412
|
symbol: self.params.execution.context.symbol,
|
|
3409
3413
|
currentPrice: currentPrice,
|
|
3414
|
+
backtest: self.params.execution.context.backtest,
|
|
3410
3415
|
};
|
|
3411
3416
|
if (self.params.callbacks?.onTick) {
|
|
3412
3417
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3438,6 +3443,7 @@ const OPEN_NEW_PENDING_SIGNAL_FN = async (self, signal) => {
|
|
|
3438
3443
|
exchangeName: self.params.method.context.exchangeName,
|
|
3439
3444
|
symbol: self.params.execution.context.symbol,
|
|
3440
3445
|
currentPrice: signal.priceOpen,
|
|
3446
|
+
backtest: self.params.execution.context.backtest,
|
|
3441
3447
|
};
|
|
3442
3448
|
if (self.params.callbacks?.onTick) {
|
|
3443
3449
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3502,6 +3508,7 @@ const CLOSE_PENDING_SIGNAL_FN = async (self, signal, currentPrice, closeReason)
|
|
|
3502
3508
|
strategyName: self.params.method.context.strategyName,
|
|
3503
3509
|
exchangeName: self.params.method.context.exchangeName,
|
|
3504
3510
|
symbol: self.params.execution.context.symbol,
|
|
3511
|
+
backtest: self.params.execution.context.backtest,
|
|
3505
3512
|
};
|
|
3506
3513
|
if (self.params.callbacks?.onTick) {
|
|
3507
3514
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3571,6 +3578,7 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice) => {
|
|
|
3571
3578
|
symbol: self.params.execution.context.symbol,
|
|
3572
3579
|
percentTp,
|
|
3573
3580
|
percentSl,
|
|
3581
|
+
backtest: self.params.execution.context.backtest,
|
|
3574
3582
|
};
|
|
3575
3583
|
if (self.params.callbacks?.onTick) {
|
|
3576
3584
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3588,6 +3596,7 @@ const RETURN_IDLE_FN = async (self, currentPrice) => {
|
|
|
3588
3596
|
exchangeName: self.params.method.context.exchangeName,
|
|
3589
3597
|
symbol: self.params.execution.context.symbol,
|
|
3590
3598
|
currentPrice: currentPrice,
|
|
3599
|
+
backtest: self.params.execution.context.backtest,
|
|
3591
3600
|
};
|
|
3592
3601
|
if (self.params.callbacks?.onTick) {
|
|
3593
3602
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3614,6 +3623,7 @@ const CANCEL_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, averagePr
|
|
|
3614
3623
|
strategyName: self.params.method.context.strategyName,
|
|
3615
3624
|
exchangeName: self.params.method.context.exchangeName,
|
|
3616
3625
|
symbol: self.params.execution.context.symbol,
|
|
3626
|
+
backtest: self.params.execution.context.backtest,
|
|
3617
3627
|
};
|
|
3618
3628
|
if (self.params.callbacks?.onTick) {
|
|
3619
3629
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3709,6 +3719,7 @@ const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, c
|
|
|
3709
3719
|
strategyName: self.params.method.context.strategyName,
|
|
3710
3720
|
exchangeName: self.params.method.context.exchangeName,
|
|
3711
3721
|
symbol: self.params.execution.context.symbol,
|
|
3722
|
+
backtest: self.params.execution.context.backtest,
|
|
3712
3723
|
};
|
|
3713
3724
|
if (self.params.callbacks?.onTick) {
|
|
3714
3725
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -4207,6 +4218,7 @@ class ClientStrategy {
|
|
|
4207
4218
|
strategyName: this.params.method.context.strategyName,
|
|
4208
4219
|
exchangeName: this.params.method.context.exchangeName,
|
|
4209
4220
|
symbol: this.params.execution.context.symbol,
|
|
4221
|
+
backtest: this.params.execution.context.backtest,
|
|
4210
4222
|
};
|
|
4211
4223
|
return result; // Cast to IStrategyBacktestResult (which includes Active)
|
|
4212
4224
|
}
|
|
@@ -4337,7 +4349,7 @@ class MergeRisk {
|
|
|
4337
4349
|
* @returns Promise resolving to true if all risks approve, false if any risk rejects
|
|
4338
4350
|
*/
|
|
4339
4351
|
async checkSignal(params) {
|
|
4340
|
-
|
|
4352
|
+
bt.loggerService.info("MergeRisk checkSignal", {
|
|
4341
4353
|
params,
|
|
4342
4354
|
});
|
|
4343
4355
|
const riskCheck = await Promise.all(this._riskList.map(async (risk) => await risk.checkSignal(params)));
|
|
@@ -4354,7 +4366,7 @@ class MergeRisk {
|
|
|
4354
4366
|
* @returns Promise that resolves when all risks have registered the signal
|
|
4355
4367
|
*/
|
|
4356
4368
|
async addSignal(symbol, context) {
|
|
4357
|
-
|
|
4369
|
+
bt.loggerService.info("MergeRisk addSignal", {
|
|
4358
4370
|
symbol,
|
|
4359
4371
|
context,
|
|
4360
4372
|
});
|
|
@@ -4371,7 +4383,7 @@ class MergeRisk {
|
|
|
4371
4383
|
* @returns Promise that resolves when all risks have removed the signal
|
|
4372
4384
|
*/
|
|
4373
4385
|
async removeSignal(symbol, context) {
|
|
4374
|
-
|
|
4386
|
+
bt.loggerService.info("MergeRisk removeSignal", {
|
|
4375
4387
|
symbol,
|
|
4376
4388
|
context,
|
|
4377
4389
|
});
|
|
@@ -4439,19 +4451,19 @@ class RiskUtils {
|
|
|
4439
4451
|
* }
|
|
4440
4452
|
* ```
|
|
4441
4453
|
*/
|
|
4442
|
-
this.getData = async (symbol, strategyName) => {
|
|
4443
|
-
|
|
4454
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
4455
|
+
bt.loggerService.info(RISK_METHOD_NAME_GET_DATA, {
|
|
4444
4456
|
symbol,
|
|
4445
4457
|
strategyName,
|
|
4446
4458
|
});
|
|
4447
|
-
|
|
4459
|
+
bt.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_GET_DATA);
|
|
4448
4460
|
{
|
|
4449
|
-
const { riskName, riskList } =
|
|
4461
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
4450
4462
|
riskName &&
|
|
4451
|
-
|
|
4452
|
-
riskList && riskList.forEach((riskName) =>
|
|
4463
|
+
bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_DATA);
|
|
4464
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_DATA));
|
|
4453
4465
|
}
|
|
4454
|
-
return await
|
|
4466
|
+
return await bt.riskMarkdownService.getData(symbol, strategyName, backtest);
|
|
4455
4467
|
};
|
|
4456
4468
|
/**
|
|
4457
4469
|
* Generates markdown report with all risk rejection events for a symbol-strategy pair.
|
|
@@ -4494,19 +4506,19 @@ class RiskUtils {
|
|
|
4494
4506
|
* // - my-strategy: 1
|
|
4495
4507
|
* ```
|
|
4496
4508
|
*/
|
|
4497
|
-
this.getReport = async (symbol, strategyName, columns) => {
|
|
4498
|
-
|
|
4509
|
+
this.getReport = async (symbol, strategyName, backtest, columns) => {
|
|
4510
|
+
bt.loggerService.info(RISK_METHOD_NAME_GET_REPORT, {
|
|
4499
4511
|
symbol,
|
|
4500
4512
|
strategyName,
|
|
4501
4513
|
});
|
|
4502
|
-
|
|
4514
|
+
bt.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_GET_REPORT);
|
|
4503
4515
|
{
|
|
4504
|
-
const { riskName, riskList } =
|
|
4516
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
4505
4517
|
riskName &&
|
|
4506
|
-
|
|
4507
|
-
riskList && riskList.forEach((riskName) =>
|
|
4518
|
+
bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_REPORT);
|
|
4519
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_REPORT));
|
|
4508
4520
|
}
|
|
4509
|
-
return await
|
|
4521
|
+
return await bt.riskMarkdownService.getReport(symbol, strategyName, backtest, columns);
|
|
4510
4522
|
};
|
|
4511
4523
|
/**
|
|
4512
4524
|
* Generates and saves markdown report to file.
|
|
@@ -4540,20 +4552,20 @@ class RiskUtils {
|
|
|
4540
4552
|
* }
|
|
4541
4553
|
* ```
|
|
4542
4554
|
*/
|
|
4543
|
-
this.dump = async (symbol, strategyName, path, columns) => {
|
|
4544
|
-
|
|
4555
|
+
this.dump = async (symbol, strategyName, backtest, path, columns) => {
|
|
4556
|
+
bt.loggerService.info(RISK_METHOD_NAME_DUMP, {
|
|
4545
4557
|
symbol,
|
|
4546
4558
|
strategyName,
|
|
4547
4559
|
path,
|
|
4548
4560
|
});
|
|
4549
|
-
|
|
4561
|
+
bt.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_DUMP);
|
|
4550
4562
|
{
|
|
4551
|
-
const { riskName, riskList } =
|
|
4563
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
4552
4564
|
riskName &&
|
|
4553
|
-
|
|
4554
|
-
riskList && riskList.forEach((riskName) =>
|
|
4565
|
+
bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_DUMP);
|
|
4566
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_DUMP));
|
|
4555
4567
|
}
|
|
4556
|
-
await
|
|
4568
|
+
await bt.riskMarkdownService.dump(symbol, strategyName, backtest, path, columns);
|
|
4557
4569
|
};
|
|
4558
4570
|
}
|
|
4559
4571
|
}
|
|
@@ -5171,7 +5183,7 @@ const DO_VALIDATION_FN = functoolsKit.trycatch(async (validation, params) => {
|
|
|
5171
5183
|
error: functoolsKit.errorData(error),
|
|
5172
5184
|
message: functoolsKit.getErrorMessage(error),
|
|
5173
5185
|
};
|
|
5174
|
-
|
|
5186
|
+
bt.loggerService.warn(message, payload);
|
|
5175
5187
|
console.warn(message, payload);
|
|
5176
5188
|
validationSubject.next(error);
|
|
5177
5189
|
},
|
|
@@ -5266,7 +5278,7 @@ class ClientRisk {
|
|
|
5266
5278
|
}
|
|
5267
5279
|
if (!isValid) {
|
|
5268
5280
|
// Call params.onRejected for riskSubject emission
|
|
5269
|
-
await this.params.onRejected(params.symbol, params, riskMap.size, rejectionNote, Date.now());
|
|
5281
|
+
await this.params.onRejected(params.symbol, params, riskMap.size, rejectionNote, Date.now(), this.params.backtest);
|
|
5270
5282
|
// Call schema callbacks.onRejected if defined
|
|
5271
5283
|
if (this.params.callbacks?.onRejected) {
|
|
5272
5284
|
this.params.callbacks.onRejected(params.symbol, params);
|
|
@@ -5347,8 +5359,9 @@ class ClientRisk {
|
|
|
5347
5359
|
* @param activePositionCount - Number of active positions at rejection time
|
|
5348
5360
|
* @param comment - Rejection reason from validation note or "N/A"
|
|
5349
5361
|
* @param timestamp - Event timestamp in milliseconds
|
|
5362
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
5350
5363
|
*/
|
|
5351
|
-
const COMMIT_REJECTION_FN = async (symbol, params, activePositionCount, comment, timestamp) => await riskSubject.next({
|
|
5364
|
+
const COMMIT_REJECTION_FN = async (symbol, params, activePositionCount, comment, timestamp, backtest) => await riskSubject.next({
|
|
5352
5365
|
symbol,
|
|
5353
5366
|
pendingSignal: params.pendingSignal,
|
|
5354
5367
|
strategyName: params.strategyName,
|
|
@@ -5357,6 +5370,7 @@ const COMMIT_REJECTION_FN = async (symbol, params, activePositionCount, comment,
|
|
|
5357
5370
|
activePositionCount,
|
|
5358
5371
|
comment,
|
|
5359
5372
|
timestamp,
|
|
5373
|
+
backtest,
|
|
5360
5374
|
});
|
|
5361
5375
|
/**
|
|
5362
5376
|
* Connection service routing risk operations to correct ClientRisk instance.
|
|
@@ -7031,7 +7045,7 @@ class WalkerLogicPrivateService {
|
|
|
7031
7045
|
symbol,
|
|
7032
7046
|
});
|
|
7033
7047
|
// Get statistics from BacktestMarkdownService
|
|
7034
|
-
const stats = await this.backtestMarkdownService.getData(symbol, strategyName);
|
|
7048
|
+
const stats = await this.backtestMarkdownService.getData(symbol, strategyName, true);
|
|
7035
7049
|
// Extract metric value
|
|
7036
7050
|
const value = stats[metric];
|
|
7037
7051
|
const metricValue = value !== null &&
|
|
@@ -7095,7 +7109,7 @@ class WalkerLogicPrivateService {
|
|
|
7095
7109
|
bestStrategy,
|
|
7096
7110
|
bestMetric,
|
|
7097
7111
|
bestStats: bestStrategy !== null
|
|
7098
|
-
? await this.backtestMarkdownService.getData(symbol, bestStrategy)
|
|
7112
|
+
? await this.backtestMarkdownService.getData(symbol, bestStrategy, true)
|
|
7099
7113
|
: null,
|
|
7100
7114
|
};
|
|
7101
7115
|
// Call onComplete callback if provided with final best results
|
|
@@ -7608,10 +7622,10 @@ class BacktestMarkdownService {
|
|
|
7608
7622
|
/** Logger service for debug output */
|
|
7609
7623
|
this.loggerService = inject(TYPES.loggerService);
|
|
7610
7624
|
/**
|
|
7611
|
-
* Memoized function to get or create ReportStorage for a symbol-strategy
|
|
7612
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
7625
|
+
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
7626
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
7613
7627
|
*/
|
|
7614
|
-
this.getStorage = functoolsKit.memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new ReportStorage$5());
|
|
7628
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$5());
|
|
7615
7629
|
/**
|
|
7616
7630
|
* Processes tick events and accumulates closed signals.
|
|
7617
7631
|
* Should be called from IStrategyCallbacks.onTick.
|
|
@@ -7638,7 +7652,7 @@ class BacktestMarkdownService {
|
|
|
7638
7652
|
if (data.action !== "closed") {
|
|
7639
7653
|
return;
|
|
7640
7654
|
}
|
|
7641
|
-
const storage = this.getStorage(data.symbol, data.strategyName);
|
|
7655
|
+
const storage = this.getStorage(data.symbol, data.strategyName, true);
|
|
7642
7656
|
storage.addSignal(data);
|
|
7643
7657
|
};
|
|
7644
7658
|
/**
|
|
@@ -7647,21 +7661,23 @@ class BacktestMarkdownService {
|
|
|
7647
7661
|
*
|
|
7648
7662
|
* @param symbol - Trading pair symbol
|
|
7649
7663
|
* @param strategyName - Strategy name to get data for
|
|
7664
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
7650
7665
|
* @returns Statistical data object with all metrics
|
|
7651
7666
|
*
|
|
7652
7667
|
* @example
|
|
7653
7668
|
* ```typescript
|
|
7654
7669
|
* const service = new BacktestMarkdownService();
|
|
7655
|
-
* const stats = await service.getData("BTCUSDT", "my-strategy");
|
|
7670
|
+
* const stats = await service.getData("BTCUSDT", "my-strategy", true);
|
|
7656
7671
|
* console.log(stats.sharpeRatio, stats.winRate);
|
|
7657
7672
|
* ```
|
|
7658
7673
|
*/
|
|
7659
|
-
this.getData = async (symbol, strategyName) => {
|
|
7674
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
7660
7675
|
this.loggerService.log("backtestMarkdownService getData", {
|
|
7661
7676
|
symbol,
|
|
7662
7677
|
strategyName,
|
|
7678
|
+
backtest,
|
|
7663
7679
|
});
|
|
7664
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
7680
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
7665
7681
|
return storage.getData();
|
|
7666
7682
|
};
|
|
7667
7683
|
/**
|
|
@@ -7670,22 +7686,24 @@ class BacktestMarkdownService {
|
|
|
7670
7686
|
*
|
|
7671
7687
|
* @param symbol - Trading pair symbol
|
|
7672
7688
|
* @param strategyName - Strategy name to generate report for
|
|
7689
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
7673
7690
|
* @param columns - Column configuration for formatting the table
|
|
7674
7691
|
* @returns Markdown formatted report string with table of all closed signals
|
|
7675
7692
|
*
|
|
7676
7693
|
* @example
|
|
7677
7694
|
* ```typescript
|
|
7678
7695
|
* const service = new BacktestMarkdownService();
|
|
7679
|
-
* const markdown = await service.getReport("BTCUSDT", "my-strategy");
|
|
7696
|
+
* const markdown = await service.getReport("BTCUSDT", "my-strategy", true);
|
|
7680
7697
|
* console.log(markdown);
|
|
7681
7698
|
* ```
|
|
7682
7699
|
*/
|
|
7683
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.backtest_columns) => {
|
|
7700
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.backtest_columns) => {
|
|
7684
7701
|
this.loggerService.log("backtestMarkdownService getReport", {
|
|
7685
7702
|
symbol,
|
|
7686
7703
|
strategyName,
|
|
7704
|
+
backtest,
|
|
7687
7705
|
});
|
|
7688
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
7706
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
7689
7707
|
return storage.getReport(strategyName, columns);
|
|
7690
7708
|
};
|
|
7691
7709
|
/**
|
|
@@ -7695,6 +7713,7 @@ class BacktestMarkdownService {
|
|
|
7695
7713
|
*
|
|
7696
7714
|
* @param symbol - Trading pair symbol
|
|
7697
7715
|
* @param strategyName - Strategy name to save report for
|
|
7716
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
7698
7717
|
* @param path - Directory path to save report (default: "./dump/backtest")
|
|
7699
7718
|
* @param columns - Column configuration for formatting the table
|
|
7700
7719
|
*
|
|
@@ -7703,45 +7722,48 @@ class BacktestMarkdownService {
|
|
|
7703
7722
|
* const service = new BacktestMarkdownService();
|
|
7704
7723
|
*
|
|
7705
7724
|
* // Save to default path: ./dump/backtest/my-strategy.md
|
|
7706
|
-
* await service.dump("BTCUSDT", "my-strategy");
|
|
7725
|
+
* await service.dump("BTCUSDT", "my-strategy", true);
|
|
7707
7726
|
*
|
|
7708
7727
|
* // Save to custom path: ./custom/path/my-strategy.md
|
|
7709
|
-
* await service.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
7728
|
+
* await service.dump("BTCUSDT", "my-strategy", true, "./custom/path");
|
|
7710
7729
|
* ```
|
|
7711
7730
|
*/
|
|
7712
|
-
this.dump = async (symbol, strategyName, path = "./dump/backtest", columns = COLUMN_CONFIG.backtest_columns) => {
|
|
7731
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/backtest", columns = COLUMN_CONFIG.backtest_columns) => {
|
|
7713
7732
|
this.loggerService.log("backtestMarkdownService dump", {
|
|
7714
7733
|
symbol,
|
|
7715
7734
|
strategyName,
|
|
7735
|
+
backtest,
|
|
7716
7736
|
path,
|
|
7717
7737
|
});
|
|
7718
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
7738
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
7719
7739
|
await storage.dump(strategyName, path, columns);
|
|
7720
7740
|
};
|
|
7721
7741
|
/**
|
|
7722
7742
|
* Clears accumulated signal data from storage.
|
|
7723
|
-
* If ctx is provided, clears only that specific symbol-strategy
|
|
7743
|
+
* If ctx is provided, clears only that specific symbol-strategy-backtest triple's data.
|
|
7724
7744
|
* If nothing is provided, clears all data.
|
|
7725
7745
|
*
|
|
7746
|
+
* @param backtest - Backtest mode flag
|
|
7726
7747
|
* @param ctx - Optional context with symbol and strategyName
|
|
7727
7748
|
*
|
|
7728
7749
|
* @example
|
|
7729
7750
|
* ```typescript
|
|
7730
7751
|
* const service = new BacktestMarkdownService();
|
|
7731
7752
|
*
|
|
7732
|
-
* // Clear specific symbol-strategy
|
|
7733
|
-
* await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
7753
|
+
* // Clear specific symbol-strategy-backtest triple
|
|
7754
|
+
* await service.clear(true, { symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
7734
7755
|
*
|
|
7735
7756
|
* // Clear all data
|
|
7736
7757
|
* await service.clear();
|
|
7737
7758
|
* ```
|
|
7738
7759
|
*/
|
|
7739
|
-
this.clear = async (ctx) => {
|
|
7760
|
+
this.clear = async (backtest, ctx) => {
|
|
7740
7761
|
this.loggerService.log("backtestMarkdownService clear", {
|
|
7762
|
+
backtest,
|
|
7741
7763
|
ctx,
|
|
7742
7764
|
});
|
|
7743
7765
|
if (ctx) {
|
|
7744
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
7766
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
7745
7767
|
this.getStorage.clear(key);
|
|
7746
7768
|
}
|
|
7747
7769
|
else {
|
|
@@ -8092,10 +8114,10 @@ class LiveMarkdownService {
|
|
|
8092
8114
|
/** Logger service for debug output */
|
|
8093
8115
|
this.loggerService = inject(TYPES.loggerService);
|
|
8094
8116
|
/**
|
|
8095
|
-
* Memoized function to get or create ReportStorage for a symbol-strategy
|
|
8096
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
8117
|
+
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
8118
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8097
8119
|
*/
|
|
8098
|
-
this.getStorage = functoolsKit.memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new ReportStorage$4());
|
|
8120
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$4());
|
|
8099
8121
|
/**
|
|
8100
8122
|
* Processes tick events and accumulates all event types.
|
|
8101
8123
|
* Should be called from IStrategyCallbacks.onTick.
|
|
@@ -8121,7 +8143,7 @@ class LiveMarkdownService {
|
|
|
8121
8143
|
this.loggerService.log("liveMarkdownService tick", {
|
|
8122
8144
|
data,
|
|
8123
8145
|
});
|
|
8124
|
-
const storage = this.getStorage(data.symbol, data.strategyName);
|
|
8146
|
+
const storage = this.getStorage(data.symbol, data.strategyName, false);
|
|
8125
8147
|
if (data.action === "idle") {
|
|
8126
8148
|
storage.addIdleEvent(data.currentPrice);
|
|
8127
8149
|
}
|
|
@@ -8141,21 +8163,23 @@ class LiveMarkdownService {
|
|
|
8141
8163
|
*
|
|
8142
8164
|
* @param symbol - Trading pair symbol
|
|
8143
8165
|
* @param strategyName - Strategy name to get data for
|
|
8166
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8144
8167
|
* @returns Statistical data object with all metrics
|
|
8145
8168
|
*
|
|
8146
8169
|
* @example
|
|
8147
8170
|
* ```typescript
|
|
8148
8171
|
* const service = new LiveMarkdownService();
|
|
8149
|
-
* const stats = await service.getData("BTCUSDT", "my-strategy");
|
|
8172
|
+
* const stats = await service.getData("BTCUSDT", "my-strategy", false);
|
|
8150
8173
|
* console.log(stats.sharpeRatio, stats.winRate);
|
|
8151
8174
|
* ```
|
|
8152
8175
|
*/
|
|
8153
|
-
this.getData = async (symbol, strategyName) => {
|
|
8176
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
8154
8177
|
this.loggerService.log("liveMarkdownService getData", {
|
|
8155
8178
|
symbol,
|
|
8156
8179
|
strategyName,
|
|
8180
|
+
backtest,
|
|
8157
8181
|
});
|
|
8158
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8182
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8159
8183
|
return storage.getData();
|
|
8160
8184
|
};
|
|
8161
8185
|
/**
|
|
@@ -8164,22 +8188,24 @@ class LiveMarkdownService {
|
|
|
8164
8188
|
*
|
|
8165
8189
|
* @param symbol - Trading pair symbol
|
|
8166
8190
|
* @param strategyName - Strategy name to generate report for
|
|
8191
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8167
8192
|
* @param columns - Column configuration for formatting the table
|
|
8168
8193
|
* @returns Markdown formatted report string with table of all events
|
|
8169
8194
|
*
|
|
8170
8195
|
* @example
|
|
8171
8196
|
* ```typescript
|
|
8172
8197
|
* const service = new LiveMarkdownService();
|
|
8173
|
-
* const markdown = await service.getReport("BTCUSDT", "my-strategy");
|
|
8198
|
+
* const markdown = await service.getReport("BTCUSDT", "my-strategy", false);
|
|
8174
8199
|
* console.log(markdown);
|
|
8175
8200
|
* ```
|
|
8176
8201
|
*/
|
|
8177
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.live_columns) => {
|
|
8202
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.live_columns) => {
|
|
8178
8203
|
this.loggerService.log("liveMarkdownService getReport", {
|
|
8179
8204
|
symbol,
|
|
8180
8205
|
strategyName,
|
|
8206
|
+
backtest,
|
|
8181
8207
|
});
|
|
8182
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8208
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8183
8209
|
return storage.getReport(strategyName, columns);
|
|
8184
8210
|
};
|
|
8185
8211
|
/**
|
|
@@ -8189,6 +8215,7 @@ class LiveMarkdownService {
|
|
|
8189
8215
|
*
|
|
8190
8216
|
* @param symbol - Trading pair symbol
|
|
8191
8217
|
* @param strategyName - Strategy name to save report for
|
|
8218
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8192
8219
|
* @param path - Directory path to save report (default: "./dump/live")
|
|
8193
8220
|
* @param columns - Column configuration for formatting the table
|
|
8194
8221
|
*
|
|
@@ -8197,45 +8224,48 @@ class LiveMarkdownService {
|
|
|
8197
8224
|
* const service = new LiveMarkdownService();
|
|
8198
8225
|
*
|
|
8199
8226
|
* // Save to default path: ./dump/live/my-strategy.md
|
|
8200
|
-
* await service.dump("BTCUSDT", "my-strategy");
|
|
8227
|
+
* await service.dump("BTCUSDT", "my-strategy", false);
|
|
8201
8228
|
*
|
|
8202
8229
|
* // Save to custom path: ./custom/path/my-strategy.md
|
|
8203
|
-
* await service.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
8230
|
+
* await service.dump("BTCUSDT", "my-strategy", false, "./custom/path");
|
|
8204
8231
|
* ```
|
|
8205
8232
|
*/
|
|
8206
|
-
this.dump = async (symbol, strategyName, path = "./dump/live", columns = COLUMN_CONFIG.live_columns) => {
|
|
8233
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/live", columns = COLUMN_CONFIG.live_columns) => {
|
|
8207
8234
|
this.loggerService.log("liveMarkdownService dump", {
|
|
8208
8235
|
symbol,
|
|
8209
8236
|
strategyName,
|
|
8237
|
+
backtest,
|
|
8210
8238
|
path,
|
|
8211
8239
|
});
|
|
8212
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8240
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8213
8241
|
await storage.dump(strategyName, path, columns);
|
|
8214
8242
|
};
|
|
8215
8243
|
/**
|
|
8216
8244
|
* Clears accumulated event data from storage.
|
|
8217
|
-
* If ctx is provided, clears only that specific symbol-strategy
|
|
8245
|
+
* If ctx is provided, clears only that specific symbol-strategy-backtest triple's data.
|
|
8218
8246
|
* If nothing is provided, clears all data.
|
|
8219
8247
|
*
|
|
8248
|
+
* @param backtest - Backtest mode flag
|
|
8220
8249
|
* @param ctx - Optional context with symbol and strategyName
|
|
8221
8250
|
*
|
|
8222
8251
|
* @example
|
|
8223
8252
|
* ```typescript
|
|
8224
8253
|
* const service = new LiveMarkdownService();
|
|
8225
8254
|
*
|
|
8226
|
-
* // Clear specific symbol-strategy
|
|
8227
|
-
* await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
8255
|
+
* // Clear specific symbol-strategy-backtest triple
|
|
8256
|
+
* await service.clear(false, { symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
8228
8257
|
*
|
|
8229
8258
|
* // Clear all data
|
|
8230
8259
|
* await service.clear();
|
|
8231
8260
|
* ```
|
|
8232
8261
|
*/
|
|
8233
|
-
this.clear = async (ctx) => {
|
|
8262
|
+
this.clear = async (backtest, ctx) => {
|
|
8234
8263
|
this.loggerService.log("liveMarkdownService clear", {
|
|
8264
|
+
backtest,
|
|
8235
8265
|
ctx,
|
|
8236
8266
|
});
|
|
8237
8267
|
if (ctx) {
|
|
8238
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
8268
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8239
8269
|
this.getStorage.clear(key);
|
|
8240
8270
|
}
|
|
8241
8271
|
else {
|
|
@@ -8490,10 +8520,10 @@ class ScheduleMarkdownService {
|
|
|
8490
8520
|
/** Logger service for debug output */
|
|
8491
8521
|
this.loggerService = inject(TYPES.loggerService);
|
|
8492
8522
|
/**
|
|
8493
|
-
* Memoized function to get or create ReportStorage for a symbol-strategy
|
|
8494
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
8523
|
+
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
8524
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8495
8525
|
*/
|
|
8496
|
-
this.getStorage = functoolsKit.memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new ReportStorage$3());
|
|
8526
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$3());
|
|
8497
8527
|
/**
|
|
8498
8528
|
* Processes tick events and accumulates scheduled/opened/cancelled events.
|
|
8499
8529
|
* Should be called from signalEmitter subscription.
|
|
@@ -8512,7 +8542,7 @@ class ScheduleMarkdownService {
|
|
|
8512
8542
|
this.loggerService.log("scheduleMarkdownService tick", {
|
|
8513
8543
|
data,
|
|
8514
8544
|
});
|
|
8515
|
-
const storage = this.getStorage(data.symbol, data.strategyName);
|
|
8545
|
+
const storage = this.getStorage(data.symbol, data.strategyName, data.backtest);
|
|
8516
8546
|
if (data.action === "scheduled") {
|
|
8517
8547
|
storage.addScheduledEvent(data);
|
|
8518
8548
|
}
|
|
@@ -8533,21 +8563,23 @@ class ScheduleMarkdownService {
|
|
|
8533
8563
|
*
|
|
8534
8564
|
* @param symbol - Trading pair symbol
|
|
8535
8565
|
* @param strategyName - Strategy name to get data for
|
|
8566
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8536
8567
|
* @returns Statistical data object with all metrics
|
|
8537
8568
|
*
|
|
8538
8569
|
* @example
|
|
8539
8570
|
* ```typescript
|
|
8540
8571
|
* const service = new ScheduleMarkdownService();
|
|
8541
|
-
* const stats = await service.getData("BTCUSDT", "my-strategy");
|
|
8572
|
+
* const stats = await service.getData("BTCUSDT", "my-strategy", false);
|
|
8542
8573
|
* console.log(stats.cancellationRate, stats.avgWaitTime);
|
|
8543
8574
|
* ```
|
|
8544
8575
|
*/
|
|
8545
|
-
this.getData = async (symbol, strategyName) => {
|
|
8576
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
8546
8577
|
this.loggerService.log("scheduleMarkdownService getData", {
|
|
8547
8578
|
symbol,
|
|
8548
8579
|
strategyName,
|
|
8580
|
+
backtest,
|
|
8549
8581
|
});
|
|
8550
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8582
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8551
8583
|
return storage.getData();
|
|
8552
8584
|
};
|
|
8553
8585
|
/**
|
|
@@ -8556,22 +8588,24 @@ class ScheduleMarkdownService {
|
|
|
8556
8588
|
*
|
|
8557
8589
|
* @param symbol - Trading pair symbol
|
|
8558
8590
|
* @param strategyName - Strategy name to generate report for
|
|
8591
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8559
8592
|
* @param columns - Column configuration for formatting the table
|
|
8560
8593
|
* @returns Markdown formatted report string with table of all events
|
|
8561
8594
|
*
|
|
8562
8595
|
* @example
|
|
8563
8596
|
* ```typescript
|
|
8564
8597
|
* const service = new ScheduleMarkdownService();
|
|
8565
|
-
* const markdown = await service.getReport("BTCUSDT", "my-strategy");
|
|
8598
|
+
* const markdown = await service.getReport("BTCUSDT", "my-strategy", false);
|
|
8566
8599
|
* console.log(markdown);
|
|
8567
8600
|
* ```
|
|
8568
8601
|
*/
|
|
8569
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.schedule_columns) => {
|
|
8602
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.schedule_columns) => {
|
|
8570
8603
|
this.loggerService.log("scheduleMarkdownService getReport", {
|
|
8571
8604
|
symbol,
|
|
8572
8605
|
strategyName,
|
|
8606
|
+
backtest,
|
|
8573
8607
|
});
|
|
8574
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8608
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8575
8609
|
return storage.getReport(strategyName, columns);
|
|
8576
8610
|
};
|
|
8577
8611
|
/**
|
|
@@ -8581,6 +8615,7 @@ class ScheduleMarkdownService {
|
|
|
8581
8615
|
*
|
|
8582
8616
|
* @param symbol - Trading pair symbol
|
|
8583
8617
|
* @param strategyName - Strategy name to save report for
|
|
8618
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8584
8619
|
* @param path - Directory path to save report (default: "./dump/schedule")
|
|
8585
8620
|
* @param columns - Column configuration for formatting the table
|
|
8586
8621
|
*
|
|
@@ -8589,45 +8624,48 @@ class ScheduleMarkdownService {
|
|
|
8589
8624
|
* const service = new ScheduleMarkdownService();
|
|
8590
8625
|
*
|
|
8591
8626
|
* // Save to default path: ./dump/schedule/my-strategy.md
|
|
8592
|
-
* await service.dump("BTCUSDT", "my-strategy");
|
|
8627
|
+
* await service.dump("BTCUSDT", "my-strategy", false);
|
|
8593
8628
|
*
|
|
8594
8629
|
* // Save to custom path: ./custom/path/my-strategy.md
|
|
8595
|
-
* await service.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
8630
|
+
* await service.dump("BTCUSDT", "my-strategy", false, "./custom/path");
|
|
8596
8631
|
* ```
|
|
8597
8632
|
*/
|
|
8598
|
-
this.dump = async (symbol, strategyName, path = "./dump/schedule", columns = COLUMN_CONFIG.schedule_columns) => {
|
|
8633
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/schedule", columns = COLUMN_CONFIG.schedule_columns) => {
|
|
8599
8634
|
this.loggerService.log("scheduleMarkdownService dump", {
|
|
8600
8635
|
symbol,
|
|
8601
8636
|
strategyName,
|
|
8637
|
+
backtest,
|
|
8602
8638
|
path,
|
|
8603
8639
|
});
|
|
8604
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8640
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8605
8641
|
await storage.dump(strategyName, path, columns);
|
|
8606
8642
|
};
|
|
8607
8643
|
/**
|
|
8608
8644
|
* Clears accumulated event data from storage.
|
|
8609
|
-
* If ctx is provided, clears only that specific symbol-strategy
|
|
8645
|
+
* If ctx is provided, clears only that specific symbol-strategy-backtest triple's data.
|
|
8610
8646
|
* If nothing is provided, clears all data.
|
|
8611
8647
|
*
|
|
8648
|
+
* @param backtest - Backtest mode flag
|
|
8612
8649
|
* @param ctx - Optional context with symbol and strategyName
|
|
8613
8650
|
*
|
|
8614
8651
|
* @example
|
|
8615
8652
|
* ```typescript
|
|
8616
8653
|
* const service = new ScheduleMarkdownService();
|
|
8617
8654
|
*
|
|
8618
|
-
* // Clear specific symbol-strategy
|
|
8619
|
-
* await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
8655
|
+
* // Clear specific symbol-strategy-backtest triple
|
|
8656
|
+
* await service.clear(false, { symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
8620
8657
|
*
|
|
8621
8658
|
* // Clear all data
|
|
8622
8659
|
* await service.clear();
|
|
8623
8660
|
* ```
|
|
8624
8661
|
*/
|
|
8625
|
-
this.clear = async (ctx) => {
|
|
8662
|
+
this.clear = async (backtest, ctx) => {
|
|
8626
8663
|
this.loggerService.log("scheduleMarkdownService clear", {
|
|
8664
|
+
backtest,
|
|
8627
8665
|
ctx,
|
|
8628
8666
|
});
|
|
8629
8667
|
if (ctx) {
|
|
8630
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
8668
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8631
8669
|
this.getStorage.clear(key);
|
|
8632
8670
|
}
|
|
8633
8671
|
else {
|
|
@@ -8866,10 +8904,10 @@ class PerformanceMarkdownService {
|
|
|
8866
8904
|
/** Logger service for debug output */
|
|
8867
8905
|
this.loggerService = inject(TYPES.loggerService);
|
|
8868
8906
|
/**
|
|
8869
|
-
* Memoized function to get or create PerformanceStorage for a symbol-strategy
|
|
8870
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
8907
|
+
* Memoized function to get or create PerformanceStorage for a symbol-strategy-backtest triple.
|
|
8908
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8871
8909
|
*/
|
|
8872
|
-
this.getStorage = functoolsKit.memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new PerformanceStorage());
|
|
8910
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new PerformanceStorage());
|
|
8873
8911
|
/**
|
|
8874
8912
|
* Processes performance events and accumulates metrics.
|
|
8875
8913
|
* Should be called from performance tracking code.
|
|
@@ -8882,7 +8920,7 @@ class PerformanceMarkdownService {
|
|
|
8882
8920
|
});
|
|
8883
8921
|
const symbol = event.symbol || "global";
|
|
8884
8922
|
const strategyName = event.strategyName || "global";
|
|
8885
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8923
|
+
const storage = this.getStorage(symbol, strategyName, event.backtest);
|
|
8886
8924
|
storage.addEvent(event);
|
|
8887
8925
|
};
|
|
8888
8926
|
/**
|
|
@@ -8890,22 +8928,24 @@ class PerformanceMarkdownService {
|
|
|
8890
8928
|
*
|
|
8891
8929
|
* @param symbol - Trading pair symbol
|
|
8892
8930
|
* @param strategyName - Strategy name to get data for
|
|
8931
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8893
8932
|
* @returns Performance statistics with aggregated metrics
|
|
8894
8933
|
*
|
|
8895
8934
|
* @example
|
|
8896
8935
|
* ```typescript
|
|
8897
|
-
* const stats = await performanceService.getData("BTCUSDT", "my-strategy");
|
|
8936
|
+
* const stats = await performanceService.getData("BTCUSDT", "my-strategy", false);
|
|
8898
8937
|
* console.log("Total time:", stats.totalDuration);
|
|
8899
8938
|
* console.log("Slowest operation:", Object.values(stats.metricStats)
|
|
8900
8939
|
* .sort((a, b) => b.avgDuration - a.avgDuration)[0]);
|
|
8901
8940
|
* ```
|
|
8902
8941
|
*/
|
|
8903
|
-
this.getData = async (symbol, strategyName) => {
|
|
8942
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
8904
8943
|
this.loggerService.log("performanceMarkdownService getData", {
|
|
8905
8944
|
symbol,
|
|
8906
8945
|
strategyName,
|
|
8946
|
+
backtest,
|
|
8907
8947
|
});
|
|
8908
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8948
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8909
8949
|
return storage.getData(strategyName);
|
|
8910
8950
|
};
|
|
8911
8951
|
/**
|
|
@@ -8913,21 +8953,23 @@ class PerformanceMarkdownService {
|
|
|
8913
8953
|
*
|
|
8914
8954
|
* @param symbol - Trading pair symbol
|
|
8915
8955
|
* @param strategyName - Strategy name to generate report for
|
|
8956
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8916
8957
|
* @param columns - Column configuration for formatting the table
|
|
8917
8958
|
* @returns Markdown formatted report string
|
|
8918
8959
|
*
|
|
8919
8960
|
* @example
|
|
8920
8961
|
* ```typescript
|
|
8921
|
-
* const markdown = await performanceService.getReport("BTCUSDT", "my-strategy");
|
|
8962
|
+
* const markdown = await performanceService.getReport("BTCUSDT", "my-strategy", false);
|
|
8922
8963
|
* console.log(markdown);
|
|
8923
8964
|
* ```
|
|
8924
8965
|
*/
|
|
8925
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.performance_columns) => {
|
|
8966
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.performance_columns) => {
|
|
8926
8967
|
this.loggerService.log("performanceMarkdownService getReport", {
|
|
8927
8968
|
symbol,
|
|
8928
8969
|
strategyName,
|
|
8970
|
+
backtest,
|
|
8929
8971
|
});
|
|
8930
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8972
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8931
8973
|
return storage.getReport(strategyName, columns);
|
|
8932
8974
|
};
|
|
8933
8975
|
/**
|
|
@@ -8935,42 +8977,45 @@ class PerformanceMarkdownService {
|
|
|
8935
8977
|
*
|
|
8936
8978
|
* @param symbol - Trading pair symbol
|
|
8937
8979
|
* @param strategyName - Strategy name to save report for
|
|
8980
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8938
8981
|
* @param path - Directory path to save report
|
|
8939
8982
|
* @param columns - Column configuration for formatting the table
|
|
8940
8983
|
*
|
|
8941
8984
|
* @example
|
|
8942
8985
|
* ```typescript
|
|
8943
8986
|
* // Save to default path: ./dump/performance/my-strategy.md
|
|
8944
|
-
* await performanceService.dump("BTCUSDT", "my-strategy");
|
|
8987
|
+
* await performanceService.dump("BTCUSDT", "my-strategy", false);
|
|
8945
8988
|
*
|
|
8946
8989
|
* // Save to custom path
|
|
8947
|
-
* await performanceService.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
8990
|
+
* await performanceService.dump("BTCUSDT", "my-strategy", false, "./custom/path");
|
|
8948
8991
|
* ```
|
|
8949
8992
|
*/
|
|
8950
|
-
this.dump = async (symbol, strategyName, path = "./dump/performance", columns = COLUMN_CONFIG.performance_columns) => {
|
|
8993
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/performance", columns = COLUMN_CONFIG.performance_columns) => {
|
|
8951
8994
|
this.loggerService.log("performanceMarkdownService dump", {
|
|
8952
8995
|
symbol,
|
|
8953
8996
|
strategyName,
|
|
8997
|
+
backtest,
|
|
8954
8998
|
path,
|
|
8955
8999
|
});
|
|
8956
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
9000
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8957
9001
|
await storage.dump(strategyName, path, columns);
|
|
8958
9002
|
};
|
|
8959
9003
|
/**
|
|
8960
9004
|
* Clears accumulated performance data from storage.
|
|
8961
9005
|
*
|
|
8962
|
-
* @param
|
|
8963
|
-
* @param
|
|
9006
|
+
* @param backtest - Backtest mode flag
|
|
9007
|
+
* @param ctx - Optional context with symbol and strategyName
|
|
8964
9008
|
*/
|
|
8965
|
-
this.clear = async (ctx) => {
|
|
9009
|
+
this.clear = async (backtest, ctx) => {
|
|
8966
9010
|
this.loggerService.log("performanceMarkdownService clear", {
|
|
9011
|
+
backtest,
|
|
8967
9012
|
ctx,
|
|
8968
9013
|
});
|
|
8969
9014
|
if (ctx) {
|
|
8970
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
9015
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8971
9016
|
this.getStorage.clear(key);
|
|
8972
9017
|
}
|
|
8973
|
-
{
|
|
9018
|
+
else {
|
|
8974
9019
|
this.getStorage.clear();
|
|
8975
9020
|
}
|
|
8976
9021
|
};
|
|
@@ -9734,10 +9779,10 @@ class HeatMarkdownService {
|
|
|
9734
9779
|
/** Logger service for debug output */
|
|
9735
9780
|
this.loggerService = inject(TYPES.loggerService);
|
|
9736
9781
|
/**
|
|
9737
|
-
* Memoized function to get or create HeatmapStorage for a strategy.
|
|
9738
|
-
* Each strategy gets its own isolated heatmap storage instance.
|
|
9782
|
+
* Memoized function to get or create HeatmapStorage for a strategy and backtest mode.
|
|
9783
|
+
* Each strategy + backtest mode combination gets its own isolated heatmap storage instance.
|
|
9739
9784
|
*/
|
|
9740
|
-
this.getStorage = functoolsKit.memoize(([strategyName]) => `${strategyName}`, () => new HeatmapStorage());
|
|
9785
|
+
this.getStorage = functoolsKit.memoize(([strategyName, backtest]) => `${strategyName}:${backtest ? "backtest" : "live"}`, () => new HeatmapStorage());
|
|
9741
9786
|
/**
|
|
9742
9787
|
* Processes tick events and accumulates closed signals.
|
|
9743
9788
|
* Should be called from signal emitter subscription.
|
|
@@ -9753,19 +9798,20 @@ class HeatMarkdownService {
|
|
|
9753
9798
|
if (data.action !== "closed") {
|
|
9754
9799
|
return;
|
|
9755
9800
|
}
|
|
9756
|
-
const storage = this.getStorage(data.strategyName);
|
|
9801
|
+
const storage = this.getStorage(data.strategyName, data.backtest);
|
|
9757
9802
|
storage.addSignal(data);
|
|
9758
9803
|
};
|
|
9759
9804
|
/**
|
|
9760
9805
|
* Gets aggregated portfolio heatmap statistics for a strategy.
|
|
9761
9806
|
*
|
|
9762
9807
|
* @param strategyName - Strategy name to get heatmap data for
|
|
9808
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
9763
9809
|
* @returns Promise resolving to heatmap statistics with per-symbol and portfolio-wide metrics
|
|
9764
9810
|
*
|
|
9765
9811
|
* @example
|
|
9766
9812
|
* ```typescript
|
|
9767
9813
|
* const service = new HeatMarkdownService();
|
|
9768
|
-
* const stats = await service.getData("my-strategy");
|
|
9814
|
+
* const stats = await service.getData("my-strategy", true);
|
|
9769
9815
|
*
|
|
9770
9816
|
* console.log(`Total symbols: ${stats.totalSymbols}`);
|
|
9771
9817
|
* console.log(`Portfolio PNL: ${stats.portfolioTotalPnl}%`);
|
|
@@ -9775,24 +9821,26 @@ class HeatMarkdownService {
|
|
|
9775
9821
|
* });
|
|
9776
9822
|
* ```
|
|
9777
9823
|
*/
|
|
9778
|
-
this.getData = async (strategyName) => {
|
|
9824
|
+
this.getData = async (strategyName, backtest) => {
|
|
9779
9825
|
this.loggerService.log(HEATMAP_METHOD_NAME_GET_DATA, {
|
|
9780
9826
|
strategyName,
|
|
9827
|
+
backtest,
|
|
9781
9828
|
});
|
|
9782
|
-
const storage = this.getStorage(strategyName);
|
|
9829
|
+
const storage = this.getStorage(strategyName, backtest);
|
|
9783
9830
|
return storage.getData();
|
|
9784
9831
|
};
|
|
9785
9832
|
/**
|
|
9786
9833
|
* Generates markdown report with portfolio heatmap table for a strategy.
|
|
9787
9834
|
*
|
|
9788
9835
|
* @param strategyName - Strategy name to generate heatmap report for
|
|
9836
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
9789
9837
|
* @param columns - Column configuration for formatting the table
|
|
9790
9838
|
* @returns Promise resolving to markdown formatted report string
|
|
9791
9839
|
*
|
|
9792
9840
|
* @example
|
|
9793
9841
|
* ```typescript
|
|
9794
9842
|
* const service = new HeatMarkdownService();
|
|
9795
|
-
* const markdown = await service.getReport("my-strategy");
|
|
9843
|
+
* const markdown = await service.getReport("my-strategy", true);
|
|
9796
9844
|
* console.log(markdown);
|
|
9797
9845
|
* // Output:
|
|
9798
9846
|
* // # Portfolio Heatmap: my-strategy
|
|
@@ -9806,11 +9854,12 @@ class HeatMarkdownService {
|
|
|
9806
9854
|
* // ...
|
|
9807
9855
|
* ```
|
|
9808
9856
|
*/
|
|
9809
|
-
this.getReport = async (strategyName, columns = COLUMN_CONFIG.heat_columns) => {
|
|
9857
|
+
this.getReport = async (strategyName, backtest, columns = COLUMN_CONFIG.heat_columns) => {
|
|
9810
9858
|
this.loggerService.log(HEATMAP_METHOD_NAME_GET_REPORT, {
|
|
9811
9859
|
strategyName,
|
|
9860
|
+
backtest,
|
|
9812
9861
|
});
|
|
9813
|
-
const storage = this.getStorage(strategyName);
|
|
9862
|
+
const storage = this.getStorage(strategyName, backtest);
|
|
9814
9863
|
return storage.getReport(strategyName, columns);
|
|
9815
9864
|
};
|
|
9816
9865
|
/**
|
|
@@ -9820,6 +9869,7 @@ class HeatMarkdownService {
|
|
|
9820
9869
|
* Default filename: {strategyName}.md
|
|
9821
9870
|
*
|
|
9822
9871
|
* @param strategyName - Strategy name to save heatmap report for
|
|
9872
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
9823
9873
|
* @param path - Optional directory path to save report (default: "./dump/heatmap")
|
|
9824
9874
|
* @param columns - Column configuration for formatting the table
|
|
9825
9875
|
*
|
|
@@ -9828,43 +9878,52 @@ class HeatMarkdownService {
|
|
|
9828
9878
|
* const service = new HeatMarkdownService();
|
|
9829
9879
|
*
|
|
9830
9880
|
* // Save to default path: ./dump/heatmap/my-strategy.md
|
|
9831
|
-
* await service.dump("my-strategy");
|
|
9881
|
+
* await service.dump("my-strategy", true);
|
|
9832
9882
|
*
|
|
9833
9883
|
* // Save to custom path: ./reports/my-strategy.md
|
|
9834
|
-
* await service.dump("my-strategy", "./reports");
|
|
9884
|
+
* await service.dump("my-strategy", true, "./reports");
|
|
9835
9885
|
* ```
|
|
9836
9886
|
*/
|
|
9837
|
-
this.dump = async (strategyName, path = "./dump/heatmap", columns = COLUMN_CONFIG.heat_columns) => {
|
|
9887
|
+
this.dump = async (strategyName, backtest, path = "./dump/heatmap", columns = COLUMN_CONFIG.heat_columns) => {
|
|
9838
9888
|
this.loggerService.log(HEATMAP_METHOD_NAME_DUMP, {
|
|
9839
9889
|
strategyName,
|
|
9890
|
+
backtest,
|
|
9840
9891
|
path,
|
|
9841
9892
|
});
|
|
9842
|
-
const storage = this.getStorage(strategyName);
|
|
9893
|
+
const storage = this.getStorage(strategyName, backtest);
|
|
9843
9894
|
await storage.dump(strategyName, path, columns);
|
|
9844
9895
|
};
|
|
9845
9896
|
/**
|
|
9846
9897
|
* Clears accumulated heatmap data from storage.
|
|
9847
|
-
* If
|
|
9848
|
-
* If
|
|
9898
|
+
* If ctx is provided, clears only that strategy+backtest combination's data.
|
|
9899
|
+
* If ctx is omitted, clears all data.
|
|
9849
9900
|
*
|
|
9850
|
-
* @param
|
|
9901
|
+
* @param backtest - Backtest mode flag
|
|
9902
|
+
* @param ctx - Optional context with strategyName to clear specific data
|
|
9851
9903
|
*
|
|
9852
9904
|
* @example
|
|
9853
9905
|
* ```typescript
|
|
9854
9906
|
* const service = new HeatMarkdownService();
|
|
9855
9907
|
*
|
|
9856
|
-
* // Clear specific strategy data
|
|
9857
|
-
* await service.clear("my-strategy");
|
|
9908
|
+
* // Clear specific strategy+backtest data
|
|
9909
|
+
* await service.clear(true, { strategyName: "my-strategy" });
|
|
9858
9910
|
*
|
|
9859
|
-
* // Clear all
|
|
9911
|
+
* // Clear all data
|
|
9860
9912
|
* await service.clear();
|
|
9861
9913
|
* ```
|
|
9862
9914
|
*/
|
|
9863
|
-
this.clear = async (
|
|
9915
|
+
this.clear = async (backtest, ctx) => {
|
|
9864
9916
|
this.loggerService.log(HEATMAP_METHOD_NAME_CLEAR, {
|
|
9865
|
-
|
|
9917
|
+
backtest,
|
|
9918
|
+
ctx,
|
|
9866
9919
|
});
|
|
9867
|
-
|
|
9920
|
+
if (ctx) {
|
|
9921
|
+
const key = `${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
9922
|
+
this.getStorage.clear(key);
|
|
9923
|
+
}
|
|
9924
|
+
else {
|
|
9925
|
+
this.getStorage.clear();
|
|
9926
|
+
}
|
|
9868
9927
|
};
|
|
9869
9928
|
/**
|
|
9870
9929
|
* Initializes the service by subscribing to signal events.
|
|
@@ -12433,10 +12492,10 @@ class PartialMarkdownService {
|
|
|
12433
12492
|
/** Logger service for debug output */
|
|
12434
12493
|
this.loggerService = inject(TYPES.loggerService);
|
|
12435
12494
|
/**
|
|
12436
|
-
* Memoized function to get or create ReportStorage for a symbol-strategy
|
|
12437
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
12495
|
+
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
12496
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
12438
12497
|
*/
|
|
12439
|
-
this.getStorage = functoolsKit.memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new ReportStorage$1());
|
|
12498
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$1());
|
|
12440
12499
|
/**
|
|
12441
12500
|
* Processes profit events and accumulates them.
|
|
12442
12501
|
* Should be called from partialProfitSubject subscription.
|
|
@@ -12453,7 +12512,7 @@ class PartialMarkdownService {
|
|
|
12453
12512
|
this.loggerService.log("partialMarkdownService tickProfit", {
|
|
12454
12513
|
data,
|
|
12455
12514
|
});
|
|
12456
|
-
const storage = this.getStorage(data.symbol, data.data.strategyName);
|
|
12515
|
+
const storage = this.getStorage(data.symbol, data.data.strategyName, data.backtest);
|
|
12457
12516
|
storage.addProfitEvent(data.data, data.currentPrice, data.level, data.backtest, data.timestamp);
|
|
12458
12517
|
};
|
|
12459
12518
|
/**
|
|
@@ -12472,7 +12531,7 @@ class PartialMarkdownService {
|
|
|
12472
12531
|
this.loggerService.log("partialMarkdownService tickLoss", {
|
|
12473
12532
|
data,
|
|
12474
12533
|
});
|
|
12475
|
-
const storage = this.getStorage(data.symbol, data.data.strategyName);
|
|
12534
|
+
const storage = this.getStorage(data.symbol, data.data.strategyName, data.backtest);
|
|
12476
12535
|
storage.addLossEvent(data.data, data.currentPrice, data.level, data.backtest, data.timestamp);
|
|
12477
12536
|
};
|
|
12478
12537
|
/**
|
|
@@ -12481,21 +12540,23 @@ class PartialMarkdownService {
|
|
|
12481
12540
|
*
|
|
12482
12541
|
* @param symbol - Trading pair symbol to get data for
|
|
12483
12542
|
* @param strategyName - Strategy name to get data for
|
|
12543
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
12484
12544
|
* @returns Statistical data object with all metrics
|
|
12485
12545
|
*
|
|
12486
12546
|
* @example
|
|
12487
12547
|
* ```typescript
|
|
12488
12548
|
* const service = new PartialMarkdownService();
|
|
12489
|
-
* const stats = await service.getData("BTCUSDT", "my-strategy");
|
|
12549
|
+
* const stats = await service.getData("BTCUSDT", "my-strategy", false);
|
|
12490
12550
|
* console.log(stats.totalProfit, stats.totalLoss);
|
|
12491
12551
|
* ```
|
|
12492
12552
|
*/
|
|
12493
|
-
this.getData = async (symbol, strategyName) => {
|
|
12553
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
12494
12554
|
this.loggerService.log("partialMarkdownService getData", {
|
|
12495
12555
|
symbol,
|
|
12496
12556
|
strategyName,
|
|
12557
|
+
backtest,
|
|
12497
12558
|
});
|
|
12498
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
12559
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
12499
12560
|
return storage.getData();
|
|
12500
12561
|
};
|
|
12501
12562
|
/**
|
|
@@ -12504,22 +12565,24 @@ class PartialMarkdownService {
|
|
|
12504
12565
|
*
|
|
12505
12566
|
* @param symbol - Trading pair symbol to generate report for
|
|
12506
12567
|
* @param strategyName - Strategy name to generate report for
|
|
12568
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
12507
12569
|
* @param columns - Column configuration for formatting the table
|
|
12508
12570
|
* @returns Markdown formatted report string with table of all events
|
|
12509
12571
|
*
|
|
12510
12572
|
* @example
|
|
12511
12573
|
* ```typescript
|
|
12512
12574
|
* const service = new PartialMarkdownService();
|
|
12513
|
-
* const markdown = await service.getReport("BTCUSDT", "my-strategy");
|
|
12575
|
+
* const markdown = await service.getReport("BTCUSDT", "my-strategy", false);
|
|
12514
12576
|
* console.log(markdown);
|
|
12515
12577
|
* ```
|
|
12516
12578
|
*/
|
|
12517
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.partial_columns) => {
|
|
12579
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.partial_columns) => {
|
|
12518
12580
|
this.loggerService.log("partialMarkdownService getReport", {
|
|
12519
12581
|
symbol,
|
|
12520
12582
|
strategyName,
|
|
12583
|
+
backtest,
|
|
12521
12584
|
});
|
|
12522
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
12585
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
12523
12586
|
return storage.getReport(symbol, strategyName, columns);
|
|
12524
12587
|
};
|
|
12525
12588
|
/**
|
|
@@ -12529,6 +12592,7 @@ class PartialMarkdownService {
|
|
|
12529
12592
|
*
|
|
12530
12593
|
* @param symbol - Trading pair symbol to save report for
|
|
12531
12594
|
* @param strategyName - Strategy name to save report for
|
|
12595
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
12532
12596
|
* @param path - Directory path to save report (default: "./dump/partial")
|
|
12533
12597
|
* @param columns - Column configuration for formatting the table
|
|
12534
12598
|
*
|
|
@@ -12537,45 +12601,48 @@ class PartialMarkdownService {
|
|
|
12537
12601
|
* const service = new PartialMarkdownService();
|
|
12538
12602
|
*
|
|
12539
12603
|
* // Save to default path: ./dump/partial/BTCUSDT_my-strategy.md
|
|
12540
|
-
* await service.dump("BTCUSDT", "my-strategy");
|
|
12604
|
+
* await service.dump("BTCUSDT", "my-strategy", false);
|
|
12541
12605
|
*
|
|
12542
12606
|
* // Save to custom path: ./custom/path/BTCUSDT_my-strategy.md
|
|
12543
|
-
* await service.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
12607
|
+
* await service.dump("BTCUSDT", "my-strategy", false, "./custom/path");
|
|
12544
12608
|
* ```
|
|
12545
12609
|
*/
|
|
12546
|
-
this.dump = async (symbol, strategyName, path = "./dump/partial", columns = COLUMN_CONFIG.partial_columns) => {
|
|
12610
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/partial", columns = COLUMN_CONFIG.partial_columns) => {
|
|
12547
12611
|
this.loggerService.log("partialMarkdownService dump", {
|
|
12548
12612
|
symbol,
|
|
12549
12613
|
strategyName,
|
|
12614
|
+
backtest,
|
|
12550
12615
|
path,
|
|
12551
12616
|
});
|
|
12552
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
12617
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
12553
12618
|
await storage.dump(symbol, strategyName, path, columns);
|
|
12554
12619
|
};
|
|
12555
12620
|
/**
|
|
12556
12621
|
* Clears accumulated event data from storage.
|
|
12557
|
-
* If ctx is provided, clears only that specific symbol-strategy
|
|
12622
|
+
* If ctx is provided, clears only that specific symbol-strategy-backtest triple's data.
|
|
12558
12623
|
* If nothing is provided, clears all data.
|
|
12559
12624
|
*
|
|
12625
|
+
* @param backtest - Backtest mode flag
|
|
12560
12626
|
* @param ctx - Optional context with symbol and strategyName
|
|
12561
12627
|
*
|
|
12562
12628
|
* @example
|
|
12563
12629
|
* ```typescript
|
|
12564
12630
|
* const service = new PartialMarkdownService();
|
|
12565
12631
|
*
|
|
12566
|
-
* // Clear specific symbol-strategy
|
|
12567
|
-
* await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
12632
|
+
* // Clear specific symbol-strategy-backtest triple
|
|
12633
|
+
* await service.clear(false, { symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
12568
12634
|
*
|
|
12569
12635
|
* // Clear all data
|
|
12570
12636
|
* await service.clear();
|
|
12571
12637
|
* ```
|
|
12572
12638
|
*/
|
|
12573
|
-
this.clear = async (ctx) => {
|
|
12639
|
+
this.clear = async (backtest, ctx) => {
|
|
12574
12640
|
this.loggerService.log("partialMarkdownService clear", {
|
|
12641
|
+
backtest,
|
|
12575
12642
|
ctx,
|
|
12576
12643
|
});
|
|
12577
12644
|
if (ctx) {
|
|
12578
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
12645
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
12579
12646
|
this.getStorage.clear(key);
|
|
12580
12647
|
}
|
|
12581
12648
|
else {
|
|
@@ -13151,10 +13218,10 @@ class RiskMarkdownService {
|
|
|
13151
13218
|
/** Logger service for debug output */
|
|
13152
13219
|
this.loggerService = inject(TYPES.loggerService);
|
|
13153
13220
|
/**
|
|
13154
|
-
* Memoized function to get or create ReportStorage for a symbol-strategy
|
|
13155
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
13221
|
+
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
13222
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
13156
13223
|
*/
|
|
13157
|
-
this.getStorage = functoolsKit.memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new ReportStorage());
|
|
13224
|
+
this.getStorage = functoolsKit.memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage());
|
|
13158
13225
|
/**
|
|
13159
13226
|
* Processes risk rejection events and accumulates them.
|
|
13160
13227
|
* Should be called from riskSubject subscription.
|
|
@@ -13171,7 +13238,7 @@ class RiskMarkdownService {
|
|
|
13171
13238
|
this.loggerService.log("riskMarkdownService tickRejection", {
|
|
13172
13239
|
data,
|
|
13173
13240
|
});
|
|
13174
|
-
const storage = this.getStorage(data.symbol, data.strategyName);
|
|
13241
|
+
const storage = this.getStorage(data.symbol, data.strategyName, data.backtest);
|
|
13175
13242
|
storage.addRejectionEvent(data);
|
|
13176
13243
|
};
|
|
13177
13244
|
/**
|
|
@@ -13180,21 +13247,23 @@ class RiskMarkdownService {
|
|
|
13180
13247
|
*
|
|
13181
13248
|
* @param symbol - Trading pair symbol to get data for
|
|
13182
13249
|
* @param strategyName - Strategy name to get data for
|
|
13250
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
13183
13251
|
* @returns Statistical data object with all metrics
|
|
13184
13252
|
*
|
|
13185
13253
|
* @example
|
|
13186
13254
|
* ```typescript
|
|
13187
13255
|
* const service = new RiskMarkdownService();
|
|
13188
|
-
* const stats = await service.getData("BTCUSDT", "my-strategy");
|
|
13256
|
+
* const stats = await service.getData("BTCUSDT", "my-strategy", false);
|
|
13189
13257
|
* console.log(stats.totalRejections, stats.bySymbol);
|
|
13190
13258
|
* ```
|
|
13191
13259
|
*/
|
|
13192
|
-
this.getData = async (symbol, strategyName) => {
|
|
13260
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
13193
13261
|
this.loggerService.log("riskMarkdownService getData", {
|
|
13194
13262
|
symbol,
|
|
13195
13263
|
strategyName,
|
|
13264
|
+
backtest,
|
|
13196
13265
|
});
|
|
13197
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
13266
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
13198
13267
|
return storage.getData();
|
|
13199
13268
|
};
|
|
13200
13269
|
/**
|
|
@@ -13203,22 +13272,24 @@ class RiskMarkdownService {
|
|
|
13203
13272
|
*
|
|
13204
13273
|
* @param symbol - Trading pair symbol to generate report for
|
|
13205
13274
|
* @param strategyName - Strategy name to generate report for
|
|
13275
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
13206
13276
|
* @param columns - Column configuration for formatting the table
|
|
13207
13277
|
* @returns Markdown formatted report string with table of all events
|
|
13208
13278
|
*
|
|
13209
13279
|
* @example
|
|
13210
13280
|
* ```typescript
|
|
13211
13281
|
* const service = new RiskMarkdownService();
|
|
13212
|
-
* const markdown = await service.getReport("BTCUSDT", "my-strategy");
|
|
13282
|
+
* const markdown = await service.getReport("BTCUSDT", "my-strategy", false);
|
|
13213
13283
|
* console.log(markdown);
|
|
13214
13284
|
* ```
|
|
13215
13285
|
*/
|
|
13216
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.risk_columns) => {
|
|
13286
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.risk_columns) => {
|
|
13217
13287
|
this.loggerService.log("riskMarkdownService getReport", {
|
|
13218
13288
|
symbol,
|
|
13219
13289
|
strategyName,
|
|
13290
|
+
backtest,
|
|
13220
13291
|
});
|
|
13221
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
13292
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
13222
13293
|
return storage.getReport(symbol, strategyName, columns);
|
|
13223
13294
|
};
|
|
13224
13295
|
/**
|
|
@@ -13228,6 +13299,7 @@ class RiskMarkdownService {
|
|
|
13228
13299
|
*
|
|
13229
13300
|
* @param symbol - Trading pair symbol to save report for
|
|
13230
13301
|
* @param strategyName - Strategy name to save report for
|
|
13302
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
13231
13303
|
* @param path - Directory path to save report (default: "./dump/risk")
|
|
13232
13304
|
* @param columns - Column configuration for formatting the table
|
|
13233
13305
|
*
|
|
@@ -13236,45 +13308,48 @@ class RiskMarkdownService {
|
|
|
13236
13308
|
* const service = new RiskMarkdownService();
|
|
13237
13309
|
*
|
|
13238
13310
|
* // Save to default path: ./dump/risk/BTCUSDT_my-strategy.md
|
|
13239
|
-
* await service.dump("BTCUSDT", "my-strategy");
|
|
13311
|
+
* await service.dump("BTCUSDT", "my-strategy", false);
|
|
13240
13312
|
*
|
|
13241
13313
|
* // Save to custom path: ./custom/path/BTCUSDT_my-strategy.md
|
|
13242
|
-
* await service.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
13314
|
+
* await service.dump("BTCUSDT", "my-strategy", false, "./custom/path");
|
|
13243
13315
|
* ```
|
|
13244
13316
|
*/
|
|
13245
|
-
this.dump = async (symbol, strategyName, path = "./dump/risk", columns = COLUMN_CONFIG.risk_columns) => {
|
|
13317
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/risk", columns = COLUMN_CONFIG.risk_columns) => {
|
|
13246
13318
|
this.loggerService.log("riskMarkdownService dump", {
|
|
13247
13319
|
symbol,
|
|
13248
13320
|
strategyName,
|
|
13321
|
+
backtest,
|
|
13249
13322
|
path,
|
|
13250
13323
|
});
|
|
13251
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
13324
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
13252
13325
|
await storage.dump(symbol, strategyName, path, columns);
|
|
13253
13326
|
};
|
|
13254
13327
|
/**
|
|
13255
13328
|
* Clears accumulated event data from storage.
|
|
13256
|
-
* If ctx is provided, clears only that specific symbol-strategy
|
|
13329
|
+
* If ctx is provided, clears only that specific symbol-strategy-backtest triple's data.
|
|
13257
13330
|
* If nothing is provided, clears all data.
|
|
13258
13331
|
*
|
|
13332
|
+
* @param backtest - Backtest mode flag
|
|
13259
13333
|
* @param ctx - Optional context with symbol and strategyName
|
|
13260
13334
|
*
|
|
13261
13335
|
* @example
|
|
13262
13336
|
* ```typescript
|
|
13263
13337
|
* const service = new RiskMarkdownService();
|
|
13264
13338
|
*
|
|
13265
|
-
* // Clear specific symbol-strategy
|
|
13266
|
-
* await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
13339
|
+
* // Clear specific symbol-strategy-backtest triple
|
|
13340
|
+
* await service.clear(false, { symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
13267
13341
|
*
|
|
13268
13342
|
* // Clear all data
|
|
13269
13343
|
* await service.clear();
|
|
13270
13344
|
* ```
|
|
13271
13345
|
*/
|
|
13272
|
-
this.clear = async (ctx) => {
|
|
13346
|
+
this.clear = async (backtest, ctx) => {
|
|
13273
13347
|
this.loggerService.log("riskMarkdownService clear", {
|
|
13348
|
+
backtest,
|
|
13274
13349
|
ctx,
|
|
13275
13350
|
});
|
|
13276
13351
|
if (ctx) {
|
|
13277
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
13352
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
13278
13353
|
this.getStorage.clear(key);
|
|
13279
13354
|
}
|
|
13280
13355
|
else {
|
|
@@ -13579,7 +13654,7 @@ const backtest = {
|
|
|
13579
13654
|
...templateServices,
|
|
13580
13655
|
};
|
|
13581
13656
|
init();
|
|
13582
|
-
var
|
|
13657
|
+
var bt = backtest;
|
|
13583
13658
|
|
|
13584
13659
|
/**
|
|
13585
13660
|
* Sets custom logger implementation for the framework.
|
|
@@ -13599,7 +13674,7 @@ var backtest$1 = backtest;
|
|
|
13599
13674
|
* ```
|
|
13600
13675
|
*/
|
|
13601
13676
|
function setLogger(logger) {
|
|
13602
|
-
|
|
13677
|
+
bt.loggerService.setLogger(logger);
|
|
13603
13678
|
}
|
|
13604
13679
|
/**
|
|
13605
13680
|
* Sets global configuration parameters for the framework.
|
|
@@ -13617,7 +13692,7 @@ function setConfig(config, _unsafe) {
|
|
|
13617
13692
|
const prevConfig = Object.assign({}, GLOBAL_CONFIG);
|
|
13618
13693
|
try {
|
|
13619
13694
|
Object.assign(GLOBAL_CONFIG, config);
|
|
13620
|
-
!_unsafe &&
|
|
13695
|
+
!_unsafe && bt.configValidationService.validate();
|
|
13621
13696
|
}
|
|
13622
13697
|
catch (error) {
|
|
13623
13698
|
console.warn(`backtest-kit setConfig failed: ${functoolsKit.getErrorMessage(error)}`, config);
|
|
@@ -13688,7 +13763,7 @@ function setColumns(columns, _unsafe) {
|
|
|
13688
13763
|
const prevConfig = Object.assign({}, COLUMN_CONFIG);
|
|
13689
13764
|
try {
|
|
13690
13765
|
Object.assign(COLUMN_CONFIG, columns);
|
|
13691
|
-
!_unsafe &&
|
|
13766
|
+
!_unsafe && bt.columnValidationService.validate();
|
|
13692
13767
|
}
|
|
13693
13768
|
catch (error) {
|
|
13694
13769
|
console.warn(`backtest-kit setColumns failed: ${functoolsKit.getErrorMessage(error)}`, columns);
|
|
@@ -13773,11 +13848,11 @@ const ADD_OPTIMIZER_METHOD_NAME = "add.addOptimizer";
|
|
|
13773
13848
|
* ```
|
|
13774
13849
|
*/
|
|
13775
13850
|
function addStrategy(strategySchema) {
|
|
13776
|
-
|
|
13851
|
+
bt.loggerService.info(ADD_STRATEGY_METHOD_NAME, {
|
|
13777
13852
|
strategySchema,
|
|
13778
13853
|
});
|
|
13779
|
-
|
|
13780
|
-
|
|
13854
|
+
bt.strategyValidationService.addStrategy(strategySchema.strategyName, strategySchema);
|
|
13855
|
+
bt.strategySchemaService.register(strategySchema.strategyName, strategySchema);
|
|
13781
13856
|
}
|
|
13782
13857
|
/**
|
|
13783
13858
|
* Registers an exchange data source in the framework.
|
|
@@ -13815,11 +13890,11 @@ function addStrategy(strategySchema) {
|
|
|
13815
13890
|
* ```
|
|
13816
13891
|
*/
|
|
13817
13892
|
function addExchange(exchangeSchema) {
|
|
13818
|
-
|
|
13893
|
+
bt.loggerService.info(ADD_EXCHANGE_METHOD_NAME, {
|
|
13819
13894
|
exchangeSchema,
|
|
13820
13895
|
});
|
|
13821
|
-
|
|
13822
|
-
|
|
13896
|
+
bt.exchangeValidationService.addExchange(exchangeSchema.exchangeName, exchangeSchema);
|
|
13897
|
+
bt.exchangeSchemaService.register(exchangeSchema.exchangeName, exchangeSchema);
|
|
13823
13898
|
}
|
|
13824
13899
|
/**
|
|
13825
13900
|
* Registers a timeframe generator for backtesting.
|
|
@@ -13852,11 +13927,11 @@ function addExchange(exchangeSchema) {
|
|
|
13852
13927
|
* ```
|
|
13853
13928
|
*/
|
|
13854
13929
|
function addFrame(frameSchema) {
|
|
13855
|
-
|
|
13930
|
+
bt.loggerService.info(ADD_FRAME_METHOD_NAME, {
|
|
13856
13931
|
frameSchema,
|
|
13857
13932
|
});
|
|
13858
|
-
|
|
13859
|
-
|
|
13933
|
+
bt.frameValidationService.addFrame(frameSchema.frameName, frameSchema);
|
|
13934
|
+
bt.frameSchemaService.register(frameSchema.frameName, frameSchema);
|
|
13860
13935
|
}
|
|
13861
13936
|
/**
|
|
13862
13937
|
* Registers a walker for strategy comparison.
|
|
@@ -13896,11 +13971,11 @@ function addFrame(frameSchema) {
|
|
|
13896
13971
|
* ```
|
|
13897
13972
|
*/
|
|
13898
13973
|
function addWalker(walkerSchema) {
|
|
13899
|
-
|
|
13974
|
+
bt.loggerService.info(ADD_WALKER_METHOD_NAME, {
|
|
13900
13975
|
walkerSchema,
|
|
13901
13976
|
});
|
|
13902
|
-
|
|
13903
|
-
|
|
13977
|
+
bt.walkerValidationService.addWalker(walkerSchema.walkerName, walkerSchema);
|
|
13978
|
+
bt.walkerSchemaService.register(walkerSchema.walkerName, walkerSchema);
|
|
13904
13979
|
}
|
|
13905
13980
|
/**
|
|
13906
13981
|
* Registers a position sizing configuration in the framework.
|
|
@@ -13955,11 +14030,11 @@ function addWalker(walkerSchema) {
|
|
|
13955
14030
|
* ```
|
|
13956
14031
|
*/
|
|
13957
14032
|
function addSizing(sizingSchema) {
|
|
13958
|
-
|
|
14033
|
+
bt.loggerService.info(ADD_SIZING_METHOD_NAME, {
|
|
13959
14034
|
sizingSchema,
|
|
13960
14035
|
});
|
|
13961
|
-
|
|
13962
|
-
|
|
14036
|
+
bt.sizingValidationService.addSizing(sizingSchema.sizingName, sizingSchema);
|
|
14037
|
+
bt.sizingSchemaService.register(sizingSchema.sizingName, sizingSchema);
|
|
13963
14038
|
}
|
|
13964
14039
|
/**
|
|
13965
14040
|
* Registers a risk management configuration in the framework.
|
|
@@ -14023,11 +14098,11 @@ function addSizing(sizingSchema) {
|
|
|
14023
14098
|
* ```
|
|
14024
14099
|
*/
|
|
14025
14100
|
function addRisk(riskSchema) {
|
|
14026
|
-
|
|
14101
|
+
bt.loggerService.info(ADD_RISK_METHOD_NAME, {
|
|
14027
14102
|
riskSchema,
|
|
14028
14103
|
});
|
|
14029
|
-
|
|
14030
|
-
|
|
14104
|
+
bt.riskValidationService.addRisk(riskSchema.riskName, riskSchema);
|
|
14105
|
+
bt.riskSchemaService.register(riskSchema.riskName, riskSchema);
|
|
14031
14106
|
}
|
|
14032
14107
|
/**
|
|
14033
14108
|
* Registers an optimizer configuration in the framework.
|
|
@@ -14117,11 +14192,11 @@ function addRisk(riskSchema) {
|
|
|
14117
14192
|
* ```
|
|
14118
14193
|
*/
|
|
14119
14194
|
function addOptimizer(optimizerSchema) {
|
|
14120
|
-
|
|
14195
|
+
bt.loggerService.info(ADD_OPTIMIZER_METHOD_NAME, {
|
|
14121
14196
|
optimizerSchema,
|
|
14122
14197
|
});
|
|
14123
|
-
|
|
14124
|
-
|
|
14198
|
+
bt.optimizerValidationService.addOptimizer(optimizerSchema.optimizerName, optimizerSchema);
|
|
14199
|
+
bt.optimizerSchemaService.register(optimizerSchema.optimizerName, optimizerSchema);
|
|
14125
14200
|
}
|
|
14126
14201
|
|
|
14127
14202
|
const LIST_EXCHANGES_METHOD_NAME = "list.listExchanges";
|
|
@@ -14157,8 +14232,8 @@ const LIST_OPTIMIZERS_METHOD_NAME = "list.listOptimizers";
|
|
|
14157
14232
|
* ```
|
|
14158
14233
|
*/
|
|
14159
14234
|
async function listExchanges() {
|
|
14160
|
-
|
|
14161
|
-
return await
|
|
14235
|
+
bt.loggerService.log(LIST_EXCHANGES_METHOD_NAME);
|
|
14236
|
+
return await bt.exchangeValidationService.list();
|
|
14162
14237
|
}
|
|
14163
14238
|
/**
|
|
14164
14239
|
* Returns a list of all registered strategy schemas.
|
|
@@ -14191,8 +14266,8 @@ async function listExchanges() {
|
|
|
14191
14266
|
* ```
|
|
14192
14267
|
*/
|
|
14193
14268
|
async function listStrategies() {
|
|
14194
|
-
|
|
14195
|
-
return await
|
|
14269
|
+
bt.loggerService.log(LIST_STRATEGIES_METHOD_NAME);
|
|
14270
|
+
return await bt.strategyValidationService.list();
|
|
14196
14271
|
}
|
|
14197
14272
|
/**
|
|
14198
14273
|
* Returns a list of all registered frame schemas.
|
|
@@ -14220,8 +14295,8 @@ async function listStrategies() {
|
|
|
14220
14295
|
* ```
|
|
14221
14296
|
*/
|
|
14222
14297
|
async function listFrames() {
|
|
14223
|
-
|
|
14224
|
-
return await
|
|
14298
|
+
bt.loggerService.log(LIST_FRAMES_METHOD_NAME);
|
|
14299
|
+
return await bt.frameValidationService.list();
|
|
14225
14300
|
}
|
|
14226
14301
|
/**
|
|
14227
14302
|
* Returns a list of all registered walker schemas.
|
|
@@ -14250,8 +14325,8 @@ async function listFrames() {
|
|
|
14250
14325
|
* ```
|
|
14251
14326
|
*/
|
|
14252
14327
|
async function listWalkers() {
|
|
14253
|
-
|
|
14254
|
-
return await
|
|
14328
|
+
bt.loggerService.log(LIST_WALKERS_METHOD_NAME);
|
|
14329
|
+
return await bt.walkerValidationService.list();
|
|
14255
14330
|
}
|
|
14256
14331
|
/**
|
|
14257
14332
|
* Returns a list of all registered sizing schemas.
|
|
@@ -14289,8 +14364,8 @@ async function listWalkers() {
|
|
|
14289
14364
|
* ```
|
|
14290
14365
|
*/
|
|
14291
14366
|
async function listSizings() {
|
|
14292
|
-
|
|
14293
|
-
return await
|
|
14367
|
+
bt.loggerService.log(LIST_SIZINGS_METHOD_NAME);
|
|
14368
|
+
return await bt.sizingValidationService.list();
|
|
14294
14369
|
}
|
|
14295
14370
|
/**
|
|
14296
14371
|
* Returns a list of all registered risk schemas.
|
|
@@ -14325,8 +14400,8 @@ async function listSizings() {
|
|
|
14325
14400
|
* ```
|
|
14326
14401
|
*/
|
|
14327
14402
|
async function listRisks() {
|
|
14328
|
-
|
|
14329
|
-
return await
|
|
14403
|
+
bt.loggerService.log(LIST_RISKS_METHOD_NAME);
|
|
14404
|
+
return await bt.riskValidationService.list();
|
|
14330
14405
|
}
|
|
14331
14406
|
/**
|
|
14332
14407
|
* Returns a list of all registered optimizer schemas.
|
|
@@ -14365,8 +14440,8 @@ async function listRisks() {
|
|
|
14365
14440
|
* ```
|
|
14366
14441
|
*/
|
|
14367
14442
|
async function listOptimizers() {
|
|
14368
|
-
|
|
14369
|
-
return await
|
|
14443
|
+
bt.loggerService.log(LIST_OPTIMIZERS_METHOD_NAME);
|
|
14444
|
+
return await bt.optimizerValidationService.list();
|
|
14370
14445
|
}
|
|
14371
14446
|
|
|
14372
14447
|
const LISTEN_SIGNAL_METHOD_NAME = "event.listenSignal";
|
|
@@ -14423,7 +14498,7 @@ const LISTEN_RISK_ONCE_METHOD_NAME = "event.listenRiskOnce";
|
|
|
14423
14498
|
* ```
|
|
14424
14499
|
*/
|
|
14425
14500
|
function listenSignal(fn) {
|
|
14426
|
-
|
|
14501
|
+
bt.loggerService.log(LISTEN_SIGNAL_METHOD_NAME);
|
|
14427
14502
|
return signalEmitter.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
14428
14503
|
}
|
|
14429
14504
|
/**
|
|
@@ -14459,7 +14534,7 @@ function listenSignal(fn) {
|
|
|
14459
14534
|
* ```
|
|
14460
14535
|
*/
|
|
14461
14536
|
function listenSignalOnce(filterFn, fn) {
|
|
14462
|
-
|
|
14537
|
+
bt.loggerService.log(LISTEN_SIGNAL_ONCE_METHOD_NAME);
|
|
14463
14538
|
return signalEmitter.filter(filterFn).once(fn);
|
|
14464
14539
|
}
|
|
14465
14540
|
/**
|
|
@@ -14483,7 +14558,7 @@ function listenSignalOnce(filterFn, fn) {
|
|
|
14483
14558
|
* ```
|
|
14484
14559
|
*/
|
|
14485
14560
|
function listenSignalLive(fn) {
|
|
14486
|
-
|
|
14561
|
+
bt.loggerService.log(LISTEN_SIGNAL_LIVE_METHOD_NAME);
|
|
14487
14562
|
return signalLiveEmitter.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
14488
14563
|
}
|
|
14489
14564
|
/**
|
|
@@ -14508,7 +14583,7 @@ function listenSignalLive(fn) {
|
|
|
14508
14583
|
* ```
|
|
14509
14584
|
*/
|
|
14510
14585
|
function listenSignalLiveOnce(filterFn, fn) {
|
|
14511
|
-
|
|
14586
|
+
bt.loggerService.log(LISTEN_SIGNAL_LIVE_ONCE_METHOD_NAME);
|
|
14512
14587
|
return signalLiveEmitter.filter(filterFn).once(fn);
|
|
14513
14588
|
}
|
|
14514
14589
|
/**
|
|
@@ -14532,7 +14607,7 @@ function listenSignalLiveOnce(filterFn, fn) {
|
|
|
14532
14607
|
* ```
|
|
14533
14608
|
*/
|
|
14534
14609
|
function listenSignalBacktest(fn) {
|
|
14535
|
-
|
|
14610
|
+
bt.loggerService.log(LISTEN_SIGNAL_BACKTEST_METHOD_NAME);
|
|
14536
14611
|
return signalBacktestEmitter.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
14537
14612
|
}
|
|
14538
14613
|
/**
|
|
@@ -14557,7 +14632,7 @@ function listenSignalBacktest(fn) {
|
|
|
14557
14632
|
* ```
|
|
14558
14633
|
*/
|
|
14559
14634
|
function listenSignalBacktestOnce(filterFn, fn) {
|
|
14560
|
-
|
|
14635
|
+
bt.loggerService.log(LISTEN_SIGNAL_BACKTEST_ONCE_METHOD_NAME);
|
|
14561
14636
|
return signalBacktestEmitter.filter(filterFn).once(fn);
|
|
14562
14637
|
}
|
|
14563
14638
|
/**
|
|
@@ -14585,7 +14660,7 @@ function listenSignalBacktestOnce(filterFn, fn) {
|
|
|
14585
14660
|
* ```
|
|
14586
14661
|
*/
|
|
14587
14662
|
function listenError(fn) {
|
|
14588
|
-
|
|
14663
|
+
bt.loggerService.log(LISTEN_ERROR_METHOD_NAME);
|
|
14589
14664
|
return errorEmitter.subscribe(functoolsKit.queued(async (error) => fn(error)));
|
|
14590
14665
|
}
|
|
14591
14666
|
/**
|
|
@@ -14613,7 +14688,7 @@ function listenError(fn) {
|
|
|
14613
14688
|
* ```
|
|
14614
14689
|
*/
|
|
14615
14690
|
function listenExit(fn) {
|
|
14616
|
-
|
|
14691
|
+
bt.loggerService.log(LISTEN_EXIT_METHOD_NAME);
|
|
14617
14692
|
return exitEmitter.subscribe(functoolsKit.queued(async (error) => fn(error)));
|
|
14618
14693
|
}
|
|
14619
14694
|
/**
|
|
@@ -14644,7 +14719,7 @@ function listenExit(fn) {
|
|
|
14644
14719
|
* ```
|
|
14645
14720
|
*/
|
|
14646
14721
|
function listenDoneLive(fn) {
|
|
14647
|
-
|
|
14722
|
+
bt.loggerService.log(LISTEN_DONE_LIVE_METHOD_NAME);
|
|
14648
14723
|
return doneLiveSubject.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
14649
14724
|
}
|
|
14650
14725
|
/**
|
|
@@ -14674,7 +14749,7 @@ function listenDoneLive(fn) {
|
|
|
14674
14749
|
* ```
|
|
14675
14750
|
*/
|
|
14676
14751
|
function listenDoneLiveOnce(filterFn, fn) {
|
|
14677
|
-
|
|
14752
|
+
bt.loggerService.log(LISTEN_DONE_LIVE_ONCE_METHOD_NAME);
|
|
14678
14753
|
return doneLiveSubject.filter(filterFn).once(fn);
|
|
14679
14754
|
}
|
|
14680
14755
|
/**
|
|
@@ -14706,7 +14781,7 @@ function listenDoneLiveOnce(filterFn, fn) {
|
|
|
14706
14781
|
* ```
|
|
14707
14782
|
*/
|
|
14708
14783
|
function listenDoneBacktest(fn) {
|
|
14709
|
-
|
|
14784
|
+
bt.loggerService.log(LISTEN_DONE_BACKTEST_METHOD_NAME);
|
|
14710
14785
|
return doneBacktestSubject.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
14711
14786
|
}
|
|
14712
14787
|
/**
|
|
@@ -14737,7 +14812,7 @@ function listenDoneBacktest(fn) {
|
|
|
14737
14812
|
* ```
|
|
14738
14813
|
*/
|
|
14739
14814
|
function listenDoneBacktestOnce(filterFn, fn) {
|
|
14740
|
-
|
|
14815
|
+
bt.loggerService.log(LISTEN_DONE_BACKTEST_ONCE_METHOD_NAME);
|
|
14741
14816
|
return doneBacktestSubject.filter(filterFn).once(fn);
|
|
14742
14817
|
}
|
|
14743
14818
|
/**
|
|
@@ -14767,7 +14842,7 @@ function listenDoneBacktestOnce(filterFn, fn) {
|
|
|
14767
14842
|
* ```
|
|
14768
14843
|
*/
|
|
14769
14844
|
function listenDoneWalker(fn) {
|
|
14770
|
-
|
|
14845
|
+
bt.loggerService.log(LISTEN_DONE_WALKER_METHOD_NAME);
|
|
14771
14846
|
return doneWalkerSubject.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
14772
14847
|
}
|
|
14773
14848
|
/**
|
|
@@ -14796,7 +14871,7 @@ function listenDoneWalker(fn) {
|
|
|
14796
14871
|
* ```
|
|
14797
14872
|
*/
|
|
14798
14873
|
function listenDoneWalkerOnce(filterFn, fn) {
|
|
14799
|
-
|
|
14874
|
+
bt.loggerService.log(LISTEN_DONE_WALKER_ONCE_METHOD_NAME);
|
|
14800
14875
|
return doneWalkerSubject.filter(filterFn).once(fn);
|
|
14801
14876
|
}
|
|
14802
14877
|
/**
|
|
@@ -14830,7 +14905,7 @@ function listenDoneWalkerOnce(filterFn, fn) {
|
|
|
14830
14905
|
* ```
|
|
14831
14906
|
*/
|
|
14832
14907
|
function listenBacktestProgress(fn) {
|
|
14833
|
-
|
|
14908
|
+
bt.loggerService.log(LISTEN_PROGRESS_METHOD_NAME);
|
|
14834
14909
|
return progressBacktestEmitter.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
14835
14910
|
}
|
|
14836
14911
|
/**
|
|
@@ -14864,7 +14939,7 @@ function listenBacktestProgress(fn) {
|
|
|
14864
14939
|
* ```
|
|
14865
14940
|
*/
|
|
14866
14941
|
function listenWalkerProgress(fn) {
|
|
14867
|
-
|
|
14942
|
+
bt.loggerService.log(LISTEN_PROGRESS_WALKER_METHOD_NAME);
|
|
14868
14943
|
return progressWalkerEmitter.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
14869
14944
|
}
|
|
14870
14945
|
/**
|
|
@@ -14892,7 +14967,7 @@ function listenWalkerProgress(fn) {
|
|
|
14892
14967
|
* ```
|
|
14893
14968
|
*/
|
|
14894
14969
|
function listenOptimizerProgress(fn) {
|
|
14895
|
-
|
|
14970
|
+
bt.loggerService.log(LISTEN_PROGRESS_OPTIMIZER_METHOD_NAME);
|
|
14896
14971
|
return progressOptimizerEmitter.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
14897
14972
|
}
|
|
14898
14973
|
/**
|
|
@@ -14928,7 +15003,7 @@ function listenOptimizerProgress(fn) {
|
|
|
14928
15003
|
* ```
|
|
14929
15004
|
*/
|
|
14930
15005
|
function listenPerformance(fn) {
|
|
14931
|
-
|
|
15006
|
+
bt.loggerService.log(LISTEN_PERFORMANCE_METHOD_NAME);
|
|
14932
15007
|
return performanceEmitter.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
14933
15008
|
}
|
|
14934
15009
|
/**
|
|
@@ -14962,7 +15037,7 @@ function listenPerformance(fn) {
|
|
|
14962
15037
|
* ```
|
|
14963
15038
|
*/
|
|
14964
15039
|
function listenWalker(fn) {
|
|
14965
|
-
|
|
15040
|
+
bt.loggerService.log(LISTEN_WALKER_METHOD_NAME);
|
|
14966
15041
|
return walkerEmitter.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
14967
15042
|
}
|
|
14968
15043
|
/**
|
|
@@ -15005,7 +15080,7 @@ function listenWalker(fn) {
|
|
|
15005
15080
|
* ```
|
|
15006
15081
|
*/
|
|
15007
15082
|
function listenWalkerOnce(filterFn, fn) {
|
|
15008
|
-
|
|
15083
|
+
bt.loggerService.log(LISTEN_WALKER_ONCE_METHOD_NAME);
|
|
15009
15084
|
return walkerEmitter.filter(filterFn).once(fn);
|
|
15010
15085
|
}
|
|
15011
15086
|
/**
|
|
@@ -15040,7 +15115,7 @@ function listenWalkerOnce(filterFn, fn) {
|
|
|
15040
15115
|
* ```
|
|
15041
15116
|
*/
|
|
15042
15117
|
function listenWalkerComplete(fn) {
|
|
15043
|
-
|
|
15118
|
+
bt.loggerService.log(LISTEN_WALKER_COMPLETE_METHOD_NAME);
|
|
15044
15119
|
return walkerCompleteSubject.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
15045
15120
|
}
|
|
15046
15121
|
/**
|
|
@@ -15068,7 +15143,7 @@ function listenWalkerComplete(fn) {
|
|
|
15068
15143
|
* ```
|
|
15069
15144
|
*/
|
|
15070
15145
|
function listenValidation(fn) {
|
|
15071
|
-
|
|
15146
|
+
bt.loggerService.log(LISTEN_VALIDATION_METHOD_NAME);
|
|
15072
15147
|
return validationSubject.subscribe(functoolsKit.queued(async (error) => fn(error)));
|
|
15073
15148
|
}
|
|
15074
15149
|
/**
|
|
@@ -15096,7 +15171,7 @@ function listenValidation(fn) {
|
|
|
15096
15171
|
* ```
|
|
15097
15172
|
*/
|
|
15098
15173
|
function listenPartialProfit(fn) {
|
|
15099
|
-
|
|
15174
|
+
bt.loggerService.log(LISTEN_PARTIAL_PROFIT_METHOD_NAME);
|
|
15100
15175
|
return partialProfitSubject.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
15101
15176
|
}
|
|
15102
15177
|
/**
|
|
@@ -15130,7 +15205,7 @@ function listenPartialProfit(fn) {
|
|
|
15130
15205
|
* ```
|
|
15131
15206
|
*/
|
|
15132
15207
|
function listenPartialProfitOnce(filterFn, fn) {
|
|
15133
|
-
|
|
15208
|
+
bt.loggerService.log(LISTEN_PARTIAL_PROFIT_ONCE_METHOD_NAME);
|
|
15134
15209
|
return partialProfitSubject.filter(filterFn).once(fn);
|
|
15135
15210
|
}
|
|
15136
15211
|
/**
|
|
@@ -15158,7 +15233,7 @@ function listenPartialProfitOnce(filterFn, fn) {
|
|
|
15158
15233
|
* ```
|
|
15159
15234
|
*/
|
|
15160
15235
|
function listenPartialLoss(fn) {
|
|
15161
|
-
|
|
15236
|
+
bt.loggerService.log(LISTEN_PARTIAL_LOSS_METHOD_NAME);
|
|
15162
15237
|
return partialLossSubject.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
15163
15238
|
}
|
|
15164
15239
|
/**
|
|
@@ -15192,7 +15267,7 @@ function listenPartialLoss(fn) {
|
|
|
15192
15267
|
* ```
|
|
15193
15268
|
*/
|
|
15194
15269
|
function listenPartialLossOnce(filterFn, fn) {
|
|
15195
|
-
|
|
15270
|
+
bt.loggerService.log(LISTEN_PARTIAL_LOSS_ONCE_METHOD_NAME);
|
|
15196
15271
|
return partialLossSubject.filter(filterFn).once(fn);
|
|
15197
15272
|
}
|
|
15198
15273
|
/**
|
|
@@ -15224,7 +15299,7 @@ function listenPartialLossOnce(filterFn, fn) {
|
|
|
15224
15299
|
* ```
|
|
15225
15300
|
*/
|
|
15226
15301
|
function listenRisk(fn) {
|
|
15227
|
-
|
|
15302
|
+
bt.loggerService.log(LISTEN_RISK_METHOD_NAME);
|
|
15228
15303
|
return riskSubject.subscribe(functoolsKit.queued(async (event) => fn(event)));
|
|
15229
15304
|
}
|
|
15230
15305
|
/**
|
|
@@ -15261,7 +15336,7 @@ function listenRisk(fn) {
|
|
|
15261
15336
|
* ```
|
|
15262
15337
|
*/
|
|
15263
15338
|
function listenRiskOnce(filterFn, fn) {
|
|
15264
|
-
|
|
15339
|
+
bt.loggerService.log(LISTEN_RISK_ONCE_METHOD_NAME);
|
|
15265
15340
|
return riskSubject.filter(filterFn).once(fn);
|
|
15266
15341
|
}
|
|
15267
15342
|
|
|
@@ -15289,12 +15364,12 @@ const GET_MODE_METHOD_NAME = "exchange.getMode";
|
|
|
15289
15364
|
* ```
|
|
15290
15365
|
*/
|
|
15291
15366
|
async function getCandles(symbol, interval, limit) {
|
|
15292
|
-
|
|
15367
|
+
bt.loggerService.info(GET_CANDLES_METHOD_NAME, {
|
|
15293
15368
|
symbol,
|
|
15294
15369
|
interval,
|
|
15295
15370
|
limit,
|
|
15296
15371
|
});
|
|
15297
|
-
return await
|
|
15372
|
+
return await bt.exchangeConnectionService.getCandles(symbol, interval, limit);
|
|
15298
15373
|
}
|
|
15299
15374
|
/**
|
|
15300
15375
|
* Calculates VWAP (Volume Weighted Average Price) for a symbol.
|
|
@@ -15315,10 +15390,10 @@ async function getCandles(symbol, interval, limit) {
|
|
|
15315
15390
|
* ```
|
|
15316
15391
|
*/
|
|
15317
15392
|
async function getAveragePrice(symbol) {
|
|
15318
|
-
|
|
15393
|
+
bt.loggerService.info(GET_AVERAGE_PRICE_METHOD_NAME, {
|
|
15319
15394
|
symbol,
|
|
15320
15395
|
});
|
|
15321
|
-
return await
|
|
15396
|
+
return await bt.exchangeConnectionService.getAveragePrice(symbol);
|
|
15322
15397
|
}
|
|
15323
15398
|
/**
|
|
15324
15399
|
* Formats a price value according to exchange rules.
|
|
@@ -15336,11 +15411,11 @@ async function getAveragePrice(symbol) {
|
|
|
15336
15411
|
* ```
|
|
15337
15412
|
*/
|
|
15338
15413
|
async function formatPrice(symbol, price) {
|
|
15339
|
-
|
|
15414
|
+
bt.loggerService.info(FORMAT_PRICE_METHOD_NAME, {
|
|
15340
15415
|
symbol,
|
|
15341
15416
|
price,
|
|
15342
15417
|
});
|
|
15343
|
-
return await
|
|
15418
|
+
return await bt.exchangeConnectionService.formatPrice(symbol, price);
|
|
15344
15419
|
}
|
|
15345
15420
|
/**
|
|
15346
15421
|
* Formats a quantity value according to exchange rules.
|
|
@@ -15358,11 +15433,11 @@ async function formatPrice(symbol, price) {
|
|
|
15358
15433
|
* ```
|
|
15359
15434
|
*/
|
|
15360
15435
|
async function formatQuantity(symbol, quantity) {
|
|
15361
|
-
|
|
15436
|
+
bt.loggerService.info(FORMAT_QUANTITY_METHOD_NAME, {
|
|
15362
15437
|
symbol,
|
|
15363
15438
|
quantity,
|
|
15364
15439
|
});
|
|
15365
|
-
return await
|
|
15440
|
+
return await bt.exchangeConnectionService.formatQuantity(symbol, quantity);
|
|
15366
15441
|
}
|
|
15367
15442
|
/**
|
|
15368
15443
|
* Gets the current date from execution context.
|
|
@@ -15379,8 +15454,8 @@ async function formatQuantity(symbol, quantity) {
|
|
|
15379
15454
|
* ```
|
|
15380
15455
|
*/
|
|
15381
15456
|
async function getDate() {
|
|
15382
|
-
|
|
15383
|
-
const { when } =
|
|
15457
|
+
bt.loggerService.info(GET_DATE_METHOD_NAME);
|
|
15458
|
+
const { when } = bt.executionContextService.context;
|
|
15384
15459
|
return new Date(when.getTime());
|
|
15385
15460
|
}
|
|
15386
15461
|
/**
|
|
@@ -15399,9 +15474,9 @@ async function getDate() {
|
|
|
15399
15474
|
* ```
|
|
15400
15475
|
*/
|
|
15401
15476
|
async function getMode() {
|
|
15402
|
-
|
|
15403
|
-
const { backtest: bt } =
|
|
15404
|
-
return bt ? "backtest" : "live";
|
|
15477
|
+
bt.loggerService.info(GET_MODE_METHOD_NAME);
|
|
15478
|
+
const { backtest: bt$1 } = bt.executionContextService.context;
|
|
15479
|
+
return bt$1 ? "backtest" : "live";
|
|
15405
15480
|
}
|
|
15406
15481
|
|
|
15407
15482
|
const DUMP_SIGNAL_METHOD_NAME = "dump.dumpSignal";
|
|
@@ -15472,13 +15547,13 @@ const DUMP_SIGNAL_METHOD_NAME = "dump.dumpSignal";
|
|
|
15472
15547
|
* ```
|
|
15473
15548
|
*/
|
|
15474
15549
|
async function dumpSignal(signalId, history, signal, outputDir = "./dump/strategy") {
|
|
15475
|
-
|
|
15550
|
+
bt.loggerService.info(DUMP_SIGNAL_METHOD_NAME, {
|
|
15476
15551
|
signalId,
|
|
15477
15552
|
history,
|
|
15478
15553
|
signal,
|
|
15479
15554
|
outputDir,
|
|
15480
15555
|
});
|
|
15481
|
-
return await
|
|
15556
|
+
return await bt.outlineMarkdownService.dumpSignal(signalId, history, signal, outputDir);
|
|
15482
15557
|
}
|
|
15483
15558
|
|
|
15484
15559
|
const BACKTEST_METHOD_NAME_RUN = "BacktestUtils.run";
|
|
@@ -15565,7 +15640,7 @@ class BacktestInstance {
|
|
|
15565
15640
|
* @internal
|
|
15566
15641
|
*/
|
|
15567
15642
|
this.task = functoolsKit.singlerun(async (symbol, context) => {
|
|
15568
|
-
|
|
15643
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_TASK, {
|
|
15569
15644
|
symbol,
|
|
15570
15645
|
context,
|
|
15571
15646
|
});
|
|
@@ -15584,7 +15659,7 @@ class BacktestInstance {
|
|
|
15584
15659
|
* ```
|
|
15585
15660
|
*/
|
|
15586
15661
|
this.getStatus = async () => {
|
|
15587
|
-
|
|
15662
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_GET_STATUS);
|
|
15588
15663
|
return {
|
|
15589
15664
|
id: this.id,
|
|
15590
15665
|
symbol: this.symbol,
|
|
@@ -15600,23 +15675,27 @@ class BacktestInstance {
|
|
|
15600
15675
|
* @returns Async generator yielding closed signals with PNL
|
|
15601
15676
|
*/
|
|
15602
15677
|
this.run = (symbol, context) => {
|
|
15603
|
-
|
|
15678
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_RUN, {
|
|
15604
15679
|
symbol,
|
|
15605
15680
|
context,
|
|
15606
15681
|
});
|
|
15607
15682
|
{
|
|
15608
|
-
|
|
15609
|
-
|
|
15683
|
+
bt.backtestMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15684
|
+
bt.liveMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15685
|
+
bt.scheduleMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15686
|
+
bt.performanceMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15687
|
+
bt.partialMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15688
|
+
bt.riskMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15610
15689
|
}
|
|
15611
15690
|
{
|
|
15612
|
-
|
|
15691
|
+
bt.strategyCoreService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15613
15692
|
}
|
|
15614
15693
|
{
|
|
15615
|
-
const { riskName, riskList } =
|
|
15616
|
-
riskName &&
|
|
15617
|
-
riskList && riskList.forEach((riskName) =>
|
|
15694
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
15695
|
+
riskName && bt.riskGlobalService.clear(true, riskName);
|
|
15696
|
+
riskList && riskList.forEach((riskName) => bt.riskGlobalService.clear(true, riskName));
|
|
15618
15697
|
}
|
|
15619
|
-
return
|
|
15698
|
+
return bt.backtestCommandService.run(symbol, context);
|
|
15620
15699
|
};
|
|
15621
15700
|
/**
|
|
15622
15701
|
* Runs backtest in background without yielding results.
|
|
@@ -15639,14 +15718,23 @@ class BacktestInstance {
|
|
|
15639
15718
|
* ```
|
|
15640
15719
|
*/
|
|
15641
15720
|
this.background = (symbol, context) => {
|
|
15642
|
-
|
|
15721
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_BACKGROUND, {
|
|
15643
15722
|
symbol,
|
|
15644
15723
|
context,
|
|
15645
15724
|
});
|
|
15725
|
+
{
|
|
15726
|
+
const currentStatus = this.task.getStatus();
|
|
15727
|
+
if (currentStatus === "pending") {
|
|
15728
|
+
throw new Error(`Backtest.background is already running for symbol=${symbol} strategyName=${context.strategyName} exchangeName=${context.exchangeName} frameName=${context.frameName}`);
|
|
15729
|
+
}
|
|
15730
|
+
if (currentStatus === "rejected") {
|
|
15731
|
+
throw new Error(`Backtest.background has failed for symbol=${symbol} strategyName=${context.strategyName} exchangeName=${context.exchangeName} frameName=${context.frameName}`);
|
|
15732
|
+
}
|
|
15733
|
+
}
|
|
15646
15734
|
this.task(symbol, context).catch((error) => exitEmitter.next(new Error(functoolsKit.getErrorMessage(error))));
|
|
15647
15735
|
return () => {
|
|
15648
|
-
|
|
15649
|
-
|
|
15736
|
+
bt.strategyCoreService.stop(true, { symbol, strategyName: context.strategyName });
|
|
15737
|
+
bt.strategyCoreService
|
|
15650
15738
|
.getPendingSignal(true, symbol, context.strategyName)
|
|
15651
15739
|
.then(async (pendingSignal) => {
|
|
15652
15740
|
if (pendingSignal) {
|
|
@@ -15683,11 +15771,11 @@ class BacktestInstance {
|
|
|
15683
15771
|
* ```
|
|
15684
15772
|
*/
|
|
15685
15773
|
this.stop = async (symbol, strategyName) => {
|
|
15686
|
-
|
|
15774
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_STOP, {
|
|
15687
15775
|
symbol,
|
|
15688
15776
|
strategyName,
|
|
15689
15777
|
});
|
|
15690
|
-
await
|
|
15778
|
+
await bt.strategyCoreService.stop(true, { symbol, strategyName });
|
|
15691
15779
|
};
|
|
15692
15780
|
/**
|
|
15693
15781
|
* Gets statistical data from all closed signals for a symbol-strategy pair.
|
|
@@ -15704,11 +15792,11 @@ class BacktestInstance {
|
|
|
15704
15792
|
* ```
|
|
15705
15793
|
*/
|
|
15706
15794
|
this.getData = async (symbol, strategyName) => {
|
|
15707
|
-
|
|
15795
|
+
bt.loggerService.info("BacktestUtils.getData", {
|
|
15708
15796
|
symbol,
|
|
15709
15797
|
strategyName,
|
|
15710
15798
|
});
|
|
15711
|
-
return await
|
|
15799
|
+
return await bt.backtestMarkdownService.getData(symbol, strategyName, true);
|
|
15712
15800
|
};
|
|
15713
15801
|
/**
|
|
15714
15802
|
* Generates markdown report with all closed signals for a symbol-strategy pair.
|
|
@@ -15726,11 +15814,11 @@ class BacktestInstance {
|
|
|
15726
15814
|
* ```
|
|
15727
15815
|
*/
|
|
15728
15816
|
this.getReport = async (symbol, strategyName, columns) => {
|
|
15729
|
-
|
|
15817
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_GET_REPORT, {
|
|
15730
15818
|
symbol,
|
|
15731
15819
|
strategyName,
|
|
15732
15820
|
});
|
|
15733
|
-
return await
|
|
15821
|
+
return await bt.backtestMarkdownService.getReport(symbol, strategyName, true, columns);
|
|
15734
15822
|
};
|
|
15735
15823
|
/**
|
|
15736
15824
|
* Saves strategy report to disk.
|
|
@@ -15751,12 +15839,12 @@ class BacktestInstance {
|
|
|
15751
15839
|
* ```
|
|
15752
15840
|
*/
|
|
15753
15841
|
this.dump = async (symbol, strategyName, path, columns) => {
|
|
15754
|
-
|
|
15842
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_DUMP, {
|
|
15755
15843
|
symbol,
|
|
15756
15844
|
strategyName,
|
|
15757
15845
|
path,
|
|
15758
15846
|
});
|
|
15759
|
-
await
|
|
15847
|
+
await bt.backtestMarkdownService.dump(symbol, strategyName, true, path, columns);
|
|
15760
15848
|
};
|
|
15761
15849
|
}
|
|
15762
15850
|
}
|
|
@@ -15795,14 +15883,14 @@ class BacktestUtils {
|
|
|
15795
15883
|
*/
|
|
15796
15884
|
this.run = (symbol, context) => {
|
|
15797
15885
|
{
|
|
15798
|
-
|
|
15799
|
-
|
|
15800
|
-
|
|
15886
|
+
bt.strategyValidationService.validate(context.strategyName, BACKTEST_METHOD_NAME_RUN);
|
|
15887
|
+
bt.exchangeValidationService.validate(context.exchangeName, BACKTEST_METHOD_NAME_RUN);
|
|
15888
|
+
bt.frameValidationService.validate(context.frameName, BACKTEST_METHOD_NAME_RUN);
|
|
15801
15889
|
}
|
|
15802
15890
|
{
|
|
15803
|
-
const { riskName, riskList } =
|
|
15804
|
-
riskName &&
|
|
15805
|
-
riskList && riskList.forEach((riskName) =>
|
|
15891
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
15892
|
+
riskName && bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_RUN);
|
|
15893
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_RUN));
|
|
15806
15894
|
}
|
|
15807
15895
|
const instance = this._getInstance(symbol, context.strategyName);
|
|
15808
15896
|
return instance.run(symbol, context);
|
|
@@ -15829,13 +15917,13 @@ class BacktestUtils {
|
|
|
15829
15917
|
* ```
|
|
15830
15918
|
*/
|
|
15831
15919
|
this.background = (symbol, context) => {
|
|
15832
|
-
|
|
15833
|
-
|
|
15834
|
-
|
|
15920
|
+
bt.strategyValidationService.validate(context.strategyName, BACKTEST_METHOD_NAME_BACKGROUND);
|
|
15921
|
+
bt.exchangeValidationService.validate(context.exchangeName, BACKTEST_METHOD_NAME_BACKGROUND);
|
|
15922
|
+
bt.frameValidationService.validate(context.frameName, BACKTEST_METHOD_NAME_BACKGROUND);
|
|
15835
15923
|
{
|
|
15836
|
-
const { riskName, riskList } =
|
|
15837
|
-
riskName &&
|
|
15838
|
-
riskList && riskList.forEach((riskName) =>
|
|
15924
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
15925
|
+
riskName && bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_BACKGROUND);
|
|
15926
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_BACKGROUND));
|
|
15839
15927
|
}
|
|
15840
15928
|
const instance = this._getInstance(symbol, context.strategyName);
|
|
15841
15929
|
return instance.background(symbol, context);
|
|
@@ -15858,11 +15946,11 @@ class BacktestUtils {
|
|
|
15858
15946
|
* ```
|
|
15859
15947
|
*/
|
|
15860
15948
|
this.stop = async (symbol, strategyName) => {
|
|
15861
|
-
|
|
15949
|
+
bt.strategyValidationService.validate(strategyName, BACKTEST_METHOD_NAME_STOP);
|
|
15862
15950
|
{
|
|
15863
|
-
const { riskName, riskList } =
|
|
15864
|
-
riskName &&
|
|
15865
|
-
riskList && riskList.forEach((riskName) =>
|
|
15951
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
15952
|
+
riskName && bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_STOP);
|
|
15953
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_STOP));
|
|
15866
15954
|
}
|
|
15867
15955
|
const instance = this._getInstance(symbol, strategyName);
|
|
15868
15956
|
return await instance.stop(symbol, strategyName);
|
|
@@ -15881,11 +15969,11 @@ class BacktestUtils {
|
|
|
15881
15969
|
* ```
|
|
15882
15970
|
*/
|
|
15883
15971
|
this.getData = async (symbol, strategyName) => {
|
|
15884
|
-
|
|
15972
|
+
bt.strategyValidationService.validate(strategyName, "BacktestUtils.getData");
|
|
15885
15973
|
{
|
|
15886
|
-
const { riskName, riskList } =
|
|
15887
|
-
riskName &&
|
|
15888
|
-
riskList && riskList.forEach((riskName) =>
|
|
15974
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
15975
|
+
riskName && bt.riskValidationService.validate(riskName, "BacktestUtils.getData");
|
|
15976
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, "BacktestUtils.getData"));
|
|
15889
15977
|
}
|
|
15890
15978
|
const instance = this._getInstance(symbol, strategyName);
|
|
15891
15979
|
return await instance.getData(symbol, strategyName);
|
|
@@ -15905,11 +15993,11 @@ class BacktestUtils {
|
|
|
15905
15993
|
* ```
|
|
15906
15994
|
*/
|
|
15907
15995
|
this.getReport = async (symbol, strategyName, columns) => {
|
|
15908
|
-
|
|
15996
|
+
bt.strategyValidationService.validate(strategyName, BACKTEST_METHOD_NAME_GET_REPORT);
|
|
15909
15997
|
{
|
|
15910
|
-
const { riskName, riskList } =
|
|
15911
|
-
riskName &&
|
|
15912
|
-
riskList && riskList.forEach((riskName) =>
|
|
15998
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
15999
|
+
riskName && bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_REPORT);
|
|
16000
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_REPORT));
|
|
15913
16001
|
}
|
|
15914
16002
|
const instance = this._getInstance(symbol, strategyName);
|
|
15915
16003
|
return await instance.getReport(symbol, strategyName, columns);
|
|
@@ -15932,11 +16020,11 @@ class BacktestUtils {
|
|
|
15932
16020
|
* ```
|
|
15933
16021
|
*/
|
|
15934
16022
|
this.dump = async (symbol, strategyName, path, columns) => {
|
|
15935
|
-
|
|
16023
|
+
bt.strategyValidationService.validate(strategyName, BACKTEST_METHOD_NAME_DUMP);
|
|
15936
16024
|
{
|
|
15937
|
-
const { riskName, riskList } =
|
|
15938
|
-
riskName &&
|
|
15939
|
-
riskList && riskList.forEach((riskName) =>
|
|
16025
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16026
|
+
riskName && bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_DUMP);
|
|
16027
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_DUMP));
|
|
15940
16028
|
}
|
|
15941
16029
|
const instance = this._getInstance(symbol, strategyName);
|
|
15942
16030
|
return await instance.dump(symbol, strategyName, path, columns);
|
|
@@ -16066,7 +16154,7 @@ class LiveInstance {
|
|
|
16066
16154
|
* @internal
|
|
16067
16155
|
*/
|
|
16068
16156
|
this.task = functoolsKit.singlerun(async (symbol, context) => {
|
|
16069
|
-
|
|
16157
|
+
bt.loggerService.info(LIVE_METHOD_NAME_TASK, {
|
|
16070
16158
|
symbol,
|
|
16071
16159
|
context,
|
|
16072
16160
|
});
|
|
@@ -16085,7 +16173,7 @@ class LiveInstance {
|
|
|
16085
16173
|
* ```
|
|
16086
16174
|
*/
|
|
16087
16175
|
this.getStatus = async () => {
|
|
16088
|
-
|
|
16176
|
+
bt.loggerService.info(LIVE_METHOD_NAME_GET_STATUS);
|
|
16089
16177
|
return {
|
|
16090
16178
|
id: this.id,
|
|
16091
16179
|
symbol: this.symbol,
|
|
@@ -16104,23 +16192,27 @@ class LiveInstance {
|
|
|
16104
16192
|
* @returns Infinite async generator yielding opened and closed signals
|
|
16105
16193
|
*/
|
|
16106
16194
|
this.run = (symbol, context) => {
|
|
16107
|
-
|
|
16195
|
+
bt.loggerService.info(LIVE_METHOD_NAME_RUN, {
|
|
16108
16196
|
symbol,
|
|
16109
16197
|
context,
|
|
16110
16198
|
});
|
|
16111
16199
|
{
|
|
16112
|
-
|
|
16113
|
-
|
|
16200
|
+
bt.backtestMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16201
|
+
bt.liveMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16202
|
+
bt.scheduleMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16203
|
+
bt.performanceMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16204
|
+
bt.partialMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16205
|
+
bt.riskMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16114
16206
|
}
|
|
16115
16207
|
{
|
|
16116
|
-
|
|
16208
|
+
bt.strategyCoreService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16117
16209
|
}
|
|
16118
16210
|
{
|
|
16119
|
-
const { riskName, riskList } =
|
|
16120
|
-
riskName &&
|
|
16121
|
-
riskList && riskList.forEach((riskName) =>
|
|
16211
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
16212
|
+
riskName && bt.riskGlobalService.clear(false, riskName);
|
|
16213
|
+
riskList && riskList.forEach((riskName) => bt.riskGlobalService.clear(false, riskName));
|
|
16122
16214
|
}
|
|
16123
|
-
return
|
|
16215
|
+
return bt.liveCommandService.run(symbol, context);
|
|
16124
16216
|
};
|
|
16125
16217
|
/**
|
|
16126
16218
|
* Runs live trading in background without yielding results.
|
|
@@ -16143,14 +16235,23 @@ class LiveInstance {
|
|
|
16143
16235
|
* ```
|
|
16144
16236
|
*/
|
|
16145
16237
|
this.background = (symbol, context) => {
|
|
16146
|
-
|
|
16238
|
+
bt.loggerService.info(LIVE_METHOD_NAME_BACKGROUND, {
|
|
16147
16239
|
symbol,
|
|
16148
16240
|
context,
|
|
16149
16241
|
});
|
|
16242
|
+
const currentStatus = this.task.getStatus();
|
|
16243
|
+
{
|
|
16244
|
+
if (currentStatus === "pending") {
|
|
16245
|
+
throw new Error(`Live.background is already running for symbol=${symbol} strategyName=${context.strategyName} exchangeName=${context.exchangeName}`);
|
|
16246
|
+
}
|
|
16247
|
+
if (currentStatus === "rejected") {
|
|
16248
|
+
throw new Error(`Live.background has failed for symbol=${symbol} strategyName=${context.strategyName} exchangeName=${context.exchangeName}`);
|
|
16249
|
+
}
|
|
16250
|
+
}
|
|
16150
16251
|
this.task(symbol, context).catch((error) => exitEmitter.next(new Error(functoolsKit.getErrorMessage(error))));
|
|
16151
16252
|
return () => {
|
|
16152
|
-
|
|
16153
|
-
|
|
16253
|
+
bt.strategyCoreService.stop(false, { symbol, strategyName: context.strategyName });
|
|
16254
|
+
bt.strategyCoreService
|
|
16154
16255
|
.getPendingSignal(false, symbol, context.strategyName)
|
|
16155
16256
|
.then(async (pendingSignal) => {
|
|
16156
16257
|
if (pendingSignal) {
|
|
@@ -16187,11 +16288,11 @@ class LiveInstance {
|
|
|
16187
16288
|
* ```
|
|
16188
16289
|
*/
|
|
16189
16290
|
this.stop = async (symbol, strategyName) => {
|
|
16190
|
-
|
|
16291
|
+
bt.loggerService.info(LIVE_METHOD_NAME_STOP, {
|
|
16191
16292
|
symbol,
|
|
16192
16293
|
strategyName,
|
|
16193
16294
|
});
|
|
16194
|
-
await
|
|
16295
|
+
await bt.strategyCoreService.stop(false, { symbol, strategyName });
|
|
16195
16296
|
};
|
|
16196
16297
|
/**
|
|
16197
16298
|
* Gets statistical data from all live trading events for a symbol-strategy pair.
|
|
@@ -16208,11 +16309,11 @@ class LiveInstance {
|
|
|
16208
16309
|
* ```
|
|
16209
16310
|
*/
|
|
16210
16311
|
this.getData = async (symbol, strategyName) => {
|
|
16211
|
-
|
|
16312
|
+
bt.loggerService.info("LiveUtils.getData", {
|
|
16212
16313
|
symbol,
|
|
16213
16314
|
strategyName,
|
|
16214
16315
|
});
|
|
16215
|
-
return await
|
|
16316
|
+
return await bt.liveMarkdownService.getData(symbol, strategyName, false);
|
|
16216
16317
|
};
|
|
16217
16318
|
/**
|
|
16218
16319
|
* Generates markdown report with all events for a symbol-strategy pair.
|
|
@@ -16230,11 +16331,11 @@ class LiveInstance {
|
|
|
16230
16331
|
* ```
|
|
16231
16332
|
*/
|
|
16232
16333
|
this.getReport = async (symbol, strategyName, columns) => {
|
|
16233
|
-
|
|
16334
|
+
bt.loggerService.info(LIVE_METHOD_NAME_GET_REPORT, {
|
|
16234
16335
|
symbol,
|
|
16235
16336
|
strategyName,
|
|
16236
16337
|
});
|
|
16237
|
-
return await
|
|
16338
|
+
return await bt.liveMarkdownService.getReport(symbol, strategyName, false, columns);
|
|
16238
16339
|
};
|
|
16239
16340
|
/**
|
|
16240
16341
|
* Saves strategy report to disk.
|
|
@@ -16255,12 +16356,12 @@ class LiveInstance {
|
|
|
16255
16356
|
* ```
|
|
16256
16357
|
*/
|
|
16257
16358
|
this.dump = async (symbol, strategyName, path, columns) => {
|
|
16258
|
-
|
|
16359
|
+
bt.loggerService.info(LIVE_METHOD_NAME_DUMP, {
|
|
16259
16360
|
symbol,
|
|
16260
16361
|
strategyName,
|
|
16261
16362
|
path,
|
|
16262
16363
|
});
|
|
16263
|
-
await
|
|
16364
|
+
await bt.liveMarkdownService.dump(symbol, strategyName, false, path, columns);
|
|
16264
16365
|
};
|
|
16265
16366
|
}
|
|
16266
16367
|
}
|
|
@@ -16312,13 +16413,13 @@ class LiveUtils {
|
|
|
16312
16413
|
*/
|
|
16313
16414
|
this.run = (symbol, context) => {
|
|
16314
16415
|
{
|
|
16315
|
-
|
|
16316
|
-
|
|
16416
|
+
bt.strategyValidationService.validate(context.strategyName, LIVE_METHOD_NAME_RUN);
|
|
16417
|
+
bt.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_RUN);
|
|
16317
16418
|
}
|
|
16318
16419
|
{
|
|
16319
|
-
const { riskName, riskList } =
|
|
16320
|
-
riskName &&
|
|
16321
|
-
riskList && riskList.forEach((riskName) =>
|
|
16420
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
16421
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_RUN);
|
|
16422
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_RUN));
|
|
16322
16423
|
}
|
|
16323
16424
|
const instance = this._getInstance(symbol, context.strategyName);
|
|
16324
16425
|
return instance.run(symbol, context);
|
|
@@ -16345,12 +16446,12 @@ class LiveUtils {
|
|
|
16345
16446
|
* ```
|
|
16346
16447
|
*/
|
|
16347
16448
|
this.background = (symbol, context) => {
|
|
16348
|
-
|
|
16349
|
-
|
|
16449
|
+
bt.strategyValidationService.validate(context.strategyName, LIVE_METHOD_NAME_BACKGROUND);
|
|
16450
|
+
bt.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_BACKGROUND);
|
|
16350
16451
|
{
|
|
16351
|
-
const { riskName, riskList } =
|
|
16352
|
-
riskName &&
|
|
16353
|
-
riskList && riskList.forEach((riskName) =>
|
|
16452
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
16453
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_BACKGROUND);
|
|
16454
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_BACKGROUND));
|
|
16354
16455
|
}
|
|
16355
16456
|
const instance = this._getInstance(symbol, context.strategyName);
|
|
16356
16457
|
return instance.background(symbol, context);
|
|
@@ -16373,11 +16474,11 @@ class LiveUtils {
|
|
|
16373
16474
|
* ```
|
|
16374
16475
|
*/
|
|
16375
16476
|
this.stop = async (symbol, strategyName) => {
|
|
16376
|
-
|
|
16477
|
+
bt.strategyValidationService.validate(strategyName, LIVE_METHOD_NAME_STOP);
|
|
16377
16478
|
{
|
|
16378
|
-
const { riskName, riskList } =
|
|
16379
|
-
riskName &&
|
|
16380
|
-
riskList && riskList.forEach((riskName) =>
|
|
16479
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16480
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_STOP);
|
|
16481
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_STOP));
|
|
16381
16482
|
}
|
|
16382
16483
|
const instance = this._getInstance(symbol, strategyName);
|
|
16383
16484
|
return await instance.stop(symbol, strategyName);
|
|
@@ -16396,11 +16497,11 @@ class LiveUtils {
|
|
|
16396
16497
|
* ```
|
|
16397
16498
|
*/
|
|
16398
16499
|
this.getData = async (symbol, strategyName) => {
|
|
16399
|
-
|
|
16500
|
+
bt.strategyValidationService.validate(strategyName, "LiveUtils.getData");
|
|
16400
16501
|
{
|
|
16401
|
-
const { riskName, riskList } =
|
|
16402
|
-
riskName &&
|
|
16403
|
-
riskList && riskList.forEach((riskName) =>
|
|
16502
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16503
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_DATA);
|
|
16504
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_DATA));
|
|
16404
16505
|
}
|
|
16405
16506
|
const instance = this._getInstance(symbol, strategyName);
|
|
16406
16507
|
return await instance.getData(symbol, strategyName);
|
|
@@ -16420,11 +16521,11 @@ class LiveUtils {
|
|
|
16420
16521
|
* ```
|
|
16421
16522
|
*/
|
|
16422
16523
|
this.getReport = async (symbol, strategyName, columns) => {
|
|
16423
|
-
|
|
16524
|
+
bt.strategyValidationService.validate(strategyName, LIVE_METHOD_NAME_GET_REPORT);
|
|
16424
16525
|
{
|
|
16425
|
-
const { riskName, riskList } =
|
|
16426
|
-
riskName &&
|
|
16427
|
-
riskList && riskList.forEach((riskName) =>
|
|
16526
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16527
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_REPORT);
|
|
16528
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_REPORT));
|
|
16428
16529
|
}
|
|
16429
16530
|
const instance = this._getInstance(symbol, strategyName);
|
|
16430
16531
|
return await instance.getReport(symbol, strategyName, columns);
|
|
@@ -16447,11 +16548,11 @@ class LiveUtils {
|
|
|
16447
16548
|
* ```
|
|
16448
16549
|
*/
|
|
16449
16550
|
this.dump = async (symbol, strategyName, path, columns) => {
|
|
16450
|
-
|
|
16551
|
+
bt.strategyValidationService.validate(strategyName, LIVE_METHOD_NAME_DUMP);
|
|
16451
16552
|
{
|
|
16452
|
-
const { riskName, riskList } =
|
|
16453
|
-
riskName &&
|
|
16454
|
-
riskList && riskList.forEach((riskName) =>
|
|
16553
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16554
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_DUMP);
|
|
16555
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_DUMP));
|
|
16455
16556
|
}
|
|
16456
16557
|
const instance = this._getInstance(symbol, strategyName);
|
|
16457
16558
|
return await instance.dump(symbol, strategyName, path, columns);
|
|
@@ -16535,18 +16636,19 @@ class ScheduleUtils {
|
|
|
16535
16636
|
* console.log(stats.cancellationRate, stats.avgWaitTime);
|
|
16536
16637
|
* ```
|
|
16537
16638
|
*/
|
|
16538
|
-
this.getData = async (symbol, strategyName) => {
|
|
16539
|
-
|
|
16639
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
16640
|
+
bt.loggerService.info(SCHEDULE_METHOD_NAME_GET_DATA, {
|
|
16540
16641
|
symbol,
|
|
16541
16642
|
strategyName,
|
|
16643
|
+
backtest,
|
|
16542
16644
|
});
|
|
16543
|
-
|
|
16645
|
+
bt.strategyValidationService.validate(strategyName, SCHEDULE_METHOD_NAME_GET_DATA);
|
|
16544
16646
|
{
|
|
16545
|
-
const { riskName, riskList } =
|
|
16546
|
-
riskName &&
|
|
16547
|
-
riskList && riskList.forEach((riskName) =>
|
|
16647
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16648
|
+
riskName && bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_DATA);
|
|
16649
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_DATA));
|
|
16548
16650
|
}
|
|
16549
|
-
return await
|
|
16651
|
+
return await bt.scheduleMarkdownService.getData(symbol, strategyName, backtest);
|
|
16550
16652
|
};
|
|
16551
16653
|
/**
|
|
16552
16654
|
* Generates markdown report with all scheduled events for a symbol-strategy pair.
|
|
@@ -16562,18 +16664,19 @@ class ScheduleUtils {
|
|
|
16562
16664
|
* console.log(markdown);
|
|
16563
16665
|
* ```
|
|
16564
16666
|
*/
|
|
16565
|
-
this.getReport = async (symbol, strategyName, columns) => {
|
|
16566
|
-
|
|
16667
|
+
this.getReport = async (symbol, strategyName, backtest, columns) => {
|
|
16668
|
+
bt.loggerService.info(SCHEDULE_METHOD_NAME_GET_REPORT, {
|
|
16567
16669
|
symbol,
|
|
16568
16670
|
strategyName,
|
|
16671
|
+
backtest,
|
|
16569
16672
|
});
|
|
16570
|
-
|
|
16673
|
+
bt.strategyValidationService.validate(strategyName, SCHEDULE_METHOD_NAME_GET_REPORT);
|
|
16571
16674
|
{
|
|
16572
|
-
const { riskName, riskList } =
|
|
16573
|
-
riskName &&
|
|
16574
|
-
riskList && riskList.forEach((riskName) =>
|
|
16675
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16676
|
+
riskName && bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_REPORT);
|
|
16677
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_REPORT));
|
|
16575
16678
|
}
|
|
16576
|
-
return await
|
|
16679
|
+
return await bt.scheduleMarkdownService.getReport(symbol, strategyName, backtest, columns);
|
|
16577
16680
|
};
|
|
16578
16681
|
/**
|
|
16579
16682
|
* Saves strategy report to disk.
|
|
@@ -16592,19 +16695,20 @@ class ScheduleUtils {
|
|
|
16592
16695
|
* await Schedule.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
16593
16696
|
* ```
|
|
16594
16697
|
*/
|
|
16595
|
-
this.dump = async (symbol, strategyName, path, columns) => {
|
|
16596
|
-
|
|
16698
|
+
this.dump = async (symbol, strategyName, backtest, path, columns) => {
|
|
16699
|
+
bt.loggerService.info(SCHEDULE_METHOD_NAME_DUMP, {
|
|
16597
16700
|
symbol,
|
|
16598
16701
|
strategyName,
|
|
16702
|
+
backtest,
|
|
16599
16703
|
path,
|
|
16600
16704
|
});
|
|
16601
|
-
|
|
16705
|
+
bt.strategyValidationService.validate(strategyName, SCHEDULE_METHOD_NAME_DUMP);
|
|
16602
16706
|
{
|
|
16603
|
-
const { riskName, riskList } =
|
|
16604
|
-
riskName &&
|
|
16605
|
-
riskList && riskList.forEach((riskName) =>
|
|
16707
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16708
|
+
riskName && bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_DUMP);
|
|
16709
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_DUMP));
|
|
16606
16710
|
}
|
|
16607
|
-
await
|
|
16711
|
+
await bt.scheduleMarkdownService.dump(symbol, strategyName, backtest, path, columns);
|
|
16608
16712
|
};
|
|
16609
16713
|
}
|
|
16610
16714
|
}
|
|
@@ -16642,7 +16746,7 @@ const PERFORMANCE_METHOD_NAME_DUMP = "Performance.dump";
|
|
|
16642
16746
|
* console.log(`${event.metricType}: ${event.duration.toFixed(2)}ms`);
|
|
16643
16747
|
* });
|
|
16644
16748
|
*
|
|
16645
|
-
* // Run
|
|
16749
|
+
* // Run bt...
|
|
16646
16750
|
*
|
|
16647
16751
|
* // Get aggregated statistics
|
|
16648
16752
|
* const stats = await Performance.getData("my-strategy");
|
|
@@ -16685,14 +16789,14 @@ class Performance {
|
|
|
16685
16789
|
* }
|
|
16686
16790
|
* ```
|
|
16687
16791
|
*/
|
|
16688
|
-
static async getData(symbol, strategyName) {
|
|
16689
|
-
|
|
16792
|
+
static async getData(symbol, strategyName, backtest) {
|
|
16793
|
+
bt.strategyValidationService.validate(strategyName, PERFORMANCE_METHOD_NAME_GET_DATA);
|
|
16690
16794
|
{
|
|
16691
|
-
const { riskName, riskList } =
|
|
16692
|
-
riskName &&
|
|
16693
|
-
riskList && riskList.forEach((riskName) =>
|
|
16795
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16796
|
+
riskName && bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_DATA);
|
|
16797
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_DATA));
|
|
16694
16798
|
}
|
|
16695
|
-
return
|
|
16799
|
+
return bt.performanceMarkdownService.getData(symbol, strategyName, backtest);
|
|
16696
16800
|
}
|
|
16697
16801
|
/**
|
|
16698
16802
|
* Generates markdown report with performance analysis.
|
|
@@ -16717,14 +16821,14 @@ class Performance {
|
|
|
16717
16821
|
* await fs.writeFile("performance-report.md", markdown);
|
|
16718
16822
|
* ```
|
|
16719
16823
|
*/
|
|
16720
|
-
static async getReport(symbol, strategyName, columns) {
|
|
16721
|
-
|
|
16824
|
+
static async getReport(symbol, strategyName, backtest, columns) {
|
|
16825
|
+
bt.strategyValidationService.validate(strategyName, PERFORMANCE_METHOD_NAME_GET_REPORT);
|
|
16722
16826
|
{
|
|
16723
|
-
const { riskName, riskList } =
|
|
16724
|
-
riskName &&
|
|
16725
|
-
riskList && riskList.forEach((riskName) =>
|
|
16827
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16828
|
+
riskName && bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_REPORT);
|
|
16829
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_REPORT));
|
|
16726
16830
|
}
|
|
16727
|
-
return
|
|
16831
|
+
return bt.performanceMarkdownService.getReport(symbol, strategyName, backtest, columns);
|
|
16728
16832
|
}
|
|
16729
16833
|
/**
|
|
16730
16834
|
* Saves performance report to disk.
|
|
@@ -16746,14 +16850,14 @@ class Performance {
|
|
|
16746
16850
|
* await Performance.dump("BTCUSDT", "my-strategy", "./reports/perf");
|
|
16747
16851
|
* ```
|
|
16748
16852
|
*/
|
|
16749
|
-
static async dump(symbol, strategyName, path = "./dump/performance", columns) {
|
|
16750
|
-
|
|
16853
|
+
static async dump(symbol, strategyName, backtest, path = "./dump/performance", columns) {
|
|
16854
|
+
bt.strategyValidationService.validate(strategyName, PERFORMANCE_METHOD_NAME_DUMP);
|
|
16751
16855
|
{
|
|
16752
|
-
const { riskName, riskList } =
|
|
16753
|
-
riskName &&
|
|
16754
|
-
riskList && riskList.forEach((riskName) =>
|
|
16856
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16857
|
+
riskName && bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_DUMP);
|
|
16858
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_DUMP));
|
|
16755
16859
|
}
|
|
16756
|
-
return
|
|
16860
|
+
return bt.performanceMarkdownService.dump(symbol, strategyName, backtest, path, columns);
|
|
16757
16861
|
}
|
|
16758
16862
|
}
|
|
16759
16863
|
|
|
@@ -16787,7 +16891,7 @@ const INSTANCE_TASK_FN = async (symbol, context, self) => {
|
|
|
16787
16891
|
}
|
|
16788
16892
|
}
|
|
16789
16893
|
if (!self._isDone) {
|
|
16790
|
-
const walkerSchema =
|
|
16894
|
+
const walkerSchema = bt.walkerSchemaService.get(context.walkerName);
|
|
16791
16895
|
await doneWalkerSubject.next({
|
|
16792
16896
|
exchangeName: walkerSchema.exchangeName,
|
|
16793
16897
|
strategyName: context.walkerName,
|
|
@@ -16841,7 +16945,7 @@ class WalkerInstance {
|
|
|
16841
16945
|
* @internal
|
|
16842
16946
|
*/
|
|
16843
16947
|
this.task = functoolsKit.singlerun(async (symbol, context) => {
|
|
16844
|
-
|
|
16948
|
+
bt.loggerService.info(WALKER_METHOD_NAME_TASK, {
|
|
16845
16949
|
symbol,
|
|
16846
16950
|
context,
|
|
16847
16951
|
});
|
|
@@ -16860,7 +16964,7 @@ class WalkerInstance {
|
|
|
16860
16964
|
* ```
|
|
16861
16965
|
*/
|
|
16862
16966
|
this.getStatus = async () => {
|
|
16863
|
-
|
|
16967
|
+
bt.loggerService.info(WALKER_METHOD_NAME_GET_STATUS);
|
|
16864
16968
|
return {
|
|
16865
16969
|
id: this.id,
|
|
16866
16970
|
symbol: this.symbol,
|
|
@@ -16876,35 +16980,39 @@ class WalkerInstance {
|
|
|
16876
16980
|
* @returns Async generator yielding progress updates after each strategy
|
|
16877
16981
|
*/
|
|
16878
16982
|
this.run = (symbol, context) => {
|
|
16879
|
-
|
|
16983
|
+
bt.loggerService.info(WALKER_METHOD_NAME_RUN, {
|
|
16880
16984
|
symbol,
|
|
16881
16985
|
context,
|
|
16882
16986
|
});
|
|
16883
|
-
|
|
16884
|
-
const walkerSchema =
|
|
16885
|
-
|
|
16886
|
-
|
|
16987
|
+
bt.walkerValidationService.validate(context.walkerName, WALKER_METHOD_NAME_RUN);
|
|
16988
|
+
const walkerSchema = bt.walkerSchemaService.get(context.walkerName);
|
|
16989
|
+
bt.exchangeValidationService.validate(walkerSchema.exchangeName, WALKER_METHOD_NAME_RUN);
|
|
16990
|
+
bt.frameValidationService.validate(walkerSchema.frameName, WALKER_METHOD_NAME_RUN);
|
|
16887
16991
|
for (const strategyName of walkerSchema.strategies) {
|
|
16888
|
-
|
|
16992
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_RUN);
|
|
16889
16993
|
}
|
|
16890
|
-
|
|
16994
|
+
bt.walkerMarkdownService.clear(context.walkerName);
|
|
16891
16995
|
// Clear backtest data for all strategies
|
|
16892
16996
|
for (const strategyName of walkerSchema.strategies) {
|
|
16893
16997
|
{
|
|
16894
|
-
|
|
16895
|
-
|
|
16998
|
+
bt.backtestMarkdownService.clear(true, { symbol, strategyName });
|
|
16999
|
+
bt.liveMarkdownService.clear(true, { symbol, strategyName });
|
|
17000
|
+
bt.scheduleMarkdownService.clear(true, { symbol, strategyName });
|
|
17001
|
+
bt.performanceMarkdownService.clear(true, { symbol, strategyName });
|
|
17002
|
+
bt.partialMarkdownService.clear(true, { symbol, strategyName });
|
|
17003
|
+
bt.riskMarkdownService.clear(true, { symbol, strategyName });
|
|
16896
17004
|
}
|
|
16897
17005
|
{
|
|
16898
|
-
|
|
17006
|
+
bt.strategyCoreService.clear(true, { symbol, strategyName });
|
|
16899
17007
|
}
|
|
16900
17008
|
{
|
|
16901
|
-
const { riskName, riskList } =
|
|
16902
|
-
riskName &&
|
|
17009
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17010
|
+
riskName && bt.riskGlobalService.clear(true, riskName);
|
|
16903
17011
|
riskList &&
|
|
16904
|
-
riskList.forEach((riskName) =>
|
|
17012
|
+
riskList.forEach((riskName) => bt.riskGlobalService.clear(true, riskName));
|
|
16905
17013
|
}
|
|
16906
17014
|
}
|
|
16907
|
-
return
|
|
17015
|
+
return bt.walkerCommandService.run(symbol, {
|
|
16908
17016
|
walkerName: context.walkerName,
|
|
16909
17017
|
exchangeName: walkerSchema.exchangeName,
|
|
16910
17018
|
frameName: walkerSchema.frameName,
|
|
@@ -16929,15 +17037,24 @@ class WalkerInstance {
|
|
|
16929
17037
|
* ```
|
|
16930
17038
|
*/
|
|
16931
17039
|
this.background = (symbol, context) => {
|
|
16932
|
-
|
|
17040
|
+
bt.loggerService.info(WALKER_METHOD_NAME_BACKGROUND, {
|
|
16933
17041
|
symbol,
|
|
16934
17042
|
context,
|
|
16935
17043
|
});
|
|
16936
|
-
const walkerSchema =
|
|
17044
|
+
const walkerSchema = bt.walkerSchemaService.get(context.walkerName);
|
|
17045
|
+
{
|
|
17046
|
+
const currentStatus = this.task.getStatus();
|
|
17047
|
+
if (currentStatus === "pending") {
|
|
17048
|
+
throw new Error(`Walker.background is already running for symbol=${symbol} walkerName=${context.walkerName}`);
|
|
17049
|
+
}
|
|
17050
|
+
if (currentStatus === "rejected") {
|
|
17051
|
+
throw new Error(`Walker.background has failed for symbol=${symbol} walkerName=${context.walkerName}`);
|
|
17052
|
+
}
|
|
17053
|
+
}
|
|
16937
17054
|
this.task(symbol, context).catch((error) => exitEmitter.next(new Error(functoolsKit.getErrorMessage(error))));
|
|
16938
17055
|
return () => {
|
|
16939
17056
|
for (const strategyName of walkerSchema.strategies) {
|
|
16940
|
-
|
|
17057
|
+
bt.strategyCoreService.stop(true, { symbol, strategyName });
|
|
16941
17058
|
walkerStopSubject.next({
|
|
16942
17059
|
symbol,
|
|
16943
17060
|
strategyName,
|
|
@@ -16980,14 +17097,14 @@ class WalkerInstance {
|
|
|
16980
17097
|
* ```
|
|
16981
17098
|
*/
|
|
16982
17099
|
this.stop = async (symbol, walkerName) => {
|
|
16983
|
-
|
|
17100
|
+
bt.loggerService.info(WALKER_METHOD_NAME_STOP, {
|
|
16984
17101
|
symbol,
|
|
16985
17102
|
walkerName,
|
|
16986
17103
|
});
|
|
16987
|
-
const walkerSchema =
|
|
17104
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
16988
17105
|
for (const strategyName of walkerSchema.strategies) {
|
|
16989
17106
|
await walkerStopSubject.next({ symbol, strategyName, walkerName });
|
|
16990
|
-
await
|
|
17107
|
+
await bt.strategyCoreService.stop(true, { symbol, strategyName });
|
|
16991
17108
|
}
|
|
16992
17109
|
};
|
|
16993
17110
|
/**
|
|
@@ -17005,12 +17122,12 @@ class WalkerInstance {
|
|
|
17005
17122
|
* ```
|
|
17006
17123
|
*/
|
|
17007
17124
|
this.getData = async (symbol, walkerName) => {
|
|
17008
|
-
|
|
17125
|
+
bt.loggerService.info(WALKER_METHOD_NAME_GET_DATA, {
|
|
17009
17126
|
symbol,
|
|
17010
17127
|
walkerName,
|
|
17011
17128
|
});
|
|
17012
|
-
const walkerSchema =
|
|
17013
|
-
return await
|
|
17129
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17130
|
+
return await bt.walkerMarkdownService.getData(walkerName, symbol, walkerSchema.metric || "sharpeRatio", {
|
|
17014
17131
|
exchangeName: walkerSchema.exchangeName,
|
|
17015
17132
|
frameName: walkerSchema.frameName,
|
|
17016
17133
|
});
|
|
@@ -17032,12 +17149,12 @@ class WalkerInstance {
|
|
|
17032
17149
|
* ```
|
|
17033
17150
|
*/
|
|
17034
17151
|
this.getReport = async (symbol, walkerName, strategyColumns, pnlColumns) => {
|
|
17035
|
-
|
|
17152
|
+
bt.loggerService.info(WALKER_METHOD_NAME_GET_REPORT, {
|
|
17036
17153
|
symbol,
|
|
17037
17154
|
walkerName,
|
|
17038
17155
|
});
|
|
17039
|
-
const walkerSchema =
|
|
17040
|
-
return await
|
|
17156
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17157
|
+
return await bt.walkerMarkdownService.getReport(walkerName, symbol, walkerSchema.metric || "sharpeRatio", {
|
|
17041
17158
|
exchangeName: walkerSchema.exchangeName,
|
|
17042
17159
|
frameName: walkerSchema.frameName,
|
|
17043
17160
|
}, strategyColumns, pnlColumns);
|
|
@@ -17062,13 +17179,13 @@ class WalkerInstance {
|
|
|
17062
17179
|
* ```
|
|
17063
17180
|
*/
|
|
17064
17181
|
this.dump = async (symbol, walkerName, path, strategyColumns, pnlColumns) => {
|
|
17065
|
-
|
|
17182
|
+
bt.loggerService.info(WALKER_METHOD_NAME_DUMP, {
|
|
17066
17183
|
symbol,
|
|
17067
17184
|
walkerName,
|
|
17068
17185
|
path,
|
|
17069
17186
|
});
|
|
17070
|
-
const walkerSchema =
|
|
17071
|
-
await
|
|
17187
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17188
|
+
await bt.walkerMarkdownService.dump(walkerName, symbol, walkerSchema.metric || "sharpeRatio", {
|
|
17072
17189
|
exchangeName: walkerSchema.exchangeName,
|
|
17073
17190
|
frameName: walkerSchema.frameName,
|
|
17074
17191
|
}, path, strategyColumns, pnlColumns);
|
|
@@ -17109,17 +17226,17 @@ class WalkerUtils {
|
|
|
17109
17226
|
* @returns Async generator yielding progress updates after each strategy
|
|
17110
17227
|
*/
|
|
17111
17228
|
this.run = (symbol, context) => {
|
|
17112
|
-
|
|
17113
|
-
const walkerSchema =
|
|
17114
|
-
|
|
17115
|
-
|
|
17229
|
+
bt.walkerValidationService.validate(context.walkerName, WALKER_METHOD_NAME_RUN);
|
|
17230
|
+
const walkerSchema = bt.walkerSchemaService.get(context.walkerName);
|
|
17231
|
+
bt.exchangeValidationService.validate(walkerSchema.exchangeName, WALKER_METHOD_NAME_RUN);
|
|
17232
|
+
bt.frameValidationService.validate(walkerSchema.frameName, WALKER_METHOD_NAME_RUN);
|
|
17116
17233
|
for (const strategyName of walkerSchema.strategies) {
|
|
17117
|
-
|
|
17118
|
-
const { riskName, riskList } =
|
|
17234
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_RUN);
|
|
17235
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17119
17236
|
riskName &&
|
|
17120
|
-
|
|
17237
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_RUN);
|
|
17121
17238
|
riskList &&
|
|
17122
|
-
riskList.forEach((riskName) =>
|
|
17239
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_RUN));
|
|
17123
17240
|
}
|
|
17124
17241
|
const instance = this._getInstance(symbol, context.walkerName);
|
|
17125
17242
|
return instance.run(symbol, context);
|
|
@@ -17144,17 +17261,17 @@ class WalkerUtils {
|
|
|
17144
17261
|
* ```
|
|
17145
17262
|
*/
|
|
17146
17263
|
this.background = (symbol, context) => {
|
|
17147
|
-
|
|
17148
|
-
const walkerSchema =
|
|
17149
|
-
|
|
17150
|
-
|
|
17264
|
+
bt.walkerValidationService.validate(context.walkerName, WALKER_METHOD_NAME_BACKGROUND);
|
|
17265
|
+
const walkerSchema = bt.walkerSchemaService.get(context.walkerName);
|
|
17266
|
+
bt.exchangeValidationService.validate(walkerSchema.exchangeName, WALKER_METHOD_NAME_BACKGROUND);
|
|
17267
|
+
bt.frameValidationService.validate(walkerSchema.frameName, WALKER_METHOD_NAME_BACKGROUND);
|
|
17151
17268
|
for (const strategyName of walkerSchema.strategies) {
|
|
17152
|
-
|
|
17153
|
-
const { riskName, riskList } =
|
|
17269
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_BACKGROUND);
|
|
17270
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17154
17271
|
riskName &&
|
|
17155
|
-
|
|
17272
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_BACKGROUND);
|
|
17156
17273
|
riskList &&
|
|
17157
|
-
riskList.forEach((riskName) =>
|
|
17274
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_BACKGROUND));
|
|
17158
17275
|
}
|
|
17159
17276
|
const instance = this._getInstance(symbol, context.walkerName);
|
|
17160
17277
|
return instance.background(symbol, context);
|
|
@@ -17183,15 +17300,15 @@ class WalkerUtils {
|
|
|
17183
17300
|
* ```
|
|
17184
17301
|
*/
|
|
17185
17302
|
this.stop = async (symbol, walkerName) => {
|
|
17186
|
-
|
|
17187
|
-
const walkerSchema =
|
|
17303
|
+
bt.walkerValidationService.validate(walkerName, WALKER_METHOD_NAME_STOP);
|
|
17304
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17188
17305
|
for (const strategyName of walkerSchema.strategies) {
|
|
17189
|
-
|
|
17190
|
-
const { riskName, riskList } =
|
|
17306
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_STOP);
|
|
17307
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17191
17308
|
riskName &&
|
|
17192
|
-
|
|
17309
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_STOP);
|
|
17193
17310
|
riskList &&
|
|
17194
|
-
riskList.forEach((riskName) =>
|
|
17311
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_STOP));
|
|
17195
17312
|
}
|
|
17196
17313
|
const instance = this._getInstance(symbol, walkerName);
|
|
17197
17314
|
return await instance.stop(symbol, walkerName);
|
|
@@ -17210,15 +17327,15 @@ class WalkerUtils {
|
|
|
17210
17327
|
* ```
|
|
17211
17328
|
*/
|
|
17212
17329
|
this.getData = async (symbol, walkerName) => {
|
|
17213
|
-
|
|
17214
|
-
const walkerSchema =
|
|
17330
|
+
bt.walkerValidationService.validate(walkerName, WALKER_METHOD_NAME_GET_DATA);
|
|
17331
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17215
17332
|
for (const strategyName of walkerSchema.strategies) {
|
|
17216
|
-
|
|
17217
|
-
const { riskName, riskList } =
|
|
17333
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_GET_DATA);
|
|
17334
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17218
17335
|
riskName &&
|
|
17219
|
-
|
|
17336
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_DATA);
|
|
17220
17337
|
riskList &&
|
|
17221
|
-
riskList.forEach((riskName) =>
|
|
17338
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_DATA));
|
|
17222
17339
|
}
|
|
17223
17340
|
const instance = this._getInstance(symbol, walkerName);
|
|
17224
17341
|
return await instance.getData(symbol, walkerName);
|
|
@@ -17239,15 +17356,15 @@ class WalkerUtils {
|
|
|
17239
17356
|
* ```
|
|
17240
17357
|
*/
|
|
17241
17358
|
this.getReport = async (symbol, walkerName, strategyColumns, pnlColumns) => {
|
|
17242
|
-
|
|
17243
|
-
const walkerSchema =
|
|
17359
|
+
bt.walkerValidationService.validate(walkerName, WALKER_METHOD_NAME_GET_REPORT);
|
|
17360
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17244
17361
|
for (const strategyName of walkerSchema.strategies) {
|
|
17245
|
-
|
|
17246
|
-
const { riskName, riskList } =
|
|
17362
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_GET_REPORT);
|
|
17363
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17247
17364
|
riskName &&
|
|
17248
|
-
|
|
17365
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_REPORT);
|
|
17249
17366
|
riskList &&
|
|
17250
|
-
riskList.forEach((riskName) =>
|
|
17367
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_REPORT));
|
|
17251
17368
|
}
|
|
17252
17369
|
const instance = this._getInstance(symbol, walkerName);
|
|
17253
17370
|
return await instance.getReport(symbol, walkerName, strategyColumns, pnlColumns);
|
|
@@ -17271,15 +17388,15 @@ class WalkerUtils {
|
|
|
17271
17388
|
* ```
|
|
17272
17389
|
*/
|
|
17273
17390
|
this.dump = async (symbol, walkerName, path, strategyColumns, pnlColumns) => {
|
|
17274
|
-
|
|
17275
|
-
const walkerSchema =
|
|
17391
|
+
bt.walkerValidationService.validate(walkerName, WALKER_METHOD_NAME_DUMP);
|
|
17392
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17276
17393
|
for (const strategyName of walkerSchema.strategies) {
|
|
17277
|
-
|
|
17278
|
-
const { riskName, riskList } =
|
|
17394
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_DUMP);
|
|
17395
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17279
17396
|
riskName &&
|
|
17280
|
-
|
|
17397
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_DUMP);
|
|
17281
17398
|
riskList &&
|
|
17282
|
-
riskList.forEach((riskName) =>
|
|
17399
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_DUMP));
|
|
17283
17400
|
}
|
|
17284
17401
|
const instance = this._getInstance(symbol, walkerName);
|
|
17285
17402
|
return await instance.dump(symbol, walkerName, path, strategyColumns, pnlColumns);
|
|
@@ -17371,15 +17488,15 @@ class HeatUtils {
|
|
|
17371
17488
|
* });
|
|
17372
17489
|
* ```
|
|
17373
17490
|
*/
|
|
17374
|
-
this.getData = async (strategyName) => {
|
|
17375
|
-
|
|
17376
|
-
|
|
17491
|
+
this.getData = async (strategyName, backtest) => {
|
|
17492
|
+
bt.loggerService.info(HEAT_METHOD_NAME_GET_DATA, { strategyName });
|
|
17493
|
+
bt.strategyValidationService.validate(strategyName, HEAT_METHOD_NAME_GET_DATA);
|
|
17377
17494
|
{
|
|
17378
|
-
const { riskName, riskList } =
|
|
17379
|
-
riskName &&
|
|
17380
|
-
riskList && riskList.forEach((riskName) =>
|
|
17495
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17496
|
+
riskName && bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_DATA);
|
|
17497
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_DATA));
|
|
17381
17498
|
}
|
|
17382
|
-
return await
|
|
17499
|
+
return await bt.heatMarkdownService.getData(strategyName, backtest);
|
|
17383
17500
|
};
|
|
17384
17501
|
/**
|
|
17385
17502
|
* Generates markdown report with portfolio heatmap table for a strategy.
|
|
@@ -17407,15 +17524,15 @@ class HeatUtils {
|
|
|
17407
17524
|
* // ...
|
|
17408
17525
|
* ```
|
|
17409
17526
|
*/
|
|
17410
|
-
this.getReport = async (strategyName, columns) => {
|
|
17411
|
-
|
|
17412
|
-
|
|
17527
|
+
this.getReport = async (strategyName, backtest, columns) => {
|
|
17528
|
+
bt.loggerService.info(HEAT_METHOD_NAME_GET_REPORT, { strategyName });
|
|
17529
|
+
bt.strategyValidationService.validate(strategyName, HEAT_METHOD_NAME_GET_REPORT);
|
|
17413
17530
|
{
|
|
17414
|
-
const { riskName, riskList } =
|
|
17415
|
-
riskName &&
|
|
17416
|
-
riskList && riskList.forEach((riskName) =>
|
|
17531
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17532
|
+
riskName && bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_REPORT);
|
|
17533
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_REPORT));
|
|
17417
17534
|
}
|
|
17418
|
-
return await
|
|
17535
|
+
return await bt.heatMarkdownService.getReport(strategyName, backtest, columns);
|
|
17419
17536
|
};
|
|
17420
17537
|
/**
|
|
17421
17538
|
* Saves heatmap report to disk for a strategy.
|
|
@@ -17436,15 +17553,15 @@ class HeatUtils {
|
|
|
17436
17553
|
* await Heat.dump("my-strategy", "./reports");
|
|
17437
17554
|
* ```
|
|
17438
17555
|
*/
|
|
17439
|
-
this.dump = async (strategyName, path, columns) => {
|
|
17440
|
-
|
|
17441
|
-
|
|
17556
|
+
this.dump = async (strategyName, backtest, path, columns) => {
|
|
17557
|
+
bt.loggerService.info(HEAT_METHOD_NAME_DUMP, { strategyName, path });
|
|
17558
|
+
bt.strategyValidationService.validate(strategyName, HEAT_METHOD_NAME_DUMP);
|
|
17442
17559
|
{
|
|
17443
|
-
const { riskName, riskList } =
|
|
17444
|
-
riskName &&
|
|
17445
|
-
riskList && riskList.forEach((riskName) =>
|
|
17560
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17561
|
+
riskName && bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_DUMP);
|
|
17562
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_DUMP));
|
|
17446
17563
|
}
|
|
17447
|
-
await
|
|
17564
|
+
await bt.heatMarkdownService.dump(strategyName, backtest, path, columns);
|
|
17448
17565
|
};
|
|
17449
17566
|
}
|
|
17450
17567
|
}
|
|
@@ -17531,12 +17648,12 @@ class PositionSizeUtils {
|
|
|
17531
17648
|
* @throws Error if sizing schema method is not "fixed-percentage"
|
|
17532
17649
|
*/
|
|
17533
17650
|
PositionSizeUtils.fixedPercentage = async (symbol, accountBalance, priceOpen, priceStopLoss, context) => {
|
|
17534
|
-
|
|
17651
|
+
bt.loggerService.info(POSITION_SIZE_METHOD_NAME_FIXED, {
|
|
17535
17652
|
context,
|
|
17536
17653
|
symbol,
|
|
17537
17654
|
});
|
|
17538
|
-
|
|
17539
|
-
return await
|
|
17655
|
+
bt.sizingValidationService.validate(context.sizingName, POSITION_SIZE_METHOD_NAME_FIXED, "fixed-percentage");
|
|
17656
|
+
return await bt.sizingGlobalService.calculate({
|
|
17540
17657
|
symbol,
|
|
17541
17658
|
accountBalance,
|
|
17542
17659
|
priceOpen,
|
|
@@ -17557,12 +17674,12 @@ PositionSizeUtils.fixedPercentage = async (symbol, accountBalance, priceOpen, pr
|
|
|
17557
17674
|
* @throws Error if sizing schema method is not "kelly-criterion"
|
|
17558
17675
|
*/
|
|
17559
17676
|
PositionSizeUtils.kellyCriterion = async (symbol, accountBalance, priceOpen, winRate, winLossRatio, context) => {
|
|
17560
|
-
|
|
17677
|
+
bt.loggerService.info(POSITION_SIZE_METHOD_NAME_KELLY, {
|
|
17561
17678
|
context,
|
|
17562
17679
|
symbol,
|
|
17563
17680
|
});
|
|
17564
|
-
|
|
17565
|
-
return await
|
|
17681
|
+
bt.sizingValidationService.validate(context.sizingName, POSITION_SIZE_METHOD_NAME_KELLY, "kelly-criterion");
|
|
17682
|
+
return await bt.sizingGlobalService.calculate({
|
|
17566
17683
|
symbol,
|
|
17567
17684
|
accountBalance,
|
|
17568
17685
|
priceOpen,
|
|
@@ -17583,12 +17700,12 @@ PositionSizeUtils.kellyCriterion = async (symbol, accountBalance, priceOpen, win
|
|
|
17583
17700
|
* @throws Error if sizing schema method is not "atr-based"
|
|
17584
17701
|
*/
|
|
17585
17702
|
PositionSizeUtils.atrBased = async (symbol, accountBalance, priceOpen, atr, context) => {
|
|
17586
|
-
|
|
17703
|
+
bt.loggerService.info(POSITION_SIZE_METHOD_NAME_ATR, {
|
|
17587
17704
|
context,
|
|
17588
17705
|
symbol,
|
|
17589
17706
|
});
|
|
17590
|
-
|
|
17591
|
-
return await
|
|
17707
|
+
bt.sizingValidationService.validate(context.sizingName, POSITION_SIZE_METHOD_NAME_ATR, "atr-based");
|
|
17708
|
+
return await bt.sizingGlobalService.calculate({
|
|
17592
17709
|
symbol,
|
|
17593
17710
|
accountBalance,
|
|
17594
17711
|
priceOpen,
|
|
@@ -17637,12 +17754,12 @@ class OptimizerUtils {
|
|
|
17637
17754
|
* @throws Error if optimizer not found
|
|
17638
17755
|
*/
|
|
17639
17756
|
this.getData = async (symbol, context) => {
|
|
17640
|
-
|
|
17757
|
+
bt.loggerService.info(OPTIMIZER_METHOD_NAME_GET_DATA, {
|
|
17641
17758
|
symbol,
|
|
17642
17759
|
context,
|
|
17643
17760
|
});
|
|
17644
|
-
|
|
17645
|
-
return await
|
|
17761
|
+
bt.optimizerValidationService.validate(context.optimizerName, OPTIMIZER_METHOD_NAME_GET_DATA);
|
|
17762
|
+
return await bt.optimizerGlobalService.getData(symbol, context.optimizerName);
|
|
17646
17763
|
};
|
|
17647
17764
|
/**
|
|
17648
17765
|
* Generates complete executable strategy code.
|
|
@@ -17654,12 +17771,12 @@ class OptimizerUtils {
|
|
|
17654
17771
|
* @throws Error if optimizer not found
|
|
17655
17772
|
*/
|
|
17656
17773
|
this.getCode = async (symbol, context) => {
|
|
17657
|
-
|
|
17774
|
+
bt.loggerService.info(OPTIMIZER_METHOD_NAME_GET_CODE, {
|
|
17658
17775
|
symbol,
|
|
17659
17776
|
context,
|
|
17660
17777
|
});
|
|
17661
|
-
|
|
17662
|
-
return await
|
|
17778
|
+
bt.optimizerValidationService.validate(context.optimizerName, OPTIMIZER_METHOD_NAME_GET_CODE);
|
|
17779
|
+
return await bt.optimizerGlobalService.getCode(symbol, context.optimizerName);
|
|
17663
17780
|
};
|
|
17664
17781
|
/**
|
|
17665
17782
|
* Generates and saves strategy code to file.
|
|
@@ -17673,13 +17790,13 @@ class OptimizerUtils {
|
|
|
17673
17790
|
* @throws Error if optimizer not found or file write fails
|
|
17674
17791
|
*/
|
|
17675
17792
|
this.dump = async (symbol, context, path) => {
|
|
17676
|
-
|
|
17793
|
+
bt.loggerService.info(OPTIMIZER_METHOD_NAME_DUMP, {
|
|
17677
17794
|
symbol,
|
|
17678
17795
|
context,
|
|
17679
17796
|
path,
|
|
17680
17797
|
});
|
|
17681
|
-
|
|
17682
|
-
await
|
|
17798
|
+
bt.optimizerValidationService.validate(context.optimizerName, OPTIMIZER_METHOD_NAME_DUMP);
|
|
17799
|
+
await bt.optimizerGlobalService.dump(symbol, context.optimizerName, path);
|
|
17683
17800
|
};
|
|
17684
17801
|
}
|
|
17685
17802
|
}
|
|
@@ -17760,15 +17877,15 @@ class PartialUtils {
|
|
|
17760
17877
|
* }
|
|
17761
17878
|
* ```
|
|
17762
17879
|
*/
|
|
17763
|
-
this.getData = async (symbol, strategyName) => {
|
|
17764
|
-
|
|
17765
|
-
|
|
17880
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
17881
|
+
bt.loggerService.info(PARTIAL_METHOD_NAME_GET_DATA, { symbol, strategyName });
|
|
17882
|
+
bt.strategyValidationService.validate(strategyName, PARTIAL_METHOD_NAME_GET_DATA);
|
|
17766
17883
|
{
|
|
17767
|
-
const { riskName, riskList } =
|
|
17768
|
-
riskName &&
|
|
17769
|
-
riskList && riskList.forEach((riskName) =>
|
|
17884
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17885
|
+
riskName && bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_DATA);
|
|
17886
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_DATA));
|
|
17770
17887
|
}
|
|
17771
|
-
return await
|
|
17888
|
+
return await bt.partialMarkdownService.getData(symbol, strategyName, backtest);
|
|
17772
17889
|
};
|
|
17773
17890
|
/**
|
|
17774
17891
|
* Generates markdown report with all partial profit/loss events for a symbol-strategy pair.
|
|
@@ -17809,15 +17926,15 @@ class PartialUtils {
|
|
|
17809
17926
|
* // **Loss events:** 1
|
|
17810
17927
|
* ```
|
|
17811
17928
|
*/
|
|
17812
|
-
this.getReport = async (symbol, strategyName, columns) => {
|
|
17813
|
-
|
|
17814
|
-
|
|
17929
|
+
this.getReport = async (symbol, strategyName, backtest, columns) => {
|
|
17930
|
+
bt.loggerService.info(PARTIAL_METHOD_NAME_GET_REPORT, { symbol, strategyName });
|
|
17931
|
+
bt.strategyValidationService.validate(strategyName, PARTIAL_METHOD_NAME_GET_REPORT);
|
|
17815
17932
|
{
|
|
17816
|
-
const { riskName, riskList } =
|
|
17817
|
-
riskName &&
|
|
17818
|
-
riskList && riskList.forEach((riskName) =>
|
|
17933
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17934
|
+
riskName && bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_REPORT);
|
|
17935
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_REPORT));
|
|
17819
17936
|
}
|
|
17820
|
-
return await
|
|
17937
|
+
return await bt.partialMarkdownService.getReport(symbol, strategyName, backtest, columns);
|
|
17821
17938
|
};
|
|
17822
17939
|
/**
|
|
17823
17940
|
* Generates and saves markdown report to file.
|
|
@@ -17851,15 +17968,15 @@ class PartialUtils {
|
|
|
17851
17968
|
* }
|
|
17852
17969
|
* ```
|
|
17853
17970
|
*/
|
|
17854
|
-
this.dump = async (symbol, strategyName, path, columns) => {
|
|
17855
|
-
|
|
17856
|
-
|
|
17971
|
+
this.dump = async (symbol, strategyName, backtest, path, columns) => {
|
|
17972
|
+
bt.loggerService.info(PARTIAL_METHOD_NAME_DUMP, { symbol, strategyName, path });
|
|
17973
|
+
bt.strategyValidationService.validate(strategyName, PARTIAL_METHOD_NAME_DUMP);
|
|
17857
17974
|
{
|
|
17858
|
-
const { riskName, riskList } =
|
|
17859
|
-
riskName &&
|
|
17860
|
-
riskList && riskList.forEach((riskName) =>
|
|
17975
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17976
|
+
riskName && bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_DUMP);
|
|
17977
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_DUMP));
|
|
17861
17978
|
}
|
|
17862
|
-
await
|
|
17979
|
+
await bt.partialMarkdownService.dump(symbol, strategyName, backtest, path, columns);
|
|
17863
17980
|
};
|
|
17864
17981
|
}
|
|
17865
17982
|
}
|