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.mjs
CHANGED
|
@@ -2041,7 +2041,7 @@ const BASE_WAIT_FOR_INIT_FN_METHOD_NAME = "PersistBase.waitForInitFn";
|
|
|
2041
2041
|
const BASE_UNLINK_RETRY_COUNT = 5;
|
|
2042
2042
|
const BASE_UNLINK_RETRY_DELAY = 1000;
|
|
2043
2043
|
const BASE_WAIT_FOR_INIT_FN = async (self) => {
|
|
2044
|
-
|
|
2044
|
+
bt.loggerService.debug(BASE_WAIT_FOR_INIT_FN_METHOD_NAME, {
|
|
2045
2045
|
entityName: self.entityName,
|
|
2046
2046
|
directory: self._directory,
|
|
2047
2047
|
});
|
|
@@ -2099,7 +2099,7 @@ const PersistBase = makeExtendable(class {
|
|
|
2099
2099
|
this.entityName = entityName;
|
|
2100
2100
|
this.baseDir = baseDir;
|
|
2101
2101
|
this[_a] = singleshot(async () => await BASE_WAIT_FOR_INIT_FN(this));
|
|
2102
|
-
|
|
2102
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_CTOR, {
|
|
2103
2103
|
entityName: this.entityName,
|
|
2104
2104
|
baseDir,
|
|
2105
2105
|
});
|
|
@@ -2115,7 +2115,7 @@ const PersistBase = makeExtendable(class {
|
|
|
2115
2115
|
return join(this.baseDir, this.entityName, `${entityId}.json`);
|
|
2116
2116
|
}
|
|
2117
2117
|
async waitForInit(initial) {
|
|
2118
|
-
|
|
2118
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_WAIT_FOR_INIT, {
|
|
2119
2119
|
entityName: this.entityName,
|
|
2120
2120
|
initial,
|
|
2121
2121
|
});
|
|
@@ -2132,7 +2132,7 @@ const PersistBase = makeExtendable(class {
|
|
|
2132
2132
|
return length;
|
|
2133
2133
|
}
|
|
2134
2134
|
async readValue(entityId) {
|
|
2135
|
-
|
|
2135
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_READ_VALUE, {
|
|
2136
2136
|
entityName: this.entityName,
|
|
2137
2137
|
entityId,
|
|
2138
2138
|
});
|
|
@@ -2149,7 +2149,7 @@ const PersistBase = makeExtendable(class {
|
|
|
2149
2149
|
}
|
|
2150
2150
|
}
|
|
2151
2151
|
async hasValue(entityId) {
|
|
2152
|
-
|
|
2152
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_HAS_VALUE, {
|
|
2153
2153
|
entityName: this.entityName,
|
|
2154
2154
|
entityId,
|
|
2155
2155
|
});
|
|
@@ -2166,7 +2166,7 @@ const PersistBase = makeExtendable(class {
|
|
|
2166
2166
|
}
|
|
2167
2167
|
}
|
|
2168
2168
|
async writeValue(entityId, entity) {
|
|
2169
|
-
|
|
2169
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_WRITE_VALUE, {
|
|
2170
2170
|
entityName: this.entityName,
|
|
2171
2171
|
entityId,
|
|
2172
2172
|
});
|
|
@@ -2187,7 +2187,7 @@ const PersistBase = makeExtendable(class {
|
|
|
2187
2187
|
* @throws Error if entity not found or deletion fails
|
|
2188
2188
|
*/
|
|
2189
2189
|
async removeValue(entityId) {
|
|
2190
|
-
|
|
2190
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_REMOVE_VALUE, {
|
|
2191
2191
|
entityName: this.entityName,
|
|
2192
2192
|
entityId,
|
|
2193
2193
|
});
|
|
@@ -2209,7 +2209,7 @@ const PersistBase = makeExtendable(class {
|
|
|
2209
2209
|
* @throws Error if deletion fails
|
|
2210
2210
|
*/
|
|
2211
2211
|
async removeAll() {
|
|
2212
|
-
|
|
2212
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_REMOVE_ALL, {
|
|
2213
2213
|
entityName: this.entityName,
|
|
2214
2214
|
});
|
|
2215
2215
|
try {
|
|
@@ -2231,7 +2231,7 @@ const PersistBase = makeExtendable(class {
|
|
|
2231
2231
|
* @throws Error if reading fails
|
|
2232
2232
|
*/
|
|
2233
2233
|
async *values() {
|
|
2234
|
-
|
|
2234
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_VALUES, {
|
|
2235
2235
|
entityName: this.entityName,
|
|
2236
2236
|
});
|
|
2237
2237
|
try {
|
|
@@ -2260,7 +2260,7 @@ const PersistBase = makeExtendable(class {
|
|
|
2260
2260
|
* @throws Error if reading fails
|
|
2261
2261
|
*/
|
|
2262
2262
|
async *keys() {
|
|
2263
|
-
|
|
2263
|
+
bt.loggerService.debug(PERSIST_BASE_METHOD_NAME_KEYS, {
|
|
2264
2264
|
entityName: this.entityName,
|
|
2265
2265
|
});
|
|
2266
2266
|
try {
|
|
@@ -2365,7 +2365,7 @@ class PersistSignalUtils {
|
|
|
2365
2365
|
* @returns Promise resolving to signal or null
|
|
2366
2366
|
*/
|
|
2367
2367
|
this.readSignalData = async (symbol, strategyName) => {
|
|
2368
|
-
|
|
2368
|
+
bt.loggerService.info(PERSIST_SIGNAL_UTILS_METHOD_NAME_READ_DATA);
|
|
2369
2369
|
const key = `${symbol}:${strategyName}`;
|
|
2370
2370
|
const isInitial = !this.getSignalStorage.has(key);
|
|
2371
2371
|
const stateStorage = this.getSignalStorage(symbol, strategyName);
|
|
@@ -2387,7 +2387,7 @@ class PersistSignalUtils {
|
|
|
2387
2387
|
* @returns Promise that resolves when write is complete
|
|
2388
2388
|
*/
|
|
2389
2389
|
this.writeSignalData = async (signalRow, symbol, strategyName) => {
|
|
2390
|
-
|
|
2390
|
+
bt.loggerService.info(PERSIST_SIGNAL_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2391
2391
|
const key = `${symbol}:${strategyName}`;
|
|
2392
2392
|
const isInitial = !this.getSignalStorage.has(key);
|
|
2393
2393
|
const stateStorage = this.getSignalStorage(symbol, strategyName);
|
|
@@ -2410,7 +2410,7 @@ class PersistSignalUtils {
|
|
|
2410
2410
|
* ```
|
|
2411
2411
|
*/
|
|
2412
2412
|
usePersistSignalAdapter(Ctor) {
|
|
2413
|
-
|
|
2413
|
+
bt.loggerService.info(PERSIST_SIGNAL_UTILS_METHOD_NAME_USE_PERSIST_SIGNAL_ADAPTER);
|
|
2414
2414
|
this.PersistSignalFactory = Ctor;
|
|
2415
2415
|
}
|
|
2416
2416
|
}
|
|
@@ -2462,7 +2462,7 @@ class PersistRiskUtils {
|
|
|
2462
2462
|
* @returns Promise resolving to Map of active positions
|
|
2463
2463
|
*/
|
|
2464
2464
|
this.readPositionData = async (riskName) => {
|
|
2465
|
-
|
|
2465
|
+
bt.loggerService.info(PERSIST_RISK_UTILS_METHOD_NAME_READ_DATA);
|
|
2466
2466
|
const isInitial = !this.getRiskStorage.has(riskName);
|
|
2467
2467
|
const stateStorage = this.getRiskStorage(riskName);
|
|
2468
2468
|
await stateStorage.waitForInit(isInitial);
|
|
@@ -2483,7 +2483,7 @@ class PersistRiskUtils {
|
|
|
2483
2483
|
* @returns Promise that resolves when write is complete
|
|
2484
2484
|
*/
|
|
2485
2485
|
this.writePositionData = async (riskRow, riskName) => {
|
|
2486
|
-
|
|
2486
|
+
bt.loggerService.info(PERSIST_RISK_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2487
2487
|
const isInitial = !this.getRiskStorage.has(riskName);
|
|
2488
2488
|
const stateStorage = this.getRiskStorage(riskName);
|
|
2489
2489
|
await stateStorage.waitForInit(isInitial);
|
|
@@ -2506,7 +2506,7 @@ class PersistRiskUtils {
|
|
|
2506
2506
|
* ```
|
|
2507
2507
|
*/
|
|
2508
2508
|
usePersistRiskAdapter(Ctor) {
|
|
2509
|
-
|
|
2509
|
+
bt.loggerService.info(PERSIST_RISK_UTILS_METHOD_NAME_USE_PERSIST_RISK_ADAPTER);
|
|
2510
2510
|
this.PersistRiskFactory = Ctor;
|
|
2511
2511
|
}
|
|
2512
2512
|
}
|
|
@@ -2556,7 +2556,7 @@ class PersistScheduleUtils {
|
|
|
2556
2556
|
* @returns Promise resolving to scheduled signal or null
|
|
2557
2557
|
*/
|
|
2558
2558
|
this.readScheduleData = async (symbol, strategyName) => {
|
|
2559
|
-
|
|
2559
|
+
bt.loggerService.info(PERSIST_SCHEDULE_UTILS_METHOD_NAME_READ_DATA);
|
|
2560
2560
|
const key = `${symbol}:${strategyName}`;
|
|
2561
2561
|
const isInitial = !this.getScheduleStorage.has(key);
|
|
2562
2562
|
const stateStorage = this.getScheduleStorage(symbol, strategyName);
|
|
@@ -2578,7 +2578,7 @@ class PersistScheduleUtils {
|
|
|
2578
2578
|
* @returns Promise that resolves when write is complete
|
|
2579
2579
|
*/
|
|
2580
2580
|
this.writeScheduleData = async (scheduledSignalRow, symbol, strategyName) => {
|
|
2581
|
-
|
|
2581
|
+
bt.loggerService.info(PERSIST_SCHEDULE_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2582
2582
|
const key = `${symbol}:${strategyName}`;
|
|
2583
2583
|
const isInitial = !this.getScheduleStorage.has(key);
|
|
2584
2584
|
const stateStorage = this.getScheduleStorage(symbol, strategyName);
|
|
@@ -2601,7 +2601,7 @@ class PersistScheduleUtils {
|
|
|
2601
2601
|
* ```
|
|
2602
2602
|
*/
|
|
2603
2603
|
usePersistScheduleAdapter(Ctor) {
|
|
2604
|
-
|
|
2604
|
+
bt.loggerService.info(PERSIST_SCHEDULE_UTILS_METHOD_NAME_USE_PERSIST_SCHEDULE_ADAPTER);
|
|
2605
2605
|
this.PersistScheduleFactory = Ctor;
|
|
2606
2606
|
}
|
|
2607
2607
|
}
|
|
@@ -2651,7 +2651,7 @@ class PersistPartialUtils {
|
|
|
2651
2651
|
* @returns Promise resolving to partial data record
|
|
2652
2652
|
*/
|
|
2653
2653
|
this.readPartialData = async (symbol, strategyName) => {
|
|
2654
|
-
|
|
2654
|
+
bt.loggerService.info(PERSIST_PARTIAL_UTILS_METHOD_NAME_READ_DATA);
|
|
2655
2655
|
const key = `${symbol}:${strategyName}`;
|
|
2656
2656
|
const isInitial = !this.getPartialStorage.has(key);
|
|
2657
2657
|
const stateStorage = this.getPartialStorage(symbol, strategyName);
|
|
@@ -2674,7 +2674,7 @@ class PersistPartialUtils {
|
|
|
2674
2674
|
* @returns Promise that resolves when write is complete
|
|
2675
2675
|
*/
|
|
2676
2676
|
this.writePartialData = async (partialData, symbol, strategyName) => {
|
|
2677
|
-
|
|
2677
|
+
bt.loggerService.info(PERSIST_PARTIAL_UTILS_METHOD_NAME_WRITE_DATA);
|
|
2678
2678
|
const key = `${symbol}:${strategyName}`;
|
|
2679
2679
|
const isInitial = !this.getPartialStorage.has(key);
|
|
2680
2680
|
const stateStorage = this.getPartialStorage(symbol, strategyName);
|
|
@@ -2698,7 +2698,7 @@ class PersistPartialUtils {
|
|
|
2698
2698
|
* ```
|
|
2699
2699
|
*/
|
|
2700
2700
|
usePersistPartialAdapter(Ctor) {
|
|
2701
|
-
|
|
2701
|
+
bt.loggerService.info(PERSIST_PARTIAL_UTILS_METHOD_NAME_USE_PERSIST_PARTIAL_ADAPTER);
|
|
2702
2702
|
this.PersistPartialFactory = Ctor;
|
|
2703
2703
|
}
|
|
2704
2704
|
}
|
|
@@ -3167,7 +3167,7 @@ const GET_SIGNAL_FN = trycatch(async (self) => {
|
|
|
3167
3167
|
error: errorData(error),
|
|
3168
3168
|
message: getErrorMessage(error),
|
|
3169
3169
|
};
|
|
3170
|
-
|
|
3170
|
+
bt.loggerService.warn(message, payload);
|
|
3171
3171
|
console.warn(message, payload);
|
|
3172
3172
|
errorEmitter.next(error);
|
|
3173
3173
|
},
|
|
@@ -3246,6 +3246,7 @@ const CHECK_SCHEDULED_SIGNAL_TIMEOUT_FN = async (self, scheduled, currentPrice)
|
|
|
3246
3246
|
strategyName: self.params.method.context.strategyName,
|
|
3247
3247
|
exchangeName: self.params.method.context.exchangeName,
|
|
3248
3248
|
symbol: self.params.execution.context.symbol,
|
|
3249
|
+
backtest: self.params.execution.context.backtest,
|
|
3249
3250
|
};
|
|
3250
3251
|
if (self.params.callbacks?.onTick) {
|
|
3251
3252
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3297,6 +3298,7 @@ const CANCEL_SCHEDULED_SIGNAL_BY_STOPLOSS_FN = async (self, scheduled, currentPr
|
|
|
3297
3298
|
exchangeName: self.params.method.context.exchangeName,
|
|
3298
3299
|
symbol: self.params.execution.context.symbol,
|
|
3299
3300
|
currentPrice: currentPrice,
|
|
3301
|
+
backtest: self.params.execution.context.backtest,
|
|
3300
3302
|
};
|
|
3301
3303
|
if (self.params.callbacks?.onTick) {
|
|
3302
3304
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3364,6 +3366,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_FN = async (self, scheduled, activationTimestamp
|
|
|
3364
3366
|
exchangeName: self.params.method.context.exchangeName,
|
|
3365
3367
|
symbol: self.params.execution.context.symbol,
|
|
3366
3368
|
currentPrice: self._pendingSignal.priceOpen,
|
|
3369
|
+
backtest: self.params.execution.context.backtest,
|
|
3367
3370
|
};
|
|
3368
3371
|
if (self.params.callbacks?.onTick) {
|
|
3369
3372
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3380,6 +3383,7 @@ const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice)
|
|
|
3380
3383
|
symbol: self.params.execution.context.symbol,
|
|
3381
3384
|
percentTp: 0,
|
|
3382
3385
|
percentSl: 0,
|
|
3386
|
+
backtest: self.params.execution.context.backtest,
|
|
3383
3387
|
};
|
|
3384
3388
|
if (self.params.callbacks?.onTick) {
|
|
3385
3389
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3405,6 +3409,7 @@ const OPEN_NEW_SCHEDULED_SIGNAL_FN = async (self, signal) => {
|
|
|
3405
3409
|
exchangeName: self.params.method.context.exchangeName,
|
|
3406
3410
|
symbol: self.params.execution.context.symbol,
|
|
3407
3411
|
currentPrice: currentPrice,
|
|
3412
|
+
backtest: self.params.execution.context.backtest,
|
|
3408
3413
|
};
|
|
3409
3414
|
if (self.params.callbacks?.onTick) {
|
|
3410
3415
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3436,6 +3441,7 @@ const OPEN_NEW_PENDING_SIGNAL_FN = async (self, signal) => {
|
|
|
3436
3441
|
exchangeName: self.params.method.context.exchangeName,
|
|
3437
3442
|
symbol: self.params.execution.context.symbol,
|
|
3438
3443
|
currentPrice: signal.priceOpen,
|
|
3444
|
+
backtest: self.params.execution.context.backtest,
|
|
3439
3445
|
};
|
|
3440
3446
|
if (self.params.callbacks?.onTick) {
|
|
3441
3447
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3500,6 +3506,7 @@ const CLOSE_PENDING_SIGNAL_FN = async (self, signal, currentPrice, closeReason)
|
|
|
3500
3506
|
strategyName: self.params.method.context.strategyName,
|
|
3501
3507
|
exchangeName: self.params.method.context.exchangeName,
|
|
3502
3508
|
symbol: self.params.execution.context.symbol,
|
|
3509
|
+
backtest: self.params.execution.context.backtest,
|
|
3503
3510
|
};
|
|
3504
3511
|
if (self.params.callbacks?.onTick) {
|
|
3505
3512
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3569,6 +3576,7 @@ const RETURN_PENDING_SIGNAL_ACTIVE_FN = async (self, signal, currentPrice) => {
|
|
|
3569
3576
|
symbol: self.params.execution.context.symbol,
|
|
3570
3577
|
percentTp,
|
|
3571
3578
|
percentSl,
|
|
3579
|
+
backtest: self.params.execution.context.backtest,
|
|
3572
3580
|
};
|
|
3573
3581
|
if (self.params.callbacks?.onTick) {
|
|
3574
3582
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3586,6 +3594,7 @@ const RETURN_IDLE_FN = async (self, currentPrice) => {
|
|
|
3586
3594
|
exchangeName: self.params.method.context.exchangeName,
|
|
3587
3595
|
symbol: self.params.execution.context.symbol,
|
|
3588
3596
|
currentPrice: currentPrice,
|
|
3597
|
+
backtest: self.params.execution.context.backtest,
|
|
3589
3598
|
};
|
|
3590
3599
|
if (self.params.callbacks?.onTick) {
|
|
3591
3600
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3612,6 +3621,7 @@ const CANCEL_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, averagePr
|
|
|
3612
3621
|
strategyName: self.params.method.context.strategyName,
|
|
3613
3622
|
exchangeName: self.params.method.context.exchangeName,
|
|
3614
3623
|
symbol: self.params.execution.context.symbol,
|
|
3624
|
+
backtest: self.params.execution.context.backtest,
|
|
3615
3625
|
};
|
|
3616
3626
|
if (self.params.callbacks?.onTick) {
|
|
3617
3627
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -3707,6 +3717,7 @@ const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, c
|
|
|
3707
3717
|
strategyName: self.params.method.context.strategyName,
|
|
3708
3718
|
exchangeName: self.params.method.context.exchangeName,
|
|
3709
3719
|
symbol: self.params.execution.context.symbol,
|
|
3720
|
+
backtest: self.params.execution.context.backtest,
|
|
3710
3721
|
};
|
|
3711
3722
|
if (self.params.callbacks?.onTick) {
|
|
3712
3723
|
self.params.callbacks.onTick(self.params.execution.context.symbol, result, self.params.execution.context.backtest);
|
|
@@ -4205,6 +4216,7 @@ class ClientStrategy {
|
|
|
4205
4216
|
strategyName: this.params.method.context.strategyName,
|
|
4206
4217
|
exchangeName: this.params.method.context.exchangeName,
|
|
4207
4218
|
symbol: this.params.execution.context.symbol,
|
|
4219
|
+
backtest: this.params.execution.context.backtest,
|
|
4208
4220
|
};
|
|
4209
4221
|
return result; // Cast to IStrategyBacktestResult (which includes Active)
|
|
4210
4222
|
}
|
|
@@ -4335,7 +4347,7 @@ class MergeRisk {
|
|
|
4335
4347
|
* @returns Promise resolving to true if all risks approve, false if any risk rejects
|
|
4336
4348
|
*/
|
|
4337
4349
|
async checkSignal(params) {
|
|
4338
|
-
|
|
4350
|
+
bt.loggerService.info("MergeRisk checkSignal", {
|
|
4339
4351
|
params,
|
|
4340
4352
|
});
|
|
4341
4353
|
const riskCheck = await Promise.all(this._riskList.map(async (risk) => await risk.checkSignal(params)));
|
|
@@ -4352,7 +4364,7 @@ class MergeRisk {
|
|
|
4352
4364
|
* @returns Promise that resolves when all risks have registered the signal
|
|
4353
4365
|
*/
|
|
4354
4366
|
async addSignal(symbol, context) {
|
|
4355
|
-
|
|
4367
|
+
bt.loggerService.info("MergeRisk addSignal", {
|
|
4356
4368
|
symbol,
|
|
4357
4369
|
context,
|
|
4358
4370
|
});
|
|
@@ -4369,7 +4381,7 @@ class MergeRisk {
|
|
|
4369
4381
|
* @returns Promise that resolves when all risks have removed the signal
|
|
4370
4382
|
*/
|
|
4371
4383
|
async removeSignal(symbol, context) {
|
|
4372
|
-
|
|
4384
|
+
bt.loggerService.info("MergeRisk removeSignal", {
|
|
4373
4385
|
symbol,
|
|
4374
4386
|
context,
|
|
4375
4387
|
});
|
|
@@ -4437,19 +4449,19 @@ class RiskUtils {
|
|
|
4437
4449
|
* }
|
|
4438
4450
|
* ```
|
|
4439
4451
|
*/
|
|
4440
|
-
this.getData = async (symbol, strategyName) => {
|
|
4441
|
-
|
|
4452
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
4453
|
+
bt.loggerService.info(RISK_METHOD_NAME_GET_DATA, {
|
|
4442
4454
|
symbol,
|
|
4443
4455
|
strategyName,
|
|
4444
4456
|
});
|
|
4445
|
-
|
|
4457
|
+
bt.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_GET_DATA);
|
|
4446
4458
|
{
|
|
4447
|
-
const { riskName, riskList } =
|
|
4459
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
4448
4460
|
riskName &&
|
|
4449
|
-
|
|
4450
|
-
riskList && riskList.forEach((riskName) =>
|
|
4461
|
+
bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_DATA);
|
|
4462
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_DATA));
|
|
4451
4463
|
}
|
|
4452
|
-
return await
|
|
4464
|
+
return await bt.riskMarkdownService.getData(symbol, strategyName, backtest);
|
|
4453
4465
|
};
|
|
4454
4466
|
/**
|
|
4455
4467
|
* Generates markdown report with all risk rejection events for a symbol-strategy pair.
|
|
@@ -4492,19 +4504,19 @@ class RiskUtils {
|
|
|
4492
4504
|
* // - my-strategy: 1
|
|
4493
4505
|
* ```
|
|
4494
4506
|
*/
|
|
4495
|
-
this.getReport = async (symbol, strategyName, columns) => {
|
|
4496
|
-
|
|
4507
|
+
this.getReport = async (symbol, strategyName, backtest, columns) => {
|
|
4508
|
+
bt.loggerService.info(RISK_METHOD_NAME_GET_REPORT, {
|
|
4497
4509
|
symbol,
|
|
4498
4510
|
strategyName,
|
|
4499
4511
|
});
|
|
4500
|
-
|
|
4512
|
+
bt.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_GET_REPORT);
|
|
4501
4513
|
{
|
|
4502
|
-
const { riskName, riskList } =
|
|
4514
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
4503
4515
|
riskName &&
|
|
4504
|
-
|
|
4505
|
-
riskList && riskList.forEach((riskName) =>
|
|
4516
|
+
bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_REPORT);
|
|
4517
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_GET_REPORT));
|
|
4506
4518
|
}
|
|
4507
|
-
return await
|
|
4519
|
+
return await bt.riskMarkdownService.getReport(symbol, strategyName, backtest, columns);
|
|
4508
4520
|
};
|
|
4509
4521
|
/**
|
|
4510
4522
|
* Generates and saves markdown report to file.
|
|
@@ -4538,20 +4550,20 @@ class RiskUtils {
|
|
|
4538
4550
|
* }
|
|
4539
4551
|
* ```
|
|
4540
4552
|
*/
|
|
4541
|
-
this.dump = async (symbol, strategyName, path, columns) => {
|
|
4542
|
-
|
|
4553
|
+
this.dump = async (symbol, strategyName, backtest, path, columns) => {
|
|
4554
|
+
bt.loggerService.info(RISK_METHOD_NAME_DUMP, {
|
|
4543
4555
|
symbol,
|
|
4544
4556
|
strategyName,
|
|
4545
4557
|
path,
|
|
4546
4558
|
});
|
|
4547
|
-
|
|
4559
|
+
bt.strategyValidationService.validate(strategyName, RISK_METHOD_NAME_DUMP);
|
|
4548
4560
|
{
|
|
4549
|
-
const { riskName, riskList } =
|
|
4561
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
4550
4562
|
riskName &&
|
|
4551
|
-
|
|
4552
|
-
riskList && riskList.forEach((riskName) =>
|
|
4563
|
+
bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_DUMP);
|
|
4564
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, RISK_METHOD_NAME_DUMP));
|
|
4553
4565
|
}
|
|
4554
|
-
await
|
|
4566
|
+
await bt.riskMarkdownService.dump(symbol, strategyName, backtest, path, columns);
|
|
4555
4567
|
};
|
|
4556
4568
|
}
|
|
4557
4569
|
}
|
|
@@ -5169,7 +5181,7 @@ const DO_VALIDATION_FN = trycatch(async (validation, params) => {
|
|
|
5169
5181
|
error: errorData(error),
|
|
5170
5182
|
message: getErrorMessage(error),
|
|
5171
5183
|
};
|
|
5172
|
-
|
|
5184
|
+
bt.loggerService.warn(message, payload);
|
|
5173
5185
|
console.warn(message, payload);
|
|
5174
5186
|
validationSubject.next(error);
|
|
5175
5187
|
},
|
|
@@ -5264,7 +5276,7 @@ class ClientRisk {
|
|
|
5264
5276
|
}
|
|
5265
5277
|
if (!isValid) {
|
|
5266
5278
|
// Call params.onRejected for riskSubject emission
|
|
5267
|
-
await this.params.onRejected(params.symbol, params, riskMap.size, rejectionNote, Date.now());
|
|
5279
|
+
await this.params.onRejected(params.symbol, params, riskMap.size, rejectionNote, Date.now(), this.params.backtest);
|
|
5268
5280
|
// Call schema callbacks.onRejected if defined
|
|
5269
5281
|
if (this.params.callbacks?.onRejected) {
|
|
5270
5282
|
this.params.callbacks.onRejected(params.symbol, params);
|
|
@@ -5345,8 +5357,9 @@ class ClientRisk {
|
|
|
5345
5357
|
* @param activePositionCount - Number of active positions at rejection time
|
|
5346
5358
|
* @param comment - Rejection reason from validation note or "N/A"
|
|
5347
5359
|
* @param timestamp - Event timestamp in milliseconds
|
|
5360
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
5348
5361
|
*/
|
|
5349
|
-
const COMMIT_REJECTION_FN = async (symbol, params, activePositionCount, comment, timestamp) => await riskSubject.next({
|
|
5362
|
+
const COMMIT_REJECTION_FN = async (symbol, params, activePositionCount, comment, timestamp, backtest) => await riskSubject.next({
|
|
5350
5363
|
symbol,
|
|
5351
5364
|
pendingSignal: params.pendingSignal,
|
|
5352
5365
|
strategyName: params.strategyName,
|
|
@@ -5355,6 +5368,7 @@ const COMMIT_REJECTION_FN = async (symbol, params, activePositionCount, comment,
|
|
|
5355
5368
|
activePositionCount,
|
|
5356
5369
|
comment,
|
|
5357
5370
|
timestamp,
|
|
5371
|
+
backtest,
|
|
5358
5372
|
});
|
|
5359
5373
|
/**
|
|
5360
5374
|
* Connection service routing risk operations to correct ClientRisk instance.
|
|
@@ -7029,7 +7043,7 @@ class WalkerLogicPrivateService {
|
|
|
7029
7043
|
symbol,
|
|
7030
7044
|
});
|
|
7031
7045
|
// Get statistics from BacktestMarkdownService
|
|
7032
|
-
const stats = await this.backtestMarkdownService.getData(symbol, strategyName);
|
|
7046
|
+
const stats = await this.backtestMarkdownService.getData(symbol, strategyName, true);
|
|
7033
7047
|
// Extract metric value
|
|
7034
7048
|
const value = stats[metric];
|
|
7035
7049
|
const metricValue = value !== null &&
|
|
@@ -7093,7 +7107,7 @@ class WalkerLogicPrivateService {
|
|
|
7093
7107
|
bestStrategy,
|
|
7094
7108
|
bestMetric,
|
|
7095
7109
|
bestStats: bestStrategy !== null
|
|
7096
|
-
? await this.backtestMarkdownService.getData(symbol, bestStrategy)
|
|
7110
|
+
? await this.backtestMarkdownService.getData(symbol, bestStrategy, true)
|
|
7097
7111
|
: null,
|
|
7098
7112
|
};
|
|
7099
7113
|
// Call onComplete callback if provided with final best results
|
|
@@ -7606,10 +7620,10 @@ class BacktestMarkdownService {
|
|
|
7606
7620
|
/** Logger service for debug output */
|
|
7607
7621
|
this.loggerService = inject(TYPES.loggerService);
|
|
7608
7622
|
/**
|
|
7609
|
-
* Memoized function to get or create ReportStorage for a symbol-strategy
|
|
7610
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
7623
|
+
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
7624
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
7611
7625
|
*/
|
|
7612
|
-
this.getStorage = memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new ReportStorage$5());
|
|
7626
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$5());
|
|
7613
7627
|
/**
|
|
7614
7628
|
* Processes tick events and accumulates closed signals.
|
|
7615
7629
|
* Should be called from IStrategyCallbacks.onTick.
|
|
@@ -7636,7 +7650,7 @@ class BacktestMarkdownService {
|
|
|
7636
7650
|
if (data.action !== "closed") {
|
|
7637
7651
|
return;
|
|
7638
7652
|
}
|
|
7639
|
-
const storage = this.getStorage(data.symbol, data.strategyName);
|
|
7653
|
+
const storage = this.getStorage(data.symbol, data.strategyName, true);
|
|
7640
7654
|
storage.addSignal(data);
|
|
7641
7655
|
};
|
|
7642
7656
|
/**
|
|
@@ -7645,21 +7659,23 @@ class BacktestMarkdownService {
|
|
|
7645
7659
|
*
|
|
7646
7660
|
* @param symbol - Trading pair symbol
|
|
7647
7661
|
* @param strategyName - Strategy name to get data for
|
|
7662
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
7648
7663
|
* @returns Statistical data object with all metrics
|
|
7649
7664
|
*
|
|
7650
7665
|
* @example
|
|
7651
7666
|
* ```typescript
|
|
7652
7667
|
* const service = new BacktestMarkdownService();
|
|
7653
|
-
* const stats = await service.getData("BTCUSDT", "my-strategy");
|
|
7668
|
+
* const stats = await service.getData("BTCUSDT", "my-strategy", true);
|
|
7654
7669
|
* console.log(stats.sharpeRatio, stats.winRate);
|
|
7655
7670
|
* ```
|
|
7656
7671
|
*/
|
|
7657
|
-
this.getData = async (symbol, strategyName) => {
|
|
7672
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
7658
7673
|
this.loggerService.log("backtestMarkdownService getData", {
|
|
7659
7674
|
symbol,
|
|
7660
7675
|
strategyName,
|
|
7676
|
+
backtest,
|
|
7661
7677
|
});
|
|
7662
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
7678
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
7663
7679
|
return storage.getData();
|
|
7664
7680
|
};
|
|
7665
7681
|
/**
|
|
@@ -7668,22 +7684,24 @@ class BacktestMarkdownService {
|
|
|
7668
7684
|
*
|
|
7669
7685
|
* @param symbol - Trading pair symbol
|
|
7670
7686
|
* @param strategyName - Strategy name to generate report for
|
|
7687
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
7671
7688
|
* @param columns - Column configuration for formatting the table
|
|
7672
7689
|
* @returns Markdown formatted report string with table of all closed signals
|
|
7673
7690
|
*
|
|
7674
7691
|
* @example
|
|
7675
7692
|
* ```typescript
|
|
7676
7693
|
* const service = new BacktestMarkdownService();
|
|
7677
|
-
* const markdown = await service.getReport("BTCUSDT", "my-strategy");
|
|
7694
|
+
* const markdown = await service.getReport("BTCUSDT", "my-strategy", true);
|
|
7678
7695
|
* console.log(markdown);
|
|
7679
7696
|
* ```
|
|
7680
7697
|
*/
|
|
7681
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.backtest_columns) => {
|
|
7698
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.backtest_columns) => {
|
|
7682
7699
|
this.loggerService.log("backtestMarkdownService getReport", {
|
|
7683
7700
|
symbol,
|
|
7684
7701
|
strategyName,
|
|
7702
|
+
backtest,
|
|
7685
7703
|
});
|
|
7686
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
7704
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
7687
7705
|
return storage.getReport(strategyName, columns);
|
|
7688
7706
|
};
|
|
7689
7707
|
/**
|
|
@@ -7693,6 +7711,7 @@ class BacktestMarkdownService {
|
|
|
7693
7711
|
*
|
|
7694
7712
|
* @param symbol - Trading pair symbol
|
|
7695
7713
|
* @param strategyName - Strategy name to save report for
|
|
7714
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
7696
7715
|
* @param path - Directory path to save report (default: "./dump/backtest")
|
|
7697
7716
|
* @param columns - Column configuration for formatting the table
|
|
7698
7717
|
*
|
|
@@ -7701,45 +7720,48 @@ class BacktestMarkdownService {
|
|
|
7701
7720
|
* const service = new BacktestMarkdownService();
|
|
7702
7721
|
*
|
|
7703
7722
|
* // Save to default path: ./dump/backtest/my-strategy.md
|
|
7704
|
-
* await service.dump("BTCUSDT", "my-strategy");
|
|
7723
|
+
* await service.dump("BTCUSDT", "my-strategy", true);
|
|
7705
7724
|
*
|
|
7706
7725
|
* // Save to custom path: ./custom/path/my-strategy.md
|
|
7707
|
-
* await service.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
7726
|
+
* await service.dump("BTCUSDT", "my-strategy", true, "./custom/path");
|
|
7708
7727
|
* ```
|
|
7709
7728
|
*/
|
|
7710
|
-
this.dump = async (symbol, strategyName, path = "./dump/backtest", columns = COLUMN_CONFIG.backtest_columns) => {
|
|
7729
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/backtest", columns = COLUMN_CONFIG.backtest_columns) => {
|
|
7711
7730
|
this.loggerService.log("backtestMarkdownService dump", {
|
|
7712
7731
|
symbol,
|
|
7713
7732
|
strategyName,
|
|
7733
|
+
backtest,
|
|
7714
7734
|
path,
|
|
7715
7735
|
});
|
|
7716
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
7736
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
7717
7737
|
await storage.dump(strategyName, path, columns);
|
|
7718
7738
|
};
|
|
7719
7739
|
/**
|
|
7720
7740
|
* Clears accumulated signal data from storage.
|
|
7721
|
-
* If ctx is provided, clears only that specific symbol-strategy
|
|
7741
|
+
* If ctx is provided, clears only that specific symbol-strategy-backtest triple's data.
|
|
7722
7742
|
* If nothing is provided, clears all data.
|
|
7723
7743
|
*
|
|
7744
|
+
* @param backtest - Backtest mode flag
|
|
7724
7745
|
* @param ctx - Optional context with symbol and strategyName
|
|
7725
7746
|
*
|
|
7726
7747
|
* @example
|
|
7727
7748
|
* ```typescript
|
|
7728
7749
|
* const service = new BacktestMarkdownService();
|
|
7729
7750
|
*
|
|
7730
|
-
* // Clear specific symbol-strategy
|
|
7731
|
-
* await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
7751
|
+
* // Clear specific symbol-strategy-backtest triple
|
|
7752
|
+
* await service.clear(true, { symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
7732
7753
|
*
|
|
7733
7754
|
* // Clear all data
|
|
7734
7755
|
* await service.clear();
|
|
7735
7756
|
* ```
|
|
7736
7757
|
*/
|
|
7737
|
-
this.clear = async (ctx) => {
|
|
7758
|
+
this.clear = async (backtest, ctx) => {
|
|
7738
7759
|
this.loggerService.log("backtestMarkdownService clear", {
|
|
7760
|
+
backtest,
|
|
7739
7761
|
ctx,
|
|
7740
7762
|
});
|
|
7741
7763
|
if (ctx) {
|
|
7742
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
7764
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
7743
7765
|
this.getStorage.clear(key);
|
|
7744
7766
|
}
|
|
7745
7767
|
else {
|
|
@@ -8090,10 +8112,10 @@ class LiveMarkdownService {
|
|
|
8090
8112
|
/** Logger service for debug output */
|
|
8091
8113
|
this.loggerService = inject(TYPES.loggerService);
|
|
8092
8114
|
/**
|
|
8093
|
-
* Memoized function to get or create ReportStorage for a symbol-strategy
|
|
8094
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
8115
|
+
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
8116
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8095
8117
|
*/
|
|
8096
|
-
this.getStorage = memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new ReportStorage$4());
|
|
8118
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$4());
|
|
8097
8119
|
/**
|
|
8098
8120
|
* Processes tick events and accumulates all event types.
|
|
8099
8121
|
* Should be called from IStrategyCallbacks.onTick.
|
|
@@ -8119,7 +8141,7 @@ class LiveMarkdownService {
|
|
|
8119
8141
|
this.loggerService.log("liveMarkdownService tick", {
|
|
8120
8142
|
data,
|
|
8121
8143
|
});
|
|
8122
|
-
const storage = this.getStorage(data.symbol, data.strategyName);
|
|
8144
|
+
const storage = this.getStorage(data.symbol, data.strategyName, false);
|
|
8123
8145
|
if (data.action === "idle") {
|
|
8124
8146
|
storage.addIdleEvent(data.currentPrice);
|
|
8125
8147
|
}
|
|
@@ -8139,21 +8161,23 @@ class LiveMarkdownService {
|
|
|
8139
8161
|
*
|
|
8140
8162
|
* @param symbol - Trading pair symbol
|
|
8141
8163
|
* @param strategyName - Strategy name to get data for
|
|
8164
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8142
8165
|
* @returns Statistical data object with all metrics
|
|
8143
8166
|
*
|
|
8144
8167
|
* @example
|
|
8145
8168
|
* ```typescript
|
|
8146
8169
|
* const service = new LiveMarkdownService();
|
|
8147
|
-
* const stats = await service.getData("BTCUSDT", "my-strategy");
|
|
8170
|
+
* const stats = await service.getData("BTCUSDT", "my-strategy", false);
|
|
8148
8171
|
* console.log(stats.sharpeRatio, stats.winRate);
|
|
8149
8172
|
* ```
|
|
8150
8173
|
*/
|
|
8151
|
-
this.getData = async (symbol, strategyName) => {
|
|
8174
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
8152
8175
|
this.loggerService.log("liveMarkdownService getData", {
|
|
8153
8176
|
symbol,
|
|
8154
8177
|
strategyName,
|
|
8178
|
+
backtest,
|
|
8155
8179
|
});
|
|
8156
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8180
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8157
8181
|
return storage.getData();
|
|
8158
8182
|
};
|
|
8159
8183
|
/**
|
|
@@ -8162,22 +8186,24 @@ class LiveMarkdownService {
|
|
|
8162
8186
|
*
|
|
8163
8187
|
* @param symbol - Trading pair symbol
|
|
8164
8188
|
* @param strategyName - Strategy name to generate report for
|
|
8189
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8165
8190
|
* @param columns - Column configuration for formatting the table
|
|
8166
8191
|
* @returns Markdown formatted report string with table of all events
|
|
8167
8192
|
*
|
|
8168
8193
|
* @example
|
|
8169
8194
|
* ```typescript
|
|
8170
8195
|
* const service = new LiveMarkdownService();
|
|
8171
|
-
* const markdown = await service.getReport("BTCUSDT", "my-strategy");
|
|
8196
|
+
* const markdown = await service.getReport("BTCUSDT", "my-strategy", false);
|
|
8172
8197
|
* console.log(markdown);
|
|
8173
8198
|
* ```
|
|
8174
8199
|
*/
|
|
8175
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.live_columns) => {
|
|
8200
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.live_columns) => {
|
|
8176
8201
|
this.loggerService.log("liveMarkdownService getReport", {
|
|
8177
8202
|
symbol,
|
|
8178
8203
|
strategyName,
|
|
8204
|
+
backtest,
|
|
8179
8205
|
});
|
|
8180
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8206
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8181
8207
|
return storage.getReport(strategyName, columns);
|
|
8182
8208
|
};
|
|
8183
8209
|
/**
|
|
@@ -8187,6 +8213,7 @@ class LiveMarkdownService {
|
|
|
8187
8213
|
*
|
|
8188
8214
|
* @param symbol - Trading pair symbol
|
|
8189
8215
|
* @param strategyName - Strategy name to save report for
|
|
8216
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8190
8217
|
* @param path - Directory path to save report (default: "./dump/live")
|
|
8191
8218
|
* @param columns - Column configuration for formatting the table
|
|
8192
8219
|
*
|
|
@@ -8195,45 +8222,48 @@ class LiveMarkdownService {
|
|
|
8195
8222
|
* const service = new LiveMarkdownService();
|
|
8196
8223
|
*
|
|
8197
8224
|
* // Save to default path: ./dump/live/my-strategy.md
|
|
8198
|
-
* await service.dump("BTCUSDT", "my-strategy");
|
|
8225
|
+
* await service.dump("BTCUSDT", "my-strategy", false);
|
|
8199
8226
|
*
|
|
8200
8227
|
* // Save to custom path: ./custom/path/my-strategy.md
|
|
8201
|
-
* await service.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
8228
|
+
* await service.dump("BTCUSDT", "my-strategy", false, "./custom/path");
|
|
8202
8229
|
* ```
|
|
8203
8230
|
*/
|
|
8204
|
-
this.dump = async (symbol, strategyName, path = "./dump/live", columns = COLUMN_CONFIG.live_columns) => {
|
|
8231
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/live", columns = COLUMN_CONFIG.live_columns) => {
|
|
8205
8232
|
this.loggerService.log("liveMarkdownService dump", {
|
|
8206
8233
|
symbol,
|
|
8207
8234
|
strategyName,
|
|
8235
|
+
backtest,
|
|
8208
8236
|
path,
|
|
8209
8237
|
});
|
|
8210
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8238
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8211
8239
|
await storage.dump(strategyName, path, columns);
|
|
8212
8240
|
};
|
|
8213
8241
|
/**
|
|
8214
8242
|
* Clears accumulated event data from storage.
|
|
8215
|
-
* If ctx is provided, clears only that specific symbol-strategy
|
|
8243
|
+
* If ctx is provided, clears only that specific symbol-strategy-backtest triple's data.
|
|
8216
8244
|
* If nothing is provided, clears all data.
|
|
8217
8245
|
*
|
|
8246
|
+
* @param backtest - Backtest mode flag
|
|
8218
8247
|
* @param ctx - Optional context with symbol and strategyName
|
|
8219
8248
|
*
|
|
8220
8249
|
* @example
|
|
8221
8250
|
* ```typescript
|
|
8222
8251
|
* const service = new LiveMarkdownService();
|
|
8223
8252
|
*
|
|
8224
|
-
* // Clear specific symbol-strategy
|
|
8225
|
-
* await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
8253
|
+
* // Clear specific symbol-strategy-backtest triple
|
|
8254
|
+
* await service.clear(false, { symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
8226
8255
|
*
|
|
8227
8256
|
* // Clear all data
|
|
8228
8257
|
* await service.clear();
|
|
8229
8258
|
* ```
|
|
8230
8259
|
*/
|
|
8231
|
-
this.clear = async (ctx) => {
|
|
8260
|
+
this.clear = async (backtest, ctx) => {
|
|
8232
8261
|
this.loggerService.log("liveMarkdownService clear", {
|
|
8262
|
+
backtest,
|
|
8233
8263
|
ctx,
|
|
8234
8264
|
});
|
|
8235
8265
|
if (ctx) {
|
|
8236
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
8266
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8237
8267
|
this.getStorage.clear(key);
|
|
8238
8268
|
}
|
|
8239
8269
|
else {
|
|
@@ -8488,10 +8518,10 @@ class ScheduleMarkdownService {
|
|
|
8488
8518
|
/** Logger service for debug output */
|
|
8489
8519
|
this.loggerService = inject(TYPES.loggerService);
|
|
8490
8520
|
/**
|
|
8491
|
-
* Memoized function to get or create ReportStorage for a symbol-strategy
|
|
8492
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
8521
|
+
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
8522
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8493
8523
|
*/
|
|
8494
|
-
this.getStorage = memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new ReportStorage$3());
|
|
8524
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$3());
|
|
8495
8525
|
/**
|
|
8496
8526
|
* Processes tick events and accumulates scheduled/opened/cancelled events.
|
|
8497
8527
|
* Should be called from signalEmitter subscription.
|
|
@@ -8510,7 +8540,7 @@ class ScheduleMarkdownService {
|
|
|
8510
8540
|
this.loggerService.log("scheduleMarkdownService tick", {
|
|
8511
8541
|
data,
|
|
8512
8542
|
});
|
|
8513
|
-
const storage = this.getStorage(data.symbol, data.strategyName);
|
|
8543
|
+
const storage = this.getStorage(data.symbol, data.strategyName, data.backtest);
|
|
8514
8544
|
if (data.action === "scheduled") {
|
|
8515
8545
|
storage.addScheduledEvent(data);
|
|
8516
8546
|
}
|
|
@@ -8531,21 +8561,23 @@ class ScheduleMarkdownService {
|
|
|
8531
8561
|
*
|
|
8532
8562
|
* @param symbol - Trading pair symbol
|
|
8533
8563
|
* @param strategyName - Strategy name to get data for
|
|
8564
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8534
8565
|
* @returns Statistical data object with all metrics
|
|
8535
8566
|
*
|
|
8536
8567
|
* @example
|
|
8537
8568
|
* ```typescript
|
|
8538
8569
|
* const service = new ScheduleMarkdownService();
|
|
8539
|
-
* const stats = await service.getData("BTCUSDT", "my-strategy");
|
|
8570
|
+
* const stats = await service.getData("BTCUSDT", "my-strategy", false);
|
|
8540
8571
|
* console.log(stats.cancellationRate, stats.avgWaitTime);
|
|
8541
8572
|
* ```
|
|
8542
8573
|
*/
|
|
8543
|
-
this.getData = async (symbol, strategyName) => {
|
|
8574
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
8544
8575
|
this.loggerService.log("scheduleMarkdownService getData", {
|
|
8545
8576
|
symbol,
|
|
8546
8577
|
strategyName,
|
|
8578
|
+
backtest,
|
|
8547
8579
|
});
|
|
8548
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8580
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8549
8581
|
return storage.getData();
|
|
8550
8582
|
};
|
|
8551
8583
|
/**
|
|
@@ -8554,22 +8586,24 @@ class ScheduleMarkdownService {
|
|
|
8554
8586
|
*
|
|
8555
8587
|
* @param symbol - Trading pair symbol
|
|
8556
8588
|
* @param strategyName - Strategy name to generate report for
|
|
8589
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8557
8590
|
* @param columns - Column configuration for formatting the table
|
|
8558
8591
|
* @returns Markdown formatted report string with table of all events
|
|
8559
8592
|
*
|
|
8560
8593
|
* @example
|
|
8561
8594
|
* ```typescript
|
|
8562
8595
|
* const service = new ScheduleMarkdownService();
|
|
8563
|
-
* const markdown = await service.getReport("BTCUSDT", "my-strategy");
|
|
8596
|
+
* const markdown = await service.getReport("BTCUSDT", "my-strategy", false);
|
|
8564
8597
|
* console.log(markdown);
|
|
8565
8598
|
* ```
|
|
8566
8599
|
*/
|
|
8567
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.schedule_columns) => {
|
|
8600
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.schedule_columns) => {
|
|
8568
8601
|
this.loggerService.log("scheduleMarkdownService getReport", {
|
|
8569
8602
|
symbol,
|
|
8570
8603
|
strategyName,
|
|
8604
|
+
backtest,
|
|
8571
8605
|
});
|
|
8572
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8606
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8573
8607
|
return storage.getReport(strategyName, columns);
|
|
8574
8608
|
};
|
|
8575
8609
|
/**
|
|
@@ -8579,6 +8613,7 @@ class ScheduleMarkdownService {
|
|
|
8579
8613
|
*
|
|
8580
8614
|
* @param symbol - Trading pair symbol
|
|
8581
8615
|
* @param strategyName - Strategy name to save report for
|
|
8616
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8582
8617
|
* @param path - Directory path to save report (default: "./dump/schedule")
|
|
8583
8618
|
* @param columns - Column configuration for formatting the table
|
|
8584
8619
|
*
|
|
@@ -8587,45 +8622,48 @@ class ScheduleMarkdownService {
|
|
|
8587
8622
|
* const service = new ScheduleMarkdownService();
|
|
8588
8623
|
*
|
|
8589
8624
|
* // Save to default path: ./dump/schedule/my-strategy.md
|
|
8590
|
-
* await service.dump("BTCUSDT", "my-strategy");
|
|
8625
|
+
* await service.dump("BTCUSDT", "my-strategy", false);
|
|
8591
8626
|
*
|
|
8592
8627
|
* // Save to custom path: ./custom/path/my-strategy.md
|
|
8593
|
-
* await service.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
8628
|
+
* await service.dump("BTCUSDT", "my-strategy", false, "./custom/path");
|
|
8594
8629
|
* ```
|
|
8595
8630
|
*/
|
|
8596
|
-
this.dump = async (symbol, strategyName, path = "./dump/schedule", columns = COLUMN_CONFIG.schedule_columns) => {
|
|
8631
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/schedule", columns = COLUMN_CONFIG.schedule_columns) => {
|
|
8597
8632
|
this.loggerService.log("scheduleMarkdownService dump", {
|
|
8598
8633
|
symbol,
|
|
8599
8634
|
strategyName,
|
|
8635
|
+
backtest,
|
|
8600
8636
|
path,
|
|
8601
8637
|
});
|
|
8602
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8638
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8603
8639
|
await storage.dump(strategyName, path, columns);
|
|
8604
8640
|
};
|
|
8605
8641
|
/**
|
|
8606
8642
|
* Clears accumulated event data from storage.
|
|
8607
|
-
* If ctx is provided, clears only that specific symbol-strategy
|
|
8643
|
+
* If ctx is provided, clears only that specific symbol-strategy-backtest triple's data.
|
|
8608
8644
|
* If nothing is provided, clears all data.
|
|
8609
8645
|
*
|
|
8646
|
+
* @param backtest - Backtest mode flag
|
|
8610
8647
|
* @param ctx - Optional context with symbol and strategyName
|
|
8611
8648
|
*
|
|
8612
8649
|
* @example
|
|
8613
8650
|
* ```typescript
|
|
8614
8651
|
* const service = new ScheduleMarkdownService();
|
|
8615
8652
|
*
|
|
8616
|
-
* // Clear specific symbol-strategy
|
|
8617
|
-
* await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
8653
|
+
* // Clear specific symbol-strategy-backtest triple
|
|
8654
|
+
* await service.clear(false, { symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
8618
8655
|
*
|
|
8619
8656
|
* // Clear all data
|
|
8620
8657
|
* await service.clear();
|
|
8621
8658
|
* ```
|
|
8622
8659
|
*/
|
|
8623
|
-
this.clear = async (ctx) => {
|
|
8660
|
+
this.clear = async (backtest, ctx) => {
|
|
8624
8661
|
this.loggerService.log("scheduleMarkdownService clear", {
|
|
8662
|
+
backtest,
|
|
8625
8663
|
ctx,
|
|
8626
8664
|
});
|
|
8627
8665
|
if (ctx) {
|
|
8628
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
8666
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8629
8667
|
this.getStorage.clear(key);
|
|
8630
8668
|
}
|
|
8631
8669
|
else {
|
|
@@ -8864,10 +8902,10 @@ class PerformanceMarkdownService {
|
|
|
8864
8902
|
/** Logger service for debug output */
|
|
8865
8903
|
this.loggerService = inject(TYPES.loggerService);
|
|
8866
8904
|
/**
|
|
8867
|
-
* Memoized function to get or create PerformanceStorage for a symbol-strategy
|
|
8868
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
8905
|
+
* Memoized function to get or create PerformanceStorage for a symbol-strategy-backtest triple.
|
|
8906
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
8869
8907
|
*/
|
|
8870
|
-
this.getStorage = memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new PerformanceStorage());
|
|
8908
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new PerformanceStorage());
|
|
8871
8909
|
/**
|
|
8872
8910
|
* Processes performance events and accumulates metrics.
|
|
8873
8911
|
* Should be called from performance tracking code.
|
|
@@ -8880,7 +8918,7 @@ class PerformanceMarkdownService {
|
|
|
8880
8918
|
});
|
|
8881
8919
|
const symbol = event.symbol || "global";
|
|
8882
8920
|
const strategyName = event.strategyName || "global";
|
|
8883
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8921
|
+
const storage = this.getStorage(symbol, strategyName, event.backtest);
|
|
8884
8922
|
storage.addEvent(event);
|
|
8885
8923
|
};
|
|
8886
8924
|
/**
|
|
@@ -8888,22 +8926,24 @@ class PerformanceMarkdownService {
|
|
|
8888
8926
|
*
|
|
8889
8927
|
* @param symbol - Trading pair symbol
|
|
8890
8928
|
* @param strategyName - Strategy name to get data for
|
|
8929
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8891
8930
|
* @returns Performance statistics with aggregated metrics
|
|
8892
8931
|
*
|
|
8893
8932
|
* @example
|
|
8894
8933
|
* ```typescript
|
|
8895
|
-
* const stats = await performanceService.getData("BTCUSDT", "my-strategy");
|
|
8934
|
+
* const stats = await performanceService.getData("BTCUSDT", "my-strategy", false);
|
|
8896
8935
|
* console.log("Total time:", stats.totalDuration);
|
|
8897
8936
|
* console.log("Slowest operation:", Object.values(stats.metricStats)
|
|
8898
8937
|
* .sort((a, b) => b.avgDuration - a.avgDuration)[0]);
|
|
8899
8938
|
* ```
|
|
8900
8939
|
*/
|
|
8901
|
-
this.getData = async (symbol, strategyName) => {
|
|
8940
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
8902
8941
|
this.loggerService.log("performanceMarkdownService getData", {
|
|
8903
8942
|
symbol,
|
|
8904
8943
|
strategyName,
|
|
8944
|
+
backtest,
|
|
8905
8945
|
});
|
|
8906
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8946
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8907
8947
|
return storage.getData(strategyName);
|
|
8908
8948
|
};
|
|
8909
8949
|
/**
|
|
@@ -8911,21 +8951,23 @@ class PerformanceMarkdownService {
|
|
|
8911
8951
|
*
|
|
8912
8952
|
* @param symbol - Trading pair symbol
|
|
8913
8953
|
* @param strategyName - Strategy name to generate report for
|
|
8954
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8914
8955
|
* @param columns - Column configuration for formatting the table
|
|
8915
8956
|
* @returns Markdown formatted report string
|
|
8916
8957
|
*
|
|
8917
8958
|
* @example
|
|
8918
8959
|
* ```typescript
|
|
8919
|
-
* const markdown = await performanceService.getReport("BTCUSDT", "my-strategy");
|
|
8960
|
+
* const markdown = await performanceService.getReport("BTCUSDT", "my-strategy", false);
|
|
8920
8961
|
* console.log(markdown);
|
|
8921
8962
|
* ```
|
|
8922
8963
|
*/
|
|
8923
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.performance_columns) => {
|
|
8964
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.performance_columns) => {
|
|
8924
8965
|
this.loggerService.log("performanceMarkdownService getReport", {
|
|
8925
8966
|
symbol,
|
|
8926
8967
|
strategyName,
|
|
8968
|
+
backtest,
|
|
8927
8969
|
});
|
|
8928
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8970
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8929
8971
|
return storage.getReport(strategyName, columns);
|
|
8930
8972
|
};
|
|
8931
8973
|
/**
|
|
@@ -8933,42 +8975,45 @@ class PerformanceMarkdownService {
|
|
|
8933
8975
|
*
|
|
8934
8976
|
* @param symbol - Trading pair symbol
|
|
8935
8977
|
* @param strategyName - Strategy name to save report for
|
|
8978
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
8936
8979
|
* @param path - Directory path to save report
|
|
8937
8980
|
* @param columns - Column configuration for formatting the table
|
|
8938
8981
|
*
|
|
8939
8982
|
* @example
|
|
8940
8983
|
* ```typescript
|
|
8941
8984
|
* // Save to default path: ./dump/performance/my-strategy.md
|
|
8942
|
-
* await performanceService.dump("BTCUSDT", "my-strategy");
|
|
8985
|
+
* await performanceService.dump("BTCUSDT", "my-strategy", false);
|
|
8943
8986
|
*
|
|
8944
8987
|
* // Save to custom path
|
|
8945
|
-
* await performanceService.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
8988
|
+
* await performanceService.dump("BTCUSDT", "my-strategy", false, "./custom/path");
|
|
8946
8989
|
* ```
|
|
8947
8990
|
*/
|
|
8948
|
-
this.dump = async (symbol, strategyName, path = "./dump/performance", columns = COLUMN_CONFIG.performance_columns) => {
|
|
8991
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/performance", columns = COLUMN_CONFIG.performance_columns) => {
|
|
8949
8992
|
this.loggerService.log("performanceMarkdownService dump", {
|
|
8950
8993
|
symbol,
|
|
8951
8994
|
strategyName,
|
|
8995
|
+
backtest,
|
|
8952
8996
|
path,
|
|
8953
8997
|
});
|
|
8954
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
8998
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
8955
8999
|
await storage.dump(strategyName, path, columns);
|
|
8956
9000
|
};
|
|
8957
9001
|
/**
|
|
8958
9002
|
* Clears accumulated performance data from storage.
|
|
8959
9003
|
*
|
|
8960
|
-
* @param
|
|
8961
|
-
* @param
|
|
9004
|
+
* @param backtest - Backtest mode flag
|
|
9005
|
+
* @param ctx - Optional context with symbol and strategyName
|
|
8962
9006
|
*/
|
|
8963
|
-
this.clear = async (ctx) => {
|
|
9007
|
+
this.clear = async (backtest, ctx) => {
|
|
8964
9008
|
this.loggerService.log("performanceMarkdownService clear", {
|
|
9009
|
+
backtest,
|
|
8965
9010
|
ctx,
|
|
8966
9011
|
});
|
|
8967
9012
|
if (ctx) {
|
|
8968
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
9013
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
8969
9014
|
this.getStorage.clear(key);
|
|
8970
9015
|
}
|
|
8971
|
-
{
|
|
9016
|
+
else {
|
|
8972
9017
|
this.getStorage.clear();
|
|
8973
9018
|
}
|
|
8974
9019
|
};
|
|
@@ -9732,10 +9777,10 @@ class HeatMarkdownService {
|
|
|
9732
9777
|
/** Logger service for debug output */
|
|
9733
9778
|
this.loggerService = inject(TYPES.loggerService);
|
|
9734
9779
|
/**
|
|
9735
|
-
* Memoized function to get or create HeatmapStorage for a strategy.
|
|
9736
|
-
* Each strategy gets its own isolated heatmap storage instance.
|
|
9780
|
+
* Memoized function to get or create HeatmapStorage for a strategy and backtest mode.
|
|
9781
|
+
* Each strategy + backtest mode combination gets its own isolated heatmap storage instance.
|
|
9737
9782
|
*/
|
|
9738
|
-
this.getStorage = memoize(([strategyName]) => `${strategyName}`, () => new HeatmapStorage());
|
|
9783
|
+
this.getStorage = memoize(([strategyName, backtest]) => `${strategyName}:${backtest ? "backtest" : "live"}`, () => new HeatmapStorage());
|
|
9739
9784
|
/**
|
|
9740
9785
|
* Processes tick events and accumulates closed signals.
|
|
9741
9786
|
* Should be called from signal emitter subscription.
|
|
@@ -9751,19 +9796,20 @@ class HeatMarkdownService {
|
|
|
9751
9796
|
if (data.action !== "closed") {
|
|
9752
9797
|
return;
|
|
9753
9798
|
}
|
|
9754
|
-
const storage = this.getStorage(data.strategyName);
|
|
9799
|
+
const storage = this.getStorage(data.strategyName, data.backtest);
|
|
9755
9800
|
storage.addSignal(data);
|
|
9756
9801
|
};
|
|
9757
9802
|
/**
|
|
9758
9803
|
* Gets aggregated portfolio heatmap statistics for a strategy.
|
|
9759
9804
|
*
|
|
9760
9805
|
* @param strategyName - Strategy name to get heatmap data for
|
|
9806
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
9761
9807
|
* @returns Promise resolving to heatmap statistics with per-symbol and portfolio-wide metrics
|
|
9762
9808
|
*
|
|
9763
9809
|
* @example
|
|
9764
9810
|
* ```typescript
|
|
9765
9811
|
* const service = new HeatMarkdownService();
|
|
9766
|
-
* const stats = await service.getData("my-strategy");
|
|
9812
|
+
* const stats = await service.getData("my-strategy", true);
|
|
9767
9813
|
*
|
|
9768
9814
|
* console.log(`Total symbols: ${stats.totalSymbols}`);
|
|
9769
9815
|
* console.log(`Portfolio PNL: ${stats.portfolioTotalPnl}%`);
|
|
@@ -9773,24 +9819,26 @@ class HeatMarkdownService {
|
|
|
9773
9819
|
* });
|
|
9774
9820
|
* ```
|
|
9775
9821
|
*/
|
|
9776
|
-
this.getData = async (strategyName) => {
|
|
9822
|
+
this.getData = async (strategyName, backtest) => {
|
|
9777
9823
|
this.loggerService.log(HEATMAP_METHOD_NAME_GET_DATA, {
|
|
9778
9824
|
strategyName,
|
|
9825
|
+
backtest,
|
|
9779
9826
|
});
|
|
9780
|
-
const storage = this.getStorage(strategyName);
|
|
9827
|
+
const storage = this.getStorage(strategyName, backtest);
|
|
9781
9828
|
return storage.getData();
|
|
9782
9829
|
};
|
|
9783
9830
|
/**
|
|
9784
9831
|
* Generates markdown report with portfolio heatmap table for a strategy.
|
|
9785
9832
|
*
|
|
9786
9833
|
* @param strategyName - Strategy name to generate heatmap report for
|
|
9834
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
9787
9835
|
* @param columns - Column configuration for formatting the table
|
|
9788
9836
|
* @returns Promise resolving to markdown formatted report string
|
|
9789
9837
|
*
|
|
9790
9838
|
* @example
|
|
9791
9839
|
* ```typescript
|
|
9792
9840
|
* const service = new HeatMarkdownService();
|
|
9793
|
-
* const markdown = await service.getReport("my-strategy");
|
|
9841
|
+
* const markdown = await service.getReport("my-strategy", true);
|
|
9794
9842
|
* console.log(markdown);
|
|
9795
9843
|
* // Output:
|
|
9796
9844
|
* // # Portfolio Heatmap: my-strategy
|
|
@@ -9804,11 +9852,12 @@ class HeatMarkdownService {
|
|
|
9804
9852
|
* // ...
|
|
9805
9853
|
* ```
|
|
9806
9854
|
*/
|
|
9807
|
-
this.getReport = async (strategyName, columns = COLUMN_CONFIG.heat_columns) => {
|
|
9855
|
+
this.getReport = async (strategyName, backtest, columns = COLUMN_CONFIG.heat_columns) => {
|
|
9808
9856
|
this.loggerService.log(HEATMAP_METHOD_NAME_GET_REPORT, {
|
|
9809
9857
|
strategyName,
|
|
9858
|
+
backtest,
|
|
9810
9859
|
});
|
|
9811
|
-
const storage = this.getStorage(strategyName);
|
|
9860
|
+
const storage = this.getStorage(strategyName, backtest);
|
|
9812
9861
|
return storage.getReport(strategyName, columns);
|
|
9813
9862
|
};
|
|
9814
9863
|
/**
|
|
@@ -9818,6 +9867,7 @@ class HeatMarkdownService {
|
|
|
9818
9867
|
* Default filename: {strategyName}.md
|
|
9819
9868
|
*
|
|
9820
9869
|
* @param strategyName - Strategy name to save heatmap report for
|
|
9870
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
9821
9871
|
* @param path - Optional directory path to save report (default: "./dump/heatmap")
|
|
9822
9872
|
* @param columns - Column configuration for formatting the table
|
|
9823
9873
|
*
|
|
@@ -9826,43 +9876,52 @@ class HeatMarkdownService {
|
|
|
9826
9876
|
* const service = new HeatMarkdownService();
|
|
9827
9877
|
*
|
|
9828
9878
|
* // Save to default path: ./dump/heatmap/my-strategy.md
|
|
9829
|
-
* await service.dump("my-strategy");
|
|
9879
|
+
* await service.dump("my-strategy", true);
|
|
9830
9880
|
*
|
|
9831
9881
|
* // Save to custom path: ./reports/my-strategy.md
|
|
9832
|
-
* await service.dump("my-strategy", "./reports");
|
|
9882
|
+
* await service.dump("my-strategy", true, "./reports");
|
|
9833
9883
|
* ```
|
|
9834
9884
|
*/
|
|
9835
|
-
this.dump = async (strategyName, path = "./dump/heatmap", columns = COLUMN_CONFIG.heat_columns) => {
|
|
9885
|
+
this.dump = async (strategyName, backtest, path = "./dump/heatmap", columns = COLUMN_CONFIG.heat_columns) => {
|
|
9836
9886
|
this.loggerService.log(HEATMAP_METHOD_NAME_DUMP, {
|
|
9837
9887
|
strategyName,
|
|
9888
|
+
backtest,
|
|
9838
9889
|
path,
|
|
9839
9890
|
});
|
|
9840
|
-
const storage = this.getStorage(strategyName);
|
|
9891
|
+
const storage = this.getStorage(strategyName, backtest);
|
|
9841
9892
|
await storage.dump(strategyName, path, columns);
|
|
9842
9893
|
};
|
|
9843
9894
|
/**
|
|
9844
9895
|
* Clears accumulated heatmap data from storage.
|
|
9845
|
-
* If
|
|
9846
|
-
* If
|
|
9896
|
+
* If ctx is provided, clears only that strategy+backtest combination's data.
|
|
9897
|
+
* If ctx is omitted, clears all data.
|
|
9847
9898
|
*
|
|
9848
|
-
* @param
|
|
9899
|
+
* @param backtest - Backtest mode flag
|
|
9900
|
+
* @param ctx - Optional context with strategyName to clear specific data
|
|
9849
9901
|
*
|
|
9850
9902
|
* @example
|
|
9851
9903
|
* ```typescript
|
|
9852
9904
|
* const service = new HeatMarkdownService();
|
|
9853
9905
|
*
|
|
9854
|
-
* // Clear specific strategy data
|
|
9855
|
-
* await service.clear("my-strategy");
|
|
9906
|
+
* // Clear specific strategy+backtest data
|
|
9907
|
+
* await service.clear(true, { strategyName: "my-strategy" });
|
|
9856
9908
|
*
|
|
9857
|
-
* // Clear all
|
|
9909
|
+
* // Clear all data
|
|
9858
9910
|
* await service.clear();
|
|
9859
9911
|
* ```
|
|
9860
9912
|
*/
|
|
9861
|
-
this.clear = async (
|
|
9913
|
+
this.clear = async (backtest, ctx) => {
|
|
9862
9914
|
this.loggerService.log(HEATMAP_METHOD_NAME_CLEAR, {
|
|
9863
|
-
|
|
9915
|
+
backtest,
|
|
9916
|
+
ctx,
|
|
9864
9917
|
});
|
|
9865
|
-
|
|
9918
|
+
if (ctx) {
|
|
9919
|
+
const key = `${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
9920
|
+
this.getStorage.clear(key);
|
|
9921
|
+
}
|
|
9922
|
+
else {
|
|
9923
|
+
this.getStorage.clear();
|
|
9924
|
+
}
|
|
9866
9925
|
};
|
|
9867
9926
|
/**
|
|
9868
9927
|
* Initializes the service by subscribing to signal events.
|
|
@@ -12431,10 +12490,10 @@ class PartialMarkdownService {
|
|
|
12431
12490
|
/** Logger service for debug output */
|
|
12432
12491
|
this.loggerService = inject(TYPES.loggerService);
|
|
12433
12492
|
/**
|
|
12434
|
-
* Memoized function to get or create ReportStorage for a symbol-strategy
|
|
12435
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
12493
|
+
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
12494
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
12436
12495
|
*/
|
|
12437
|
-
this.getStorage = memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new ReportStorage$1());
|
|
12496
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage$1());
|
|
12438
12497
|
/**
|
|
12439
12498
|
* Processes profit events and accumulates them.
|
|
12440
12499
|
* Should be called from partialProfitSubject subscription.
|
|
@@ -12451,7 +12510,7 @@ class PartialMarkdownService {
|
|
|
12451
12510
|
this.loggerService.log("partialMarkdownService tickProfit", {
|
|
12452
12511
|
data,
|
|
12453
12512
|
});
|
|
12454
|
-
const storage = this.getStorage(data.symbol, data.data.strategyName);
|
|
12513
|
+
const storage = this.getStorage(data.symbol, data.data.strategyName, data.backtest);
|
|
12455
12514
|
storage.addProfitEvent(data.data, data.currentPrice, data.level, data.backtest, data.timestamp);
|
|
12456
12515
|
};
|
|
12457
12516
|
/**
|
|
@@ -12470,7 +12529,7 @@ class PartialMarkdownService {
|
|
|
12470
12529
|
this.loggerService.log("partialMarkdownService tickLoss", {
|
|
12471
12530
|
data,
|
|
12472
12531
|
});
|
|
12473
|
-
const storage = this.getStorage(data.symbol, data.data.strategyName);
|
|
12532
|
+
const storage = this.getStorage(data.symbol, data.data.strategyName, data.backtest);
|
|
12474
12533
|
storage.addLossEvent(data.data, data.currentPrice, data.level, data.backtest, data.timestamp);
|
|
12475
12534
|
};
|
|
12476
12535
|
/**
|
|
@@ -12479,21 +12538,23 @@ class PartialMarkdownService {
|
|
|
12479
12538
|
*
|
|
12480
12539
|
* @param symbol - Trading pair symbol to get data for
|
|
12481
12540
|
* @param strategyName - Strategy name to get data for
|
|
12541
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
12482
12542
|
* @returns Statistical data object with all metrics
|
|
12483
12543
|
*
|
|
12484
12544
|
* @example
|
|
12485
12545
|
* ```typescript
|
|
12486
12546
|
* const service = new PartialMarkdownService();
|
|
12487
|
-
* const stats = await service.getData("BTCUSDT", "my-strategy");
|
|
12547
|
+
* const stats = await service.getData("BTCUSDT", "my-strategy", false);
|
|
12488
12548
|
* console.log(stats.totalProfit, stats.totalLoss);
|
|
12489
12549
|
* ```
|
|
12490
12550
|
*/
|
|
12491
|
-
this.getData = async (symbol, strategyName) => {
|
|
12551
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
12492
12552
|
this.loggerService.log("partialMarkdownService getData", {
|
|
12493
12553
|
symbol,
|
|
12494
12554
|
strategyName,
|
|
12555
|
+
backtest,
|
|
12495
12556
|
});
|
|
12496
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
12557
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
12497
12558
|
return storage.getData();
|
|
12498
12559
|
};
|
|
12499
12560
|
/**
|
|
@@ -12502,22 +12563,24 @@ class PartialMarkdownService {
|
|
|
12502
12563
|
*
|
|
12503
12564
|
* @param symbol - Trading pair symbol to generate report for
|
|
12504
12565
|
* @param strategyName - Strategy name to generate report for
|
|
12566
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
12505
12567
|
* @param columns - Column configuration for formatting the table
|
|
12506
12568
|
* @returns Markdown formatted report string with table of all events
|
|
12507
12569
|
*
|
|
12508
12570
|
* @example
|
|
12509
12571
|
* ```typescript
|
|
12510
12572
|
* const service = new PartialMarkdownService();
|
|
12511
|
-
* const markdown = await service.getReport("BTCUSDT", "my-strategy");
|
|
12573
|
+
* const markdown = await service.getReport("BTCUSDT", "my-strategy", false);
|
|
12512
12574
|
* console.log(markdown);
|
|
12513
12575
|
* ```
|
|
12514
12576
|
*/
|
|
12515
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.partial_columns) => {
|
|
12577
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.partial_columns) => {
|
|
12516
12578
|
this.loggerService.log("partialMarkdownService getReport", {
|
|
12517
12579
|
symbol,
|
|
12518
12580
|
strategyName,
|
|
12581
|
+
backtest,
|
|
12519
12582
|
});
|
|
12520
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
12583
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
12521
12584
|
return storage.getReport(symbol, strategyName, columns);
|
|
12522
12585
|
};
|
|
12523
12586
|
/**
|
|
@@ -12527,6 +12590,7 @@ class PartialMarkdownService {
|
|
|
12527
12590
|
*
|
|
12528
12591
|
* @param symbol - Trading pair symbol to save report for
|
|
12529
12592
|
* @param strategyName - Strategy name to save report for
|
|
12593
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
12530
12594
|
* @param path - Directory path to save report (default: "./dump/partial")
|
|
12531
12595
|
* @param columns - Column configuration for formatting the table
|
|
12532
12596
|
*
|
|
@@ -12535,45 +12599,48 @@ class PartialMarkdownService {
|
|
|
12535
12599
|
* const service = new PartialMarkdownService();
|
|
12536
12600
|
*
|
|
12537
12601
|
* // Save to default path: ./dump/partial/BTCUSDT_my-strategy.md
|
|
12538
|
-
* await service.dump("BTCUSDT", "my-strategy");
|
|
12602
|
+
* await service.dump("BTCUSDT", "my-strategy", false);
|
|
12539
12603
|
*
|
|
12540
12604
|
* // Save to custom path: ./custom/path/BTCUSDT_my-strategy.md
|
|
12541
|
-
* await service.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
12605
|
+
* await service.dump("BTCUSDT", "my-strategy", false, "./custom/path");
|
|
12542
12606
|
* ```
|
|
12543
12607
|
*/
|
|
12544
|
-
this.dump = async (symbol, strategyName, path = "./dump/partial", columns = COLUMN_CONFIG.partial_columns) => {
|
|
12608
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/partial", columns = COLUMN_CONFIG.partial_columns) => {
|
|
12545
12609
|
this.loggerService.log("partialMarkdownService dump", {
|
|
12546
12610
|
symbol,
|
|
12547
12611
|
strategyName,
|
|
12612
|
+
backtest,
|
|
12548
12613
|
path,
|
|
12549
12614
|
});
|
|
12550
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
12615
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
12551
12616
|
await storage.dump(symbol, strategyName, path, columns);
|
|
12552
12617
|
};
|
|
12553
12618
|
/**
|
|
12554
12619
|
* Clears accumulated event data from storage.
|
|
12555
|
-
* If ctx is provided, clears only that specific symbol-strategy
|
|
12620
|
+
* If ctx is provided, clears only that specific symbol-strategy-backtest triple's data.
|
|
12556
12621
|
* If nothing is provided, clears all data.
|
|
12557
12622
|
*
|
|
12623
|
+
* @param backtest - Backtest mode flag
|
|
12558
12624
|
* @param ctx - Optional context with symbol and strategyName
|
|
12559
12625
|
*
|
|
12560
12626
|
* @example
|
|
12561
12627
|
* ```typescript
|
|
12562
12628
|
* const service = new PartialMarkdownService();
|
|
12563
12629
|
*
|
|
12564
|
-
* // Clear specific symbol-strategy
|
|
12565
|
-
* await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
12630
|
+
* // Clear specific symbol-strategy-backtest triple
|
|
12631
|
+
* await service.clear(false, { symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
12566
12632
|
*
|
|
12567
12633
|
* // Clear all data
|
|
12568
12634
|
* await service.clear();
|
|
12569
12635
|
* ```
|
|
12570
12636
|
*/
|
|
12571
|
-
this.clear = async (ctx) => {
|
|
12637
|
+
this.clear = async (backtest, ctx) => {
|
|
12572
12638
|
this.loggerService.log("partialMarkdownService clear", {
|
|
12639
|
+
backtest,
|
|
12573
12640
|
ctx,
|
|
12574
12641
|
});
|
|
12575
12642
|
if (ctx) {
|
|
12576
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
12643
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
12577
12644
|
this.getStorage.clear(key);
|
|
12578
12645
|
}
|
|
12579
12646
|
else {
|
|
@@ -13149,10 +13216,10 @@ class RiskMarkdownService {
|
|
|
13149
13216
|
/** Logger service for debug output */
|
|
13150
13217
|
this.loggerService = inject(TYPES.loggerService);
|
|
13151
13218
|
/**
|
|
13152
|
-
* Memoized function to get or create ReportStorage for a symbol-strategy
|
|
13153
|
-
* Each symbol-strategy combination gets its own isolated storage instance.
|
|
13219
|
+
* Memoized function to get or create ReportStorage for a symbol-strategy-backtest triple.
|
|
13220
|
+
* Each symbol-strategy-backtest combination gets its own isolated storage instance.
|
|
13154
13221
|
*/
|
|
13155
|
-
this.getStorage = memoize(([symbol, strategyName]) => `${symbol}:${strategyName}`, () => new ReportStorage());
|
|
13222
|
+
this.getStorage = memoize(([symbol, strategyName, backtest]) => `${symbol}:${strategyName}:${backtest ? "backtest" : "live"}`, () => new ReportStorage());
|
|
13156
13223
|
/**
|
|
13157
13224
|
* Processes risk rejection events and accumulates them.
|
|
13158
13225
|
* Should be called from riskSubject subscription.
|
|
@@ -13169,7 +13236,7 @@ class RiskMarkdownService {
|
|
|
13169
13236
|
this.loggerService.log("riskMarkdownService tickRejection", {
|
|
13170
13237
|
data,
|
|
13171
13238
|
});
|
|
13172
|
-
const storage = this.getStorage(data.symbol, data.strategyName);
|
|
13239
|
+
const storage = this.getStorage(data.symbol, data.strategyName, data.backtest);
|
|
13173
13240
|
storage.addRejectionEvent(data);
|
|
13174
13241
|
};
|
|
13175
13242
|
/**
|
|
@@ -13178,21 +13245,23 @@ class RiskMarkdownService {
|
|
|
13178
13245
|
*
|
|
13179
13246
|
* @param symbol - Trading pair symbol to get data for
|
|
13180
13247
|
* @param strategyName - Strategy name to get data for
|
|
13248
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
13181
13249
|
* @returns Statistical data object with all metrics
|
|
13182
13250
|
*
|
|
13183
13251
|
* @example
|
|
13184
13252
|
* ```typescript
|
|
13185
13253
|
* const service = new RiskMarkdownService();
|
|
13186
|
-
* const stats = await service.getData("BTCUSDT", "my-strategy");
|
|
13254
|
+
* const stats = await service.getData("BTCUSDT", "my-strategy", false);
|
|
13187
13255
|
* console.log(stats.totalRejections, stats.bySymbol);
|
|
13188
13256
|
* ```
|
|
13189
13257
|
*/
|
|
13190
|
-
this.getData = async (symbol, strategyName) => {
|
|
13258
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
13191
13259
|
this.loggerService.log("riskMarkdownService getData", {
|
|
13192
13260
|
symbol,
|
|
13193
13261
|
strategyName,
|
|
13262
|
+
backtest,
|
|
13194
13263
|
});
|
|
13195
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
13264
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
13196
13265
|
return storage.getData();
|
|
13197
13266
|
};
|
|
13198
13267
|
/**
|
|
@@ -13201,22 +13270,24 @@ class RiskMarkdownService {
|
|
|
13201
13270
|
*
|
|
13202
13271
|
* @param symbol - Trading pair symbol to generate report for
|
|
13203
13272
|
* @param strategyName - Strategy name to generate report for
|
|
13273
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
13204
13274
|
* @param columns - Column configuration for formatting the table
|
|
13205
13275
|
* @returns Markdown formatted report string with table of all events
|
|
13206
13276
|
*
|
|
13207
13277
|
* @example
|
|
13208
13278
|
* ```typescript
|
|
13209
13279
|
* const service = new RiskMarkdownService();
|
|
13210
|
-
* const markdown = await service.getReport("BTCUSDT", "my-strategy");
|
|
13280
|
+
* const markdown = await service.getReport("BTCUSDT", "my-strategy", false);
|
|
13211
13281
|
* console.log(markdown);
|
|
13212
13282
|
* ```
|
|
13213
13283
|
*/
|
|
13214
|
-
this.getReport = async (symbol, strategyName, columns = COLUMN_CONFIG.risk_columns) => {
|
|
13284
|
+
this.getReport = async (symbol, strategyName, backtest, columns = COLUMN_CONFIG.risk_columns) => {
|
|
13215
13285
|
this.loggerService.log("riskMarkdownService getReport", {
|
|
13216
13286
|
symbol,
|
|
13217
13287
|
strategyName,
|
|
13288
|
+
backtest,
|
|
13218
13289
|
});
|
|
13219
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
13290
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
13220
13291
|
return storage.getReport(symbol, strategyName, columns);
|
|
13221
13292
|
};
|
|
13222
13293
|
/**
|
|
@@ -13226,6 +13297,7 @@ class RiskMarkdownService {
|
|
|
13226
13297
|
*
|
|
13227
13298
|
* @param symbol - Trading pair symbol to save report for
|
|
13228
13299
|
* @param strategyName - Strategy name to save report for
|
|
13300
|
+
* @param backtest - True if backtest mode, false if live mode
|
|
13229
13301
|
* @param path - Directory path to save report (default: "./dump/risk")
|
|
13230
13302
|
* @param columns - Column configuration for formatting the table
|
|
13231
13303
|
*
|
|
@@ -13234,45 +13306,48 @@ class RiskMarkdownService {
|
|
|
13234
13306
|
* const service = new RiskMarkdownService();
|
|
13235
13307
|
*
|
|
13236
13308
|
* // Save to default path: ./dump/risk/BTCUSDT_my-strategy.md
|
|
13237
|
-
* await service.dump("BTCUSDT", "my-strategy");
|
|
13309
|
+
* await service.dump("BTCUSDT", "my-strategy", false);
|
|
13238
13310
|
*
|
|
13239
13311
|
* // Save to custom path: ./custom/path/BTCUSDT_my-strategy.md
|
|
13240
|
-
* await service.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
13312
|
+
* await service.dump("BTCUSDT", "my-strategy", false, "./custom/path");
|
|
13241
13313
|
* ```
|
|
13242
13314
|
*/
|
|
13243
|
-
this.dump = async (symbol, strategyName, path = "./dump/risk", columns = COLUMN_CONFIG.risk_columns) => {
|
|
13315
|
+
this.dump = async (symbol, strategyName, backtest, path = "./dump/risk", columns = COLUMN_CONFIG.risk_columns) => {
|
|
13244
13316
|
this.loggerService.log("riskMarkdownService dump", {
|
|
13245
13317
|
symbol,
|
|
13246
13318
|
strategyName,
|
|
13319
|
+
backtest,
|
|
13247
13320
|
path,
|
|
13248
13321
|
});
|
|
13249
|
-
const storage = this.getStorage(symbol, strategyName);
|
|
13322
|
+
const storage = this.getStorage(symbol, strategyName, backtest);
|
|
13250
13323
|
await storage.dump(symbol, strategyName, path, columns);
|
|
13251
13324
|
};
|
|
13252
13325
|
/**
|
|
13253
13326
|
* Clears accumulated event data from storage.
|
|
13254
|
-
* If ctx is provided, clears only that specific symbol-strategy
|
|
13327
|
+
* If ctx is provided, clears only that specific symbol-strategy-backtest triple's data.
|
|
13255
13328
|
* If nothing is provided, clears all data.
|
|
13256
13329
|
*
|
|
13330
|
+
* @param backtest - Backtest mode flag
|
|
13257
13331
|
* @param ctx - Optional context with symbol and strategyName
|
|
13258
13332
|
*
|
|
13259
13333
|
* @example
|
|
13260
13334
|
* ```typescript
|
|
13261
13335
|
* const service = new RiskMarkdownService();
|
|
13262
13336
|
*
|
|
13263
|
-
* // Clear specific symbol-strategy
|
|
13264
|
-
* await service.clear({ symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
13337
|
+
* // Clear specific symbol-strategy-backtest triple
|
|
13338
|
+
* await service.clear(false, { symbol: "BTCUSDT", strategyName: "my-strategy" });
|
|
13265
13339
|
*
|
|
13266
13340
|
* // Clear all data
|
|
13267
13341
|
* await service.clear();
|
|
13268
13342
|
* ```
|
|
13269
13343
|
*/
|
|
13270
|
-
this.clear = async (ctx) => {
|
|
13344
|
+
this.clear = async (backtest, ctx) => {
|
|
13271
13345
|
this.loggerService.log("riskMarkdownService clear", {
|
|
13346
|
+
backtest,
|
|
13272
13347
|
ctx,
|
|
13273
13348
|
});
|
|
13274
13349
|
if (ctx) {
|
|
13275
|
-
const key = `${ctx.symbol}:${ctx.strategyName}`;
|
|
13350
|
+
const key = `${ctx.symbol}:${ctx.strategyName}:${backtest ? "backtest" : "live"}`;
|
|
13276
13351
|
this.getStorage.clear(key);
|
|
13277
13352
|
}
|
|
13278
13353
|
else {
|
|
@@ -13577,7 +13652,7 @@ const backtest = {
|
|
|
13577
13652
|
...templateServices,
|
|
13578
13653
|
};
|
|
13579
13654
|
init();
|
|
13580
|
-
var
|
|
13655
|
+
var bt = backtest;
|
|
13581
13656
|
|
|
13582
13657
|
/**
|
|
13583
13658
|
* Sets custom logger implementation for the framework.
|
|
@@ -13597,7 +13672,7 @@ var backtest$1 = backtest;
|
|
|
13597
13672
|
* ```
|
|
13598
13673
|
*/
|
|
13599
13674
|
function setLogger(logger) {
|
|
13600
|
-
|
|
13675
|
+
bt.loggerService.setLogger(logger);
|
|
13601
13676
|
}
|
|
13602
13677
|
/**
|
|
13603
13678
|
* Sets global configuration parameters for the framework.
|
|
@@ -13615,7 +13690,7 @@ function setConfig(config, _unsafe) {
|
|
|
13615
13690
|
const prevConfig = Object.assign({}, GLOBAL_CONFIG);
|
|
13616
13691
|
try {
|
|
13617
13692
|
Object.assign(GLOBAL_CONFIG, config);
|
|
13618
|
-
!_unsafe &&
|
|
13693
|
+
!_unsafe && bt.configValidationService.validate();
|
|
13619
13694
|
}
|
|
13620
13695
|
catch (error) {
|
|
13621
13696
|
console.warn(`backtest-kit setConfig failed: ${getErrorMessage(error)}`, config);
|
|
@@ -13686,7 +13761,7 @@ function setColumns(columns, _unsafe) {
|
|
|
13686
13761
|
const prevConfig = Object.assign({}, COLUMN_CONFIG);
|
|
13687
13762
|
try {
|
|
13688
13763
|
Object.assign(COLUMN_CONFIG, columns);
|
|
13689
|
-
!_unsafe &&
|
|
13764
|
+
!_unsafe && bt.columnValidationService.validate();
|
|
13690
13765
|
}
|
|
13691
13766
|
catch (error) {
|
|
13692
13767
|
console.warn(`backtest-kit setColumns failed: ${getErrorMessage(error)}`, columns);
|
|
@@ -13771,11 +13846,11 @@ const ADD_OPTIMIZER_METHOD_NAME = "add.addOptimizer";
|
|
|
13771
13846
|
* ```
|
|
13772
13847
|
*/
|
|
13773
13848
|
function addStrategy(strategySchema) {
|
|
13774
|
-
|
|
13849
|
+
bt.loggerService.info(ADD_STRATEGY_METHOD_NAME, {
|
|
13775
13850
|
strategySchema,
|
|
13776
13851
|
});
|
|
13777
|
-
|
|
13778
|
-
|
|
13852
|
+
bt.strategyValidationService.addStrategy(strategySchema.strategyName, strategySchema);
|
|
13853
|
+
bt.strategySchemaService.register(strategySchema.strategyName, strategySchema);
|
|
13779
13854
|
}
|
|
13780
13855
|
/**
|
|
13781
13856
|
* Registers an exchange data source in the framework.
|
|
@@ -13813,11 +13888,11 @@ function addStrategy(strategySchema) {
|
|
|
13813
13888
|
* ```
|
|
13814
13889
|
*/
|
|
13815
13890
|
function addExchange(exchangeSchema) {
|
|
13816
|
-
|
|
13891
|
+
bt.loggerService.info(ADD_EXCHANGE_METHOD_NAME, {
|
|
13817
13892
|
exchangeSchema,
|
|
13818
13893
|
});
|
|
13819
|
-
|
|
13820
|
-
|
|
13894
|
+
bt.exchangeValidationService.addExchange(exchangeSchema.exchangeName, exchangeSchema);
|
|
13895
|
+
bt.exchangeSchemaService.register(exchangeSchema.exchangeName, exchangeSchema);
|
|
13821
13896
|
}
|
|
13822
13897
|
/**
|
|
13823
13898
|
* Registers a timeframe generator for backtesting.
|
|
@@ -13850,11 +13925,11 @@ function addExchange(exchangeSchema) {
|
|
|
13850
13925
|
* ```
|
|
13851
13926
|
*/
|
|
13852
13927
|
function addFrame(frameSchema) {
|
|
13853
|
-
|
|
13928
|
+
bt.loggerService.info(ADD_FRAME_METHOD_NAME, {
|
|
13854
13929
|
frameSchema,
|
|
13855
13930
|
});
|
|
13856
|
-
|
|
13857
|
-
|
|
13931
|
+
bt.frameValidationService.addFrame(frameSchema.frameName, frameSchema);
|
|
13932
|
+
bt.frameSchemaService.register(frameSchema.frameName, frameSchema);
|
|
13858
13933
|
}
|
|
13859
13934
|
/**
|
|
13860
13935
|
* Registers a walker for strategy comparison.
|
|
@@ -13894,11 +13969,11 @@ function addFrame(frameSchema) {
|
|
|
13894
13969
|
* ```
|
|
13895
13970
|
*/
|
|
13896
13971
|
function addWalker(walkerSchema) {
|
|
13897
|
-
|
|
13972
|
+
bt.loggerService.info(ADD_WALKER_METHOD_NAME, {
|
|
13898
13973
|
walkerSchema,
|
|
13899
13974
|
});
|
|
13900
|
-
|
|
13901
|
-
|
|
13975
|
+
bt.walkerValidationService.addWalker(walkerSchema.walkerName, walkerSchema);
|
|
13976
|
+
bt.walkerSchemaService.register(walkerSchema.walkerName, walkerSchema);
|
|
13902
13977
|
}
|
|
13903
13978
|
/**
|
|
13904
13979
|
* Registers a position sizing configuration in the framework.
|
|
@@ -13953,11 +14028,11 @@ function addWalker(walkerSchema) {
|
|
|
13953
14028
|
* ```
|
|
13954
14029
|
*/
|
|
13955
14030
|
function addSizing(sizingSchema) {
|
|
13956
|
-
|
|
14031
|
+
bt.loggerService.info(ADD_SIZING_METHOD_NAME, {
|
|
13957
14032
|
sizingSchema,
|
|
13958
14033
|
});
|
|
13959
|
-
|
|
13960
|
-
|
|
14034
|
+
bt.sizingValidationService.addSizing(sizingSchema.sizingName, sizingSchema);
|
|
14035
|
+
bt.sizingSchemaService.register(sizingSchema.sizingName, sizingSchema);
|
|
13961
14036
|
}
|
|
13962
14037
|
/**
|
|
13963
14038
|
* Registers a risk management configuration in the framework.
|
|
@@ -14021,11 +14096,11 @@ function addSizing(sizingSchema) {
|
|
|
14021
14096
|
* ```
|
|
14022
14097
|
*/
|
|
14023
14098
|
function addRisk(riskSchema) {
|
|
14024
|
-
|
|
14099
|
+
bt.loggerService.info(ADD_RISK_METHOD_NAME, {
|
|
14025
14100
|
riskSchema,
|
|
14026
14101
|
});
|
|
14027
|
-
|
|
14028
|
-
|
|
14102
|
+
bt.riskValidationService.addRisk(riskSchema.riskName, riskSchema);
|
|
14103
|
+
bt.riskSchemaService.register(riskSchema.riskName, riskSchema);
|
|
14029
14104
|
}
|
|
14030
14105
|
/**
|
|
14031
14106
|
* Registers an optimizer configuration in the framework.
|
|
@@ -14115,11 +14190,11 @@ function addRisk(riskSchema) {
|
|
|
14115
14190
|
* ```
|
|
14116
14191
|
*/
|
|
14117
14192
|
function addOptimizer(optimizerSchema) {
|
|
14118
|
-
|
|
14193
|
+
bt.loggerService.info(ADD_OPTIMIZER_METHOD_NAME, {
|
|
14119
14194
|
optimizerSchema,
|
|
14120
14195
|
});
|
|
14121
|
-
|
|
14122
|
-
|
|
14196
|
+
bt.optimizerValidationService.addOptimizer(optimizerSchema.optimizerName, optimizerSchema);
|
|
14197
|
+
bt.optimizerSchemaService.register(optimizerSchema.optimizerName, optimizerSchema);
|
|
14123
14198
|
}
|
|
14124
14199
|
|
|
14125
14200
|
const LIST_EXCHANGES_METHOD_NAME = "list.listExchanges";
|
|
@@ -14155,8 +14230,8 @@ const LIST_OPTIMIZERS_METHOD_NAME = "list.listOptimizers";
|
|
|
14155
14230
|
* ```
|
|
14156
14231
|
*/
|
|
14157
14232
|
async function listExchanges() {
|
|
14158
|
-
|
|
14159
|
-
return await
|
|
14233
|
+
bt.loggerService.log(LIST_EXCHANGES_METHOD_NAME);
|
|
14234
|
+
return await bt.exchangeValidationService.list();
|
|
14160
14235
|
}
|
|
14161
14236
|
/**
|
|
14162
14237
|
* Returns a list of all registered strategy schemas.
|
|
@@ -14189,8 +14264,8 @@ async function listExchanges() {
|
|
|
14189
14264
|
* ```
|
|
14190
14265
|
*/
|
|
14191
14266
|
async function listStrategies() {
|
|
14192
|
-
|
|
14193
|
-
return await
|
|
14267
|
+
bt.loggerService.log(LIST_STRATEGIES_METHOD_NAME);
|
|
14268
|
+
return await bt.strategyValidationService.list();
|
|
14194
14269
|
}
|
|
14195
14270
|
/**
|
|
14196
14271
|
* Returns a list of all registered frame schemas.
|
|
@@ -14218,8 +14293,8 @@ async function listStrategies() {
|
|
|
14218
14293
|
* ```
|
|
14219
14294
|
*/
|
|
14220
14295
|
async function listFrames() {
|
|
14221
|
-
|
|
14222
|
-
return await
|
|
14296
|
+
bt.loggerService.log(LIST_FRAMES_METHOD_NAME);
|
|
14297
|
+
return await bt.frameValidationService.list();
|
|
14223
14298
|
}
|
|
14224
14299
|
/**
|
|
14225
14300
|
* Returns a list of all registered walker schemas.
|
|
@@ -14248,8 +14323,8 @@ async function listFrames() {
|
|
|
14248
14323
|
* ```
|
|
14249
14324
|
*/
|
|
14250
14325
|
async function listWalkers() {
|
|
14251
|
-
|
|
14252
|
-
return await
|
|
14326
|
+
bt.loggerService.log(LIST_WALKERS_METHOD_NAME);
|
|
14327
|
+
return await bt.walkerValidationService.list();
|
|
14253
14328
|
}
|
|
14254
14329
|
/**
|
|
14255
14330
|
* Returns a list of all registered sizing schemas.
|
|
@@ -14287,8 +14362,8 @@ async function listWalkers() {
|
|
|
14287
14362
|
* ```
|
|
14288
14363
|
*/
|
|
14289
14364
|
async function listSizings() {
|
|
14290
|
-
|
|
14291
|
-
return await
|
|
14365
|
+
bt.loggerService.log(LIST_SIZINGS_METHOD_NAME);
|
|
14366
|
+
return await bt.sizingValidationService.list();
|
|
14292
14367
|
}
|
|
14293
14368
|
/**
|
|
14294
14369
|
* Returns a list of all registered risk schemas.
|
|
@@ -14323,8 +14398,8 @@ async function listSizings() {
|
|
|
14323
14398
|
* ```
|
|
14324
14399
|
*/
|
|
14325
14400
|
async function listRisks() {
|
|
14326
|
-
|
|
14327
|
-
return await
|
|
14401
|
+
bt.loggerService.log(LIST_RISKS_METHOD_NAME);
|
|
14402
|
+
return await bt.riskValidationService.list();
|
|
14328
14403
|
}
|
|
14329
14404
|
/**
|
|
14330
14405
|
* Returns a list of all registered optimizer schemas.
|
|
@@ -14363,8 +14438,8 @@ async function listRisks() {
|
|
|
14363
14438
|
* ```
|
|
14364
14439
|
*/
|
|
14365
14440
|
async function listOptimizers() {
|
|
14366
|
-
|
|
14367
|
-
return await
|
|
14441
|
+
bt.loggerService.log(LIST_OPTIMIZERS_METHOD_NAME);
|
|
14442
|
+
return await bt.optimizerValidationService.list();
|
|
14368
14443
|
}
|
|
14369
14444
|
|
|
14370
14445
|
const LISTEN_SIGNAL_METHOD_NAME = "event.listenSignal";
|
|
@@ -14421,7 +14496,7 @@ const LISTEN_RISK_ONCE_METHOD_NAME = "event.listenRiskOnce";
|
|
|
14421
14496
|
* ```
|
|
14422
14497
|
*/
|
|
14423
14498
|
function listenSignal(fn) {
|
|
14424
|
-
|
|
14499
|
+
bt.loggerService.log(LISTEN_SIGNAL_METHOD_NAME);
|
|
14425
14500
|
return signalEmitter.subscribe(queued(async (event) => fn(event)));
|
|
14426
14501
|
}
|
|
14427
14502
|
/**
|
|
@@ -14457,7 +14532,7 @@ function listenSignal(fn) {
|
|
|
14457
14532
|
* ```
|
|
14458
14533
|
*/
|
|
14459
14534
|
function listenSignalOnce(filterFn, fn) {
|
|
14460
|
-
|
|
14535
|
+
bt.loggerService.log(LISTEN_SIGNAL_ONCE_METHOD_NAME);
|
|
14461
14536
|
return signalEmitter.filter(filterFn).once(fn);
|
|
14462
14537
|
}
|
|
14463
14538
|
/**
|
|
@@ -14481,7 +14556,7 @@ function listenSignalOnce(filterFn, fn) {
|
|
|
14481
14556
|
* ```
|
|
14482
14557
|
*/
|
|
14483
14558
|
function listenSignalLive(fn) {
|
|
14484
|
-
|
|
14559
|
+
bt.loggerService.log(LISTEN_SIGNAL_LIVE_METHOD_NAME);
|
|
14485
14560
|
return signalLiveEmitter.subscribe(queued(async (event) => fn(event)));
|
|
14486
14561
|
}
|
|
14487
14562
|
/**
|
|
@@ -14506,7 +14581,7 @@ function listenSignalLive(fn) {
|
|
|
14506
14581
|
* ```
|
|
14507
14582
|
*/
|
|
14508
14583
|
function listenSignalLiveOnce(filterFn, fn) {
|
|
14509
|
-
|
|
14584
|
+
bt.loggerService.log(LISTEN_SIGNAL_LIVE_ONCE_METHOD_NAME);
|
|
14510
14585
|
return signalLiveEmitter.filter(filterFn).once(fn);
|
|
14511
14586
|
}
|
|
14512
14587
|
/**
|
|
@@ -14530,7 +14605,7 @@ function listenSignalLiveOnce(filterFn, fn) {
|
|
|
14530
14605
|
* ```
|
|
14531
14606
|
*/
|
|
14532
14607
|
function listenSignalBacktest(fn) {
|
|
14533
|
-
|
|
14608
|
+
bt.loggerService.log(LISTEN_SIGNAL_BACKTEST_METHOD_NAME);
|
|
14534
14609
|
return signalBacktestEmitter.subscribe(queued(async (event) => fn(event)));
|
|
14535
14610
|
}
|
|
14536
14611
|
/**
|
|
@@ -14555,7 +14630,7 @@ function listenSignalBacktest(fn) {
|
|
|
14555
14630
|
* ```
|
|
14556
14631
|
*/
|
|
14557
14632
|
function listenSignalBacktestOnce(filterFn, fn) {
|
|
14558
|
-
|
|
14633
|
+
bt.loggerService.log(LISTEN_SIGNAL_BACKTEST_ONCE_METHOD_NAME);
|
|
14559
14634
|
return signalBacktestEmitter.filter(filterFn).once(fn);
|
|
14560
14635
|
}
|
|
14561
14636
|
/**
|
|
@@ -14583,7 +14658,7 @@ function listenSignalBacktestOnce(filterFn, fn) {
|
|
|
14583
14658
|
* ```
|
|
14584
14659
|
*/
|
|
14585
14660
|
function listenError(fn) {
|
|
14586
|
-
|
|
14661
|
+
bt.loggerService.log(LISTEN_ERROR_METHOD_NAME);
|
|
14587
14662
|
return errorEmitter.subscribe(queued(async (error) => fn(error)));
|
|
14588
14663
|
}
|
|
14589
14664
|
/**
|
|
@@ -14611,7 +14686,7 @@ function listenError(fn) {
|
|
|
14611
14686
|
* ```
|
|
14612
14687
|
*/
|
|
14613
14688
|
function listenExit(fn) {
|
|
14614
|
-
|
|
14689
|
+
bt.loggerService.log(LISTEN_EXIT_METHOD_NAME);
|
|
14615
14690
|
return exitEmitter.subscribe(queued(async (error) => fn(error)));
|
|
14616
14691
|
}
|
|
14617
14692
|
/**
|
|
@@ -14642,7 +14717,7 @@ function listenExit(fn) {
|
|
|
14642
14717
|
* ```
|
|
14643
14718
|
*/
|
|
14644
14719
|
function listenDoneLive(fn) {
|
|
14645
|
-
|
|
14720
|
+
bt.loggerService.log(LISTEN_DONE_LIVE_METHOD_NAME);
|
|
14646
14721
|
return doneLiveSubject.subscribe(queued(async (event) => fn(event)));
|
|
14647
14722
|
}
|
|
14648
14723
|
/**
|
|
@@ -14672,7 +14747,7 @@ function listenDoneLive(fn) {
|
|
|
14672
14747
|
* ```
|
|
14673
14748
|
*/
|
|
14674
14749
|
function listenDoneLiveOnce(filterFn, fn) {
|
|
14675
|
-
|
|
14750
|
+
bt.loggerService.log(LISTEN_DONE_LIVE_ONCE_METHOD_NAME);
|
|
14676
14751
|
return doneLiveSubject.filter(filterFn).once(fn);
|
|
14677
14752
|
}
|
|
14678
14753
|
/**
|
|
@@ -14704,7 +14779,7 @@ function listenDoneLiveOnce(filterFn, fn) {
|
|
|
14704
14779
|
* ```
|
|
14705
14780
|
*/
|
|
14706
14781
|
function listenDoneBacktest(fn) {
|
|
14707
|
-
|
|
14782
|
+
bt.loggerService.log(LISTEN_DONE_BACKTEST_METHOD_NAME);
|
|
14708
14783
|
return doneBacktestSubject.subscribe(queued(async (event) => fn(event)));
|
|
14709
14784
|
}
|
|
14710
14785
|
/**
|
|
@@ -14735,7 +14810,7 @@ function listenDoneBacktest(fn) {
|
|
|
14735
14810
|
* ```
|
|
14736
14811
|
*/
|
|
14737
14812
|
function listenDoneBacktestOnce(filterFn, fn) {
|
|
14738
|
-
|
|
14813
|
+
bt.loggerService.log(LISTEN_DONE_BACKTEST_ONCE_METHOD_NAME);
|
|
14739
14814
|
return doneBacktestSubject.filter(filterFn).once(fn);
|
|
14740
14815
|
}
|
|
14741
14816
|
/**
|
|
@@ -14765,7 +14840,7 @@ function listenDoneBacktestOnce(filterFn, fn) {
|
|
|
14765
14840
|
* ```
|
|
14766
14841
|
*/
|
|
14767
14842
|
function listenDoneWalker(fn) {
|
|
14768
|
-
|
|
14843
|
+
bt.loggerService.log(LISTEN_DONE_WALKER_METHOD_NAME);
|
|
14769
14844
|
return doneWalkerSubject.subscribe(queued(async (event) => fn(event)));
|
|
14770
14845
|
}
|
|
14771
14846
|
/**
|
|
@@ -14794,7 +14869,7 @@ function listenDoneWalker(fn) {
|
|
|
14794
14869
|
* ```
|
|
14795
14870
|
*/
|
|
14796
14871
|
function listenDoneWalkerOnce(filterFn, fn) {
|
|
14797
|
-
|
|
14872
|
+
bt.loggerService.log(LISTEN_DONE_WALKER_ONCE_METHOD_NAME);
|
|
14798
14873
|
return doneWalkerSubject.filter(filterFn).once(fn);
|
|
14799
14874
|
}
|
|
14800
14875
|
/**
|
|
@@ -14828,7 +14903,7 @@ function listenDoneWalkerOnce(filterFn, fn) {
|
|
|
14828
14903
|
* ```
|
|
14829
14904
|
*/
|
|
14830
14905
|
function listenBacktestProgress(fn) {
|
|
14831
|
-
|
|
14906
|
+
bt.loggerService.log(LISTEN_PROGRESS_METHOD_NAME);
|
|
14832
14907
|
return progressBacktestEmitter.subscribe(queued(async (event) => fn(event)));
|
|
14833
14908
|
}
|
|
14834
14909
|
/**
|
|
@@ -14862,7 +14937,7 @@ function listenBacktestProgress(fn) {
|
|
|
14862
14937
|
* ```
|
|
14863
14938
|
*/
|
|
14864
14939
|
function listenWalkerProgress(fn) {
|
|
14865
|
-
|
|
14940
|
+
bt.loggerService.log(LISTEN_PROGRESS_WALKER_METHOD_NAME);
|
|
14866
14941
|
return progressWalkerEmitter.subscribe(queued(async (event) => fn(event)));
|
|
14867
14942
|
}
|
|
14868
14943
|
/**
|
|
@@ -14890,7 +14965,7 @@ function listenWalkerProgress(fn) {
|
|
|
14890
14965
|
* ```
|
|
14891
14966
|
*/
|
|
14892
14967
|
function listenOptimizerProgress(fn) {
|
|
14893
|
-
|
|
14968
|
+
bt.loggerService.log(LISTEN_PROGRESS_OPTIMIZER_METHOD_NAME);
|
|
14894
14969
|
return progressOptimizerEmitter.subscribe(queued(async (event) => fn(event)));
|
|
14895
14970
|
}
|
|
14896
14971
|
/**
|
|
@@ -14926,7 +15001,7 @@ function listenOptimizerProgress(fn) {
|
|
|
14926
15001
|
* ```
|
|
14927
15002
|
*/
|
|
14928
15003
|
function listenPerformance(fn) {
|
|
14929
|
-
|
|
15004
|
+
bt.loggerService.log(LISTEN_PERFORMANCE_METHOD_NAME);
|
|
14930
15005
|
return performanceEmitter.subscribe(queued(async (event) => fn(event)));
|
|
14931
15006
|
}
|
|
14932
15007
|
/**
|
|
@@ -14960,7 +15035,7 @@ function listenPerformance(fn) {
|
|
|
14960
15035
|
* ```
|
|
14961
15036
|
*/
|
|
14962
15037
|
function listenWalker(fn) {
|
|
14963
|
-
|
|
15038
|
+
bt.loggerService.log(LISTEN_WALKER_METHOD_NAME);
|
|
14964
15039
|
return walkerEmitter.subscribe(queued(async (event) => fn(event)));
|
|
14965
15040
|
}
|
|
14966
15041
|
/**
|
|
@@ -15003,7 +15078,7 @@ function listenWalker(fn) {
|
|
|
15003
15078
|
* ```
|
|
15004
15079
|
*/
|
|
15005
15080
|
function listenWalkerOnce(filterFn, fn) {
|
|
15006
|
-
|
|
15081
|
+
bt.loggerService.log(LISTEN_WALKER_ONCE_METHOD_NAME);
|
|
15007
15082
|
return walkerEmitter.filter(filterFn).once(fn);
|
|
15008
15083
|
}
|
|
15009
15084
|
/**
|
|
@@ -15038,7 +15113,7 @@ function listenWalkerOnce(filterFn, fn) {
|
|
|
15038
15113
|
* ```
|
|
15039
15114
|
*/
|
|
15040
15115
|
function listenWalkerComplete(fn) {
|
|
15041
|
-
|
|
15116
|
+
bt.loggerService.log(LISTEN_WALKER_COMPLETE_METHOD_NAME);
|
|
15042
15117
|
return walkerCompleteSubject.subscribe(queued(async (event) => fn(event)));
|
|
15043
15118
|
}
|
|
15044
15119
|
/**
|
|
@@ -15066,7 +15141,7 @@ function listenWalkerComplete(fn) {
|
|
|
15066
15141
|
* ```
|
|
15067
15142
|
*/
|
|
15068
15143
|
function listenValidation(fn) {
|
|
15069
|
-
|
|
15144
|
+
bt.loggerService.log(LISTEN_VALIDATION_METHOD_NAME);
|
|
15070
15145
|
return validationSubject.subscribe(queued(async (error) => fn(error)));
|
|
15071
15146
|
}
|
|
15072
15147
|
/**
|
|
@@ -15094,7 +15169,7 @@ function listenValidation(fn) {
|
|
|
15094
15169
|
* ```
|
|
15095
15170
|
*/
|
|
15096
15171
|
function listenPartialProfit(fn) {
|
|
15097
|
-
|
|
15172
|
+
bt.loggerService.log(LISTEN_PARTIAL_PROFIT_METHOD_NAME);
|
|
15098
15173
|
return partialProfitSubject.subscribe(queued(async (event) => fn(event)));
|
|
15099
15174
|
}
|
|
15100
15175
|
/**
|
|
@@ -15128,7 +15203,7 @@ function listenPartialProfit(fn) {
|
|
|
15128
15203
|
* ```
|
|
15129
15204
|
*/
|
|
15130
15205
|
function listenPartialProfitOnce(filterFn, fn) {
|
|
15131
|
-
|
|
15206
|
+
bt.loggerService.log(LISTEN_PARTIAL_PROFIT_ONCE_METHOD_NAME);
|
|
15132
15207
|
return partialProfitSubject.filter(filterFn).once(fn);
|
|
15133
15208
|
}
|
|
15134
15209
|
/**
|
|
@@ -15156,7 +15231,7 @@ function listenPartialProfitOnce(filterFn, fn) {
|
|
|
15156
15231
|
* ```
|
|
15157
15232
|
*/
|
|
15158
15233
|
function listenPartialLoss(fn) {
|
|
15159
|
-
|
|
15234
|
+
bt.loggerService.log(LISTEN_PARTIAL_LOSS_METHOD_NAME);
|
|
15160
15235
|
return partialLossSubject.subscribe(queued(async (event) => fn(event)));
|
|
15161
15236
|
}
|
|
15162
15237
|
/**
|
|
@@ -15190,7 +15265,7 @@ function listenPartialLoss(fn) {
|
|
|
15190
15265
|
* ```
|
|
15191
15266
|
*/
|
|
15192
15267
|
function listenPartialLossOnce(filterFn, fn) {
|
|
15193
|
-
|
|
15268
|
+
bt.loggerService.log(LISTEN_PARTIAL_LOSS_ONCE_METHOD_NAME);
|
|
15194
15269
|
return partialLossSubject.filter(filterFn).once(fn);
|
|
15195
15270
|
}
|
|
15196
15271
|
/**
|
|
@@ -15222,7 +15297,7 @@ function listenPartialLossOnce(filterFn, fn) {
|
|
|
15222
15297
|
* ```
|
|
15223
15298
|
*/
|
|
15224
15299
|
function listenRisk(fn) {
|
|
15225
|
-
|
|
15300
|
+
bt.loggerService.log(LISTEN_RISK_METHOD_NAME);
|
|
15226
15301
|
return riskSubject.subscribe(queued(async (event) => fn(event)));
|
|
15227
15302
|
}
|
|
15228
15303
|
/**
|
|
@@ -15259,7 +15334,7 @@ function listenRisk(fn) {
|
|
|
15259
15334
|
* ```
|
|
15260
15335
|
*/
|
|
15261
15336
|
function listenRiskOnce(filterFn, fn) {
|
|
15262
|
-
|
|
15337
|
+
bt.loggerService.log(LISTEN_RISK_ONCE_METHOD_NAME);
|
|
15263
15338
|
return riskSubject.filter(filterFn).once(fn);
|
|
15264
15339
|
}
|
|
15265
15340
|
|
|
@@ -15287,12 +15362,12 @@ const GET_MODE_METHOD_NAME = "exchange.getMode";
|
|
|
15287
15362
|
* ```
|
|
15288
15363
|
*/
|
|
15289
15364
|
async function getCandles(symbol, interval, limit) {
|
|
15290
|
-
|
|
15365
|
+
bt.loggerService.info(GET_CANDLES_METHOD_NAME, {
|
|
15291
15366
|
symbol,
|
|
15292
15367
|
interval,
|
|
15293
15368
|
limit,
|
|
15294
15369
|
});
|
|
15295
|
-
return await
|
|
15370
|
+
return await bt.exchangeConnectionService.getCandles(symbol, interval, limit);
|
|
15296
15371
|
}
|
|
15297
15372
|
/**
|
|
15298
15373
|
* Calculates VWAP (Volume Weighted Average Price) for a symbol.
|
|
@@ -15313,10 +15388,10 @@ async function getCandles(symbol, interval, limit) {
|
|
|
15313
15388
|
* ```
|
|
15314
15389
|
*/
|
|
15315
15390
|
async function getAveragePrice(symbol) {
|
|
15316
|
-
|
|
15391
|
+
bt.loggerService.info(GET_AVERAGE_PRICE_METHOD_NAME, {
|
|
15317
15392
|
symbol,
|
|
15318
15393
|
});
|
|
15319
|
-
return await
|
|
15394
|
+
return await bt.exchangeConnectionService.getAveragePrice(symbol);
|
|
15320
15395
|
}
|
|
15321
15396
|
/**
|
|
15322
15397
|
* Formats a price value according to exchange rules.
|
|
@@ -15334,11 +15409,11 @@ async function getAveragePrice(symbol) {
|
|
|
15334
15409
|
* ```
|
|
15335
15410
|
*/
|
|
15336
15411
|
async function formatPrice(symbol, price) {
|
|
15337
|
-
|
|
15412
|
+
bt.loggerService.info(FORMAT_PRICE_METHOD_NAME, {
|
|
15338
15413
|
symbol,
|
|
15339
15414
|
price,
|
|
15340
15415
|
});
|
|
15341
|
-
return await
|
|
15416
|
+
return await bt.exchangeConnectionService.formatPrice(symbol, price);
|
|
15342
15417
|
}
|
|
15343
15418
|
/**
|
|
15344
15419
|
* Formats a quantity value according to exchange rules.
|
|
@@ -15356,11 +15431,11 @@ async function formatPrice(symbol, price) {
|
|
|
15356
15431
|
* ```
|
|
15357
15432
|
*/
|
|
15358
15433
|
async function formatQuantity(symbol, quantity) {
|
|
15359
|
-
|
|
15434
|
+
bt.loggerService.info(FORMAT_QUANTITY_METHOD_NAME, {
|
|
15360
15435
|
symbol,
|
|
15361
15436
|
quantity,
|
|
15362
15437
|
});
|
|
15363
|
-
return await
|
|
15438
|
+
return await bt.exchangeConnectionService.formatQuantity(symbol, quantity);
|
|
15364
15439
|
}
|
|
15365
15440
|
/**
|
|
15366
15441
|
* Gets the current date from execution context.
|
|
@@ -15377,8 +15452,8 @@ async function formatQuantity(symbol, quantity) {
|
|
|
15377
15452
|
* ```
|
|
15378
15453
|
*/
|
|
15379
15454
|
async function getDate() {
|
|
15380
|
-
|
|
15381
|
-
const { when } =
|
|
15455
|
+
bt.loggerService.info(GET_DATE_METHOD_NAME);
|
|
15456
|
+
const { when } = bt.executionContextService.context;
|
|
15382
15457
|
return new Date(when.getTime());
|
|
15383
15458
|
}
|
|
15384
15459
|
/**
|
|
@@ -15397,9 +15472,9 @@ async function getDate() {
|
|
|
15397
15472
|
* ```
|
|
15398
15473
|
*/
|
|
15399
15474
|
async function getMode() {
|
|
15400
|
-
|
|
15401
|
-
const { backtest: bt } =
|
|
15402
|
-
return bt ? "backtest" : "live";
|
|
15475
|
+
bt.loggerService.info(GET_MODE_METHOD_NAME);
|
|
15476
|
+
const { backtest: bt$1 } = bt.executionContextService.context;
|
|
15477
|
+
return bt$1 ? "backtest" : "live";
|
|
15403
15478
|
}
|
|
15404
15479
|
|
|
15405
15480
|
const DUMP_SIGNAL_METHOD_NAME = "dump.dumpSignal";
|
|
@@ -15470,13 +15545,13 @@ const DUMP_SIGNAL_METHOD_NAME = "dump.dumpSignal";
|
|
|
15470
15545
|
* ```
|
|
15471
15546
|
*/
|
|
15472
15547
|
async function dumpSignal(signalId, history, signal, outputDir = "./dump/strategy") {
|
|
15473
|
-
|
|
15548
|
+
bt.loggerService.info(DUMP_SIGNAL_METHOD_NAME, {
|
|
15474
15549
|
signalId,
|
|
15475
15550
|
history,
|
|
15476
15551
|
signal,
|
|
15477
15552
|
outputDir,
|
|
15478
15553
|
});
|
|
15479
|
-
return await
|
|
15554
|
+
return await bt.outlineMarkdownService.dumpSignal(signalId, history, signal, outputDir);
|
|
15480
15555
|
}
|
|
15481
15556
|
|
|
15482
15557
|
const BACKTEST_METHOD_NAME_RUN = "BacktestUtils.run";
|
|
@@ -15563,7 +15638,7 @@ class BacktestInstance {
|
|
|
15563
15638
|
* @internal
|
|
15564
15639
|
*/
|
|
15565
15640
|
this.task = singlerun(async (symbol, context) => {
|
|
15566
|
-
|
|
15641
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_TASK, {
|
|
15567
15642
|
symbol,
|
|
15568
15643
|
context,
|
|
15569
15644
|
});
|
|
@@ -15582,7 +15657,7 @@ class BacktestInstance {
|
|
|
15582
15657
|
* ```
|
|
15583
15658
|
*/
|
|
15584
15659
|
this.getStatus = async () => {
|
|
15585
|
-
|
|
15660
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_GET_STATUS);
|
|
15586
15661
|
return {
|
|
15587
15662
|
id: this.id,
|
|
15588
15663
|
symbol: this.symbol,
|
|
@@ -15598,23 +15673,27 @@ class BacktestInstance {
|
|
|
15598
15673
|
* @returns Async generator yielding closed signals with PNL
|
|
15599
15674
|
*/
|
|
15600
15675
|
this.run = (symbol, context) => {
|
|
15601
|
-
|
|
15676
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_RUN, {
|
|
15602
15677
|
symbol,
|
|
15603
15678
|
context,
|
|
15604
15679
|
});
|
|
15605
15680
|
{
|
|
15606
|
-
|
|
15607
|
-
|
|
15681
|
+
bt.backtestMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15682
|
+
bt.liveMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15683
|
+
bt.scheduleMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15684
|
+
bt.performanceMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15685
|
+
bt.partialMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15686
|
+
bt.riskMarkdownService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15608
15687
|
}
|
|
15609
15688
|
{
|
|
15610
|
-
|
|
15689
|
+
bt.strategyCoreService.clear(true, { symbol, strategyName: context.strategyName });
|
|
15611
15690
|
}
|
|
15612
15691
|
{
|
|
15613
|
-
const { riskName, riskList } =
|
|
15614
|
-
riskName &&
|
|
15615
|
-
riskList && riskList.forEach((riskName) =>
|
|
15692
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
15693
|
+
riskName && bt.riskGlobalService.clear(true, riskName);
|
|
15694
|
+
riskList && riskList.forEach((riskName) => bt.riskGlobalService.clear(true, riskName));
|
|
15616
15695
|
}
|
|
15617
|
-
return
|
|
15696
|
+
return bt.backtestCommandService.run(symbol, context);
|
|
15618
15697
|
};
|
|
15619
15698
|
/**
|
|
15620
15699
|
* Runs backtest in background without yielding results.
|
|
@@ -15637,14 +15716,23 @@ class BacktestInstance {
|
|
|
15637
15716
|
* ```
|
|
15638
15717
|
*/
|
|
15639
15718
|
this.background = (symbol, context) => {
|
|
15640
|
-
|
|
15719
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_BACKGROUND, {
|
|
15641
15720
|
symbol,
|
|
15642
15721
|
context,
|
|
15643
15722
|
});
|
|
15723
|
+
{
|
|
15724
|
+
const currentStatus = this.task.getStatus();
|
|
15725
|
+
if (currentStatus === "pending") {
|
|
15726
|
+
throw new Error(`Backtest.background is already running for symbol=${symbol} strategyName=${context.strategyName} exchangeName=${context.exchangeName} frameName=${context.frameName}`);
|
|
15727
|
+
}
|
|
15728
|
+
if (currentStatus === "rejected") {
|
|
15729
|
+
throw new Error(`Backtest.background has failed for symbol=${symbol} strategyName=${context.strategyName} exchangeName=${context.exchangeName} frameName=${context.frameName}`);
|
|
15730
|
+
}
|
|
15731
|
+
}
|
|
15644
15732
|
this.task(symbol, context).catch((error) => exitEmitter.next(new Error(getErrorMessage(error))));
|
|
15645
15733
|
return () => {
|
|
15646
|
-
|
|
15647
|
-
|
|
15734
|
+
bt.strategyCoreService.stop(true, { symbol, strategyName: context.strategyName });
|
|
15735
|
+
bt.strategyCoreService
|
|
15648
15736
|
.getPendingSignal(true, symbol, context.strategyName)
|
|
15649
15737
|
.then(async (pendingSignal) => {
|
|
15650
15738
|
if (pendingSignal) {
|
|
@@ -15681,11 +15769,11 @@ class BacktestInstance {
|
|
|
15681
15769
|
* ```
|
|
15682
15770
|
*/
|
|
15683
15771
|
this.stop = async (symbol, strategyName) => {
|
|
15684
|
-
|
|
15772
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_STOP, {
|
|
15685
15773
|
symbol,
|
|
15686
15774
|
strategyName,
|
|
15687
15775
|
});
|
|
15688
|
-
await
|
|
15776
|
+
await bt.strategyCoreService.stop(true, { symbol, strategyName });
|
|
15689
15777
|
};
|
|
15690
15778
|
/**
|
|
15691
15779
|
* Gets statistical data from all closed signals for a symbol-strategy pair.
|
|
@@ -15702,11 +15790,11 @@ class BacktestInstance {
|
|
|
15702
15790
|
* ```
|
|
15703
15791
|
*/
|
|
15704
15792
|
this.getData = async (symbol, strategyName) => {
|
|
15705
|
-
|
|
15793
|
+
bt.loggerService.info("BacktestUtils.getData", {
|
|
15706
15794
|
symbol,
|
|
15707
15795
|
strategyName,
|
|
15708
15796
|
});
|
|
15709
|
-
return await
|
|
15797
|
+
return await bt.backtestMarkdownService.getData(symbol, strategyName, true);
|
|
15710
15798
|
};
|
|
15711
15799
|
/**
|
|
15712
15800
|
* Generates markdown report with all closed signals for a symbol-strategy pair.
|
|
@@ -15724,11 +15812,11 @@ class BacktestInstance {
|
|
|
15724
15812
|
* ```
|
|
15725
15813
|
*/
|
|
15726
15814
|
this.getReport = async (symbol, strategyName, columns) => {
|
|
15727
|
-
|
|
15815
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_GET_REPORT, {
|
|
15728
15816
|
symbol,
|
|
15729
15817
|
strategyName,
|
|
15730
15818
|
});
|
|
15731
|
-
return await
|
|
15819
|
+
return await bt.backtestMarkdownService.getReport(symbol, strategyName, true, columns);
|
|
15732
15820
|
};
|
|
15733
15821
|
/**
|
|
15734
15822
|
* Saves strategy report to disk.
|
|
@@ -15749,12 +15837,12 @@ class BacktestInstance {
|
|
|
15749
15837
|
* ```
|
|
15750
15838
|
*/
|
|
15751
15839
|
this.dump = async (symbol, strategyName, path, columns) => {
|
|
15752
|
-
|
|
15840
|
+
bt.loggerService.info(BACKTEST_METHOD_NAME_DUMP, {
|
|
15753
15841
|
symbol,
|
|
15754
15842
|
strategyName,
|
|
15755
15843
|
path,
|
|
15756
15844
|
});
|
|
15757
|
-
await
|
|
15845
|
+
await bt.backtestMarkdownService.dump(symbol, strategyName, true, path, columns);
|
|
15758
15846
|
};
|
|
15759
15847
|
}
|
|
15760
15848
|
}
|
|
@@ -15793,14 +15881,14 @@ class BacktestUtils {
|
|
|
15793
15881
|
*/
|
|
15794
15882
|
this.run = (symbol, context) => {
|
|
15795
15883
|
{
|
|
15796
|
-
|
|
15797
|
-
|
|
15798
|
-
|
|
15884
|
+
bt.strategyValidationService.validate(context.strategyName, BACKTEST_METHOD_NAME_RUN);
|
|
15885
|
+
bt.exchangeValidationService.validate(context.exchangeName, BACKTEST_METHOD_NAME_RUN);
|
|
15886
|
+
bt.frameValidationService.validate(context.frameName, BACKTEST_METHOD_NAME_RUN);
|
|
15799
15887
|
}
|
|
15800
15888
|
{
|
|
15801
|
-
const { riskName, riskList } =
|
|
15802
|
-
riskName &&
|
|
15803
|
-
riskList && riskList.forEach((riskName) =>
|
|
15889
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
15890
|
+
riskName && bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_RUN);
|
|
15891
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_RUN));
|
|
15804
15892
|
}
|
|
15805
15893
|
const instance = this._getInstance(symbol, context.strategyName);
|
|
15806
15894
|
return instance.run(symbol, context);
|
|
@@ -15827,13 +15915,13 @@ class BacktestUtils {
|
|
|
15827
15915
|
* ```
|
|
15828
15916
|
*/
|
|
15829
15917
|
this.background = (symbol, context) => {
|
|
15830
|
-
|
|
15831
|
-
|
|
15832
|
-
|
|
15918
|
+
bt.strategyValidationService.validate(context.strategyName, BACKTEST_METHOD_NAME_BACKGROUND);
|
|
15919
|
+
bt.exchangeValidationService.validate(context.exchangeName, BACKTEST_METHOD_NAME_BACKGROUND);
|
|
15920
|
+
bt.frameValidationService.validate(context.frameName, BACKTEST_METHOD_NAME_BACKGROUND);
|
|
15833
15921
|
{
|
|
15834
|
-
const { riskName, riskList } =
|
|
15835
|
-
riskName &&
|
|
15836
|
-
riskList && riskList.forEach((riskName) =>
|
|
15922
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
15923
|
+
riskName && bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_BACKGROUND);
|
|
15924
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_BACKGROUND));
|
|
15837
15925
|
}
|
|
15838
15926
|
const instance = this._getInstance(symbol, context.strategyName);
|
|
15839
15927
|
return instance.background(symbol, context);
|
|
@@ -15856,11 +15944,11 @@ class BacktestUtils {
|
|
|
15856
15944
|
* ```
|
|
15857
15945
|
*/
|
|
15858
15946
|
this.stop = async (symbol, strategyName) => {
|
|
15859
|
-
|
|
15947
|
+
bt.strategyValidationService.validate(strategyName, BACKTEST_METHOD_NAME_STOP);
|
|
15860
15948
|
{
|
|
15861
|
-
const { riskName, riskList } =
|
|
15862
|
-
riskName &&
|
|
15863
|
-
riskList && riskList.forEach((riskName) =>
|
|
15949
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
15950
|
+
riskName && bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_STOP);
|
|
15951
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_STOP));
|
|
15864
15952
|
}
|
|
15865
15953
|
const instance = this._getInstance(symbol, strategyName);
|
|
15866
15954
|
return await instance.stop(symbol, strategyName);
|
|
@@ -15879,11 +15967,11 @@ class BacktestUtils {
|
|
|
15879
15967
|
* ```
|
|
15880
15968
|
*/
|
|
15881
15969
|
this.getData = async (symbol, strategyName) => {
|
|
15882
|
-
|
|
15970
|
+
bt.strategyValidationService.validate(strategyName, "BacktestUtils.getData");
|
|
15883
15971
|
{
|
|
15884
|
-
const { riskName, riskList } =
|
|
15885
|
-
riskName &&
|
|
15886
|
-
riskList && riskList.forEach((riskName) =>
|
|
15972
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
15973
|
+
riskName && bt.riskValidationService.validate(riskName, "BacktestUtils.getData");
|
|
15974
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, "BacktestUtils.getData"));
|
|
15887
15975
|
}
|
|
15888
15976
|
const instance = this._getInstance(symbol, strategyName);
|
|
15889
15977
|
return await instance.getData(symbol, strategyName);
|
|
@@ -15903,11 +15991,11 @@ class BacktestUtils {
|
|
|
15903
15991
|
* ```
|
|
15904
15992
|
*/
|
|
15905
15993
|
this.getReport = async (symbol, strategyName, columns) => {
|
|
15906
|
-
|
|
15994
|
+
bt.strategyValidationService.validate(strategyName, BACKTEST_METHOD_NAME_GET_REPORT);
|
|
15907
15995
|
{
|
|
15908
|
-
const { riskName, riskList } =
|
|
15909
|
-
riskName &&
|
|
15910
|
-
riskList && riskList.forEach((riskName) =>
|
|
15996
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
15997
|
+
riskName && bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_REPORT);
|
|
15998
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_GET_REPORT));
|
|
15911
15999
|
}
|
|
15912
16000
|
const instance = this._getInstance(symbol, strategyName);
|
|
15913
16001
|
return await instance.getReport(symbol, strategyName, columns);
|
|
@@ -15930,11 +16018,11 @@ class BacktestUtils {
|
|
|
15930
16018
|
* ```
|
|
15931
16019
|
*/
|
|
15932
16020
|
this.dump = async (symbol, strategyName, path, columns) => {
|
|
15933
|
-
|
|
16021
|
+
bt.strategyValidationService.validate(strategyName, BACKTEST_METHOD_NAME_DUMP);
|
|
15934
16022
|
{
|
|
15935
|
-
const { riskName, riskList } =
|
|
15936
|
-
riskName &&
|
|
15937
|
-
riskList && riskList.forEach((riskName) =>
|
|
16023
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16024
|
+
riskName && bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_DUMP);
|
|
16025
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, BACKTEST_METHOD_NAME_DUMP));
|
|
15938
16026
|
}
|
|
15939
16027
|
const instance = this._getInstance(symbol, strategyName);
|
|
15940
16028
|
return await instance.dump(symbol, strategyName, path, columns);
|
|
@@ -16064,7 +16152,7 @@ class LiveInstance {
|
|
|
16064
16152
|
* @internal
|
|
16065
16153
|
*/
|
|
16066
16154
|
this.task = singlerun(async (symbol, context) => {
|
|
16067
|
-
|
|
16155
|
+
bt.loggerService.info(LIVE_METHOD_NAME_TASK, {
|
|
16068
16156
|
symbol,
|
|
16069
16157
|
context,
|
|
16070
16158
|
});
|
|
@@ -16083,7 +16171,7 @@ class LiveInstance {
|
|
|
16083
16171
|
* ```
|
|
16084
16172
|
*/
|
|
16085
16173
|
this.getStatus = async () => {
|
|
16086
|
-
|
|
16174
|
+
bt.loggerService.info(LIVE_METHOD_NAME_GET_STATUS);
|
|
16087
16175
|
return {
|
|
16088
16176
|
id: this.id,
|
|
16089
16177
|
symbol: this.symbol,
|
|
@@ -16102,23 +16190,27 @@ class LiveInstance {
|
|
|
16102
16190
|
* @returns Infinite async generator yielding opened and closed signals
|
|
16103
16191
|
*/
|
|
16104
16192
|
this.run = (symbol, context) => {
|
|
16105
|
-
|
|
16193
|
+
bt.loggerService.info(LIVE_METHOD_NAME_RUN, {
|
|
16106
16194
|
symbol,
|
|
16107
16195
|
context,
|
|
16108
16196
|
});
|
|
16109
16197
|
{
|
|
16110
|
-
|
|
16111
|
-
|
|
16198
|
+
bt.backtestMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16199
|
+
bt.liveMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16200
|
+
bt.scheduleMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16201
|
+
bt.performanceMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16202
|
+
bt.partialMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16203
|
+
bt.riskMarkdownService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16112
16204
|
}
|
|
16113
16205
|
{
|
|
16114
|
-
|
|
16206
|
+
bt.strategyCoreService.clear(false, { symbol, strategyName: context.strategyName });
|
|
16115
16207
|
}
|
|
16116
16208
|
{
|
|
16117
|
-
const { riskName, riskList } =
|
|
16118
|
-
riskName &&
|
|
16119
|
-
riskList && riskList.forEach((riskName) =>
|
|
16209
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
16210
|
+
riskName && bt.riskGlobalService.clear(false, riskName);
|
|
16211
|
+
riskList && riskList.forEach((riskName) => bt.riskGlobalService.clear(false, riskName));
|
|
16120
16212
|
}
|
|
16121
|
-
return
|
|
16213
|
+
return bt.liveCommandService.run(symbol, context);
|
|
16122
16214
|
};
|
|
16123
16215
|
/**
|
|
16124
16216
|
* Runs live trading in background without yielding results.
|
|
@@ -16141,14 +16233,23 @@ class LiveInstance {
|
|
|
16141
16233
|
* ```
|
|
16142
16234
|
*/
|
|
16143
16235
|
this.background = (symbol, context) => {
|
|
16144
|
-
|
|
16236
|
+
bt.loggerService.info(LIVE_METHOD_NAME_BACKGROUND, {
|
|
16145
16237
|
symbol,
|
|
16146
16238
|
context,
|
|
16147
16239
|
});
|
|
16240
|
+
const currentStatus = this.task.getStatus();
|
|
16241
|
+
{
|
|
16242
|
+
if (currentStatus === "pending") {
|
|
16243
|
+
throw new Error(`Live.background is already running for symbol=${symbol} strategyName=${context.strategyName} exchangeName=${context.exchangeName}`);
|
|
16244
|
+
}
|
|
16245
|
+
if (currentStatus === "rejected") {
|
|
16246
|
+
throw new Error(`Live.background has failed for symbol=${symbol} strategyName=${context.strategyName} exchangeName=${context.exchangeName}`);
|
|
16247
|
+
}
|
|
16248
|
+
}
|
|
16148
16249
|
this.task(symbol, context).catch((error) => exitEmitter.next(new Error(getErrorMessage(error))));
|
|
16149
16250
|
return () => {
|
|
16150
|
-
|
|
16151
|
-
|
|
16251
|
+
bt.strategyCoreService.stop(false, { symbol, strategyName: context.strategyName });
|
|
16252
|
+
bt.strategyCoreService
|
|
16152
16253
|
.getPendingSignal(false, symbol, context.strategyName)
|
|
16153
16254
|
.then(async (pendingSignal) => {
|
|
16154
16255
|
if (pendingSignal) {
|
|
@@ -16185,11 +16286,11 @@ class LiveInstance {
|
|
|
16185
16286
|
* ```
|
|
16186
16287
|
*/
|
|
16187
16288
|
this.stop = async (symbol, strategyName) => {
|
|
16188
|
-
|
|
16289
|
+
bt.loggerService.info(LIVE_METHOD_NAME_STOP, {
|
|
16189
16290
|
symbol,
|
|
16190
16291
|
strategyName,
|
|
16191
16292
|
});
|
|
16192
|
-
await
|
|
16293
|
+
await bt.strategyCoreService.stop(false, { symbol, strategyName });
|
|
16193
16294
|
};
|
|
16194
16295
|
/**
|
|
16195
16296
|
* Gets statistical data from all live trading events for a symbol-strategy pair.
|
|
@@ -16206,11 +16307,11 @@ class LiveInstance {
|
|
|
16206
16307
|
* ```
|
|
16207
16308
|
*/
|
|
16208
16309
|
this.getData = async (symbol, strategyName) => {
|
|
16209
|
-
|
|
16310
|
+
bt.loggerService.info("LiveUtils.getData", {
|
|
16210
16311
|
symbol,
|
|
16211
16312
|
strategyName,
|
|
16212
16313
|
});
|
|
16213
|
-
return await
|
|
16314
|
+
return await bt.liveMarkdownService.getData(symbol, strategyName, false);
|
|
16214
16315
|
};
|
|
16215
16316
|
/**
|
|
16216
16317
|
* Generates markdown report with all events for a symbol-strategy pair.
|
|
@@ -16228,11 +16329,11 @@ class LiveInstance {
|
|
|
16228
16329
|
* ```
|
|
16229
16330
|
*/
|
|
16230
16331
|
this.getReport = async (symbol, strategyName, columns) => {
|
|
16231
|
-
|
|
16332
|
+
bt.loggerService.info(LIVE_METHOD_NAME_GET_REPORT, {
|
|
16232
16333
|
symbol,
|
|
16233
16334
|
strategyName,
|
|
16234
16335
|
});
|
|
16235
|
-
return await
|
|
16336
|
+
return await bt.liveMarkdownService.getReport(symbol, strategyName, false, columns);
|
|
16236
16337
|
};
|
|
16237
16338
|
/**
|
|
16238
16339
|
* Saves strategy report to disk.
|
|
@@ -16253,12 +16354,12 @@ class LiveInstance {
|
|
|
16253
16354
|
* ```
|
|
16254
16355
|
*/
|
|
16255
16356
|
this.dump = async (symbol, strategyName, path, columns) => {
|
|
16256
|
-
|
|
16357
|
+
bt.loggerService.info(LIVE_METHOD_NAME_DUMP, {
|
|
16257
16358
|
symbol,
|
|
16258
16359
|
strategyName,
|
|
16259
16360
|
path,
|
|
16260
16361
|
});
|
|
16261
|
-
await
|
|
16362
|
+
await bt.liveMarkdownService.dump(symbol, strategyName, false, path, columns);
|
|
16262
16363
|
};
|
|
16263
16364
|
}
|
|
16264
16365
|
}
|
|
@@ -16310,13 +16411,13 @@ class LiveUtils {
|
|
|
16310
16411
|
*/
|
|
16311
16412
|
this.run = (symbol, context) => {
|
|
16312
16413
|
{
|
|
16313
|
-
|
|
16314
|
-
|
|
16414
|
+
bt.strategyValidationService.validate(context.strategyName, LIVE_METHOD_NAME_RUN);
|
|
16415
|
+
bt.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_RUN);
|
|
16315
16416
|
}
|
|
16316
16417
|
{
|
|
16317
|
-
const { riskName, riskList } =
|
|
16318
|
-
riskName &&
|
|
16319
|
-
riskList && riskList.forEach((riskName) =>
|
|
16418
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
16419
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_RUN);
|
|
16420
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_RUN));
|
|
16320
16421
|
}
|
|
16321
16422
|
const instance = this._getInstance(symbol, context.strategyName);
|
|
16322
16423
|
return instance.run(symbol, context);
|
|
@@ -16343,12 +16444,12 @@ class LiveUtils {
|
|
|
16343
16444
|
* ```
|
|
16344
16445
|
*/
|
|
16345
16446
|
this.background = (symbol, context) => {
|
|
16346
|
-
|
|
16347
|
-
|
|
16447
|
+
bt.strategyValidationService.validate(context.strategyName, LIVE_METHOD_NAME_BACKGROUND);
|
|
16448
|
+
bt.exchangeValidationService.validate(context.exchangeName, LIVE_METHOD_NAME_BACKGROUND);
|
|
16348
16449
|
{
|
|
16349
|
-
const { riskName, riskList } =
|
|
16350
|
-
riskName &&
|
|
16351
|
-
riskList && riskList.forEach((riskName) =>
|
|
16450
|
+
const { riskName, riskList } = bt.strategySchemaService.get(context.strategyName);
|
|
16451
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_BACKGROUND);
|
|
16452
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_BACKGROUND));
|
|
16352
16453
|
}
|
|
16353
16454
|
const instance = this._getInstance(symbol, context.strategyName);
|
|
16354
16455
|
return instance.background(symbol, context);
|
|
@@ -16371,11 +16472,11 @@ class LiveUtils {
|
|
|
16371
16472
|
* ```
|
|
16372
16473
|
*/
|
|
16373
16474
|
this.stop = async (symbol, strategyName) => {
|
|
16374
|
-
|
|
16475
|
+
bt.strategyValidationService.validate(strategyName, LIVE_METHOD_NAME_STOP);
|
|
16375
16476
|
{
|
|
16376
|
-
const { riskName, riskList } =
|
|
16377
|
-
riskName &&
|
|
16378
|
-
riskList && riskList.forEach((riskName) =>
|
|
16477
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16478
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_STOP);
|
|
16479
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_STOP));
|
|
16379
16480
|
}
|
|
16380
16481
|
const instance = this._getInstance(symbol, strategyName);
|
|
16381
16482
|
return await instance.stop(symbol, strategyName);
|
|
@@ -16394,11 +16495,11 @@ class LiveUtils {
|
|
|
16394
16495
|
* ```
|
|
16395
16496
|
*/
|
|
16396
16497
|
this.getData = async (symbol, strategyName) => {
|
|
16397
|
-
|
|
16498
|
+
bt.strategyValidationService.validate(strategyName, "LiveUtils.getData");
|
|
16398
16499
|
{
|
|
16399
|
-
const { riskName, riskList } =
|
|
16400
|
-
riskName &&
|
|
16401
|
-
riskList && riskList.forEach((riskName) =>
|
|
16500
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16501
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_DATA);
|
|
16502
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_DATA));
|
|
16402
16503
|
}
|
|
16403
16504
|
const instance = this._getInstance(symbol, strategyName);
|
|
16404
16505
|
return await instance.getData(symbol, strategyName);
|
|
@@ -16418,11 +16519,11 @@ class LiveUtils {
|
|
|
16418
16519
|
* ```
|
|
16419
16520
|
*/
|
|
16420
16521
|
this.getReport = async (symbol, strategyName, columns) => {
|
|
16421
|
-
|
|
16522
|
+
bt.strategyValidationService.validate(strategyName, LIVE_METHOD_NAME_GET_REPORT);
|
|
16422
16523
|
{
|
|
16423
|
-
const { riskName, riskList } =
|
|
16424
|
-
riskName &&
|
|
16425
|
-
riskList && riskList.forEach((riskName) =>
|
|
16524
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16525
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_REPORT);
|
|
16526
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_GET_REPORT));
|
|
16426
16527
|
}
|
|
16427
16528
|
const instance = this._getInstance(symbol, strategyName);
|
|
16428
16529
|
return await instance.getReport(symbol, strategyName, columns);
|
|
@@ -16445,11 +16546,11 @@ class LiveUtils {
|
|
|
16445
16546
|
* ```
|
|
16446
16547
|
*/
|
|
16447
16548
|
this.dump = async (symbol, strategyName, path, columns) => {
|
|
16448
|
-
|
|
16549
|
+
bt.strategyValidationService.validate(strategyName, LIVE_METHOD_NAME_DUMP);
|
|
16449
16550
|
{
|
|
16450
|
-
const { riskName, riskList } =
|
|
16451
|
-
riskName &&
|
|
16452
|
-
riskList && riskList.forEach((riskName) =>
|
|
16551
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16552
|
+
riskName && bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_DUMP);
|
|
16553
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, LIVE_METHOD_NAME_DUMP));
|
|
16453
16554
|
}
|
|
16454
16555
|
const instance = this._getInstance(symbol, strategyName);
|
|
16455
16556
|
return await instance.dump(symbol, strategyName, path, columns);
|
|
@@ -16533,18 +16634,19 @@ class ScheduleUtils {
|
|
|
16533
16634
|
* console.log(stats.cancellationRate, stats.avgWaitTime);
|
|
16534
16635
|
* ```
|
|
16535
16636
|
*/
|
|
16536
|
-
this.getData = async (symbol, strategyName) => {
|
|
16537
|
-
|
|
16637
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
16638
|
+
bt.loggerService.info(SCHEDULE_METHOD_NAME_GET_DATA, {
|
|
16538
16639
|
symbol,
|
|
16539
16640
|
strategyName,
|
|
16641
|
+
backtest,
|
|
16540
16642
|
});
|
|
16541
|
-
|
|
16643
|
+
bt.strategyValidationService.validate(strategyName, SCHEDULE_METHOD_NAME_GET_DATA);
|
|
16542
16644
|
{
|
|
16543
|
-
const { riskName, riskList } =
|
|
16544
|
-
riskName &&
|
|
16545
|
-
riskList && riskList.forEach((riskName) =>
|
|
16645
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16646
|
+
riskName && bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_DATA);
|
|
16647
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_DATA));
|
|
16546
16648
|
}
|
|
16547
|
-
return await
|
|
16649
|
+
return await bt.scheduleMarkdownService.getData(symbol, strategyName, backtest);
|
|
16548
16650
|
};
|
|
16549
16651
|
/**
|
|
16550
16652
|
* Generates markdown report with all scheduled events for a symbol-strategy pair.
|
|
@@ -16560,18 +16662,19 @@ class ScheduleUtils {
|
|
|
16560
16662
|
* console.log(markdown);
|
|
16561
16663
|
* ```
|
|
16562
16664
|
*/
|
|
16563
|
-
this.getReport = async (symbol, strategyName, columns) => {
|
|
16564
|
-
|
|
16665
|
+
this.getReport = async (symbol, strategyName, backtest, columns) => {
|
|
16666
|
+
bt.loggerService.info(SCHEDULE_METHOD_NAME_GET_REPORT, {
|
|
16565
16667
|
symbol,
|
|
16566
16668
|
strategyName,
|
|
16669
|
+
backtest,
|
|
16567
16670
|
});
|
|
16568
|
-
|
|
16671
|
+
bt.strategyValidationService.validate(strategyName, SCHEDULE_METHOD_NAME_GET_REPORT);
|
|
16569
16672
|
{
|
|
16570
|
-
const { riskName, riskList } =
|
|
16571
|
-
riskName &&
|
|
16572
|
-
riskList && riskList.forEach((riskName) =>
|
|
16673
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16674
|
+
riskName && bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_REPORT);
|
|
16675
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_GET_REPORT));
|
|
16573
16676
|
}
|
|
16574
|
-
return await
|
|
16677
|
+
return await bt.scheduleMarkdownService.getReport(symbol, strategyName, backtest, columns);
|
|
16575
16678
|
};
|
|
16576
16679
|
/**
|
|
16577
16680
|
* Saves strategy report to disk.
|
|
@@ -16590,19 +16693,20 @@ class ScheduleUtils {
|
|
|
16590
16693
|
* await Schedule.dump("BTCUSDT", "my-strategy", "./custom/path");
|
|
16591
16694
|
* ```
|
|
16592
16695
|
*/
|
|
16593
|
-
this.dump = async (symbol, strategyName, path, columns) => {
|
|
16594
|
-
|
|
16696
|
+
this.dump = async (symbol, strategyName, backtest, path, columns) => {
|
|
16697
|
+
bt.loggerService.info(SCHEDULE_METHOD_NAME_DUMP, {
|
|
16595
16698
|
symbol,
|
|
16596
16699
|
strategyName,
|
|
16700
|
+
backtest,
|
|
16597
16701
|
path,
|
|
16598
16702
|
});
|
|
16599
|
-
|
|
16703
|
+
bt.strategyValidationService.validate(strategyName, SCHEDULE_METHOD_NAME_DUMP);
|
|
16600
16704
|
{
|
|
16601
|
-
const { riskName, riskList } =
|
|
16602
|
-
riskName &&
|
|
16603
|
-
riskList && riskList.forEach((riskName) =>
|
|
16705
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16706
|
+
riskName && bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_DUMP);
|
|
16707
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, SCHEDULE_METHOD_NAME_DUMP));
|
|
16604
16708
|
}
|
|
16605
|
-
await
|
|
16709
|
+
await bt.scheduleMarkdownService.dump(symbol, strategyName, backtest, path, columns);
|
|
16606
16710
|
};
|
|
16607
16711
|
}
|
|
16608
16712
|
}
|
|
@@ -16640,7 +16744,7 @@ const PERFORMANCE_METHOD_NAME_DUMP = "Performance.dump";
|
|
|
16640
16744
|
* console.log(`${event.metricType}: ${event.duration.toFixed(2)}ms`);
|
|
16641
16745
|
* });
|
|
16642
16746
|
*
|
|
16643
|
-
* // Run
|
|
16747
|
+
* // Run bt...
|
|
16644
16748
|
*
|
|
16645
16749
|
* // Get aggregated statistics
|
|
16646
16750
|
* const stats = await Performance.getData("my-strategy");
|
|
@@ -16683,14 +16787,14 @@ class Performance {
|
|
|
16683
16787
|
* }
|
|
16684
16788
|
* ```
|
|
16685
16789
|
*/
|
|
16686
|
-
static async getData(symbol, strategyName) {
|
|
16687
|
-
|
|
16790
|
+
static async getData(symbol, strategyName, backtest) {
|
|
16791
|
+
bt.strategyValidationService.validate(strategyName, PERFORMANCE_METHOD_NAME_GET_DATA);
|
|
16688
16792
|
{
|
|
16689
|
-
const { riskName, riskList } =
|
|
16690
|
-
riskName &&
|
|
16691
|
-
riskList && riskList.forEach((riskName) =>
|
|
16793
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16794
|
+
riskName && bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_DATA);
|
|
16795
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_DATA));
|
|
16692
16796
|
}
|
|
16693
|
-
return
|
|
16797
|
+
return bt.performanceMarkdownService.getData(symbol, strategyName, backtest);
|
|
16694
16798
|
}
|
|
16695
16799
|
/**
|
|
16696
16800
|
* Generates markdown report with performance analysis.
|
|
@@ -16715,14 +16819,14 @@ class Performance {
|
|
|
16715
16819
|
* await fs.writeFile("performance-report.md", markdown);
|
|
16716
16820
|
* ```
|
|
16717
16821
|
*/
|
|
16718
|
-
static async getReport(symbol, strategyName, columns) {
|
|
16719
|
-
|
|
16822
|
+
static async getReport(symbol, strategyName, backtest, columns) {
|
|
16823
|
+
bt.strategyValidationService.validate(strategyName, PERFORMANCE_METHOD_NAME_GET_REPORT);
|
|
16720
16824
|
{
|
|
16721
|
-
const { riskName, riskList } =
|
|
16722
|
-
riskName &&
|
|
16723
|
-
riskList && riskList.forEach((riskName) =>
|
|
16825
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16826
|
+
riskName && bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_REPORT);
|
|
16827
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_GET_REPORT));
|
|
16724
16828
|
}
|
|
16725
|
-
return
|
|
16829
|
+
return bt.performanceMarkdownService.getReport(symbol, strategyName, backtest, columns);
|
|
16726
16830
|
}
|
|
16727
16831
|
/**
|
|
16728
16832
|
* Saves performance report to disk.
|
|
@@ -16744,14 +16848,14 @@ class Performance {
|
|
|
16744
16848
|
* await Performance.dump("BTCUSDT", "my-strategy", "./reports/perf");
|
|
16745
16849
|
* ```
|
|
16746
16850
|
*/
|
|
16747
|
-
static async dump(symbol, strategyName, path = "./dump/performance", columns) {
|
|
16748
|
-
|
|
16851
|
+
static async dump(symbol, strategyName, backtest, path = "./dump/performance", columns) {
|
|
16852
|
+
bt.strategyValidationService.validate(strategyName, PERFORMANCE_METHOD_NAME_DUMP);
|
|
16749
16853
|
{
|
|
16750
|
-
const { riskName, riskList } =
|
|
16751
|
-
riskName &&
|
|
16752
|
-
riskList && riskList.forEach((riskName) =>
|
|
16854
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
16855
|
+
riskName && bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_DUMP);
|
|
16856
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PERFORMANCE_METHOD_NAME_DUMP));
|
|
16753
16857
|
}
|
|
16754
|
-
return
|
|
16858
|
+
return bt.performanceMarkdownService.dump(symbol, strategyName, backtest, path, columns);
|
|
16755
16859
|
}
|
|
16756
16860
|
}
|
|
16757
16861
|
|
|
@@ -16785,7 +16889,7 @@ const INSTANCE_TASK_FN = async (symbol, context, self) => {
|
|
|
16785
16889
|
}
|
|
16786
16890
|
}
|
|
16787
16891
|
if (!self._isDone) {
|
|
16788
|
-
const walkerSchema =
|
|
16892
|
+
const walkerSchema = bt.walkerSchemaService.get(context.walkerName);
|
|
16789
16893
|
await doneWalkerSubject.next({
|
|
16790
16894
|
exchangeName: walkerSchema.exchangeName,
|
|
16791
16895
|
strategyName: context.walkerName,
|
|
@@ -16839,7 +16943,7 @@ class WalkerInstance {
|
|
|
16839
16943
|
* @internal
|
|
16840
16944
|
*/
|
|
16841
16945
|
this.task = singlerun(async (symbol, context) => {
|
|
16842
|
-
|
|
16946
|
+
bt.loggerService.info(WALKER_METHOD_NAME_TASK, {
|
|
16843
16947
|
symbol,
|
|
16844
16948
|
context,
|
|
16845
16949
|
});
|
|
@@ -16858,7 +16962,7 @@ class WalkerInstance {
|
|
|
16858
16962
|
* ```
|
|
16859
16963
|
*/
|
|
16860
16964
|
this.getStatus = async () => {
|
|
16861
|
-
|
|
16965
|
+
bt.loggerService.info(WALKER_METHOD_NAME_GET_STATUS);
|
|
16862
16966
|
return {
|
|
16863
16967
|
id: this.id,
|
|
16864
16968
|
symbol: this.symbol,
|
|
@@ -16874,35 +16978,39 @@ class WalkerInstance {
|
|
|
16874
16978
|
* @returns Async generator yielding progress updates after each strategy
|
|
16875
16979
|
*/
|
|
16876
16980
|
this.run = (symbol, context) => {
|
|
16877
|
-
|
|
16981
|
+
bt.loggerService.info(WALKER_METHOD_NAME_RUN, {
|
|
16878
16982
|
symbol,
|
|
16879
16983
|
context,
|
|
16880
16984
|
});
|
|
16881
|
-
|
|
16882
|
-
const walkerSchema =
|
|
16883
|
-
|
|
16884
|
-
|
|
16985
|
+
bt.walkerValidationService.validate(context.walkerName, WALKER_METHOD_NAME_RUN);
|
|
16986
|
+
const walkerSchema = bt.walkerSchemaService.get(context.walkerName);
|
|
16987
|
+
bt.exchangeValidationService.validate(walkerSchema.exchangeName, WALKER_METHOD_NAME_RUN);
|
|
16988
|
+
bt.frameValidationService.validate(walkerSchema.frameName, WALKER_METHOD_NAME_RUN);
|
|
16885
16989
|
for (const strategyName of walkerSchema.strategies) {
|
|
16886
|
-
|
|
16990
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_RUN);
|
|
16887
16991
|
}
|
|
16888
|
-
|
|
16992
|
+
bt.walkerMarkdownService.clear(context.walkerName);
|
|
16889
16993
|
// Clear backtest data for all strategies
|
|
16890
16994
|
for (const strategyName of walkerSchema.strategies) {
|
|
16891
16995
|
{
|
|
16892
|
-
|
|
16893
|
-
|
|
16996
|
+
bt.backtestMarkdownService.clear(true, { symbol, strategyName });
|
|
16997
|
+
bt.liveMarkdownService.clear(true, { symbol, strategyName });
|
|
16998
|
+
bt.scheduleMarkdownService.clear(true, { symbol, strategyName });
|
|
16999
|
+
bt.performanceMarkdownService.clear(true, { symbol, strategyName });
|
|
17000
|
+
bt.partialMarkdownService.clear(true, { symbol, strategyName });
|
|
17001
|
+
bt.riskMarkdownService.clear(true, { symbol, strategyName });
|
|
16894
17002
|
}
|
|
16895
17003
|
{
|
|
16896
|
-
|
|
17004
|
+
bt.strategyCoreService.clear(true, { symbol, strategyName });
|
|
16897
17005
|
}
|
|
16898
17006
|
{
|
|
16899
|
-
const { riskName, riskList } =
|
|
16900
|
-
riskName &&
|
|
17007
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17008
|
+
riskName && bt.riskGlobalService.clear(true, riskName);
|
|
16901
17009
|
riskList &&
|
|
16902
|
-
riskList.forEach((riskName) =>
|
|
17010
|
+
riskList.forEach((riskName) => bt.riskGlobalService.clear(true, riskName));
|
|
16903
17011
|
}
|
|
16904
17012
|
}
|
|
16905
|
-
return
|
|
17013
|
+
return bt.walkerCommandService.run(symbol, {
|
|
16906
17014
|
walkerName: context.walkerName,
|
|
16907
17015
|
exchangeName: walkerSchema.exchangeName,
|
|
16908
17016
|
frameName: walkerSchema.frameName,
|
|
@@ -16927,15 +17035,24 @@ class WalkerInstance {
|
|
|
16927
17035
|
* ```
|
|
16928
17036
|
*/
|
|
16929
17037
|
this.background = (symbol, context) => {
|
|
16930
|
-
|
|
17038
|
+
bt.loggerService.info(WALKER_METHOD_NAME_BACKGROUND, {
|
|
16931
17039
|
symbol,
|
|
16932
17040
|
context,
|
|
16933
17041
|
});
|
|
16934
|
-
const walkerSchema =
|
|
17042
|
+
const walkerSchema = bt.walkerSchemaService.get(context.walkerName);
|
|
17043
|
+
{
|
|
17044
|
+
const currentStatus = this.task.getStatus();
|
|
17045
|
+
if (currentStatus === "pending") {
|
|
17046
|
+
throw new Error(`Walker.background is already running for symbol=${symbol} walkerName=${context.walkerName}`);
|
|
17047
|
+
}
|
|
17048
|
+
if (currentStatus === "rejected") {
|
|
17049
|
+
throw new Error(`Walker.background has failed for symbol=${symbol} walkerName=${context.walkerName}`);
|
|
17050
|
+
}
|
|
17051
|
+
}
|
|
16935
17052
|
this.task(symbol, context).catch((error) => exitEmitter.next(new Error(getErrorMessage(error))));
|
|
16936
17053
|
return () => {
|
|
16937
17054
|
for (const strategyName of walkerSchema.strategies) {
|
|
16938
|
-
|
|
17055
|
+
bt.strategyCoreService.stop(true, { symbol, strategyName });
|
|
16939
17056
|
walkerStopSubject.next({
|
|
16940
17057
|
symbol,
|
|
16941
17058
|
strategyName,
|
|
@@ -16978,14 +17095,14 @@ class WalkerInstance {
|
|
|
16978
17095
|
* ```
|
|
16979
17096
|
*/
|
|
16980
17097
|
this.stop = async (symbol, walkerName) => {
|
|
16981
|
-
|
|
17098
|
+
bt.loggerService.info(WALKER_METHOD_NAME_STOP, {
|
|
16982
17099
|
symbol,
|
|
16983
17100
|
walkerName,
|
|
16984
17101
|
});
|
|
16985
|
-
const walkerSchema =
|
|
17102
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
16986
17103
|
for (const strategyName of walkerSchema.strategies) {
|
|
16987
17104
|
await walkerStopSubject.next({ symbol, strategyName, walkerName });
|
|
16988
|
-
await
|
|
17105
|
+
await bt.strategyCoreService.stop(true, { symbol, strategyName });
|
|
16989
17106
|
}
|
|
16990
17107
|
};
|
|
16991
17108
|
/**
|
|
@@ -17003,12 +17120,12 @@ class WalkerInstance {
|
|
|
17003
17120
|
* ```
|
|
17004
17121
|
*/
|
|
17005
17122
|
this.getData = async (symbol, walkerName) => {
|
|
17006
|
-
|
|
17123
|
+
bt.loggerService.info(WALKER_METHOD_NAME_GET_DATA, {
|
|
17007
17124
|
symbol,
|
|
17008
17125
|
walkerName,
|
|
17009
17126
|
});
|
|
17010
|
-
const walkerSchema =
|
|
17011
|
-
return await
|
|
17127
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17128
|
+
return await bt.walkerMarkdownService.getData(walkerName, symbol, walkerSchema.metric || "sharpeRatio", {
|
|
17012
17129
|
exchangeName: walkerSchema.exchangeName,
|
|
17013
17130
|
frameName: walkerSchema.frameName,
|
|
17014
17131
|
});
|
|
@@ -17030,12 +17147,12 @@ class WalkerInstance {
|
|
|
17030
17147
|
* ```
|
|
17031
17148
|
*/
|
|
17032
17149
|
this.getReport = async (symbol, walkerName, strategyColumns, pnlColumns) => {
|
|
17033
|
-
|
|
17150
|
+
bt.loggerService.info(WALKER_METHOD_NAME_GET_REPORT, {
|
|
17034
17151
|
symbol,
|
|
17035
17152
|
walkerName,
|
|
17036
17153
|
});
|
|
17037
|
-
const walkerSchema =
|
|
17038
|
-
return await
|
|
17154
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17155
|
+
return await bt.walkerMarkdownService.getReport(walkerName, symbol, walkerSchema.metric || "sharpeRatio", {
|
|
17039
17156
|
exchangeName: walkerSchema.exchangeName,
|
|
17040
17157
|
frameName: walkerSchema.frameName,
|
|
17041
17158
|
}, strategyColumns, pnlColumns);
|
|
@@ -17060,13 +17177,13 @@ class WalkerInstance {
|
|
|
17060
17177
|
* ```
|
|
17061
17178
|
*/
|
|
17062
17179
|
this.dump = async (symbol, walkerName, path, strategyColumns, pnlColumns) => {
|
|
17063
|
-
|
|
17180
|
+
bt.loggerService.info(WALKER_METHOD_NAME_DUMP, {
|
|
17064
17181
|
symbol,
|
|
17065
17182
|
walkerName,
|
|
17066
17183
|
path,
|
|
17067
17184
|
});
|
|
17068
|
-
const walkerSchema =
|
|
17069
|
-
await
|
|
17185
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17186
|
+
await bt.walkerMarkdownService.dump(walkerName, symbol, walkerSchema.metric || "sharpeRatio", {
|
|
17070
17187
|
exchangeName: walkerSchema.exchangeName,
|
|
17071
17188
|
frameName: walkerSchema.frameName,
|
|
17072
17189
|
}, path, strategyColumns, pnlColumns);
|
|
@@ -17107,17 +17224,17 @@ class WalkerUtils {
|
|
|
17107
17224
|
* @returns Async generator yielding progress updates after each strategy
|
|
17108
17225
|
*/
|
|
17109
17226
|
this.run = (symbol, context) => {
|
|
17110
|
-
|
|
17111
|
-
const walkerSchema =
|
|
17112
|
-
|
|
17113
|
-
|
|
17227
|
+
bt.walkerValidationService.validate(context.walkerName, WALKER_METHOD_NAME_RUN);
|
|
17228
|
+
const walkerSchema = bt.walkerSchemaService.get(context.walkerName);
|
|
17229
|
+
bt.exchangeValidationService.validate(walkerSchema.exchangeName, WALKER_METHOD_NAME_RUN);
|
|
17230
|
+
bt.frameValidationService.validate(walkerSchema.frameName, WALKER_METHOD_NAME_RUN);
|
|
17114
17231
|
for (const strategyName of walkerSchema.strategies) {
|
|
17115
|
-
|
|
17116
|
-
const { riskName, riskList } =
|
|
17232
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_RUN);
|
|
17233
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17117
17234
|
riskName &&
|
|
17118
|
-
|
|
17235
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_RUN);
|
|
17119
17236
|
riskList &&
|
|
17120
|
-
riskList.forEach((riskName) =>
|
|
17237
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_RUN));
|
|
17121
17238
|
}
|
|
17122
17239
|
const instance = this._getInstance(symbol, context.walkerName);
|
|
17123
17240
|
return instance.run(symbol, context);
|
|
@@ -17142,17 +17259,17 @@ class WalkerUtils {
|
|
|
17142
17259
|
* ```
|
|
17143
17260
|
*/
|
|
17144
17261
|
this.background = (symbol, context) => {
|
|
17145
|
-
|
|
17146
|
-
const walkerSchema =
|
|
17147
|
-
|
|
17148
|
-
|
|
17262
|
+
bt.walkerValidationService.validate(context.walkerName, WALKER_METHOD_NAME_BACKGROUND);
|
|
17263
|
+
const walkerSchema = bt.walkerSchemaService.get(context.walkerName);
|
|
17264
|
+
bt.exchangeValidationService.validate(walkerSchema.exchangeName, WALKER_METHOD_NAME_BACKGROUND);
|
|
17265
|
+
bt.frameValidationService.validate(walkerSchema.frameName, WALKER_METHOD_NAME_BACKGROUND);
|
|
17149
17266
|
for (const strategyName of walkerSchema.strategies) {
|
|
17150
|
-
|
|
17151
|
-
const { riskName, riskList } =
|
|
17267
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_BACKGROUND);
|
|
17268
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17152
17269
|
riskName &&
|
|
17153
|
-
|
|
17270
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_BACKGROUND);
|
|
17154
17271
|
riskList &&
|
|
17155
|
-
riskList.forEach((riskName) =>
|
|
17272
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_BACKGROUND));
|
|
17156
17273
|
}
|
|
17157
17274
|
const instance = this._getInstance(symbol, context.walkerName);
|
|
17158
17275
|
return instance.background(symbol, context);
|
|
@@ -17181,15 +17298,15 @@ class WalkerUtils {
|
|
|
17181
17298
|
* ```
|
|
17182
17299
|
*/
|
|
17183
17300
|
this.stop = async (symbol, walkerName) => {
|
|
17184
|
-
|
|
17185
|
-
const walkerSchema =
|
|
17301
|
+
bt.walkerValidationService.validate(walkerName, WALKER_METHOD_NAME_STOP);
|
|
17302
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17186
17303
|
for (const strategyName of walkerSchema.strategies) {
|
|
17187
|
-
|
|
17188
|
-
const { riskName, riskList } =
|
|
17304
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_STOP);
|
|
17305
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17189
17306
|
riskName &&
|
|
17190
|
-
|
|
17307
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_STOP);
|
|
17191
17308
|
riskList &&
|
|
17192
|
-
riskList.forEach((riskName) =>
|
|
17309
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_STOP));
|
|
17193
17310
|
}
|
|
17194
17311
|
const instance = this._getInstance(symbol, walkerName);
|
|
17195
17312
|
return await instance.stop(symbol, walkerName);
|
|
@@ -17208,15 +17325,15 @@ class WalkerUtils {
|
|
|
17208
17325
|
* ```
|
|
17209
17326
|
*/
|
|
17210
17327
|
this.getData = async (symbol, walkerName) => {
|
|
17211
|
-
|
|
17212
|
-
const walkerSchema =
|
|
17328
|
+
bt.walkerValidationService.validate(walkerName, WALKER_METHOD_NAME_GET_DATA);
|
|
17329
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17213
17330
|
for (const strategyName of walkerSchema.strategies) {
|
|
17214
|
-
|
|
17215
|
-
const { riskName, riskList } =
|
|
17331
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_GET_DATA);
|
|
17332
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17216
17333
|
riskName &&
|
|
17217
|
-
|
|
17334
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_DATA);
|
|
17218
17335
|
riskList &&
|
|
17219
|
-
riskList.forEach((riskName) =>
|
|
17336
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_DATA));
|
|
17220
17337
|
}
|
|
17221
17338
|
const instance = this._getInstance(symbol, walkerName);
|
|
17222
17339
|
return await instance.getData(symbol, walkerName);
|
|
@@ -17237,15 +17354,15 @@ class WalkerUtils {
|
|
|
17237
17354
|
* ```
|
|
17238
17355
|
*/
|
|
17239
17356
|
this.getReport = async (symbol, walkerName, strategyColumns, pnlColumns) => {
|
|
17240
|
-
|
|
17241
|
-
const walkerSchema =
|
|
17357
|
+
bt.walkerValidationService.validate(walkerName, WALKER_METHOD_NAME_GET_REPORT);
|
|
17358
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17242
17359
|
for (const strategyName of walkerSchema.strategies) {
|
|
17243
|
-
|
|
17244
|
-
const { riskName, riskList } =
|
|
17360
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_GET_REPORT);
|
|
17361
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17245
17362
|
riskName &&
|
|
17246
|
-
|
|
17363
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_REPORT);
|
|
17247
17364
|
riskList &&
|
|
17248
|
-
riskList.forEach((riskName) =>
|
|
17365
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_GET_REPORT));
|
|
17249
17366
|
}
|
|
17250
17367
|
const instance = this._getInstance(symbol, walkerName);
|
|
17251
17368
|
return await instance.getReport(symbol, walkerName, strategyColumns, pnlColumns);
|
|
@@ -17269,15 +17386,15 @@ class WalkerUtils {
|
|
|
17269
17386
|
* ```
|
|
17270
17387
|
*/
|
|
17271
17388
|
this.dump = async (symbol, walkerName, path, strategyColumns, pnlColumns) => {
|
|
17272
|
-
|
|
17273
|
-
const walkerSchema =
|
|
17389
|
+
bt.walkerValidationService.validate(walkerName, WALKER_METHOD_NAME_DUMP);
|
|
17390
|
+
const walkerSchema = bt.walkerSchemaService.get(walkerName);
|
|
17274
17391
|
for (const strategyName of walkerSchema.strategies) {
|
|
17275
|
-
|
|
17276
|
-
const { riskName, riskList } =
|
|
17392
|
+
bt.strategyValidationService.validate(strategyName, WALKER_METHOD_NAME_DUMP);
|
|
17393
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17277
17394
|
riskName &&
|
|
17278
|
-
|
|
17395
|
+
bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_DUMP);
|
|
17279
17396
|
riskList &&
|
|
17280
|
-
riskList.forEach((riskName) =>
|
|
17397
|
+
riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, WALKER_METHOD_NAME_DUMP));
|
|
17281
17398
|
}
|
|
17282
17399
|
const instance = this._getInstance(symbol, walkerName);
|
|
17283
17400
|
return await instance.dump(symbol, walkerName, path, strategyColumns, pnlColumns);
|
|
@@ -17369,15 +17486,15 @@ class HeatUtils {
|
|
|
17369
17486
|
* });
|
|
17370
17487
|
* ```
|
|
17371
17488
|
*/
|
|
17372
|
-
this.getData = async (strategyName) => {
|
|
17373
|
-
|
|
17374
|
-
|
|
17489
|
+
this.getData = async (strategyName, backtest) => {
|
|
17490
|
+
bt.loggerService.info(HEAT_METHOD_NAME_GET_DATA, { strategyName });
|
|
17491
|
+
bt.strategyValidationService.validate(strategyName, HEAT_METHOD_NAME_GET_DATA);
|
|
17375
17492
|
{
|
|
17376
|
-
const { riskName, riskList } =
|
|
17377
|
-
riskName &&
|
|
17378
|
-
riskList && riskList.forEach((riskName) =>
|
|
17493
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17494
|
+
riskName && bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_DATA);
|
|
17495
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_DATA));
|
|
17379
17496
|
}
|
|
17380
|
-
return await
|
|
17497
|
+
return await bt.heatMarkdownService.getData(strategyName, backtest);
|
|
17381
17498
|
};
|
|
17382
17499
|
/**
|
|
17383
17500
|
* Generates markdown report with portfolio heatmap table for a strategy.
|
|
@@ -17405,15 +17522,15 @@ class HeatUtils {
|
|
|
17405
17522
|
* // ...
|
|
17406
17523
|
* ```
|
|
17407
17524
|
*/
|
|
17408
|
-
this.getReport = async (strategyName, columns) => {
|
|
17409
|
-
|
|
17410
|
-
|
|
17525
|
+
this.getReport = async (strategyName, backtest, columns) => {
|
|
17526
|
+
bt.loggerService.info(HEAT_METHOD_NAME_GET_REPORT, { strategyName });
|
|
17527
|
+
bt.strategyValidationService.validate(strategyName, HEAT_METHOD_NAME_GET_REPORT);
|
|
17411
17528
|
{
|
|
17412
|
-
const { riskName, riskList } =
|
|
17413
|
-
riskName &&
|
|
17414
|
-
riskList && riskList.forEach((riskName) =>
|
|
17529
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17530
|
+
riskName && bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_REPORT);
|
|
17531
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_GET_REPORT));
|
|
17415
17532
|
}
|
|
17416
|
-
return await
|
|
17533
|
+
return await bt.heatMarkdownService.getReport(strategyName, backtest, columns);
|
|
17417
17534
|
};
|
|
17418
17535
|
/**
|
|
17419
17536
|
* Saves heatmap report to disk for a strategy.
|
|
@@ -17434,15 +17551,15 @@ class HeatUtils {
|
|
|
17434
17551
|
* await Heat.dump("my-strategy", "./reports");
|
|
17435
17552
|
* ```
|
|
17436
17553
|
*/
|
|
17437
|
-
this.dump = async (strategyName, path, columns) => {
|
|
17438
|
-
|
|
17439
|
-
|
|
17554
|
+
this.dump = async (strategyName, backtest, path, columns) => {
|
|
17555
|
+
bt.loggerService.info(HEAT_METHOD_NAME_DUMP, { strategyName, path });
|
|
17556
|
+
bt.strategyValidationService.validate(strategyName, HEAT_METHOD_NAME_DUMP);
|
|
17440
17557
|
{
|
|
17441
|
-
const { riskName, riskList } =
|
|
17442
|
-
riskName &&
|
|
17443
|
-
riskList && riskList.forEach((riskName) =>
|
|
17558
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17559
|
+
riskName && bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_DUMP);
|
|
17560
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, HEAT_METHOD_NAME_DUMP));
|
|
17444
17561
|
}
|
|
17445
|
-
await
|
|
17562
|
+
await bt.heatMarkdownService.dump(strategyName, backtest, path, columns);
|
|
17446
17563
|
};
|
|
17447
17564
|
}
|
|
17448
17565
|
}
|
|
@@ -17529,12 +17646,12 @@ class PositionSizeUtils {
|
|
|
17529
17646
|
* @throws Error if sizing schema method is not "fixed-percentage"
|
|
17530
17647
|
*/
|
|
17531
17648
|
PositionSizeUtils.fixedPercentage = async (symbol, accountBalance, priceOpen, priceStopLoss, context) => {
|
|
17532
|
-
|
|
17649
|
+
bt.loggerService.info(POSITION_SIZE_METHOD_NAME_FIXED, {
|
|
17533
17650
|
context,
|
|
17534
17651
|
symbol,
|
|
17535
17652
|
});
|
|
17536
|
-
|
|
17537
|
-
return await
|
|
17653
|
+
bt.sizingValidationService.validate(context.sizingName, POSITION_SIZE_METHOD_NAME_FIXED, "fixed-percentage");
|
|
17654
|
+
return await bt.sizingGlobalService.calculate({
|
|
17538
17655
|
symbol,
|
|
17539
17656
|
accountBalance,
|
|
17540
17657
|
priceOpen,
|
|
@@ -17555,12 +17672,12 @@ PositionSizeUtils.fixedPercentage = async (symbol, accountBalance, priceOpen, pr
|
|
|
17555
17672
|
* @throws Error if sizing schema method is not "kelly-criterion"
|
|
17556
17673
|
*/
|
|
17557
17674
|
PositionSizeUtils.kellyCriterion = async (symbol, accountBalance, priceOpen, winRate, winLossRatio, context) => {
|
|
17558
|
-
|
|
17675
|
+
bt.loggerService.info(POSITION_SIZE_METHOD_NAME_KELLY, {
|
|
17559
17676
|
context,
|
|
17560
17677
|
symbol,
|
|
17561
17678
|
});
|
|
17562
|
-
|
|
17563
|
-
return await
|
|
17679
|
+
bt.sizingValidationService.validate(context.sizingName, POSITION_SIZE_METHOD_NAME_KELLY, "kelly-criterion");
|
|
17680
|
+
return await bt.sizingGlobalService.calculate({
|
|
17564
17681
|
symbol,
|
|
17565
17682
|
accountBalance,
|
|
17566
17683
|
priceOpen,
|
|
@@ -17581,12 +17698,12 @@ PositionSizeUtils.kellyCriterion = async (symbol, accountBalance, priceOpen, win
|
|
|
17581
17698
|
* @throws Error if sizing schema method is not "atr-based"
|
|
17582
17699
|
*/
|
|
17583
17700
|
PositionSizeUtils.atrBased = async (symbol, accountBalance, priceOpen, atr, context) => {
|
|
17584
|
-
|
|
17701
|
+
bt.loggerService.info(POSITION_SIZE_METHOD_NAME_ATR, {
|
|
17585
17702
|
context,
|
|
17586
17703
|
symbol,
|
|
17587
17704
|
});
|
|
17588
|
-
|
|
17589
|
-
return await
|
|
17705
|
+
bt.sizingValidationService.validate(context.sizingName, POSITION_SIZE_METHOD_NAME_ATR, "atr-based");
|
|
17706
|
+
return await bt.sizingGlobalService.calculate({
|
|
17590
17707
|
symbol,
|
|
17591
17708
|
accountBalance,
|
|
17592
17709
|
priceOpen,
|
|
@@ -17635,12 +17752,12 @@ class OptimizerUtils {
|
|
|
17635
17752
|
* @throws Error if optimizer not found
|
|
17636
17753
|
*/
|
|
17637
17754
|
this.getData = async (symbol, context) => {
|
|
17638
|
-
|
|
17755
|
+
bt.loggerService.info(OPTIMIZER_METHOD_NAME_GET_DATA, {
|
|
17639
17756
|
symbol,
|
|
17640
17757
|
context,
|
|
17641
17758
|
});
|
|
17642
|
-
|
|
17643
|
-
return await
|
|
17759
|
+
bt.optimizerValidationService.validate(context.optimizerName, OPTIMIZER_METHOD_NAME_GET_DATA);
|
|
17760
|
+
return await bt.optimizerGlobalService.getData(symbol, context.optimizerName);
|
|
17644
17761
|
};
|
|
17645
17762
|
/**
|
|
17646
17763
|
* Generates complete executable strategy code.
|
|
@@ -17652,12 +17769,12 @@ class OptimizerUtils {
|
|
|
17652
17769
|
* @throws Error if optimizer not found
|
|
17653
17770
|
*/
|
|
17654
17771
|
this.getCode = async (symbol, context) => {
|
|
17655
|
-
|
|
17772
|
+
bt.loggerService.info(OPTIMIZER_METHOD_NAME_GET_CODE, {
|
|
17656
17773
|
symbol,
|
|
17657
17774
|
context,
|
|
17658
17775
|
});
|
|
17659
|
-
|
|
17660
|
-
return await
|
|
17776
|
+
bt.optimizerValidationService.validate(context.optimizerName, OPTIMIZER_METHOD_NAME_GET_CODE);
|
|
17777
|
+
return await bt.optimizerGlobalService.getCode(symbol, context.optimizerName);
|
|
17661
17778
|
};
|
|
17662
17779
|
/**
|
|
17663
17780
|
* Generates and saves strategy code to file.
|
|
@@ -17671,13 +17788,13 @@ class OptimizerUtils {
|
|
|
17671
17788
|
* @throws Error if optimizer not found or file write fails
|
|
17672
17789
|
*/
|
|
17673
17790
|
this.dump = async (symbol, context, path) => {
|
|
17674
|
-
|
|
17791
|
+
bt.loggerService.info(OPTIMIZER_METHOD_NAME_DUMP, {
|
|
17675
17792
|
symbol,
|
|
17676
17793
|
context,
|
|
17677
17794
|
path,
|
|
17678
17795
|
});
|
|
17679
|
-
|
|
17680
|
-
await
|
|
17796
|
+
bt.optimizerValidationService.validate(context.optimizerName, OPTIMIZER_METHOD_NAME_DUMP);
|
|
17797
|
+
await bt.optimizerGlobalService.dump(symbol, context.optimizerName, path);
|
|
17681
17798
|
};
|
|
17682
17799
|
}
|
|
17683
17800
|
}
|
|
@@ -17758,15 +17875,15 @@ class PartialUtils {
|
|
|
17758
17875
|
* }
|
|
17759
17876
|
* ```
|
|
17760
17877
|
*/
|
|
17761
|
-
this.getData = async (symbol, strategyName) => {
|
|
17762
|
-
|
|
17763
|
-
|
|
17878
|
+
this.getData = async (symbol, strategyName, backtest) => {
|
|
17879
|
+
bt.loggerService.info(PARTIAL_METHOD_NAME_GET_DATA, { symbol, strategyName });
|
|
17880
|
+
bt.strategyValidationService.validate(strategyName, PARTIAL_METHOD_NAME_GET_DATA);
|
|
17764
17881
|
{
|
|
17765
|
-
const { riskName, riskList } =
|
|
17766
|
-
riskName &&
|
|
17767
|
-
riskList && riskList.forEach((riskName) =>
|
|
17882
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17883
|
+
riskName && bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_DATA);
|
|
17884
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_DATA));
|
|
17768
17885
|
}
|
|
17769
|
-
return await
|
|
17886
|
+
return await bt.partialMarkdownService.getData(symbol, strategyName, backtest);
|
|
17770
17887
|
};
|
|
17771
17888
|
/**
|
|
17772
17889
|
* Generates markdown report with all partial profit/loss events for a symbol-strategy pair.
|
|
@@ -17807,15 +17924,15 @@ class PartialUtils {
|
|
|
17807
17924
|
* // **Loss events:** 1
|
|
17808
17925
|
* ```
|
|
17809
17926
|
*/
|
|
17810
|
-
this.getReport = async (symbol, strategyName, columns) => {
|
|
17811
|
-
|
|
17812
|
-
|
|
17927
|
+
this.getReport = async (symbol, strategyName, backtest, columns) => {
|
|
17928
|
+
bt.loggerService.info(PARTIAL_METHOD_NAME_GET_REPORT, { symbol, strategyName });
|
|
17929
|
+
bt.strategyValidationService.validate(strategyName, PARTIAL_METHOD_NAME_GET_REPORT);
|
|
17813
17930
|
{
|
|
17814
|
-
const { riskName, riskList } =
|
|
17815
|
-
riskName &&
|
|
17816
|
-
riskList && riskList.forEach((riskName) =>
|
|
17931
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17932
|
+
riskName && bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_REPORT);
|
|
17933
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_GET_REPORT));
|
|
17817
17934
|
}
|
|
17818
|
-
return await
|
|
17935
|
+
return await bt.partialMarkdownService.getReport(symbol, strategyName, backtest, columns);
|
|
17819
17936
|
};
|
|
17820
17937
|
/**
|
|
17821
17938
|
* Generates and saves markdown report to file.
|
|
@@ -17849,15 +17966,15 @@ class PartialUtils {
|
|
|
17849
17966
|
* }
|
|
17850
17967
|
* ```
|
|
17851
17968
|
*/
|
|
17852
|
-
this.dump = async (symbol, strategyName, path, columns) => {
|
|
17853
|
-
|
|
17854
|
-
|
|
17969
|
+
this.dump = async (symbol, strategyName, backtest, path, columns) => {
|
|
17970
|
+
bt.loggerService.info(PARTIAL_METHOD_NAME_DUMP, { symbol, strategyName, path });
|
|
17971
|
+
bt.strategyValidationService.validate(strategyName, PARTIAL_METHOD_NAME_DUMP);
|
|
17855
17972
|
{
|
|
17856
|
-
const { riskName, riskList } =
|
|
17857
|
-
riskName &&
|
|
17858
|
-
riskList && riskList.forEach((riskName) =>
|
|
17973
|
+
const { riskName, riskList } = bt.strategySchemaService.get(strategyName);
|
|
17974
|
+
riskName && bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_DUMP);
|
|
17975
|
+
riskList && riskList.forEach((riskName) => bt.riskValidationService.validate(riskName, PARTIAL_METHOD_NAME_DUMP));
|
|
17859
17976
|
}
|
|
17860
|
-
await
|
|
17977
|
+
await bt.partialMarkdownService.dump(symbol, strategyName, backtest, path, columns);
|
|
17861
17978
|
};
|
|
17862
17979
|
}
|
|
17863
17980
|
}
|