backtest-kit 7.5.0 → 7.6.0

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.mjs CHANGED
@@ -1004,6 +1004,15 @@ const PERSIST_STATE_UTILS_METHOD_NAME_CLEAR = "PersistStateUtils.clear";
1004
1004
  const PERSIST_STATE_UTILS_METHOD_NAME_DISPOSE = "PersistStateUtils.dispose";
1005
1005
  const PERSIST_STATE_UTILS_METHOD_NAME_WAIT_FOR_INIT = "PersistStateUtils.waitForInit";
1006
1006
  const PERSIST_STATE_UTILS_METHOD_NAME_USE_DUMMY = "PersistStateUtils.useDummy";
1007
+ const PERSIST_STATE_UTILS_METHOD_NAME_USE_JSON = "PersistStateUtils.useJson";
1008
+ const PERSIST_SESSION_UTILS_METHOD_NAME_USE_PERSIST_SESSION_ADAPTER = "PersistSessionUtils.usePersistSessionAdapter";
1009
+ const PERSIST_SESSION_UTILS_METHOD_NAME_READ_DATA = "PersistSessionUtils.readSessionData";
1010
+ const PERSIST_SESSION_UTILS_METHOD_NAME_WRITE_DATA = "PersistSessionUtils.writeSessionData";
1011
+ const PERSIST_SESSION_UTILS_METHOD_NAME_CLEAR = "PersistSessionUtils.clear";
1012
+ const PERSIST_SESSION_UTILS_METHOD_NAME_DISPOSE = "PersistSessionUtils.dispose";
1013
+ const PERSIST_SESSION_UTILS_METHOD_NAME_WAIT_FOR_INIT = "PersistSessionUtils.waitForInit";
1014
+ const PERSIST_SESSION_UTILS_METHOD_NAME_USE_DUMMY = "PersistSessionUtils.useDummy";
1015
+ const PERSIST_SESSION_UTILS_METHOD_NAME_USE_JSON = "PersistSessionUtils.useJson";
1007
1016
  const PERSIST_RECENT_UTILS_METHOD_NAME_USE_PERSIST_RECENT_ADAPTER = "PersistRecentUtils.usePersistRecentAdapter";
1008
1017
  const PERSIST_RECENT_UTILS_METHOD_NAME_READ_DATA = "PersistRecentUtils.readRecentData";
1009
1018
  const PERSIST_RECENT_UTILS_METHOD_NAME_WRITE_DATA = "PersistRecentUtils.writeRecentData";
@@ -3049,6 +3058,14 @@ class PersistStateUtils {
3049
3058
  LOGGER_SERVICE$7.log(PERSIST_STATE_UTILS_METHOD_NAME_USE_DUMMY);
3050
3059
  this.usePersistStateAdapter(PersistDummy);
3051
3060
  };
3061
+ /**
3062
+ * Switches to the default JSON persist adapter.
3063
+ * All future persistence writes will use JSON storage.
3064
+ */
3065
+ this.useJson = () => {
3066
+ LOGGER_SERVICE$7.log(PERSIST_STATE_UTILS_METHOD_NAME_USE_JSON);
3067
+ this.usePersistStateAdapter(PersistBase);
3068
+ };
3052
3069
  /**
3053
3070
  * Clears the memoized storage cache.
3054
3071
  * Call this when process.cwd() changes between strategy iterations
@@ -3086,6 +3103,142 @@ class PersistStateUtils {
3086
3103
  * Used by StatePersistInstance for crash-safe state persistence.
3087
3104
  */
3088
3105
  const PersistStateAdapter = new PersistStateUtils();
3106
+ /**
3107
+ * Utility class for managing session persistence.
3108
+ *
3109
+ * Features:
3110
+ * - Memoized storage instances per (strategyName, exchangeName, frameName) key
3111
+ * - Custom adapter support
3112
+ * - Atomic read/write operations
3113
+ *
3114
+ * Storage layout: ./dump/session/<strategyName>/<exchangeName>/<frameName>.json
3115
+ *
3116
+ * Used by SessionPersistInstance for crash-safe session persistence.
3117
+ */
3118
+ class PersistSessionUtils {
3119
+ constructor() {
3120
+ this.PersistSessionFactory = PersistBase;
3121
+ this.getSessionStorage = memoize(([strategyName, exchangeName, frameName]) => `${strategyName}:${exchangeName}:${frameName}`, (strategyName, exchangeName, frameName) => Reflect.construct(this.PersistSessionFactory, [
3122
+ frameName,
3123
+ `./dump/session/${strategyName}/${exchangeName}/`,
3124
+ ]));
3125
+ /**
3126
+ * Initializes the storage for a given (strategyName, exchangeName, frameName) triple.
3127
+ *
3128
+ * @param strategyName - Strategy identifier
3129
+ * @param exchangeName - Exchange identifier
3130
+ * @param frameName - Frame identifier
3131
+ * @param initial - Whether this is the first initialization
3132
+ */
3133
+ this.waitForInit = async (strategyName, exchangeName, frameName, initial) => {
3134
+ LOGGER_SERVICE$7.info(PERSIST_SESSION_UTILS_METHOD_NAME_WAIT_FOR_INIT, {
3135
+ strategyName,
3136
+ exchangeName,
3137
+ frameName,
3138
+ initial,
3139
+ });
3140
+ const key = `${strategyName}:${exchangeName}:${frameName}`;
3141
+ const isInitial = initial && !this.getSessionStorage.has(key);
3142
+ const sessionStorage = this.getSessionStorage(strategyName, exchangeName, frameName);
3143
+ await sessionStorage.waitForInit(isInitial);
3144
+ };
3145
+ /**
3146
+ * Reads a session entry from persistence storage.
3147
+ *
3148
+ * @param strategyName - Strategy identifier
3149
+ * @param exchangeName - Exchange identifier
3150
+ * @param frameName - Frame identifier
3151
+ * @returns Promise resolving to entry data or null if not found
3152
+ */
3153
+ this.readSessionData = async (strategyName, exchangeName, frameName) => {
3154
+ LOGGER_SERVICE$7.info(PERSIST_SESSION_UTILS_METHOD_NAME_READ_DATA, {
3155
+ strategyName,
3156
+ exchangeName,
3157
+ frameName,
3158
+ });
3159
+ const key = `${strategyName}:${exchangeName}:${frameName}`;
3160
+ const isInitial = !this.getSessionStorage.has(key);
3161
+ const sessionStorage = this.getSessionStorage(strategyName, exchangeName, frameName);
3162
+ await sessionStorage.waitForInit(isInitial);
3163
+ if (await sessionStorage.hasValue(frameName)) {
3164
+ return await sessionStorage.readValue(frameName);
3165
+ }
3166
+ return null;
3167
+ };
3168
+ /**
3169
+ * Writes a session entry to disk with atomic file writes.
3170
+ *
3171
+ * @param data - Entry data to persist
3172
+ * @param strategyName - Strategy identifier
3173
+ * @param exchangeName - Exchange identifier
3174
+ * @param frameName - Frame identifier
3175
+ */
3176
+ this.writeSessionData = async (data, strategyName, exchangeName, frameName) => {
3177
+ LOGGER_SERVICE$7.info(PERSIST_SESSION_UTILS_METHOD_NAME_WRITE_DATA, {
3178
+ strategyName,
3179
+ exchangeName,
3180
+ frameName,
3181
+ });
3182
+ const key = `${strategyName}:${exchangeName}:${frameName}`;
3183
+ const isInitial = !this.getSessionStorage.has(key);
3184
+ const sessionStorage = this.getSessionStorage(strategyName, exchangeName, frameName);
3185
+ await sessionStorage.waitForInit(isInitial);
3186
+ await sessionStorage.writeValue(frameName, data);
3187
+ };
3188
+ /**
3189
+ * Switches to a dummy persist adapter that discards all writes.
3190
+ * All future persistence writes will be no-ops.
3191
+ */
3192
+ this.useDummy = () => {
3193
+ LOGGER_SERVICE$7.log(PERSIST_SESSION_UTILS_METHOD_NAME_USE_DUMMY);
3194
+ this.usePersistSessionAdapter(PersistDummy);
3195
+ };
3196
+ /**
3197
+ * Switches to the default JSON persist adapter.
3198
+ * All future persistence writes will use JSON storage.
3199
+ */
3200
+ this.useJson = () => {
3201
+ LOGGER_SERVICE$7.log(PERSIST_SESSION_UTILS_METHOD_NAME_USE_JSON);
3202
+ this.usePersistSessionAdapter(PersistBase);
3203
+ };
3204
+ /**
3205
+ * Clears the memoized storage cache.
3206
+ * Call this when process.cwd() changes between strategy iterations
3207
+ * so new storage instances are created with the updated base path.
3208
+ */
3209
+ this.clear = () => {
3210
+ LOGGER_SERVICE$7.info(PERSIST_SESSION_UTILS_METHOD_NAME_CLEAR);
3211
+ this.getSessionStorage.clear();
3212
+ };
3213
+ /**
3214
+ * Disposes of the session adapter and releases any resources.
3215
+ * Call this when a session is removed to clean up its associated storage.
3216
+ *
3217
+ * @param strategyName - Strategy identifier
3218
+ * @param exchangeName - Exchange identifier
3219
+ * @param frameName - Frame identifier
3220
+ */
3221
+ this.dispose = (strategyName, exchangeName, frameName) => {
3222
+ LOGGER_SERVICE$7.info(PERSIST_SESSION_UTILS_METHOD_NAME_DISPOSE);
3223
+ const key = `${strategyName}:${exchangeName}:${frameName}`;
3224
+ this.getSessionStorage.clear(key);
3225
+ };
3226
+ }
3227
+ /**
3228
+ * Registers a custom persistence adapter.
3229
+ *
3230
+ * @param Ctor - Custom PersistBase constructor
3231
+ */
3232
+ usePersistSessionAdapter(Ctor) {
3233
+ LOGGER_SERVICE$7.info(PERSIST_SESSION_UTILS_METHOD_NAME_USE_PERSIST_SESSION_ADAPTER);
3234
+ this.PersistSessionFactory = Ctor;
3235
+ }
3236
+ }
3237
+ /**
3238
+ * Global singleton instance of PersistSessionUtils.
3239
+ * Used by SessionPersistInstance for crash-safe session persistence.
3240
+ */
3241
+ const PersistSessionAdapter = new PersistSessionUtils();
3089
3242
 
3090
3243
  var _a$2, _b$2;
3091
3244
  const BUSY_DELAY = 100;
@@ -10551,7 +10704,7 @@ const GET_RISK_FN = (dto, backtest, exchangeName, frameName, self) => {
10551
10704
  * @param backtest - Whether running in backtest mode
10552
10705
  * @returns Unique string key for memoization
10553
10706
  */
10554
- const CREATE_KEY_FN$w = (symbol, strategyName, exchangeName, frameName, backtest) => {
10707
+ const CREATE_KEY_FN$x = (symbol, strategyName, exchangeName, frameName, backtest) => {
10555
10708
  const parts = [symbol, strategyName, exchangeName];
10556
10709
  if (frameName)
10557
10710
  parts.push(frameName);
@@ -10851,7 +11004,7 @@ class StrategyConnectionService {
10851
11004
  * @param backtest - Whether running in backtest mode
10852
11005
  * @returns Configured ClientStrategy instance
10853
11006
  */
10854
- this.getStrategy = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$w(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => {
11007
+ this.getStrategy = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$x(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => {
10855
11008
  const { riskName = "", riskList = [], getSignal, interval = STRATEGY_DEFAULT_INTERVAL, callbacks, } = this.strategySchemaService.get(strategyName);
10856
11009
  return new ClientStrategy({
10857
11010
  symbol,
@@ -11813,7 +11966,7 @@ class StrategyConnectionService {
11813
11966
  }
11814
11967
  return;
11815
11968
  }
11816
- const key = CREATE_KEY_FN$w(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
11969
+ const key = CREATE_KEY_FN$x(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
11817
11970
  if (!this.getStrategy.has(key)) {
11818
11971
  return;
11819
11972
  }
@@ -12987,7 +13140,7 @@ class ClientRisk {
12987
13140
  * @param backtest - Whether running in backtest mode
12988
13141
  * @returns Unique string key for memoization
12989
13142
  */
12990
- const CREATE_KEY_FN$v = (riskName, exchangeName, frameName, backtest) => {
13143
+ const CREATE_KEY_FN$w = (riskName, exchangeName, frameName, backtest) => {
12991
13144
  const parts = [riskName, exchangeName];
12992
13145
  if (frameName)
12993
13146
  parts.push(frameName);
@@ -13087,7 +13240,7 @@ class RiskConnectionService {
13087
13240
  * @param backtest - True if backtest mode, false if live mode
13088
13241
  * @returns Configured ClientRisk instance
13089
13242
  */
13090
- this.getRisk = memoize(([riskName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$v(riskName, exchangeName, frameName, backtest), (riskName, exchangeName, frameName, backtest) => {
13243
+ this.getRisk = memoize(([riskName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$w(riskName, exchangeName, frameName, backtest), (riskName, exchangeName, frameName, backtest) => {
13091
13244
  const schema = this.riskSchemaService.get(riskName);
13092
13245
  return new ClientRisk({
13093
13246
  ...schema,
@@ -13156,7 +13309,7 @@ class RiskConnectionService {
13156
13309
  payload,
13157
13310
  });
13158
13311
  if (payload) {
13159
- const key = CREATE_KEY_FN$v(payload.riskName, payload.exchangeName, payload.frameName, payload.backtest);
13312
+ const key = CREATE_KEY_FN$w(payload.riskName, payload.exchangeName, payload.frameName, payload.backtest);
13160
13313
  this.getRisk.clear(key);
13161
13314
  }
13162
13315
  else {
@@ -14275,7 +14428,7 @@ class ClientAction {
14275
14428
  * @param backtest - Whether running in backtest mode
14276
14429
  * @returns Unique string key for memoization
14277
14430
  */
14278
- const CREATE_KEY_FN$u = (actionName, strategyName, exchangeName, frameName, backtest) => {
14431
+ const CREATE_KEY_FN$v = (actionName, strategyName, exchangeName, frameName, backtest) => {
14279
14432
  const parts = [actionName, strategyName, exchangeName];
14280
14433
  if (frameName)
14281
14434
  parts.push(frameName);
@@ -14327,7 +14480,7 @@ class ActionConnectionService {
14327
14480
  * @param backtest - True if backtest mode, false if live mode
14328
14481
  * @returns Configured ClientAction instance
14329
14482
  */
14330
- this.getAction = memoize(([actionName, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$u(actionName, strategyName, exchangeName, frameName, backtest), (actionName, strategyName, exchangeName, frameName, backtest) => {
14483
+ this.getAction = memoize(([actionName, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$v(actionName, strategyName, exchangeName, frameName, backtest), (actionName, strategyName, exchangeName, frameName, backtest) => {
14331
14484
  const schema = this.actionSchemaService.get(actionName);
14332
14485
  return new ClientAction({
14333
14486
  ...schema,
@@ -14553,7 +14706,7 @@ class ActionConnectionService {
14553
14706
  await Promise.all(actions.map(async (action) => await action.dispose()));
14554
14707
  return;
14555
14708
  }
14556
- const key = CREATE_KEY_FN$u(payload.actionName, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
14709
+ const key = CREATE_KEY_FN$v(payload.actionName, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
14557
14710
  if (!this.getAction.has(key)) {
14558
14711
  return;
14559
14712
  }
@@ -14571,7 +14724,7 @@ const METHOD_NAME_VALIDATE$3 = "exchangeCoreService validate";
14571
14724
  * @param exchangeName - Exchange name
14572
14725
  * @returns Unique string key for memoization
14573
14726
  */
14574
- const CREATE_KEY_FN$t = (exchangeName) => {
14727
+ const CREATE_KEY_FN$u = (exchangeName) => {
14575
14728
  return exchangeName;
14576
14729
  };
14577
14730
  /**
@@ -14595,7 +14748,7 @@ class ExchangeCoreService {
14595
14748
  * @param exchangeName - Name of the exchange to validate
14596
14749
  * @returns Promise that resolves when validation is complete
14597
14750
  */
14598
- this.validate = memoize(([exchangeName]) => CREATE_KEY_FN$t(exchangeName), async (exchangeName) => {
14751
+ this.validate = memoize(([exchangeName]) => CREATE_KEY_FN$u(exchangeName), async (exchangeName) => {
14599
14752
  this.loggerService.log(METHOD_NAME_VALIDATE$3, {
14600
14753
  exchangeName,
14601
14754
  });
@@ -14847,7 +15000,7 @@ const METHOD_NAME_VALIDATE$2 = "strategyCoreService validate";
14847
15000
  * @param context - Execution context with strategyName, exchangeName, frameName
14848
15001
  * @returns Unique string key for memoization
14849
15002
  */
14850
- const CREATE_KEY_FN$s = (context) => {
15003
+ const CREATE_KEY_FN$t = (context) => {
14851
15004
  const parts = [context.strategyName, context.exchangeName];
14852
15005
  if (context.frameName)
14853
15006
  parts.push(context.frameName);
@@ -14879,7 +15032,7 @@ class StrategyCoreService {
14879
15032
  * @param context - Execution context with strategyName, exchangeName, frameName
14880
15033
  * @returns Promise that resolves when validation is complete
14881
15034
  */
14882
- this.validate = memoize(([context]) => CREATE_KEY_FN$s(context), async (context) => {
15035
+ this.validate = memoize(([context]) => CREATE_KEY_FN$t(context), async (context) => {
14883
15036
  this.loggerService.log(METHOD_NAME_VALIDATE$2, {
14884
15037
  context,
14885
15038
  });
@@ -16249,7 +16402,7 @@ class SizingGlobalService {
16249
16402
  * @param context - Context with riskName, exchangeName, frameName
16250
16403
  * @returns Unique string key for memoization
16251
16404
  */
16252
- const CREATE_KEY_FN$r = (context) => {
16405
+ const CREATE_KEY_FN$s = (context) => {
16253
16406
  const parts = [context.riskName, context.exchangeName];
16254
16407
  if (context.frameName)
16255
16408
  parts.push(context.frameName);
@@ -16275,7 +16428,7 @@ class RiskGlobalService {
16275
16428
  * @param payload - Payload with riskName, exchangeName and frameName
16276
16429
  * @returns Promise that resolves when validation is complete
16277
16430
  */
16278
- this.validate = memoize(([context]) => CREATE_KEY_FN$r(context), async (context) => {
16431
+ this.validate = memoize(([context]) => CREATE_KEY_FN$s(context), async (context) => {
16279
16432
  this.loggerService.log("riskGlobalService validate", {
16280
16433
  context,
16281
16434
  });
@@ -16353,7 +16506,7 @@ const METHOD_NAME_VALIDATE$1 = "actionCoreService validate";
16353
16506
  * @param context - Execution context with strategyName, exchangeName, frameName
16354
16507
  * @returns Unique string key for memoization
16355
16508
  */
16356
- const CREATE_KEY_FN$q = (context) => {
16509
+ const CREATE_KEY_FN$r = (context) => {
16357
16510
  const parts = [context.strategyName, context.exchangeName];
16358
16511
  if (context.frameName)
16359
16512
  parts.push(context.frameName);
@@ -16397,7 +16550,7 @@ class ActionCoreService {
16397
16550
  * @param context - Strategy execution context with strategyName, exchangeName and frameName
16398
16551
  * @returns Promise that resolves when all validations complete
16399
16552
  */
16400
- this.validate = memoize(([context]) => CREATE_KEY_FN$q(context), async (context) => {
16553
+ this.validate = memoize(([context]) => CREATE_KEY_FN$r(context), async (context) => {
16401
16554
  this.loggerService.log(METHOD_NAME_VALIDATE$1, {
16402
16555
  context,
16403
16556
  });
@@ -21467,7 +21620,7 @@ const ReportWriter = new ReportWriterAdapter();
21467
21620
  * @param backtest - Whether running in backtest mode
21468
21621
  * @returns Unique string key for memoization
21469
21622
  */
21470
- const CREATE_KEY_FN$p = (symbol, strategyName, exchangeName, frameName, backtest) => {
21623
+ const CREATE_KEY_FN$q = (symbol, strategyName, exchangeName, frameName, backtest) => {
21471
21624
  const parts = [symbol, strategyName, exchangeName];
21472
21625
  if (frameName)
21473
21626
  parts.push(frameName);
@@ -21713,7 +21866,7 @@ class BacktestMarkdownService {
21713
21866
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
21714
21867
  * Each combination gets its own isolated storage instance.
21715
21868
  */
21716
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$p(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$a(symbol, strategyName, exchangeName, frameName));
21869
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$q(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$a(symbol, strategyName, exchangeName, frameName));
21717
21870
  /**
21718
21871
  * Processes tick events and accumulates closed signals.
21719
21872
  * Should be called from IStrategyCallbacks.onTick.
@@ -21870,7 +22023,7 @@ class BacktestMarkdownService {
21870
22023
  payload,
21871
22024
  });
21872
22025
  if (payload) {
21873
- const key = CREATE_KEY_FN$p(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
22026
+ const key = CREATE_KEY_FN$q(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
21874
22027
  this.getStorage.clear(key);
21875
22028
  }
21876
22029
  else {
@@ -21932,7 +22085,7 @@ class BacktestMarkdownService {
21932
22085
  * @param backtest - Whether running in backtest mode
21933
22086
  * @returns Unique string key for memoization
21934
22087
  */
21935
- const CREATE_KEY_FN$o = (symbol, strategyName, exchangeName, frameName, backtest) => {
22088
+ const CREATE_KEY_FN$p = (symbol, strategyName, exchangeName, frameName, backtest) => {
21936
22089
  const parts = [symbol, strategyName, exchangeName];
21937
22090
  if (frameName)
21938
22091
  parts.push(frameName);
@@ -22427,7 +22580,7 @@ class LiveMarkdownService {
22427
22580
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
22428
22581
  * Each combination gets its own isolated storage instance.
22429
22582
  */
22430
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$o(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$9(symbol, strategyName, exchangeName, frameName));
22583
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$p(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$9(symbol, strategyName, exchangeName, frameName));
22431
22584
  /**
22432
22585
  * Subscribes to live signal emitter to receive tick events.
22433
22586
  * Protected against multiple subscriptions.
@@ -22645,7 +22798,7 @@ class LiveMarkdownService {
22645
22798
  payload,
22646
22799
  });
22647
22800
  if (payload) {
22648
- const key = CREATE_KEY_FN$o(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
22801
+ const key = CREATE_KEY_FN$p(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
22649
22802
  this.getStorage.clear(key);
22650
22803
  }
22651
22804
  else {
@@ -22665,7 +22818,7 @@ class LiveMarkdownService {
22665
22818
  * @param backtest - Whether running in backtest mode
22666
22819
  * @returns Unique string key for memoization
22667
22820
  */
22668
- const CREATE_KEY_FN$n = (symbol, strategyName, exchangeName, frameName, backtest) => {
22821
+ const CREATE_KEY_FN$o = (symbol, strategyName, exchangeName, frameName, backtest) => {
22669
22822
  const parts = [symbol, strategyName, exchangeName];
22670
22823
  if (frameName)
22671
22824
  parts.push(frameName);
@@ -22954,7 +23107,7 @@ class ScheduleMarkdownService {
22954
23107
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
22955
23108
  * Each combination gets its own isolated storage instance.
22956
23109
  */
22957
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$n(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$8(symbol, strategyName, exchangeName, frameName));
23110
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$o(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$8(symbol, strategyName, exchangeName, frameName));
22958
23111
  /**
22959
23112
  * Subscribes to signal emitter to receive scheduled signal events.
22960
23113
  * Protected against multiple subscriptions.
@@ -23157,7 +23310,7 @@ class ScheduleMarkdownService {
23157
23310
  payload,
23158
23311
  });
23159
23312
  if (payload) {
23160
- const key = CREATE_KEY_FN$n(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
23313
+ const key = CREATE_KEY_FN$o(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
23161
23314
  this.getStorage.clear(key);
23162
23315
  }
23163
23316
  else {
@@ -23177,7 +23330,7 @@ class ScheduleMarkdownService {
23177
23330
  * @param backtest - Whether running in backtest mode
23178
23331
  * @returns Unique string key for memoization
23179
23332
  */
23180
- const CREATE_KEY_FN$m = (symbol, strategyName, exchangeName, frameName, backtest) => {
23333
+ const CREATE_KEY_FN$n = (symbol, strategyName, exchangeName, frameName, backtest) => {
23181
23334
  const parts = [symbol, strategyName, exchangeName];
23182
23335
  if (frameName)
23183
23336
  parts.push(frameName);
@@ -23422,7 +23575,7 @@ class PerformanceMarkdownService {
23422
23575
  * Memoized function to get or create PerformanceStorage for a symbol-strategy-exchange-frame-backtest combination.
23423
23576
  * Each combination gets its own isolated storage instance.
23424
23577
  */
23425
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$m(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new PerformanceStorage(symbol, strategyName, exchangeName, frameName));
23578
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$n(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new PerformanceStorage(symbol, strategyName, exchangeName, frameName));
23426
23579
  /**
23427
23580
  * Subscribes to performance emitter to receive performance events.
23428
23581
  * Protected against multiple subscriptions.
@@ -23589,7 +23742,7 @@ class PerformanceMarkdownService {
23589
23742
  payload,
23590
23743
  });
23591
23744
  if (payload) {
23592
- const key = CREATE_KEY_FN$m(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
23745
+ const key = CREATE_KEY_FN$n(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
23593
23746
  this.getStorage.clear(key);
23594
23747
  }
23595
23748
  else {
@@ -24068,7 +24221,7 @@ class WalkerMarkdownService {
24068
24221
  * @param backtest - Whether running in backtest mode
24069
24222
  * @returns Unique string key for memoization
24070
24223
  */
24071
- const CREATE_KEY_FN$l = (exchangeName, frameName, backtest) => {
24224
+ const CREATE_KEY_FN$m = (exchangeName, frameName, backtest) => {
24072
24225
  const parts = [exchangeName];
24073
24226
  if (frameName)
24074
24227
  parts.push(frameName);
@@ -24515,7 +24668,7 @@ class HeatMarkdownService {
24515
24668
  * Memoized function to get or create HeatmapStorage for exchange, frame and backtest mode.
24516
24669
  * Each exchangeName + frameName + backtest mode combination gets its own isolated heatmap storage instance.
24517
24670
  */
24518
- this.getStorage = memoize(([exchangeName, frameName, backtest]) => CREATE_KEY_FN$l(exchangeName, frameName, backtest), (exchangeName, frameName, backtest) => new HeatmapStorage(exchangeName, frameName, backtest));
24671
+ this.getStorage = memoize(([exchangeName, frameName, backtest]) => CREATE_KEY_FN$m(exchangeName, frameName, backtest), (exchangeName, frameName, backtest) => new HeatmapStorage(exchangeName, frameName, backtest));
24519
24672
  /**
24520
24673
  * Subscribes to signal emitter to receive tick events.
24521
24674
  * Protected against multiple subscriptions.
@@ -24733,7 +24886,7 @@ class HeatMarkdownService {
24733
24886
  payload,
24734
24887
  });
24735
24888
  if (payload) {
24736
- const key = CREATE_KEY_FN$l(payload.exchangeName, payload.frameName, payload.backtest);
24889
+ const key = CREATE_KEY_FN$m(payload.exchangeName, payload.frameName, payload.backtest);
24737
24890
  this.getStorage.clear(key);
24738
24891
  }
24739
24892
  else {
@@ -25764,7 +25917,7 @@ class ClientPartial {
25764
25917
  * @param backtest - Whether running in backtest mode
25765
25918
  * @returns Unique string key for memoization
25766
25919
  */
25767
- const CREATE_KEY_FN$k = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
25920
+ const CREATE_KEY_FN$l = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
25768
25921
  /**
25769
25922
  * Creates a callback function for emitting profit events to partialProfitSubject.
25770
25923
  *
@@ -25886,7 +26039,7 @@ class PartialConnectionService {
25886
26039
  * Key format: "signalId:backtest" or "signalId:live"
25887
26040
  * Value: ClientPartial instance with logger and event emitters
25888
26041
  */
25889
- this.getPartial = memoize(([signalId, backtest]) => CREATE_KEY_FN$k(signalId, backtest), (signalId, backtest) => {
26042
+ this.getPartial = memoize(([signalId, backtest]) => CREATE_KEY_FN$l(signalId, backtest), (signalId, backtest) => {
25890
26043
  return new ClientPartial({
25891
26044
  signalId,
25892
26045
  logger: this.loggerService,
@@ -25976,7 +26129,7 @@ class PartialConnectionService {
25976
26129
  const partial = this.getPartial(data.id, backtest);
25977
26130
  await partial.waitForInit(symbol, data.strategyName, data.exchangeName, backtest);
25978
26131
  await partial.clear(symbol, data, priceClose, backtest);
25979
- const key = CREATE_KEY_FN$k(data.id, backtest);
26132
+ const key = CREATE_KEY_FN$l(data.id, backtest);
25980
26133
  this.getPartial.clear(key);
25981
26134
  };
25982
26135
  }
@@ -25992,7 +26145,7 @@ class PartialConnectionService {
25992
26145
  * @param backtest - Whether running in backtest mode
25993
26146
  * @returns Unique string key for memoization
25994
26147
  */
25995
- const CREATE_KEY_FN$j = (symbol, strategyName, exchangeName, frameName, backtest) => {
26148
+ const CREATE_KEY_FN$k = (symbol, strategyName, exchangeName, frameName, backtest) => {
25996
26149
  const parts = [symbol, strategyName, exchangeName];
25997
26150
  if (frameName)
25998
26151
  parts.push(frameName);
@@ -26215,7 +26368,7 @@ class PartialMarkdownService {
26215
26368
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
26216
26369
  * Each combination gets its own isolated storage instance.
26217
26370
  */
26218
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$j(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$6(symbol, strategyName, exchangeName, frameName));
26371
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$k(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$6(symbol, strategyName, exchangeName, frameName));
26219
26372
  /**
26220
26373
  * Subscribes to partial profit/loss signal emitters to receive events.
26221
26374
  * Protected against multiple subscriptions.
@@ -26425,7 +26578,7 @@ class PartialMarkdownService {
26425
26578
  payload,
26426
26579
  });
26427
26580
  if (payload) {
26428
- const key = CREATE_KEY_FN$j(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
26581
+ const key = CREATE_KEY_FN$k(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
26429
26582
  this.getStorage.clear(key);
26430
26583
  }
26431
26584
  else {
@@ -26441,7 +26594,7 @@ class PartialMarkdownService {
26441
26594
  * @param context - Context with strategyName, exchangeName, frameName
26442
26595
  * @returns Unique string key for memoization
26443
26596
  */
26444
- const CREATE_KEY_FN$i = (context) => {
26597
+ const CREATE_KEY_FN$j = (context) => {
26445
26598
  const parts = [context.strategyName, context.exchangeName];
26446
26599
  if (context.frameName)
26447
26600
  parts.push(context.frameName);
@@ -26515,7 +26668,7 @@ class PartialGlobalService {
26515
26668
  * @param context - Context with strategyName, exchangeName and frameName
26516
26669
  * @param methodName - Name of the calling method for error tracking
26517
26670
  */
26518
- this.validate = memoize(([context]) => CREATE_KEY_FN$i(context), (context, methodName) => {
26671
+ this.validate = memoize(([context]) => CREATE_KEY_FN$j(context), (context, methodName) => {
26519
26672
  this.loggerService.log("partialGlobalService validate", {
26520
26673
  context,
26521
26674
  methodName,
@@ -26970,7 +27123,7 @@ class ClientBreakeven {
26970
27123
  * @param backtest - Whether running in backtest mode
26971
27124
  * @returns Unique string key for memoization
26972
27125
  */
26973
- const CREATE_KEY_FN$h = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
27126
+ const CREATE_KEY_FN$i = (signalId, backtest) => `${signalId}:${backtest ? "backtest" : "live"}`;
26974
27127
  /**
26975
27128
  * Creates a callback function for emitting breakeven events to breakevenSubject.
26976
27129
  *
@@ -27056,7 +27209,7 @@ class BreakevenConnectionService {
27056
27209
  * Key format: "signalId:backtest" or "signalId:live"
27057
27210
  * Value: ClientBreakeven instance with logger and event emitter
27058
27211
  */
27059
- this.getBreakeven = memoize(([signalId, backtest]) => CREATE_KEY_FN$h(signalId, backtest), (signalId, backtest) => {
27212
+ this.getBreakeven = memoize(([signalId, backtest]) => CREATE_KEY_FN$i(signalId, backtest), (signalId, backtest) => {
27060
27213
  return new ClientBreakeven({
27061
27214
  signalId,
27062
27215
  logger: this.loggerService,
@@ -27117,7 +27270,7 @@ class BreakevenConnectionService {
27117
27270
  const breakeven = this.getBreakeven(data.id, backtest);
27118
27271
  await breakeven.waitForInit(symbol, data.strategyName, data.exchangeName, backtest);
27119
27272
  await breakeven.clear(symbol, data, priceClose, backtest);
27120
- const key = CREATE_KEY_FN$h(data.id, backtest);
27273
+ const key = CREATE_KEY_FN$i(data.id, backtest);
27121
27274
  this.getBreakeven.clear(key);
27122
27275
  };
27123
27276
  }
@@ -27133,7 +27286,7 @@ class BreakevenConnectionService {
27133
27286
  * @param backtest - Whether running in backtest mode
27134
27287
  * @returns Unique string key for memoization
27135
27288
  */
27136
- const CREATE_KEY_FN$g = (symbol, strategyName, exchangeName, frameName, backtest) => {
27289
+ const CREATE_KEY_FN$h = (symbol, strategyName, exchangeName, frameName, backtest) => {
27137
27290
  const parts = [symbol, strategyName, exchangeName];
27138
27291
  if (frameName)
27139
27292
  parts.push(frameName);
@@ -27308,7 +27461,7 @@ class BreakevenMarkdownService {
27308
27461
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
27309
27462
  * Each combination gets its own isolated storage instance.
27310
27463
  */
27311
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$g(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$5(symbol, strategyName, exchangeName, frameName));
27464
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$h(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$5(symbol, strategyName, exchangeName, frameName));
27312
27465
  /**
27313
27466
  * Subscribes to breakeven signal emitter to receive events.
27314
27467
  * Protected against multiple subscriptions.
@@ -27497,7 +27650,7 @@ class BreakevenMarkdownService {
27497
27650
  payload,
27498
27651
  });
27499
27652
  if (payload) {
27500
- const key = CREATE_KEY_FN$g(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
27653
+ const key = CREATE_KEY_FN$h(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
27501
27654
  this.getStorage.clear(key);
27502
27655
  }
27503
27656
  else {
@@ -27513,7 +27666,7 @@ class BreakevenMarkdownService {
27513
27666
  * @param context - Context with strategyName, exchangeName, frameName
27514
27667
  * @returns Unique string key for memoization
27515
27668
  */
27516
- const CREATE_KEY_FN$f = (context) => {
27669
+ const CREATE_KEY_FN$g = (context) => {
27517
27670
  const parts = [context.strategyName, context.exchangeName];
27518
27671
  if (context.frameName)
27519
27672
  parts.push(context.frameName);
@@ -27587,7 +27740,7 @@ class BreakevenGlobalService {
27587
27740
  * @param context - Context with strategyName, exchangeName and frameName
27588
27741
  * @param methodName - Name of the calling method for error tracking
27589
27742
  */
27590
- this.validate = memoize(([context]) => CREATE_KEY_FN$f(context), (context, methodName) => {
27743
+ this.validate = memoize(([context]) => CREATE_KEY_FN$g(context), (context, methodName) => {
27591
27744
  this.loggerService.log("breakevenGlobalService validate", {
27592
27745
  context,
27593
27746
  methodName,
@@ -27808,7 +27961,7 @@ class ConfigValidationService {
27808
27961
  * @param backtest - Whether running in backtest mode
27809
27962
  * @returns Unique string key for memoization
27810
27963
  */
27811
- const CREATE_KEY_FN$e = (symbol, strategyName, exchangeName, frameName, backtest) => {
27964
+ const CREATE_KEY_FN$f = (symbol, strategyName, exchangeName, frameName, backtest) => {
27812
27965
  const parts = [symbol, strategyName, exchangeName];
27813
27966
  if (frameName)
27814
27967
  parts.push(frameName);
@@ -27975,7 +28128,7 @@ class RiskMarkdownService {
27975
28128
  * Memoized function to get or create ReportStorage for a symbol-strategy-exchange-frame-backtest combination.
27976
28129
  * Each combination gets its own isolated storage instance.
27977
28130
  */
27978
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$e(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$4(symbol, strategyName, exchangeName, frameName));
28131
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$f(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$4(symbol, strategyName, exchangeName, frameName));
27979
28132
  /**
27980
28133
  * Subscribes to risk rejection emitter to receive rejection events.
27981
28134
  * Protected against multiple subscriptions.
@@ -28164,7 +28317,7 @@ class RiskMarkdownService {
28164
28317
  payload,
28165
28318
  });
28166
28319
  if (payload) {
28167
- const key = CREATE_KEY_FN$e(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
28320
+ const key = CREATE_KEY_FN$f(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
28168
28321
  this.getStorage.clear(key);
28169
28322
  }
28170
28323
  else {
@@ -30744,7 +30897,7 @@ class HighestProfitReportService {
30744
30897
  * @returns Colon-separated key string for memoization
30745
30898
  * @internal
30746
30899
  */
30747
- const CREATE_KEY_FN$d = (symbol, strategyName, exchangeName, frameName, backtest) => {
30900
+ const CREATE_KEY_FN$e = (symbol, strategyName, exchangeName, frameName, backtest) => {
30748
30901
  const parts = [symbol, strategyName, exchangeName];
30749
30902
  if (frameName)
30750
30903
  parts.push(frameName);
@@ -30986,7 +31139,7 @@ class StrategyMarkdownService {
30986
31139
  *
30987
31140
  * @internal
30988
31141
  */
30989
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$d(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$3(symbol, strategyName, exchangeName, frameName));
31142
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$e(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$3(symbol, strategyName, exchangeName, frameName));
30990
31143
  /**
30991
31144
  * Records a cancel-scheduled event when a scheduled signal is cancelled.
30992
31145
  *
@@ -31560,7 +31713,7 @@ class StrategyMarkdownService {
31560
31713
  this.clear = async (payload) => {
31561
31714
  this.loggerService.log("strategyMarkdownService clear", { payload });
31562
31715
  if (payload) {
31563
- const key = CREATE_KEY_FN$d(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
31716
+ const key = CREATE_KEY_FN$e(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
31564
31717
  this.getStorage.clear(key);
31565
31718
  }
31566
31719
  else {
@@ -31668,7 +31821,7 @@ class StrategyMarkdownService {
31668
31821
  * Creates a unique key for memoizing ReportStorage instances.
31669
31822
  * Key format: "symbol:strategyName:exchangeName[:frameName]:backtest|live"
31670
31823
  */
31671
- const CREATE_KEY_FN$c = (symbol, strategyName, exchangeName, frameName, backtest) => {
31824
+ const CREATE_KEY_FN$d = (symbol, strategyName, exchangeName, frameName, backtest) => {
31672
31825
  const parts = [symbol, strategyName, exchangeName];
31673
31826
  if (frameName)
31674
31827
  parts.push(frameName);
@@ -31861,7 +32014,7 @@ let ReportStorage$2 = class ReportStorage {
31861
32014
  class SyncMarkdownService {
31862
32015
  constructor() {
31863
32016
  this.loggerService = inject(TYPES.loggerService);
31864
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$c(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$2(symbol, strategyName, exchangeName, frameName, backtest));
32017
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$d(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => new ReportStorage$2(symbol, strategyName, exchangeName, frameName, backtest));
31865
32018
  /**
31866
32019
  * Subscribes to `syncSubject` to start receiving `SignalSyncContract` events.
31867
32020
  * Protected against multiple subscriptions via `singleshot` — subsequent calls
@@ -32059,7 +32212,7 @@ class SyncMarkdownService {
32059
32212
  this.clear = async (payload) => {
32060
32213
  this.loggerService.log("syncMarkdownService clear", { payload });
32061
32214
  if (payload) {
32062
- const key = CREATE_KEY_FN$c(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
32215
+ const key = CREATE_KEY_FN$d(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
32063
32216
  this.getStorage.clear(key);
32064
32217
  }
32065
32218
  else {
@@ -32072,7 +32225,7 @@ class SyncMarkdownService {
32072
32225
  /**
32073
32226
  * Creates a unique memoization key for a symbol-strategy-exchange-frame-backtest combination.
32074
32227
  */
32075
- const CREATE_KEY_FN$b = (symbol, strategyName, exchangeName, frameName, backtest) => {
32228
+ const CREATE_KEY_FN$c = (symbol, strategyName, exchangeName, frameName, backtest) => {
32076
32229
  const parts = [symbol, strategyName, exchangeName];
32077
32230
  if (frameName)
32078
32231
  parts.push(frameName);
@@ -32250,7 +32403,7 @@ let ReportStorage$1 = class ReportStorage {
32250
32403
  class HighestProfitMarkdownService {
32251
32404
  constructor() {
32252
32405
  this.loggerService = inject(TYPES.loggerService);
32253
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$b(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$1(symbol, strategyName, exchangeName, frameName));
32406
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$c(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage$1(symbol, strategyName, exchangeName, frameName));
32254
32407
  /**
32255
32408
  * Subscribes to `highestProfitSubject` to start receiving `HighestProfitContract`
32256
32409
  * events. Protected against multiple subscriptions via `singleshot` — subsequent
@@ -32416,7 +32569,7 @@ class HighestProfitMarkdownService {
32416
32569
  this.clear = async (payload) => {
32417
32570
  this.loggerService.log("highestProfitMarkdownService clear", { payload });
32418
32571
  if (payload) {
32419
- const key = CREATE_KEY_FN$b(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
32572
+ const key = CREATE_KEY_FN$c(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
32420
32573
  this.getStorage.clear(key);
32421
32574
  }
32422
32575
  else {
@@ -32438,7 +32591,7 @@ const LISTEN_TIMEOUT$1 = 120000;
32438
32591
  * @param backtest - Whether running in backtest mode
32439
32592
  * @returns Unique string key for memoization
32440
32593
  */
32441
- const CREATE_KEY_FN$a = (symbol, strategyName, exchangeName, frameName, backtest) => {
32594
+ const CREATE_KEY_FN$b = (symbol, strategyName, exchangeName, frameName, backtest) => {
32442
32595
  const parts = [symbol, strategyName, exchangeName];
32443
32596
  if (frameName)
32444
32597
  parts.push(frameName);
@@ -32481,7 +32634,7 @@ class PriceMetaService {
32481
32634
  * Each subject holds the latest currentPrice emitted by the strategy iterator for that key.
32482
32635
  * Instances are cached until clear() is called.
32483
32636
  */
32484
- this.getSource = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$a(symbol, strategyName, exchangeName, frameName, backtest), () => new BehaviorSubject());
32637
+ this.getSource = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$b(symbol, strategyName, exchangeName, frameName, backtest), () => new BehaviorSubject());
32485
32638
  /**
32486
32639
  * Returns the current market price for the given symbol and context.
32487
32640
  *
@@ -32510,10 +32663,10 @@ class PriceMetaService {
32510
32663
  if (source.data) {
32511
32664
  return source.data;
32512
32665
  }
32513
- console.warn(`PriceMetaService: No currentPrice available for ${CREATE_KEY_FN$a(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}. Trying to fetch from strategy iterator as a fallback...`);
32666
+ console.warn(`PriceMetaService: No currentPrice available for ${CREATE_KEY_FN$b(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}. Trying to fetch from strategy iterator as a fallback...`);
32514
32667
  const currentPrice = await waitForNext(source, (data) => !!data, LISTEN_TIMEOUT$1);
32515
32668
  if (typeof currentPrice === "symbol") {
32516
- throw new Error(`PriceMetaService: Timeout while waiting for currentPrice for ${CREATE_KEY_FN$a(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}`);
32669
+ throw new Error(`PriceMetaService: Timeout while waiting for currentPrice for ${CREATE_KEY_FN$b(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}`);
32517
32670
  }
32518
32671
  return currentPrice;
32519
32672
  };
@@ -32555,7 +32708,7 @@ class PriceMetaService {
32555
32708
  this.getSource.clear();
32556
32709
  return;
32557
32710
  }
32558
- const key = CREATE_KEY_FN$a(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
32711
+ const key = CREATE_KEY_FN$b(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
32559
32712
  this.getSource.clear(key);
32560
32713
  };
32561
32714
  }
@@ -32573,7 +32726,7 @@ const LISTEN_TIMEOUT = 120000;
32573
32726
  * @param backtest - Whether running in backtest mode
32574
32727
  * @returns Unique string key for memoization
32575
32728
  */
32576
- const CREATE_KEY_FN$9 = (symbol, strategyName, exchangeName, frameName, backtest) => {
32729
+ const CREATE_KEY_FN$a = (symbol, strategyName, exchangeName, frameName, backtest) => {
32577
32730
  const parts = [symbol, strategyName, exchangeName];
32578
32731
  if (frameName)
32579
32732
  parts.push(frameName);
@@ -32616,7 +32769,7 @@ class TimeMetaService {
32616
32769
  * Each subject holds the latest createdAt timestamp emitted by the strategy iterator for that key.
32617
32770
  * Instances are cached until clear() is called.
32618
32771
  */
32619
- this.getSource = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$9(symbol, strategyName, exchangeName, frameName, backtest), () => new BehaviorSubject());
32772
+ this.getSource = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$a(symbol, strategyName, exchangeName, frameName, backtest), () => new BehaviorSubject());
32620
32773
  /**
32621
32774
  * Returns the current candle timestamp (in milliseconds) for the given symbol and context.
32622
32775
  *
@@ -32644,10 +32797,10 @@ class TimeMetaService {
32644
32797
  if (source.data) {
32645
32798
  return source.data;
32646
32799
  }
32647
- console.warn(`TimeMetaService: No timestamp available for ${CREATE_KEY_FN$9(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}. Trying to fetch from strategy iterator as a fallback...`);
32800
+ console.warn(`TimeMetaService: No timestamp available for ${CREATE_KEY_FN$a(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}. Trying to fetch from strategy iterator as a fallback...`);
32648
32801
  const timestamp = await waitForNext(source, (data) => !!data, LISTEN_TIMEOUT);
32649
32802
  if (typeof timestamp === "symbol") {
32650
- throw new Error(`TimeMetaService: Timeout while waiting for timestamp for ${CREATE_KEY_FN$9(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}`);
32803
+ throw new Error(`TimeMetaService: Timeout while waiting for timestamp for ${CREATE_KEY_FN$a(symbol, context.strategyName, context.exchangeName, context.frameName, backtest)}`);
32651
32804
  }
32652
32805
  return timestamp;
32653
32806
  };
@@ -32689,7 +32842,7 @@ class TimeMetaService {
32689
32842
  this.getSource.clear();
32690
32843
  return;
32691
32844
  }
32692
- const key = CREATE_KEY_FN$9(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
32845
+ const key = CREATE_KEY_FN$a(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
32693
32846
  this.getSource.clear(key);
32694
32847
  };
32695
32848
  }
@@ -32795,7 +32948,7 @@ class MaxDrawdownReportService {
32795
32948
  /**
32796
32949
  * Creates a unique memoization key for a symbol-strategy-exchange-frame-backtest combination.
32797
32950
  */
32798
- const CREATE_KEY_FN$8 = (symbol, strategyName, exchangeName, frameName, backtest) => {
32951
+ const CREATE_KEY_FN$9 = (symbol, strategyName, exchangeName, frameName, backtest) => {
32799
32952
  const parts = [symbol, strategyName, exchangeName];
32800
32953
  if (frameName)
32801
32954
  parts.push(frameName);
@@ -32921,7 +33074,7 @@ class ReportStorage {
32921
33074
  class MaxDrawdownMarkdownService {
32922
33075
  constructor() {
32923
33076
  this.loggerService = inject(TYPES.loggerService);
32924
- this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$8(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage(symbol, strategyName, exchangeName, frameName));
33077
+ this.getStorage = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$9(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName) => new ReportStorage(symbol, strategyName, exchangeName, frameName));
32925
33078
  /**
32926
33079
  * Subscribes to `maxDrawdownSubject` to start receiving `MaxDrawdownContract`
32927
33080
  * events. Protected against multiple subscriptions via `singleshot`.
@@ -33000,7 +33153,7 @@ class MaxDrawdownMarkdownService {
33000
33153
  this.clear = async (payload) => {
33001
33154
  this.loggerService.log("maxDrawdownMarkdownService clear", { payload });
33002
33155
  if (payload) {
33003
- const key = CREATE_KEY_FN$8(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
33156
+ const key = CREATE_KEY_FN$9(payload.symbol, payload.strategyName, payload.exchangeName, payload.frameName, payload.backtest);
33004
33157
  this.getStorage.clear(key);
33005
33158
  }
33006
33159
  else {
@@ -33018,7 +33171,7 @@ const METHOD_NAME_VALIDATE = "notificationHelperService.validate";
33018
33171
  * @param context - Execution context with strategyName, exchangeName, frameName
33019
33172
  * @returns Unique string key for memoization
33020
33173
  */
33021
- const CREATE_KEY_FN$7 = (context) => {
33174
+ const CREATE_KEY_FN$8 = (context) => {
33022
33175
  const parts = [context.strategyName, context.exchangeName];
33023
33176
  if (context.frameName)
33024
33177
  parts.push(context.frameName);
@@ -33051,7 +33204,7 @@ class NotificationHelperService {
33051
33204
  * @param context - Routing context: strategyName, exchangeName, frameName
33052
33205
  * @throws {Error} If any registered schema fails validation
33053
33206
  */
33054
- this.validate = memoize(([context]) => CREATE_KEY_FN$7(context), async (context) => {
33207
+ this.validate = memoize(([context]) => CREATE_KEY_FN$8(context), async (context) => {
33055
33208
  this.loggerService.log(METHOD_NAME_VALIDATE, {
33056
33209
  context,
33057
33210
  });
@@ -46595,7 +46748,7 @@ const RECENT_ADAPTER_METHOD_NAME_GET_MINUTES_SINCE_LATEST_SIGNAL = "RecentAdapte
46595
46748
  * @param backtest - Flag indicating if the context is backtest or live
46596
46749
  * @returns Composite key string
46597
46750
  */
46598
- const CREATE_KEY_FN$6 = (symbol, strategyName, exchangeName, frameName, backtest) => {
46751
+ const CREATE_KEY_FN$7 = (symbol, strategyName, exchangeName, frameName, backtest) => {
46599
46752
  const parts = [symbol, strategyName, exchangeName];
46600
46753
  if (frameName)
46601
46754
  parts.push(frameName);
@@ -46685,7 +46838,7 @@ class RecentMemoryBacktestUtils {
46685
46838
  backtest.loggerService.info(RECENT_MEMORY_BACKTEST_METHOD_NAME_HANDLE_ACTIVE_PING, {
46686
46839
  signalId: event.data.id,
46687
46840
  });
46688
- const key = CREATE_KEY_FN$6(event.symbol, event.strategyName, event.exchangeName, event.data.frameName, event.backtest);
46841
+ const key = CREATE_KEY_FN$7(event.symbol, event.strategyName, event.exchangeName, event.data.frameName, event.backtest);
46689
46842
  this._signals.set(key, event.data);
46690
46843
  };
46691
46844
  /**
@@ -46698,7 +46851,7 @@ class RecentMemoryBacktestUtils {
46698
46851
  * @returns The latest signal or null if not found
46699
46852
  */
46700
46853
  this.getLatestSignal = async (symbol, strategyName, exchangeName, frameName, backtest$1) => {
46701
- const key = CREATE_KEY_FN$6(symbol, strategyName, exchangeName, frameName, backtest$1);
46854
+ const key = CREATE_KEY_FN$7(symbol, strategyName, exchangeName, frameName, backtest$1);
46702
46855
  backtest.loggerService.info(RECENT_MEMORY_BACKTEST_METHOD_NAME_GET_LATEST_SIGNAL, { key });
46703
46856
  return this._signals.get(key) ?? null;
46704
46857
  };
@@ -46804,7 +46957,7 @@ class RecentMemoryLiveUtils {
46804
46957
  backtest.loggerService.info(RECENT_MEMORY_LIVE_METHOD_NAME_HANDLE_ACTIVE_PING, {
46805
46958
  signalId: event.data.id,
46806
46959
  });
46807
- const key = CREATE_KEY_FN$6(event.symbol, event.strategyName, event.exchangeName, event.data.frameName, event.backtest);
46960
+ const key = CREATE_KEY_FN$7(event.symbol, event.strategyName, event.exchangeName, event.data.frameName, event.backtest);
46808
46961
  this._signals.set(key, event.data);
46809
46962
  };
46810
46963
  /**
@@ -46817,7 +46970,7 @@ class RecentMemoryLiveUtils {
46817
46970
  * @returns The latest signal or null if not found
46818
46971
  */
46819
46972
  this.getLatestSignal = async (symbol, strategyName, exchangeName, frameName, backtest$1) => {
46820
- const key = CREATE_KEY_FN$6(symbol, strategyName, exchangeName, frameName, backtest$1);
46973
+ const key = CREATE_KEY_FN$7(symbol, strategyName, exchangeName, frameName, backtest$1);
46821
46974
  backtest.loggerService.info(RECENT_MEMORY_LIVE_METHOD_NAME_GET_LATEST_SIGNAL, { key });
46822
46975
  return this._signals.get(key) ?? null;
46823
46976
  };
@@ -47168,7 +47321,7 @@ const RecentLive = new RecentLiveAdapter();
47168
47321
  */
47169
47322
  const RecentBacktest = new RecentBacktestAdapter();
47170
47323
 
47171
- const CREATE_KEY_FN$5 = (signalId, bucketName) => `${signalId}_${bucketName}`;
47324
+ const CREATE_KEY_FN$6 = (signalId, bucketName) => `${signalId}_${bucketName}`;
47172
47325
  const STATE_LOCAL_INSTANCE_METHOD_NAME_GET = "StateLocalInstance.getState";
47173
47326
  const STATE_LOCAL_INSTANCE_METHOD_NAME_SET = "StateLocalInstance.setState";
47174
47327
  const STATE_PERSIST_INSTANCE_METHOD_NAME_WAIT_FOR_INIT = "StatePersistInstance.waitForInit";
@@ -47346,7 +47499,7 @@ class StatePersistInstance {
47346
47499
  else {
47347
47500
  this._value = dispatch;
47348
47501
  }
47349
- const id = CREATE_KEY_FN$5(this.signalId, this.bucketName);
47502
+ const id = CREATE_KEY_FN$6(this.signalId, this.bucketName);
47350
47503
  await PersistStateAdapter.writeStateData({ id, data: this._value }, this.signalId, this.bucketName);
47351
47504
  return this._value;
47352
47505
  });
@@ -47391,14 +47544,14 @@ class StatePersistInstance {
47391
47544
  class StateBacktestAdapter {
47392
47545
  constructor() {
47393
47546
  this.StateFactory = StateLocalInstance;
47394
- this.getInstance = memoize(([signalId, bucketName]) => CREATE_KEY_FN$5(signalId, bucketName), (signalId, bucketName, initialValue) => Reflect.construct(this.StateFactory, [initialValue, signalId, bucketName]));
47547
+ this.getInstance = memoize(([signalId, bucketName]) => CREATE_KEY_FN$6(signalId, bucketName), (signalId, bucketName, initialValue) => Reflect.construct(this.StateFactory, [initialValue, signalId, bucketName]));
47395
47548
  /**
47396
47549
  * Disposes all memoized instances for the given signalId.
47397
47550
  * Called by StateAdapter when a signal is cancelled or closed.
47398
47551
  * @param signalId - Signal identifier to dispose
47399
47552
  */
47400
47553
  this.disposeSignal = (signalId) => {
47401
- const prefix = CREATE_KEY_FN$5(signalId, "");
47554
+ const prefix = CREATE_KEY_FN$6(signalId, "");
47402
47555
  for (const key of this.getInstance.keys()) {
47403
47556
  if (key.startsWith(prefix)) {
47404
47557
  const instance = this.getInstance.get(key);
@@ -47419,7 +47572,7 @@ class StateBacktestAdapter {
47419
47572
  signalId: dto.signalId,
47420
47573
  bucketName: dto.bucketName,
47421
47574
  });
47422
- const key = CREATE_KEY_FN$5(dto.signalId, dto.bucketName);
47575
+ const key = CREATE_KEY_FN$6(dto.signalId, dto.bucketName);
47423
47576
  const isInitial = !this.getInstance.has(key);
47424
47577
  const instance = this.getInstance(dto.signalId, dto.bucketName, dto.initialValue);
47425
47578
  await instance.waitForInit(isInitial);
@@ -47438,7 +47591,7 @@ class StateBacktestAdapter {
47438
47591
  signalId: dto.signalId,
47439
47592
  bucketName: dto.bucketName,
47440
47593
  });
47441
- const key = CREATE_KEY_FN$5(dto.signalId, dto.bucketName);
47594
+ const key = CREATE_KEY_FN$6(dto.signalId, dto.bucketName);
47442
47595
  const isInitial = !this.getInstance.has(key);
47443
47596
  const instance = this.getInstance(dto.signalId, dto.bucketName, dto.initialValue);
47444
47597
  await instance.waitForInit(isInitial);
@@ -47506,14 +47659,14 @@ class StateBacktestAdapter {
47506
47659
  class StateLiveAdapter {
47507
47660
  constructor() {
47508
47661
  this.StateFactory = StatePersistInstance;
47509
- this.getInstance = memoize(([signalId, bucketName]) => CREATE_KEY_FN$5(signalId, bucketName), (signalId, bucketName, initialValue) => Reflect.construct(this.StateFactory, [initialValue, signalId, bucketName]));
47662
+ this.getInstance = memoize(([signalId, bucketName]) => CREATE_KEY_FN$6(signalId, bucketName), (signalId, bucketName, initialValue) => Reflect.construct(this.StateFactory, [initialValue, signalId, bucketName]));
47510
47663
  /**
47511
47664
  * Disposes all memoized instances for the given signalId.
47512
47665
  * Called by StateAdapter when a signal is cancelled or closed.
47513
47666
  * @param signalId - Signal identifier to dispose
47514
47667
  */
47515
47668
  this.disposeSignal = (signalId) => {
47516
- const prefix = CREATE_KEY_FN$5(signalId, "");
47669
+ const prefix = CREATE_KEY_FN$6(signalId, "");
47517
47670
  for (const key of this.getInstance.keys()) {
47518
47671
  if (key.startsWith(prefix)) {
47519
47672
  const instance = this.getInstance.get(key);
@@ -47534,7 +47687,7 @@ class StateLiveAdapter {
47534
47687
  signalId: dto.signalId,
47535
47688
  bucketName: dto.bucketName,
47536
47689
  });
47537
- const key = CREATE_KEY_FN$5(dto.signalId, dto.bucketName);
47690
+ const key = CREATE_KEY_FN$6(dto.signalId, dto.bucketName);
47538
47691
  const isInitial = !this.getInstance.has(key);
47539
47692
  const instance = this.getInstance(dto.signalId, dto.bucketName, dto.initialValue);
47540
47693
  await instance.waitForInit(isInitial);
@@ -47553,7 +47706,7 @@ class StateLiveAdapter {
47553
47706
  signalId: dto.signalId,
47554
47707
  bucketName: dto.bucketName,
47555
47708
  });
47556
- const key = CREATE_KEY_FN$5(dto.signalId, dto.bucketName);
47709
+ const key = CREATE_KEY_FN$6(dto.signalId, dto.bucketName);
47557
47710
  const isInitial = !this.getInstance.has(key);
47558
47711
  const instance = this.getInstance(dto.signalId, dto.bucketName, dto.initialValue);
47559
47712
  await instance.waitForInit(isInitial);
@@ -47924,6 +48077,540 @@ async function setSignalState(dispatch, dto) {
47924
48077
  throw new Error(`setSignalState requires a pending or scheduled signal for symbol=${symbol} bucketName=${bucketName}`);
47925
48078
  }
47926
48079
 
48080
+ const CREATE_KEY_FN$5 = (symbol, strategyName, exchangeName, frameName, backtest) => {
48081
+ const parts = [symbol, strategyName, exchangeName];
48082
+ if (frameName)
48083
+ parts.push(frameName);
48084
+ parts.push(backtest ? "backtest" : "live");
48085
+ return parts.join(":");
48086
+ };
48087
+ const SESSION_LOCAL_INSTANCE_METHOD_NAME_GET = "SessionLocalInstance.getData";
48088
+ const SESSION_LOCAL_INSTANCE_METHOD_NAME_SET = "SessionLocalInstance.setData";
48089
+ const SESSION_PERSIST_INSTANCE_METHOD_NAME_WAIT_FOR_INIT = "SessionPersistInstance.waitForInit";
48090
+ const SESSION_PERSIST_INSTANCE_METHOD_NAME_GET = "SessionPersistInstance.getData";
48091
+ const SESSION_PERSIST_INSTANCE_METHOD_NAME_SET = "SessionPersistInstance.setData";
48092
+ const SESSION_BACKTEST_ADAPTER_METHOD_NAME_DISPOSE = "SessionBacktestAdapter.dispose";
48093
+ const SESSION_BACKTEST_ADAPTER_METHOD_NAME_GET = "SessionBacktestAdapter.getData";
48094
+ const SESSION_BACKTEST_ADAPTER_METHOD_NAME_SET = "SessionBacktestAdapter.setData";
48095
+ const SESSION_BACKTEST_ADAPTER_METHOD_NAME_USE_LOCAL = "SessionBacktestAdapter.useLocal";
48096
+ const SESSION_BACKTEST_ADAPTER_METHOD_NAME_USE_PERSIST = "SessionBacktestAdapter.usePersist";
48097
+ const SESSION_BACKTEST_ADAPTER_METHOD_NAME_USE_DUMMY = "SessionBacktestAdapter.useDummy";
48098
+ const SESSION_BACKTEST_ADAPTER_METHOD_NAME_USE_SESSION_ADAPTER = "SessionBacktestAdapter.useSessionAdapter";
48099
+ const SESSION_BACKTEST_ADAPTER_METHOD_NAME_CLEAR = "SessionBacktestAdapter.clear";
48100
+ const SESSION_LIVE_ADAPTER_METHOD_NAME_DISPOSE = "SessionLiveAdapter.dispose";
48101
+ const SESSION_LIVE_ADAPTER_METHOD_NAME_GET = "SessionLiveAdapter.getData";
48102
+ const SESSION_LIVE_ADAPTER_METHOD_NAME_SET = "SessionLiveAdapter.setData";
48103
+ const SESSION_LIVE_ADAPTER_METHOD_NAME_USE_LOCAL = "SessionLiveAdapter.useLocal";
48104
+ const SESSION_LIVE_ADAPTER_METHOD_NAME_USE_PERSIST = "SessionLiveAdapter.usePersist";
48105
+ const SESSION_LIVE_ADAPTER_METHOD_NAME_USE_DUMMY = "SessionLiveAdapter.useDummy";
48106
+ const SESSION_LIVE_ADAPTER_METHOD_NAME_USE_SESSION_ADAPTER = "SessionLiveAdapter.useSessionAdapter";
48107
+ const SESSION_LIVE_ADAPTER_METHOD_NAME_CLEAR = "SessionLiveAdapter.clear";
48108
+ const SESSION_ADAPTER_METHOD_NAME_GET = "SessionAdapter.getData";
48109
+ const SESSION_ADAPTER_METHOD_NAME_SET = "SessionAdapter.setData";
48110
+ /**
48111
+ * In-process session instance backed by a plain object reference.
48112
+ * All data lives in process memory only — no disk persistence.
48113
+ *
48114
+ * Features:
48115
+ * - Mutable in-memory session data
48116
+ * - Scoped per (symbol, strategyName, exchangeName, frameName) tuple
48117
+ *
48118
+ * Use for backtesting and unit tests where persistence between runs is not needed.
48119
+ */
48120
+ class SessionLocalInstance {
48121
+ constructor(symbol, strategyName, exchangeName, frameName, backtest$1) {
48122
+ this.symbol = symbol;
48123
+ this.strategyName = strategyName;
48124
+ this.exchangeName = exchangeName;
48125
+ this.frameName = frameName;
48126
+ this.backtest = backtest$1;
48127
+ this._data = null;
48128
+ /**
48129
+ * Initializes _data to null — local session needs no async setup.
48130
+ * @returns Promise that resolves immediately
48131
+ */
48132
+ this.waitForInit = singleshot(async (_initial) => {
48133
+ this._data = null;
48134
+ });
48135
+ /**
48136
+ * Read the current in-memory session value.
48137
+ * @returns Current session value, or null if not set
48138
+ */
48139
+ this.getData = async () => {
48140
+ backtest.loggerService.debug(SESSION_LOCAL_INSTANCE_METHOD_NAME_GET, {
48141
+ strategyName: this.strategyName,
48142
+ exchangeName: this.exchangeName,
48143
+ frameName: this.frameName,
48144
+ });
48145
+ return this._data;
48146
+ };
48147
+ /**
48148
+ * Update the in-memory session value.
48149
+ * @param value - New value or null to clear
48150
+ */
48151
+ this.setData = async (value) => {
48152
+ backtest.loggerService.debug(SESSION_LOCAL_INSTANCE_METHOD_NAME_SET, {
48153
+ strategyName: this.strategyName,
48154
+ exchangeName: this.exchangeName,
48155
+ frameName: this.frameName,
48156
+ });
48157
+ this._data = value;
48158
+ };
48159
+ }
48160
+ /** Releases resources held by this instance. */
48161
+ async dispose() {
48162
+ backtest.loggerService.debug(SESSION_BACKTEST_ADAPTER_METHOD_NAME_DISPOSE, {
48163
+ strategyName: this.strategyName,
48164
+ exchangeName: this.exchangeName,
48165
+ frameName: this.frameName,
48166
+ });
48167
+ }
48168
+ }
48169
+ /**
48170
+ * No-op session instance that discards all writes.
48171
+ * Used for disabling session storage in tests or dry-run scenarios.
48172
+ *
48173
+ * Useful when replaying historical candles without needing to accumulate
48174
+ * cross-candle session state — getData always returns null.
48175
+ */
48176
+ class SessionDummyInstance {
48177
+ constructor(symbol, strategyName, exchangeName, frameName, backtest) {
48178
+ this.symbol = symbol;
48179
+ this.strategyName = strategyName;
48180
+ this.exchangeName = exchangeName;
48181
+ this.frameName = frameName;
48182
+ this.backtest = backtest;
48183
+ /**
48184
+ * No-op initialization.
48185
+ * @returns Promise that resolves immediately
48186
+ */
48187
+ this.waitForInit = singleshot(async (_initial) => {
48188
+ });
48189
+ /**
48190
+ * No-op read — always returns null.
48191
+ * @returns null
48192
+ */
48193
+ this.getData = async () => {
48194
+ return null;
48195
+ };
48196
+ /**
48197
+ * No-op write — discards the value.
48198
+ */
48199
+ this.setData = async (_value) => {
48200
+ };
48201
+ }
48202
+ /** No-op. */
48203
+ async dispose() {
48204
+ }
48205
+ }
48206
+ /**
48207
+ * File-system backed session instance.
48208
+ * Data is persisted atomically to disk via PersistSessionAdapter.
48209
+ * Session is restored from disk on waitForInit.
48210
+ *
48211
+ * Features:
48212
+ * - Crash-safe atomic file writes
48213
+ * - Scoped per (symbol, strategyName, exchangeName, frameName) tuple
48214
+ *
48215
+ * Use in live trading to survive process restarts mid-session.
48216
+ */
48217
+ class SessionPersistInstance {
48218
+ constructor(symbol, strategyName, exchangeName, frameName, backtest$1) {
48219
+ this.symbol = symbol;
48220
+ this.strategyName = strategyName;
48221
+ this.exchangeName = exchangeName;
48222
+ this.frameName = frameName;
48223
+ this.backtest = backtest$1;
48224
+ this._data = null;
48225
+ /**
48226
+ * Initialize persistence storage and restore session from disk.
48227
+ * @param initial - Whether this is the first initialization
48228
+ */
48229
+ this.waitForInit = singleshot(async (initial) => {
48230
+ backtest.loggerService.debug(SESSION_PERSIST_INSTANCE_METHOD_NAME_WAIT_FOR_INIT, {
48231
+ strategyName: this.strategyName,
48232
+ exchangeName: this.exchangeName,
48233
+ frameName: this.frameName,
48234
+ initial,
48235
+ });
48236
+ await PersistSessionAdapter.waitForInit(this.strategyName, this.exchangeName, this.frameName, initial);
48237
+ const data = await PersistSessionAdapter.readSessionData(this.strategyName, this.exchangeName, this.frameName);
48238
+ if (data) {
48239
+ this._data = data.data;
48240
+ return;
48241
+ }
48242
+ this._data = null;
48243
+ });
48244
+ /**
48245
+ * Read the current persisted session value.
48246
+ * @returns Current session value, or null if not set
48247
+ */
48248
+ this.getData = async () => {
48249
+ backtest.loggerService.debug(SESSION_PERSIST_INSTANCE_METHOD_NAME_GET, {
48250
+ strategyName: this.strategyName,
48251
+ exchangeName: this.exchangeName,
48252
+ frameName: this.frameName,
48253
+ });
48254
+ return this._data;
48255
+ };
48256
+ /**
48257
+ * Update session value and persist to disk atomically.
48258
+ * @param value - New value or null to clear
48259
+ */
48260
+ this.setData = async (value) => {
48261
+ backtest.loggerService.debug(SESSION_PERSIST_INSTANCE_METHOD_NAME_SET, {
48262
+ strategyName: this.strategyName,
48263
+ exchangeName: this.exchangeName,
48264
+ frameName: this.frameName,
48265
+ });
48266
+ this._data = value;
48267
+ const id = CREATE_KEY_FN$5(this.symbol, this.strategyName, this.exchangeName, this.frameName, this.backtest);
48268
+ await PersistSessionAdapter.writeSessionData({ id, data: value }, this.strategyName, this.exchangeName, this.frameName);
48269
+ };
48270
+ }
48271
+ /** Releases resources held by this instance. */
48272
+ async dispose() {
48273
+ backtest.loggerService.debug(SESSION_LIVE_ADAPTER_METHOD_NAME_DISPOSE, {
48274
+ strategyName: this.strategyName,
48275
+ exchangeName: this.exchangeName,
48276
+ frameName: this.frameName,
48277
+ });
48278
+ await PersistSessionAdapter.dispose(this.strategyName, this.exchangeName, this.frameName);
48279
+ }
48280
+ }
48281
+ /**
48282
+ * Backtest session adapter with pluggable storage backend.
48283
+ *
48284
+ * Features:
48285
+ * - Adapter pattern for swappable session instance implementations
48286
+ * - Default backend: SessionLocalInstance (in-memory, no disk persistence)
48287
+ * - Alternative backends: SessionPersistInstance, SessionDummyInstance
48288
+ * - Convenience methods: useLocal(), usePersist(), useDummy(), useSessionAdapter()
48289
+ * - Memoized instances per (symbol, strategyName, exchangeName, frameName) tuple
48290
+ */
48291
+ class SessionBacktestAdapter {
48292
+ constructor() {
48293
+ this.SessionFactory = SessionLocalInstance;
48294
+ this.getInstance = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$5(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => Reflect.construct(this.SessionFactory, [symbol, strategyName, exchangeName, frameName, backtest]));
48295
+ /**
48296
+ * Read the current session value for a backtest run.
48297
+ * @param symbol - Trading pair symbol
48298
+ * @param context.strategyName - Strategy identifier
48299
+ * @param context.exchangeName - Exchange identifier
48300
+ * @param context.frameName - Frame identifier
48301
+ * @returns Current session value, or null if not set
48302
+ */
48303
+ this.getData = async (symbol, context) => {
48304
+ backtest.loggerService.debug(SESSION_BACKTEST_ADAPTER_METHOD_NAME_GET, {
48305
+ strategyName: context.strategyName,
48306
+ exchangeName: context.exchangeName,
48307
+ frameName: context.frameName,
48308
+ });
48309
+ const key = CREATE_KEY_FN$5(symbol, context.strategyName, context.exchangeName, context.frameName, true);
48310
+ const isInitial = !this.getInstance.has(key);
48311
+ const instance = this.getInstance(symbol, context.strategyName, context.exchangeName, context.frameName, true);
48312
+ await instance.waitForInit(isInitial);
48313
+ return await instance.getData();
48314
+ };
48315
+ /**
48316
+ * Update the session value for a backtest run.
48317
+ * @param symbol - Trading pair symbol
48318
+ * @param value - New value or null to clear
48319
+ * @param context.strategyName - Strategy identifier
48320
+ * @param context.exchangeName - Exchange identifier
48321
+ * @param context.frameName - Frame identifier
48322
+ */
48323
+ this.setData = async (symbol, value, context) => {
48324
+ backtest.loggerService.debug(SESSION_BACKTEST_ADAPTER_METHOD_NAME_SET, {
48325
+ strategyName: context.strategyName,
48326
+ exchangeName: context.exchangeName,
48327
+ frameName: context.frameName,
48328
+ });
48329
+ const key = CREATE_KEY_FN$5(symbol, context.strategyName, context.exchangeName, context.frameName, true);
48330
+ const isInitial = !this.getInstance.has(key);
48331
+ const instance = this.getInstance(symbol, context.strategyName, context.exchangeName, context.frameName, true);
48332
+ await instance.waitForInit(isInitial);
48333
+ return await instance.setData(value);
48334
+ };
48335
+ /**
48336
+ * Switches to in-memory adapter (default).
48337
+ * All data lives in process memory only.
48338
+ */
48339
+ this.useLocal = () => {
48340
+ backtest.loggerService.info(SESSION_BACKTEST_ADAPTER_METHOD_NAME_USE_LOCAL);
48341
+ this.SessionFactory = SessionLocalInstance;
48342
+ };
48343
+ /**
48344
+ * Switches to file-system backed adapter.
48345
+ * Data is persisted to disk via PersistSessionAdapter.
48346
+ */
48347
+ this.usePersist = () => {
48348
+ backtest.loggerService.info(SESSION_BACKTEST_ADAPTER_METHOD_NAME_USE_PERSIST);
48349
+ this.SessionFactory = SessionPersistInstance;
48350
+ };
48351
+ /**
48352
+ * Switches to dummy adapter that discards all writes.
48353
+ */
48354
+ this.useDummy = () => {
48355
+ backtest.loggerService.info(SESSION_BACKTEST_ADAPTER_METHOD_NAME_USE_DUMMY);
48356
+ this.SessionFactory = SessionDummyInstance;
48357
+ };
48358
+ /**
48359
+ * Switches to a custom session adapter implementation.
48360
+ * @param Ctor - Constructor for the custom session instance
48361
+ */
48362
+ this.useSessionAdapter = (Ctor) => {
48363
+ backtest.loggerService.info(SESSION_BACKTEST_ADAPTER_METHOD_NAME_USE_SESSION_ADAPTER);
48364
+ this.SessionFactory = Ctor;
48365
+ };
48366
+ /**
48367
+ * Clears the memoized instance cache.
48368
+ * Call this when process.cwd() changes between strategy iterations
48369
+ * so new instances are created with the updated base path.
48370
+ */
48371
+ this.clear = () => {
48372
+ backtest.loggerService.info(SESSION_BACKTEST_ADAPTER_METHOD_NAME_CLEAR);
48373
+ this.getInstance.clear();
48374
+ };
48375
+ }
48376
+ }
48377
+ /**
48378
+ * Live trading session adapter with pluggable storage backend.
48379
+ *
48380
+ * Features:
48381
+ * - Adapter pattern for swappable session instance implementations
48382
+ * - Default backend: SessionPersistInstance (file-system backed, survives restarts)
48383
+ * - Alternative backends: SessionLocalInstance, SessionDummyInstance
48384
+ * - Convenience methods: useLocal(), usePersist(), useDummy(), useSessionAdapter()
48385
+ * - Memoized instances per (symbol, strategyName, exchangeName, frameName) tuple
48386
+ */
48387
+ class SessionLiveAdapter {
48388
+ constructor() {
48389
+ this.SessionFactory = SessionPersistInstance;
48390
+ this.getInstance = memoize(([symbol, strategyName, exchangeName, frameName, backtest]) => CREATE_KEY_FN$5(symbol, strategyName, exchangeName, frameName, backtest), (symbol, strategyName, exchangeName, frameName, backtest) => Reflect.construct(this.SessionFactory, [symbol, strategyName, exchangeName, frameName, backtest]));
48391
+ /**
48392
+ * Read the current session value for a live run.
48393
+ * @param symbol - Trading pair symbol
48394
+ * @param context.strategyName - Strategy identifier
48395
+ * @param context.exchangeName - Exchange identifier
48396
+ * @param context.frameName - Frame identifier
48397
+ * @returns Current session value, or null if not set
48398
+ */
48399
+ this.getData = async (symbol, context) => {
48400
+ backtest.loggerService.debug(SESSION_LIVE_ADAPTER_METHOD_NAME_GET, {
48401
+ strategyName: context.strategyName,
48402
+ exchangeName: context.exchangeName,
48403
+ frameName: context.frameName,
48404
+ });
48405
+ const key = CREATE_KEY_FN$5(symbol, context.strategyName, context.exchangeName, context.frameName, false);
48406
+ const isInitial = !this.getInstance.has(key);
48407
+ const instance = this.getInstance(symbol, context.strategyName, context.exchangeName, context.frameName, false);
48408
+ await instance.waitForInit(isInitial);
48409
+ return await instance.getData();
48410
+ };
48411
+ /**
48412
+ * Update the session value for a live run.
48413
+ * @param symbol - Trading pair symbol
48414
+ * @param value - New value or null to clear
48415
+ * @param context.strategyName - Strategy identifier
48416
+ * @param context.exchangeName - Exchange identifier
48417
+ * @param context.frameName - Frame identifier
48418
+ */
48419
+ this.setData = async (symbol, value, context) => {
48420
+ backtest.loggerService.debug(SESSION_LIVE_ADAPTER_METHOD_NAME_SET, {
48421
+ strategyName: context.strategyName,
48422
+ exchangeName: context.exchangeName,
48423
+ frameName: context.frameName,
48424
+ });
48425
+ const key = CREATE_KEY_FN$5(symbol, context.strategyName, context.exchangeName, context.frameName, false);
48426
+ const isInitial = !this.getInstance.has(key);
48427
+ const instance = this.getInstance(symbol, context.strategyName, context.exchangeName, context.frameName, false);
48428
+ await instance.waitForInit(isInitial);
48429
+ return await instance.setData(value);
48430
+ };
48431
+ /**
48432
+ * Switches to in-memory adapter.
48433
+ * All data lives in process memory only.
48434
+ */
48435
+ this.useLocal = () => {
48436
+ backtest.loggerService.info(SESSION_LIVE_ADAPTER_METHOD_NAME_USE_LOCAL);
48437
+ this.SessionFactory = SessionLocalInstance;
48438
+ };
48439
+ /**
48440
+ * Switches to file-system backed adapter (default).
48441
+ * Data is persisted to disk via PersistSessionAdapter.
48442
+ */
48443
+ this.usePersist = () => {
48444
+ backtest.loggerService.info(SESSION_LIVE_ADAPTER_METHOD_NAME_USE_PERSIST);
48445
+ this.SessionFactory = SessionPersistInstance;
48446
+ };
48447
+ /**
48448
+ * Switches to dummy adapter that discards all writes.
48449
+ */
48450
+ this.useDummy = () => {
48451
+ backtest.loggerService.info(SESSION_LIVE_ADAPTER_METHOD_NAME_USE_DUMMY);
48452
+ this.SessionFactory = SessionDummyInstance;
48453
+ };
48454
+ /**
48455
+ * Switches to a custom session adapter implementation.
48456
+ * @param Ctor - Constructor for the custom session instance
48457
+ */
48458
+ this.useSessionAdapter = (Ctor) => {
48459
+ backtest.loggerService.info(SESSION_LIVE_ADAPTER_METHOD_NAME_USE_SESSION_ADAPTER);
48460
+ this.SessionFactory = Ctor;
48461
+ };
48462
+ /**
48463
+ * Clears the memoized instance cache.
48464
+ * Call this when process.cwd() changes between strategy iterations
48465
+ * so new instances are created with the updated base path.
48466
+ */
48467
+ this.clear = () => {
48468
+ backtest.loggerService.info(SESSION_LIVE_ADAPTER_METHOD_NAME_CLEAR);
48469
+ this.getInstance.clear();
48470
+ };
48471
+ }
48472
+ }
48473
+ /**
48474
+ * Main session adapter that manages both backtest and live session storage.
48475
+ *
48476
+ * Features:
48477
+ * - Routes all operations to SessionBacktest or SessionLive based on the backtest flag
48478
+ */
48479
+ class SessionAdapter {
48480
+ constructor() {
48481
+ /**
48482
+ * Read the current session value for a signal.
48483
+ * Routes to SessionBacktest or SessionLive based on backtest.
48484
+ * @param symbol - Trading pair symbol
48485
+ * @param context.strategyName - Strategy identifier
48486
+ * @param context.exchangeName - Exchange identifier
48487
+ * @param context.frameName - Frame identifier
48488
+ * @param backtest - Flag indicating if the context is backtest or live
48489
+ * @returns Current session value, or null if not set
48490
+ */
48491
+ this.getData = async (symbol, context, backtest$1) => {
48492
+ backtest.loggerService.debug(SESSION_ADAPTER_METHOD_NAME_GET, {
48493
+ strategyName: context.strategyName,
48494
+ exchangeName: context.exchangeName,
48495
+ frameName: context.frameName,
48496
+ backtest: backtest$1,
48497
+ });
48498
+ if (backtest$1) {
48499
+ return await SessionBacktest.getData(symbol, context);
48500
+ }
48501
+ return await SessionLive.getData(symbol, context);
48502
+ };
48503
+ /**
48504
+ * Update the session value for a signal.
48505
+ * Routes to SessionBacktest or SessionLive based on backtest.
48506
+ * @param symbol - Trading pair symbol
48507
+ * @param value - New value or null to clear
48508
+ * @param context.strategyName - Strategy identifier
48509
+ * @param context.exchangeName - Exchange identifier
48510
+ * @param context.frameName - Frame identifier
48511
+ * @param backtest - Flag indicating if the context is backtest or live
48512
+ */
48513
+ this.setData = async (symbol, value, context, backtest$1) => {
48514
+ backtest.loggerService.debug(SESSION_ADAPTER_METHOD_NAME_SET, {
48515
+ strategyName: context.strategyName,
48516
+ exchangeName: context.exchangeName,
48517
+ frameName: context.frameName,
48518
+ backtest: backtest$1,
48519
+ });
48520
+ if (backtest$1) {
48521
+ return await SessionBacktest.setData(symbol, value, context);
48522
+ }
48523
+ return await SessionLive.setData(symbol, value, context);
48524
+ };
48525
+ }
48526
+ }
48527
+ /**
48528
+ * Global singleton instance of SessionAdapter.
48529
+ * Provides unified session management for backtest and live trading.
48530
+ */
48531
+ const Session = new SessionAdapter();
48532
+ /**
48533
+ * Global singleton instance of SessionLiveAdapter.
48534
+ * Provides live trading session storage with pluggable backends.
48535
+ */
48536
+ const SessionLive = new SessionLiveAdapter();
48537
+ /**
48538
+ * Global singleton instance of SessionBacktestAdapter.
48539
+ * Provides backtest session storage with pluggable backends.
48540
+ */
48541
+ const SessionBacktest = new SessionBacktestAdapter();
48542
+
48543
+ const GET_SESSION_METHOD_NAME = "session.getSession";
48544
+ const SET_SESSION_METHOD_NAME = "session.setSession";
48545
+ /**
48546
+ * Reads the session value scoped to the current (symbol, strategy, exchange, frame) context.
48547
+ *
48548
+ * Session data persists across candles within a single run and can survive process
48549
+ * restarts in live mode — useful for caching LLM inference results, intermediate
48550
+ * indicator state, or any cross-candle accumulator that is not tied to a specific signal.
48551
+ *
48552
+ * Automatically detects backtest/live mode from execution context.
48553
+ *
48554
+ * @param symbol - Trading pair symbol
48555
+ * @returns Promise resolving to current session value, or null if not set
48556
+ *
48557
+ * @example
48558
+ * ```typescript
48559
+ * import { getSession } from "backtest-kit";
48560
+ *
48561
+ * const session = await getSession<{ lastLlmSignal: string }>("BTCUSDT");
48562
+ * if (session?.lastLlmSignal === "buy") {
48563
+ * // reuse cached LLM result instead of calling the model again
48564
+ * }
48565
+ * ```
48566
+ */
48567
+ async function getSessionData(symbol) {
48568
+ backtest.loggerService.info(GET_SESSION_METHOD_NAME, { symbol });
48569
+ if (!ExecutionContextService.hasContext()) {
48570
+ throw new Error("getSession requires an execution context");
48571
+ }
48572
+ if (!MethodContextService.hasContext()) {
48573
+ throw new Error("getSession requires a method context");
48574
+ }
48575
+ const { backtest: isBacktest } = backtest.executionContextService.context;
48576
+ const { exchangeName, frameName, strategyName } = backtest.methodContextService.context;
48577
+ return await Session.getData(symbol, { exchangeName, frameName, strategyName }, isBacktest);
48578
+ }
48579
+ /**
48580
+ * Writes a session value scoped to the current (symbol, strategy, exchange, frame) context.
48581
+ *
48582
+ * Session data persists across candles within a single run and can survive process
48583
+ * restarts in live mode — useful for caching LLM inference results, intermediate
48584
+ * indicator state, or any cross-candle accumulator that is not tied to a specific signal.
48585
+ *
48586
+ * Pass null to clear the session.
48587
+ *
48588
+ * Automatically detects backtest/live mode from execution context.
48589
+ *
48590
+ * @param symbol - Trading pair symbol
48591
+ * @param value - New value or null to clear
48592
+ * @returns Promise that resolves when the session has been written
48593
+ *
48594
+ * @example
48595
+ * ```typescript
48596
+ * import { setSession } from "backtest-kit";
48597
+ *
48598
+ * await setSession("BTCUSDT", { lastLlmSignal: "buy" });
48599
+ * ```
48600
+ */
48601
+ async function setSessionData(symbol, value) {
48602
+ backtest.loggerService.info(SET_SESSION_METHOD_NAME, { symbol });
48603
+ if (!ExecutionContextService.hasContext()) {
48604
+ throw new Error("setSession requires an execution context");
48605
+ }
48606
+ if (!MethodContextService.hasContext()) {
48607
+ throw new Error("setSession requires a method context");
48608
+ }
48609
+ const { backtest: isBacktest } = backtest.executionContextService.context;
48610
+ const { exchangeName, frameName, strategyName } = backtest.methodContextService.context;
48611
+ await Session.setData(symbol, value, { exchangeName, frameName, strategyName }, isBacktest);
48612
+ }
48613
+
47927
48614
  const CREATE_SIGNAL_STATE_METHOD_NAME = "state.createSignalState";
47928
48615
  const CREATE_SET_STATE_FN = (params) => async (dispatch) => {
47929
48616
  if (!ExecutionContextService.hasContext()) {
@@ -51782,7 +52469,7 @@ class LogAdapter {
51782
52469
  */
51783
52470
  const Log = new LogAdapter();
51784
52471
 
51785
- const METHOD_NAME_CREATE_SNAPSHOT = "SessionUtils.createSnapshot";
52472
+ const METHOD_NAME_CREATE_SNAPSHOT = "SystemUtils.createSnapshot";
51786
52473
  /** List of all global subjects whose listeners should be snapshotted for session isolation */
51787
52474
  const SUBJECT_ISOLATION_LIST = [
51788
52475
  activePingSubject,
@@ -51829,7 +52516,7 @@ const CREATE_SUBJECT_SNAPSHOT_FN = (subject) => {
51829
52516
  * Allows temporarily detaching all subject subscriptions so that one session
51830
52517
  * does not interfere with another, then restoring them afterwards.
51831
52518
  */
51832
- class SessionUtils {
52519
+ class SystemUtils {
51833
52520
  constructor() {
51834
52521
  /**
51835
52522
  * Snapshots the current listener state of every global subject by replacing
@@ -51843,7 +52530,7 @@ class SessionUtils {
51843
52530
  };
51844
52531
  }
51845
52532
  }
51846
- const Session = new SessionUtils();
52533
+ const System = new SystemUtils();
51847
52534
 
51848
52535
  const SCHEDULE_METHOD_NAME_GET_DATA = "ScheduleUtils.getData";
51849
52536
  const SCHEDULE_METHOD_NAME_GET_REPORT = "ScheduleUtils.getReport";
@@ -60868,4 +61555,4 @@ const validateSignal = (signal, currentPrice) => {
60868
61555
  return !errors.length;
60869
61556
  };
60870
61557
 
60871
- export { ActionBase, Backtest, Breakeven, Broker, BrokerBase, Cache, Constant, Dump, Exchange, ExecutionContextService, Heat, HighestProfit, Interval, Live, Log, Markdown, MarkdownFileBase, MarkdownFolderBase, MarkdownWriter, MaxDrawdown, Memory, MemoryBacktest, MemoryBacktestAdapter, MemoryLive, MemoryLiveAdapter, MethodContextService, Notification, NotificationBacktest, NotificationLive, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistIntervalAdapter, PersistLogAdapter, PersistMeasureAdapter, PersistMemoryAdapter, PersistNotificationAdapter, PersistPartialAdapter, PersistRecentAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSignalAdapter, PersistStateAdapter, PersistStorageAdapter, Position, PositionSize, Recent, RecentBacktest, RecentLive, Reflect$1 as Reflect, Report, ReportBase, ReportWriter, Risk, Schedule, Session, State, StateBacktest, StateBacktestAdapter, StateLive, StateLiveAdapter, Storage, StorageBacktest, StorageLive, Strategy, Sync, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, alignToInterval, checkCandles, commitActivateScheduled, commitAverageBuy, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialLossCost, commitPartialProfit, commitPartialProfitCost, commitSignalNotify, commitTrailingStop, commitTrailingStopCost, commitTrailingTake, commitTrailingTakeCost, createSignalState, dumpAgentAnswer, dumpError, dumpJson, dumpRecord, dumpTable, dumpText, emitters, formatPrice, formatQuantity, get, getActionSchema, getAggregatedTrades, getAveragePrice, getBacktestTimeframe, getBreakeven, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getEffectivePriceOpen, getExchangeSchema, getFrameSchema, getLatestSignal, getMaxDrawdownDistancePnlCost, getMaxDrawdownDistancePnlPercentage, getMinutesSinceLatestSignalCreated, getMode, getNextCandles, getOrderBook, getPendingSignal, getPositionActiveMinutes, getPositionCountdownMinutes, getPositionDrawdownMinutes, getPositionEffectivePrice, getPositionEntries, getPositionEntryOverlap, getPositionEstimateMinutes, getPositionHighestMaxDrawdownPnlCost, getPositionHighestMaxDrawdownPnlPercentage, getPositionHighestPnlCost, getPositionHighestPnlPercentage, getPositionHighestProfitBreakeven, getPositionHighestProfitDistancePnlCost, getPositionHighestProfitDistancePnlPercentage, getPositionHighestProfitMinutes, getPositionHighestProfitPrice, getPositionHighestProfitTimestamp, getPositionInvestedCost, getPositionInvestedCount, getPositionLevels, getPositionMaxDrawdownMinutes, getPositionMaxDrawdownPnlCost, getPositionMaxDrawdownPnlPercentage, getPositionMaxDrawdownPrice, getPositionMaxDrawdownTimestamp, getPositionPartialOverlap, getPositionPartials, getPositionPnlCost, getPositionPnlPercent, getPositionWaitingMinutes, getRawCandles, getRiskSchema, getScheduledSignal, getSignalState, getSizingSchema, getStrategySchema, getSymbol, getTimestamp, getTotalClosed, getTotalCostClosed, getTotalPercentClosed, getWalkerSchema, hasNoPendingSignal, hasNoScheduledSignal, hasTradeContext, investedCostToPercent, backtest as lib, listExchangeSchema, listFrameSchema, listMemory, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenHighestProfit, listenHighestProfitOnce, listenIdlePing, listenIdlePingOnce, listenMaxDrawdown, listenMaxDrawdownOnce, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalNotify, listenSignalNotifyOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenSync, listenSyncOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, percentDiff, percentToCloseCost, percentValue, readMemory, removeMemory, roundTicks, runInMockContext, searchMemory, set, setColumns, setConfig, setLogger, setSignalState, shutdown, slPercentShiftToPrice, slPriceToPercentShift, stopStrategy, toProfitLossDto, tpPercentShiftToPrice, tpPriceToPercentShift, validate, validateCommonSignal, validatePendingSignal, validateScheduledSignal, validateSignal, waitForCandle, warmCandles, writeMemory };
61558
+ export { ActionBase, Backtest, Breakeven, Broker, BrokerBase, Cache, Constant, Dump, Exchange, ExecutionContextService, Heat, HighestProfit, Interval, Live, Log, Markdown, MarkdownFileBase, MarkdownFolderBase, MarkdownWriter, MaxDrawdown, Memory, MemoryBacktest, MemoryBacktestAdapter, MemoryLive, MemoryLiveAdapter, MethodContextService, Notification, NotificationBacktest, NotificationLive, Partial, Performance, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistIntervalAdapter, PersistLogAdapter, PersistMeasureAdapter, PersistMemoryAdapter, PersistNotificationAdapter, PersistPartialAdapter, PersistRecentAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSessionAdapter, PersistSignalAdapter, PersistStateAdapter, PersistStorageAdapter, Position, PositionSize, Recent, RecentBacktest, RecentLive, Reflect$1 as Reflect, Report, ReportBase, ReportWriter, Risk, Schedule, Session, SessionBacktest, SessionLive, State, StateBacktest, StateBacktestAdapter, StateLive, StateLiveAdapter, Storage, StorageBacktest, StorageLive, Strategy, Sync, System, Walker, addActionSchema, addExchangeSchema, addFrameSchema, addRiskSchema, addSizingSchema, addStrategySchema, addWalkerSchema, alignToInterval, checkCandles, commitActivateScheduled, commitAverageBuy, commitBreakeven, commitCancelScheduled, commitClosePending, commitPartialLoss, commitPartialLossCost, commitPartialProfit, commitPartialProfitCost, commitSignalNotify, commitTrailingStop, commitTrailingStopCost, commitTrailingTake, commitTrailingTakeCost, createSignalState, dumpAgentAnswer, dumpError, dumpJson, dumpRecord, dumpTable, dumpText, emitters, formatPrice, formatQuantity, get, getActionSchema, getAggregatedTrades, getAveragePrice, getBacktestTimeframe, getBreakeven, getCandles, getColumns, getConfig, getContext, getDate, getDefaultColumns, getDefaultConfig, getEffectivePriceOpen, getExchangeSchema, getFrameSchema, getLatestSignal, getMaxDrawdownDistancePnlCost, getMaxDrawdownDistancePnlPercentage, getMinutesSinceLatestSignalCreated, getMode, getNextCandles, getOrderBook, getPendingSignal, getPositionActiveMinutes, getPositionCountdownMinutes, getPositionDrawdownMinutes, getPositionEffectivePrice, getPositionEntries, getPositionEntryOverlap, getPositionEstimateMinutes, getPositionHighestMaxDrawdownPnlCost, getPositionHighestMaxDrawdownPnlPercentage, getPositionHighestPnlCost, getPositionHighestPnlPercentage, getPositionHighestProfitBreakeven, getPositionHighestProfitDistancePnlCost, getPositionHighestProfitDistancePnlPercentage, getPositionHighestProfitMinutes, getPositionHighestProfitPrice, getPositionHighestProfitTimestamp, getPositionInvestedCost, getPositionInvestedCount, getPositionLevels, getPositionMaxDrawdownMinutes, getPositionMaxDrawdownPnlCost, getPositionMaxDrawdownPnlPercentage, getPositionMaxDrawdownPrice, getPositionMaxDrawdownTimestamp, getPositionPartialOverlap, getPositionPartials, getPositionPnlCost, getPositionPnlPercent, getPositionWaitingMinutes, getRawCandles, getRiskSchema, getScheduledSignal, getSessionData, getSignalState, getSizingSchema, getStrategySchema, getSymbol, getTimestamp, getTotalClosed, getTotalCostClosed, getTotalPercentClosed, getWalkerSchema, hasNoPendingSignal, hasNoScheduledSignal, hasTradeContext, investedCostToPercent, backtest as lib, listExchangeSchema, listFrameSchema, listMemory, listRiskSchema, listSizingSchema, listStrategySchema, listWalkerSchema, listenActivePing, listenActivePingOnce, listenBacktestProgress, listenBreakevenAvailable, listenBreakevenAvailableOnce, listenDoneBacktest, listenDoneBacktestOnce, listenDoneLive, listenDoneLiveOnce, listenDoneWalker, listenDoneWalkerOnce, listenError, listenExit, listenHighestProfit, listenHighestProfitOnce, listenIdlePing, listenIdlePingOnce, listenMaxDrawdown, listenMaxDrawdownOnce, listenPartialLossAvailable, listenPartialLossAvailableOnce, listenPartialProfitAvailable, listenPartialProfitAvailableOnce, listenPerformance, listenRisk, listenRiskOnce, listenSchedulePing, listenSchedulePingOnce, listenSignal, listenSignalBacktest, listenSignalBacktestOnce, listenSignalLive, listenSignalLiveOnce, listenSignalNotify, listenSignalNotifyOnce, listenSignalOnce, listenStrategyCommit, listenStrategyCommitOnce, listenSync, listenSyncOnce, listenValidation, listenWalker, listenWalkerComplete, listenWalkerOnce, listenWalkerProgress, overrideActionSchema, overrideExchangeSchema, overrideFrameSchema, overrideRiskSchema, overrideSizingSchema, overrideStrategySchema, overrideWalkerSchema, parseArgs, percentDiff, percentToCloseCost, percentValue, readMemory, removeMemory, roundTicks, runInMockContext, searchMemory, set, setColumns, setConfig, setLogger, setSessionData, setSignalState, shutdown, slPercentShiftToPrice, slPriceToPercentShift, stopStrategy, toProfitLossDto, tpPercentShiftToPrice, tpPriceToPercentShift, validate, validateCommonSignal, validatePendingSignal, validateScheduledSignal, validateSignal, waitForCandle, warmCandles, writeMemory };