backtest-kit 8.5.0 → 9.0.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.
Files changed (6) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1825 -1825
  3. package/build/index.cjs +2319 -929
  4. package/build/index.mjs +2305 -930
  5. package/package.json +86 -86
  6. package/types.d.ts +1972 -402
package/types.d.ts CHANGED
@@ -147,6 +147,15 @@ type FrameName = string;
147
147
  * Can be void, null, or an IRiskRejectionResult object.
148
148
  */
149
149
  type RiskRejection = void | IRiskRejectionResult | string | null;
150
+ /**
151
+ * Risk check options for concurrent calls.
152
+ * `reserve: true` writes a placeholder into the active position map atomically with the check,
153
+ * so concurrent checkSignal calls observe the incremented size before the deferred addSignal call lands.
154
+ */
155
+ interface IRiskCheckOptions {
156
+ /** concurrent checkSignal calls observe the incremented size before the deferred addSignal call lands. */
157
+ reserve: boolean;
158
+ }
150
159
  /**
151
160
  * Risk check arguments for evaluating whether to allow opening a new position.
152
161
  * Called BEFORE signal creation to validate if conditions allow new signals.
@@ -299,9 +308,40 @@ interface IRisk {
299
308
  * Check if a signal should be allowed based on risk limits.
300
309
  *
301
310
  * @param params - Risk check arguments (position size, portfolio state, etc.)
311
+ * @param options - Optional flags. `reserve: true` writes a placeholder
312
+ * into the active position map atomically with the check,
313
+ * so concurrent checkSignal calls observe the incremented
314
+ * size before the deferred addSignal call lands.
302
315
  * @returns Promise resolving to risk check result
303
316
  */
304
- checkSignal: (params: IRiskCheckArgs) => Promise<boolean>;
317
+ checkSignal: (params: IRiskCheckArgs, options?: Partial<IRiskCheckOptions>) => Promise<boolean>;
318
+ /**
319
+ * Concurrency-safe variant of {@link checkSignal}: atomically validates the
320
+ * signal AND, on success, writes a placeholder for the future position into
321
+ * the active position map within the same critical section.
322
+ *
323
+ * **Why this exists.** `checkSignal` followed later by `addSignal` is not
324
+ * atomic — between the two calls the caller does signal setup work that
325
+ * yields to the event loop (sync-open callback, persist writes, etc.). When
326
+ * several strategies sharing the same risk profile run in parallel, all of
327
+ * them can pass `checkSignal` while the active position map is still empty,
328
+ * then each call `addSignal` and blow past the limit. Reserving inside the
329
+ * lock guarantees the next concurrent caller observes the incremented size
330
+ * before its own validation runs.
331
+ *
332
+ * The reservation uses the same map key as the eventual `addSignal` call
333
+ * (`strategyName + exchangeName + symbol`), so `addSignal` overwrites the
334
+ * placeholder rather than appending a duplicate.
335
+ *
336
+ * Callers MUST ensure that every successful return is followed by either
337
+ * `addSignal` (overwrites the placeholder with real data) or `removeSignal`
338
+ * (clears the placeholder if opening is aborted). Otherwise the riskMap
339
+ * accumulates stale reservations.
340
+ *
341
+ * @param params - Risk check arguments (position size, portfolio state, etc.)
342
+ * @returns Promise resolving to true if allowed (and reserved), false if rejected (no reservation)
343
+ */
344
+ checkSignalAndReserve: (params: IRiskCheckArgs) => Promise<boolean>;
305
345
  /**
306
346
  * Register a new opened signal/position.
307
347
  *
@@ -12911,6 +12951,92 @@ declare class PersistBase<EntityName extends string = string> implements IPersis
12911
12951
  */
12912
12952
  keys(): AsyncGenerator<EntityId>;
12913
12953
  }
12954
+ /**
12955
+ * Per-context signal persistence instance interface.
12956
+ * Scoped to a specific (symbol, strategyName, exchangeName) triple.
12957
+ *
12958
+ * Custom adapters should implement this interface to override the default
12959
+ * file-based signal persistence behavior.
12960
+ */
12961
+ interface IPersistSignalInstance {
12962
+ /**
12963
+ * Initialize storage for this signal context.
12964
+ *
12965
+ * @param initial - Whether this is the first initialization
12966
+ * @returns Promise that resolves when initialization is complete
12967
+ */
12968
+ waitForInit(initial: boolean): Promise<void>;
12969
+ /**
12970
+ * Read persisted signal data for this context.
12971
+ *
12972
+ * @returns Promise resolving to signal or null if none persisted
12973
+ */
12974
+ readSignalData(): Promise<ISignalRow | null>;
12975
+ /**
12976
+ * Write signal data for this context (null to clear).
12977
+ *
12978
+ * @param signalRow - Signal data to persist, or null to clear
12979
+ * @returns Promise that resolves when write is complete
12980
+ */
12981
+ writeSignalData(signalRow: ISignalRow | null): Promise<void>;
12982
+ }
12983
+ /**
12984
+ * Default file-based implementation of IPersistSignalInstance.
12985
+ *
12986
+ * Features:
12987
+ * - Wraps PersistBase for atomic JSON writes
12988
+ * - Uses symbol as entity ID within a per-context PersistBase
12989
+ * - Crash-safe via atomic writes
12990
+ *
12991
+ * @example
12992
+ * ```typescript
12993
+ * const instance = new PersistSignalInstance("BTCUSDT", "my-strategy", "binance");
12994
+ * await instance.waitForInit(true);
12995
+ * await instance.writeSignalData(signalRow);
12996
+ * const restored = await instance.readSignalData();
12997
+ * ```
12998
+ */
12999
+ declare class PersistSignalInstance implements IPersistSignalInstance {
13000
+ readonly symbol: string;
13001
+ readonly strategyName: StrategyName;
13002
+ readonly exchangeName: ExchangeName;
13003
+ /** Underlying file-based storage scoped to this context */
13004
+ private readonly _storage;
13005
+ /**
13006
+ * Creates new signal persistence instance.
13007
+ *
13008
+ * @param symbol - Trading pair symbol
13009
+ * @param strategyName - Strategy identifier
13010
+ * @param exchangeName - Exchange identifier
13011
+ */
13012
+ constructor(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName);
13013
+ /**
13014
+ * Initializes the underlying PersistBase storage.
13015
+ * Delegates to PersistBase.waitForInit which uses singleshot.
13016
+ *
13017
+ * @param initial - Whether this is the first initialization
13018
+ * @returns Promise that resolves when initialization is complete
13019
+ */
13020
+ waitForInit(initial: boolean): Promise<void>;
13021
+ /**
13022
+ * Reads the persisted signal using `symbol` as the entity key.
13023
+ *
13024
+ * @returns Promise resolving to the signal or null if not found
13025
+ */
13026
+ readSignalData(): Promise<ISignalRow | null>;
13027
+ /**
13028
+ * Writes the signal (or null to clear) using `symbol` as the entity key.
13029
+ *
13030
+ * @param signalRow - Signal data to persist, or null to clear
13031
+ * @returns Promise that resolves when write is complete
13032
+ */
13033
+ writeSignalData(signalRow: ISignalRow | null): Promise<void>;
13034
+ }
13035
+ /**
13036
+ * Constructor type for IPersistSignalInstance.
13037
+ * Used by PersistSignalUtils.usePersistSignalAdapter() to register custom adapters.
13038
+ */
13039
+ type TPersistSignalInstanceCtor = new (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => IPersistSignalInstance;
12914
13040
  /**
12915
13041
  * Utility class for managing signal persistence.
12916
13042
  *
@@ -12923,42 +13049,37 @@ declare class PersistBase<EntityName extends string = string> implements IPersis
12923
13049
  * Used by ClientStrategy for live mode persistence.
12924
13050
  */
12925
13051
  declare class PersistSignalUtils {
12926
- private PersistSignalFactory;
13052
+ /**
13053
+ * Constructor used to create per-context signal instances.
13054
+ * Replaceable via usePersistSignalAdapter() / useJson() / useDummy().
13055
+ */
13056
+ private PersistSignalInstanceCtor;
13057
+ /**
13058
+ * Memoized factory creating one IPersistSignalInstance per (symbol, strategy, exchange) triple.
13059
+ */
12927
13060
  private getStorage;
12928
13061
  /**
12929
- * Registers a custom persistence adapter.
12930
- *
12931
- * @param Ctor - Custom PersistBase constructor
13062
+ * Registers a custom IPersistSignalInstance constructor.
13063
+ * Clears the memoization cache so subsequent calls use the new adapter.
12932
13064
  *
12933
- * @example
12934
- * ```typescript
12935
- * class RedisPersist extends PersistBase {
12936
- * async readValue(id) { return JSON.parse(await redis.get(id)); }
12937
- * async writeValue(id, entity) { await redis.set(id, JSON.stringify(entity)); }
12938
- * }
12939
- * PersistSignalAdapter.usePersistSignalAdapter(RedisPersist);
12940
- * ```
13065
+ * @param Ctor - Custom IPersistSignalInstance constructor
12941
13066
  */
12942
- usePersistSignalAdapter(Ctor: TPersistBaseCtor<StrategyName, SignalData>): void;
13067
+ usePersistSignalAdapter(Ctor: TPersistSignalInstanceCtor): void;
12943
13068
  /**
12944
- * Reads persisted signal data for a symbol and strategy.
12945
- *
12946
- * Called by ClientStrategy.waitForInit() to restore state.
12947
- * Returns null if no signal exists.
13069
+ * Reads persisted signal for the given context.
13070
+ * Lazily initializes the instance on first access.
12948
13071
  *
12949
13072
  * @param symbol - Trading pair symbol
12950
13073
  * @param strategyName - Strategy identifier
12951
13074
  * @param exchangeName - Exchange identifier
12952
- * @returns Promise resolving to signal or null
13075
+ * @returns Promise resolving to signal or null if none persisted
12953
13076
  */
12954
13077
  readSignalData: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<ISignalRow | null>;
12955
13078
  /**
12956
- * Writes signal data to disk with atomic file writes.
12957
- *
12958
- * Called by ClientStrategy.setPendingSignal() to persist state.
12959
- * Uses atomic writes to prevent corruption on crashes.
13079
+ * Writes signal data (or null to clear) for the given context.
13080
+ * Lazily initializes the instance on first access.
12960
13081
  *
12961
- * @param signalRow - Signal data (null to clear)
13082
+ * @param signalRow - Signal data to persist, or null to clear
12962
13083
  * @param symbol - Trading pair symbol
12963
13084
  * @param strategyName - Strategy identifier
12964
13085
  * @param exchangeName - Exchange identifier
@@ -12966,19 +13087,16 @@ declare class PersistSignalUtils {
12966
13087
  */
12967
13088
  writeSignalData: (signalRow: ISignalRow | null, symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<void>;
12968
13089
  /**
12969
- * Clears the memoized storage cache.
12970
- * Call this when process.cwd() changes between strategy iterations
12971
- * so new storage instances are created with the updated base path.
13090
+ * Clears the memoized instance cache.
13091
+ * Call when process.cwd() changes between strategy iterations.
12972
13092
  */
12973
13093
  clear(): void;
12974
13094
  /**
12975
- * Switches to the default JSON persist adapter.
12976
- * All future persistence writes will use JSON storage.
13095
+ * Switches to the default file-based PersistSignalInstance.
12977
13096
  */
12978
13097
  useJson(): void;
12979
13098
  /**
12980
- * Switches to a dummy persist adapter that discards all writes.
12981
- * All future persistence writes will be no-ops.
13099
+ * Switches to PersistSignalDummyInstance (all operations are no-ops).
12982
13100
  */
12983
13101
  useDummy(): void;
12984
13102
  }
@@ -13004,6 +13122,91 @@ declare const PersistSignalAdapter: PersistSignalUtils;
13004
13122
  * Stores Map entries as array of [key, value] tuples for JSON serialization.
13005
13123
  */
13006
13124
  type RiskData = Array<[string, IRiskActivePosition]>;
13125
+ /**
13126
+ * Per-context risk positions persistence instance interface.
13127
+ * Scoped to a specific (riskName, exchangeName) pair.
13128
+ *
13129
+ * Custom adapters should implement this interface to override the default
13130
+ * file-based active positions persistence behavior.
13131
+ */
13132
+ interface IPersistRiskInstance {
13133
+ /**
13134
+ * Initialize storage for this risk context.
13135
+ *
13136
+ * @param initial - Whether this is the first initialization
13137
+ * @returns Promise that resolves when initialization is complete
13138
+ */
13139
+ waitForInit(initial: boolean): Promise<void>;
13140
+ /**
13141
+ * Read persisted active positions for this context.
13142
+ *
13143
+ * @returns Promise resolving to position entries (empty array if none persisted)
13144
+ */
13145
+ readPositionData(): Promise<RiskData>;
13146
+ /**
13147
+ * Write active positions for this context.
13148
+ *
13149
+ * @param riskRow - Position entries to persist
13150
+ * @returns Promise that resolves when write is complete
13151
+ */
13152
+ writePositionData(riskRow: RiskData): Promise<void>;
13153
+ }
13154
+ /**
13155
+ * Default file-based implementation of IPersistRiskInstance.
13156
+ *
13157
+ * Features:
13158
+ * - Wraps PersistBase for atomic JSON writes
13159
+ * - Uses fixed entity ID "positions" within a per-context PersistBase
13160
+ * - Crash-safe via atomic writes
13161
+ *
13162
+ * @example
13163
+ * ```typescript
13164
+ * const instance = new PersistRiskInstance("my-risk", "binance");
13165
+ * await instance.waitForInit(true);
13166
+ * await instance.writePositionData([["strategy:BTCUSDT", positionData]]);
13167
+ * const positions = await instance.readPositionData();
13168
+ * ```
13169
+ */
13170
+ declare class PersistRiskInstance implements IPersistRiskInstance {
13171
+ readonly riskName: RiskName;
13172
+ readonly exchangeName: ExchangeName;
13173
+ /** Fixed entity key for storing the positions array */
13174
+ private static readonly STORAGE_KEY;
13175
+ /** Underlying file-based storage scoped to this context */
13176
+ private readonly _storage;
13177
+ /**
13178
+ * Creates new risk positions persistence instance.
13179
+ *
13180
+ * @param riskName - Risk profile identifier
13181
+ * @param exchangeName - Exchange identifier
13182
+ */
13183
+ constructor(riskName: RiskName, exchangeName: ExchangeName);
13184
+ /**
13185
+ * Initializes the underlying PersistBase storage.
13186
+ *
13187
+ * @param initial - Whether this is the first initialization
13188
+ * @returns Promise that resolves when initialization is complete
13189
+ */
13190
+ waitForInit(initial: boolean): Promise<void>;
13191
+ /**
13192
+ * Reads the persisted positions array using the fixed STORAGE_KEY.
13193
+ *
13194
+ * @returns Promise resolving to positions (empty array if none persisted)
13195
+ */
13196
+ readPositionData(): Promise<RiskData>;
13197
+ /**
13198
+ * Writes the positions array using the fixed STORAGE_KEY.
13199
+ *
13200
+ * @param riskRow - Position entries to persist
13201
+ * @returns Promise that resolves when write is complete
13202
+ */
13203
+ writePositionData(riskRow: RiskData): Promise<void>;
13204
+ }
13205
+ /**
13206
+ * Constructor type for IPersistRiskInstance.
13207
+ * Used by PersistRiskUtils.usePersistRiskAdapter() to register custom adapters.
13208
+ */
13209
+ type TPersistRiskInstanceCtor = new (riskName: RiskName, exchangeName: ExchangeName) => IPersistRiskInstance;
13007
13210
  /**
13008
13211
  * Utility class for managing risk active positions persistence.
13009
13212
  *
@@ -13016,60 +13219,52 @@ type RiskData = Array<[string, IRiskActivePosition]>;
13016
13219
  * Used by ClientRisk for live mode persistence of active positions.
13017
13220
  */
13018
13221
  declare class PersistRiskUtils {
13019
- private PersistRiskFactory;
13222
+ /**
13223
+ * Constructor used to create per-context risk instances.
13224
+ * Replaceable via usePersistRiskAdapter() / useJson() / useDummy().
13225
+ */
13226
+ private PersistRiskInstanceCtor;
13227
+ /**
13228
+ * Memoized factory creating one IPersistRiskInstance per (riskName, exchange) pair.
13229
+ */
13020
13230
  private getRiskStorage;
13021
13231
  /**
13022
- * Registers a custom persistence adapter.
13023
- *
13024
- * @param Ctor - Custom PersistBase constructor
13232
+ * Registers a custom IPersistRiskInstance constructor.
13233
+ * Clears the memoization cache so subsequent calls use the new adapter.
13025
13234
  *
13026
- * @example
13027
- * ```typescript
13028
- * class RedisPersist extends PersistBase {
13029
- * async readValue(id) { return JSON.parse(await redis.get(id)); }
13030
- * async writeValue(id, entity) { await redis.set(id, JSON.stringify(entity)); }
13031
- * }
13032
- * PersistRiskAdapter.usePersistRiskAdapter(RedisPersist);
13033
- * ```
13235
+ * @param Ctor - Custom IPersistRiskInstance constructor
13034
13236
  */
13035
- usePersistRiskAdapter(Ctor: TPersistBaseCtor<RiskName, RiskData>): void;
13237
+ usePersistRiskAdapter(Ctor: TPersistRiskInstanceCtor): void;
13036
13238
  /**
13037
- * Reads persisted active positions for a risk profile.
13038
- *
13039
- * Called by ClientRisk.waitForInit() to restore state.
13040
- * Returns empty Map if no positions exist.
13239
+ * Reads persisted active positions for the given risk context.
13240
+ * Lazily initializes the instance on first access.
13041
13241
  *
13042
13242
  * @param riskName - Risk profile identifier
13043
13243
  * @param exchangeName - Exchange identifier
13044
- * @returns Promise resolving to Map of active positions
13244
+ * @returns Promise resolving to position entries (empty array if none)
13045
13245
  */
13046
13246
  readPositionData: (riskName: RiskName, exchangeName: ExchangeName) => Promise<RiskData>;
13047
13247
  /**
13048
- * Writes active positions to disk with atomic file writes.
13049
- *
13050
- * Called by ClientRisk after addSignal/removeSignal to persist state.
13051
- * Uses atomic writes to prevent corruption on crashes.
13248
+ * Writes active positions for the given risk context.
13249
+ * Lazily initializes the instance on first access.
13052
13250
  *
13053
- * @param positions - Map of active positions
13251
+ * @param riskRow - Position entries to persist
13054
13252
  * @param riskName - Risk profile identifier
13055
13253
  * @param exchangeName - Exchange identifier
13056
13254
  * @returns Promise that resolves when write is complete
13057
13255
  */
13058
13256
  writePositionData: (riskRow: RiskData, riskName: RiskName, exchangeName: ExchangeName) => Promise<void>;
13059
13257
  /**
13060
- * Clears the memoized storage cache.
13061
- * Call this when process.cwd() changes between strategy iterations
13062
- * so new storage instances are created with the updated base path.
13258
+ * Clears the memoized instance cache.
13259
+ * Call when process.cwd() changes between strategy iterations.
13063
13260
  */
13064
13261
  clear(): void;
13065
13262
  /**
13066
- * Switches to the default JSON persist adapter.
13067
- * All future persistence writes will use JSON storage.
13263
+ * Switches to the default file-based PersistRiskInstance.
13068
13264
  */
13069
13265
  useJson(): void;
13070
13266
  /**
13071
- * Switches to a dummy persist adapter that discards all writes.
13072
- * All future persistence writes will be no-ops.
13267
+ * Switches to PersistRiskDummyInstance (all operations are no-ops).
13073
13268
  */
13074
13269
  useDummy(): void;
13075
13270
  }
@@ -13095,6 +13290,91 @@ declare const PersistRiskAdapter: PersistRiskUtils;
13095
13290
  * Contains nullable scheduled signal for atomic updates.
13096
13291
  */
13097
13292
  type ScheduleData = IScheduledSignalRow | null;
13293
+ /**
13294
+ * Per-context scheduled signal persistence instance interface.
13295
+ * Scoped to a specific (symbol, strategyName, exchangeName) triple.
13296
+ *
13297
+ * Custom adapters should implement this interface to override the default
13298
+ * file-based scheduled signal persistence behavior.
13299
+ */
13300
+ interface IPersistScheduleInstance {
13301
+ /**
13302
+ * Initialize storage for this scheduled signal context.
13303
+ *
13304
+ * @param initial - Whether this is the first initialization
13305
+ * @returns Promise that resolves when initialization is complete
13306
+ */
13307
+ waitForInit(initial: boolean): Promise<void>;
13308
+ /**
13309
+ * Read persisted scheduled signal for this context.
13310
+ *
13311
+ * @returns Promise resolving to scheduled signal or null if none persisted
13312
+ */
13313
+ readScheduleData(): Promise<IScheduledSignalRow | null>;
13314
+ /**
13315
+ * Write scheduled signal for this context (null to clear).
13316
+ *
13317
+ * @param row - Scheduled signal data to persist, or null to clear
13318
+ * @returns Promise that resolves when write is complete
13319
+ */
13320
+ writeScheduleData(row: IScheduledSignalRow | null): Promise<void>;
13321
+ }
13322
+ /**
13323
+ * Default file-based implementation of IPersistScheduleInstance.
13324
+ *
13325
+ * Features:
13326
+ * - Wraps PersistBase for atomic JSON writes
13327
+ * - Uses symbol as entity ID within a per-context PersistBase
13328
+ * - Crash-safe via atomic writes
13329
+ *
13330
+ * @example
13331
+ * ```typescript
13332
+ * const instance = new PersistScheduleInstance("BTCUSDT", "my-strategy", "binance");
13333
+ * await instance.waitForInit(true);
13334
+ * await instance.writeScheduleData(scheduledRow);
13335
+ * const restored = await instance.readScheduleData();
13336
+ * ```
13337
+ */
13338
+ declare class PersistScheduleInstance implements IPersistScheduleInstance {
13339
+ readonly symbol: string;
13340
+ readonly strategyName: StrategyName;
13341
+ readonly exchangeName: ExchangeName;
13342
+ /** Underlying file-based storage scoped to this context */
13343
+ private readonly _storage;
13344
+ /**
13345
+ * Creates new scheduled signal persistence instance.
13346
+ *
13347
+ * @param symbol - Trading pair symbol
13348
+ * @param strategyName - Strategy identifier
13349
+ * @param exchangeName - Exchange identifier
13350
+ */
13351
+ constructor(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName);
13352
+ /**
13353
+ * Initializes the underlying PersistBase storage.
13354
+ *
13355
+ * @param initial - Whether this is the first initialization
13356
+ * @returns Promise that resolves when initialization is complete
13357
+ */
13358
+ waitForInit(initial: boolean): Promise<void>;
13359
+ /**
13360
+ * Reads the persisted scheduled signal using `symbol` as the entity key.
13361
+ *
13362
+ * @returns Promise resolving to scheduled signal or null if not found
13363
+ */
13364
+ readScheduleData(): Promise<IScheduledSignalRow | null>;
13365
+ /**
13366
+ * Writes the scheduled signal (or null to clear) using `symbol` as the entity key.
13367
+ *
13368
+ * @param row - Scheduled signal data to persist, or null to clear
13369
+ * @returns Promise that resolves when write is complete
13370
+ */
13371
+ writeScheduleData(row: IScheduledSignalRow | null): Promise<void>;
13372
+ }
13373
+ /**
13374
+ * Constructor type for IPersistScheduleInstance.
13375
+ * Used by PersistScheduleUtils.usePersistScheduleAdapter() to register custom adapters.
13376
+ */
13377
+ type TPersistScheduleInstanceCtor = new (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => IPersistScheduleInstance;
13098
13378
  /**
13099
13379
  * Utility class for managing scheduled signal persistence.
13100
13380
  *
@@ -13107,42 +13387,37 @@ type ScheduleData = IScheduledSignalRow | null;
13107
13387
  * Used by ClientStrategy for live mode persistence of scheduled signals (_scheduledSignal).
13108
13388
  */
13109
13389
  declare class PersistScheduleUtils {
13110
- private PersistScheduleFactory;
13390
+ /**
13391
+ * Constructor used to create per-context scheduled signal instances.
13392
+ * Replaceable via usePersistScheduleAdapter() / useJson() / useDummy().
13393
+ */
13394
+ private PersistScheduleInstanceCtor;
13395
+ /**
13396
+ * Memoized factory creating one IPersistScheduleInstance per (symbol, strategy, exchange) triple.
13397
+ */
13111
13398
  private getScheduleStorage;
13112
13399
  /**
13113
- * Registers a custom persistence adapter.
13114
- *
13115
- * @param Ctor - Custom PersistBase constructor
13400
+ * Registers a custom IPersistScheduleInstance constructor.
13401
+ * Clears the memoization cache so subsequent calls use the new adapter.
13116
13402
  *
13117
- * @example
13118
- * ```typescript
13119
- * class RedisPersist extends PersistBase {
13120
- * async readValue(id) { return JSON.parse(await redis.get(id)); }
13121
- * async writeValue(id, entity) { await redis.set(id, JSON.stringify(entity)); }
13122
- * }
13123
- * PersistScheduleAdapter.usePersistScheduleAdapter(RedisPersist);
13124
- * ```
13403
+ * @param Ctor - Custom IPersistScheduleInstance constructor
13125
13404
  */
13126
- usePersistScheduleAdapter(Ctor: TPersistBaseCtor<StrategyName, ScheduleData>): void;
13405
+ usePersistScheduleAdapter(Ctor: TPersistScheduleInstanceCtor): void;
13127
13406
  /**
13128
- * Reads persisted scheduled signal data for a symbol and strategy.
13129
- *
13130
- * Called by ClientStrategy.waitForInit() to restore scheduled signal state.
13131
- * Returns null if no scheduled signal exists.
13407
+ * Reads persisted scheduled signal for the given context.
13408
+ * Lazily initializes the instance on first access.
13132
13409
  *
13133
13410
  * @param symbol - Trading pair symbol
13134
13411
  * @param strategyName - Strategy identifier
13135
13412
  * @param exchangeName - Exchange identifier
13136
- * @returns Promise resolving to scheduled signal or null
13413
+ * @returns Promise resolving to scheduled signal or null if none persisted
13137
13414
  */
13138
13415
  readScheduleData: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<IScheduledSignalRow | null>;
13139
13416
  /**
13140
- * Writes scheduled signal data to disk with atomic file writes.
13141
- *
13142
- * Called by ClientStrategy.setScheduledSignal() to persist state.
13143
- * Uses atomic writes to prevent corruption on crashes.
13417
+ * Writes scheduled signal (or null to clear) for the given context.
13418
+ * Lazily initializes the instance on first access.
13144
13419
  *
13145
- * @param scheduledSignalRow - Scheduled signal data (null to clear)
13420
+ * @param scheduledSignalRow - Scheduled signal data to persist, or null to clear
13146
13421
  * @param symbol - Trading pair symbol
13147
13422
  * @param strategyName - Strategy identifier
13148
13423
  * @param exchangeName - Exchange identifier
@@ -13150,19 +13425,16 @@ declare class PersistScheduleUtils {
13150
13425
  */
13151
13426
  writeScheduleData: (scheduledSignalRow: IScheduledSignalRow | null, symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<void>;
13152
13427
  /**
13153
- * Clears the memoized storage cache.
13154
- * Call this when process.cwd() changes between strategy iterations
13155
- * so new storage instances are created with the updated base path.
13428
+ * Clears the memoized instance cache.
13429
+ * Call when process.cwd() changes between strategy iterations.
13156
13430
  */
13157
13431
  clear(): void;
13158
13432
  /**
13159
- * Switches to the default JSON persist adapter.
13160
- * All future persistence writes will use JSON storage.
13433
+ * Switches to the default file-based PersistScheduleInstance.
13161
13434
  */
13162
13435
  useJson(): void;
13163
13436
  /**
13164
- * Switches to a dummy persist adapter that discards all writes.
13165
- * All future persistence writes will be no-ops.
13437
+ * Switches to PersistScheduleDummyInstance (all operations are no-ops).
13166
13438
  */
13167
13439
  useDummy(): void;
13168
13440
  }
@@ -13188,6 +13460,98 @@ declare const PersistScheduleAdapter: PersistScheduleUtils;
13188
13460
  * Stores profit and loss levels as arrays for JSON serialization.
13189
13461
  */
13190
13462
  type PartialData = Record<string, IPartialData>;
13463
+ /**
13464
+ * Per-context partial profit/loss levels persistence instance interface.
13465
+ * Scoped to a specific (symbol, strategyName, exchangeName) triple.
13466
+ *
13467
+ * Each signal's partial data is stored under its own signalId key within
13468
+ * the context-scoped storage.
13469
+ *
13470
+ * Custom adapters should implement this interface to override the default
13471
+ * file-based partial data persistence behavior.
13472
+ */
13473
+ interface IPersistPartialInstance {
13474
+ /**
13475
+ * Initialize storage for this partial context.
13476
+ *
13477
+ * @param initial - Whether this is the first initialization
13478
+ * @returns Promise that resolves when initialization is complete
13479
+ */
13480
+ waitForInit(initial: boolean): Promise<void>;
13481
+ /**
13482
+ * Read persisted partial data for a specific signal.
13483
+ *
13484
+ * @param signalId - Signal identifier
13485
+ * @returns Promise resolving to partial data record (empty object if none persisted)
13486
+ */
13487
+ readPartialData(signalId: string): Promise<PartialData>;
13488
+ /**
13489
+ * Write partial data for a specific signal.
13490
+ *
13491
+ * @param data - Partial data record to persist
13492
+ * @param signalId - Signal identifier
13493
+ * @returns Promise that resolves when write is complete
13494
+ */
13495
+ writePartialData(data: PartialData, signalId: string): Promise<void>;
13496
+ }
13497
+ /**
13498
+ * Default file-based implementation of IPersistPartialInstance.
13499
+ *
13500
+ * Features:
13501
+ * - Wraps PersistBase for atomic JSON writes
13502
+ * - Uses signalId as entity ID within a per-context PersistBase
13503
+ * - Crash-safe via atomic writes
13504
+ *
13505
+ * @example
13506
+ * ```typescript
13507
+ * const instance = new PersistPartialInstance("BTCUSDT", "my-strategy", "binance");
13508
+ * await instance.waitForInit(true);
13509
+ * await instance.writePartialData(partialData, "signal-id-1");
13510
+ * const restored = await instance.readPartialData("signal-id-1");
13511
+ * ```
13512
+ */
13513
+ declare class PersistPartialInstance implements IPersistPartialInstance {
13514
+ readonly symbol: string;
13515
+ readonly strategyName: StrategyName;
13516
+ readonly exchangeName: ExchangeName;
13517
+ /** Underlying file-based storage scoped to this context */
13518
+ private readonly _storage;
13519
+ /**
13520
+ * Creates new partial data persistence instance.
13521
+ *
13522
+ * @param symbol - Trading pair symbol
13523
+ * @param strategyName - Strategy identifier
13524
+ * @param exchangeName - Exchange identifier
13525
+ */
13526
+ constructor(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName);
13527
+ /**
13528
+ * Initializes the underlying PersistBase storage.
13529
+ *
13530
+ * @param initial - Whether this is the first initialization
13531
+ * @returns Promise that resolves when initialization is complete
13532
+ */
13533
+ waitForInit(initial: boolean): Promise<void>;
13534
+ /**
13535
+ * Reads the partial data for the given signal using `signalId` as the entity key.
13536
+ *
13537
+ * @param signalId - Signal identifier
13538
+ * @returns Promise resolving to partial data record (empty object if not found)
13539
+ */
13540
+ readPartialData(signalId: string): Promise<PartialData>;
13541
+ /**
13542
+ * Writes the partial data for the given signal using `signalId` as the entity key.
13543
+ *
13544
+ * @param data - Partial data record to persist
13545
+ * @param signalId - Signal identifier
13546
+ * @returns Promise that resolves when write is complete
13547
+ */
13548
+ writePartialData(data: PartialData, signalId: string): Promise<void>;
13549
+ }
13550
+ /**
13551
+ * Constructor type for IPersistPartialInstance.
13552
+ * Used by PersistPartialUtils.usePersistPartialAdapter() to register custom adapters.
13553
+ */
13554
+ type TPersistPartialInstanceCtor = new (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => IPersistPartialInstance;
13191
13555
  /**
13192
13556
  * Utility class for managing partial profit/loss levels persistence.
13193
13557
  *
@@ -13200,43 +13564,39 @@ type PartialData = Record<string, IPartialData>;
13200
13564
  * Used by ClientPartial for live mode persistence of profit/loss levels.
13201
13565
  */
13202
13566
  declare class PersistPartialUtils {
13203
- private PersistPartialFactory;
13567
+ /**
13568
+ * Constructor used to create per-context partial data instances.
13569
+ * Replaceable via usePersistPartialAdapter() / useJson() / useDummy().
13570
+ */
13571
+ private PersistPartialInstanceCtor;
13572
+ /**
13573
+ * Memoized factory creating one IPersistPartialInstance per (symbol, strategy, exchange) triple.
13574
+ * Each signal's partial data is stored under its own signalId within the instance.
13575
+ */
13204
13576
  private getPartialStorage;
13205
13577
  /**
13206
- * Registers a custom persistence adapter.
13207
- *
13208
- * @param Ctor - Custom PersistBase constructor
13578
+ * Registers a custom IPersistPartialInstance constructor.
13579
+ * Clears the memoization cache so subsequent calls use the new adapter.
13209
13580
  *
13210
- * @example
13211
- * ```typescript
13212
- * class RedisPersist extends PersistBase {
13213
- * async readValue(id) { return JSON.parse(await redis.get(id)); }
13214
- * async writeValue(id, entity) { await redis.set(id, JSON.stringify(entity)); }
13215
- * }
13216
- * PersistPartialAdapter.usePersistPartialAdapter(RedisPersist);
13217
- * ```
13581
+ * @param Ctor - Custom IPersistPartialInstance constructor
13218
13582
  */
13219
- usePersistPartialAdapter(Ctor: TPersistBaseCtor<string, PartialData>): void;
13583
+ usePersistPartialAdapter(Ctor: TPersistPartialInstanceCtor): void;
13220
13584
  /**
13221
- * Reads persisted partial data for a symbol and strategy.
13222
- *
13223
- * Called by ClientPartial.waitForInit() to restore state.
13224
- * Returns empty object if no partial data exists.
13585
+ * Reads partial data for the given context and signalId.
13586
+ * Lazily initializes the instance on first access.
13225
13587
  *
13226
13588
  * @param symbol - Trading pair symbol
13227
13589
  * @param strategyName - Strategy identifier
13228
13590
  * @param signalId - Signal identifier
13229
13591
  * @param exchangeName - Exchange identifier
13230
- * @returns Promise resolving to partial data record
13592
+ * @returns Promise resolving to partial data record (empty object if none)
13231
13593
  */
13232
13594
  readPartialData: (symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<PartialData>;
13233
13595
  /**
13234
- * Writes partial data to disk with atomic file writes.
13235
- *
13236
- * Called by ClientPartial after profit/loss level changes to persist state.
13237
- * Uses atomic writes to prevent corruption on crashes.
13596
+ * Writes partial data for the given context and signalId.
13597
+ * Lazily initializes the instance on first access.
13238
13598
  *
13239
- * @param partialData - Record of signal IDs to partial data
13599
+ * @param partialData - Partial data record to persist
13240
13600
  * @param symbol - Trading pair symbol
13241
13601
  * @param strategyName - Strategy identifier
13242
13602
  * @param signalId - Signal identifier
@@ -13245,19 +13605,16 @@ declare class PersistPartialUtils {
13245
13605
  */
13246
13606
  writePartialData: (partialData: PartialData, symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<void>;
13247
13607
  /**
13248
- * Clears the memoized storage cache.
13249
- * Call this when process.cwd() changes between strategy iterations
13250
- * so new storage instances are created with the updated base path.
13608
+ * Clears the memoized instance cache.
13609
+ * Call when process.cwd() changes between strategy iterations.
13251
13610
  */
13252
13611
  clear(): void;
13253
13612
  /**
13254
- * Switches to the default JSON persist adapter.
13255
- * All future persistence writes will use JSON storage.
13613
+ * Switches to the default file-based PersistPartialInstance.
13256
13614
  */
13257
13615
  useJson(): void;
13258
13616
  /**
13259
- * Switches to a dummy persist adapter that discards all writes.
13260
- * All future persistence writes will be no-ops.
13617
+ * Switches to PersistPartialDummyInstance (all operations are no-ops).
13261
13618
  */
13262
13619
  useDummy(): void;
13263
13620
  }
@@ -13283,11 +13640,103 @@ declare const PersistPartialAdapter: PersistPartialUtils;
13283
13640
  * Stores breakeven state (reached flag) for each signal ID.
13284
13641
  */
13285
13642
  type BreakevenData = Record<string, IBreakevenData>;
13643
+ /**
13644
+ * Per-context breakeven state persistence instance interface.
13645
+ * Scoped to a specific (symbol, strategyName, exchangeName) triple.
13646
+ *
13647
+ * Each signal's breakeven data is stored under its own signalId key within
13648
+ * the context-scoped storage.
13649
+ *
13650
+ * Custom adapters should implement this interface to override the default
13651
+ * file-based breakeven persistence behavior.
13652
+ */
13653
+ interface IPersistBreakevenInstance {
13654
+ /**
13655
+ * Initialize storage for this breakeven context.
13656
+ *
13657
+ * @param initial - Whether this is the first initialization
13658
+ * @returns Promise that resolves when initialization is complete
13659
+ */
13660
+ waitForInit(initial: boolean): Promise<void>;
13661
+ /**
13662
+ * Read persisted breakeven data for a specific signal.
13663
+ *
13664
+ * @param signalId - Signal identifier
13665
+ * @returns Promise resolving to breakeven data record (empty object if none persisted)
13666
+ */
13667
+ readBreakevenData(signalId: string): Promise<BreakevenData>;
13668
+ /**
13669
+ * Write breakeven data for a specific signal.
13670
+ *
13671
+ * @param data - Breakeven data record to persist
13672
+ * @param signalId - Signal identifier
13673
+ * @returns Promise that resolves when write is complete
13674
+ */
13675
+ writeBreakevenData(data: BreakevenData, signalId: string): Promise<void>;
13676
+ }
13677
+ /**
13678
+ * Default file-based implementation of IPersistBreakevenInstance.
13679
+ *
13680
+ * Features:
13681
+ * - Wraps PersistBase for atomic JSON writes
13682
+ * - Uses signalId as entity ID within a per-context PersistBase
13683
+ * - Crash-safe via atomic writes
13684
+ *
13685
+ * @example
13686
+ * ```typescript
13687
+ * const instance = new PersistBreakevenInstance("BTCUSDT", "my-strategy", "binance");
13688
+ * await instance.waitForInit(true);
13689
+ * await instance.writeBreakevenData(breakevenData, "signal-id-1");
13690
+ * const restored = await instance.readBreakevenData("signal-id-1");
13691
+ * ```
13692
+ */
13693
+ declare class PersistBreakevenInstance implements IPersistBreakevenInstance {
13694
+ readonly symbol: string;
13695
+ readonly strategyName: StrategyName;
13696
+ readonly exchangeName: ExchangeName;
13697
+ /** Underlying file-based storage scoped to this context */
13698
+ private readonly _storage;
13699
+ /**
13700
+ * Creates new breakeven persistence instance.
13701
+ *
13702
+ * @param symbol - Trading pair symbol
13703
+ * @param strategyName - Strategy identifier
13704
+ * @param exchangeName - Exchange identifier
13705
+ */
13706
+ constructor(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName);
13707
+ /**
13708
+ * Initializes the underlying PersistBase storage.
13709
+ *
13710
+ * @param initial - Whether this is the first initialization
13711
+ * @returns Promise that resolves when initialization is complete
13712
+ */
13713
+ waitForInit(initial: boolean): Promise<void>;
13714
+ /**
13715
+ * Reads the breakeven data for the given signal using `signalId` as the entity key.
13716
+ *
13717
+ * @param signalId - Signal identifier
13718
+ * @returns Promise resolving to breakeven data record (empty object if not found)
13719
+ */
13720
+ readBreakevenData(signalId: string): Promise<BreakevenData>;
13721
+ /**
13722
+ * Writes the breakeven data for the given signal using `signalId` as the entity key.
13723
+ *
13724
+ * @param data - Breakeven data record to persist
13725
+ * @param signalId - Signal identifier
13726
+ * @returns Promise that resolves when write is complete
13727
+ */
13728
+ writeBreakevenData(data: BreakevenData, signalId: string): Promise<void>;
13729
+ }
13730
+ /**
13731
+ * Constructor type for IPersistBreakevenInstance.
13732
+ * Used by PersistBreakevenUtils.usePersistBreakevenAdapter() to register custom adapters.
13733
+ */
13734
+ type TPersistBreakevenInstanceCtor = new (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => IPersistBreakevenInstance;
13286
13735
  /**
13287
13736
  * Persistence utility class for breakeven state management.
13288
13737
  *
13289
13738
  * Handles reading and writing breakeven state to disk.
13290
- * Uses memoized PersistBase instances per symbol-strategy pair.
13739
+ * Uses memoized PersistBreakevenInstance instances per symbol-strategy pair.
13291
13740
  *
13292
13741
  * Features:
13293
13742
  * - Atomic file writes via PersistBase.writeValue()
@@ -13316,55 +13765,36 @@ type BreakevenData = Record<string, IBreakevenData>;
13316
13765
  */
13317
13766
  declare class PersistBreakevenUtils {
13318
13767
  /**
13319
- * Factory for creating PersistBase instances.
13320
- * Can be replaced via usePersistBreakevenAdapter().
13768
+ * Constructor used to create per-context breakeven instances.
13769
+ * Replaceable via usePersistBreakevenAdapter() / useJson() / useDummy().
13321
13770
  */
13322
- private PersistBreakevenFactory;
13771
+ private PersistBreakevenInstanceCtor;
13323
13772
  /**
13324
- * Memoized storage factory for breakeven data.
13325
- * Creates one PersistBase instance per symbol-strategy-exchange combination.
13326
- * Key format: "symbol:strategyName:exchangeName"
13327
- *
13328
- * @param symbol - Trading pair symbol
13329
- * @param strategyName - Strategy identifier
13330
- * @param exchangeName - Exchange identifier
13331
- * @returns PersistBase instance for this symbol-strategy-exchange combination
13773
+ * Memoized factory creating one IPersistBreakevenInstance per (symbol, strategy, exchange) triple.
13774
+ * Each signal's breakeven data is stored under its own signalId within the instance.
13332
13775
  */
13333
13776
  private getBreakevenStorage;
13334
13777
  /**
13335
- * Registers a custom persistence adapter.
13778
+ * Registers a custom IPersistBreakevenInstance constructor.
13779
+ * Clears the memoization cache so subsequent calls use the new adapter.
13336
13780
  *
13337
- * @param Ctor - Custom PersistBase constructor
13338
- *
13339
- * @example
13340
- * ```typescript
13341
- * class RedisPersist extends PersistBase {
13342
- * async readValue(id) { return JSON.parse(await redis.get(id)); }
13343
- * async writeValue(id, entity) { await redis.set(id, JSON.stringify(entity)); }
13344
- * }
13345
- * PersistBreakevenAdapter.usePersistBreakevenAdapter(RedisPersist);
13346
- * ```
13781
+ * @param Ctor - Custom IPersistBreakevenInstance constructor
13347
13782
  */
13348
- usePersistBreakevenAdapter(Ctor: TPersistBaseCtor<string, BreakevenData>): void;
13783
+ usePersistBreakevenAdapter(Ctor: TPersistBreakevenInstanceCtor): void;
13349
13784
  /**
13350
- * Reads persisted breakeven data for a symbol and strategy.
13351
- *
13352
- * Called by ClientBreakeven.waitForInit() to restore state.
13353
- * Returns empty object if no breakeven data exists.
13785
+ * Reads breakeven data for the given context and signalId.
13786
+ * Lazily initializes the instance on first access.
13354
13787
  *
13355
13788
  * @param symbol - Trading pair symbol
13356
13789
  * @param strategyName - Strategy identifier
13357
13790
  * @param signalId - Signal identifier
13358
13791
  * @param exchangeName - Exchange identifier
13359
- * @returns Promise resolving to breakeven data record
13792
+ * @returns Promise resolving to breakeven data record (empty object if none)
13360
13793
  */
13361
13794
  readBreakevenData: (symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<BreakevenData>;
13362
13795
  /**
13363
- * Writes breakeven data to disk.
13364
- *
13365
- * Called by ClientBreakeven._persistState() after state changes.
13366
- * Creates directory and file if they don't exist.
13367
- * Uses atomic writes to prevent data corruption.
13796
+ * Writes breakeven data for the given context and signalId.
13797
+ * Lazily initializes the instance on first access.
13368
13798
  *
13369
13799
  * @param breakevenData - Breakeven data record to persist
13370
13800
  * @param symbol - Trading pair symbol
@@ -13375,19 +13805,16 @@ declare class PersistBreakevenUtils {
13375
13805
  */
13376
13806
  writeBreakevenData: (breakevenData: BreakevenData, symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<void>;
13377
13807
  /**
13378
- * Clears the memoized storage cache.
13379
- * Call this when process.cwd() changes between strategy iterations
13380
- * so new storage instances are created with the updated base path.
13808
+ * Clears the memoized instance cache.
13809
+ * Call when process.cwd() changes between strategy iterations.
13381
13810
  */
13382
13811
  clear(): void;
13383
13812
  /**
13384
- * Switches to the default JSON persist adapter.
13385
- * All future persistence writes will use JSON storage.
13813
+ * Switches to the default file-based PersistBreakevenInstance.
13386
13814
  */
13387
13815
  useJson(): void;
13388
13816
  /**
13389
- * Switches to a dummy persist adapter that discards all writes.
13390
- * All future persistence writes will be no-ops.
13817
+ * Switches to PersistBreakevenDummyInstance (all operations are no-ops).
13391
13818
  */
13392
13819
  useDummy(): void;
13393
13820
  }
@@ -13413,6 +13840,110 @@ declare const PersistBreakevenAdapter: PersistBreakevenUtils;
13413
13840
  * Each candle is stored as a separate JSON file.
13414
13841
  */
13415
13842
  type CandleData = ICandleData;
13843
+ /**
13844
+ * Per-context candle cache persistence instance interface.
13845
+ * Scoped to a specific (symbol, interval, exchangeName) triple.
13846
+ *
13847
+ * Each candle is keyed by its timestamp inside the context-scoped storage.
13848
+ * `readCandlesData` returns `null` when ANY of the expected timestamps is
13849
+ * missing (cache miss), so the caller can refetch from the exchange.
13850
+ *
13851
+ * Custom adapters should implement this interface to override the default
13852
+ * file-based candle cache behavior.
13853
+ */
13854
+ interface IPersistCandleInstance {
13855
+ /**
13856
+ * Initialize storage for this candle context.
13857
+ *
13858
+ * @param initial - Whether this is the first initialization
13859
+ * @returns Promise that resolves when initialization is complete
13860
+ */
13861
+ waitForInit(initial: boolean): Promise<void>;
13862
+ /**
13863
+ * Read cached candles for the requested time window.
13864
+ * Returns null if any candle in the window is missing (cache miss).
13865
+ *
13866
+ * @param limit - Number of candles requested
13867
+ * @param sinceTimestamp - Aligned start timestamp (openTime of first candle)
13868
+ * @param untilTimestamp - Reserved for API compatibility, not used by default
13869
+ * @returns Promise resolving to candles in order, or null on cache miss
13870
+ */
13871
+ readCandlesData(limit: number, sinceTimestamp: number, untilTimestamp: number): Promise<CandleData[] | null>;
13872
+ /**
13873
+ * Write candles to cache.
13874
+ * Implementations may skip incomplete candles (closeTime > now) and
13875
+ * existing keys to avoid overwriting fully closed candles.
13876
+ *
13877
+ * @param candles - Array of candle data to cache
13878
+ * @returns Promise that resolves when all writes are complete
13879
+ */
13880
+ writeCandlesData(candles: CandleData[]): Promise<void>;
13881
+ }
13882
+ /**
13883
+ * Default file-based implementation of IPersistCandleInstance.
13884
+ *
13885
+ * Features:
13886
+ * - Each candle stored as a separate JSON file keyed by its timestamp
13887
+ * - Read returns null on any missing timestamp (cache miss → refetch)
13888
+ * - Write skips incomplete candles (closeTime > now) and existing keys
13889
+ * - Invalid cached candles emit warnings via errorEmitter and treated as miss
13890
+ *
13891
+ * @example
13892
+ * ```typescript
13893
+ * const instance = new PersistCandleInstance("BTCUSDT", "1m", "binance");
13894
+ * await instance.waitForInit(true);
13895
+ * await instance.writeCandlesData(candles);
13896
+ * const cached = await instance.readCandlesData(100, since, until);
13897
+ * ```
13898
+ */
13899
+ declare class PersistCandleInstance implements IPersistCandleInstance {
13900
+ readonly symbol: string;
13901
+ readonly interval: CandleInterval;
13902
+ readonly exchangeName: ExchangeName;
13903
+ /** Underlying file-based storage scoped to this context */
13904
+ private readonly _storage;
13905
+ /**
13906
+ * Creates new candle cache persistence instance.
13907
+ *
13908
+ * @param symbol - Trading pair symbol
13909
+ * @param interval - Candle interval (1m, 5m, 1h, etc.)
13910
+ * @param exchangeName - Exchange identifier
13911
+ */
13912
+ constructor(symbol: string, interval: CandleInterval, exchangeName: ExchangeName);
13913
+ /**
13914
+ * Initializes the underlying PersistBase storage.
13915
+ *
13916
+ * @param initial - Whether this is the first initialization
13917
+ * @returns Promise that resolves when initialization is complete
13918
+ */
13919
+ waitForInit(initial: boolean): Promise<void>;
13920
+ /**
13921
+ * Reads cached candles for the requested window.
13922
+ * Computes expected timestamps (sinceTimestamp + i * stepMs) and reads each
13923
+ * by timestamp key. Returns null on ANY missing timestamp (cache miss).
13924
+ * Invalid cached candles emit a warning via errorEmitter and are treated as miss.
13925
+ *
13926
+ * @param limit - Number of candles requested
13927
+ * @param sinceTimestamp - Aligned start timestamp (openTime of first candle)
13928
+ * @param _untilTimestamp - Reserved for API compatibility, unused
13929
+ * @returns Promise resolving to candles in order, or null on cache miss
13930
+ */
13931
+ readCandlesData(limit: number, sinceTimestamp: number, _untilTimestamp: number): Promise<CandleData[] | null>;
13932
+ /**
13933
+ * Writes candles to cache.
13934
+ * Skips incomplete candles (closeTime > now) and existing keys to keep
13935
+ * the cache append-only for fully closed candles.
13936
+ *
13937
+ * @param candles - Array of candle data to cache
13938
+ * @returns Promise that resolves when all writes are complete
13939
+ */
13940
+ writeCandlesData(candles: CandleData[]): Promise<void>;
13941
+ }
13942
+ /**
13943
+ * Constructor type for IPersistCandleInstance.
13944
+ * Used by PersistCandleUtils.usePersistCandleAdapter() to register custom adapters.
13945
+ */
13946
+ type TPersistCandleInstanceCtor = new (symbol: string, interval: CandleInterval, exchangeName: ExchangeName) => IPersistCandleInstance;
13416
13947
  /**
13417
13948
  * Utility class for managing candles cache persistence.
13418
13949
  *
@@ -13425,43 +13956,40 @@ type CandleData = ICandleData;
13425
13956
  * Used by ClientExchange for candle data caching.
13426
13957
  */
13427
13958
  declare class PersistCandleUtils {
13428
- private PersistCandlesFactory;
13959
+ /**
13960
+ * Constructor used to create per-context candle cache instances.
13961
+ * Replaceable via usePersistCandleAdapter() / useJson() / useDummy().
13962
+ */
13963
+ private PersistCandleInstanceCtor;
13964
+ /**
13965
+ * Memoized factory creating one IPersistCandleInstance per (symbol, interval, exchange) triple.
13966
+ */
13429
13967
  private getCandlesStorage;
13430
13968
  /**
13431
- * Registers a custom persistence adapter.
13969
+ * Registers a custom IPersistCandleInstance constructor.
13970
+ * Clears the memoization cache so subsequent calls use the new adapter.
13432
13971
  *
13433
- * @param Ctor - Custom PersistBase constructor
13972
+ * @param Ctor - Custom IPersistCandleInstance constructor
13434
13973
  */
13435
- usePersistCandleAdapter(Ctor: TPersistBaseCtor<string, CandleData>): void;
13974
+ usePersistCandleAdapter(Ctor: TPersistCandleInstanceCtor): void;
13436
13975
  /**
13437
- * Reads cached candles for a specific exchange, symbol, and interval.
13438
- * Returns candles only if cache contains ALL requested candles.
13439
- *
13440
- * Algorithm (matches ClientExchange.ts logic):
13441
- * 1. Calculate expected timestamps: sinceTimestamp, sinceTimestamp + stepMs, ..., sinceTimestamp + (limit-1) * stepMs
13442
- * 2. Try to read each expected candle by timestamp key
13443
- * 3. If ANY candle is missing, return null (cache miss)
13444
- * 4. If all candles found, return them in order
13976
+ * Reads cached candles for the given context and time window.
13977
+ * Lazily initializes the instance on first access.
13445
13978
  *
13446
13979
  * @param symbol - Trading pair symbol
13447
13980
  * @param interval - Candle interval
13448
13981
  * @param exchangeName - Exchange identifier
13449
13982
  * @param limit - Number of candles requested
13450
13983
  * @param sinceTimestamp - Aligned start timestamp (openTime of first candle)
13451
- * @param _untilTimestamp - Unused, kept for API compatibility
13452
- * @returns Promise resolving to array of candles or null if cache is incomplete
13984
+ * @param untilTimestamp - Reserved for API compatibility
13985
+ * @returns Promise resolving to candles in order, or null on cache miss
13453
13986
  */
13454
- readCandlesData: (symbol: string, interval: CandleInterval, exchangeName: ExchangeName, limit: number, sinceTimestamp: number, _untilTimestamp: number) => Promise<CandleData[] | null>;
13987
+ readCandlesData: (symbol: string, interval: CandleInterval, exchangeName: ExchangeName, limit: number, sinceTimestamp: number, untilTimestamp: number) => Promise<CandleData[] | null>;
13455
13988
  /**
13456
- * Writes candles to cache with atomic file writes.
13457
- * Each candle is stored as a separate JSON file named by its timestamp.
13458
- *
13459
- * The candles passed to this function should be validated candles from the adapter:
13460
- * - First candle.timestamp equals aligned sinceTimestamp (openTime)
13461
- * - Exact number of candles as requested
13462
- * - All candles are fully closed (timestamp + stepMs < untilTimestamp)
13989
+ * Writes candles to cache for the given context.
13990
+ * Lazily initializes the instance on first access.
13463
13991
  *
13464
- * @param candles - Array of candle data to cache (validated by the caller)
13992
+ * @param candles - Array of candle data to cache
13465
13993
  * @param symbol - Trading pair symbol
13466
13994
  * @param interval - Candle interval
13467
13995
  * @param exchangeName - Exchange identifier
@@ -13469,19 +13997,16 @@ declare class PersistCandleUtils {
13469
13997
  */
13470
13998
  writeCandlesData: (candles: CandleData[], symbol: string, interval: CandleInterval, exchangeName: ExchangeName) => Promise<void>;
13471
13999
  /**
13472
- * Clears the memoized storage cache.
13473
- * Call this when process.cwd() changes between strategy iterations
13474
- * so new storage instances are created with the updated base path.
14000
+ * Clears the memoized instance cache.
14001
+ * Call when process.cwd() changes between strategy iterations.
13475
14002
  */
13476
14003
  clear(): void;
13477
14004
  /**
13478
- * Switches to the default JSON persist adapter.
13479
- * All future persistence writes will use JSON storage.
14005
+ * Switches to the default file-based PersistCandleInstance.
13480
14006
  */
13481
14007
  useJson(): void;
13482
14008
  /**
13483
- * Switches to a dummy persist adapter that discards all writes.
13484
- * All future persistence writes will be no-ops.
14009
+ * Switches to PersistCandleDummyInstance (always returns null on read, discards writes).
13485
14010
  */
13486
14011
  useDummy(): void;
13487
14012
  }
@@ -13506,6 +14031,90 @@ declare const PersistCandleAdapter: PersistCandleUtils;
13506
14031
  * Each signal is stored as a separate file keyed by its id.
13507
14032
  */
13508
14033
  type StorageData = IStorageSignalRow[];
14034
+ /**
14035
+ * Per-context signal storage persistence instance interface.
14036
+ * Scoped to either backtest or live mode (one instance per mode).
14037
+ *
14038
+ * Each stored signal is keyed by its `signal.id` and the read operation
14039
+ * iterates over all stored entries to return them as an array.
14040
+ *
14041
+ * Custom adapters should implement this interface to override the default
14042
+ * file-based signal storage behavior.
14043
+ */
14044
+ interface IPersistStorageInstance {
14045
+ /**
14046
+ * Initialize storage for this mode.
14047
+ *
14048
+ * @param initial - Whether this is the first initialization
14049
+ * @returns Promise that resolves when initialization is complete
14050
+ */
14051
+ waitForInit(initial: boolean): Promise<void>;
14052
+ /**
14053
+ * Read all persisted signals by iterating storage keys.
14054
+ *
14055
+ * @returns Promise resolving to array of signal entries
14056
+ */
14057
+ readStorageData(): Promise<StorageData>;
14058
+ /**
14059
+ * Write signals to storage. Each signal is keyed by its `signal.id`.
14060
+ *
14061
+ * @param signals - Signal entries to persist
14062
+ * @returns Promise that resolves when all writes are complete
14063
+ */
14064
+ writeStorageData(signals: StorageData): Promise<void>;
14065
+ }
14066
+ /**
14067
+ * Default file-based implementation of IPersistStorageInstance.
14068
+ *
14069
+ * Features:
14070
+ * - Each signal stored as separate JSON file keyed by signal.id
14071
+ * - Read iterates all keys via PersistBase.keys()
14072
+ * - Crash-safe via atomic writes
14073
+ *
14074
+ * @example
14075
+ * ```typescript
14076
+ * const instance = new PersistStorageInstance(false);
14077
+ * await instance.waitForInit(true);
14078
+ * await instance.writeStorageData(signals);
14079
+ * const all = await instance.readStorageData();
14080
+ * ```
14081
+ */
14082
+ declare class PersistStorageInstance implements IPersistStorageInstance {
14083
+ readonly backtest: boolean;
14084
+ /** Underlying file-based storage for this mode */
14085
+ private readonly _storage;
14086
+ /**
14087
+ * Creates new signal storage persistence instance.
14088
+ *
14089
+ * @param backtest - True for backtest mode storage, false for live mode
14090
+ */
14091
+ constructor(backtest: boolean);
14092
+ /**
14093
+ * Initializes the underlying PersistBase storage.
14094
+ *
14095
+ * @param initial - Whether this is the first initialization
14096
+ * @returns Promise that resolves when initialization is complete
14097
+ */
14098
+ waitForInit(initial: boolean): Promise<void>;
14099
+ /**
14100
+ * Reads all persisted signals by iterating storage keys.
14101
+ *
14102
+ * @returns Promise resolving to array of signal entries
14103
+ */
14104
+ readStorageData(): Promise<StorageData>;
14105
+ /**
14106
+ * Writes each signal as a separate entity keyed by `signal.id`.
14107
+ *
14108
+ * @param signals - Signal entries to persist
14109
+ * @returns Promise that resolves when all writes are complete
14110
+ */
14111
+ writeStorageData(signals: StorageData): Promise<void>;
14112
+ }
14113
+ /**
14114
+ * Constructor type for IPersistStorageInstance.
14115
+ * Used by PersistStorageUtils.usePersistStorageAdapter() to register custom adapters.
14116
+ */
14117
+ type TPersistStorageInstanceCtor = new (backtest: boolean) => IPersistStorageInstance;
13509
14118
  /**
13510
14119
  * Utility class for managing signal storage persistence.
13511
14120
  *
@@ -13519,51 +14128,51 @@ type StorageData = IStorageSignalRow[];
13519
14128
  * Used by SignalLiveUtils for live mode persistence of signals.
13520
14129
  */
13521
14130
  declare class PersistStorageUtils {
13522
- private PersistStorageFactory;
14131
+ /**
14132
+ * Constructor used to create per-mode signal storage instances.
14133
+ * Replaceable via usePersistStorageAdapter() / useJson() / useDummy().
14134
+ */
14135
+ private PersistStorageInstanceCtor;
14136
+ /**
14137
+ * Memoized factory creating one IPersistStorageInstance per mode (backtest/live).
14138
+ * Key: "backtest" or "live".
14139
+ */
13523
14140
  private getStorage;
13524
14141
  /**
13525
- * Registers a custom persistence adapter.
14142
+ * Registers a custom IPersistStorageInstance constructor.
14143
+ * Clears the memoization cache so subsequent calls use the new adapter.
13526
14144
  *
13527
- * @param Ctor - Custom PersistBase constructor
14145
+ * @param Ctor - Custom IPersistStorageInstance constructor
13528
14146
  */
13529
- usePersistStorageAdapter(Ctor: TPersistBaseCtor<string, IStorageSignalRow>): void;
14147
+ usePersistStorageAdapter(Ctor: TPersistStorageInstanceCtor): void;
13530
14148
  /**
13531
- * Reads persisted signals data.
14149
+ * Reads all persisted signals for the given mode.
14150
+ * Lazily initializes the instance on first access.
13532
14151
  *
13533
- * Called by StorageLiveUtils/StorageBacktestUtils.waitForInit() to restore state.
13534
- * Uses keys() from PersistBase to iterate over all stored signals.
13535
- * Returns empty array if no signals exist.
13536
- *
13537
- * @param backtest - If true, reads from backtest storage; otherwise from live storage
14152
+ * @param backtest - True for backtest mode storage, false for live mode
13538
14153
  * @returns Promise resolving to array of signal entries
13539
14154
  */
13540
14155
  readStorageData: (backtest: boolean) => Promise<StorageData>;
13541
14156
  /**
13542
- * Writes signal data to disk with atomic file writes.
13543
- *
13544
- * Called by StorageLiveUtils/StorageBacktestUtils after signal changes to persist state.
13545
- * Uses signal.id as the storage key for individual file storage.
13546
- * Uses atomic writes to prevent corruption on crashes.
14157
+ * Writes signals for the given mode.
14158
+ * Lazily initializes the instance on first access.
13547
14159
  *
13548
14160
  * @param signalData - Signal entries to persist
13549
- * @param backtest - If true, writes to backtest storage; otherwise to live storage
14161
+ * @param backtest - True for backtest mode storage, false for live mode
13550
14162
  * @returns Promise that resolves when write is complete
13551
14163
  */
13552
14164
  writeStorageData: (signalData: StorageData, backtest: boolean) => Promise<void>;
13553
14165
  /**
13554
- * Clears the memoized storage cache.
13555
- * Call this when process.cwd() changes between strategy iterations
13556
- * so new storage instances are created with the updated base path.
14166
+ * Clears the memoized instance cache.
14167
+ * Call when process.cwd() changes between strategy iterations.
13557
14168
  */
13558
14169
  clear(): void;
13559
14170
  /**
13560
- * Switches to the default JSON persist adapter.
13561
- * All future persistence writes will use JSON storage.
14171
+ * Switches to the default file-based PersistStorageInstance.
13562
14172
  */
13563
14173
  useJson(): void;
13564
14174
  /**
13565
- * Switches to a dummy persist adapter that discards all writes.
13566
- * All future persistence writes will be no-ops.
14175
+ * Switches to PersistStorageDummyInstance (all operations are no-ops).
13567
14176
  */
13568
14177
  useDummy(): void;
13569
14178
  }
@@ -13577,6 +14186,90 @@ declare const PersistStorageAdapter: PersistStorageUtils;
13577
14186
  * Each notification is stored as a separate file keyed by its id.
13578
14187
  */
13579
14188
  type NotificationData = NotificationModel[];
14189
+ /**
14190
+ * Per-context notification persistence instance interface.
14191
+ * Scoped to either backtest or live mode (one instance per mode).
14192
+ *
14193
+ * Each notification is keyed by its id and the read operation iterates over
14194
+ * all stored notifications.
14195
+ *
14196
+ * Custom adapters should implement this interface to override the default
14197
+ * file-based notification storage behavior.
14198
+ */
14199
+ interface IPersistNotificationInstance {
14200
+ /**
14201
+ * Initialize storage for this mode.
14202
+ *
14203
+ * @param initial - Whether this is the first initialization
14204
+ * @returns Promise that resolves when initialization is complete
14205
+ */
14206
+ waitForInit(initial: boolean): Promise<void>;
14207
+ /**
14208
+ * Read all persisted notifications by iterating storage keys.
14209
+ *
14210
+ * @returns Promise resolving to array of notification entries
14211
+ */
14212
+ readNotificationData(): Promise<NotificationData>;
14213
+ /**
14214
+ * Write notifications to storage. Each notification is keyed by its id.
14215
+ *
14216
+ * @param notifications - Notification entries to persist
14217
+ * @returns Promise that resolves when all writes are complete
14218
+ */
14219
+ writeNotificationData(notifications: NotificationData): Promise<void>;
14220
+ }
14221
+ /**
14222
+ * Default file-based implementation of IPersistNotificationInstance.
14223
+ *
14224
+ * Features:
14225
+ * - Each notification stored as separate JSON file keyed by id
14226
+ * - Read iterates all keys via PersistBase.keys()
14227
+ * - Crash-safe via atomic writes
14228
+ *
14229
+ * @example
14230
+ * ```typescript
14231
+ * const instance = new PersistNotificationInstance(false);
14232
+ * await instance.waitForInit(true);
14233
+ * await instance.writeNotificationData(notifications);
14234
+ * const all = await instance.readNotificationData();
14235
+ * ```
14236
+ */
14237
+ declare class PersistNotificationInstance implements IPersistNotificationInstance {
14238
+ readonly backtest: boolean;
14239
+ /** Underlying file-based storage for this mode */
14240
+ private readonly _storage;
14241
+ /**
14242
+ * Creates new notification persistence instance.
14243
+ *
14244
+ * @param backtest - True for backtest mode storage, false for live mode
14245
+ */
14246
+ constructor(backtest: boolean);
14247
+ /**
14248
+ * Initializes the underlying PersistBase storage.
14249
+ *
14250
+ * @param initial - Whether this is the first initialization
14251
+ * @returns Promise that resolves when initialization is complete
14252
+ */
14253
+ waitForInit(initial: boolean): Promise<void>;
14254
+ /**
14255
+ * Reads all persisted notifications by iterating storage keys.
14256
+ *
14257
+ * @returns Promise resolving to array of notification entries
14258
+ */
14259
+ readNotificationData(): Promise<NotificationData>;
14260
+ /**
14261
+ * Writes each notification as a separate entity keyed by `notification.id`.
14262
+ *
14263
+ * @param notifications - Notification entries to persist
14264
+ * @returns Promise that resolves when all writes are complete
14265
+ */
14266
+ writeNotificationData(notifications: NotificationData): Promise<void>;
14267
+ }
14268
+ /**
14269
+ * Constructor type for IPersistNotificationInstance.
14270
+ * Used by PersistNotificationUtils.usePersistNotificationAdapter() to register custom adapters.
14271
+ */
14272
+ type TPersistNotificationInstanceCtor = new (backtest: boolean) => IPersistNotificationInstance;
13580
14273
  /**
13581
14274
  * Utility class for managing notification persistence.
13582
14275
  *
@@ -13590,51 +14283,52 @@ type NotificationData = NotificationModel[];
13590
14283
  * Used by NotificationPersistLiveUtils/NotificationPersistBacktestUtils for persistence.
13591
14284
  */
13592
14285
  declare class PersistNotificationUtils {
13593
- private PersistNotificationFactory;
14286
+ /**
14287
+ * Constructor used to create per-mode notification instances.
14288
+ * Replaceable via usePersistNotificationAdapter() / useJson() / useDummy().
14289
+ */
14290
+ private PersistNotificationInstanceCtor;
14291
+ /**
14292
+ * Memoized factory creating one IPersistNotificationInstance per mode (backtest/live).
14293
+ * Key: "backtest" or "live".
14294
+ */
13594
14295
  private getNotificationStorage;
13595
14296
  /**
13596
- * Registers a custom persistence adapter.
14297
+ * Registers a custom IPersistNotificationInstance constructor.
14298
+ * Clears the memoization cache so subsequent calls use the new adapter.
13597
14299
  *
13598
- * @param Ctor - Custom PersistBase constructor
14300
+ * @param Ctor - Custom IPersistNotificationInstance constructor
13599
14301
  */
13600
- usePersistNotificationAdapter(Ctor: TPersistBaseCtor<string, NotificationModel>): void;
14302
+ usePersistNotificationAdapter(Ctor: TPersistNotificationInstanceCtor): void;
13601
14303
  /**
13602
- * Reads persisted notifications data.
13603
- *
13604
- * Called by NotificationPersistLiveUtils/NotificationPersistBacktestUtils.waitForInit() to restore state.
13605
- * Uses keys() from PersistBase to iterate over all stored notifications.
13606
- * Returns empty array if no notifications exist.
14304
+ * Reads persisted notifications for the given mode.
14305
+ * Lazily initializes the instance on first access.
13607
14306
  *
13608
- * @param backtest - If true, reads from backtest storage; otherwise from live storage
14307
+ * @param backtest - True for backtest mode storage, false for live mode
13609
14308
  * @returns Promise resolving to array of notification entries
13610
14309
  */
13611
14310
  readNotificationData: (backtest: boolean) => Promise<NotificationData>;
13612
14311
  /**
13613
- * Writes notification data to disk with atomic file writes.
13614
- *
13615
- * Called by NotificationPersistLiveUtils/NotificationPersistBacktestUtils after notification changes to persist state.
13616
- * Uses notification.id as the storage key for individual file storage.
13617
- * Uses atomic writes to prevent corruption on crashes.
14312
+ * Writes notifications for the given mode.
14313
+ * Lazily initializes the instance on first access.
13618
14314
  *
13619
14315
  * @param notificationData - Notification entries to persist
13620
- * @param backtest - If true, writes to backtest storage; otherwise to live storage
14316
+ * @param backtest - True for backtest mode storage, false for live mode
13621
14317
  * @returns Promise that resolves when write is complete
13622
14318
  */
13623
14319
  writeNotificationData: (notificationData: NotificationData, backtest: boolean) => Promise<void>;
13624
14320
  /**
13625
- * Clears the memoized storage cache.
13626
- * Call this when process.cwd() changes between strategy iterations
13627
- * so new storage instances are created with the updated base path.
14321
+ * Clears the memoized instance cache.
14322
+ * Call when process.cwd() changes between strategy iterations so new
14323
+ * instances are created with the updated base path.
13628
14324
  */
13629
14325
  clear(): void;
13630
14326
  /**
13631
- * Switches to the default JSON persist adapter.
13632
- * All future persistence writes will use JSON storage.
14327
+ * Switches to the default file-based PersistNotificationInstance.
13633
14328
  */
13634
14329
  useJson(): void;
13635
14330
  /**
13636
- * Switches to a dummy persist adapter that discards all writes.
13637
- * All future persistence writes will be no-ops.
14331
+ * Switches to PersistNotificationDummyInstance (all operations are no-ops).
13638
14332
  */
13639
14333
  useDummy(): void;
13640
14334
  }
@@ -13649,11 +14343,98 @@ declare const PersistNotificationAdapter: PersistNotificationUtils;
13649
14343
  * Each log entry is stored as a separate file keyed by its id.
13650
14344
  */
13651
14345
  type LogData = ILogEntry[];
14346
+ /**
14347
+ * Global log entry persistence instance interface.
14348
+ * Unlike other Persist instances, log storage has no context — there is
14349
+ * a single global instance per process.
14350
+ *
14351
+ * Each log entry is keyed by its id and the read operation iterates over
14352
+ * all stored entries.
14353
+ *
14354
+ * Custom adapters should implement this interface to override the default
14355
+ * file-based log storage behavior.
14356
+ */
14357
+ interface IPersistLogInstance {
14358
+ /**
14359
+ * Initialize the global log storage.
14360
+ *
14361
+ * @param initial - Whether this is the first initialization
14362
+ * @returns Promise that resolves when initialization is complete
14363
+ */
14364
+ waitForInit(initial: boolean): Promise<void>;
14365
+ /**
14366
+ * Read all persisted log entries by iterating storage keys.
14367
+ *
14368
+ * @returns Promise resolving to array of log entries
14369
+ */
14370
+ readLogData(): Promise<LogData>;
14371
+ /**
14372
+ * Write log entries to storage. Each entry is keyed by its id.
14373
+ * Implementations should skip entries whose id already exists to keep
14374
+ * the log append-only.
14375
+ *
14376
+ * @param entries - Log entries to persist
14377
+ * @returns Promise that resolves when all writes are complete
14378
+ */
14379
+ writeLogData(entries: LogData): Promise<void>;
14380
+ }
14381
+ /**
14382
+ * Default file-based implementation of IPersistLogInstance.
14383
+ *
14384
+ * Features:
14385
+ * - Each log entry stored as separate JSON file keyed by entry.id
14386
+ * - Read iterates all keys via PersistBase.keys()
14387
+ * - Append-only: existing keys are skipped on write
14388
+ * - Crash-safe via atomic writes
14389
+ *
14390
+ * @example
14391
+ * ```typescript
14392
+ * const instance = new PersistLogInstance();
14393
+ * await instance.waitForInit(true);
14394
+ * await instance.writeLogData(entries);
14395
+ * const all = await instance.readLogData();
14396
+ * ```
14397
+ */
14398
+ declare class PersistLogInstance implements IPersistLogInstance {
14399
+ /** Underlying file-based storage for log entries */
14400
+ private readonly _storage;
14401
+ /**
14402
+ * Creates new log persistence instance.
14403
+ * No context parameters — there is a single global log storage.
14404
+ */
14405
+ constructor();
14406
+ /**
14407
+ * Initializes the underlying PersistBase storage.
14408
+ *
14409
+ * @param initial - Whether this is the first initialization
14410
+ * @returns Promise that resolves when initialization is complete
14411
+ */
14412
+ waitForInit(initial: boolean): Promise<void>;
14413
+ /**
14414
+ * Reads all persisted log entries by iterating storage keys.
14415
+ *
14416
+ * @returns Promise resolving to array of log entries
14417
+ */
14418
+ readLogData(): Promise<LogData>;
14419
+ /**
14420
+ * Writes log entries append-only — skips entries whose id already exists
14421
+ * so the log file is never overwritten.
14422
+ *
14423
+ * @param logData - Log entries to persist
14424
+ * @returns Promise that resolves when all writes are complete
14425
+ */
14426
+ writeLogData(logData: LogData): Promise<void>;
14427
+ }
14428
+ /**
14429
+ * Constructor type for IPersistLogInstance.
14430
+ * Used by PersistLogUtils.usePersistLogAdapter() to register custom adapters.
14431
+ */
14432
+ type TPersistLogInstanceCtor = new () => IPersistLogInstance;
13652
14433
  /**
13653
14434
  * Utility class for managing log entry persistence.
13654
14435
  *
13655
14436
  * Features:
13656
- * - Memoized storage instance
14437
+ * - Cached storage instance
13657
14438
  * - Custom adapter support
13658
14439
  * - Atomic read/write operations for LogData
13659
14440
  * - Each log entry stored as separate file keyed by id
@@ -13662,50 +14443,55 @@ type LogData = ILogEntry[];
13662
14443
  * Used by LogPersistUtils for log entry persistence.
13663
14444
  */
13664
14445
  declare class PersistLogUtils {
13665
- private PersistLogFactory;
13666
- private _logStorage;
13667
- private getLogStorage;
13668
14446
  /**
13669
- * Registers a custom persistence adapter.
14447
+ * Constructor used to create the global log instance.
14448
+ * Replaceable via usePersistLogAdapter() / useJson() / useDummy().
14449
+ */
14450
+ private PersistLogInstanceCtor;
14451
+ /**
14452
+ * Cached singleton log instance. Lazily created on first access.
14453
+ * Reset to null by clear() and usePersistLogAdapter().
14454
+ */
14455
+ private _logInstance;
14456
+ /**
14457
+ * Returns the cached log instance, creating it on first access.
13670
14458
  *
13671
- * @param Ctor - Custom PersistBase constructor
14459
+ * @returns The IPersistLogInstance singleton
13672
14460
  */
13673
- usePersistLogAdapter(Ctor: TPersistBaseCtor<string, ILogEntry>): void;
14461
+ private getLogInstance;
13674
14462
  /**
13675
- * Reads persisted log entries.
14463
+ * Registers a custom IPersistLogInstance constructor.
14464
+ * Drops the cached instance so the next access uses the new adapter.
13676
14465
  *
13677
- * Called by LogPersistUtils.waitForInit() to restore state.
13678
- * Uses keys() from PersistBase to iterate over all stored entries.
13679
- * Returns empty array if no entries exist.
14466
+ * @param Ctor - Custom IPersistLogInstance constructor
14467
+ */
14468
+ usePersistLogAdapter(Ctor: TPersistLogInstanceCtor): void;
14469
+ /**
14470
+ * Reads all persisted log entries.
14471
+ * Lazily initializes the instance on first access.
13680
14472
  *
13681
14473
  * @returns Promise resolving to array of log entries
13682
14474
  */
13683
14475
  readLogData: () => Promise<LogData>;
13684
14476
  /**
13685
- * Writes log entries to disk with atomic file writes.
13686
- *
13687
- * Called by LogPersistUtils after each log call to persist state.
13688
- * Uses entry.id as the storage key for individual file storage.
13689
- * Uses atomic writes to prevent corruption on crashes.
14477
+ * Writes log entries (append-only duplicates by id are skipped).
14478
+ * Lazily initializes the instance on first access.
13690
14479
  *
13691
14480
  * @param logData - Log entries to persist
13692
14481
  * @returns Promise that resolves when write is complete
13693
14482
  */
13694
14483
  writeLogData: (logData: LogData) => Promise<void>;
13695
14484
  /**
13696
- * Clears the cached storage instance.
13697
- * Call this when process.cwd() changes between strategy iterations
13698
- * so a new storage instance is created with the updated base path.
14485
+ * Drops the cached log instance.
14486
+ * Call when process.cwd() changes between strategy iterations.
13699
14487
  */
13700
14488
  clear(): void;
13701
14489
  /**
13702
- * Switches to the default JSON persist adapter.
13703
- * All future persistence writes will use JSON storage.
14490
+ * Switches to the default file-based PersistLogInstance.
13704
14491
  */
13705
14492
  useJson(): void;
13706
14493
  /**
13707
- * Switches to a dummy persist adapter that discards all writes.
13708
- * All future persistence writes will be no-ops.
14494
+ * Switches to PersistLogDummyInstance (all operations are no-ops).
13709
14495
  */
13710
14496
  useDummy(): void;
13711
14497
  }
@@ -13714,6 +14500,122 @@ declare class PersistLogUtils {
13714
14500
  * Used by LogPersistUtils for log entry persistence.
13715
14501
  */
13716
14502
  declare const PersistLogAdapter: PersistLogUtils;
14503
+ /**
14504
+ * Per-bucket measure cache persistence instance interface.
14505
+ * Used by Cache.file for caching external API responses.
14506
+ *
14507
+ * Supports soft delete: removed entries stay on disk with `removed: true`
14508
+ * flag and are filtered out by read/list operations.
14509
+ *
14510
+ * Custom adapters should implement this interface to override the default
14511
+ * file-based measure cache behavior.
14512
+ */
14513
+ interface IPersistMeasureInstance {
14514
+ /**
14515
+ * Initialize storage for this bucket.
14516
+ *
14517
+ * @param initial - Whether this is the first initialization
14518
+ * @returns Promise that resolves when initialization is complete
14519
+ */
14520
+ waitForInit(initial: boolean): Promise<void>;
14521
+ /**
14522
+ * Read cached entry by key.
14523
+ *
14524
+ * @param key - Cache key within the bucket
14525
+ * @returns Promise resolving to cached value, or null if not found or soft-deleted
14526
+ */
14527
+ readMeasureData(key: string): Promise<MeasureData | null>;
14528
+ /**
14529
+ * Write entry to cache.
14530
+ *
14531
+ * @param data - Data to cache
14532
+ * @param key - Cache key within the bucket
14533
+ * @returns Promise that resolves when write is complete
14534
+ */
14535
+ writeMeasureData(data: MeasureData, key: string): Promise<void>;
14536
+ /**
14537
+ * Soft-delete an entry by setting its `removed` flag.
14538
+ * File stays on disk, but subsequent reads return null.
14539
+ *
14540
+ * @param key - Cache key within the bucket
14541
+ * @returns Promise that resolves when removal is complete
14542
+ */
14543
+ removeMeasureData(key: string): Promise<void>;
14544
+ /**
14545
+ * Iterate all non-removed entry keys for this bucket.
14546
+ *
14547
+ * @returns AsyncGenerator yielding entry keys
14548
+ */
14549
+ listMeasureData(): AsyncGenerator<string>;
14550
+ }
14551
+ /**
14552
+ * Default file-based implementation of IPersistMeasureInstance.
14553
+ *
14554
+ * Features:
14555
+ * - Wraps PersistBase for atomic JSON writes
14556
+ * - Soft delete via `removed: true` flag
14557
+ * - listMeasureData filters out removed entries
14558
+ *
14559
+ * @example
14560
+ * ```typescript
14561
+ * const instance = new PersistMeasureInstance("my-bucket");
14562
+ * await instance.waitForInit(true);
14563
+ * await instance.writeMeasureData({ id: "x", data: {}, removed: false }, "key1");
14564
+ * const data = await instance.readMeasureData("key1");
14565
+ * await instance.removeMeasureData("key1");
14566
+ * ```
14567
+ */
14568
+ declare class PersistMeasureInstance implements IPersistMeasureInstance {
14569
+ readonly bucket: string;
14570
+ /** Underlying file-based storage for this bucket */
14571
+ private readonly _storage;
14572
+ /**
14573
+ * Creates new measure cache persistence instance.
14574
+ *
14575
+ * @param bucket - Cache bucket identifier
14576
+ */
14577
+ constructor(bucket: string);
14578
+ /**
14579
+ * Initializes the underlying PersistBase storage.
14580
+ *
14581
+ * @param initial - Whether this is the first initialization
14582
+ * @returns Promise that resolves when initialization is complete
14583
+ */
14584
+ waitForInit(initial: boolean): Promise<void>;
14585
+ /**
14586
+ * Reads a measure entry by key. Returns null if entry is missing or soft-deleted.
14587
+ *
14588
+ * @param key - Cache key within the bucket
14589
+ * @returns Promise resolving to entry data, or null
14590
+ */
14591
+ readMeasureData(key: string): Promise<MeasureData | null>;
14592
+ /**
14593
+ * Writes a measure entry under the given key.
14594
+ *
14595
+ * @param data - Data to cache
14596
+ * @param key - Cache key within the bucket
14597
+ * @returns Promise that resolves when write is complete
14598
+ */
14599
+ writeMeasureData(data: MeasureData, key: string): Promise<void>;
14600
+ /**
14601
+ * Soft-deletes an entry by writing `removed: true` flag while preserving the file.
14602
+ *
14603
+ * @param key - Cache key within the bucket
14604
+ * @returns Promise that resolves when removal is complete
14605
+ */
14606
+ removeMeasureData(key: string): Promise<void>;
14607
+ /**
14608
+ * Iterates all entries in the bucket, yielding keys of non-removed entries only.
14609
+ *
14610
+ * @returns AsyncGenerator yielding entry keys
14611
+ */
14612
+ listMeasureData(): AsyncGenerator<string>;
14613
+ }
14614
+ /**
14615
+ * Constructor type for IPersistMeasureInstance.
14616
+ * Used by PersistMeasureUtils.usePersistMeasureAdapter() to register custom adapters.
14617
+ */
14618
+ type TPersistMeasureInstanceCtor = new (bucket: string) => IPersistMeasureInstance;
13717
14619
  /**
13718
14620
  * Utility class for managing external API response cache persistence.
13719
14621
  *
@@ -13726,60 +14628,69 @@ declare const PersistLogAdapter: PersistLogUtils;
13726
14628
  * Used by Cache.file for persistent caching of external API responses.
13727
14629
  */
13728
14630
  declare class PersistMeasureUtils {
13729
- private PersistMeasureFactory;
14631
+ /**
14632
+ * Constructor used to create per-bucket measure cache instances.
14633
+ * Replaceable via usePersistMeasureAdapter() / useJson() / useDummy().
14634
+ */
14635
+ private PersistMeasureInstanceCtor;
14636
+ /**
14637
+ * Memoized factory creating one IPersistMeasureInstance per bucket.
14638
+ */
13730
14639
  private getMeasureStorage;
13731
14640
  /**
13732
- * Registers a custom persistence adapter.
14641
+ * Registers a custom IPersistMeasureInstance constructor.
14642
+ * Clears the memoization cache so subsequent calls use the new adapter.
13733
14643
  *
13734
- * @param Ctor - Custom PersistBase constructor
14644
+ * @param Ctor - Custom IPersistMeasureInstance constructor
13735
14645
  */
13736
- usePersistMeasureAdapter(Ctor: TPersistBaseCtor<string, MeasureData>): void;
14646
+ usePersistMeasureAdapter(Ctor: TPersistMeasureInstanceCtor): void;
13737
14647
  /**
13738
- * Reads cached measure data for a given bucket and key.
14648
+ * Reads a measure entry from the given bucket by key.
14649
+ * Lazily initializes the bucket instance on first access.
13739
14650
  *
13740
- * @param bucket - Storage bucket (e.g. aligned timestamp + symbol)
13741
- * @param key - Dynamic cache key within the bucket
13742
- * @returns Promise resolving to cached value or null if not found
14651
+ * @param bucket - Storage bucket identifier
14652
+ * @param key - Cache key within the bucket
14653
+ * @returns Promise resolving to cached value, or null if not found / soft-deleted
13743
14654
  */
13744
14655
  readMeasureData: (bucket: string, key: string) => Promise<MeasureData | null>;
13745
14656
  /**
13746
- * Writes measure data to disk with atomic file writes.
14657
+ * Writes a measure entry to the given bucket under the given key.
14658
+ * Lazily initializes the bucket instance on first access.
13747
14659
  *
13748
14660
  * @param data - Data to cache
13749
- * @param bucket - Storage bucket (e.g. aligned timestamp + symbol)
13750
- * @param key - Dynamic cache key within the bucket
14661
+ * @param bucket - Storage bucket identifier
14662
+ * @param key - Cache key within the bucket
13751
14663
  * @returns Promise that resolves when write is complete
13752
14664
  */
13753
14665
  writeMeasureData: (data: MeasureData, bucket: string, key: string) => Promise<void>;
13754
14666
  /**
13755
- * Marks a cached entry as removed (soft delete file is kept on disk).
13756
- * After this call `readMeasureData` for the same key returns `null`.
14667
+ * Soft-deletes a measure entry in the given bucket by setting `removed: true`.
14668
+ * Lazily initializes the bucket instance on first access.
13757
14669
  *
13758
- * @param bucket - Storage bucket
13759
- * @param key - Dynamic cache key within the bucket
14670
+ * @param bucket - Storage bucket identifier
14671
+ * @param key - Cache key within the bucket
13760
14672
  * @returns Promise that resolves when removal is complete
13761
14673
  */
13762
14674
  removeMeasureData: (bucket: string, key: string) => Promise<void>;
13763
14675
  /**
13764
- * Async generator yielding all non-removed entity keys for a given bucket.
13765
- * Used by `CacheFileInstance.clear()` to iterate and soft-delete all entries.
14676
+ * Iterates all non-removed measure entries for the given bucket.
14677
+ * Lazily initializes the bucket instance on first access.
13766
14678
  *
13767
- * @param bucket - Storage bucket
13768
- * @returns AsyncGenerator yielding entity keys
14679
+ * @param bucket - Storage bucket identifier
14680
+ * @returns AsyncGenerator yielding entry keys
13769
14681
  */
13770
14682
  listMeasureData(bucket: string): AsyncGenerator<string>;
13771
14683
  /**
13772
- * Clears the memoized storage cache.
13773
- * Call this when process.cwd() changes between strategy iterations
13774
- * so new storage instances are created with the updated base path.
14684
+ * Clears the memoized bucket instance cache.
14685
+ * Call when process.cwd() changes between strategy iterations.
13775
14686
  */
13776
14687
  clear(): void;
13777
14688
  /**
13778
- * Switches to the default JSON persist adapter.
14689
+ * Switches to the default file-based PersistMeasureInstance.
13779
14690
  */
13780
14691
  useJson(): void;
13781
14692
  /**
13782
- * Switches to a dummy persist adapter that discards all writes.
14693
+ * Switches to PersistMeasureDummyInstance (all operations are no-ops).
13783
14694
  */
13784
14695
  useDummy(): void;
13785
14696
  }
@@ -13788,6 +14699,124 @@ declare class PersistMeasureUtils {
13788
14699
  * Used by Cache.file for persistent caching of external API responses.
13789
14700
  */
13790
14701
  declare const PersistMeasureAdapter: PersistMeasureUtils;
14702
+ /**
14703
+ * Per-bucket interval marker persistence instance interface.
14704
+ * Used by Interval.file for once-per-interval signal firing.
14705
+ *
14706
+ * A record's presence means the interval has already fired for that
14707
+ * bucket+key. Soft-deleted records (removed=true) act as if absent,
14708
+ * allowing the function to fire again.
14709
+ *
14710
+ * Custom adapters should implement this interface to override the default
14711
+ * file-based interval marker behavior.
14712
+ */
14713
+ interface IPersistIntervalInstance {
14714
+ /**
14715
+ * Initialize storage for this bucket.
14716
+ *
14717
+ * @param initial - Whether this is the first initialization
14718
+ * @returns Promise that resolves when initialization is complete
14719
+ */
14720
+ waitForInit(initial: boolean): Promise<void>;
14721
+ /**
14722
+ * Read interval marker by key.
14723
+ *
14724
+ * @param key - Marker key within the bucket
14725
+ * @returns Promise resolving to stored value, or null if not found or soft-deleted
14726
+ */
14727
+ readIntervalData(key: string): Promise<IntervalData | null>;
14728
+ /**
14729
+ * Write interval marker.
14730
+ *
14731
+ * @param data - Data to store
14732
+ * @param key - Marker key within the bucket
14733
+ * @returns Promise that resolves when write is complete
14734
+ */
14735
+ writeIntervalData(data: IntervalData, key: string): Promise<void>;
14736
+ /**
14737
+ * Soft-delete a marker. After this call the function will fire again
14738
+ * on the next IntervalFileInstance.run call for the same key.
14739
+ *
14740
+ * @param key - Marker key within the bucket
14741
+ * @returns Promise that resolves when removal is complete
14742
+ */
14743
+ removeIntervalData(key: string): Promise<void>;
14744
+ /**
14745
+ * Iterate all non-removed marker keys for this bucket.
14746
+ *
14747
+ * @returns AsyncGenerator yielding marker keys
14748
+ */
14749
+ listIntervalData(): AsyncGenerator<string>;
14750
+ }
14751
+ /**
14752
+ * Default file-based implementation of IPersistIntervalInstance.
14753
+ *
14754
+ * Features:
14755
+ * - Wraps PersistBase for atomic JSON writes
14756
+ * - Soft delete via `removed: true` flag
14757
+ * - listIntervalData filters out removed markers
14758
+ *
14759
+ * @example
14760
+ * ```typescript
14761
+ * const instance = new PersistIntervalInstance("my-interval-bucket");
14762
+ * await instance.waitForInit(true);
14763
+ * await instance.writeIntervalData({ id: "x", data: {}, removed: false }, "key1");
14764
+ * const marker = await instance.readIntervalData("key1");
14765
+ * await instance.removeIntervalData("key1");
14766
+ * ```
14767
+ */
14768
+ declare class PersistIntervalInstance implements IPersistIntervalInstance {
14769
+ readonly bucket: string;
14770
+ /** Underlying file-based storage for this bucket */
14771
+ private readonly _storage;
14772
+ /**
14773
+ * Creates new interval marker persistence instance.
14774
+ *
14775
+ * @param bucket - Marker bucket identifier
14776
+ */
14777
+ constructor(bucket: string);
14778
+ /**
14779
+ * Initializes the underlying PersistBase storage.
14780
+ *
14781
+ * @param initial - Whether this is the first initialization
14782
+ * @returns Promise that resolves when initialization is complete
14783
+ */
14784
+ waitForInit(initial: boolean): Promise<void>;
14785
+ /**
14786
+ * Reads an interval marker by key. Returns null if marker is missing or soft-deleted.
14787
+ *
14788
+ * @param key - Marker key within the bucket
14789
+ * @returns Promise resolving to stored data, or null
14790
+ */
14791
+ readIntervalData(key: string): Promise<IntervalData | null>;
14792
+ /**
14793
+ * Writes an interval marker under the given key.
14794
+ *
14795
+ * @param data - Data to store
14796
+ * @param key - Marker key within the bucket
14797
+ * @returns Promise that resolves when write is complete
14798
+ */
14799
+ writeIntervalData(data: IntervalData, key: string): Promise<void>;
14800
+ /**
14801
+ * Soft-deletes a marker by writing `removed: true` flag while preserving the file.
14802
+ * Subsequent reads will return null, allowing the interval to fire again.
14803
+ *
14804
+ * @param key - Marker key within the bucket
14805
+ * @returns Promise that resolves when removal is complete
14806
+ */
14807
+ removeIntervalData(key: string): Promise<void>;
14808
+ /**
14809
+ * Iterates all markers in the bucket, yielding keys of non-removed markers only.
14810
+ *
14811
+ * @returns AsyncGenerator yielding marker keys
14812
+ */
14813
+ listIntervalData(): AsyncGenerator<string>;
14814
+ }
14815
+ /**
14816
+ * Constructor type for IPersistIntervalInstance.
14817
+ * Used by PersistIntervalUtils.usePersistIntervalAdapter() to register custom adapters.
14818
+ */
14819
+ type TPersistIntervalInstanceCtor = new (bucket: string) => IPersistIntervalInstance;
13791
14820
  /**
13792
14821
  * Persistence layer for Interval.file once-per-interval signal firing.
13793
14822
  *
@@ -13796,60 +14825,69 @@ declare const PersistMeasureAdapter: PersistMeasureUtils;
13796
14825
  * absence means the function has not yet fired (or returned null last time).
13797
14826
  */
13798
14827
  declare class PersistIntervalUtils {
13799
- private PersistIntervalFactory;
14828
+ /**
14829
+ * Constructor used to create per-bucket interval marker instances.
14830
+ * Replaceable via usePersistIntervalAdapter() / useJson() / useDummy().
14831
+ */
14832
+ private PersistIntervalInstanceCtor;
14833
+ /**
14834
+ * Memoized factory creating one IPersistIntervalInstance per bucket.
14835
+ */
13800
14836
  private getIntervalStorage;
13801
14837
  /**
13802
- * Registers a custom persistence adapter.
14838
+ * Registers a custom IPersistIntervalInstance constructor.
14839
+ * Clears the memoization cache so subsequent calls use the new adapter.
13803
14840
  *
13804
- * @param Ctor - Custom PersistBase constructor
14841
+ * @param Ctor - Custom IPersistIntervalInstance constructor
13805
14842
  */
13806
- usePersistIntervalAdapter(Ctor: TPersistBaseCtor<string, IntervalData>): void;
14843
+ usePersistIntervalAdapter(Ctor: TPersistIntervalInstanceCtor): void;
13807
14844
  /**
13808
- * Reads interval data for a given bucket and key.
14845
+ * Reads an interval marker from the given bucket by key.
14846
+ * Lazily initializes the bucket instance on first access.
13809
14847
  *
13810
- * @param bucket - Storage bucket (instance name + interval + index)
13811
- * @param key - Entity key within the bucket (symbol + aligned timestamp)
13812
- * @returns Promise resolving to stored value or null if not found
14848
+ * @param bucket - Storage bucket identifier
14849
+ * @param key - Marker key within the bucket
14850
+ * @returns Promise resolving to marker data, or null if not found / soft-deleted
13813
14851
  */
13814
14852
  readIntervalData: (bucket: string, key: string) => Promise<IntervalData | null>;
13815
14853
  /**
13816
- * Writes interval data to disk.
14854
+ * Writes an interval marker to the given bucket under the given key.
14855
+ * Lazily initializes the bucket instance on first access.
13817
14856
  *
13818
14857
  * @param data - Data to store
13819
- * @param bucket - Storage bucket
13820
- * @param key - Entity key within the bucket
14858
+ * @param bucket - Storage bucket identifier
14859
+ * @param key - Marker key within the bucket
13821
14860
  * @returns Promise that resolves when write is complete
13822
14861
  */
13823
14862
  writeIntervalData: (data: IntervalData, bucket: string, key: string) => Promise<void>;
13824
14863
  /**
13825
- * Marks an interval entry as removed (soft delete file is kept on disk).
13826
- * After this call `readIntervalData` for the same key returns `null`,
13827
- * so the function will fire again on the next `IntervalFileInstance.run` call.
14864
+ * Soft-deletes a marker in the given bucket by setting `removed: true`.
14865
+ * Lazily initializes the bucket instance on first access.
13828
14866
  *
13829
- * @param bucket - Storage bucket
13830
- * @param key - Entity key within the bucket
14867
+ * @param bucket - Storage bucket identifier
14868
+ * @param key - Marker key within the bucket
13831
14869
  * @returns Promise that resolves when removal is complete
13832
14870
  */
13833
14871
  removeIntervalData: (bucket: string, key: string) => Promise<void>;
13834
14872
  /**
13835
- * Async generator yielding all non-removed entity keys for a given bucket.
13836
- * Used by `IntervalFileInstance.clear()` to iterate and soft-delete all entries.
14873
+ * Iterates all non-removed markers for the given bucket.
14874
+ * Lazily initializes the bucket instance on first access.
13837
14875
  *
13838
- * @param bucket - Storage bucket
13839
- * @returns AsyncGenerator yielding entity keys
14876
+ * @param bucket - Storage bucket identifier
14877
+ * @returns AsyncGenerator yielding marker keys
13840
14878
  */
13841
14879
  listIntervalData(bucket: string): AsyncGenerator<string>;
13842
14880
  /**
13843
- * Clears the memoized storage cache.
13844
- * Call this when process.cwd() changes between strategy iterations.
14881
+ * Clears the memoized bucket instance cache.
14882
+ * Call when process.cwd() changes between strategy iterations.
13845
14883
  */
13846
14884
  clear(): void;
13847
14885
  /**
13848
- * Switches to the default JSON persist adapter.
14886
+ * Switches to the default file-based PersistIntervalInstance.
13849
14887
  */
13850
14888
  useJson(): void;
13851
14889
  /**
13852
- * Switches to a dummy persist adapter that discards all writes.
14890
+ * Switches to PersistIntervalDummyInstance (all operations are no-ops).
13853
14891
  */
13854
14892
  useDummy(): void;
13855
14893
  }
@@ -13868,6 +14906,156 @@ type MemoryData = {
13868
14906
  removed: boolean;
13869
14907
  index: string;
13870
14908
  };
14909
+ /**
14910
+ * Per-context memory entry persistence instance interface.
14911
+ * Scoped to a specific (signalId, bucketName) pair.
14912
+ *
14913
+ * Used by MemoryPersistInstance for LLM memory storage. Supports soft delete
14914
+ * via `removed: true` flag — soft-deleted entries stay on disk but are
14915
+ * filtered out by read/list operations.
14916
+ *
14917
+ * Custom adapters should implement this interface to override the default
14918
+ * file-based memory entry behavior.
14919
+ */
14920
+ interface IPersistMemoryInstance {
14921
+ /**
14922
+ * Initialize storage for this memory context.
14923
+ *
14924
+ * @param initial - Whether this is the first initialization
14925
+ * @returns Promise that resolves when initialization is complete
14926
+ */
14927
+ waitForInit(initial: boolean): Promise<void>;
14928
+ /**
14929
+ * Read a memory entry by id.
14930
+ *
14931
+ * @param memoryId - Memory entry identifier
14932
+ * @returns Promise resolving to entry data, or null if not found or soft-deleted
14933
+ */
14934
+ readMemoryData(memoryId: string): Promise<MemoryData | null>;
14935
+ /**
14936
+ * Check whether a memory entry exists (regardless of removed flag).
14937
+ *
14938
+ * @param memoryId - Memory entry identifier
14939
+ * @returns Promise resolving to true if entry exists on disk
14940
+ */
14941
+ hasMemoryData(memoryId: string): Promise<boolean>;
14942
+ /**
14943
+ * Write a memory entry.
14944
+ *
14945
+ * @param data - Entry data to persist
14946
+ * @param memoryId - Memory entry identifier
14947
+ * @returns Promise that resolves when write is complete
14948
+ */
14949
+ writeMemoryData(data: MemoryData, memoryId: string): Promise<void>;
14950
+ /**
14951
+ * Soft-delete a memory entry. File stays on disk; subsequent reads return null.
14952
+ *
14953
+ * @param memoryId - Memory entry identifier
14954
+ * @returns Promise that resolves when removal is complete
14955
+ */
14956
+ removeMemoryData(memoryId: string): Promise<void>;
14957
+ /**
14958
+ * Iterate all non-removed memory entries for this context.
14959
+ * Used by MemoryPersistInstance to rebuild the BM25 index on init.
14960
+ *
14961
+ * @returns AsyncGenerator yielding entry id + data tuples
14962
+ */
14963
+ listMemoryData(): AsyncGenerator<{
14964
+ memoryId: string;
14965
+ data: MemoryData;
14966
+ }>;
14967
+ /**
14968
+ * Release any resources held by this instance.
14969
+ * Default implementations may treat this as a no-op.
14970
+ */
14971
+ dispose(): void;
14972
+ }
14973
+ /**
14974
+ * Default file-based implementation of IPersistMemoryInstance.
14975
+ *
14976
+ * Features:
14977
+ * - Wraps PersistBase for atomic JSON writes
14978
+ * - Soft delete via `removed: true` flag
14979
+ * - listMemoryData filters out removed entries
14980
+ * - dispose is a no-op (memo cache is managed by PersistMemoryUtils)
14981
+ *
14982
+ * @example
14983
+ * ```typescript
14984
+ * const instance = new PersistMemoryInstance("signal-1", "context-bucket");
14985
+ * await instance.waitForInit(true);
14986
+ * await instance.writeMemoryData(entryData, "memory-id-1");
14987
+ * const data = await instance.readMemoryData("memory-id-1");
14988
+ * ```
14989
+ */
14990
+ declare class PersistMemoryInstance implements IPersistMemoryInstance {
14991
+ readonly signalId: string;
14992
+ readonly bucketName: string;
14993
+ /** Underlying file-based storage scoped to this context */
14994
+ private readonly _storage;
14995
+ /**
14996
+ * Creates new memory persistence instance.
14997
+ *
14998
+ * @param signalId - Signal identifier (entity folder name)
14999
+ * @param bucketName - Bucket name (subfolder under memory/)
15000
+ */
15001
+ constructor(signalId: string, bucketName: string);
15002
+ /**
15003
+ * Initializes the underlying PersistBase storage.
15004
+ *
15005
+ * @param initial - Whether this is the first initialization
15006
+ * @returns Promise that resolves when initialization is complete
15007
+ */
15008
+ waitForInit(initial: boolean): Promise<void>;
15009
+ /**
15010
+ * Reads a memory entry by id. Returns null if entry is missing or soft-deleted.
15011
+ *
15012
+ * @param memoryId - Memory entry identifier
15013
+ * @returns Promise resolving to entry data, or null
15014
+ */
15015
+ readMemoryData(memoryId: string): Promise<MemoryData | null>;
15016
+ /**
15017
+ * Checks whether a memory entry exists on disk (regardless of removed flag).
15018
+ *
15019
+ * @param memoryId - Memory entry identifier
15020
+ * @returns Promise resolving to true if entry file exists
15021
+ */
15022
+ hasMemoryData(memoryId: string): Promise<boolean>;
15023
+ /**
15024
+ * Writes a memory entry under the given id.
15025
+ *
15026
+ * @param data - Entry data to persist
15027
+ * @param memoryId - Memory entry identifier
15028
+ * @returns Promise that resolves when write is complete
15029
+ */
15030
+ writeMemoryData(data: MemoryData, memoryId: string): Promise<void>;
15031
+ /**
15032
+ * Soft-deletes a memory entry by writing `removed: true` flag.
15033
+ *
15034
+ * @param memoryId - Memory entry identifier
15035
+ * @returns Promise that resolves when removal is complete
15036
+ */
15037
+ removeMemoryData(memoryId: string): Promise<void>;
15038
+ /**
15039
+ * Iterates all memory entries in the bucket, yielding id + data tuples
15040
+ * for non-removed entries only.
15041
+ *
15042
+ * @returns AsyncGenerator yielding `{ memoryId, data }` tuples
15043
+ */
15044
+ listMemoryData(): AsyncGenerator<{
15045
+ memoryId: string;
15046
+ data: MemoryData;
15047
+ }>;
15048
+ /**
15049
+ * No-op for the default file-based implementation.
15050
+ * Resource cleanup (memo cache invalidation) is handled by PersistMemoryUtils.dispose().
15051
+ */
15052
+ dispose(): void;
15053
+ }
15054
+ /**
15055
+ * Constructor type for IPersistMemoryInstance.
15056
+ * Used by PersistMemoryUtils.usePersistMemoryAdapter() to register custom adapters.
15057
+ */
15058
+ type TPersistMemoryInstanceCtor = new (signalId: string, bucketName: string) => IPersistMemoryInstance;
13871
15059
  /**
13872
15060
  * Utility class for managing memory entry persistence.
13873
15061
  *
@@ -13882,43 +15070,45 @@ type MemoryData = {
13882
15070
  * Used by MemoryPersistInstance for crash-safe memory persistence.
13883
15071
  */
13884
15072
  declare class PersistMemoryUtils {
13885
- private PersistMemoryFactory;
15073
+ /**
15074
+ * Constructor used to create per-context memory instances.
15075
+ * Replaceable via usePersistMemoryAdapter() / useJson() / useDummy().
15076
+ */
15077
+ private PersistMemoryInstanceCtor;
15078
+ /**
15079
+ * Memoized factory creating one IPersistMemoryInstance per (signalId, bucketName) pair.
15080
+ */
13886
15081
  private getMemoryStorage;
13887
15082
  /**
13888
- * Registers a custom persistence adapter.
13889
- *
13890
- * @param Ctor - Custom PersistBase constructor
15083
+ * Registers a custom IPersistMemoryInstance constructor.
15084
+ * Clears the memoization cache so subsequent calls use the new adapter.
13891
15085
  *
13892
- * @example
13893
- * ```typescript
13894
- * class RedisPersist extends PersistBase {
13895
- * async readValue(id) { return JSON.parse(await redis.get(id)); }
13896
- * async writeValue(id, entity) { await redis.set(id, JSON.stringify(entity)); }
13897
- * }
13898
- * PersistMemoryAdapter.usePersistMemoryAdapter(RedisPersist);
13899
- * ```
15086
+ * @param Ctor - Custom IPersistMemoryInstance constructor
13900
15087
  */
13901
- usePersistMemoryAdapter(Ctor: TPersistBaseCtor<string, MemoryData>): void;
15088
+ usePersistMemoryAdapter(Ctor: TPersistMemoryInstanceCtor): void;
13902
15089
  /**
13903
- * Initializes the storage for a given (signalId, bucketName) pair.
15090
+ * Initializes the memory storage for the given context.
15091
+ * Skips initialization when `initial` is false (used to gate first-time setup).
13904
15092
  *
13905
- * @param signalId - Signal identifier (entity folder name)
13906
- * @param bucketName - Bucket name (subfolder under memory/)
15093
+ * @param signalId - Signal identifier
15094
+ * @param bucketName - Bucket name
13907
15095
  * @param initial - Whether this is the first initialization
13908
15096
  * @returns Promise that resolves when initialization is complete
13909
15097
  */
13910
15098
  waitForInit: (signalId: string, bucketName: string, initial: boolean) => Promise<void>;
13911
15099
  /**
13912
- * Reads a memory entry from persistence storage.
15100
+ * Reads a memory entry for the given context and id.
15101
+ * Lazily initializes the instance on first access.
13913
15102
  *
13914
15103
  * @param signalId - Signal identifier
13915
15104
  * @param bucketName - Bucket name
13916
15105
  * @param memoryId - Memory entry identifier
13917
- * @returns Promise resolving to entry data or null if not found
15106
+ * @returns Promise resolving to entry data, or null if not found / soft-deleted
13918
15107
  */
13919
15108
  readMemoryData: (signalId: string, bucketName: string, memoryId: string) => Promise<MemoryData | null>;
13920
15109
  /**
13921
- * Checks if a memory entry exists in persistence storage.
15110
+ * Checks whether a memory entry exists on disk for the given context.
15111
+ * Lazily initializes the instance on first access.
13922
15112
  *
13923
15113
  * @param signalId - Signal identifier
13924
15114
  * @param bucketName - Bucket name
@@ -13927,7 +15117,8 @@ declare class PersistMemoryUtils {
13927
15117
  */
13928
15118
  hasMemoryData: (signalId: string, bucketName: string, memoryId: string) => Promise<boolean>;
13929
15119
  /**
13930
- * Writes a memory entry to disk with atomic file writes.
15120
+ * Writes a memory entry for the given context.
15121
+ * Lazily initializes the instance on first access.
13931
15122
  *
13932
15123
  * @param data - Entry data to persist
13933
15124
  * @param signalId - Signal identifier
@@ -13937,7 +15128,8 @@ declare class PersistMemoryUtils {
13937
15128
  */
13938
15129
  writeMemoryData: (data: MemoryData, signalId: string, bucketName: string, memoryId: string) => Promise<void>;
13939
15130
  /**
13940
- * Marks a memory entry as removed (soft delete — file is kept on disk).
15131
+ * Soft-deletes a memory entry for the given context.
15132
+ * Lazily initializes the instance on first access.
13941
15133
  *
13942
15134
  * @param signalId - Signal identifier
13943
15135
  * @param bucketName - Bucket name
@@ -13946,40 +15138,37 @@ declare class PersistMemoryUtils {
13946
15138
  */
13947
15139
  removeMemoryData: (signalId: string, bucketName: string, memoryId: string) => Promise<void>;
13948
15140
  /**
13949
- * Lists all memory entry IDs for a given (signalId, bucketName) pair.
15141
+ * Iterates all non-removed memory entries for the given context.
13950
15142
  * Used by MemoryPersistInstance to rebuild the BM25 index on init.
15143
+ * Lazily initializes the instance on first access.
13951
15144
  *
13952
15145
  * @param signalId - Signal identifier
13953
15146
  * @param bucketName - Bucket name
13954
- * @returns AsyncGenerator yielding memory entry IDs
15147
+ * @returns AsyncGenerator yielding `{ memoryId, data }` tuples
13955
15148
  */
13956
15149
  listMemoryData(signalId: string, bucketName: string): AsyncGenerator<{
13957
15150
  memoryId: string;
13958
15151
  data: MemoryData;
13959
15152
  }>;
13960
15153
  /**
13961
- * Clears the memoized storage cache.
13962
- * Call this when process.cwd() changes between strategy iterations
13963
- * so new storage instances are created with the updated base path.
15154
+ * Clears the memoized instance cache.
15155
+ * Call when process.cwd() changes between strategy iterations.
13964
15156
  */
13965
15157
  clear: () => void;
13966
15158
  /**
13967
- * Disposes of the memory adapter and releases any resources.
13968
- * Call this when a signal is removed to clean up its associated storage.
15159
+ * Drops the memoized instance for the given context.
15160
+ * Call when a signal is removed to clean up its associated storage entry.
13969
15161
  *
13970
15162
  * @param signalId - Signal identifier
13971
15163
  * @param bucketName - Bucket name
13972
- * @returns void
13973
15164
  */
13974
15165
  dispose: (signalId: string, bucketName: string) => void;
13975
15166
  /**
13976
- * Switches to the default JSON persist adapter.
13977
- * All future persistence writes will use JSON storage.
15167
+ * Switches to the default file-based PersistMemoryInstance.
13978
15168
  */
13979
15169
  useJson(): void;
13980
15170
  /**
13981
- * Switches to a dummy persist adapter that discards all writes.
13982
- * All future persistence writes will be no-ops.
15171
+ * Switches to PersistMemoryDummyInstance (all operations are no-ops).
13983
15172
  */
13984
15173
  useDummy(): void;
13985
15174
  }
@@ -14005,6 +15194,96 @@ declare const PersistMemoryAdapter: PersistMemoryUtils;
14005
15194
  * Stores the latest active signal per context key.
14006
15195
  */
14007
15196
  type RecentData = IPublicSignalRow | null;
15197
+ /**
15198
+ * Per-context recent signal persistence instance interface.
15199
+ * Scoped to a specific (symbol, strategyName, exchangeName, frameName, backtest) tuple.
15200
+ *
15201
+ * Stores the latest active signal for the given context, allowing live/backtest
15202
+ * separation. Custom adapters should implement this interface to override the
15203
+ * default file-based recent signal behavior.
15204
+ */
15205
+ interface IPersistRecentInstance {
15206
+ /**
15207
+ * Initialize storage for this recent signal context.
15208
+ *
15209
+ * @param initial - Whether this is the first initialization
15210
+ * @returns Promise that resolves when initialization is complete
15211
+ */
15212
+ waitForInit(initial: boolean): Promise<void>;
15213
+ /**
15214
+ * Read the latest persisted recent signal for this context.
15215
+ *
15216
+ * @returns Promise resolving to recent signal or null if none persisted
15217
+ */
15218
+ readRecentData(): Promise<IPublicSignalRow | null>;
15219
+ /**
15220
+ * Write the latest recent signal for this context.
15221
+ *
15222
+ * @param signalRow - Recent signal data to persist
15223
+ * @returns Promise that resolves when write is complete
15224
+ */
15225
+ writeRecentData(signalRow: IPublicSignalRow): Promise<void>;
15226
+ }
15227
+ /**
15228
+ * Default file-based implementation of IPersistRecentInstance.
15229
+ *
15230
+ * Features:
15231
+ * - Wraps PersistBase for atomic JSON writes
15232
+ * - Uses symbol as entity ID within a per-context PersistBase
15233
+ * - Context key includes backtest/live mode and optional frameName
15234
+ *
15235
+ * @example
15236
+ * ```typescript
15237
+ * const instance = new PersistRecentInstance("BTCUSDT", "my-strategy", "binance", "frame-1", false);
15238
+ * await instance.waitForInit(true);
15239
+ * await instance.writeRecentData(publicSignalRow);
15240
+ * const recent = await instance.readRecentData();
15241
+ * ```
15242
+ */
15243
+ declare class PersistRecentInstance implements IPersistRecentInstance {
15244
+ readonly symbol: string;
15245
+ readonly strategyName: StrategyName;
15246
+ readonly exchangeName: ExchangeName;
15247
+ readonly frameName: FrameName;
15248
+ readonly backtest: boolean;
15249
+ /** Underlying file-based storage scoped to this context */
15250
+ private readonly _storage;
15251
+ /**
15252
+ * Creates new recent signal persistence instance.
15253
+ *
15254
+ * @param symbol - Trading pair symbol
15255
+ * @param strategyName - Strategy identifier
15256
+ * @param exchangeName - Exchange identifier
15257
+ * @param frameName - Frame identifier (may be empty for live mode)
15258
+ * @param backtest - True for backtest mode, false for live mode
15259
+ */
15260
+ constructor(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean);
15261
+ /**
15262
+ * Initializes the underlying PersistBase storage.
15263
+ *
15264
+ * @param initial - Whether this is the first initialization
15265
+ * @returns Promise that resolves when initialization is complete
15266
+ */
15267
+ waitForInit(initial: boolean): Promise<void>;
15268
+ /**
15269
+ * Reads the persisted recent signal using `symbol` as the entity key.
15270
+ *
15271
+ * @returns Promise resolving to recent signal or null if not found
15272
+ */
15273
+ readRecentData(): Promise<IPublicSignalRow | null>;
15274
+ /**
15275
+ * Writes the recent signal using `symbol` as the entity key.
15276
+ *
15277
+ * @param signalRow - Recent signal data to persist
15278
+ * @returns Promise that resolves when write is complete
15279
+ */
15280
+ writeRecentData(signalRow: IPublicSignalRow): Promise<void>;
15281
+ }
15282
+ /**
15283
+ * Constructor type for IPersistRecentInstance.
15284
+ * Used by PersistRecentUtils.usePersistRecentAdapter() to register custom adapters.
15285
+ */
15286
+ type TPersistRecentInstanceCtor = new (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean) => IPersistRecentInstance;
14008
15287
  /**
14009
15288
  * Utility class for managing recent signal persistence.
14010
15289
  *
@@ -14017,55 +15296,70 @@ type RecentData = IPublicSignalRow | null;
14017
15296
  * Used by RecentPersistBacktestUtils/RecentPersistLiveUtils for recent signal persistence.
14018
15297
  */
14019
15298
  declare class PersistRecentUtils {
14020
- private PersistRecentFactory;
14021
- private getStorage;
14022
- private createKeyParts;
14023
15299
  /**
14024
- * Registers a custom persistence adapter.
15300
+ * Constructor used to create per-context recent signal instances.
15301
+ * Replaceable via usePersistRecentAdapter() / useJson() / useDummy().
15302
+ */
15303
+ private PersistRecentInstanceCtor;
15304
+ /**
15305
+ * Builds the composite memoization key for a recent signal context.
15306
+ * Includes optional frameName and the backtest/live mode flag.
14025
15307
  *
14026
- * @param Ctor - Custom PersistBase constructor
15308
+ * @param symbol - Trading pair symbol
15309
+ * @param strategyName - Strategy identifier
15310
+ * @param exchangeName - Exchange identifier
15311
+ * @param frameName - Frame identifier (omitted from key if empty)
15312
+ * @param backtest - True for backtest mode, false for live mode
15313
+ * @returns Composite key string
15314
+ */
15315
+ private createKey;
15316
+ /**
15317
+ * Memoized factory creating one IPersistRecentInstance per context tuple.
14027
15318
  */
14028
- usePersistRecentAdapter(Ctor: TPersistBaseCtor<string, IPublicSignalRow>): void;
15319
+ private getStorage;
14029
15320
  /**
14030
- * Reads the latest persisted recent signal for a given context.
15321
+ * Registers a custom IPersistRecentInstance constructor.
15322
+ * Clears the memoization cache so subsequent calls use the new adapter.
14031
15323
  *
14032
- * Returns null if no recent signal exists.
15324
+ * @param Ctor - Custom IPersistRecentInstance constructor
15325
+ */
15326
+ usePersistRecentAdapter(Ctor: TPersistRecentInstanceCtor): void;
15327
+ /**
15328
+ * Reads the latest recent signal for the given context.
15329
+ * Lazily initializes the instance on first access.
14033
15330
  *
14034
15331
  * @param symbol - Trading pair symbol
14035
15332
  * @param strategyName - Strategy identifier
14036
15333
  * @param exchangeName - Exchange identifier
14037
- * @param frameName - Frame identifier
14038
- * @returns Promise resolving to recent signal or null
15334
+ * @param frameName - Frame identifier (may be empty)
15335
+ * @param backtest - True for backtest mode, false for live mode
15336
+ * @returns Promise resolving to recent signal or null if none persisted
14039
15337
  */
14040
15338
  readRecentData: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean) => Promise<IPublicSignalRow | null>;
14041
15339
  /**
14042
- * Writes the latest recent signal to disk with atomic file writes.
14043
- *
14044
- * Uses symbol as the entity ID within the per-context storage instance.
14045
- * Uses atomic writes to prevent corruption on crashes.
15340
+ * Writes the latest recent signal for the given context.
15341
+ * Lazily initializes the instance on first access.
14046
15342
  *
14047
15343
  * @param signalRow - Recent signal data to persist
14048
15344
  * @param symbol - Trading pair symbol
14049
15345
  * @param strategyName - Strategy identifier
14050
15346
  * @param exchangeName - Exchange identifier
14051
- * @param frameName - Frame identifier
15347
+ * @param frameName - Frame identifier (may be empty)
15348
+ * @param backtest - True for backtest mode, false for live mode
14052
15349
  * @returns Promise that resolves when write is complete
14053
15350
  */
14054
15351
  writeRecentData: (signalRow: IPublicSignalRow, symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean) => Promise<void>;
14055
15352
  /**
14056
- * Clears the memoized storage cache.
14057
- * Call this when process.cwd() changes between strategy iterations
14058
- * so new storage instances are created with the updated base path.
15353
+ * Clears the memoized instance cache.
15354
+ * Call when process.cwd() changes between strategy iterations.
14059
15355
  */
14060
15356
  clear(): void;
14061
15357
  /**
14062
- * Switches to the default JSON persist adapter.
14063
- * All future persistence writes will use JSON storage.
15358
+ * Switches to the default file-based PersistRecentInstance.
14064
15359
  */
14065
15360
  useJson(): void;
14066
15361
  /**
14067
- * Switches to a dummy persist adapter that discards all writes.
14068
- * All future persistence writes will be no-ops.
15362
+ * Switches to PersistRecentDummyInstance (all operations are no-ops).
14069
15363
  */
14070
15364
  useDummy(): void;
14071
15365
  }
@@ -14082,6 +15376,100 @@ type StateData = {
14082
15376
  id: string;
14083
15377
  data: object;
14084
15378
  };
15379
+ /**
15380
+ * Per-context state persistence instance interface.
15381
+ * Scoped to a specific (signalId, bucketName) pair.
15382
+ *
15383
+ * Used by StatePersistInstance for crash-safe strategy state storage.
15384
+ * Custom adapters should implement this interface to override the default
15385
+ * file-based state behavior.
15386
+ */
15387
+ interface IPersistStateInstance {
15388
+ /**
15389
+ * Initialize storage for this state context.
15390
+ *
15391
+ * @param initial - Whether this is the first initialization
15392
+ * @returns Promise that resolves when initialization is complete
15393
+ */
15394
+ waitForInit(initial: boolean): Promise<void>;
15395
+ /**
15396
+ * Read persisted state for this context.
15397
+ *
15398
+ * @returns Promise resolving to state data or null if none persisted
15399
+ */
15400
+ readStateData(): Promise<StateData | null>;
15401
+ /**
15402
+ * Write state for this context.
15403
+ *
15404
+ * @param data - State data to persist
15405
+ * @returns Promise that resolves when write is complete
15406
+ */
15407
+ writeStateData(data: StateData): Promise<void>;
15408
+ /**
15409
+ * Release any resources held by this instance.
15410
+ * Default implementations may treat this as a no-op.
15411
+ */
15412
+ dispose(): void;
15413
+ }
15414
+ /**
15415
+ * Default file-based implementation of IPersistStateInstance.
15416
+ *
15417
+ * Features:
15418
+ * - Wraps PersistBase for atomic JSON writes
15419
+ * - Uses bucketName as entity ID within a per-signal PersistBase
15420
+ * - dispose is a no-op (memo cache is managed by PersistStateUtils)
15421
+ *
15422
+ * @example
15423
+ * ```typescript
15424
+ * const instance = new PersistStateInstance("signal-1", "counter");
15425
+ * await instance.waitForInit(true);
15426
+ * await instance.writeStateData({ id: "counter", data: { count: 1 } });
15427
+ * const state = await instance.readStateData();
15428
+ * ```
15429
+ */
15430
+ declare class PersistStateInstance implements IPersistStateInstance {
15431
+ readonly signalId: string;
15432
+ readonly bucketName: string;
15433
+ /** Underlying file-based storage scoped to this context */
15434
+ private readonly _storage;
15435
+ /**
15436
+ * Creates new state persistence instance.
15437
+ *
15438
+ * @param signalId - Signal identifier (folder name under state/)
15439
+ * @param bucketName - Bucket name (file name)
15440
+ */
15441
+ constructor(signalId: string, bucketName: string);
15442
+ /**
15443
+ * Initializes the underlying PersistBase storage.
15444
+ *
15445
+ * @param initial - Whether this is the first initialization
15446
+ * @returns Promise that resolves when initialization is complete
15447
+ */
15448
+ waitForInit(initial: boolean): Promise<void>;
15449
+ /**
15450
+ * Reads the persisted state using `bucketName` as the entity key.
15451
+ *
15452
+ * @returns Promise resolving to state data or null if not found
15453
+ */
15454
+ readStateData(): Promise<StateData | null>;
15455
+ /**
15456
+ * Writes the state using `bucketName` as the entity key.
15457
+ *
15458
+ * @param data - State data to persist
15459
+ * @returns Promise that resolves when write is complete
15460
+ */
15461
+ writeStateData(data: StateData): Promise<void>;
15462
+ /**
15463
+ * No-op for the default file-based implementation.
15464
+ * Resource cleanup (memo cache invalidation) is handled by PersistStateUtils.dispose().
15465
+ */
15466
+ dispose(): void;
15467
+ }
15468
+ /**
15469
+ * Constructor type for IPersistStateInstance.
15470
+ * Used by PersistStateUtils.usePersistStateAdapter() to register custom adapters.
15471
+ */
15472
+ type TPersistStateInstanceCtor = new (signalId: string, bucketName: string) => IPersistStateInstance;
14085
15473
  /**
14086
15474
  * Utility class for managing state persistence.
14087
15475
  *
@@ -14095,57 +15483,67 @@ type StateData = {
14095
15483
  * Used by StatePersistInstance for crash-safe state persistence.
14096
15484
  */
14097
15485
  declare class PersistStateUtils {
14098
- private PersistStateFactory;
15486
+ /**
15487
+ * Constructor used to create per-context state instances.
15488
+ * Replaceable via usePersistStateAdapter() / useJson() / useDummy().
15489
+ */
15490
+ private PersistStateInstanceCtor;
15491
+ /**
15492
+ * Memoized factory creating one IPersistStateInstance per (signalId, bucketName) pair.
15493
+ */
14099
15494
  private getStateStorage;
14100
15495
  /**
14101
- * Registers a custom persistence adapter.
15496
+ * Registers a custom IPersistStateInstance constructor.
15497
+ * Clears the memoization cache so subsequent calls use the new adapter.
14102
15498
  *
14103
- * @param Ctor - Custom PersistBase constructor
15499
+ * @param Ctor - Custom IPersistStateInstance constructor
14104
15500
  */
14105
- usePersistStateAdapter(Ctor: TPersistBaseCtor<string, StateData>): void;
15501
+ usePersistStateAdapter(Ctor: TPersistStateInstanceCtor): void;
14106
15502
  /**
14107
- * Initializes the storage for a given (signalId, bucketName) pair.
15503
+ * Initializes the state storage for the given context.
15504
+ * Skips initialization when `initial` is false (used to gate first-time setup).
14108
15505
  *
14109
15506
  * @param signalId - Signal identifier
14110
15507
  * @param bucketName - Bucket name
14111
15508
  * @param initial - Whether this is the first initialization
15509
+ * @returns Promise that resolves when initialization is complete
14112
15510
  */
14113
15511
  waitForInit: (signalId: string, bucketName: string, initial: boolean) => Promise<void>;
14114
15512
  /**
14115
- * Reads a state entry from persistence storage.
15513
+ * Reads persisted state for the given context.
15514
+ * Lazily initializes the instance on first access.
14116
15515
  *
14117
15516
  * @param signalId - Signal identifier
14118
15517
  * @param bucketName - Bucket name
14119
- * @returns Promise resolving to entry data or null if not found
15518
+ * @returns Promise resolving to state data or null if none persisted
14120
15519
  */
14121
15520
  readStateData: (signalId: string, bucketName: string) => Promise<StateData | null>;
14122
15521
  /**
14123
- * Writes a state entry to disk with atomic file writes.
15522
+ * Writes state for the given context.
15523
+ * Lazily initializes the instance on first access.
14124
15524
  *
14125
- * @param data - Entry data to persist
15525
+ * @param data - State data to persist
14126
15526
  * @param signalId - Signal identifier
14127
15527
  * @param bucketName - Bucket name
15528
+ * @returns Promise that resolves when write is complete
14128
15529
  */
14129
15530
  writeStateData: (data: StateData, signalId: string, bucketName: string) => Promise<void>;
14130
15531
  /**
14131
- * Switches to a dummy persist adapter that discards all writes.
14132
- * All future persistence writes will be no-ops.
15532
+ * Switches to PersistStateDummyInstance (all operations are no-ops).
14133
15533
  */
14134
15534
  useDummy: () => void;
14135
15535
  /**
14136
- * Switches to the default JSON persist adapter.
14137
- * All future persistence writes will use JSON storage.
15536
+ * Switches to the default file-based PersistStateInstance.
14138
15537
  */
14139
15538
  useJson: () => void;
14140
15539
  /**
14141
- * Clears the memoized storage cache.
14142
- * Call this when process.cwd() changes between strategy iterations
14143
- * so new storage instances are created with the updated base path.
15540
+ * Clears the memoized instance cache.
15541
+ * Call when process.cwd() changes between strategy iterations.
14144
15542
  */
14145
15543
  clear: () => void;
14146
15544
  /**
14147
- * Disposes of the state adapter and releases any resources.
14148
- * Call this when a signal is removed to clean up its associated storage.
15545
+ * Drops the memoized instance for the given context.
15546
+ * Call when a signal is removed to clean up its associated storage entry.
14149
15547
  *
14150
15548
  * @param signalId - Signal identifier
14151
15549
  * @param bucketName - Bucket name
@@ -14165,6 +15563,102 @@ type SessionData = {
14165
15563
  id: string;
14166
15564
  data: object | null;
14167
15565
  };
15566
+ /**
15567
+ * Per-context session persistence instance interface.
15568
+ * Scoped to a specific (strategyName, exchangeName, frameName) triple.
15569
+ *
15570
+ * Used by SessionPersistInstance for crash-safe session storage.
15571
+ * Custom adapters should implement this interface to override the default
15572
+ * file-based session behavior.
15573
+ */
15574
+ interface IPersistSessionInstance {
15575
+ /**
15576
+ * Initialize storage for this session context.
15577
+ *
15578
+ * @param initial - Whether this is the first initialization
15579
+ * @returns Promise that resolves when initialization is complete
15580
+ */
15581
+ waitForInit(initial: boolean): Promise<void>;
15582
+ /**
15583
+ * Read persisted session data for this context.
15584
+ *
15585
+ * @returns Promise resolving to session data or null if none persisted
15586
+ */
15587
+ readSessionData(): Promise<SessionData | null>;
15588
+ /**
15589
+ * Write session data for this context.
15590
+ *
15591
+ * @param data - Session data to persist
15592
+ * @returns Promise that resolves when write is complete
15593
+ */
15594
+ writeSessionData(data: SessionData): Promise<void>;
15595
+ /**
15596
+ * Release any resources held by this instance.
15597
+ * Default implementations may treat this as a no-op.
15598
+ */
15599
+ dispose(): void;
15600
+ }
15601
+ /**
15602
+ * Default file-based implementation of IPersistSessionInstance.
15603
+ *
15604
+ * Features:
15605
+ * - Wraps PersistBase for atomic JSON writes
15606
+ * - Uses frameName as entity ID within a per-strategy/exchange PersistBase
15607
+ * - dispose is a no-op (memo cache is managed by PersistSessionUtils)
15608
+ *
15609
+ * @example
15610
+ * ```typescript
15611
+ * const instance = new PersistSessionInstance("my-strategy", "binance", "frame-1");
15612
+ * await instance.waitForInit(true);
15613
+ * await instance.writeSessionData({ id: "frame-1", data: { session: "state" } });
15614
+ * const session = await instance.readSessionData();
15615
+ * ```
15616
+ */
15617
+ declare class PersistSessionInstance implements IPersistSessionInstance {
15618
+ readonly strategyName: string;
15619
+ readonly exchangeName: string;
15620
+ readonly frameName: string;
15621
+ /** Underlying file-based storage scoped to this context */
15622
+ private readonly _storage;
15623
+ /**
15624
+ * Creates new session persistence instance.
15625
+ *
15626
+ * @param strategyName - Strategy identifier
15627
+ * @param exchangeName - Exchange identifier
15628
+ * @param frameName - Frame identifier (also used as entity ID)
15629
+ */
15630
+ constructor(strategyName: string, exchangeName: string, frameName: string);
15631
+ /**
15632
+ * Initializes the underlying PersistBase storage.
15633
+ *
15634
+ * @param initial - Whether this is the first initialization
15635
+ * @returns Promise that resolves when initialization is complete
15636
+ */
15637
+ waitForInit(initial: boolean): Promise<void>;
15638
+ /**
15639
+ * Reads the persisted session data using `frameName` as the entity key.
15640
+ *
15641
+ * @returns Promise resolving to session data or null if not found
15642
+ */
15643
+ readSessionData(): Promise<SessionData | null>;
15644
+ /**
15645
+ * Writes the session data using `frameName` as the entity key.
15646
+ *
15647
+ * @param data - Session data to persist
15648
+ * @returns Promise that resolves when write is complete
15649
+ */
15650
+ writeSessionData(data: SessionData): Promise<void>;
15651
+ /**
15652
+ * No-op for the default file-based implementation.
15653
+ * Resource cleanup (memo cache invalidation) is handled by PersistSessionUtils.dispose().
15654
+ */
15655
+ dispose(): void;
15656
+ }
15657
+ /**
15658
+ * Constructor type for IPersistSessionInstance.
15659
+ * Used by PersistSessionUtils.usePersistSessionAdapter() to register custom adapters.
15660
+ */
15661
+ type TPersistSessionInstanceCtor = new (strategyName: string, exchangeName: string, frameName: string) => IPersistSessionInstance;
14168
15662
  /**
14169
15663
  * Utility class for managing session persistence.
14170
15664
  *
@@ -14178,60 +15672,71 @@ type SessionData = {
14178
15672
  * Used by SessionPersistInstance for crash-safe session persistence.
14179
15673
  */
14180
15674
  declare class PersistSessionUtils {
14181
- private PersistSessionFactory;
15675
+ /**
15676
+ * Constructor used to create per-context session instances.
15677
+ * Replaceable via usePersistSessionAdapter() / useJson() / useDummy().
15678
+ */
15679
+ private PersistSessionInstanceCtor;
15680
+ /**
15681
+ * Memoized factory creating one IPersistSessionInstance per
15682
+ * (strategyName, exchangeName, frameName) triple.
15683
+ */
14182
15684
  private getSessionStorage;
14183
15685
  /**
14184
- * Registers a custom persistence adapter.
15686
+ * Registers a custom IPersistSessionInstance constructor.
15687
+ * Clears the memoization cache so subsequent calls use the new adapter.
14185
15688
  *
14186
- * @param Ctor - Custom PersistBase constructor
15689
+ * @param Ctor - Custom IPersistSessionInstance constructor
14187
15690
  */
14188
- usePersistSessionAdapter(Ctor: TPersistBaseCtor<string, SessionData>): void;
15691
+ usePersistSessionAdapter(Ctor: TPersistSessionInstanceCtor): void;
14189
15692
  /**
14190
- * Initializes the storage for a given (strategyName, exchangeName, frameName) triple.
15693
+ * Initializes the session storage for the given context.
15694
+ * Skips initialization when `initial` is false (used to gate first-time setup).
14191
15695
  *
14192
15696
  * @param strategyName - Strategy identifier
14193
15697
  * @param exchangeName - Exchange identifier
14194
15698
  * @param frameName - Frame identifier
14195
15699
  * @param initial - Whether this is the first initialization
15700
+ * @returns Promise that resolves when initialization is complete
14196
15701
  */
14197
15702
  waitForInit: (strategyName: string, exchangeName: string, frameName: string, initial: boolean) => Promise<void>;
14198
15703
  /**
14199
- * Reads a session entry from persistence storage.
15704
+ * Reads persisted session data for the given context.
15705
+ * Lazily initializes the instance on first access.
14200
15706
  *
14201
15707
  * @param strategyName - Strategy identifier
14202
15708
  * @param exchangeName - Exchange identifier
14203
15709
  * @param frameName - Frame identifier
14204
- * @returns Promise resolving to entry data or null if not found
15710
+ * @returns Promise resolving to session data or null if none persisted
14205
15711
  */
14206
15712
  readSessionData: (strategyName: string, exchangeName: string, frameName: string) => Promise<SessionData | null>;
14207
15713
  /**
14208
- * Writes a session entry to disk with atomic file writes.
15714
+ * Writes session data for the given context.
15715
+ * Lazily initializes the instance on first access.
14209
15716
  *
14210
- * @param data - Entry data to persist
15717
+ * @param data - Session data to persist
14211
15718
  * @param strategyName - Strategy identifier
14212
15719
  * @param exchangeName - Exchange identifier
14213
15720
  * @param frameName - Frame identifier
15721
+ * @returns Promise that resolves when write is complete
14214
15722
  */
14215
15723
  writeSessionData: (data: SessionData, strategyName: string, exchangeName: string, frameName: string) => Promise<void>;
14216
15724
  /**
14217
- * Switches to a dummy persist adapter that discards all writes.
14218
- * All future persistence writes will be no-ops.
15725
+ * Switches to PersistSessionDummyInstance (all operations are no-ops).
14219
15726
  */
14220
15727
  useDummy: () => void;
14221
15728
  /**
14222
- * Switches to the default JSON persist adapter.
14223
- * All future persistence writes will use JSON storage.
15729
+ * Switches to the default file-based PersistSessionInstance.
14224
15730
  */
14225
15731
  useJson: () => void;
14226
15732
  /**
14227
- * Clears the memoized storage cache.
14228
- * Call this when process.cwd() changes between strategy iterations
14229
- * so new storage instances are created with the updated base path.
15733
+ * Clears the memoized instance cache.
15734
+ * Call when process.cwd() changes between strategy iterations.
14230
15735
  */
14231
15736
  clear: () => void;
14232
15737
  /**
14233
- * Disposes of the session adapter and releases any resources.
14234
- * Call this when a session is removed to clean up its associated storage.
15738
+ * Drops the memoized instance for the given context.
15739
+ * Call when a session is removed to clean up its associated storage entry.
14235
15740
  *
14236
15741
  * @param strategyName - Strategy identifier
14237
15742
  * @param exchangeName - Exchange identifier
@@ -27309,7 +28814,33 @@ declare class ClientRisk implements IRisk {
27309
28814
  * @param params - Risk check arguments (passthrough from ClientStrategy)
27310
28815
  * @returns Promise resolving to true if allowed, false if rejected
27311
28816
  */
27312
- checkSignal: (params: IRiskCheckArgs) => Promise<boolean>;
28817
+ checkSignal: (params: IRiskCheckArgs, options?: Partial<IRiskCheckOptions>) => Promise<boolean>;
28818
+ /**
28819
+ * Concurrency-safe variant of {@link checkSignal}: validates the signal AND
28820
+ * reserves a placeholder slot in the active position map atomically.
28821
+ *
28822
+ * **Why this exists.** `checkSignal` followed later by `addSignal` is not
28823
+ * atomic — between the two calls the caller does signal setup work that
28824
+ * yields to the event loop (sync-open callback, persist writes, etc.). When
28825
+ * several strategies sharing the same risk profile run in parallel, all of
28826
+ * them can pass `checkSignal` while the active position map is still empty,
28827
+ * then each call `addSignal` and blow past the limit. Reserving inside the
28828
+ * lock guarantees the next concurrent caller observes the incremented size
28829
+ * before its own validation runs.
28830
+ *
28831
+ * The reservation uses the same map key as the eventual `addSignal` call
28832
+ * (`strategyName + exchangeName + symbol`), so `addSignal` overwrites the
28833
+ * placeholder rather than appending a duplicate.
28834
+ *
28835
+ * Callers MUST ensure that every successful return is followed by either
28836
+ * `addSignal` (overwrites the placeholder with real data) or `removeSignal`
28837
+ * (clears the placeholder if opening is aborted). Otherwise the riskMap
28838
+ * accumulates stale reservations.
28839
+ *
28840
+ * @param params - Risk check arguments (passthrough from ClientStrategy)
28841
+ * @returns Promise resolving to true if allowed (and reserved), false if rejected (no reservation)
28842
+ */
28843
+ checkSignalAndReserve: (params: IRiskCheckArgs) => Promise<boolean>;
27313
28844
  }
27314
28845
 
27315
28846
  /**
@@ -27728,6 +29259,26 @@ declare class RiskConnectionService implements TRisk$1 {
27728
29259
  exchangeName: ExchangeName;
27729
29260
  frameName: FrameName;
27730
29261
  backtest: boolean;
29262
+ }, options?: Partial<IRiskCheckOptions>) => Promise<boolean>;
29263
+ /**
29264
+ * Concurrency-safe variant of {@link checkSignal} — validates the signal AND
29265
+ * reserves a placeholder in the active position map atomically.
29266
+ *
29267
+ * Routes to the same ClientRisk instance as {@link checkSignal} but delegates
29268
+ * to its `checkSignalAndReserve` method. Use from execution paths where the
29269
+ * caller will follow up with `addSignal` on success — guarantees concurrent
29270
+ * callers cannot all pass validation against a stale empty map. See
29271
+ * {@link IRisk.checkSignalAndReserve} for the full rationale.
29272
+ *
29273
+ * @param params - Risk check arguments (portfolio state, position details)
29274
+ * @param payload - Execution payload with risk name, exchangeName, frameName and backtest mode
29275
+ * @returns Promise resolving to true if allowed (and reserved), false if rejected (no reservation)
29276
+ */
29277
+ checkSignalAndReserve: (params: IRiskCheckArgs, payload: {
29278
+ riskName: RiskName;
29279
+ exchangeName: ExchangeName;
29280
+ frameName: FrameName;
29281
+ backtest: boolean;
27731
29282
  }) => Promise<boolean>;
27732
29283
  /**
27733
29284
  * Registers an opened signal with the risk management system.
@@ -31404,6 +32955,25 @@ declare class RiskGlobalService implements TRisk {
31404
32955
  exchangeName: ExchangeName;
31405
32956
  frameName: FrameName;
31406
32957
  backtest: boolean;
32958
+ }, options?: Partial<IRiskCheckOptions>) => Promise<boolean>;
32959
+ /**
32960
+ * Concurrency-safe variant of {@link checkSignal} — validates the signal AND
32961
+ * reserves a placeholder in the active position map atomically.
32962
+ *
32963
+ * Use from strategy execution paths where the caller will follow up with
32964
+ * `addSignal` on success — guarantees concurrent callers cannot all pass
32965
+ * validation against a stale empty map. See {@link IRisk.checkSignalAndReserve}
32966
+ * for the full rationale.
32967
+ *
32968
+ * @param params - Risk check arguments (portfolio state, position details)
32969
+ * @param payload - Execution payload with risk name, exchangeName, frameName and backtest mode
32970
+ * @returns Promise resolving to true if allowed (and reserved), false if rejected (no reservation)
32971
+ */
32972
+ checkSignalAndReserve: (params: IRiskCheckArgs, payload: {
32973
+ riskName: RiskName;
32974
+ exchangeName: ExchangeName;
32975
+ frameName: FrameName;
32976
+ backtest: boolean;
31407
32977
  }) => Promise<boolean>;
31408
32978
  /**
31409
32979
  * Registers an opened signal with the risk management system.
@@ -34157,4 +35727,4 @@ declare const getTotalClosed: (signal: Signal) => {
34157
35727
  remainingCostBasis: number;
34158
35728
  };
34159
35729
 
34160
- export { ActionBase, type ActivateScheduledCommit, type ActivateScheduledCommitNotification, type ActivePingContract, type AverageBuyCommit, type AverageBuyCommitNotification, Backtest, type BacktestStatisticsModel, Breakeven, type BreakevenAvailableNotification, type BreakevenCommit, type BreakevenCommitNotification, type BreakevenContract, type BreakevenData, type BreakevenEvent, type BreakevenStatisticsModel, Broker, type BrokerAverageBuyPayload, BrokerBase, type BrokerBreakevenPayload, type BrokerPartialLossPayload, type BrokerPartialProfitPayload, type BrokerSignalClosePayload, type BrokerSignalOpenPayload, type BrokerTrailingStopPayload, type BrokerTrailingTakePayload, Cache, type CancelScheduledCommit, type CancelScheduledCommitNotification, type CandleData, type CandleInterval, type ClosePendingCommit, type ClosePendingCommitNotification, type ColumnConfig, type ColumnModel, type CommitPayload, Constant, type CriticalErrorNotification, type DoneContract, Dump, type EntityId, Exchange, ExecutionContextService, type FrameInterval, type GlobalConfig, Heat, type HeatmapStatisticsModel, HighestProfit, type HighestProfitContract, type HighestProfitEvent, type HighestProfitStatisticsModel, type IActionSchema, type IActivateScheduledCommitRow, type IAggregatedTradeData, type IBidData, type IBreakevenCommitRow, type IBroker, type ICandleData, type ICommitRow, type IDumpContext, type IDumpInstance, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type ILog, type ILogEntry, type ILogger, type IMarkdownDumpOptions, type IMemoryInstance, type INotificationUtils, type IOrderBookData, type IPartialLossCommitRow, type IPartialProfitCommitRow, type IPersistBase, type IPositionSizeATRParams, type IPositionSizeFixedPercentageParams, type IPositionSizeKellyParams, type IPublicAction, type IPublicCandleData, type IPublicSignalRow, type IRecentUtils, type IReportDumpOptions, type IRiskActivePosition, type IRiskCheckArgs, type IRiskSchema, type IRiskSignalRow, type IRiskValidation, type IRiskValidationFn, type IRiskValidationPayload, type IScheduledSignalCancelRow, type IScheduledSignalRow, type ISessionInstance, type ISignalDto, type ISignalIntervalDto, type ISignalRow, type ISizingCalculateParams, type ISizingCalculateParamsATR, type ISizingCalculateParamsFixedPercentage, type ISizingCalculateParamsKelly, type ISizingParams, type ISizingParamsATR, type ISizingParamsFixedPercentage, type ISizingParamsKelly, type ISizingSchema, type ISizingSchemaATR, type ISizingSchemaFixedPercentage, type ISizingSchemaKelly, type IStateInstance, type IStorageSignalRow, type IStorageUtils, type IStrategyPnL, type IStrategyResult, type IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultCancelled, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, type IStrategyTickResultScheduled, type IStrategyTickResultWaiting, type ITrailingStopCommitRow, type ITrailingTakeCommitRow, type IWalkerResults, type IWalkerSchema, type IWalkerStrategyResult, type IdlePingContract, type InfoErrorNotification, Interval, type IntervalData, Live, type LiveStatisticsModel, Log, type LogData, Markdown, MarkdownFileBase, MarkdownFolderBase, type MarkdownName, MarkdownWriter, MaxDrawdown, type MaxDrawdownContract, type MaxDrawdownEvent, type MaxDrawdownStatisticsModel, type MeasureData, Memory, MemoryBacktest, MemoryBacktestAdapter, type MemoryData, MemoryLive, MemoryLiveAdapter, type MessageModel, type MessageRole, type MessageToolCall, MethodContextService, type MetricStats, Notification, NotificationBacktest, type NotificationData, NotificationLive, type NotificationModel, Partial$1 as Partial, type PartialData, type PartialEvent, type PartialLossAvailableNotification, type PartialLossCommit, type PartialLossCommitNotification, type PartialLossContract, type PartialProfitAvailableNotification, type PartialProfitCommit, type PartialProfitCommitNotification, type PartialProfitContract, type PartialStatisticsModel, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatisticsModel, PersistBase, PersistBreakevenAdapter, PersistCandleAdapter, PersistIntervalAdapter, PersistLogAdapter, PersistMeasureAdapter, PersistMemoryAdapter, PersistNotificationAdapter, PersistPartialAdapter, PersistRecentAdapter, PersistRiskAdapter, PersistScheduleAdapter, PersistSessionAdapter, PersistSignalAdapter, PersistStateAdapter, PersistStorageAdapter, Position, PositionSize, type ProgressBacktestContract, type ProgressWalkerContract, Recent, RecentBacktest, type RecentData, RecentLive, Reflect, Report, ReportBase, type ReportName, ReportWriter, Risk, type RiskContract, type RiskData, type RiskEvent, type RiskRejectionNotification, type RiskStatisticsModel, Schedule, type ScheduleData, type SchedulePingContract, type ScheduleStatisticsModel, type ScheduledEvent, Session, SessionBacktest, type SessionData, SessionLive, type SignalCancelledNotification, type SignalCloseContract, type SignalClosedNotification, type SignalData, type SignalInfoContract, type SignalInfoNotification, type SignalInterval, type SignalOpenContract, type SignalOpenedNotification, type SignalScheduledNotification, type SignalSyncCloseNotification, type SignalSyncContract, type SignalSyncOpenNotification, State, StateBacktest, StateBacktestAdapter, type StateData, StateLive, StateLiveAdapter, Storage, StorageBacktest, type StorageData, StorageLive, Strategy, type StrategyActionType, type StrategyCancelReason, type StrategyCloseReason, type StrategyCommitContract, type StrategyEvent, type StrategyStatisticsModel, Sync, type SyncEvent, type SyncStatisticsModel, System, type TBrokerCtor, type TDumpInstanceCtor, type TLogCtor, type TMarkdownBase, type TMemoryInstanceCtor, type TNotificationUtilsCtor, type TPersistBase, type TPersistBaseCtor, type TRecentUtilsCtor, type TReportBase, type TSessionInstanceCtor, type TStateInstanceCtor, type TStorageUtilsCtor, type TickEvent, type TrailingStopCommit, type TrailingStopCommitNotification, type TrailingTakeCommit, type TrailingTakeCommitNotification, type ValidationErrorNotification, Walker, type WalkerCompleteContract, type WalkerContract, type WalkerMetric, type SignalData$1 as WalkerSignalData, type WalkerStatisticsModel, 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, getClosePrice, 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 };
35730
+ export { ActionBase, type ActivateScheduledCommit, type ActivateScheduledCommitNotification, type ActivePingContract, type AverageBuyCommit, type AverageBuyCommitNotification, Backtest, type BacktestStatisticsModel, Breakeven, type BreakevenAvailableNotification, type BreakevenCommit, type BreakevenCommitNotification, type BreakevenContract, type BreakevenData, type BreakevenEvent, type BreakevenStatisticsModel, Broker, type BrokerAverageBuyPayload, BrokerBase, type BrokerBreakevenPayload, type BrokerPartialLossPayload, type BrokerPartialProfitPayload, type BrokerSignalClosePayload, type BrokerSignalOpenPayload, type BrokerTrailingStopPayload, type BrokerTrailingTakePayload, Cache, type CancelScheduledCommit, type CancelScheduledCommitNotification, type CandleData, type CandleInterval, type ClosePendingCommit, type ClosePendingCommitNotification, type ColumnConfig, type ColumnModel, type CommitPayload, Constant, type CriticalErrorNotification, type DoneContract, Dump, type EntityId, Exchange, ExecutionContextService, type FrameInterval, type GlobalConfig, Heat, type HeatmapStatisticsModel, HighestProfit, type HighestProfitContract, type HighestProfitEvent, type HighestProfitStatisticsModel, type IActionSchema, type IActivateScheduledCommitRow, type IAggregatedTradeData, type IBidData, type IBreakevenCommitRow, type IBroker, type ICandleData, type ICommitRow, type IDumpContext, type IDumpInstance, type IExchangeSchema, type IFrameSchema, type IHeatmapRow, type ILog, type ILogEntry, type ILogger, type IMarkdownDumpOptions, type IMemoryInstance, type INotificationUtils, type IOrderBookData, type IPartialLossCommitRow, type IPartialProfitCommitRow, type IPersistBase, type IPersistBreakevenInstance, type IPersistCandleInstance, type IPersistIntervalInstance, type IPersistLogInstance, type IPersistMeasureInstance, type IPersistMemoryInstance, type IPersistNotificationInstance, type IPersistPartialInstance, type IPersistRecentInstance, type IPersistRiskInstance, type IPersistScheduleInstance, type IPersistSessionInstance, type IPersistSignalInstance, type IPersistStateInstance, type IPersistStorageInstance, type IPositionSizeATRParams, type IPositionSizeFixedPercentageParams, type IPositionSizeKellyParams, type IPublicAction, type IPublicCandleData, type IPublicSignalRow, type IRecentUtils, type IReportDumpOptions, type IRiskActivePosition, type IRiskCheckArgs, type IRiskSchema, type IRiskSignalRow, type IRiskValidation, type IRiskValidationFn, type IRiskValidationPayload, type IScheduledSignalCancelRow, type IScheduledSignalRow, type ISessionInstance, type ISignalDto, type ISignalIntervalDto, type ISignalRow, type ISizingCalculateParams, type ISizingCalculateParamsATR, type ISizingCalculateParamsFixedPercentage, type ISizingCalculateParamsKelly, type ISizingParams, type ISizingParamsATR, type ISizingParamsFixedPercentage, type ISizingParamsKelly, type ISizingSchema, type ISizingSchemaATR, type ISizingSchemaFixedPercentage, type ISizingSchemaKelly, type IStateInstance, type IStorageSignalRow, type IStorageUtils, type IStrategyPnL, type IStrategyResult, type IStrategySchema, type IStrategyTickResult, type IStrategyTickResultActive, type IStrategyTickResultCancelled, type IStrategyTickResultClosed, type IStrategyTickResultIdle, type IStrategyTickResultOpened, type IStrategyTickResultScheduled, type IStrategyTickResultWaiting, type ITrailingStopCommitRow, type ITrailingTakeCommitRow, type IWalkerResults, type IWalkerSchema, type IWalkerStrategyResult, type IdlePingContract, type InfoErrorNotification, Interval, type IntervalData, Live, type LiveStatisticsModel, Log, type LogData, Markdown, MarkdownFileBase, MarkdownFolderBase, type MarkdownName, MarkdownWriter, MaxDrawdown, type MaxDrawdownContract, type MaxDrawdownEvent, type MaxDrawdownStatisticsModel, type MeasureData, Memory, MemoryBacktest, MemoryBacktestAdapter, type MemoryData, MemoryLive, MemoryLiveAdapter, type MessageModel, type MessageRole, type MessageToolCall, MethodContextService, type MetricStats, Notification, NotificationBacktest, type NotificationData, NotificationLive, type NotificationModel, Partial$1 as Partial, type PartialData, type PartialEvent, type PartialLossAvailableNotification, type PartialLossCommit, type PartialLossCommitNotification, type PartialLossContract, type PartialProfitAvailableNotification, type PartialProfitCommit, type PartialProfitCommitNotification, type PartialProfitContract, type PartialStatisticsModel, Performance, type PerformanceContract, type PerformanceMetricType, type PerformanceStatisticsModel, PersistBase, PersistBreakevenAdapter, PersistBreakevenInstance, PersistCandleAdapter, PersistCandleInstance, PersistIntervalAdapter, PersistIntervalInstance, PersistLogAdapter, PersistLogInstance, PersistMeasureAdapter, PersistMeasureInstance, PersistMemoryAdapter, PersistMemoryInstance, PersistNotificationAdapter, PersistNotificationInstance, PersistPartialAdapter, PersistPartialInstance, PersistRecentAdapter, PersistRecentInstance, PersistRiskAdapter, PersistRiskInstance, PersistScheduleAdapter, PersistScheduleInstance, PersistSessionAdapter, PersistSessionInstance, PersistSignalAdapter, PersistSignalInstance, PersistStateAdapter, PersistStateInstance, PersistStorageAdapter, PersistStorageInstance, Position, PositionSize, type ProgressBacktestContract, type ProgressWalkerContract, Recent, RecentBacktest, type RecentData, RecentLive, Reflect, Report, ReportBase, type ReportName, ReportWriter, Risk, type RiskContract, type RiskData, type RiskEvent, type RiskRejectionNotification, type RiskStatisticsModel, Schedule, type ScheduleData, type SchedulePingContract, type ScheduleStatisticsModel, type ScheduledEvent, Session, SessionBacktest, type SessionData, SessionLive, type SignalCancelledNotification, type SignalCloseContract, type SignalClosedNotification, type SignalData, type SignalInfoContract, type SignalInfoNotification, type SignalInterval, type SignalOpenContract, type SignalOpenedNotification, type SignalScheduledNotification, type SignalSyncCloseNotification, type SignalSyncContract, type SignalSyncOpenNotification, State, StateBacktest, StateBacktestAdapter, type StateData, StateLive, StateLiveAdapter, Storage, StorageBacktest, type StorageData, StorageLive, Strategy, type StrategyActionType, type StrategyCancelReason, type StrategyCloseReason, type StrategyCommitContract, type StrategyEvent, type StrategyStatisticsModel, Sync, type SyncEvent, type SyncStatisticsModel, System, type TBrokerCtor, type TDumpInstanceCtor, type TLogCtor, type TMarkdownBase, type TMemoryInstanceCtor, type TNotificationUtilsCtor, type TPersistBase, type TPersistBaseCtor, type TPersistBreakevenInstanceCtor, type TPersistCandleInstanceCtor, type TPersistIntervalInstanceCtor, type TPersistLogInstanceCtor, type TPersistMeasureInstanceCtor, type TPersistMemoryInstanceCtor, type TPersistNotificationInstanceCtor, type TPersistPartialInstanceCtor, type TPersistRecentInstanceCtor, type TPersistRiskInstanceCtor, type TPersistScheduleInstanceCtor, type TPersistSessionInstanceCtor, type TPersistSignalInstanceCtor, type TPersistStateInstanceCtor, type TPersistStorageInstanceCtor, type TRecentUtilsCtor, type TReportBase, type TSessionInstanceCtor, type TStateInstanceCtor, type TStorageUtilsCtor, type TickEvent, type TrailingStopCommit, type TrailingStopCommitNotification, type TrailingTakeCommit, type TrailingTakeCommitNotification, type ValidationErrorNotification, Walker, type WalkerCompleteContract, type WalkerContract, type WalkerMetric, type SignalData$1 as WalkerSignalData, type WalkerStatisticsModel, 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, getClosePrice, 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 };