backtest-kit 9.7.0 → 9.8.1
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/LICENSE +21 -21
- package/README.md +1871 -1871
- package/build/index.cjs +283 -180
- package/build/index.mjs +284 -181
- package/package.json +86 -86
- package/types.d.ts +100 -28
package/build/index.cjs
CHANGED
|
@@ -36127,72 +36127,41 @@ const PRINT_PROGRESS_FN = (fetched, total, symbol, interval) => {
|
|
|
36127
36127
|
}
|
|
36128
36128
|
};
|
|
36129
36129
|
/**
|
|
36130
|
-
* Checks cached candle
|
|
36131
|
-
*
|
|
36130
|
+
* Checks cached candle presence via the persist adapter.
|
|
36131
|
+
* Issues one ranged read; adapter-side `hasValue` covers each expected timestamp,
|
|
36132
|
+
* so a single missing or unaligned candle yields a miss without loading the whole dataset.
|
|
36132
36133
|
*
|
|
36133
36134
|
* @param params - Validation parameters
|
|
36134
36135
|
*/
|
|
36135
36136
|
async function checkCandles(params) {
|
|
36136
|
-
const { symbol, exchangeName, interval, from, to
|
|
36137
|
+
const { symbol, exchangeName, interval, from, to } = params;
|
|
36137
36138
|
backtest.loggerService.info(CHECK_CANDLES_METHOD_NAME, params);
|
|
36138
36139
|
const step = INTERVAL_MINUTES$3[interval];
|
|
36139
36140
|
if (!step) {
|
|
36140
36141
|
throw new Error(`checkCandles: unsupported interval=${interval}`);
|
|
36141
36142
|
}
|
|
36142
36143
|
const stepMs = step * MS_PER_MINUTE$3;
|
|
36143
|
-
const dir = path.join(baseDir, exchangeName, symbol, interval);
|
|
36144
36144
|
const fromTs = ALIGN_TO_INTERVAL_FN(from.getTime(), step);
|
|
36145
36145
|
const toTs = ALIGN_TO_INTERVAL_FN(to.getTime(), step);
|
|
36146
|
-
|
|
36147
|
-
|
|
36148
|
-
|
|
36149
|
-
catch {
|
|
36150
|
-
throw new Error(`checkCandles: cache directory not found: ${dir}`);
|
|
36151
|
-
}
|
|
36152
|
-
// Collect only filenames (strings) in range via async iterator — no full readdir in memory
|
|
36153
|
-
const files = [];
|
|
36154
|
-
for await (const entry of await fs.opendir(dir)) {
|
|
36155
|
-
if (!entry.isFile() || !entry.name.endsWith(".json")) {
|
|
36156
|
-
continue;
|
|
36157
|
-
}
|
|
36158
|
-
const ts = Number(entry.name.replace(".json", ""));
|
|
36159
|
-
if (ts >= fromTs && ts < toTs) {
|
|
36160
|
-
files.push(entry.name);
|
|
36161
|
-
}
|
|
36162
|
-
}
|
|
36163
|
-
if (files.length === 0) {
|
|
36164
|
-
throw new Error(`checkCandles: no cached candles in range [${fromTs}, ${toTs}) in ${dir}`);
|
|
36146
|
+
const totalCandles = Math.floor((toTs - fromTs) / stepMs);
|
|
36147
|
+
if (totalCandles <= 0) {
|
|
36148
|
+
throw new Error(`checkCandles: empty range [${fromTs}, ${toTs}) for ${symbol} ${interval}`);
|
|
36165
36149
|
}
|
|
36166
|
-
|
|
36167
|
-
let
|
|
36168
|
-
|
|
36169
|
-
|
|
36170
|
-
|
|
36171
|
-
const
|
|
36172
|
-
const
|
|
36173
|
-
|
|
36174
|
-
|
|
36175
|
-
candle = JSON.parse(raw);
|
|
36176
|
-
}
|
|
36177
|
-
catch {
|
|
36178
|
-
throw new Error(`checkCandles: ${files[i]} contains invalid JSON`);
|
|
36179
|
-
}
|
|
36180
|
-
const { timestamp } = candle;
|
|
36181
|
-
const aligned = ALIGN_TO_INTERVAL_FN(timestamp, step);
|
|
36182
|
-
if (timestamp !== aligned) {
|
|
36183
|
-
throw new Error(`checkCandles: ${files[i]} timestamp not aligned to ${interval} boundary (actual=${timestamp}, expected=${aligned})`);
|
|
36184
|
-
}
|
|
36185
|
-
if (prevTimestamp !== null) {
|
|
36186
|
-
const gap = timestamp - prevTimestamp;
|
|
36187
|
-
if (gap !== stepMs) {
|
|
36188
|
-
throw new Error(`checkCandles: gap between ${prevName} and ${files[i]} (actual=${gap}ms, expected=${stepMs}ms)`);
|
|
36189
|
-
}
|
|
36150
|
+
let checked = 0;
|
|
36151
|
+
let currentSince = fromTs;
|
|
36152
|
+
PRINT_PROGRESS_FN(checked, totalCandles, symbol, interval);
|
|
36153
|
+
while (checked < totalCandles) {
|
|
36154
|
+
const chunkLimit = Math.min(totalCandles - checked, GLOBAL_CONFIG.CC_MAX_CANDLES_PER_REQUEST);
|
|
36155
|
+
const chunkUntil = currentSince + chunkLimit * stepMs;
|
|
36156
|
+
const candles = await PersistCandleAdapter.readCandlesData(symbol, interval, exchangeName, chunkLimit, currentSince, chunkUntil);
|
|
36157
|
+
if (!candles) {
|
|
36158
|
+
throw new Error(`checkCandles: cache miss for ${symbol} ${interval} [${currentSince}, ${chunkUntil})`);
|
|
36190
36159
|
}
|
|
36191
|
-
|
|
36192
|
-
|
|
36193
|
-
PRINT_PROGRESS_FN(
|
|
36160
|
+
checked += chunkLimit;
|
|
36161
|
+
currentSince = chunkUntil;
|
|
36162
|
+
PRINT_PROGRESS_FN(checked, totalCandles, symbol, interval);
|
|
36194
36163
|
}
|
|
36195
|
-
console.log(`checkCandles: OK ${
|
|
36164
|
+
console.log(`checkCandles: OK ${totalCandles} candles ${symbol} ${interval}`);
|
|
36196
36165
|
}
|
|
36197
36166
|
/**
|
|
36198
36167
|
* Pre-caches candles for a date range into persist storage.
|
|
@@ -37443,7 +37412,19 @@ class BrokerProxy {
|
|
|
37443
37412
|
*/
|
|
37444
37413
|
class BrokerAdapter {
|
|
37445
37414
|
constructor() {
|
|
37446
|
-
|
|
37415
|
+
/** Factory producing the active `BrokerProxy` instance */
|
|
37416
|
+
this._brokerFactory = () => null;
|
|
37417
|
+
/**
|
|
37418
|
+
* Lazily constructs the `BrokerProxy` from the registered factory and
|
|
37419
|
+
* memoizes the result via `singleshot`.
|
|
37420
|
+
*
|
|
37421
|
+
* The proxy is built on the first call and cached for all subsequent calls.
|
|
37422
|
+
* Returns `null` when no adapter has been registered via `useBrokerAdapter()`.
|
|
37423
|
+
*
|
|
37424
|
+
* Reset via `clear()` so the next call rebuilds from the current factory
|
|
37425
|
+
* (e.g. when `process.cwd()` changes between strategy iterations).
|
|
37426
|
+
*/
|
|
37427
|
+
this.getInstance = functoolsKit.singleshot(() => this._brokerFactory());
|
|
37447
37428
|
/**
|
|
37448
37429
|
* Forwards a signal-open event to the registered broker adapter.
|
|
37449
37430
|
*
|
|
@@ -37477,7 +37458,10 @@ class BrokerAdapter {
|
|
|
37477
37458
|
if (payload.backtest) {
|
|
37478
37459
|
return;
|
|
37479
37460
|
}
|
|
37480
|
-
|
|
37461
|
+
const instance = this.getInstance();
|
|
37462
|
+
if (instance) {
|
|
37463
|
+
await instance.onSignalOpenCommit(payload);
|
|
37464
|
+
}
|
|
37481
37465
|
};
|
|
37482
37466
|
/**
|
|
37483
37467
|
* Forwards a signal-close event to the registered broker adapter.
|
|
@@ -37515,7 +37499,10 @@ class BrokerAdapter {
|
|
|
37515
37499
|
if (payload.backtest) {
|
|
37516
37500
|
return;
|
|
37517
37501
|
}
|
|
37518
|
-
|
|
37502
|
+
const instance = this.getInstance();
|
|
37503
|
+
if (instance) {
|
|
37504
|
+
await instance.onSignalCloseCommit(payload);
|
|
37505
|
+
}
|
|
37519
37506
|
};
|
|
37520
37507
|
/**
|
|
37521
37508
|
* Intercepts a partial-profit close before DI-core mutation.
|
|
@@ -37551,7 +37538,10 @@ class BrokerAdapter {
|
|
|
37551
37538
|
if (payload.backtest) {
|
|
37552
37539
|
return;
|
|
37553
37540
|
}
|
|
37554
|
-
|
|
37541
|
+
const instance = this.getInstance();
|
|
37542
|
+
if (instance) {
|
|
37543
|
+
await instance.onPartialProfitCommit(payload);
|
|
37544
|
+
}
|
|
37555
37545
|
};
|
|
37556
37546
|
/**
|
|
37557
37547
|
* Intercepts a partial-loss close before DI-core mutation.
|
|
@@ -37587,7 +37577,10 @@ class BrokerAdapter {
|
|
|
37587
37577
|
if (payload.backtest) {
|
|
37588
37578
|
return;
|
|
37589
37579
|
}
|
|
37590
|
-
|
|
37580
|
+
const instance = this.getInstance();
|
|
37581
|
+
if (instance) {
|
|
37582
|
+
await instance.onPartialLossCommit(payload);
|
|
37583
|
+
}
|
|
37591
37584
|
};
|
|
37592
37585
|
/**
|
|
37593
37586
|
* Intercepts a trailing stop-loss update before DI-core mutation.
|
|
@@ -37623,7 +37616,10 @@ class BrokerAdapter {
|
|
|
37623
37616
|
if (payload.backtest) {
|
|
37624
37617
|
return;
|
|
37625
37618
|
}
|
|
37626
|
-
|
|
37619
|
+
const instance = this.getInstance();
|
|
37620
|
+
if (instance) {
|
|
37621
|
+
await instance.onTrailingStopCommit(payload);
|
|
37622
|
+
}
|
|
37627
37623
|
};
|
|
37628
37624
|
/**
|
|
37629
37625
|
* Intercepts a trailing take-profit update before DI-core mutation.
|
|
@@ -37659,7 +37655,10 @@ class BrokerAdapter {
|
|
|
37659
37655
|
if (payload.backtest) {
|
|
37660
37656
|
return;
|
|
37661
37657
|
}
|
|
37662
|
-
|
|
37658
|
+
const instance = this.getInstance();
|
|
37659
|
+
if (instance) {
|
|
37660
|
+
await instance.onTrailingTakeCommit(payload);
|
|
37661
|
+
}
|
|
37663
37662
|
};
|
|
37664
37663
|
/**
|
|
37665
37664
|
* Intercepts a breakeven operation before DI-core mutation.
|
|
@@ -37696,7 +37695,10 @@ class BrokerAdapter {
|
|
|
37696
37695
|
if (payload.backtest) {
|
|
37697
37696
|
return;
|
|
37698
37697
|
}
|
|
37699
|
-
|
|
37698
|
+
const instance = this.getInstance();
|
|
37699
|
+
if (instance) {
|
|
37700
|
+
await instance.onBreakevenCommit(payload);
|
|
37701
|
+
}
|
|
37700
37702
|
};
|
|
37701
37703
|
/**
|
|
37702
37704
|
* Intercepts a DCA average-buy entry before DI-core mutation.
|
|
@@ -37732,7 +37734,10 @@ class BrokerAdapter {
|
|
|
37732
37734
|
if (payload.backtest) {
|
|
37733
37735
|
return;
|
|
37734
37736
|
}
|
|
37735
|
-
|
|
37737
|
+
const instance = this.getInstance();
|
|
37738
|
+
if (instance) {
|
|
37739
|
+
await instance.onAverageBuyCommit(payload);
|
|
37740
|
+
}
|
|
37736
37741
|
};
|
|
37737
37742
|
/**
|
|
37738
37743
|
* Registers a broker adapter instance or constructor to receive commit* callbacks.
|
|
@@ -37756,11 +37761,12 @@ class BrokerAdapter {
|
|
|
37756
37761
|
this.useBrokerAdapter = (broker) => {
|
|
37757
37762
|
backtest.loggerService.info(BROKER_METHOD_NAME_USE_BROKER_ADAPTER, {});
|
|
37758
37763
|
if (typeof broker === "function") {
|
|
37759
|
-
|
|
37760
|
-
|
|
37761
|
-
|
|
37764
|
+
this._brokerFactory = () => new BrokerProxy(Reflect.construct(broker, []));
|
|
37765
|
+
}
|
|
37766
|
+
else {
|
|
37767
|
+
this._brokerFactory = () => new BrokerProxy(broker);
|
|
37762
37768
|
}
|
|
37763
|
-
this.
|
|
37769
|
+
this.getInstance.clear();
|
|
37764
37770
|
};
|
|
37765
37771
|
/**
|
|
37766
37772
|
* Activates the broker: subscribes to syncSubject for signal-open / signal-close routing.
|
|
@@ -37787,7 +37793,8 @@ class BrokerAdapter {
|
|
|
37787
37793
|
*/
|
|
37788
37794
|
this.enable = functoolsKit.singleshot(() => {
|
|
37789
37795
|
backtest.loggerService.info(BROKER_METHOD_NAME_ENABLE, {});
|
|
37790
|
-
|
|
37796
|
+
const instance = this.getInstance();
|
|
37797
|
+
if (!instance) {
|
|
37791
37798
|
this.enable.clear();
|
|
37792
37799
|
throw new Error("No broker instance provided. Call Broker.useBrokerAdapter first.");
|
|
37793
37800
|
}
|
|
@@ -37875,7 +37882,7 @@ class BrokerAdapter {
|
|
|
37875
37882
|
*/
|
|
37876
37883
|
this.clear = () => {
|
|
37877
37884
|
backtest.loggerService.info(BROKER_METHOD_NAME_CLEAR, {});
|
|
37878
|
-
this.
|
|
37885
|
+
this.getInstance.clear();
|
|
37879
37886
|
this.enable.clear();
|
|
37880
37887
|
};
|
|
37881
37888
|
}
|
|
@@ -48895,8 +48902,16 @@ class RecentMemoryLiveUtils {
|
|
|
48895
48902
|
*/
|
|
48896
48903
|
class RecentBacktestAdapter {
|
|
48897
48904
|
constructor() {
|
|
48898
|
-
/**
|
|
48899
|
-
this.
|
|
48905
|
+
/** Factory producing the active storage utils instance */
|
|
48906
|
+
this._recentBacktestFactory = () => new RecentMemoryBacktestUtils();
|
|
48907
|
+
/**
|
|
48908
|
+
* Lazily constructs the storage utils from the registered factory and memoizes
|
|
48909
|
+
* the result via `singleshot`.
|
|
48910
|
+
*
|
|
48911
|
+
* The instance is built on the first call and cached for all subsequent calls.
|
|
48912
|
+
* Reset via `clear()` so the next call rebuilds from the current factory.
|
|
48913
|
+
*/
|
|
48914
|
+
this.getInstance = functoolsKit.singleshot(() => this._recentBacktestFactory());
|
|
48900
48915
|
/**
|
|
48901
48916
|
* Handles active ping event.
|
|
48902
48917
|
* Proxies call to the underlying storage adapter.
|
|
@@ -48906,7 +48921,7 @@ class RecentBacktestAdapter {
|
|
|
48906
48921
|
backtest.loggerService.info(RECENT_BACKTEST_ADAPTER_METHOD_NAME_HANDLE_ACTIVE_PING, {
|
|
48907
48922
|
signalId: event.data.id,
|
|
48908
48923
|
});
|
|
48909
|
-
return await this.
|
|
48924
|
+
return await this.getInstance().handleActivePing(event);
|
|
48910
48925
|
};
|
|
48911
48926
|
/**
|
|
48912
48927
|
* Retrieves the latest signal for the given context.
|
|
@@ -48927,7 +48942,7 @@ class RecentBacktestAdapter {
|
|
|
48927
48942
|
frameName,
|
|
48928
48943
|
backtest: backtest$1,
|
|
48929
48944
|
});
|
|
48930
|
-
return await this.
|
|
48945
|
+
return await this.getInstance().getLatestSignal(symbol, strategyName, exchangeName, frameName, backtest$1, when);
|
|
48931
48946
|
};
|
|
48932
48947
|
/**
|
|
48933
48948
|
* Returns the number of whole minutes elapsed since the latest signal's creation timestamp.
|
|
@@ -48951,7 +48966,7 @@ class RecentBacktestAdapter {
|
|
|
48951
48966
|
backtest: backtest$1,
|
|
48952
48967
|
timestamp,
|
|
48953
48968
|
});
|
|
48954
|
-
const signal = await this.
|
|
48969
|
+
const signal = await this.getInstance().getLatestSignal(symbol, strategyName, exchangeName, frameName, backtest$1, new Date(timestamp));
|
|
48955
48970
|
if (!signal) {
|
|
48956
48971
|
return null;
|
|
48957
48972
|
}
|
|
@@ -48964,7 +48979,8 @@ class RecentBacktestAdapter {
|
|
|
48964
48979
|
*/
|
|
48965
48980
|
this.useRecentAdapter = (Ctor) => {
|
|
48966
48981
|
backtest.loggerService.info(RECENT_BACKTEST_ADAPTER_METHOD_NAME_USE_ADAPTER);
|
|
48967
|
-
this.
|
|
48982
|
+
this._recentBacktestFactory = () => Reflect.construct(Ctor, []);
|
|
48983
|
+
this.getInstance.clear();
|
|
48968
48984
|
};
|
|
48969
48985
|
/**
|
|
48970
48986
|
* Switches to persistent storage adapter.
|
|
@@ -48972,7 +48988,8 @@ class RecentBacktestAdapter {
|
|
|
48972
48988
|
*/
|
|
48973
48989
|
this.usePersist = () => {
|
|
48974
48990
|
backtest.loggerService.info(RECENT_BACKTEST_ADAPTER_METHOD_NAME_USE_PERSIST);
|
|
48975
|
-
this.
|
|
48991
|
+
this._recentBacktestFactory = () => new RecentPersistBacktestUtils();
|
|
48992
|
+
this.getInstance.clear();
|
|
48976
48993
|
};
|
|
48977
48994
|
/**
|
|
48978
48995
|
* Switches to in-memory storage adapter (default).
|
|
@@ -48980,14 +48997,17 @@ class RecentBacktestAdapter {
|
|
|
48980
48997
|
*/
|
|
48981
48998
|
this.useMemory = () => {
|
|
48982
48999
|
backtest.loggerService.info(RECENT_BACKTEST_ADAPTER_METHOD_NAME_USE_MEMORY);
|
|
48983
|
-
this.
|
|
49000
|
+
this._recentBacktestFactory = () => new RecentMemoryBacktestUtils();
|
|
49001
|
+
this.getInstance.clear();
|
|
48984
49002
|
};
|
|
48985
49003
|
/**
|
|
48986
|
-
* Clears the
|
|
49004
|
+
* Clears the memoized utils instance.
|
|
49005
|
+
* Call this when process.cwd() changes between strategy iterations
|
|
49006
|
+
* so a new instance is created with the updated base path.
|
|
48987
49007
|
*/
|
|
48988
49008
|
this.clear = () => {
|
|
48989
49009
|
backtest.loggerService.info(RECENT_BACKTEST_ADAPTER_METHOD_NAME_CLEAR);
|
|
48990
|
-
this.
|
|
49010
|
+
this.getInstance.clear();
|
|
48991
49011
|
};
|
|
48992
49012
|
}
|
|
48993
49013
|
}
|
|
@@ -49002,8 +49022,16 @@ class RecentBacktestAdapter {
|
|
|
49002
49022
|
*/
|
|
49003
49023
|
class RecentLiveAdapter {
|
|
49004
49024
|
constructor() {
|
|
49005
|
-
/**
|
|
49006
|
-
this.
|
|
49025
|
+
/** Factory producing the active storage utils instance */
|
|
49026
|
+
this._recentLiveFactory = () => new RecentPersistLiveUtils();
|
|
49027
|
+
/**
|
|
49028
|
+
* Lazily constructs the storage utils from the registered factory and memoizes
|
|
49029
|
+
* the result via `singleshot`.
|
|
49030
|
+
*
|
|
49031
|
+
* The instance is built on the first call and cached for all subsequent calls.
|
|
49032
|
+
* Reset via `clear()` so the next call rebuilds from the current factory.
|
|
49033
|
+
*/
|
|
49034
|
+
this.getInstance = functoolsKit.singleshot(() => this._recentLiveFactory());
|
|
49007
49035
|
/**
|
|
49008
49036
|
* Handles active ping event.
|
|
49009
49037
|
* Proxies call to the underlying storage adapter.
|
|
@@ -49013,7 +49041,7 @@ class RecentLiveAdapter {
|
|
|
49013
49041
|
backtest.loggerService.info(RECENT_LIVE_ADAPTER_METHOD_NAME_HANDLE_ACTIVE_PING, {
|
|
49014
49042
|
signalId: event.data.id,
|
|
49015
49043
|
});
|
|
49016
|
-
return await this.
|
|
49044
|
+
return await this.getInstance().handleActivePing(event);
|
|
49017
49045
|
};
|
|
49018
49046
|
/**
|
|
49019
49047
|
* Retrieves the latest signal for the given context.
|
|
@@ -49034,7 +49062,7 @@ class RecentLiveAdapter {
|
|
|
49034
49062
|
frameName,
|
|
49035
49063
|
backtest: backtest$1,
|
|
49036
49064
|
});
|
|
49037
|
-
return await this.
|
|
49065
|
+
return await this.getInstance().getLatestSignal(symbol, strategyName, exchangeName, frameName, backtest$1, when);
|
|
49038
49066
|
};
|
|
49039
49067
|
/**
|
|
49040
49068
|
* Returns the number of whole minutes elapsed since the latest signal's creation timestamp.
|
|
@@ -49058,7 +49086,7 @@ class RecentLiveAdapter {
|
|
|
49058
49086
|
backtest: backtest$1,
|
|
49059
49087
|
timestamp,
|
|
49060
49088
|
});
|
|
49061
|
-
const signal = await this.
|
|
49089
|
+
const signal = await this.getInstance().getLatestSignal(symbol, strategyName, exchangeName, frameName, backtest$1, new Date(timestamp));
|
|
49062
49090
|
if (!signal) {
|
|
49063
49091
|
return null;
|
|
49064
49092
|
}
|
|
@@ -49071,7 +49099,8 @@ class RecentLiveAdapter {
|
|
|
49071
49099
|
*/
|
|
49072
49100
|
this.useRecentAdapter = (Ctor) => {
|
|
49073
49101
|
backtest.loggerService.info(RECENT_LIVE_ADAPTER_METHOD_NAME_USE_ADAPTER);
|
|
49074
|
-
this.
|
|
49102
|
+
this._recentLiveFactory = () => Reflect.construct(Ctor, []);
|
|
49103
|
+
this.getInstance.clear();
|
|
49075
49104
|
};
|
|
49076
49105
|
/**
|
|
49077
49106
|
* Switches to persistent storage adapter (default).
|
|
@@ -49079,7 +49108,8 @@ class RecentLiveAdapter {
|
|
|
49079
49108
|
*/
|
|
49080
49109
|
this.usePersist = () => {
|
|
49081
49110
|
backtest.loggerService.info(RECENT_LIVE_ADAPTER_METHOD_NAME_USE_PERSIST);
|
|
49082
|
-
this.
|
|
49111
|
+
this._recentLiveFactory = () => new RecentPersistLiveUtils();
|
|
49112
|
+
this.getInstance.clear();
|
|
49083
49113
|
};
|
|
49084
49114
|
/**
|
|
49085
49115
|
* Switches to in-memory storage adapter.
|
|
@@ -49087,14 +49117,17 @@ class RecentLiveAdapter {
|
|
|
49087
49117
|
*/
|
|
49088
49118
|
this.useMemory = () => {
|
|
49089
49119
|
backtest.loggerService.info(RECENT_LIVE_ADAPTER_METHOD_NAME_USE_MEMORY);
|
|
49090
|
-
this.
|
|
49120
|
+
this._recentLiveFactory = () => new RecentMemoryLiveUtils();
|
|
49121
|
+
this.getInstance.clear();
|
|
49091
49122
|
};
|
|
49092
49123
|
/**
|
|
49093
|
-
* Clears the
|
|
49124
|
+
* Clears the memoized utils instance.
|
|
49125
|
+
* Call this when process.cwd() changes between strategy iterations
|
|
49126
|
+
* so a new instance is created with the updated base path.
|
|
49094
49127
|
*/
|
|
49095
49128
|
this.clear = () => {
|
|
49096
49129
|
backtest.loggerService.info(RECENT_LIVE_ADAPTER_METHOD_NAME_CLEAR);
|
|
49097
|
-
this.
|
|
49130
|
+
this.getInstance.clear();
|
|
49098
49131
|
};
|
|
49099
49132
|
}
|
|
49100
49133
|
}
|
|
@@ -54419,16 +54452,26 @@ class LogDummyUtils {
|
|
|
54419
54452
|
*/
|
|
54420
54453
|
class LogAdapter {
|
|
54421
54454
|
constructor() {
|
|
54422
|
-
/**
|
|
54423
|
-
this.
|
|
54455
|
+
/** Factory producing the active log utils instance */
|
|
54456
|
+
this._logFactory = () => new LogMemoryUtils();
|
|
54457
|
+
/**
|
|
54458
|
+
* Lazily constructs the log utils from the registered factory and memoizes
|
|
54459
|
+
* the result via `singleshot`.
|
|
54460
|
+
*
|
|
54461
|
+
* The instance is built on the first call and cached for all subsequent calls.
|
|
54462
|
+
* Reset via `clear()` so the next call rebuilds from the current factory
|
|
54463
|
+
* (e.g. when `process.cwd()` changes between strategy iterations).
|
|
54464
|
+
*/
|
|
54465
|
+
this.getInstance = functoolsKit.singleshot(() => this._logFactory());
|
|
54424
54466
|
/**
|
|
54425
54467
|
* Lists all stored log entries.
|
|
54426
54468
|
* Proxies call to the underlying log adapter.
|
|
54427
54469
|
* @returns Array of all log entries
|
|
54428
54470
|
*/
|
|
54429
54471
|
this.getList = async () => {
|
|
54430
|
-
|
|
54431
|
-
|
|
54472
|
+
const log = this.getInstance();
|
|
54473
|
+
if (log.getList) {
|
|
54474
|
+
return await log.getList();
|
|
54432
54475
|
}
|
|
54433
54476
|
return [];
|
|
54434
54477
|
};
|
|
@@ -54439,8 +54482,9 @@ class LogAdapter {
|
|
|
54439
54482
|
* @param args - Additional arguments
|
|
54440
54483
|
*/
|
|
54441
54484
|
this.log = (topic, ...args) => {
|
|
54442
|
-
|
|
54443
|
-
|
|
54485
|
+
const log = this.getInstance();
|
|
54486
|
+
if (log.log) {
|
|
54487
|
+
log.log(topic, ...args);
|
|
54444
54488
|
}
|
|
54445
54489
|
};
|
|
54446
54490
|
/**
|
|
@@ -54450,8 +54494,9 @@ class LogAdapter {
|
|
|
54450
54494
|
* @param args - Additional arguments
|
|
54451
54495
|
*/
|
|
54452
54496
|
this.debug = (topic, ...args) => {
|
|
54453
|
-
|
|
54454
|
-
|
|
54497
|
+
const log = this.getInstance();
|
|
54498
|
+
if (log.debug) {
|
|
54499
|
+
log.debug(topic, ...args);
|
|
54455
54500
|
}
|
|
54456
54501
|
};
|
|
54457
54502
|
/**
|
|
@@ -54461,8 +54506,9 @@ class LogAdapter {
|
|
|
54461
54506
|
* @param args - Additional arguments
|
|
54462
54507
|
*/
|
|
54463
54508
|
this.info = (topic, ...args) => {
|
|
54464
|
-
|
|
54465
|
-
|
|
54509
|
+
const log = this.getInstance();
|
|
54510
|
+
if (log.info) {
|
|
54511
|
+
log.info(topic, ...args);
|
|
54466
54512
|
}
|
|
54467
54513
|
};
|
|
54468
54514
|
/**
|
|
@@ -54472,8 +54518,9 @@ class LogAdapter {
|
|
|
54472
54518
|
* @param args - Additional arguments
|
|
54473
54519
|
*/
|
|
54474
54520
|
this.warn = (topic, ...args) => {
|
|
54475
|
-
|
|
54476
|
-
|
|
54521
|
+
const log = this.getInstance();
|
|
54522
|
+
if (log.warn) {
|
|
54523
|
+
log.warn(topic, ...args);
|
|
54477
54524
|
}
|
|
54478
54525
|
};
|
|
54479
54526
|
/**
|
|
@@ -54483,7 +54530,8 @@ class LogAdapter {
|
|
|
54483
54530
|
*/
|
|
54484
54531
|
this.useLogger = (Ctor) => {
|
|
54485
54532
|
backtest.loggerService.info(LOG_ADAPTER_METHOD_NAME_USE_LOGGER);
|
|
54486
|
-
this.
|
|
54533
|
+
this._logFactory = () => Reflect.construct(Ctor, []);
|
|
54534
|
+
this.getInstance.clear();
|
|
54487
54535
|
};
|
|
54488
54536
|
/**
|
|
54489
54537
|
* Switches to persistent log adapter.
|
|
@@ -54491,7 +54539,8 @@ class LogAdapter {
|
|
|
54491
54539
|
*/
|
|
54492
54540
|
this.usePersist = () => {
|
|
54493
54541
|
backtest.loggerService.info(LOG_ADAPTER_METHOD_NAME_USE_PERSIST);
|
|
54494
|
-
this.
|
|
54542
|
+
this._logFactory = () => new LogPersistUtils();
|
|
54543
|
+
this.getInstance.clear();
|
|
54495
54544
|
};
|
|
54496
54545
|
/**
|
|
54497
54546
|
* Switches to in-memory log adapter (default).
|
|
@@ -54499,7 +54548,8 @@ class LogAdapter {
|
|
|
54499
54548
|
*/
|
|
54500
54549
|
this.useMemory = () => {
|
|
54501
54550
|
backtest.loggerService.info(LOG_ADAPTER_METHOD_NAME_USE_MEMORY);
|
|
54502
|
-
this.
|
|
54551
|
+
this._logFactory = () => new LogMemoryUtils();
|
|
54552
|
+
this.getInstance.clear();
|
|
54503
54553
|
};
|
|
54504
54554
|
/**
|
|
54505
54555
|
* Switches to dummy log adapter.
|
|
@@ -54507,7 +54557,8 @@ class LogAdapter {
|
|
|
54507
54557
|
*/
|
|
54508
54558
|
this.useDummy = () => {
|
|
54509
54559
|
backtest.loggerService.info(LOG_ADAPTER_METHOD_NAME_USE_DUMMY);
|
|
54510
|
-
this.
|
|
54560
|
+
this._logFactory = () => new LogDummyUtils();
|
|
54561
|
+
this.getInstance.clear();
|
|
54511
54562
|
};
|
|
54512
54563
|
/**
|
|
54513
54564
|
* Switches to JSONL file log adapter.
|
|
@@ -54517,18 +54568,22 @@ class LogAdapter {
|
|
|
54517
54568
|
* @param fileName - Base file name without extension (default: "log")
|
|
54518
54569
|
* @param dirName - Directory for the JSONL file (default: ./dump/log)
|
|
54519
54570
|
*/
|
|
54520
|
-
this.useJsonl = (fileName = "log.jsonl", dirName
|
|
54571
|
+
this.useJsonl = (fileName = "log.jsonl", dirName) => {
|
|
54521
54572
|
backtest.loggerService.info(LOG_ADAPTER_METHOD_NAME_USE_JSONL);
|
|
54522
|
-
this.
|
|
54573
|
+
this._logFactory = () => {
|
|
54574
|
+
const dir = dirName || path.join(process.cwd(), "./dump/log");
|
|
54575
|
+
return new LogJsonlUtils(fileName, dir);
|
|
54576
|
+
};
|
|
54577
|
+
this.getInstance.clear();
|
|
54523
54578
|
};
|
|
54524
54579
|
/**
|
|
54525
|
-
* Clears the
|
|
54580
|
+
* Clears the memoized log instance.
|
|
54526
54581
|
* Call this when process.cwd() changes between strategy iterations
|
|
54527
54582
|
* so a new adapter instance is created with the updated base path.
|
|
54528
54583
|
*/
|
|
54529
54584
|
this.clear = () => {
|
|
54530
54585
|
backtest.loggerService.info(LOG_ADAPTER_METHOD_NAME_CLEAR);
|
|
54531
|
-
this.
|
|
54586
|
+
this.getInstance.clear();
|
|
54532
54587
|
};
|
|
54533
54588
|
}
|
|
54534
54589
|
}
|
|
@@ -58420,15 +58475,23 @@ class StorageDummyLiveUtils {
|
|
|
58420
58475
|
*/
|
|
58421
58476
|
class StorageBacktestAdapter {
|
|
58422
58477
|
constructor() {
|
|
58423
|
-
/**
|
|
58424
|
-
this.
|
|
58478
|
+
/** Factory producing the active storage utils instance */
|
|
58479
|
+
this._signalBacktestFactory = () => new StorageMemoryBacktestUtils();
|
|
58480
|
+
/**
|
|
58481
|
+
* Lazily constructs the storage utils from the registered factory and memoizes
|
|
58482
|
+
* the result via `singleshot`.
|
|
58483
|
+
*
|
|
58484
|
+
* The instance is built on the first call and cached for all subsequent calls.
|
|
58485
|
+
* Reset via `clear()` so the next call rebuilds from the current factory.
|
|
58486
|
+
*/
|
|
58487
|
+
this.getInstance = functoolsKit.singleshot(() => this._signalBacktestFactory());
|
|
58425
58488
|
/**
|
|
58426
58489
|
* Handles signal opened event.
|
|
58427
58490
|
* Proxies call to the underlying storage adapter.
|
|
58428
58491
|
* @param tick - The opened signal tick data
|
|
58429
58492
|
*/
|
|
58430
58493
|
this.handleOpened = async (tick) => {
|
|
58431
|
-
return await this.
|
|
58494
|
+
return await this.getInstance().handleOpened(tick);
|
|
58432
58495
|
};
|
|
58433
58496
|
/**
|
|
58434
58497
|
* Handles signal closed event.
|
|
@@ -58436,7 +58499,7 @@ class StorageBacktestAdapter {
|
|
|
58436
58499
|
* @param tick - The closed signal tick data
|
|
58437
58500
|
*/
|
|
58438
58501
|
this.handleClosed = async (tick) => {
|
|
58439
|
-
return await this.
|
|
58502
|
+
return await this.getInstance().handleClosed(tick);
|
|
58440
58503
|
};
|
|
58441
58504
|
/**
|
|
58442
58505
|
* Handles signal scheduled event.
|
|
@@ -58444,7 +58507,7 @@ class StorageBacktestAdapter {
|
|
|
58444
58507
|
* @param tick - The scheduled signal tick data
|
|
58445
58508
|
*/
|
|
58446
58509
|
this.handleScheduled = async (tick) => {
|
|
58447
|
-
return await this.
|
|
58510
|
+
return await this.getInstance().handleScheduled(tick);
|
|
58448
58511
|
};
|
|
58449
58512
|
/**
|
|
58450
58513
|
* Handles signal cancelled event.
|
|
@@ -58452,7 +58515,7 @@ class StorageBacktestAdapter {
|
|
|
58452
58515
|
* @param tick - The cancelled signal tick data
|
|
58453
58516
|
*/
|
|
58454
58517
|
this.handleCancelled = async (tick) => {
|
|
58455
|
-
return await this.
|
|
58518
|
+
return await this.getInstance().handleCancelled(tick);
|
|
58456
58519
|
};
|
|
58457
58520
|
/**
|
|
58458
58521
|
* Finds a signal by its ID.
|
|
@@ -58461,7 +58524,7 @@ class StorageBacktestAdapter {
|
|
|
58461
58524
|
* @returns The signal row or null if not found
|
|
58462
58525
|
*/
|
|
58463
58526
|
this.findById = async (id) => {
|
|
58464
|
-
return await this.
|
|
58527
|
+
return await this.getInstance().findById(id);
|
|
58465
58528
|
};
|
|
58466
58529
|
/**
|
|
58467
58530
|
* Lists all stored signals.
|
|
@@ -58469,13 +58532,13 @@ class StorageBacktestAdapter {
|
|
|
58469
58532
|
* @returns Array of all signal rows
|
|
58470
58533
|
*/
|
|
58471
58534
|
this.list = async () => {
|
|
58472
|
-
return await this.
|
|
58535
|
+
return await this.getInstance().list();
|
|
58473
58536
|
};
|
|
58474
58537
|
this.handleActivePing = async (event) => {
|
|
58475
|
-
return await this.
|
|
58538
|
+
return await this.getInstance().handleActivePing(event);
|
|
58476
58539
|
};
|
|
58477
58540
|
this.handleSchedulePing = async (event) => {
|
|
58478
|
-
return await this.
|
|
58541
|
+
return await this.getInstance().handleSchedulePing(event);
|
|
58479
58542
|
};
|
|
58480
58543
|
/**
|
|
58481
58544
|
* Sets the storage adapter constructor.
|
|
@@ -58485,7 +58548,8 @@ class StorageBacktestAdapter {
|
|
|
58485
58548
|
*/
|
|
58486
58549
|
this.useStorageAdapter = (Ctor) => {
|
|
58487
58550
|
backtest.loggerService.info(STORAGE_BACKTEST_ADAPTER_METHOD_NAME_USE_ADAPTER);
|
|
58488
|
-
this.
|
|
58551
|
+
this._signalBacktestFactory = () => Reflect.construct(Ctor, []);
|
|
58552
|
+
this.getInstance.clear();
|
|
58489
58553
|
};
|
|
58490
58554
|
/**
|
|
58491
58555
|
* Switches to dummy storage adapter.
|
|
@@ -58493,7 +58557,8 @@ class StorageBacktestAdapter {
|
|
|
58493
58557
|
*/
|
|
58494
58558
|
this.useDummy = () => {
|
|
58495
58559
|
backtest.loggerService.info(STORAGE_BACKTEST_ADAPTER_METHOD_NAME_USE_DUMMY);
|
|
58496
|
-
this.
|
|
58560
|
+
this._signalBacktestFactory = () => new StorageDummyBacktestUtils();
|
|
58561
|
+
this.getInstance.clear();
|
|
58497
58562
|
};
|
|
58498
58563
|
/**
|
|
58499
58564
|
* Switches to persistent storage adapter (default).
|
|
@@ -58501,7 +58566,8 @@ class StorageBacktestAdapter {
|
|
|
58501
58566
|
*/
|
|
58502
58567
|
this.usePersist = () => {
|
|
58503
58568
|
backtest.loggerService.info(STORAGE_BACKTEST_ADAPTER_METHOD_NAME_USE_PERSIST);
|
|
58504
|
-
this.
|
|
58569
|
+
this._signalBacktestFactory = () => new StoragePersistBacktestUtils();
|
|
58570
|
+
this.getInstance.clear();
|
|
58505
58571
|
};
|
|
58506
58572
|
/**
|
|
58507
58573
|
* Switches to in-memory storage adapter.
|
|
@@ -58509,16 +58575,17 @@ class StorageBacktestAdapter {
|
|
|
58509
58575
|
*/
|
|
58510
58576
|
this.useMemory = () => {
|
|
58511
58577
|
backtest.loggerService.info(STORAGE_BACKTEST_ADAPTER_METHOD_NAME_USE_MEMORY);
|
|
58512
|
-
this.
|
|
58578
|
+
this._signalBacktestFactory = () => new StorageMemoryBacktestUtils();
|
|
58579
|
+
this.getInstance.clear();
|
|
58513
58580
|
};
|
|
58514
58581
|
/**
|
|
58515
|
-
* Clears the
|
|
58582
|
+
* Clears the memoized utils instance.
|
|
58516
58583
|
* Call this when process.cwd() changes between strategy iterations
|
|
58517
58584
|
* so a new instance is created with the updated base path.
|
|
58518
58585
|
*/
|
|
58519
58586
|
this.clear = () => {
|
|
58520
58587
|
backtest.loggerService.info(STORAGE_BACKTEST_ADAPTER_METHOD_NAME_CLEAR);
|
|
58521
|
-
this.
|
|
58588
|
+
this.getInstance.clear();
|
|
58522
58589
|
};
|
|
58523
58590
|
}
|
|
58524
58591
|
}
|
|
@@ -58533,15 +58600,23 @@ class StorageBacktestAdapter {
|
|
|
58533
58600
|
*/
|
|
58534
58601
|
class StorageLiveAdapter {
|
|
58535
58602
|
constructor() {
|
|
58536
|
-
/**
|
|
58537
|
-
this.
|
|
58603
|
+
/** Factory producing the active storage utils instance */
|
|
58604
|
+
this._signalLiveFactory = () => new StoragePersistLiveUtils();
|
|
58605
|
+
/**
|
|
58606
|
+
* Lazily constructs the storage utils from the registered factory and memoizes
|
|
58607
|
+
* the result via `singleshot`.
|
|
58608
|
+
*
|
|
58609
|
+
* The instance is built on the first call and cached for all subsequent calls.
|
|
58610
|
+
* Reset via `clear()` so the next call rebuilds from the current factory.
|
|
58611
|
+
*/
|
|
58612
|
+
this.getInstance = functoolsKit.singleshot(() => this._signalLiveFactory());
|
|
58538
58613
|
/**
|
|
58539
58614
|
* Handles signal opened event.
|
|
58540
58615
|
* Proxies call to the underlying storage adapter.
|
|
58541
58616
|
* @param tick - The opened signal tick data
|
|
58542
58617
|
*/
|
|
58543
58618
|
this.handleOpened = async (tick) => {
|
|
58544
|
-
return await this.
|
|
58619
|
+
return await this.getInstance().handleOpened(tick);
|
|
58545
58620
|
};
|
|
58546
58621
|
/**
|
|
58547
58622
|
* Handles signal closed event.
|
|
@@ -58549,7 +58624,7 @@ class StorageLiveAdapter {
|
|
|
58549
58624
|
* @param tick - The closed signal tick data
|
|
58550
58625
|
*/
|
|
58551
58626
|
this.handleClosed = async (tick) => {
|
|
58552
|
-
return await this.
|
|
58627
|
+
return await this.getInstance().handleClosed(tick);
|
|
58553
58628
|
};
|
|
58554
58629
|
/**
|
|
58555
58630
|
* Handles signal scheduled event.
|
|
@@ -58557,7 +58632,7 @@ class StorageLiveAdapter {
|
|
|
58557
58632
|
* @param tick - The scheduled signal tick data
|
|
58558
58633
|
*/
|
|
58559
58634
|
this.handleScheduled = async (tick) => {
|
|
58560
|
-
return await this.
|
|
58635
|
+
return await this.getInstance().handleScheduled(tick);
|
|
58561
58636
|
};
|
|
58562
58637
|
/**
|
|
58563
58638
|
* Handles signal cancelled event.
|
|
@@ -58565,7 +58640,7 @@ class StorageLiveAdapter {
|
|
|
58565
58640
|
* @param tick - The cancelled signal tick data
|
|
58566
58641
|
*/
|
|
58567
58642
|
this.handleCancelled = async (tick) => {
|
|
58568
|
-
return await this.
|
|
58643
|
+
return await this.getInstance().handleCancelled(tick);
|
|
58569
58644
|
};
|
|
58570
58645
|
/**
|
|
58571
58646
|
* Finds a signal by its ID.
|
|
@@ -58574,7 +58649,7 @@ class StorageLiveAdapter {
|
|
|
58574
58649
|
* @returns The signal row or null if not found
|
|
58575
58650
|
*/
|
|
58576
58651
|
this.findById = async (id) => {
|
|
58577
|
-
return await this.
|
|
58652
|
+
return await this.getInstance().findById(id);
|
|
58578
58653
|
};
|
|
58579
58654
|
/**
|
|
58580
58655
|
* Lists all stored signals.
|
|
@@ -58582,13 +58657,13 @@ class StorageLiveAdapter {
|
|
|
58582
58657
|
* @returns Array of all signal rows
|
|
58583
58658
|
*/
|
|
58584
58659
|
this.list = async () => {
|
|
58585
|
-
return await this.
|
|
58660
|
+
return await this.getInstance().list();
|
|
58586
58661
|
};
|
|
58587
58662
|
this.handleActivePing = async (event) => {
|
|
58588
|
-
return await this.
|
|
58663
|
+
return await this.getInstance().handleActivePing(event);
|
|
58589
58664
|
};
|
|
58590
58665
|
this.handleSchedulePing = async (event) => {
|
|
58591
|
-
return await this.
|
|
58666
|
+
return await this.getInstance().handleSchedulePing(event);
|
|
58592
58667
|
};
|
|
58593
58668
|
/**
|
|
58594
58669
|
* Sets the storage adapter constructor.
|
|
@@ -58598,7 +58673,8 @@ class StorageLiveAdapter {
|
|
|
58598
58673
|
*/
|
|
58599
58674
|
this.useStorageAdapter = (Ctor) => {
|
|
58600
58675
|
backtest.loggerService.info(STORAGE_LIVE_ADAPTER_METHOD_NAME_USE_ADAPTER);
|
|
58601
|
-
this.
|
|
58676
|
+
this._signalLiveFactory = () => Reflect.construct(Ctor, []);
|
|
58677
|
+
this.getInstance.clear();
|
|
58602
58678
|
};
|
|
58603
58679
|
/**
|
|
58604
58680
|
* Switches to dummy storage adapter.
|
|
@@ -58606,7 +58682,8 @@ class StorageLiveAdapter {
|
|
|
58606
58682
|
*/
|
|
58607
58683
|
this.useDummy = () => {
|
|
58608
58684
|
backtest.loggerService.info(STORAGE_LIVE_ADAPTER_METHOD_NAME_USE_DUMMY);
|
|
58609
|
-
this.
|
|
58685
|
+
this._signalLiveFactory = () => new StorageDummyLiveUtils();
|
|
58686
|
+
this.getInstance.clear();
|
|
58610
58687
|
};
|
|
58611
58688
|
/**
|
|
58612
58689
|
* Switches to persistent storage adapter (default).
|
|
@@ -58614,7 +58691,8 @@ class StorageLiveAdapter {
|
|
|
58614
58691
|
*/
|
|
58615
58692
|
this.usePersist = () => {
|
|
58616
58693
|
backtest.loggerService.info(STORAGE_LIVE_ADAPTER_METHOD_NAME_USE_PERSIST);
|
|
58617
|
-
this.
|
|
58694
|
+
this._signalLiveFactory = () => new StoragePersistLiveUtils();
|
|
58695
|
+
this.getInstance.clear();
|
|
58618
58696
|
};
|
|
58619
58697
|
/**
|
|
58620
58698
|
* Switches to in-memory storage adapter.
|
|
@@ -58622,16 +58700,17 @@ class StorageLiveAdapter {
|
|
|
58622
58700
|
*/
|
|
58623
58701
|
this.useMemory = () => {
|
|
58624
58702
|
backtest.loggerService.info(STORAGE_LIVE_ADAPTER_METHOD_NAME_USE_MEMORY);
|
|
58625
|
-
this.
|
|
58703
|
+
this._signalLiveFactory = () => new StorageMemoryLiveUtils();
|
|
58704
|
+
this.getInstance.clear();
|
|
58626
58705
|
};
|
|
58627
58706
|
/**
|
|
58628
|
-
* Clears the
|
|
58707
|
+
* Clears the memoized utils instance.
|
|
58629
58708
|
* Call this when process.cwd() changes between strategy iterations
|
|
58630
58709
|
* so a new instance is created with the updated base path.
|
|
58631
58710
|
*/
|
|
58632
58711
|
this.clear = () => {
|
|
58633
58712
|
backtest.loggerService.info(STORAGE_LIVE_ADAPTER_METHOD_NAME_CLEAR);
|
|
58634
|
-
this.
|
|
58713
|
+
this.getInstance.clear();
|
|
58635
58714
|
};
|
|
58636
58715
|
}
|
|
58637
58716
|
}
|
|
@@ -60747,18 +60826,26 @@ class NotificationPersistLiveUtils {
|
|
|
60747
60826
|
*/
|
|
60748
60827
|
class NotificationBacktestAdapter {
|
|
60749
60828
|
constructor() {
|
|
60750
|
-
/**
|
|
60751
|
-
this.
|
|
60829
|
+
/** Factory producing the active notification utils instance */
|
|
60830
|
+
this._notificationBacktestFactory = () => new NotificationMemoryBacktestUtils();
|
|
60831
|
+
/**
|
|
60832
|
+
* Lazily constructs the notification utils from the registered factory and
|
|
60833
|
+
* memoizes the result via `singleshot`.
|
|
60834
|
+
*
|
|
60835
|
+
* The instance is built on the first call and cached for all subsequent calls.
|
|
60836
|
+
* Reset via `clear()` so the next call rebuilds from the current factory.
|
|
60837
|
+
*/
|
|
60838
|
+
this.getInstance = functoolsKit.singleshot(() => this._notificationBacktestFactory());
|
|
60752
60839
|
/**
|
|
60753
60840
|
* Handles signal events.
|
|
60754
60841
|
* Proxies call to the underlying notification adapter.
|
|
60755
60842
|
* @param data - The strategy tick result data
|
|
60756
60843
|
*/
|
|
60757
60844
|
this.handleSignal = async (data) => {
|
|
60758
|
-
return await this.
|
|
60845
|
+
return await this.getInstance().handleSignal(data);
|
|
60759
60846
|
};
|
|
60760
60847
|
this.handleSignalNotify = async (data) => {
|
|
60761
|
-
return await this.
|
|
60848
|
+
return await this.getInstance().handleSignalNotify(data);
|
|
60762
60849
|
};
|
|
60763
60850
|
/**
|
|
60764
60851
|
* Handles partial profit availability event.
|
|
@@ -60766,7 +60853,7 @@ class NotificationBacktestAdapter {
|
|
|
60766
60853
|
* @param data - The partial profit contract data
|
|
60767
60854
|
*/
|
|
60768
60855
|
this.handlePartialProfit = async (data) => {
|
|
60769
|
-
return await this.
|
|
60856
|
+
return await this.getInstance().handlePartialProfit(data);
|
|
60770
60857
|
};
|
|
60771
60858
|
/**
|
|
60772
60859
|
* Handles partial loss availability event.
|
|
@@ -60774,7 +60861,7 @@ class NotificationBacktestAdapter {
|
|
|
60774
60861
|
* @param data - The partial loss contract data
|
|
60775
60862
|
*/
|
|
60776
60863
|
this.handlePartialLoss = async (data) => {
|
|
60777
|
-
return await this.
|
|
60864
|
+
return await this.getInstance().handlePartialLoss(data);
|
|
60778
60865
|
};
|
|
60779
60866
|
/**
|
|
60780
60867
|
* Handles breakeven availability event.
|
|
@@ -60782,7 +60869,7 @@ class NotificationBacktestAdapter {
|
|
|
60782
60869
|
* @param data - The breakeven contract data
|
|
60783
60870
|
*/
|
|
60784
60871
|
this.handleBreakeven = async (data) => {
|
|
60785
|
-
return await this.
|
|
60872
|
+
return await this.getInstance().handleBreakeven(data);
|
|
60786
60873
|
};
|
|
60787
60874
|
/**
|
|
60788
60875
|
* Handles strategy commit events.
|
|
@@ -60790,7 +60877,7 @@ class NotificationBacktestAdapter {
|
|
|
60790
60877
|
* @param data - The strategy commit contract data
|
|
60791
60878
|
*/
|
|
60792
60879
|
this.handleStrategyCommit = async (data) => {
|
|
60793
|
-
return await this.
|
|
60880
|
+
return await this.getInstance().handleStrategyCommit(data);
|
|
60794
60881
|
};
|
|
60795
60882
|
/**
|
|
60796
60883
|
* Handles signal sync events (signal-open, signal-close).
|
|
@@ -60798,7 +60885,7 @@ class NotificationBacktestAdapter {
|
|
|
60798
60885
|
* @param data - The signal sync contract data
|
|
60799
60886
|
*/
|
|
60800
60887
|
this.handleSync = functoolsKit.trycatch(async (data) => {
|
|
60801
|
-
return await this.
|
|
60888
|
+
return await this.getInstance().handleSync(data);
|
|
60802
60889
|
}, {
|
|
60803
60890
|
defaultValue: null,
|
|
60804
60891
|
});
|
|
@@ -60808,7 +60895,7 @@ class NotificationBacktestAdapter {
|
|
|
60808
60895
|
* @param data - The risk contract data
|
|
60809
60896
|
*/
|
|
60810
60897
|
this.handleRisk = async (data) => {
|
|
60811
|
-
return await this.
|
|
60898
|
+
return await this.getInstance().handleRisk(data);
|
|
60812
60899
|
};
|
|
60813
60900
|
/**
|
|
60814
60901
|
* Handles error event.
|
|
@@ -60816,7 +60903,7 @@ class NotificationBacktestAdapter {
|
|
|
60816
60903
|
* @param error - The error object
|
|
60817
60904
|
*/
|
|
60818
60905
|
this.handleError = async (error) => {
|
|
60819
|
-
return await this.
|
|
60906
|
+
return await this.getInstance().handleError(error);
|
|
60820
60907
|
};
|
|
60821
60908
|
/**
|
|
60822
60909
|
* Handles critical error event.
|
|
@@ -60824,7 +60911,7 @@ class NotificationBacktestAdapter {
|
|
|
60824
60911
|
* @param error - The error object
|
|
60825
60912
|
*/
|
|
60826
60913
|
this.handleCriticalError = async (error) => {
|
|
60827
|
-
return await this.
|
|
60914
|
+
return await this.getInstance().handleCriticalError(error);
|
|
60828
60915
|
};
|
|
60829
60916
|
/**
|
|
60830
60917
|
* Handles validation error event.
|
|
@@ -60832,7 +60919,7 @@ class NotificationBacktestAdapter {
|
|
|
60832
60919
|
* @param error - The error object
|
|
60833
60920
|
*/
|
|
60834
60921
|
this.handleValidationError = async (error) => {
|
|
60835
|
-
return await this.
|
|
60922
|
+
return await this.getInstance().handleValidationError(error);
|
|
60836
60923
|
};
|
|
60837
60924
|
/**
|
|
60838
60925
|
* Gets all stored notifications.
|
|
@@ -60840,14 +60927,14 @@ class NotificationBacktestAdapter {
|
|
|
60840
60927
|
* @returns Array of all notification models
|
|
60841
60928
|
*/
|
|
60842
60929
|
this.getData = async () => {
|
|
60843
|
-
return await this.
|
|
60930
|
+
return await this.getInstance().getData();
|
|
60844
60931
|
};
|
|
60845
60932
|
/**
|
|
60846
60933
|
* Clears all stored notifications.
|
|
60847
60934
|
* Proxies call to the underlying notification adapter.
|
|
60848
60935
|
*/
|
|
60849
60936
|
this.dispose = async () => {
|
|
60850
|
-
return await this.
|
|
60937
|
+
return await this.getInstance().dispose();
|
|
60851
60938
|
};
|
|
60852
60939
|
/**
|
|
60853
60940
|
* Sets the notification adapter constructor.
|
|
@@ -60857,7 +60944,8 @@ class NotificationBacktestAdapter {
|
|
|
60857
60944
|
*/
|
|
60858
60945
|
this.useNotificationAdapter = (Ctor) => {
|
|
60859
60946
|
backtest.loggerService.info(NOTIFICATION_BACKTEST_ADAPTER_METHOD_NAME_USE_ADAPTER);
|
|
60860
|
-
this.
|
|
60947
|
+
this._notificationBacktestFactory = () => Reflect.construct(Ctor, []);
|
|
60948
|
+
this.getInstance.clear();
|
|
60861
60949
|
};
|
|
60862
60950
|
/**
|
|
60863
60951
|
* Switches to dummy notification adapter.
|
|
@@ -60865,7 +60953,8 @@ class NotificationBacktestAdapter {
|
|
|
60865
60953
|
*/
|
|
60866
60954
|
this.useDummy = () => {
|
|
60867
60955
|
backtest.loggerService.info(NOTIFICATION_BACKTEST_ADAPTER_METHOD_NAME_USE_DUMMY);
|
|
60868
|
-
this.
|
|
60956
|
+
this._notificationBacktestFactory = () => new NotificationDummyBacktestUtils();
|
|
60957
|
+
this.getInstance.clear();
|
|
60869
60958
|
};
|
|
60870
60959
|
/**
|
|
60871
60960
|
* Switches to in-memory notification adapter (default).
|
|
@@ -60873,7 +60962,8 @@ class NotificationBacktestAdapter {
|
|
|
60873
60962
|
*/
|
|
60874
60963
|
this.useMemory = () => {
|
|
60875
60964
|
backtest.loggerService.info(NOTIFICATION_BACKTEST_ADAPTER_METHOD_NAME_USE_MEMORY);
|
|
60876
|
-
this.
|
|
60965
|
+
this._notificationBacktestFactory = () => new NotificationMemoryBacktestUtils();
|
|
60966
|
+
this.getInstance.clear();
|
|
60877
60967
|
};
|
|
60878
60968
|
/**
|
|
60879
60969
|
* Switches to persistent notification adapter.
|
|
@@ -60881,16 +60971,17 @@ class NotificationBacktestAdapter {
|
|
|
60881
60971
|
*/
|
|
60882
60972
|
this.usePersist = () => {
|
|
60883
60973
|
backtest.loggerService.info(NOTIFICATION_BACKTEST_ADAPTER_METHOD_NAME_USE_PERSIST);
|
|
60884
|
-
this.
|
|
60974
|
+
this._notificationBacktestFactory = () => new NotificationPersistBacktestUtils();
|
|
60975
|
+
this.getInstance.clear();
|
|
60885
60976
|
};
|
|
60886
60977
|
/**
|
|
60887
|
-
*
|
|
60978
|
+
* Clears the memoized utils instance.
|
|
60888
60979
|
* Call this when process.cwd() changes between strategy iterations
|
|
60889
60980
|
* so a new instance is created with the updated base path.
|
|
60890
60981
|
*/
|
|
60891
60982
|
this.clear = () => {
|
|
60892
60983
|
backtest.loggerService.info(NOTIFICATION_BACKTEST_ADAPTER_METHOD_NAME_CLEAR);
|
|
60893
|
-
this.
|
|
60984
|
+
this.getInstance.clear();
|
|
60894
60985
|
};
|
|
60895
60986
|
}
|
|
60896
60987
|
}
|
|
@@ -60905,18 +60996,26 @@ class NotificationBacktestAdapter {
|
|
|
60905
60996
|
*/
|
|
60906
60997
|
class NotificationLiveAdapter {
|
|
60907
60998
|
constructor() {
|
|
60908
|
-
/**
|
|
60909
|
-
this.
|
|
60999
|
+
/** Factory producing the active notification utils instance */
|
|
61000
|
+
this._notificationLiveFactory = () => new NotificationMemoryLiveUtils();
|
|
61001
|
+
/**
|
|
61002
|
+
* Lazily constructs the notification utils from the registered factory and
|
|
61003
|
+
* memoizes the result via `singleshot`.
|
|
61004
|
+
*
|
|
61005
|
+
* The instance is built on the first call and cached for all subsequent calls.
|
|
61006
|
+
* Reset via `clear()` so the next call rebuilds from the current factory.
|
|
61007
|
+
*/
|
|
61008
|
+
this.getInstance = functoolsKit.singleshot(() => this._notificationLiveFactory());
|
|
60910
61009
|
/**
|
|
60911
61010
|
* Handles signal events.
|
|
60912
61011
|
* Proxies call to the underlying notification adapter.
|
|
60913
61012
|
* @param data - The strategy tick result data
|
|
60914
61013
|
*/
|
|
60915
61014
|
this.handleSignal = async (data) => {
|
|
60916
|
-
return await this.
|
|
61015
|
+
return await this.getInstance().handleSignal(data);
|
|
60917
61016
|
};
|
|
60918
61017
|
this.handleSignalNotify = async (data) => {
|
|
60919
|
-
return await this.
|
|
61018
|
+
return await this.getInstance().handleSignalNotify(data);
|
|
60920
61019
|
};
|
|
60921
61020
|
/**
|
|
60922
61021
|
* Handles partial profit availability event.
|
|
@@ -60924,7 +61023,7 @@ class NotificationLiveAdapter {
|
|
|
60924
61023
|
* @param data - The partial profit contract data
|
|
60925
61024
|
*/
|
|
60926
61025
|
this.handlePartialProfit = async (data) => {
|
|
60927
|
-
return await this.
|
|
61026
|
+
return await this.getInstance().handlePartialProfit(data);
|
|
60928
61027
|
};
|
|
60929
61028
|
/**
|
|
60930
61029
|
* Handles partial loss availability event.
|
|
@@ -60932,7 +61031,7 @@ class NotificationLiveAdapter {
|
|
|
60932
61031
|
* @param data - The partial loss contract data
|
|
60933
61032
|
*/
|
|
60934
61033
|
this.handlePartialLoss = async (data) => {
|
|
60935
|
-
return await this.
|
|
61034
|
+
return await this.getInstance().handlePartialLoss(data);
|
|
60936
61035
|
};
|
|
60937
61036
|
/**
|
|
60938
61037
|
* Handles breakeven availability event.
|
|
@@ -60940,7 +61039,7 @@ class NotificationLiveAdapter {
|
|
|
60940
61039
|
* @param data - The breakeven contract data
|
|
60941
61040
|
*/
|
|
60942
61041
|
this.handleBreakeven = async (data) => {
|
|
60943
|
-
return await this.
|
|
61042
|
+
return await this.getInstance().handleBreakeven(data);
|
|
60944
61043
|
};
|
|
60945
61044
|
/**
|
|
60946
61045
|
* Handles strategy commit events.
|
|
@@ -60948,7 +61047,7 @@ class NotificationLiveAdapter {
|
|
|
60948
61047
|
* @param data - The strategy commit contract data
|
|
60949
61048
|
*/
|
|
60950
61049
|
this.handleStrategyCommit = async (data) => {
|
|
60951
|
-
return await this.
|
|
61050
|
+
return await this.getInstance().handleStrategyCommit(data);
|
|
60952
61051
|
};
|
|
60953
61052
|
/**
|
|
60954
61053
|
* Handles signal sync events (signal-open, signal-close).
|
|
@@ -60956,7 +61055,7 @@ class NotificationLiveAdapter {
|
|
|
60956
61055
|
* @param data - The signal sync contract data
|
|
60957
61056
|
*/
|
|
60958
61057
|
this.handleSync = functoolsKit.trycatch(async (data) => {
|
|
60959
|
-
return await this.
|
|
61058
|
+
return await this.getInstance().handleSync(data);
|
|
60960
61059
|
}, {
|
|
60961
61060
|
defaultValue: null,
|
|
60962
61061
|
});
|
|
@@ -60966,7 +61065,7 @@ class NotificationLiveAdapter {
|
|
|
60966
61065
|
* @param data - The risk contract data
|
|
60967
61066
|
*/
|
|
60968
61067
|
this.handleRisk = async (data) => {
|
|
60969
|
-
return await this.
|
|
61068
|
+
return await this.getInstance().handleRisk(data);
|
|
60970
61069
|
};
|
|
60971
61070
|
/**
|
|
60972
61071
|
* Handles error event.
|
|
@@ -60974,7 +61073,7 @@ class NotificationLiveAdapter {
|
|
|
60974
61073
|
* @param error - The error object
|
|
60975
61074
|
*/
|
|
60976
61075
|
this.handleError = async (error) => {
|
|
60977
|
-
return await this.
|
|
61076
|
+
return await this.getInstance().handleError(error);
|
|
60978
61077
|
};
|
|
60979
61078
|
/**
|
|
60980
61079
|
* Handles critical error event.
|
|
@@ -60982,7 +61081,7 @@ class NotificationLiveAdapter {
|
|
|
60982
61081
|
* @param error - The error object
|
|
60983
61082
|
*/
|
|
60984
61083
|
this.handleCriticalError = async (error) => {
|
|
60985
|
-
return await this.
|
|
61084
|
+
return await this.getInstance().handleCriticalError(error);
|
|
60986
61085
|
};
|
|
60987
61086
|
/**
|
|
60988
61087
|
* Handles validation error event.
|
|
@@ -60990,7 +61089,7 @@ class NotificationLiveAdapter {
|
|
|
60990
61089
|
* @param error - The error object
|
|
60991
61090
|
*/
|
|
60992
61091
|
this.handleValidationError = async (error) => {
|
|
60993
|
-
return await this.
|
|
61092
|
+
return await this.getInstance().handleValidationError(error);
|
|
60994
61093
|
};
|
|
60995
61094
|
/**
|
|
60996
61095
|
* Gets all stored notifications.
|
|
@@ -60998,14 +61097,14 @@ class NotificationLiveAdapter {
|
|
|
60998
61097
|
* @returns Array of all notification models
|
|
60999
61098
|
*/
|
|
61000
61099
|
this.getData = async () => {
|
|
61001
|
-
return await this.
|
|
61100
|
+
return await this.getInstance().getData();
|
|
61002
61101
|
};
|
|
61003
61102
|
/**
|
|
61004
61103
|
* Clears all stored notifications.
|
|
61005
61104
|
* Proxies call to the underlying notification adapter.
|
|
61006
61105
|
*/
|
|
61007
61106
|
this.dispose = async () => {
|
|
61008
|
-
return await this.
|
|
61107
|
+
return await this.getInstance().dispose();
|
|
61009
61108
|
};
|
|
61010
61109
|
/**
|
|
61011
61110
|
* Sets the notification adapter constructor.
|
|
@@ -61015,7 +61114,8 @@ class NotificationLiveAdapter {
|
|
|
61015
61114
|
*/
|
|
61016
61115
|
this.useNotificationAdapter = (Ctor) => {
|
|
61017
61116
|
backtest.loggerService.info(NOTIFICATION_LIVE_ADAPTER_METHOD_NAME_USE_ADAPTER);
|
|
61018
|
-
this.
|
|
61117
|
+
this._notificationLiveFactory = () => Reflect.construct(Ctor, []);
|
|
61118
|
+
this.getInstance.clear();
|
|
61019
61119
|
};
|
|
61020
61120
|
/**
|
|
61021
61121
|
* Switches to dummy notification adapter.
|
|
@@ -61023,7 +61123,8 @@ class NotificationLiveAdapter {
|
|
|
61023
61123
|
*/
|
|
61024
61124
|
this.useDummy = () => {
|
|
61025
61125
|
backtest.loggerService.info(NOTIFICATION_LIVE_ADAPTER_METHOD_NAME_USE_DUMMY);
|
|
61026
|
-
this.
|
|
61126
|
+
this._notificationLiveFactory = () => new NotificationDummyLiveUtils();
|
|
61127
|
+
this.getInstance.clear();
|
|
61027
61128
|
};
|
|
61028
61129
|
/**
|
|
61029
61130
|
* Switches to in-memory notification adapter (default).
|
|
@@ -61031,7 +61132,8 @@ class NotificationLiveAdapter {
|
|
|
61031
61132
|
*/
|
|
61032
61133
|
this.useMemory = () => {
|
|
61033
61134
|
backtest.loggerService.info(NOTIFICATION_LIVE_ADAPTER_METHOD_NAME_USE_MEMORY);
|
|
61034
|
-
this.
|
|
61135
|
+
this._notificationLiveFactory = () => new NotificationMemoryLiveUtils();
|
|
61136
|
+
this.getInstance.clear();
|
|
61035
61137
|
};
|
|
61036
61138
|
/**
|
|
61037
61139
|
* Switches to persistent notification adapter.
|
|
@@ -61039,16 +61141,17 @@ class NotificationLiveAdapter {
|
|
|
61039
61141
|
*/
|
|
61040
61142
|
this.usePersist = () => {
|
|
61041
61143
|
backtest.loggerService.info(NOTIFICATION_LIVE_ADAPTER_METHOD_NAME_USE_PERSIST);
|
|
61042
|
-
this.
|
|
61144
|
+
this._notificationLiveFactory = () => new NotificationPersistLiveUtils();
|
|
61145
|
+
this.getInstance.clear();
|
|
61043
61146
|
};
|
|
61044
61147
|
/**
|
|
61045
|
-
*
|
|
61148
|
+
* Clears the memoized utils instance.
|
|
61046
61149
|
* Call this when process.cwd() changes between strategy iterations
|
|
61047
61150
|
* so a new instance is created with the updated base path.
|
|
61048
61151
|
*/
|
|
61049
61152
|
this.clear = () => {
|
|
61050
61153
|
backtest.loggerService.info(NOTIFICATION_LIVE_ADAPTER_METHOD_NAME_CLEAR);
|
|
61051
|
-
this.
|
|
61154
|
+
this.getInstance.clear();
|
|
61052
61155
|
};
|
|
61053
61156
|
}
|
|
61054
61157
|
}
|