backtest-kit 2.2.6 → 2.2.8
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 +101 -20
- package/build/index.mjs +101 -20
- package/package.json +1 -1
- package/types.d.ts +11 -1
package/build/index.cjs
CHANGED
|
@@ -556,10 +556,19 @@ const activePingSubject = new functoolsKit.Subject();
|
|
|
556
556
|
* Used by StrategyReportService and StrategyMarkdownService for event logging and reporting.
|
|
557
557
|
*/
|
|
558
558
|
const strategyCommitSubject = new functoolsKit.Subject();
|
|
559
|
+
/**
|
|
560
|
+
* ClientStrategy::backtest using return instead of async iterator emitter.
|
|
561
|
+
* If signal was scheduled to open, emits when the signal is actually opened.
|
|
562
|
+
*
|
|
563
|
+
* Allows to yield IStrategyTickResultOpened in addition to IStrategyTickResultClosed | IStrategyTickResultCancelled for
|
|
564
|
+
* BacktestLogicPrivateService::*run
|
|
565
|
+
*/
|
|
566
|
+
const backtestScheduleOpenSubject = new functoolsKit.Subject();
|
|
559
567
|
|
|
560
568
|
var emitters = /*#__PURE__*/Object.freeze({
|
|
561
569
|
__proto__: null,
|
|
562
570
|
activePingSubject: activePingSubject,
|
|
571
|
+
backtestScheduleOpenSubject: backtestScheduleOpenSubject,
|
|
563
572
|
breakevenSubject: breakevenSubject,
|
|
564
573
|
doneBacktestSubject: doneBacktestSubject,
|
|
565
574
|
doneLiveSubject: doneLiveSubject,
|
|
@@ -4231,6 +4240,36 @@ const CALL_BREAKEVEN_CLEAR_FN = functoolsKit.trycatch(beginTime(async (self, sym
|
|
|
4231
4240
|
errorEmitter.next(error);
|
|
4232
4241
|
},
|
|
4233
4242
|
});
|
|
4243
|
+
const CALL_BACKTEST_SCHEDULE_OPEN_FN = functoolsKit.trycatch(beginTime(async (self, symbol, signal, timestamp, backtest) => {
|
|
4244
|
+
await ExecutionContextService.runInContext(async () => {
|
|
4245
|
+
backtestScheduleOpenSubject.next({
|
|
4246
|
+
action: "opened",
|
|
4247
|
+
signal: TO_PUBLIC_SIGNAL(signal),
|
|
4248
|
+
strategyName: self.params.method.context.strategyName,
|
|
4249
|
+
exchangeName: self.params.method.context.exchangeName,
|
|
4250
|
+
frameName: self.params.method.context.frameName,
|
|
4251
|
+
symbol: symbol,
|
|
4252
|
+
currentPrice: signal.priceOpen,
|
|
4253
|
+
backtest: true,
|
|
4254
|
+
createdAt: timestamp,
|
|
4255
|
+
});
|
|
4256
|
+
}, {
|
|
4257
|
+
when: new Date(timestamp),
|
|
4258
|
+
symbol: symbol,
|
|
4259
|
+
backtest: backtest,
|
|
4260
|
+
});
|
|
4261
|
+
}), {
|
|
4262
|
+
fallback: (error) => {
|
|
4263
|
+
const message = "ClientStrategy CALL_BACKTEST_SCHEDULE_OPEN_FN thrown";
|
|
4264
|
+
const payload = {
|
|
4265
|
+
error: functoolsKit.errorData(error),
|
|
4266
|
+
message: functoolsKit.getErrorMessage(error),
|
|
4267
|
+
};
|
|
4268
|
+
bt.loggerService.warn(message, payload);
|
|
4269
|
+
console.warn(message, payload);
|
|
4270
|
+
errorEmitter.next(error);
|
|
4271
|
+
},
|
|
4272
|
+
});
|
|
4234
4273
|
const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice) => {
|
|
4235
4274
|
const currentTime = self.params.execution.context.when.getTime();
|
|
4236
4275
|
await CALL_SCHEDULE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, currentTime, self.params.execution.context.backtest);
|
|
@@ -4520,6 +4559,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, activat
|
|
|
4520
4559
|
await self.setPendingSignal(activatedSignal);
|
|
4521
4560
|
await CALL_RISK_ADD_SIGNAL_FN(self, self.params.execution.context.symbol, activatedSignal, activationTime, self.params.execution.context.backtest);
|
|
4522
4561
|
await CALL_OPEN_CALLBACKS_FN(self, self.params.execution.context.symbol, activatedSignal, activatedSignal.priceOpen, activationTime, self.params.execution.context.backtest);
|
|
4562
|
+
await CALL_BACKTEST_SCHEDULE_OPEN_FN(self, self.params.execution.context.symbol, activatedSignal, activationTime, self.params.execution.context.backtest);
|
|
4523
4563
|
return true;
|
|
4524
4564
|
};
|
|
4525
4565
|
const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, closeReason, closeTimestamp) => {
|
|
@@ -6514,6 +6554,40 @@ class RiskUtils {
|
|
|
6514
6554
|
*/
|
|
6515
6555
|
const Risk = new RiskUtils();
|
|
6516
6556
|
|
|
6557
|
+
/**
|
|
6558
|
+
* Emits signal tick results with correct execution context timestamp.
|
|
6559
|
+
* Wraps emitter calls in ExecutionContextService.runInContext to preserve
|
|
6560
|
+
* the temporal context from the tick's createdAt timestamp.
|
|
6561
|
+
*/
|
|
6562
|
+
const CALL_SIGNAL_EMIT_FN = functoolsKit.trycatch(beginTime(async (self, tick, context, isBacktest, symbol) => {
|
|
6563
|
+
await ExecutionContextService.runInContext(async () => {
|
|
6564
|
+
if (isBacktest) {
|
|
6565
|
+
await signalBacktestEmitter.next(tick);
|
|
6566
|
+
await self.actionCoreService.signalBacktest(isBacktest, tick, context);
|
|
6567
|
+
}
|
|
6568
|
+
if (!isBacktest) {
|
|
6569
|
+
await signalLiveEmitter.next(tick);
|
|
6570
|
+
await self.actionCoreService.signalLive(isBacktest, tick, context);
|
|
6571
|
+
}
|
|
6572
|
+
await signalEmitter.next(tick);
|
|
6573
|
+
await self.actionCoreService.signal(isBacktest, tick, context);
|
|
6574
|
+
}, {
|
|
6575
|
+
when: new Date(tick.createdAt),
|
|
6576
|
+
symbol: symbol,
|
|
6577
|
+
backtest: isBacktest,
|
|
6578
|
+
});
|
|
6579
|
+
}), {
|
|
6580
|
+
fallback: (error) => {
|
|
6581
|
+
const message = "StrategyConnectionService CALL_SIGNAL_EMIT_FN thrown";
|
|
6582
|
+
const payload = {
|
|
6583
|
+
error: functoolsKit.errorData(error),
|
|
6584
|
+
message: functoolsKit.getErrorMessage(error),
|
|
6585
|
+
};
|
|
6586
|
+
bt.loggerService.warn(message, payload);
|
|
6587
|
+
console.warn(message, payload);
|
|
6588
|
+
errorEmitter.next(error);
|
|
6589
|
+
},
|
|
6590
|
+
});
|
|
6517
6591
|
/**
|
|
6518
6592
|
* No-operation IRisk implementation.
|
|
6519
6593
|
* Always allows signals and performs no actions.
|
|
@@ -6886,16 +6960,7 @@ class StrategyConnectionService {
|
|
|
6886
6960
|
await strategy.waitForInit();
|
|
6887
6961
|
const tick = await strategy.tick(symbol, context.strategyName);
|
|
6888
6962
|
{
|
|
6889
|
-
|
|
6890
|
-
await signalBacktestEmitter.next(tick);
|
|
6891
|
-
await this.actionCoreService.signalBacktest(backtest, tick, context);
|
|
6892
|
-
}
|
|
6893
|
-
if (!this.executionContextService.context.backtest) {
|
|
6894
|
-
await signalLiveEmitter.next(tick);
|
|
6895
|
-
await this.actionCoreService.signalLive(backtest, tick, context);
|
|
6896
|
-
}
|
|
6897
|
-
await signalEmitter.next(tick);
|
|
6898
|
-
await this.actionCoreService.signal(backtest, tick, context);
|
|
6963
|
+
await CALL_SIGNAL_EMIT_FN(this, tick, context, backtest, symbol);
|
|
6899
6964
|
}
|
|
6900
6965
|
return tick;
|
|
6901
6966
|
};
|
|
@@ -6922,16 +6987,7 @@ class StrategyConnectionService {
|
|
|
6922
6987
|
await strategy.waitForInit();
|
|
6923
6988
|
const tick = await strategy.backtest(symbol, context.strategyName, candles);
|
|
6924
6989
|
{
|
|
6925
|
-
|
|
6926
|
-
await signalBacktestEmitter.next(tick);
|
|
6927
|
-
await this.actionCoreService.signalBacktest(backtest, tick, context);
|
|
6928
|
-
}
|
|
6929
|
-
if (!this.executionContextService.context.backtest) {
|
|
6930
|
-
await signalLiveEmitter.next(tick);
|
|
6931
|
-
await this.actionCoreService.signalLive(backtest, tick, context);
|
|
6932
|
-
}
|
|
6933
|
-
await signalEmitter.next(tick);
|
|
6934
|
-
await this.actionCoreService.signal(backtest, tick, context);
|
|
6990
|
+
await CALL_SIGNAL_EMIT_FN(this, tick, context, backtest, symbol);
|
|
6935
6991
|
}
|
|
6936
6992
|
return tick;
|
|
6937
6993
|
};
|
|
@@ -11961,6 +12017,7 @@ class BacktestLogicPrivateService {
|
|
|
11961
12017
|
this.exchangeCoreService = inject(TYPES.exchangeCoreService);
|
|
11962
12018
|
this.frameCoreService = inject(TYPES.frameCoreService);
|
|
11963
12019
|
this.methodContextService = inject(TYPES.methodContextService);
|
|
12020
|
+
this.actionCoreService = inject(TYPES.actionCoreService);
|
|
11964
12021
|
}
|
|
11965
12022
|
/**
|
|
11966
12023
|
* Runs backtest for a symbol, streaming closed signals as async generator.
|
|
@@ -12095,6 +12152,27 @@ class BacktestLogicPrivateService {
|
|
|
12095
12152
|
// backtest() сам обработает scheduled signal: найдет активацию/отмену
|
|
12096
12153
|
// и если активируется - продолжит с TP/SL мониторингом
|
|
12097
12154
|
let backtestResult;
|
|
12155
|
+
let unScheduleOpen;
|
|
12156
|
+
{
|
|
12157
|
+
const { strategyName, exchangeName, frameName } = this.methodContextService.context;
|
|
12158
|
+
unScheduleOpen = backtestScheduleOpenSubject.filter((event) => {
|
|
12159
|
+
let isOk = true;
|
|
12160
|
+
{
|
|
12161
|
+
isOk = isOk && event.strategyName === strategyName;
|
|
12162
|
+
isOk = isOk && event.exchangeName === exchangeName;
|
|
12163
|
+
isOk = isOk && event.frameName === frameName;
|
|
12164
|
+
isOk = isOk && event.symbol === symbol;
|
|
12165
|
+
}
|
|
12166
|
+
return isOk;
|
|
12167
|
+
}).connect(async (tick) => {
|
|
12168
|
+
await signalBacktestEmitter.next(tick);
|
|
12169
|
+
await this.actionCoreService.signalBacktest(true, tick, {
|
|
12170
|
+
strategyName,
|
|
12171
|
+
exchangeName,
|
|
12172
|
+
frameName,
|
|
12173
|
+
});
|
|
12174
|
+
});
|
|
12175
|
+
}
|
|
12098
12176
|
try {
|
|
12099
12177
|
backtestResult = await this.strategyCoreService.backtest(symbol, candles, when, true, {
|
|
12100
12178
|
strategyName: this.methodContextService.context.strategyName,
|
|
@@ -12113,6 +12191,9 @@ class BacktestLogicPrivateService {
|
|
|
12113
12191
|
i++;
|
|
12114
12192
|
continue;
|
|
12115
12193
|
}
|
|
12194
|
+
finally {
|
|
12195
|
+
unScheduleOpen && unScheduleOpen();
|
|
12196
|
+
}
|
|
12116
12197
|
this.loggerService.info("backtestLogicPrivateService scheduled signal closed", {
|
|
12117
12198
|
symbol,
|
|
12118
12199
|
signalId: backtestResult.signal.id,
|
package/build/index.mjs
CHANGED
|
@@ -536,10 +536,19 @@ const activePingSubject = new Subject();
|
|
|
536
536
|
* Used by StrategyReportService and StrategyMarkdownService for event logging and reporting.
|
|
537
537
|
*/
|
|
538
538
|
const strategyCommitSubject = new Subject();
|
|
539
|
+
/**
|
|
540
|
+
* ClientStrategy::backtest using return instead of async iterator emitter.
|
|
541
|
+
* If signal was scheduled to open, emits when the signal is actually opened.
|
|
542
|
+
*
|
|
543
|
+
* Allows to yield IStrategyTickResultOpened in addition to IStrategyTickResultClosed | IStrategyTickResultCancelled for
|
|
544
|
+
* BacktestLogicPrivateService::*run
|
|
545
|
+
*/
|
|
546
|
+
const backtestScheduleOpenSubject = new Subject();
|
|
539
547
|
|
|
540
548
|
var emitters = /*#__PURE__*/Object.freeze({
|
|
541
549
|
__proto__: null,
|
|
542
550
|
activePingSubject: activePingSubject,
|
|
551
|
+
backtestScheduleOpenSubject: backtestScheduleOpenSubject,
|
|
543
552
|
breakevenSubject: breakevenSubject,
|
|
544
553
|
doneBacktestSubject: doneBacktestSubject,
|
|
545
554
|
doneLiveSubject: doneLiveSubject,
|
|
@@ -4211,6 +4220,36 @@ const CALL_BREAKEVEN_CLEAR_FN = trycatch(beginTime(async (self, symbol, signal,
|
|
|
4211
4220
|
errorEmitter.next(error);
|
|
4212
4221
|
},
|
|
4213
4222
|
});
|
|
4223
|
+
const CALL_BACKTEST_SCHEDULE_OPEN_FN = trycatch(beginTime(async (self, symbol, signal, timestamp, backtest) => {
|
|
4224
|
+
await ExecutionContextService.runInContext(async () => {
|
|
4225
|
+
backtestScheduleOpenSubject.next({
|
|
4226
|
+
action: "opened",
|
|
4227
|
+
signal: TO_PUBLIC_SIGNAL(signal),
|
|
4228
|
+
strategyName: self.params.method.context.strategyName,
|
|
4229
|
+
exchangeName: self.params.method.context.exchangeName,
|
|
4230
|
+
frameName: self.params.method.context.frameName,
|
|
4231
|
+
symbol: symbol,
|
|
4232
|
+
currentPrice: signal.priceOpen,
|
|
4233
|
+
backtest: true,
|
|
4234
|
+
createdAt: timestamp,
|
|
4235
|
+
});
|
|
4236
|
+
}, {
|
|
4237
|
+
when: new Date(timestamp),
|
|
4238
|
+
symbol: symbol,
|
|
4239
|
+
backtest: backtest,
|
|
4240
|
+
});
|
|
4241
|
+
}), {
|
|
4242
|
+
fallback: (error) => {
|
|
4243
|
+
const message = "ClientStrategy CALL_BACKTEST_SCHEDULE_OPEN_FN thrown";
|
|
4244
|
+
const payload = {
|
|
4245
|
+
error: errorData(error),
|
|
4246
|
+
message: getErrorMessage(error),
|
|
4247
|
+
};
|
|
4248
|
+
bt.loggerService.warn(message, payload);
|
|
4249
|
+
console.warn(message, payload);
|
|
4250
|
+
errorEmitter.next(error);
|
|
4251
|
+
},
|
|
4252
|
+
});
|
|
4214
4253
|
const RETURN_SCHEDULED_SIGNAL_ACTIVE_FN = async (self, scheduled, currentPrice) => {
|
|
4215
4254
|
const currentTime = self.params.execution.context.when.getTime();
|
|
4216
4255
|
await CALL_SCHEDULE_PING_CALLBACKS_FN(self, self.params.execution.context.symbol, scheduled, currentTime, self.params.execution.context.backtest);
|
|
@@ -4500,6 +4539,7 @@ const ACTIVATE_SCHEDULED_SIGNAL_IN_BACKTEST_FN = async (self, scheduled, activat
|
|
|
4500
4539
|
await self.setPendingSignal(activatedSignal);
|
|
4501
4540
|
await CALL_RISK_ADD_SIGNAL_FN(self, self.params.execution.context.symbol, activatedSignal, activationTime, self.params.execution.context.backtest);
|
|
4502
4541
|
await CALL_OPEN_CALLBACKS_FN(self, self.params.execution.context.symbol, activatedSignal, activatedSignal.priceOpen, activationTime, self.params.execution.context.backtest);
|
|
4542
|
+
await CALL_BACKTEST_SCHEDULE_OPEN_FN(self, self.params.execution.context.symbol, activatedSignal, activationTime, self.params.execution.context.backtest);
|
|
4503
4543
|
return true;
|
|
4504
4544
|
};
|
|
4505
4545
|
const CLOSE_PENDING_SIGNAL_IN_BACKTEST_FN = async (self, signal, averagePrice, closeReason, closeTimestamp) => {
|
|
@@ -6494,6 +6534,40 @@ class RiskUtils {
|
|
|
6494
6534
|
*/
|
|
6495
6535
|
const Risk = new RiskUtils();
|
|
6496
6536
|
|
|
6537
|
+
/**
|
|
6538
|
+
* Emits signal tick results with correct execution context timestamp.
|
|
6539
|
+
* Wraps emitter calls in ExecutionContextService.runInContext to preserve
|
|
6540
|
+
* the temporal context from the tick's createdAt timestamp.
|
|
6541
|
+
*/
|
|
6542
|
+
const CALL_SIGNAL_EMIT_FN = trycatch(beginTime(async (self, tick, context, isBacktest, symbol) => {
|
|
6543
|
+
await ExecutionContextService.runInContext(async () => {
|
|
6544
|
+
if (isBacktest) {
|
|
6545
|
+
await signalBacktestEmitter.next(tick);
|
|
6546
|
+
await self.actionCoreService.signalBacktest(isBacktest, tick, context);
|
|
6547
|
+
}
|
|
6548
|
+
if (!isBacktest) {
|
|
6549
|
+
await signalLiveEmitter.next(tick);
|
|
6550
|
+
await self.actionCoreService.signalLive(isBacktest, tick, context);
|
|
6551
|
+
}
|
|
6552
|
+
await signalEmitter.next(tick);
|
|
6553
|
+
await self.actionCoreService.signal(isBacktest, tick, context);
|
|
6554
|
+
}, {
|
|
6555
|
+
when: new Date(tick.createdAt),
|
|
6556
|
+
symbol: symbol,
|
|
6557
|
+
backtest: isBacktest,
|
|
6558
|
+
});
|
|
6559
|
+
}), {
|
|
6560
|
+
fallback: (error) => {
|
|
6561
|
+
const message = "StrategyConnectionService CALL_SIGNAL_EMIT_FN thrown";
|
|
6562
|
+
const payload = {
|
|
6563
|
+
error: errorData(error),
|
|
6564
|
+
message: getErrorMessage(error),
|
|
6565
|
+
};
|
|
6566
|
+
bt.loggerService.warn(message, payload);
|
|
6567
|
+
console.warn(message, payload);
|
|
6568
|
+
errorEmitter.next(error);
|
|
6569
|
+
},
|
|
6570
|
+
});
|
|
6497
6571
|
/**
|
|
6498
6572
|
* No-operation IRisk implementation.
|
|
6499
6573
|
* Always allows signals and performs no actions.
|
|
@@ -6866,16 +6940,7 @@ class StrategyConnectionService {
|
|
|
6866
6940
|
await strategy.waitForInit();
|
|
6867
6941
|
const tick = await strategy.tick(symbol, context.strategyName);
|
|
6868
6942
|
{
|
|
6869
|
-
|
|
6870
|
-
await signalBacktestEmitter.next(tick);
|
|
6871
|
-
await this.actionCoreService.signalBacktest(backtest, tick, context);
|
|
6872
|
-
}
|
|
6873
|
-
if (!this.executionContextService.context.backtest) {
|
|
6874
|
-
await signalLiveEmitter.next(tick);
|
|
6875
|
-
await this.actionCoreService.signalLive(backtest, tick, context);
|
|
6876
|
-
}
|
|
6877
|
-
await signalEmitter.next(tick);
|
|
6878
|
-
await this.actionCoreService.signal(backtest, tick, context);
|
|
6943
|
+
await CALL_SIGNAL_EMIT_FN(this, tick, context, backtest, symbol);
|
|
6879
6944
|
}
|
|
6880
6945
|
return tick;
|
|
6881
6946
|
};
|
|
@@ -6902,16 +6967,7 @@ class StrategyConnectionService {
|
|
|
6902
6967
|
await strategy.waitForInit();
|
|
6903
6968
|
const tick = await strategy.backtest(symbol, context.strategyName, candles);
|
|
6904
6969
|
{
|
|
6905
|
-
|
|
6906
|
-
await signalBacktestEmitter.next(tick);
|
|
6907
|
-
await this.actionCoreService.signalBacktest(backtest, tick, context);
|
|
6908
|
-
}
|
|
6909
|
-
if (!this.executionContextService.context.backtest) {
|
|
6910
|
-
await signalLiveEmitter.next(tick);
|
|
6911
|
-
await this.actionCoreService.signalLive(backtest, tick, context);
|
|
6912
|
-
}
|
|
6913
|
-
await signalEmitter.next(tick);
|
|
6914
|
-
await this.actionCoreService.signal(backtest, tick, context);
|
|
6970
|
+
await CALL_SIGNAL_EMIT_FN(this, tick, context, backtest, symbol);
|
|
6915
6971
|
}
|
|
6916
6972
|
return tick;
|
|
6917
6973
|
};
|
|
@@ -11941,6 +11997,7 @@ class BacktestLogicPrivateService {
|
|
|
11941
11997
|
this.exchangeCoreService = inject(TYPES.exchangeCoreService);
|
|
11942
11998
|
this.frameCoreService = inject(TYPES.frameCoreService);
|
|
11943
11999
|
this.methodContextService = inject(TYPES.methodContextService);
|
|
12000
|
+
this.actionCoreService = inject(TYPES.actionCoreService);
|
|
11944
12001
|
}
|
|
11945
12002
|
/**
|
|
11946
12003
|
* Runs backtest for a symbol, streaming closed signals as async generator.
|
|
@@ -12075,6 +12132,27 @@ class BacktestLogicPrivateService {
|
|
|
12075
12132
|
// backtest() сам обработает scheduled signal: найдет активацию/отмену
|
|
12076
12133
|
// и если активируется - продолжит с TP/SL мониторингом
|
|
12077
12134
|
let backtestResult;
|
|
12135
|
+
let unScheduleOpen;
|
|
12136
|
+
{
|
|
12137
|
+
const { strategyName, exchangeName, frameName } = this.methodContextService.context;
|
|
12138
|
+
unScheduleOpen = backtestScheduleOpenSubject.filter((event) => {
|
|
12139
|
+
let isOk = true;
|
|
12140
|
+
{
|
|
12141
|
+
isOk = isOk && event.strategyName === strategyName;
|
|
12142
|
+
isOk = isOk && event.exchangeName === exchangeName;
|
|
12143
|
+
isOk = isOk && event.frameName === frameName;
|
|
12144
|
+
isOk = isOk && event.symbol === symbol;
|
|
12145
|
+
}
|
|
12146
|
+
return isOk;
|
|
12147
|
+
}).connect(async (tick) => {
|
|
12148
|
+
await signalBacktestEmitter.next(tick);
|
|
12149
|
+
await this.actionCoreService.signalBacktest(true, tick, {
|
|
12150
|
+
strategyName,
|
|
12151
|
+
exchangeName,
|
|
12152
|
+
frameName,
|
|
12153
|
+
});
|
|
12154
|
+
});
|
|
12155
|
+
}
|
|
12078
12156
|
try {
|
|
12079
12157
|
backtestResult = await this.strategyCoreService.backtest(symbol, candles, when, true, {
|
|
12080
12158
|
strategyName: this.methodContextService.context.strategyName,
|
|
@@ -12093,6 +12171,9 @@ class BacktestLogicPrivateService {
|
|
|
12093
12171
|
i++;
|
|
12094
12172
|
continue;
|
|
12095
12173
|
}
|
|
12174
|
+
finally {
|
|
12175
|
+
unScheduleOpen && unScheduleOpen();
|
|
12176
|
+
}
|
|
12096
12177
|
this.loggerService.info("backtestLogicPrivateService scheduled signal closed", {
|
|
12097
12178
|
symbol,
|
|
12098
12179
|
signalId: backtestResult.signal.id,
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -14734,8 +14734,17 @@ declare const activePingSubject: Subject<ActivePingContract>;
|
|
|
14734
14734
|
* Used by StrategyReportService and StrategyMarkdownService for event logging and reporting.
|
|
14735
14735
|
*/
|
|
14736
14736
|
declare const strategyCommitSubject: Subject<StrategyCommitContract>;
|
|
14737
|
+
/**
|
|
14738
|
+
* ClientStrategy::backtest using return instead of async iterator emitter.
|
|
14739
|
+
* If signal was scheduled to open, emits when the signal is actually opened.
|
|
14740
|
+
*
|
|
14741
|
+
* Allows to yield IStrategyTickResultOpened in addition to IStrategyTickResultClosed | IStrategyTickResultCancelled for
|
|
14742
|
+
* BacktestLogicPrivateService::*run
|
|
14743
|
+
*/
|
|
14744
|
+
declare const backtestScheduleOpenSubject: Subject<IStrategyTickResultOpened>;
|
|
14737
14745
|
|
|
14738
14746
|
declare const emitters_activePingSubject: typeof activePingSubject;
|
|
14747
|
+
declare const emitters_backtestScheduleOpenSubject: typeof backtestScheduleOpenSubject;
|
|
14739
14748
|
declare const emitters_breakevenSubject: typeof breakevenSubject;
|
|
14740
14749
|
declare const emitters_doneBacktestSubject: typeof doneBacktestSubject;
|
|
14741
14750
|
declare const emitters_doneLiveSubject: typeof doneLiveSubject;
|
|
@@ -14758,7 +14767,7 @@ declare const emitters_walkerCompleteSubject: typeof walkerCompleteSubject;
|
|
|
14758
14767
|
declare const emitters_walkerEmitter: typeof walkerEmitter;
|
|
14759
14768
|
declare const emitters_walkerStopSubject: typeof walkerStopSubject;
|
|
14760
14769
|
declare namespace emitters {
|
|
14761
|
-
export { emitters_activePingSubject as activePingSubject, emitters_breakevenSubject as breakevenSubject, emitters_doneBacktestSubject as doneBacktestSubject, emitters_doneLiveSubject as doneLiveSubject, emitters_doneWalkerSubject as doneWalkerSubject, emitters_errorEmitter as errorEmitter, emitters_exitEmitter as exitEmitter, emitters_partialLossSubject as partialLossSubject, emitters_partialProfitSubject as partialProfitSubject, emitters_performanceEmitter as performanceEmitter, emitters_progressBacktestEmitter as progressBacktestEmitter, emitters_progressWalkerEmitter as progressWalkerEmitter, emitters_riskSubject as riskSubject, emitters_schedulePingSubject as schedulePingSubject, emitters_signalBacktestEmitter as signalBacktestEmitter, emitters_signalEmitter as signalEmitter, emitters_signalLiveEmitter as signalLiveEmitter, emitters_strategyCommitSubject as strategyCommitSubject, emitters_validationSubject as validationSubject, emitters_walkerCompleteSubject as walkerCompleteSubject, emitters_walkerEmitter as walkerEmitter, emitters_walkerStopSubject as walkerStopSubject };
|
|
14770
|
+
export { emitters_activePingSubject as activePingSubject, emitters_backtestScheduleOpenSubject as backtestScheduleOpenSubject, emitters_breakevenSubject as breakevenSubject, emitters_doneBacktestSubject as doneBacktestSubject, emitters_doneLiveSubject as doneLiveSubject, emitters_doneWalkerSubject as doneWalkerSubject, emitters_errorEmitter as errorEmitter, emitters_exitEmitter as exitEmitter, emitters_partialLossSubject as partialLossSubject, emitters_partialProfitSubject as partialProfitSubject, emitters_performanceEmitter as performanceEmitter, emitters_progressBacktestEmitter as progressBacktestEmitter, emitters_progressWalkerEmitter as progressWalkerEmitter, emitters_riskSubject as riskSubject, emitters_schedulePingSubject as schedulePingSubject, emitters_signalBacktestEmitter as signalBacktestEmitter, emitters_signalEmitter as signalEmitter, emitters_signalLiveEmitter as signalLiveEmitter, emitters_strategyCommitSubject as strategyCommitSubject, emitters_validationSubject as validationSubject, emitters_walkerCompleteSubject as walkerCompleteSubject, emitters_walkerEmitter as walkerEmitter, emitters_walkerStopSubject as walkerStopSubject };
|
|
14762
14771
|
}
|
|
14763
14772
|
|
|
14764
14773
|
/**
|
|
@@ -17427,6 +17436,7 @@ declare class BacktestLogicPrivateService {
|
|
|
17427
17436
|
private readonly exchangeCoreService;
|
|
17428
17437
|
private readonly frameCoreService;
|
|
17429
17438
|
private readonly methodContextService;
|
|
17439
|
+
private readonly actionCoreService;
|
|
17430
17440
|
/**
|
|
17431
17441
|
* Runs backtest for a symbol, streaming closed signals as async generator.
|
|
17432
17442
|
*
|