backtest-kit 8.5.0 → 9.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (6) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1825 -1825
  3. package/build/index.cjs +2744 -1133
  4. package/build/index.mjs +2729 -1134
  5. package/package.json +86 -86
  6. package/types.d.ts +2113 -444
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
  *
@@ -9553,15 +9593,23 @@ interface IStateInstance {
9553
9593
  waitForInit(initial: boolean): Promise<void>;
9554
9594
  /**
9555
9595
  * Read the current state value.
9596
+ * Returns `initialValue` when the stored `when` is greater than the requested `when`
9597
+ * (look-ahead bias protection).
9598
+ * @param when - Logical timestamp at which the read is happening
9556
9599
  * @returns Current state value
9557
9600
  */
9558
- getState<Value extends object = object>(): Promise<Value>;
9601
+ getState<Value extends object = object>(when: Date): Promise<Value>;
9559
9602
  /**
9560
9603
  * Update the state value.
9604
+ * A write with a smaller `when` overwrites an existing record —
9605
+ * that lets a restarted backtest reset live-written state without breaking live.
9606
+ * The dispatch updater receives the look-ahead-guarded current value
9607
+ * (or `initialValue` when the stored `when` is in the future).
9561
9608
  * @param dispatch - New value or updater function receiving current value
9609
+ * @param when - Logical timestamp this value belongs to
9562
9610
  * @returns Updated state value
9563
9611
  */
9564
- setState<Value extends object = object>(dispatch: Value | Dispatch<Value>): Promise<Value>;
9612
+ setState<Value extends object = object>(dispatch: Value | Dispatch<Value>, when: Date): Promise<Value>;
9565
9613
  /**
9566
9614
  * Releases any resources held by this instance.
9567
9615
  */
@@ -9610,12 +9658,14 @@ declare class StateBacktestAdapter implements TStateAdapter {
9610
9658
  * @param dto.signalId - Signal identifier
9611
9659
  * @param dto.bucketName - Bucket name
9612
9660
  * @param dto.initialValue - Default value when no persisted state exists
9661
+ * @param dto.when - Logical timestamp at which the read is happening (look-ahead guard)
9613
9662
  * @returns Current state value
9614
9663
  */
9615
9664
  getState: <Value extends object = object>(dto: {
9616
9665
  signalId: string;
9617
9666
  bucketName: BucketName;
9618
9667
  initialValue: object;
9668
+ when: Date;
9619
9669
  }) => Promise<Value>;
9620
9670
  /**
9621
9671
  * Update the state value for a signal.
@@ -9623,12 +9673,14 @@ declare class StateBacktestAdapter implements TStateAdapter {
9623
9673
  * @param dto.signalId - Signal identifier
9624
9674
  * @param dto.bucketName - Bucket name
9625
9675
  * @param dto.initialValue - Default value when no persisted state exists
9676
+ * @param dto.when - Logical timestamp this value belongs to
9626
9677
  * @returns Updated state value
9627
9678
  */
9628
9679
  setState: <Value extends object = object>(dispatch: Value | Dispatch<Value>, dto: {
9629
9680
  signalId: string;
9630
9681
  bucketName: BucketName;
9631
9682
  initialValue: object;
9683
+ when: Date;
9632
9684
  }) => Promise<Value>;
9633
9685
  /**
9634
9686
  * Switches to in-memory adapter (default).
@@ -9687,12 +9739,14 @@ declare class StateLiveAdapter implements TStateAdapter {
9687
9739
  * @param dto.signalId - Signal identifier
9688
9740
  * @param dto.bucketName - Bucket name
9689
9741
  * @param dto.initialValue - Default value when no persisted state exists
9742
+ * @param dto.when - Logical timestamp at which the read is happening (look-ahead guard)
9690
9743
  * @returns Current state value
9691
9744
  */
9692
9745
  getState: <Value extends object = object>(dto: {
9693
9746
  signalId: string;
9694
9747
  bucketName: BucketName;
9695
9748
  initialValue: object;
9749
+ when: Date;
9696
9750
  }) => Promise<Value>;
9697
9751
  /**
9698
9752
  * Update the state value for a signal.
@@ -9700,12 +9754,14 @@ declare class StateLiveAdapter implements TStateAdapter {
9700
9754
  * @param dto.signalId - Signal identifier
9701
9755
  * @param dto.bucketName - Bucket name
9702
9756
  * @param dto.initialValue - Default value when no persisted state exists
9757
+ * @param dto.when - Logical timestamp this value belongs to
9703
9758
  * @returns Updated state value
9704
9759
  */
9705
9760
  setState: <Value extends object = object>(dispatch: Value | Dispatch<Value>, dto: {
9706
9761
  signalId: string;
9707
9762
  bucketName: BucketName;
9708
9763
  initialValue: object;
9764
+ when: Date;
9709
9765
  }) => Promise<Value>;
9710
9766
  /**
9711
9767
  * Switches to in-memory adapter.
@@ -9764,6 +9820,7 @@ declare class StateAdapter {
9764
9820
  * @param dto.bucketName - Bucket name
9765
9821
  * @param dto.initialValue - Default value when no persisted state exists
9766
9822
  * @param dto.backtest - Flag indicating if the context is backtest or live
9823
+ * @param dto.when - Logical timestamp at which the read is happening (look-ahead guard)
9767
9824
  * @returns Current state value
9768
9825
  * @throws Error if adapter is not enabled
9769
9826
  */
@@ -9772,6 +9829,7 @@ declare class StateAdapter {
9772
9829
  bucketName: BucketName;
9773
9830
  initialValue: object;
9774
9831
  backtest: boolean;
9832
+ when: Date;
9775
9833
  }) => Promise<Value>;
9776
9834
  /**
9777
9835
  * Update the state value for a signal.
@@ -9781,6 +9839,7 @@ declare class StateAdapter {
9781
9839
  * @param dto.bucketName - Bucket name
9782
9840
  * @param dto.initialValue - Default value when no persisted state exists
9783
9841
  * @param dto.backtest - Flag indicating if the context is backtest or live
9842
+ * @param dto.when - Logical timestamp this value belongs to
9784
9843
  * @returns Updated state value
9785
9844
  * @throws Error if adapter is not enabled
9786
9845
  */
@@ -9789,6 +9848,7 @@ declare class StateAdapter {
9789
9848
  bucketName: BucketName;
9790
9849
  initialValue: object;
9791
9850
  backtest: boolean;
9851
+ when: Date;
9792
9852
  }) => Promise<Value>;
9793
9853
  }
9794
9854
  /**
@@ -12787,6 +12847,7 @@ type MeasureData = {
12787
12847
  type IntervalData = {
12788
12848
  id: string;
12789
12849
  data: unknown;
12850
+ when: Date;
12790
12851
  removed: boolean;
12791
12852
  };
12792
12853
  /**
@@ -12911,6 +12972,92 @@ declare class PersistBase<EntityName extends string = string> implements IPersis
12911
12972
  */
12912
12973
  keys(): AsyncGenerator<EntityId>;
12913
12974
  }
12975
+ /**
12976
+ * Per-context signal persistence instance interface.
12977
+ * Scoped to a specific (symbol, strategyName, exchangeName) triple.
12978
+ *
12979
+ * Custom adapters should implement this interface to override the default
12980
+ * file-based signal persistence behavior.
12981
+ */
12982
+ interface IPersistSignalInstance {
12983
+ /**
12984
+ * Initialize storage for this signal context.
12985
+ *
12986
+ * @param initial - Whether this is the first initialization
12987
+ * @returns Promise that resolves when initialization is complete
12988
+ */
12989
+ waitForInit(initial: boolean): Promise<void>;
12990
+ /**
12991
+ * Read persisted signal data for this context.
12992
+ *
12993
+ * @returns Promise resolving to signal or null if none persisted
12994
+ */
12995
+ readSignalData(): Promise<ISignalRow | null>;
12996
+ /**
12997
+ * Write signal data for this context (null to clear).
12998
+ *
12999
+ * @param signalRow - Signal data to persist, or null to clear
13000
+ * @returns Promise that resolves when write is complete
13001
+ */
13002
+ writeSignalData(signalRow: ISignalRow | null): Promise<void>;
13003
+ }
13004
+ /**
13005
+ * Default file-based implementation of IPersistSignalInstance.
13006
+ *
13007
+ * Features:
13008
+ * - Wraps PersistBase for atomic JSON writes
13009
+ * - Uses symbol as entity ID within a per-context PersistBase
13010
+ * - Crash-safe via atomic writes
13011
+ *
13012
+ * @example
13013
+ * ```typescript
13014
+ * const instance = new PersistSignalInstance("BTCUSDT", "my-strategy", "binance");
13015
+ * await instance.waitForInit(true);
13016
+ * await instance.writeSignalData(signalRow);
13017
+ * const restored = await instance.readSignalData();
13018
+ * ```
13019
+ */
13020
+ declare class PersistSignalInstance implements IPersistSignalInstance {
13021
+ readonly symbol: string;
13022
+ readonly strategyName: StrategyName;
13023
+ readonly exchangeName: ExchangeName;
13024
+ /** Underlying file-based storage scoped to this context */
13025
+ private readonly _storage;
13026
+ /**
13027
+ * Creates new signal persistence instance.
13028
+ *
13029
+ * @param symbol - Trading pair symbol
13030
+ * @param strategyName - Strategy identifier
13031
+ * @param exchangeName - Exchange identifier
13032
+ */
13033
+ constructor(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName);
13034
+ /**
13035
+ * Initializes the underlying PersistBase storage.
13036
+ * Delegates to PersistBase.waitForInit which uses singleshot.
13037
+ *
13038
+ * @param initial - Whether this is the first initialization
13039
+ * @returns Promise that resolves when initialization is complete
13040
+ */
13041
+ waitForInit(initial: boolean): Promise<void>;
13042
+ /**
13043
+ * Reads the persisted signal using `symbol` as the entity key.
13044
+ *
13045
+ * @returns Promise resolving to the signal or null if not found
13046
+ */
13047
+ readSignalData(): Promise<ISignalRow | null>;
13048
+ /**
13049
+ * Writes the signal (or null to clear) using `symbol` as the entity key.
13050
+ *
13051
+ * @param signalRow - Signal data to persist, or null to clear
13052
+ * @returns Promise that resolves when write is complete
13053
+ */
13054
+ writeSignalData(signalRow: ISignalRow | null): Promise<void>;
13055
+ }
13056
+ /**
13057
+ * Constructor type for IPersistSignalInstance.
13058
+ * Used by PersistSignalUtils.usePersistSignalAdapter() to register custom adapters.
13059
+ */
13060
+ type TPersistSignalInstanceCtor = new (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => IPersistSignalInstance;
12914
13061
  /**
12915
13062
  * Utility class for managing signal persistence.
12916
13063
  *
@@ -12923,42 +13070,37 @@ declare class PersistBase<EntityName extends string = string> implements IPersis
12923
13070
  * Used by ClientStrategy for live mode persistence.
12924
13071
  */
12925
13072
  declare class PersistSignalUtils {
12926
- private PersistSignalFactory;
13073
+ /**
13074
+ * Constructor used to create per-context signal instances.
13075
+ * Replaceable via usePersistSignalAdapter() / useJson() / useDummy().
13076
+ */
13077
+ private PersistSignalInstanceCtor;
13078
+ /**
13079
+ * Memoized factory creating one IPersistSignalInstance per (symbol, strategy, exchange) triple.
13080
+ */
12927
13081
  private getStorage;
12928
13082
  /**
12929
- * Registers a custom persistence adapter.
13083
+ * Registers a custom IPersistSignalInstance constructor.
13084
+ * Clears the memoization cache so subsequent calls use the new adapter.
12930
13085
  *
12931
- * @param Ctor - Custom PersistBase constructor
12932
- *
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
- * ```
13086
+ * @param Ctor - Custom IPersistSignalInstance constructor
12941
13087
  */
12942
- usePersistSignalAdapter(Ctor: TPersistBaseCtor<StrategyName, SignalData>): void;
13088
+ usePersistSignalAdapter(Ctor: TPersistSignalInstanceCtor): void;
12943
13089
  /**
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.
13090
+ * Reads persisted signal for the given context.
13091
+ * Lazily initializes the instance on first access.
12948
13092
  *
12949
13093
  * @param symbol - Trading pair symbol
12950
13094
  * @param strategyName - Strategy identifier
12951
13095
  * @param exchangeName - Exchange identifier
12952
- * @returns Promise resolving to signal or null
13096
+ * @returns Promise resolving to signal or null if none persisted
12953
13097
  */
12954
13098
  readSignalData: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<ISignalRow | null>;
12955
13099
  /**
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.
13100
+ * Writes signal data (or null to clear) for the given context.
13101
+ * Lazily initializes the instance on first access.
12960
13102
  *
12961
- * @param signalRow - Signal data (null to clear)
13103
+ * @param signalRow - Signal data to persist, or null to clear
12962
13104
  * @param symbol - Trading pair symbol
12963
13105
  * @param strategyName - Strategy identifier
12964
13106
  * @param exchangeName - Exchange identifier
@@ -12966,19 +13108,16 @@ declare class PersistSignalUtils {
12966
13108
  */
12967
13109
  writeSignalData: (signalRow: ISignalRow | null, symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<void>;
12968
13110
  /**
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.
13111
+ * Clears the memoized instance cache.
13112
+ * Call when process.cwd() changes between strategy iterations.
12972
13113
  */
12973
13114
  clear(): void;
12974
13115
  /**
12975
- * Switches to the default JSON persist adapter.
12976
- * All future persistence writes will use JSON storage.
13116
+ * Switches to the default file-based PersistSignalInstance.
12977
13117
  */
12978
13118
  useJson(): void;
12979
13119
  /**
12980
- * Switches to a dummy persist adapter that discards all writes.
12981
- * All future persistence writes will be no-ops.
13120
+ * Switches to PersistSignalDummyInstance (all operations are no-ops).
12982
13121
  */
12983
13122
  useDummy(): void;
12984
13123
  }
@@ -13004,6 +13143,91 @@ declare const PersistSignalAdapter: PersistSignalUtils;
13004
13143
  * Stores Map entries as array of [key, value] tuples for JSON serialization.
13005
13144
  */
13006
13145
  type RiskData = Array<[string, IRiskActivePosition]>;
13146
+ /**
13147
+ * Per-context risk positions persistence instance interface.
13148
+ * Scoped to a specific (riskName, exchangeName) pair.
13149
+ *
13150
+ * Custom adapters should implement this interface to override the default
13151
+ * file-based active positions persistence behavior.
13152
+ */
13153
+ interface IPersistRiskInstance {
13154
+ /**
13155
+ * Initialize storage for this risk context.
13156
+ *
13157
+ * @param initial - Whether this is the first initialization
13158
+ * @returns Promise that resolves when initialization is complete
13159
+ */
13160
+ waitForInit(initial: boolean): Promise<void>;
13161
+ /**
13162
+ * Read persisted active positions for this context.
13163
+ *
13164
+ * @returns Promise resolving to position entries (empty array if none persisted)
13165
+ */
13166
+ readPositionData(): Promise<RiskData>;
13167
+ /**
13168
+ * Write active positions for this context.
13169
+ *
13170
+ * @param riskRow - Position entries to persist
13171
+ * @returns Promise that resolves when write is complete
13172
+ */
13173
+ writePositionData(riskRow: RiskData): Promise<void>;
13174
+ }
13175
+ /**
13176
+ * Default file-based implementation of IPersistRiskInstance.
13177
+ *
13178
+ * Features:
13179
+ * - Wraps PersistBase for atomic JSON writes
13180
+ * - Uses fixed entity ID "positions" within a per-context PersistBase
13181
+ * - Crash-safe via atomic writes
13182
+ *
13183
+ * @example
13184
+ * ```typescript
13185
+ * const instance = new PersistRiskInstance("my-risk", "binance");
13186
+ * await instance.waitForInit(true);
13187
+ * await instance.writePositionData([["strategy:BTCUSDT", positionData]]);
13188
+ * const positions = await instance.readPositionData();
13189
+ * ```
13190
+ */
13191
+ declare class PersistRiskInstance implements IPersistRiskInstance {
13192
+ readonly riskName: RiskName;
13193
+ readonly exchangeName: ExchangeName;
13194
+ /** Fixed entity key for storing the positions array */
13195
+ private static readonly STORAGE_KEY;
13196
+ /** Underlying file-based storage scoped to this context */
13197
+ private readonly _storage;
13198
+ /**
13199
+ * Creates new risk positions persistence instance.
13200
+ *
13201
+ * @param riskName - Risk profile identifier
13202
+ * @param exchangeName - Exchange identifier
13203
+ */
13204
+ constructor(riskName: RiskName, exchangeName: ExchangeName);
13205
+ /**
13206
+ * Initializes the underlying PersistBase storage.
13207
+ *
13208
+ * @param initial - Whether this is the first initialization
13209
+ * @returns Promise that resolves when initialization is complete
13210
+ */
13211
+ waitForInit(initial: boolean): Promise<void>;
13212
+ /**
13213
+ * Reads the persisted positions array using the fixed STORAGE_KEY.
13214
+ *
13215
+ * @returns Promise resolving to positions (empty array if none persisted)
13216
+ */
13217
+ readPositionData(): Promise<RiskData>;
13218
+ /**
13219
+ * Writes the positions array using the fixed STORAGE_KEY.
13220
+ *
13221
+ * @param riskRow - Position entries to persist
13222
+ * @returns Promise that resolves when write is complete
13223
+ */
13224
+ writePositionData(riskRow: RiskData): Promise<void>;
13225
+ }
13226
+ /**
13227
+ * Constructor type for IPersistRiskInstance.
13228
+ * Used by PersistRiskUtils.usePersistRiskAdapter() to register custom adapters.
13229
+ */
13230
+ type TPersistRiskInstanceCtor = new (riskName: RiskName, exchangeName: ExchangeName) => IPersistRiskInstance;
13007
13231
  /**
13008
13232
  * Utility class for managing risk active positions persistence.
13009
13233
  *
@@ -13016,60 +13240,52 @@ type RiskData = Array<[string, IRiskActivePosition]>;
13016
13240
  * Used by ClientRisk for live mode persistence of active positions.
13017
13241
  */
13018
13242
  declare class PersistRiskUtils {
13019
- private PersistRiskFactory;
13243
+ /**
13244
+ * Constructor used to create per-context risk instances.
13245
+ * Replaceable via usePersistRiskAdapter() / useJson() / useDummy().
13246
+ */
13247
+ private PersistRiskInstanceCtor;
13248
+ /**
13249
+ * Memoized factory creating one IPersistRiskInstance per (riskName, exchange) pair.
13250
+ */
13020
13251
  private getRiskStorage;
13021
13252
  /**
13022
- * Registers a custom persistence adapter.
13253
+ * Registers a custom IPersistRiskInstance constructor.
13254
+ * Clears the memoization cache so subsequent calls use the new adapter.
13023
13255
  *
13024
- * @param Ctor - Custom PersistBase constructor
13025
- *
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
- * ```
13256
+ * @param Ctor - Custom IPersistRiskInstance constructor
13034
13257
  */
13035
- usePersistRiskAdapter(Ctor: TPersistBaseCtor<RiskName, RiskData>): void;
13258
+ usePersistRiskAdapter(Ctor: TPersistRiskInstanceCtor): void;
13036
13259
  /**
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.
13260
+ * Reads persisted active positions for the given risk context.
13261
+ * Lazily initializes the instance on first access.
13041
13262
  *
13042
13263
  * @param riskName - Risk profile identifier
13043
13264
  * @param exchangeName - Exchange identifier
13044
- * @returns Promise resolving to Map of active positions
13265
+ * @returns Promise resolving to position entries (empty array if none)
13045
13266
  */
13046
13267
  readPositionData: (riskName: RiskName, exchangeName: ExchangeName) => Promise<RiskData>;
13047
13268
  /**
13048
- * Writes active positions to disk with atomic file writes.
13269
+ * Writes active positions for the given risk context.
13270
+ * Lazily initializes the instance on first access.
13049
13271
  *
13050
- * Called by ClientRisk after addSignal/removeSignal to persist state.
13051
- * Uses atomic writes to prevent corruption on crashes.
13052
- *
13053
- * @param positions - Map of active positions
13272
+ * @param riskRow - Position entries to persist
13054
13273
  * @param riskName - Risk profile identifier
13055
13274
  * @param exchangeName - Exchange identifier
13056
13275
  * @returns Promise that resolves when write is complete
13057
13276
  */
13058
13277
  writePositionData: (riskRow: RiskData, riskName: RiskName, exchangeName: ExchangeName) => Promise<void>;
13059
13278
  /**
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.
13279
+ * Clears the memoized instance cache.
13280
+ * Call when process.cwd() changes between strategy iterations.
13063
13281
  */
13064
13282
  clear(): void;
13065
13283
  /**
13066
- * Switches to the default JSON persist adapter.
13067
- * All future persistence writes will use JSON storage.
13284
+ * Switches to the default file-based PersistRiskInstance.
13068
13285
  */
13069
13286
  useJson(): void;
13070
13287
  /**
13071
- * Switches to a dummy persist adapter that discards all writes.
13072
- * All future persistence writes will be no-ops.
13288
+ * Switches to PersistRiskDummyInstance (all operations are no-ops).
13073
13289
  */
13074
13290
  useDummy(): void;
13075
13291
  }
@@ -13095,6 +13311,91 @@ declare const PersistRiskAdapter: PersistRiskUtils;
13095
13311
  * Contains nullable scheduled signal for atomic updates.
13096
13312
  */
13097
13313
  type ScheduleData = IScheduledSignalRow | null;
13314
+ /**
13315
+ * Per-context scheduled signal persistence instance interface.
13316
+ * Scoped to a specific (symbol, strategyName, exchangeName) triple.
13317
+ *
13318
+ * Custom adapters should implement this interface to override the default
13319
+ * file-based scheduled signal persistence behavior.
13320
+ */
13321
+ interface IPersistScheduleInstance {
13322
+ /**
13323
+ * Initialize storage for this scheduled signal context.
13324
+ *
13325
+ * @param initial - Whether this is the first initialization
13326
+ * @returns Promise that resolves when initialization is complete
13327
+ */
13328
+ waitForInit(initial: boolean): Promise<void>;
13329
+ /**
13330
+ * Read persisted scheduled signal for this context.
13331
+ *
13332
+ * @returns Promise resolving to scheduled signal or null if none persisted
13333
+ */
13334
+ readScheduleData(): Promise<IScheduledSignalRow | null>;
13335
+ /**
13336
+ * Write scheduled signal for this context (null to clear).
13337
+ *
13338
+ * @param row - Scheduled signal data to persist, or null to clear
13339
+ * @returns Promise that resolves when write is complete
13340
+ */
13341
+ writeScheduleData(row: IScheduledSignalRow | null): Promise<void>;
13342
+ }
13343
+ /**
13344
+ * Default file-based implementation of IPersistScheduleInstance.
13345
+ *
13346
+ * Features:
13347
+ * - Wraps PersistBase for atomic JSON writes
13348
+ * - Uses symbol as entity ID within a per-context PersistBase
13349
+ * - Crash-safe via atomic writes
13350
+ *
13351
+ * @example
13352
+ * ```typescript
13353
+ * const instance = new PersistScheduleInstance("BTCUSDT", "my-strategy", "binance");
13354
+ * await instance.waitForInit(true);
13355
+ * await instance.writeScheduleData(scheduledRow);
13356
+ * const restored = await instance.readScheduleData();
13357
+ * ```
13358
+ */
13359
+ declare class PersistScheduleInstance implements IPersistScheduleInstance {
13360
+ readonly symbol: string;
13361
+ readonly strategyName: StrategyName;
13362
+ readonly exchangeName: ExchangeName;
13363
+ /** Underlying file-based storage scoped to this context */
13364
+ private readonly _storage;
13365
+ /**
13366
+ * Creates new scheduled signal persistence instance.
13367
+ *
13368
+ * @param symbol - Trading pair symbol
13369
+ * @param strategyName - Strategy identifier
13370
+ * @param exchangeName - Exchange identifier
13371
+ */
13372
+ constructor(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName);
13373
+ /**
13374
+ * Initializes the underlying PersistBase storage.
13375
+ *
13376
+ * @param initial - Whether this is the first initialization
13377
+ * @returns Promise that resolves when initialization is complete
13378
+ */
13379
+ waitForInit(initial: boolean): Promise<void>;
13380
+ /**
13381
+ * Reads the persisted scheduled signal using `symbol` as the entity key.
13382
+ *
13383
+ * @returns Promise resolving to scheduled signal or null if not found
13384
+ */
13385
+ readScheduleData(): Promise<IScheduledSignalRow | null>;
13386
+ /**
13387
+ * Writes the scheduled signal (or null to clear) using `symbol` as the entity key.
13388
+ *
13389
+ * @param row - Scheduled signal data to persist, or null to clear
13390
+ * @returns Promise that resolves when write is complete
13391
+ */
13392
+ writeScheduleData(row: IScheduledSignalRow | null): Promise<void>;
13393
+ }
13394
+ /**
13395
+ * Constructor type for IPersistScheduleInstance.
13396
+ * Used by PersistScheduleUtils.usePersistScheduleAdapter() to register custom adapters.
13397
+ */
13398
+ type TPersistScheduleInstanceCtor = new (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => IPersistScheduleInstance;
13098
13399
  /**
13099
13400
  * Utility class for managing scheduled signal persistence.
13100
13401
  *
@@ -13107,42 +13408,37 @@ type ScheduleData = IScheduledSignalRow | null;
13107
13408
  * Used by ClientStrategy for live mode persistence of scheduled signals (_scheduledSignal).
13108
13409
  */
13109
13410
  declare class PersistScheduleUtils {
13110
- private PersistScheduleFactory;
13411
+ /**
13412
+ * Constructor used to create per-context scheduled signal instances.
13413
+ * Replaceable via usePersistScheduleAdapter() / useJson() / useDummy().
13414
+ */
13415
+ private PersistScheduleInstanceCtor;
13416
+ /**
13417
+ * Memoized factory creating one IPersistScheduleInstance per (symbol, strategy, exchange) triple.
13418
+ */
13111
13419
  private getScheduleStorage;
13112
13420
  /**
13113
- * Registers a custom persistence adapter.
13421
+ * Registers a custom IPersistScheduleInstance constructor.
13422
+ * Clears the memoization cache so subsequent calls use the new adapter.
13114
13423
  *
13115
- * @param Ctor - Custom PersistBase constructor
13116
- *
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
- * ```
13424
+ * @param Ctor - Custom IPersistScheduleInstance constructor
13125
13425
  */
13126
- usePersistScheduleAdapter(Ctor: TPersistBaseCtor<StrategyName, ScheduleData>): void;
13426
+ usePersistScheduleAdapter(Ctor: TPersistScheduleInstanceCtor): void;
13127
13427
  /**
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.
13428
+ * Reads persisted scheduled signal for the given context.
13429
+ * Lazily initializes the instance on first access.
13132
13430
  *
13133
13431
  * @param symbol - Trading pair symbol
13134
13432
  * @param strategyName - Strategy identifier
13135
13433
  * @param exchangeName - Exchange identifier
13136
- * @returns Promise resolving to scheduled signal or null
13434
+ * @returns Promise resolving to scheduled signal or null if none persisted
13137
13435
  */
13138
13436
  readScheduleData: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<IScheduledSignalRow | null>;
13139
13437
  /**
13140
- * Writes scheduled signal data to disk with atomic file writes.
13438
+ * Writes scheduled signal (or null to clear) for the given context.
13439
+ * Lazily initializes the instance on first access.
13141
13440
  *
13142
- * Called by ClientStrategy.setScheduledSignal() to persist state.
13143
- * Uses atomic writes to prevent corruption on crashes.
13144
- *
13145
- * @param scheduledSignalRow - Scheduled signal data (null to clear)
13441
+ * @param scheduledSignalRow - Scheduled signal data to persist, or null to clear
13146
13442
  * @param symbol - Trading pair symbol
13147
13443
  * @param strategyName - Strategy identifier
13148
13444
  * @param exchangeName - Exchange identifier
@@ -13150,19 +13446,16 @@ declare class PersistScheduleUtils {
13150
13446
  */
13151
13447
  writeScheduleData: (scheduledSignalRow: IScheduledSignalRow | null, symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => Promise<void>;
13152
13448
  /**
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.
13449
+ * Clears the memoized instance cache.
13450
+ * Call when process.cwd() changes between strategy iterations.
13156
13451
  */
13157
13452
  clear(): void;
13158
13453
  /**
13159
- * Switches to the default JSON persist adapter.
13160
- * All future persistence writes will use JSON storage.
13454
+ * Switches to the default file-based PersistScheduleInstance.
13161
13455
  */
13162
13456
  useJson(): void;
13163
13457
  /**
13164
- * Switches to a dummy persist adapter that discards all writes.
13165
- * All future persistence writes will be no-ops.
13458
+ * Switches to PersistScheduleDummyInstance (all operations are no-ops).
13166
13459
  */
13167
13460
  useDummy(): void;
13168
13461
  }
@@ -13188,6 +13481,98 @@ declare const PersistScheduleAdapter: PersistScheduleUtils;
13188
13481
  * Stores profit and loss levels as arrays for JSON serialization.
13189
13482
  */
13190
13483
  type PartialData = Record<string, IPartialData>;
13484
+ /**
13485
+ * Per-context partial profit/loss levels persistence instance interface.
13486
+ * Scoped to a specific (symbol, strategyName, exchangeName) triple.
13487
+ *
13488
+ * Each signal's partial data is stored under its own signalId key within
13489
+ * the context-scoped storage.
13490
+ *
13491
+ * Custom adapters should implement this interface to override the default
13492
+ * file-based partial data persistence behavior.
13493
+ */
13494
+ interface IPersistPartialInstance {
13495
+ /**
13496
+ * Initialize storage for this partial context.
13497
+ *
13498
+ * @param initial - Whether this is the first initialization
13499
+ * @returns Promise that resolves when initialization is complete
13500
+ */
13501
+ waitForInit(initial: boolean): Promise<void>;
13502
+ /**
13503
+ * Read persisted partial data for a specific signal.
13504
+ *
13505
+ * @param signalId - Signal identifier
13506
+ * @returns Promise resolving to partial data record (empty object if none persisted)
13507
+ */
13508
+ readPartialData(signalId: string): Promise<PartialData>;
13509
+ /**
13510
+ * Write partial data for a specific signal.
13511
+ *
13512
+ * @param data - Partial data record to persist
13513
+ * @param signalId - Signal identifier
13514
+ * @returns Promise that resolves when write is complete
13515
+ */
13516
+ writePartialData(data: PartialData, signalId: string): Promise<void>;
13517
+ }
13518
+ /**
13519
+ * Default file-based implementation of IPersistPartialInstance.
13520
+ *
13521
+ * Features:
13522
+ * - Wraps PersistBase for atomic JSON writes
13523
+ * - Uses signalId as entity ID within a per-context PersistBase
13524
+ * - Crash-safe via atomic writes
13525
+ *
13526
+ * @example
13527
+ * ```typescript
13528
+ * const instance = new PersistPartialInstance("BTCUSDT", "my-strategy", "binance");
13529
+ * await instance.waitForInit(true);
13530
+ * await instance.writePartialData(partialData, "signal-id-1");
13531
+ * const restored = await instance.readPartialData("signal-id-1");
13532
+ * ```
13533
+ */
13534
+ declare class PersistPartialInstance implements IPersistPartialInstance {
13535
+ readonly symbol: string;
13536
+ readonly strategyName: StrategyName;
13537
+ readonly exchangeName: ExchangeName;
13538
+ /** Underlying file-based storage scoped to this context */
13539
+ private readonly _storage;
13540
+ /**
13541
+ * Creates new partial data persistence instance.
13542
+ *
13543
+ * @param symbol - Trading pair symbol
13544
+ * @param strategyName - Strategy identifier
13545
+ * @param exchangeName - Exchange identifier
13546
+ */
13547
+ constructor(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName);
13548
+ /**
13549
+ * Initializes the underlying PersistBase storage.
13550
+ *
13551
+ * @param initial - Whether this is the first initialization
13552
+ * @returns Promise that resolves when initialization is complete
13553
+ */
13554
+ waitForInit(initial: boolean): Promise<void>;
13555
+ /**
13556
+ * Reads the partial data for the given signal using `signalId` as the entity key.
13557
+ *
13558
+ * @param signalId - Signal identifier
13559
+ * @returns Promise resolving to partial data record (empty object if not found)
13560
+ */
13561
+ readPartialData(signalId: string): Promise<PartialData>;
13562
+ /**
13563
+ * Writes the partial data for the given signal using `signalId` as the entity key.
13564
+ *
13565
+ * @param data - Partial data record to persist
13566
+ * @param signalId - Signal identifier
13567
+ * @returns Promise that resolves when write is complete
13568
+ */
13569
+ writePartialData(data: PartialData, signalId: string): Promise<void>;
13570
+ }
13571
+ /**
13572
+ * Constructor type for IPersistPartialInstance.
13573
+ * Used by PersistPartialUtils.usePersistPartialAdapter() to register custom adapters.
13574
+ */
13575
+ type TPersistPartialInstanceCtor = new (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => IPersistPartialInstance;
13191
13576
  /**
13192
13577
  * Utility class for managing partial profit/loss levels persistence.
13193
13578
  *
@@ -13200,43 +13585,39 @@ type PartialData = Record<string, IPartialData>;
13200
13585
  * Used by ClientPartial for live mode persistence of profit/loss levels.
13201
13586
  */
13202
13587
  declare class PersistPartialUtils {
13203
- private PersistPartialFactory;
13588
+ /**
13589
+ * Constructor used to create per-context partial data instances.
13590
+ * Replaceable via usePersistPartialAdapter() / useJson() / useDummy().
13591
+ */
13592
+ private PersistPartialInstanceCtor;
13593
+ /**
13594
+ * Memoized factory creating one IPersistPartialInstance per (symbol, strategy, exchange) triple.
13595
+ * Each signal's partial data is stored under its own signalId within the instance.
13596
+ */
13204
13597
  private getPartialStorage;
13205
13598
  /**
13206
- * Registers a custom persistence adapter.
13207
- *
13208
- * @param Ctor - Custom PersistBase constructor
13599
+ * Registers a custom IPersistPartialInstance constructor.
13600
+ * Clears the memoization cache so subsequent calls use the new adapter.
13209
13601
  *
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
- * ```
13602
+ * @param Ctor - Custom IPersistPartialInstance constructor
13218
13603
  */
13219
- usePersistPartialAdapter(Ctor: TPersistBaseCtor<string, PartialData>): void;
13604
+ usePersistPartialAdapter(Ctor: TPersistPartialInstanceCtor): void;
13220
13605
  /**
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.
13606
+ * Reads partial data for the given context and signalId.
13607
+ * Lazily initializes the instance on first access.
13225
13608
  *
13226
13609
  * @param symbol - Trading pair symbol
13227
13610
  * @param strategyName - Strategy identifier
13228
13611
  * @param signalId - Signal identifier
13229
13612
  * @param exchangeName - Exchange identifier
13230
- * @returns Promise resolving to partial data record
13613
+ * @returns Promise resolving to partial data record (empty object if none)
13231
13614
  */
13232
13615
  readPartialData: (symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<PartialData>;
13233
13616
  /**
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.
13617
+ * Writes partial data for the given context and signalId.
13618
+ * Lazily initializes the instance on first access.
13238
13619
  *
13239
- * @param partialData - Record of signal IDs to partial data
13620
+ * @param partialData - Partial data record to persist
13240
13621
  * @param symbol - Trading pair symbol
13241
13622
  * @param strategyName - Strategy identifier
13242
13623
  * @param signalId - Signal identifier
@@ -13245,19 +13626,16 @@ declare class PersistPartialUtils {
13245
13626
  */
13246
13627
  writePartialData: (partialData: PartialData, symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<void>;
13247
13628
  /**
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.
13629
+ * Clears the memoized instance cache.
13630
+ * Call when process.cwd() changes between strategy iterations.
13251
13631
  */
13252
13632
  clear(): void;
13253
13633
  /**
13254
- * Switches to the default JSON persist adapter.
13255
- * All future persistence writes will use JSON storage.
13634
+ * Switches to the default file-based PersistPartialInstance.
13256
13635
  */
13257
13636
  useJson(): void;
13258
13637
  /**
13259
- * Switches to a dummy persist adapter that discards all writes.
13260
- * All future persistence writes will be no-ops.
13638
+ * Switches to PersistPartialDummyInstance (all operations are no-ops).
13261
13639
  */
13262
13640
  useDummy(): void;
13263
13641
  }
@@ -13283,11 +13661,103 @@ declare const PersistPartialAdapter: PersistPartialUtils;
13283
13661
  * Stores breakeven state (reached flag) for each signal ID.
13284
13662
  */
13285
13663
  type BreakevenData = Record<string, IBreakevenData>;
13664
+ /**
13665
+ * Per-context breakeven state persistence instance interface.
13666
+ * Scoped to a specific (symbol, strategyName, exchangeName) triple.
13667
+ *
13668
+ * Each signal's breakeven data is stored under its own signalId key within
13669
+ * the context-scoped storage.
13670
+ *
13671
+ * Custom adapters should implement this interface to override the default
13672
+ * file-based breakeven persistence behavior.
13673
+ */
13674
+ interface IPersistBreakevenInstance {
13675
+ /**
13676
+ * Initialize storage for this breakeven context.
13677
+ *
13678
+ * @param initial - Whether this is the first initialization
13679
+ * @returns Promise that resolves when initialization is complete
13680
+ */
13681
+ waitForInit(initial: boolean): Promise<void>;
13682
+ /**
13683
+ * Read persisted breakeven data for a specific signal.
13684
+ *
13685
+ * @param signalId - Signal identifier
13686
+ * @returns Promise resolving to breakeven data record (empty object if none persisted)
13687
+ */
13688
+ readBreakevenData(signalId: string): Promise<BreakevenData>;
13689
+ /**
13690
+ * Write breakeven data for a specific signal.
13691
+ *
13692
+ * @param data - Breakeven data record to persist
13693
+ * @param signalId - Signal identifier
13694
+ * @returns Promise that resolves when write is complete
13695
+ */
13696
+ writeBreakevenData(data: BreakevenData, signalId: string): Promise<void>;
13697
+ }
13698
+ /**
13699
+ * Default file-based implementation of IPersistBreakevenInstance.
13700
+ *
13701
+ * Features:
13702
+ * - Wraps PersistBase for atomic JSON writes
13703
+ * - Uses signalId as entity ID within a per-context PersistBase
13704
+ * - Crash-safe via atomic writes
13705
+ *
13706
+ * @example
13707
+ * ```typescript
13708
+ * const instance = new PersistBreakevenInstance("BTCUSDT", "my-strategy", "binance");
13709
+ * await instance.waitForInit(true);
13710
+ * await instance.writeBreakevenData(breakevenData, "signal-id-1");
13711
+ * const restored = await instance.readBreakevenData("signal-id-1");
13712
+ * ```
13713
+ */
13714
+ declare class PersistBreakevenInstance implements IPersistBreakevenInstance {
13715
+ readonly symbol: string;
13716
+ readonly strategyName: StrategyName;
13717
+ readonly exchangeName: ExchangeName;
13718
+ /** Underlying file-based storage scoped to this context */
13719
+ private readonly _storage;
13720
+ /**
13721
+ * Creates new breakeven persistence instance.
13722
+ *
13723
+ * @param symbol - Trading pair symbol
13724
+ * @param strategyName - Strategy identifier
13725
+ * @param exchangeName - Exchange identifier
13726
+ */
13727
+ constructor(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName);
13728
+ /**
13729
+ * Initializes the underlying PersistBase storage.
13730
+ *
13731
+ * @param initial - Whether this is the first initialization
13732
+ * @returns Promise that resolves when initialization is complete
13733
+ */
13734
+ waitForInit(initial: boolean): Promise<void>;
13735
+ /**
13736
+ * Reads the breakeven data for the given signal using `signalId` as the entity key.
13737
+ *
13738
+ * @param signalId - Signal identifier
13739
+ * @returns Promise resolving to breakeven data record (empty object if not found)
13740
+ */
13741
+ readBreakevenData(signalId: string): Promise<BreakevenData>;
13742
+ /**
13743
+ * Writes the breakeven data for the given signal using `signalId` as the entity key.
13744
+ *
13745
+ * @param data - Breakeven data record to persist
13746
+ * @param signalId - Signal identifier
13747
+ * @returns Promise that resolves when write is complete
13748
+ */
13749
+ writeBreakevenData(data: BreakevenData, signalId: string): Promise<void>;
13750
+ }
13751
+ /**
13752
+ * Constructor type for IPersistBreakevenInstance.
13753
+ * Used by PersistBreakevenUtils.usePersistBreakevenAdapter() to register custom adapters.
13754
+ */
13755
+ type TPersistBreakevenInstanceCtor = new (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName) => IPersistBreakevenInstance;
13286
13756
  /**
13287
13757
  * Persistence utility class for breakeven state management.
13288
13758
  *
13289
13759
  * Handles reading and writing breakeven state to disk.
13290
- * Uses memoized PersistBase instances per symbol-strategy pair.
13760
+ * Uses memoized PersistBreakevenInstance instances per symbol-strategy pair.
13291
13761
  *
13292
13762
  * Features:
13293
13763
  * - Atomic file writes via PersistBase.writeValue()
@@ -13316,55 +13786,36 @@ type BreakevenData = Record<string, IBreakevenData>;
13316
13786
  */
13317
13787
  declare class PersistBreakevenUtils {
13318
13788
  /**
13319
- * Factory for creating PersistBase instances.
13320
- * Can be replaced via usePersistBreakevenAdapter().
13789
+ * Constructor used to create per-context breakeven instances.
13790
+ * Replaceable via usePersistBreakevenAdapter() / useJson() / useDummy().
13321
13791
  */
13322
- private PersistBreakevenFactory;
13792
+ private PersistBreakevenInstanceCtor;
13323
13793
  /**
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
13794
+ * Memoized factory creating one IPersistBreakevenInstance per (symbol, strategy, exchange) triple.
13795
+ * Each signal's breakeven data is stored under its own signalId within the instance.
13332
13796
  */
13333
13797
  private getBreakevenStorage;
13334
13798
  /**
13335
- * Registers a custom persistence adapter.
13799
+ * Registers a custom IPersistBreakevenInstance constructor.
13800
+ * Clears the memoization cache so subsequent calls use the new adapter.
13336
13801
  *
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
- * ```
13802
+ * @param Ctor - Custom IPersistBreakevenInstance constructor
13347
13803
  */
13348
- usePersistBreakevenAdapter(Ctor: TPersistBaseCtor<string, BreakevenData>): void;
13804
+ usePersistBreakevenAdapter(Ctor: TPersistBreakevenInstanceCtor): void;
13349
13805
  /**
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.
13806
+ * Reads breakeven data for the given context and signalId.
13807
+ * Lazily initializes the instance on first access.
13354
13808
  *
13355
13809
  * @param symbol - Trading pair symbol
13356
13810
  * @param strategyName - Strategy identifier
13357
13811
  * @param signalId - Signal identifier
13358
13812
  * @param exchangeName - Exchange identifier
13359
- * @returns Promise resolving to breakeven data record
13813
+ * @returns Promise resolving to breakeven data record (empty object if none)
13360
13814
  */
13361
13815
  readBreakevenData: (symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<BreakevenData>;
13362
13816
  /**
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.
13817
+ * Writes breakeven data for the given context and signalId.
13818
+ * Lazily initializes the instance on first access.
13368
13819
  *
13369
13820
  * @param breakevenData - Breakeven data record to persist
13370
13821
  * @param symbol - Trading pair symbol
@@ -13375,19 +13826,16 @@ declare class PersistBreakevenUtils {
13375
13826
  */
13376
13827
  writeBreakevenData: (breakevenData: BreakevenData, symbol: string, strategyName: StrategyName, signalId: string, exchangeName: ExchangeName) => Promise<void>;
13377
13828
  /**
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.
13829
+ * Clears the memoized instance cache.
13830
+ * Call when process.cwd() changes between strategy iterations.
13381
13831
  */
13382
13832
  clear(): void;
13383
13833
  /**
13384
- * Switches to the default JSON persist adapter.
13385
- * All future persistence writes will use JSON storage.
13834
+ * Switches to the default file-based PersistBreakevenInstance.
13386
13835
  */
13387
13836
  useJson(): void;
13388
13837
  /**
13389
- * Switches to a dummy persist adapter that discards all writes.
13390
- * All future persistence writes will be no-ops.
13838
+ * Switches to PersistBreakevenDummyInstance (all operations are no-ops).
13391
13839
  */
13392
13840
  useDummy(): void;
13393
13841
  }
@@ -13413,6 +13861,110 @@ declare const PersistBreakevenAdapter: PersistBreakevenUtils;
13413
13861
  * Each candle is stored as a separate JSON file.
13414
13862
  */
13415
13863
  type CandleData = ICandleData;
13864
+ /**
13865
+ * Per-context candle cache persistence instance interface.
13866
+ * Scoped to a specific (symbol, interval, exchangeName) triple.
13867
+ *
13868
+ * Each candle is keyed by its timestamp inside the context-scoped storage.
13869
+ * `readCandlesData` returns `null` when ANY of the expected timestamps is
13870
+ * missing (cache miss), so the caller can refetch from the exchange.
13871
+ *
13872
+ * Custom adapters should implement this interface to override the default
13873
+ * file-based candle cache behavior.
13874
+ */
13875
+ interface IPersistCandleInstance {
13876
+ /**
13877
+ * Initialize storage for this candle context.
13878
+ *
13879
+ * @param initial - Whether this is the first initialization
13880
+ * @returns Promise that resolves when initialization is complete
13881
+ */
13882
+ waitForInit(initial: boolean): Promise<void>;
13883
+ /**
13884
+ * Read cached candles for the requested time window.
13885
+ * Returns null if any candle in the window is missing (cache miss).
13886
+ *
13887
+ * @param limit - Number of candles requested
13888
+ * @param sinceTimestamp - Aligned start timestamp (openTime of first candle)
13889
+ * @param untilTimestamp - Reserved for API compatibility, not used by default
13890
+ * @returns Promise resolving to candles in order, or null on cache miss
13891
+ */
13892
+ readCandlesData(limit: number, sinceTimestamp: number, untilTimestamp: number): Promise<CandleData[] | null>;
13893
+ /**
13894
+ * Write candles to cache.
13895
+ * Implementations may skip incomplete candles (closeTime > now) and
13896
+ * existing keys to avoid overwriting fully closed candles.
13897
+ *
13898
+ * @param candles - Array of candle data to cache
13899
+ * @returns Promise that resolves when all writes are complete
13900
+ */
13901
+ writeCandlesData(candles: CandleData[]): Promise<void>;
13902
+ }
13903
+ /**
13904
+ * Default file-based implementation of IPersistCandleInstance.
13905
+ *
13906
+ * Features:
13907
+ * - Each candle stored as a separate JSON file keyed by its timestamp
13908
+ * - Read returns null on any missing timestamp (cache miss → refetch)
13909
+ * - Write skips incomplete candles (closeTime > now) and existing keys
13910
+ * - Invalid cached candles emit warnings via errorEmitter and treated as miss
13911
+ *
13912
+ * @example
13913
+ * ```typescript
13914
+ * const instance = new PersistCandleInstance("BTCUSDT", "1m", "binance");
13915
+ * await instance.waitForInit(true);
13916
+ * await instance.writeCandlesData(candles);
13917
+ * const cached = await instance.readCandlesData(100, since, until);
13918
+ * ```
13919
+ */
13920
+ declare class PersistCandleInstance implements IPersistCandleInstance {
13921
+ readonly symbol: string;
13922
+ readonly interval: CandleInterval;
13923
+ readonly exchangeName: ExchangeName;
13924
+ /** Underlying file-based storage scoped to this context */
13925
+ private readonly _storage;
13926
+ /**
13927
+ * Creates new candle cache persistence instance.
13928
+ *
13929
+ * @param symbol - Trading pair symbol
13930
+ * @param interval - Candle interval (1m, 5m, 1h, etc.)
13931
+ * @param exchangeName - Exchange identifier
13932
+ */
13933
+ constructor(symbol: string, interval: CandleInterval, exchangeName: ExchangeName);
13934
+ /**
13935
+ * Initializes the underlying PersistBase storage.
13936
+ *
13937
+ * @param initial - Whether this is the first initialization
13938
+ * @returns Promise that resolves when initialization is complete
13939
+ */
13940
+ waitForInit(initial: boolean): Promise<void>;
13941
+ /**
13942
+ * Reads cached candles for the requested window.
13943
+ * Computes expected timestamps (sinceTimestamp + i * stepMs) and reads each
13944
+ * by timestamp key. Returns null on ANY missing timestamp (cache miss).
13945
+ * Invalid cached candles emit a warning via errorEmitter and are treated as miss.
13946
+ *
13947
+ * @param limit - Number of candles requested
13948
+ * @param sinceTimestamp - Aligned start timestamp (openTime of first candle)
13949
+ * @param _untilTimestamp - Reserved for API compatibility, unused
13950
+ * @returns Promise resolving to candles in order, or null on cache miss
13951
+ */
13952
+ readCandlesData(limit: number, sinceTimestamp: number, _untilTimestamp: number): Promise<CandleData[] | null>;
13953
+ /**
13954
+ * Writes candles to cache.
13955
+ * Skips incomplete candles (closeTime > now) and existing keys to keep
13956
+ * the cache append-only for fully closed candles.
13957
+ *
13958
+ * @param candles - Array of candle data to cache
13959
+ * @returns Promise that resolves when all writes are complete
13960
+ */
13961
+ writeCandlesData(candles: CandleData[]): Promise<void>;
13962
+ }
13963
+ /**
13964
+ * Constructor type for IPersistCandleInstance.
13965
+ * Used by PersistCandleUtils.usePersistCandleAdapter() to register custom adapters.
13966
+ */
13967
+ type TPersistCandleInstanceCtor = new (symbol: string, interval: CandleInterval, exchangeName: ExchangeName) => IPersistCandleInstance;
13416
13968
  /**
13417
13969
  * Utility class for managing candles cache persistence.
13418
13970
  *
@@ -13425,43 +13977,40 @@ type CandleData = ICandleData;
13425
13977
  * Used by ClientExchange for candle data caching.
13426
13978
  */
13427
13979
  declare class PersistCandleUtils {
13428
- private PersistCandlesFactory;
13980
+ /**
13981
+ * Constructor used to create per-context candle cache instances.
13982
+ * Replaceable via usePersistCandleAdapter() / useJson() / useDummy().
13983
+ */
13984
+ private PersistCandleInstanceCtor;
13985
+ /**
13986
+ * Memoized factory creating one IPersistCandleInstance per (symbol, interval, exchange) triple.
13987
+ */
13429
13988
  private getCandlesStorage;
13430
13989
  /**
13431
- * Registers a custom persistence adapter.
13990
+ * Registers a custom IPersistCandleInstance constructor.
13991
+ * Clears the memoization cache so subsequent calls use the new adapter.
13432
13992
  *
13433
- * @param Ctor - Custom PersistBase constructor
13993
+ * @param Ctor - Custom IPersistCandleInstance constructor
13434
13994
  */
13435
- usePersistCandleAdapter(Ctor: TPersistBaseCtor<string, CandleData>): void;
13995
+ usePersistCandleAdapter(Ctor: TPersistCandleInstanceCtor): void;
13436
13996
  /**
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
13997
+ * Reads cached candles for the given context and time window.
13998
+ * Lazily initializes the instance on first access.
13445
13999
  *
13446
14000
  * @param symbol - Trading pair symbol
13447
14001
  * @param interval - Candle interval
13448
14002
  * @param exchangeName - Exchange identifier
13449
14003
  * @param limit - Number of candles requested
13450
14004
  * @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
14005
+ * @param untilTimestamp - Reserved for API compatibility
14006
+ * @returns Promise resolving to candles in order, or null on cache miss
13453
14007
  */
13454
- readCandlesData: (symbol: string, interval: CandleInterval, exchangeName: ExchangeName, limit: number, sinceTimestamp: number, _untilTimestamp: number) => Promise<CandleData[] | null>;
14008
+ readCandlesData: (symbol: string, interval: CandleInterval, exchangeName: ExchangeName, limit: number, sinceTimestamp: number, untilTimestamp: number) => Promise<CandleData[] | null>;
13455
14009
  /**
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)
14010
+ * Writes candles to cache for the given context.
14011
+ * Lazily initializes the instance on first access.
13463
14012
  *
13464
- * @param candles - Array of candle data to cache (validated by the caller)
14013
+ * @param candles - Array of candle data to cache
13465
14014
  * @param symbol - Trading pair symbol
13466
14015
  * @param interval - Candle interval
13467
14016
  * @param exchangeName - Exchange identifier
@@ -13469,19 +14018,16 @@ declare class PersistCandleUtils {
13469
14018
  */
13470
14019
  writeCandlesData: (candles: CandleData[], symbol: string, interval: CandleInterval, exchangeName: ExchangeName) => Promise<void>;
13471
14020
  /**
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.
14021
+ * Clears the memoized instance cache.
14022
+ * Call when process.cwd() changes between strategy iterations.
13475
14023
  */
13476
14024
  clear(): void;
13477
14025
  /**
13478
- * Switches to the default JSON persist adapter.
13479
- * All future persistence writes will use JSON storage.
14026
+ * Switches to the default file-based PersistCandleInstance.
13480
14027
  */
13481
14028
  useJson(): void;
13482
14029
  /**
13483
- * Switches to a dummy persist adapter that discards all writes.
13484
- * All future persistence writes will be no-ops.
14030
+ * Switches to PersistCandleDummyInstance (always returns null on read, discards writes).
13485
14031
  */
13486
14032
  useDummy(): void;
13487
14033
  }
@@ -13506,6 +14052,90 @@ declare const PersistCandleAdapter: PersistCandleUtils;
13506
14052
  * Each signal is stored as a separate file keyed by its id.
13507
14053
  */
13508
14054
  type StorageData = IStorageSignalRow[];
14055
+ /**
14056
+ * Per-context signal storage persistence instance interface.
14057
+ * Scoped to either backtest or live mode (one instance per mode).
14058
+ *
14059
+ * Each stored signal is keyed by its `signal.id` and the read operation
14060
+ * iterates over all stored entries to return them as an array.
14061
+ *
14062
+ * Custom adapters should implement this interface to override the default
14063
+ * file-based signal storage behavior.
14064
+ */
14065
+ interface IPersistStorageInstance {
14066
+ /**
14067
+ * Initialize storage for this mode.
14068
+ *
14069
+ * @param initial - Whether this is the first initialization
14070
+ * @returns Promise that resolves when initialization is complete
14071
+ */
14072
+ waitForInit(initial: boolean): Promise<void>;
14073
+ /**
14074
+ * Read all persisted signals by iterating storage keys.
14075
+ *
14076
+ * @returns Promise resolving to array of signal entries
14077
+ */
14078
+ readStorageData(): Promise<StorageData>;
14079
+ /**
14080
+ * Write signals to storage. Each signal is keyed by its `signal.id`.
14081
+ *
14082
+ * @param signals - Signal entries to persist
14083
+ * @returns Promise that resolves when all writes are complete
14084
+ */
14085
+ writeStorageData(signals: StorageData): Promise<void>;
14086
+ }
14087
+ /**
14088
+ * Default file-based implementation of IPersistStorageInstance.
14089
+ *
14090
+ * Features:
14091
+ * - Each signal stored as separate JSON file keyed by signal.id
14092
+ * - Read iterates all keys via PersistBase.keys()
14093
+ * - Crash-safe via atomic writes
14094
+ *
14095
+ * @example
14096
+ * ```typescript
14097
+ * const instance = new PersistStorageInstance(false);
14098
+ * await instance.waitForInit(true);
14099
+ * await instance.writeStorageData(signals);
14100
+ * const all = await instance.readStorageData();
14101
+ * ```
14102
+ */
14103
+ declare class PersistStorageInstance implements IPersistStorageInstance {
14104
+ readonly backtest: boolean;
14105
+ /** Underlying file-based storage for this mode */
14106
+ private readonly _storage;
14107
+ /**
14108
+ * Creates new signal storage persistence instance.
14109
+ *
14110
+ * @param backtest - True for backtest mode storage, false for live mode
14111
+ */
14112
+ constructor(backtest: boolean);
14113
+ /**
14114
+ * Initializes the underlying PersistBase storage.
14115
+ *
14116
+ * @param initial - Whether this is the first initialization
14117
+ * @returns Promise that resolves when initialization is complete
14118
+ */
14119
+ waitForInit(initial: boolean): Promise<void>;
14120
+ /**
14121
+ * Reads all persisted signals by iterating storage keys.
14122
+ *
14123
+ * @returns Promise resolving to array of signal entries
14124
+ */
14125
+ readStorageData(): Promise<StorageData>;
14126
+ /**
14127
+ * Writes each signal as a separate entity keyed by `signal.id`.
14128
+ *
14129
+ * @param signals - Signal entries to persist
14130
+ * @returns Promise that resolves when all writes are complete
14131
+ */
14132
+ writeStorageData(signals: StorageData): Promise<void>;
14133
+ }
14134
+ /**
14135
+ * Constructor type for IPersistStorageInstance.
14136
+ * Used by PersistStorageUtils.usePersistStorageAdapter() to register custom adapters.
14137
+ */
14138
+ type TPersistStorageInstanceCtor = new (backtest: boolean) => IPersistStorageInstance;
13509
14139
  /**
13510
14140
  * Utility class for managing signal storage persistence.
13511
14141
  *
@@ -13519,51 +14149,51 @@ type StorageData = IStorageSignalRow[];
13519
14149
  * Used by SignalLiveUtils for live mode persistence of signals.
13520
14150
  */
13521
14151
  declare class PersistStorageUtils {
13522
- private PersistStorageFactory;
14152
+ /**
14153
+ * Constructor used to create per-mode signal storage instances.
14154
+ * Replaceable via usePersistStorageAdapter() / useJson() / useDummy().
14155
+ */
14156
+ private PersistStorageInstanceCtor;
14157
+ /**
14158
+ * Memoized factory creating one IPersistStorageInstance per mode (backtest/live).
14159
+ * Key: "backtest" or "live".
14160
+ */
13523
14161
  private getStorage;
13524
14162
  /**
13525
- * Registers a custom persistence adapter.
14163
+ * Registers a custom IPersistStorageInstance constructor.
14164
+ * Clears the memoization cache so subsequent calls use the new adapter.
13526
14165
  *
13527
- * @param Ctor - Custom PersistBase constructor
14166
+ * @param Ctor - Custom IPersistStorageInstance constructor
13528
14167
  */
13529
- usePersistStorageAdapter(Ctor: TPersistBaseCtor<string, IStorageSignalRow>): void;
14168
+ usePersistStorageAdapter(Ctor: TPersistStorageInstanceCtor): void;
13530
14169
  /**
13531
- * Reads persisted signals data.
14170
+ * Reads all persisted signals for the given mode.
14171
+ * Lazily initializes the instance on first access.
13532
14172
  *
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
14173
+ * @param backtest - True for backtest mode storage, false for live mode
13538
14174
  * @returns Promise resolving to array of signal entries
13539
14175
  */
13540
14176
  readStorageData: (backtest: boolean) => Promise<StorageData>;
13541
14177
  /**
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.
14178
+ * Writes signals for the given mode.
14179
+ * Lazily initializes the instance on first access.
13547
14180
  *
13548
14181
  * @param signalData - Signal entries to persist
13549
- * @param backtest - If true, writes to backtest storage; otherwise to live storage
14182
+ * @param backtest - True for backtest mode storage, false for live mode
13550
14183
  * @returns Promise that resolves when write is complete
13551
14184
  */
13552
14185
  writeStorageData: (signalData: StorageData, backtest: boolean) => Promise<void>;
13553
14186
  /**
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.
14187
+ * Clears the memoized instance cache.
14188
+ * Call when process.cwd() changes between strategy iterations.
13557
14189
  */
13558
14190
  clear(): void;
13559
14191
  /**
13560
- * Switches to the default JSON persist adapter.
13561
- * All future persistence writes will use JSON storage.
14192
+ * Switches to the default file-based PersistStorageInstance.
13562
14193
  */
13563
14194
  useJson(): void;
13564
14195
  /**
13565
- * Switches to a dummy persist adapter that discards all writes.
13566
- * All future persistence writes will be no-ops.
14196
+ * Switches to PersistStorageDummyInstance (all operations are no-ops).
13567
14197
  */
13568
14198
  useDummy(): void;
13569
14199
  }
@@ -13577,6 +14207,90 @@ declare const PersistStorageAdapter: PersistStorageUtils;
13577
14207
  * Each notification is stored as a separate file keyed by its id.
13578
14208
  */
13579
14209
  type NotificationData = NotificationModel[];
14210
+ /**
14211
+ * Per-context notification persistence instance interface.
14212
+ * Scoped to either backtest or live mode (one instance per mode).
14213
+ *
14214
+ * Each notification is keyed by its id and the read operation iterates over
14215
+ * all stored notifications.
14216
+ *
14217
+ * Custom adapters should implement this interface to override the default
14218
+ * file-based notification storage behavior.
14219
+ */
14220
+ interface IPersistNotificationInstance {
14221
+ /**
14222
+ * Initialize storage for this mode.
14223
+ *
14224
+ * @param initial - Whether this is the first initialization
14225
+ * @returns Promise that resolves when initialization is complete
14226
+ */
14227
+ waitForInit(initial: boolean): Promise<void>;
14228
+ /**
14229
+ * Read all persisted notifications by iterating storage keys.
14230
+ *
14231
+ * @returns Promise resolving to array of notification entries
14232
+ */
14233
+ readNotificationData(): Promise<NotificationData>;
14234
+ /**
14235
+ * Write notifications to storage. Each notification is keyed by its id.
14236
+ *
14237
+ * @param notifications - Notification entries to persist
14238
+ * @returns Promise that resolves when all writes are complete
14239
+ */
14240
+ writeNotificationData(notifications: NotificationData): Promise<void>;
14241
+ }
14242
+ /**
14243
+ * Default file-based implementation of IPersistNotificationInstance.
14244
+ *
14245
+ * Features:
14246
+ * - Each notification stored as separate JSON file keyed by id
14247
+ * - Read iterates all keys via PersistBase.keys()
14248
+ * - Crash-safe via atomic writes
14249
+ *
14250
+ * @example
14251
+ * ```typescript
14252
+ * const instance = new PersistNotificationInstance(false);
14253
+ * await instance.waitForInit(true);
14254
+ * await instance.writeNotificationData(notifications);
14255
+ * const all = await instance.readNotificationData();
14256
+ * ```
14257
+ */
14258
+ declare class PersistNotificationInstance implements IPersistNotificationInstance {
14259
+ readonly backtest: boolean;
14260
+ /** Underlying file-based storage for this mode */
14261
+ private readonly _storage;
14262
+ /**
14263
+ * Creates new notification persistence instance.
14264
+ *
14265
+ * @param backtest - True for backtest mode storage, false for live mode
14266
+ */
14267
+ constructor(backtest: boolean);
14268
+ /**
14269
+ * Initializes the underlying PersistBase storage.
14270
+ *
14271
+ * @param initial - Whether this is the first initialization
14272
+ * @returns Promise that resolves when initialization is complete
14273
+ */
14274
+ waitForInit(initial: boolean): Promise<void>;
14275
+ /**
14276
+ * Reads all persisted notifications by iterating storage keys.
14277
+ *
14278
+ * @returns Promise resolving to array of notification entries
14279
+ */
14280
+ readNotificationData(): Promise<NotificationData>;
14281
+ /**
14282
+ * Writes each notification as a separate entity keyed by `notification.id`.
14283
+ *
14284
+ * @param notifications - Notification entries to persist
14285
+ * @returns Promise that resolves when all writes are complete
14286
+ */
14287
+ writeNotificationData(notifications: NotificationData): Promise<void>;
14288
+ }
14289
+ /**
14290
+ * Constructor type for IPersistNotificationInstance.
14291
+ * Used by PersistNotificationUtils.usePersistNotificationAdapter() to register custom adapters.
14292
+ */
14293
+ type TPersistNotificationInstanceCtor = new (backtest: boolean) => IPersistNotificationInstance;
13580
14294
  /**
13581
14295
  * Utility class for managing notification persistence.
13582
14296
  *
@@ -13590,51 +14304,52 @@ type NotificationData = NotificationModel[];
13590
14304
  * Used by NotificationPersistLiveUtils/NotificationPersistBacktestUtils for persistence.
13591
14305
  */
13592
14306
  declare class PersistNotificationUtils {
13593
- private PersistNotificationFactory;
14307
+ /**
14308
+ * Constructor used to create per-mode notification instances.
14309
+ * Replaceable via usePersistNotificationAdapter() / useJson() / useDummy().
14310
+ */
14311
+ private PersistNotificationInstanceCtor;
14312
+ /**
14313
+ * Memoized factory creating one IPersistNotificationInstance per mode (backtest/live).
14314
+ * Key: "backtest" or "live".
14315
+ */
13594
14316
  private getNotificationStorage;
13595
14317
  /**
13596
- * Registers a custom persistence adapter.
14318
+ * Registers a custom IPersistNotificationInstance constructor.
14319
+ * Clears the memoization cache so subsequent calls use the new adapter.
13597
14320
  *
13598
- * @param Ctor - Custom PersistBase constructor
14321
+ * @param Ctor - Custom IPersistNotificationInstance constructor
13599
14322
  */
13600
- usePersistNotificationAdapter(Ctor: TPersistBaseCtor<string, NotificationModel>): void;
14323
+ usePersistNotificationAdapter(Ctor: TPersistNotificationInstanceCtor): void;
13601
14324
  /**
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.
14325
+ * Reads persisted notifications for the given mode.
14326
+ * Lazily initializes the instance on first access.
13607
14327
  *
13608
- * @param backtest - If true, reads from backtest storage; otherwise from live storage
14328
+ * @param backtest - True for backtest mode storage, false for live mode
13609
14329
  * @returns Promise resolving to array of notification entries
13610
14330
  */
13611
14331
  readNotificationData: (backtest: boolean) => Promise<NotificationData>;
13612
14332
  /**
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.
14333
+ * Writes notifications for the given mode.
14334
+ * Lazily initializes the instance on first access.
13618
14335
  *
13619
14336
  * @param notificationData - Notification entries to persist
13620
- * @param backtest - If true, writes to backtest storage; otherwise to live storage
14337
+ * @param backtest - True for backtest mode storage, false for live mode
13621
14338
  * @returns Promise that resolves when write is complete
13622
14339
  */
13623
14340
  writeNotificationData: (notificationData: NotificationData, backtest: boolean) => Promise<void>;
13624
14341
  /**
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.
14342
+ * Clears the memoized instance cache.
14343
+ * Call when process.cwd() changes between strategy iterations so new
14344
+ * instances are created with the updated base path.
13628
14345
  */
13629
14346
  clear(): void;
13630
14347
  /**
13631
- * Switches to the default JSON persist adapter.
13632
- * All future persistence writes will use JSON storage.
14348
+ * Switches to the default file-based PersistNotificationInstance.
13633
14349
  */
13634
14350
  useJson(): void;
13635
14351
  /**
13636
- * Switches to a dummy persist adapter that discards all writes.
13637
- * All future persistence writes will be no-ops.
14352
+ * Switches to PersistNotificationDummyInstance (all operations are no-ops).
13638
14353
  */
13639
14354
  useDummy(): void;
13640
14355
  }
@@ -13649,11 +14364,98 @@ declare const PersistNotificationAdapter: PersistNotificationUtils;
13649
14364
  * Each log entry is stored as a separate file keyed by its id.
13650
14365
  */
13651
14366
  type LogData = ILogEntry[];
14367
+ /**
14368
+ * Global log entry persistence instance interface.
14369
+ * Unlike other Persist instances, log storage has no context — there is
14370
+ * a single global instance per process.
14371
+ *
14372
+ * Each log entry is keyed by its id and the read operation iterates over
14373
+ * all stored entries.
14374
+ *
14375
+ * Custom adapters should implement this interface to override the default
14376
+ * file-based log storage behavior.
14377
+ */
14378
+ interface IPersistLogInstance {
14379
+ /**
14380
+ * Initialize the global log storage.
14381
+ *
14382
+ * @param initial - Whether this is the first initialization
14383
+ * @returns Promise that resolves when initialization is complete
14384
+ */
14385
+ waitForInit(initial: boolean): Promise<void>;
14386
+ /**
14387
+ * Read all persisted log entries by iterating storage keys.
14388
+ *
14389
+ * @returns Promise resolving to array of log entries
14390
+ */
14391
+ readLogData(): Promise<LogData>;
14392
+ /**
14393
+ * Write log entries to storage. Each entry is keyed by its id.
14394
+ * Implementations should skip entries whose id already exists to keep
14395
+ * the log append-only.
14396
+ *
14397
+ * @param entries - Log entries to persist
14398
+ * @returns Promise that resolves when all writes are complete
14399
+ */
14400
+ writeLogData(entries: LogData): Promise<void>;
14401
+ }
14402
+ /**
14403
+ * Default file-based implementation of IPersistLogInstance.
14404
+ *
14405
+ * Features:
14406
+ * - Each log entry stored as separate JSON file keyed by entry.id
14407
+ * - Read iterates all keys via PersistBase.keys()
14408
+ * - Append-only: existing keys are skipped on write
14409
+ * - Crash-safe via atomic writes
14410
+ *
14411
+ * @example
14412
+ * ```typescript
14413
+ * const instance = new PersistLogInstance();
14414
+ * await instance.waitForInit(true);
14415
+ * await instance.writeLogData(entries);
14416
+ * const all = await instance.readLogData();
14417
+ * ```
14418
+ */
14419
+ declare class PersistLogInstance implements IPersistLogInstance {
14420
+ /** Underlying file-based storage for log entries */
14421
+ private readonly _storage;
14422
+ /**
14423
+ * Creates new log persistence instance.
14424
+ * No context parameters — there is a single global log storage.
14425
+ */
14426
+ constructor();
14427
+ /**
14428
+ * Initializes the underlying PersistBase storage.
14429
+ *
14430
+ * @param initial - Whether this is the first initialization
14431
+ * @returns Promise that resolves when initialization is complete
14432
+ */
14433
+ waitForInit(initial: boolean): Promise<void>;
14434
+ /**
14435
+ * Reads all persisted log entries by iterating storage keys.
14436
+ *
14437
+ * @returns Promise resolving to array of log entries
14438
+ */
14439
+ readLogData(): Promise<LogData>;
14440
+ /**
14441
+ * Writes log entries append-only — skips entries whose id already exists
14442
+ * so the log file is never overwritten.
14443
+ *
14444
+ * @param logData - Log entries to persist
14445
+ * @returns Promise that resolves when all writes are complete
14446
+ */
14447
+ writeLogData(logData: LogData): Promise<void>;
14448
+ }
14449
+ /**
14450
+ * Constructor type for IPersistLogInstance.
14451
+ * Used by PersistLogUtils.usePersistLogAdapter() to register custom adapters.
14452
+ */
14453
+ type TPersistLogInstanceCtor = new () => IPersistLogInstance;
13652
14454
  /**
13653
14455
  * Utility class for managing log entry persistence.
13654
14456
  *
13655
14457
  * Features:
13656
- * - Memoized storage instance
14458
+ * - Cached storage instance
13657
14459
  * - Custom adapter support
13658
14460
  * - Atomic read/write operations for LogData
13659
14461
  * - Each log entry stored as separate file keyed by id
@@ -13662,50 +14464,55 @@ type LogData = ILogEntry[];
13662
14464
  * Used by LogPersistUtils for log entry persistence.
13663
14465
  */
13664
14466
  declare class PersistLogUtils {
13665
- private PersistLogFactory;
13666
- private _logStorage;
13667
- private getLogStorage;
13668
14467
  /**
13669
- * Registers a custom persistence adapter.
14468
+ * Constructor used to create the global log instance.
14469
+ * Replaceable via usePersistLogAdapter() / useJson() / useDummy().
14470
+ */
14471
+ private PersistLogInstanceCtor;
14472
+ /**
14473
+ * Cached singleton log instance. Lazily created on first access.
14474
+ * Reset to null by clear() and usePersistLogAdapter().
14475
+ */
14476
+ private _logInstance;
14477
+ /**
14478
+ * Returns the cached log instance, creating it on first access.
13670
14479
  *
13671
- * @param Ctor - Custom PersistBase constructor
14480
+ * @returns The IPersistLogInstance singleton
13672
14481
  */
13673
- usePersistLogAdapter(Ctor: TPersistBaseCtor<string, ILogEntry>): void;
14482
+ private getLogInstance;
13674
14483
  /**
13675
- * Reads persisted log entries.
14484
+ * Registers a custom IPersistLogInstance constructor.
14485
+ * Drops the cached instance so the next access uses the new adapter.
13676
14486
  *
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.
14487
+ * @param Ctor - Custom IPersistLogInstance constructor
14488
+ */
14489
+ usePersistLogAdapter(Ctor: TPersistLogInstanceCtor): void;
14490
+ /**
14491
+ * Reads all persisted log entries.
14492
+ * Lazily initializes the instance on first access.
13680
14493
  *
13681
14494
  * @returns Promise resolving to array of log entries
13682
14495
  */
13683
14496
  readLogData: () => Promise<LogData>;
13684
14497
  /**
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.
14498
+ * Writes log entries (append-only duplicates by id are skipped).
14499
+ * Lazily initializes the instance on first access.
13690
14500
  *
13691
14501
  * @param logData - Log entries to persist
13692
14502
  * @returns Promise that resolves when write is complete
13693
14503
  */
13694
14504
  writeLogData: (logData: LogData) => Promise<void>;
13695
14505
  /**
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.
14506
+ * Drops the cached log instance.
14507
+ * Call when process.cwd() changes between strategy iterations.
13699
14508
  */
13700
14509
  clear(): void;
13701
14510
  /**
13702
- * Switches to the default JSON persist adapter.
13703
- * All future persistence writes will use JSON storage.
14511
+ * Switches to the default file-based PersistLogInstance.
13704
14512
  */
13705
14513
  useJson(): void;
13706
14514
  /**
13707
- * Switches to a dummy persist adapter that discards all writes.
13708
- * All future persistence writes will be no-ops.
14515
+ * Switches to PersistLogDummyInstance (all operations are no-ops).
13709
14516
  */
13710
14517
  useDummy(): void;
13711
14518
  }
@@ -13714,6 +14521,122 @@ declare class PersistLogUtils {
13714
14521
  * Used by LogPersistUtils for log entry persistence.
13715
14522
  */
13716
14523
  declare const PersistLogAdapter: PersistLogUtils;
14524
+ /**
14525
+ * Per-bucket measure cache persistence instance interface.
14526
+ * Used by Cache.file for caching external API responses.
14527
+ *
14528
+ * Supports soft delete: removed entries stay on disk with `removed: true`
14529
+ * flag and are filtered out by read/list operations.
14530
+ *
14531
+ * Custom adapters should implement this interface to override the default
14532
+ * file-based measure cache behavior.
14533
+ */
14534
+ interface IPersistMeasureInstance {
14535
+ /**
14536
+ * Initialize storage for this bucket.
14537
+ *
14538
+ * @param initial - Whether this is the first initialization
14539
+ * @returns Promise that resolves when initialization is complete
14540
+ */
14541
+ waitForInit(initial: boolean): Promise<void>;
14542
+ /**
14543
+ * Read cached entry by key.
14544
+ *
14545
+ * @param key - Cache key within the bucket
14546
+ * @returns Promise resolving to cached value, or null if not found or soft-deleted
14547
+ */
14548
+ readMeasureData(key: string): Promise<MeasureData | null>;
14549
+ /**
14550
+ * Write entry to cache.
14551
+ *
14552
+ * @param data - Data to cache
14553
+ * @param key - Cache key within the bucket
14554
+ * @returns Promise that resolves when write is complete
14555
+ */
14556
+ writeMeasureData(data: MeasureData, key: string, when: Date): Promise<void>;
14557
+ /**
14558
+ * Soft-delete an entry by setting its `removed` flag.
14559
+ * File stays on disk, but subsequent reads return null.
14560
+ *
14561
+ * @param key - Cache key within the bucket
14562
+ * @returns Promise that resolves when removal is complete
14563
+ */
14564
+ removeMeasureData(key: string): Promise<void>;
14565
+ /**
14566
+ * Iterate all non-removed entry keys for this bucket.
14567
+ *
14568
+ * @returns AsyncGenerator yielding entry keys
14569
+ */
14570
+ listMeasureData(): AsyncGenerator<string>;
14571
+ }
14572
+ /**
14573
+ * Default file-based implementation of IPersistMeasureInstance.
14574
+ *
14575
+ * Features:
14576
+ * - Wraps PersistBase for atomic JSON writes
14577
+ * - Soft delete via `removed: true` flag
14578
+ * - listMeasureData filters out removed entries
14579
+ *
14580
+ * @example
14581
+ * ```typescript
14582
+ * const instance = new PersistMeasureInstance("my-bucket");
14583
+ * await instance.waitForInit(true);
14584
+ * await instance.writeMeasureData({ id: "x", data: {}, removed: false }, "key1");
14585
+ * const data = await instance.readMeasureData("key1");
14586
+ * await instance.removeMeasureData("key1");
14587
+ * ```
14588
+ */
14589
+ declare class PersistMeasureInstance implements IPersistMeasureInstance {
14590
+ readonly bucket: string;
14591
+ /** Underlying file-based storage for this bucket */
14592
+ private readonly _storage;
14593
+ /**
14594
+ * Creates new measure cache persistence instance.
14595
+ *
14596
+ * @param bucket - Cache bucket identifier
14597
+ */
14598
+ constructor(bucket: string);
14599
+ /**
14600
+ * Initializes the underlying PersistBase storage.
14601
+ *
14602
+ * @param initial - Whether this is the first initialization
14603
+ * @returns Promise that resolves when initialization is complete
14604
+ */
14605
+ waitForInit(initial: boolean): Promise<void>;
14606
+ /**
14607
+ * Reads a measure entry by key. Returns null if entry is missing or soft-deleted.
14608
+ *
14609
+ * @param key - Cache key within the bucket
14610
+ * @returns Promise resolving to entry data, or null
14611
+ */
14612
+ readMeasureData(key: string): Promise<MeasureData | null>;
14613
+ /**
14614
+ * Writes a measure entry under the given key.
14615
+ *
14616
+ * @param data - Data to cache
14617
+ * @param key - Cache key within the bucket
14618
+ * @returns Promise that resolves when write is complete
14619
+ */
14620
+ writeMeasureData(data: MeasureData, key: string): Promise<void>;
14621
+ /**
14622
+ * Soft-deletes an entry by writing `removed: true` flag while preserving the file.
14623
+ *
14624
+ * @param key - Cache key within the bucket
14625
+ * @returns Promise that resolves when removal is complete
14626
+ */
14627
+ removeMeasureData(key: string): Promise<void>;
14628
+ /**
14629
+ * Iterates all entries in the bucket, yielding keys of non-removed entries only.
14630
+ *
14631
+ * @returns AsyncGenerator yielding entry keys
14632
+ */
14633
+ listMeasureData(): AsyncGenerator<string>;
14634
+ }
14635
+ /**
14636
+ * Constructor type for IPersistMeasureInstance.
14637
+ * Used by PersistMeasureUtils.usePersistMeasureAdapter() to register custom adapters.
14638
+ */
14639
+ type TPersistMeasureInstanceCtor = new (bucket: string) => IPersistMeasureInstance;
13717
14640
  /**
13718
14641
  * Utility class for managing external API response cache persistence.
13719
14642
  *
@@ -13726,60 +14649,69 @@ declare const PersistLogAdapter: PersistLogUtils;
13726
14649
  * Used by Cache.file for persistent caching of external API responses.
13727
14650
  */
13728
14651
  declare class PersistMeasureUtils {
13729
- private PersistMeasureFactory;
14652
+ /**
14653
+ * Constructor used to create per-bucket measure cache instances.
14654
+ * Replaceable via usePersistMeasureAdapter() / useJson() / useDummy().
14655
+ */
14656
+ private PersistMeasureInstanceCtor;
14657
+ /**
14658
+ * Memoized factory creating one IPersistMeasureInstance per bucket.
14659
+ */
13730
14660
  private getMeasureStorage;
13731
14661
  /**
13732
- * Registers a custom persistence adapter.
14662
+ * Registers a custom IPersistMeasureInstance constructor.
14663
+ * Clears the memoization cache so subsequent calls use the new adapter.
13733
14664
  *
13734
- * @param Ctor - Custom PersistBase constructor
14665
+ * @param Ctor - Custom IPersistMeasureInstance constructor
13735
14666
  */
13736
- usePersistMeasureAdapter(Ctor: TPersistBaseCtor<string, MeasureData>): void;
14667
+ usePersistMeasureAdapter(Ctor: TPersistMeasureInstanceCtor): void;
13737
14668
  /**
13738
- * Reads cached measure data for a given bucket and key.
14669
+ * Reads a measure entry from the given bucket by key.
14670
+ * Lazily initializes the bucket instance on first access.
13739
14671
  *
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
14672
+ * @param bucket - Storage bucket identifier
14673
+ * @param key - Cache key within the bucket
14674
+ * @returns Promise resolving to cached value, or null if not found / soft-deleted
13743
14675
  */
13744
14676
  readMeasureData: (bucket: string, key: string) => Promise<MeasureData | null>;
13745
14677
  /**
13746
- * Writes measure data to disk with atomic file writes.
14678
+ * Writes a measure entry to the given bucket under the given key.
14679
+ * Lazily initializes the bucket instance on first access.
13747
14680
  *
13748
14681
  * @param data - Data to cache
13749
- * @param bucket - Storage bucket (e.g. aligned timestamp + symbol)
13750
- * @param key - Dynamic cache key within the bucket
14682
+ * @param bucket - Storage bucket identifier
14683
+ * @param key - Cache key within the bucket
13751
14684
  * @returns Promise that resolves when write is complete
13752
14685
  */
13753
- writeMeasureData: (data: MeasureData, bucket: string, key: string) => Promise<void>;
14686
+ writeMeasureData: (data: MeasureData, bucket: string, key: string, when: Date) => Promise<void>;
13754
14687
  /**
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`.
14688
+ * Soft-deletes a measure entry in the given bucket by setting `removed: true`.
14689
+ * Lazily initializes the bucket instance on first access.
13757
14690
  *
13758
- * @param bucket - Storage bucket
13759
- * @param key - Dynamic cache key within the bucket
14691
+ * @param bucket - Storage bucket identifier
14692
+ * @param key - Cache key within the bucket
13760
14693
  * @returns Promise that resolves when removal is complete
13761
14694
  */
13762
14695
  removeMeasureData: (bucket: string, key: string) => Promise<void>;
13763
14696
  /**
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.
14697
+ * Iterates all non-removed measure entries for the given bucket.
14698
+ * Lazily initializes the bucket instance on first access.
13766
14699
  *
13767
- * @param bucket - Storage bucket
13768
- * @returns AsyncGenerator yielding entity keys
14700
+ * @param bucket - Storage bucket identifier
14701
+ * @returns AsyncGenerator yielding entry keys
13769
14702
  */
13770
14703
  listMeasureData(bucket: string): AsyncGenerator<string>;
13771
14704
  /**
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.
14705
+ * Clears the memoized bucket instance cache.
14706
+ * Call when process.cwd() changes between strategy iterations.
13775
14707
  */
13776
14708
  clear(): void;
13777
14709
  /**
13778
- * Switches to the default JSON persist adapter.
14710
+ * Switches to the default file-based PersistMeasureInstance.
13779
14711
  */
13780
14712
  useJson(): void;
13781
14713
  /**
13782
- * Switches to a dummy persist adapter that discards all writes.
14714
+ * Switches to PersistMeasureDummyInstance (all operations are no-ops).
13783
14715
  */
13784
14716
  useDummy(): void;
13785
14717
  }
@@ -13788,6 +14720,124 @@ declare class PersistMeasureUtils {
13788
14720
  * Used by Cache.file for persistent caching of external API responses.
13789
14721
  */
13790
14722
  declare const PersistMeasureAdapter: PersistMeasureUtils;
14723
+ /**
14724
+ * Per-bucket interval marker persistence instance interface.
14725
+ * Used by Interval.file for once-per-interval signal firing.
14726
+ *
14727
+ * A record's presence means the interval has already fired for that
14728
+ * bucket+key. Soft-deleted records (removed=true) act as if absent,
14729
+ * allowing the function to fire again.
14730
+ *
14731
+ * Custom adapters should implement this interface to override the default
14732
+ * file-based interval marker behavior.
14733
+ */
14734
+ interface IPersistIntervalInstance {
14735
+ /**
14736
+ * Initialize storage for this bucket.
14737
+ *
14738
+ * @param initial - Whether this is the first initialization
14739
+ * @returns Promise that resolves when initialization is complete
14740
+ */
14741
+ waitForInit(initial: boolean): Promise<void>;
14742
+ /**
14743
+ * Read interval marker by key.
14744
+ *
14745
+ * @param key - Marker key within the bucket
14746
+ * @returns Promise resolving to stored value, or null if not found or soft-deleted
14747
+ */
14748
+ readIntervalData(key: string): Promise<IntervalData | null>;
14749
+ /**
14750
+ * Write interval marker.
14751
+ *
14752
+ * @param data - Data to store
14753
+ * @param key - Marker key within the bucket
14754
+ * @returns Promise that resolves when write is complete
14755
+ */
14756
+ writeIntervalData(data: IntervalData, key: string, when: Date): Promise<void>;
14757
+ /**
14758
+ * Soft-delete a marker. After this call the function will fire again
14759
+ * on the next IntervalFileInstance.run call for the same key.
14760
+ *
14761
+ * @param key - Marker key within the bucket
14762
+ * @returns Promise that resolves when removal is complete
14763
+ */
14764
+ removeIntervalData(key: string): Promise<void>;
14765
+ /**
14766
+ * Iterate all non-removed marker keys for this bucket.
14767
+ *
14768
+ * @returns AsyncGenerator yielding marker keys
14769
+ */
14770
+ listIntervalData(): AsyncGenerator<string>;
14771
+ }
14772
+ /**
14773
+ * Default file-based implementation of IPersistIntervalInstance.
14774
+ *
14775
+ * Features:
14776
+ * - Wraps PersistBase for atomic JSON writes
14777
+ * - Soft delete via `removed: true` flag
14778
+ * - listIntervalData filters out removed markers
14779
+ *
14780
+ * @example
14781
+ * ```typescript
14782
+ * const instance = new PersistIntervalInstance("my-interval-bucket");
14783
+ * await instance.waitForInit(true);
14784
+ * await instance.writeIntervalData({ id: "x", data: {}, removed: false }, "key1");
14785
+ * const marker = await instance.readIntervalData("key1");
14786
+ * await instance.removeIntervalData("key1");
14787
+ * ```
14788
+ */
14789
+ declare class PersistIntervalInstance implements IPersistIntervalInstance {
14790
+ readonly bucket: string;
14791
+ /** Underlying file-based storage for this bucket */
14792
+ private readonly _storage;
14793
+ /**
14794
+ * Creates new interval marker persistence instance.
14795
+ *
14796
+ * @param bucket - Marker bucket identifier
14797
+ */
14798
+ constructor(bucket: string);
14799
+ /**
14800
+ * Initializes the underlying PersistBase storage.
14801
+ *
14802
+ * @param initial - Whether this is the first initialization
14803
+ * @returns Promise that resolves when initialization is complete
14804
+ */
14805
+ waitForInit(initial: boolean): Promise<void>;
14806
+ /**
14807
+ * Reads an interval marker by key. Returns null if marker is missing or soft-deleted.
14808
+ *
14809
+ * @param key - Marker key within the bucket
14810
+ * @returns Promise resolving to stored data, or null
14811
+ */
14812
+ readIntervalData(key: string): Promise<IntervalData | null>;
14813
+ /**
14814
+ * Writes an interval marker under the given key.
14815
+ *
14816
+ * @param data - Data to store
14817
+ * @param key - Marker key within the bucket
14818
+ * @returns Promise that resolves when write is complete
14819
+ */
14820
+ writeIntervalData(data: IntervalData, key: string): Promise<void>;
14821
+ /**
14822
+ * Soft-deletes a marker by writing `removed: true` flag while preserving the file.
14823
+ * Subsequent reads will return null, allowing the interval to fire again.
14824
+ *
14825
+ * @param key - Marker key within the bucket
14826
+ * @returns Promise that resolves when removal is complete
14827
+ */
14828
+ removeIntervalData(key: string): Promise<void>;
14829
+ /**
14830
+ * Iterates all markers in the bucket, yielding keys of non-removed markers only.
14831
+ *
14832
+ * @returns AsyncGenerator yielding marker keys
14833
+ */
14834
+ listIntervalData(): AsyncGenerator<string>;
14835
+ }
14836
+ /**
14837
+ * Constructor type for IPersistIntervalInstance.
14838
+ * Used by PersistIntervalUtils.usePersistIntervalAdapter() to register custom adapters.
14839
+ */
14840
+ type TPersistIntervalInstanceCtor = new (bucket: string) => IPersistIntervalInstance;
13791
14841
  /**
13792
14842
  * Persistence layer for Interval.file once-per-interval signal firing.
13793
14843
  *
@@ -13796,60 +14846,69 @@ declare const PersistMeasureAdapter: PersistMeasureUtils;
13796
14846
  * absence means the function has not yet fired (or returned null last time).
13797
14847
  */
13798
14848
  declare class PersistIntervalUtils {
13799
- private PersistIntervalFactory;
14849
+ /**
14850
+ * Constructor used to create per-bucket interval marker instances.
14851
+ * Replaceable via usePersistIntervalAdapter() / useJson() / useDummy().
14852
+ */
14853
+ private PersistIntervalInstanceCtor;
14854
+ /**
14855
+ * Memoized factory creating one IPersistIntervalInstance per bucket.
14856
+ */
13800
14857
  private getIntervalStorage;
13801
14858
  /**
13802
- * Registers a custom persistence adapter.
14859
+ * Registers a custom IPersistIntervalInstance constructor.
14860
+ * Clears the memoization cache so subsequent calls use the new adapter.
13803
14861
  *
13804
- * @param Ctor - Custom PersistBase constructor
14862
+ * @param Ctor - Custom IPersistIntervalInstance constructor
13805
14863
  */
13806
- usePersistIntervalAdapter(Ctor: TPersistBaseCtor<string, IntervalData>): void;
14864
+ usePersistIntervalAdapter(Ctor: TPersistIntervalInstanceCtor): void;
13807
14865
  /**
13808
- * Reads interval data for a given bucket and key.
14866
+ * Reads an interval marker from the given bucket by key.
14867
+ * Lazily initializes the bucket instance on first access.
13809
14868
  *
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
14869
+ * @param bucket - Storage bucket identifier
14870
+ * @param key - Marker key within the bucket
14871
+ * @returns Promise resolving to marker data, or null if not found / soft-deleted
13813
14872
  */
13814
14873
  readIntervalData: (bucket: string, key: string) => Promise<IntervalData | null>;
13815
14874
  /**
13816
- * Writes interval data to disk.
14875
+ * Writes an interval marker to the given bucket under the given key.
14876
+ * Lazily initializes the bucket instance on first access.
13817
14877
  *
13818
14878
  * @param data - Data to store
13819
- * @param bucket - Storage bucket
13820
- * @param key - Entity key within the bucket
14879
+ * @param bucket - Storage bucket identifier
14880
+ * @param key - Marker key within the bucket
13821
14881
  * @returns Promise that resolves when write is complete
13822
14882
  */
13823
- writeIntervalData: (data: IntervalData, bucket: string, key: string) => Promise<void>;
14883
+ writeIntervalData: (data: IntervalData, bucket: string, key: string, when: Date) => Promise<void>;
13824
14884
  /**
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.
14885
+ * Soft-deletes a marker in the given bucket by setting `removed: true`.
14886
+ * Lazily initializes the bucket instance on first access.
13828
14887
  *
13829
- * @param bucket - Storage bucket
13830
- * @param key - Entity key within the bucket
14888
+ * @param bucket - Storage bucket identifier
14889
+ * @param key - Marker key within the bucket
13831
14890
  * @returns Promise that resolves when removal is complete
13832
14891
  */
13833
14892
  removeIntervalData: (bucket: string, key: string) => Promise<void>;
13834
14893
  /**
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.
14894
+ * Iterates all non-removed markers for the given bucket.
14895
+ * Lazily initializes the bucket instance on first access.
13837
14896
  *
13838
- * @param bucket - Storage bucket
13839
- * @returns AsyncGenerator yielding entity keys
14897
+ * @param bucket - Storage bucket identifier
14898
+ * @returns AsyncGenerator yielding marker keys
13840
14899
  */
13841
14900
  listIntervalData(bucket: string): AsyncGenerator<string>;
13842
14901
  /**
13843
- * Clears the memoized storage cache.
13844
- * Call this when process.cwd() changes between strategy iterations.
14902
+ * Clears the memoized bucket instance cache.
14903
+ * Call when process.cwd() changes between strategy iterations.
13845
14904
  */
13846
14905
  clear(): void;
13847
14906
  /**
13848
- * Switches to the default JSON persist adapter.
14907
+ * Switches to the default file-based PersistIntervalInstance.
13849
14908
  */
13850
14909
  useJson(): void;
13851
14910
  /**
13852
- * Switches to a dummy persist adapter that discards all writes.
14911
+ * Switches to PersistIntervalDummyInstance (all operations are no-ops).
13853
14912
  */
13854
14913
  useDummy(): void;
13855
14914
  }
@@ -13867,7 +14926,158 @@ type MemoryData = {
13867
14926
  data: object;
13868
14927
  removed: boolean;
13869
14928
  index: string;
14929
+ when: number;
13870
14930
  };
14931
+ /**
14932
+ * Per-context memory entry persistence instance interface.
14933
+ * Scoped to a specific (signalId, bucketName) pair.
14934
+ *
14935
+ * Used by MemoryPersistInstance for LLM memory storage. Supports soft delete
14936
+ * via `removed: true` flag — soft-deleted entries stay on disk but are
14937
+ * filtered out by read/list operations.
14938
+ *
14939
+ * Custom adapters should implement this interface to override the default
14940
+ * file-based memory entry behavior.
14941
+ */
14942
+ interface IPersistMemoryInstance {
14943
+ /**
14944
+ * Initialize storage for this memory context.
14945
+ *
14946
+ * @param initial - Whether this is the first initialization
14947
+ * @returns Promise that resolves when initialization is complete
14948
+ */
14949
+ waitForInit(initial: boolean): Promise<void>;
14950
+ /**
14951
+ * Read a memory entry by id.
14952
+ *
14953
+ * @param memoryId - Memory entry identifier
14954
+ * @returns Promise resolving to entry data, or null if not found or soft-deleted
14955
+ */
14956
+ readMemoryData(memoryId: string): Promise<MemoryData | null>;
14957
+ /**
14958
+ * Check whether a memory entry exists (regardless of removed flag).
14959
+ *
14960
+ * @param memoryId - Memory entry identifier
14961
+ * @returns Promise resolving to true if entry exists on disk
14962
+ */
14963
+ hasMemoryData(memoryId: string): Promise<boolean>;
14964
+ /**
14965
+ * Write a memory entry.
14966
+ *
14967
+ * @param data - Entry data to persist
14968
+ * @param memoryId - Memory entry identifier
14969
+ * @returns Promise that resolves when write is complete
14970
+ */
14971
+ writeMemoryData(data: MemoryData, memoryId: string): Promise<void>;
14972
+ /**
14973
+ * Soft-delete a memory entry. File stays on disk; subsequent reads return null.
14974
+ *
14975
+ * @param memoryId - Memory entry identifier
14976
+ * @returns Promise that resolves when removal is complete
14977
+ */
14978
+ removeMemoryData(memoryId: string): Promise<void>;
14979
+ /**
14980
+ * Iterate all non-removed memory entries for this context.
14981
+ * Used by MemoryPersistInstance to rebuild the BM25 index on init.
14982
+ *
14983
+ * @returns AsyncGenerator yielding entry id + data tuples
14984
+ */
14985
+ listMemoryData(): AsyncGenerator<{
14986
+ memoryId: string;
14987
+ data: MemoryData;
14988
+ }>;
14989
+ /**
14990
+ * Release any resources held by this instance.
14991
+ * Default implementations may treat this as a no-op.
14992
+ */
14993
+ dispose(): void;
14994
+ }
14995
+ /**
14996
+ * Default file-based implementation of IPersistMemoryInstance.
14997
+ *
14998
+ * Features:
14999
+ * - Wraps PersistBase for atomic JSON writes
15000
+ * - Soft delete via `removed: true` flag
15001
+ * - listMemoryData filters out removed entries
15002
+ * - dispose is a no-op (memo cache is managed by PersistMemoryUtils)
15003
+ *
15004
+ * @example
15005
+ * ```typescript
15006
+ * const instance = new PersistMemoryInstance("signal-1", "context-bucket");
15007
+ * await instance.waitForInit(true);
15008
+ * await instance.writeMemoryData(entryData, "memory-id-1");
15009
+ * const data = await instance.readMemoryData("memory-id-1");
15010
+ * ```
15011
+ */
15012
+ declare class PersistMemoryInstance implements IPersistMemoryInstance {
15013
+ readonly signalId: string;
15014
+ readonly bucketName: string;
15015
+ /** Underlying file-based storage scoped to this context */
15016
+ private readonly _storage;
15017
+ /**
15018
+ * Creates new memory persistence instance.
15019
+ *
15020
+ * @param signalId - Signal identifier (entity folder name)
15021
+ * @param bucketName - Bucket name (subfolder under memory/)
15022
+ */
15023
+ constructor(signalId: string, bucketName: string);
15024
+ /**
15025
+ * Initializes the underlying PersistBase storage.
15026
+ *
15027
+ * @param initial - Whether this is the first initialization
15028
+ * @returns Promise that resolves when initialization is complete
15029
+ */
15030
+ waitForInit(initial: boolean): Promise<void>;
15031
+ /**
15032
+ * Reads a memory entry by id. Returns null if entry is missing or soft-deleted.
15033
+ *
15034
+ * @param memoryId - Memory entry identifier
15035
+ * @returns Promise resolving to entry data, or null
15036
+ */
15037
+ readMemoryData(memoryId: string): Promise<MemoryData | null>;
15038
+ /**
15039
+ * Checks whether a memory entry exists on disk (regardless of removed flag).
15040
+ *
15041
+ * @param memoryId - Memory entry identifier
15042
+ * @returns Promise resolving to true if entry file exists
15043
+ */
15044
+ hasMemoryData(memoryId: string): Promise<boolean>;
15045
+ /**
15046
+ * Writes a memory entry under the given id.
15047
+ *
15048
+ * @param data - Entry data to persist
15049
+ * @param memoryId - Memory entry identifier
15050
+ * @returns Promise that resolves when write is complete
15051
+ */
15052
+ writeMemoryData(data: MemoryData, memoryId: string): Promise<void>;
15053
+ /**
15054
+ * Soft-deletes a memory entry by writing `removed: true` flag.
15055
+ *
15056
+ * @param memoryId - Memory entry identifier
15057
+ * @returns Promise that resolves when removal is complete
15058
+ */
15059
+ removeMemoryData(memoryId: string): Promise<void>;
15060
+ /**
15061
+ * Iterates all memory entries in the bucket, yielding id + data tuples
15062
+ * for non-removed entries only.
15063
+ *
15064
+ * @returns AsyncGenerator yielding `{ memoryId, data }` tuples
15065
+ */
15066
+ listMemoryData(): AsyncGenerator<{
15067
+ memoryId: string;
15068
+ data: MemoryData;
15069
+ }>;
15070
+ /**
15071
+ * No-op for the default file-based implementation.
15072
+ * Resource cleanup (memo cache invalidation) is handled by PersistMemoryUtils.dispose().
15073
+ */
15074
+ dispose(): void;
15075
+ }
15076
+ /**
15077
+ * Constructor type for IPersistMemoryInstance.
15078
+ * Used by PersistMemoryUtils.usePersistMemoryAdapter() to register custom adapters.
15079
+ */
15080
+ type TPersistMemoryInstanceCtor = new (signalId: string, bucketName: string) => IPersistMemoryInstance;
13871
15081
  /**
13872
15082
  * Utility class for managing memory entry persistence.
13873
15083
  *
@@ -13882,43 +15092,45 @@ type MemoryData = {
13882
15092
  * Used by MemoryPersistInstance for crash-safe memory persistence.
13883
15093
  */
13884
15094
  declare class PersistMemoryUtils {
13885
- private PersistMemoryFactory;
15095
+ /**
15096
+ * Constructor used to create per-context memory instances.
15097
+ * Replaceable via usePersistMemoryAdapter() / useJson() / useDummy().
15098
+ */
15099
+ private PersistMemoryInstanceCtor;
15100
+ /**
15101
+ * Memoized factory creating one IPersistMemoryInstance per (signalId, bucketName) pair.
15102
+ */
13886
15103
  private getMemoryStorage;
13887
15104
  /**
13888
- * Registers a custom persistence adapter.
13889
- *
13890
- * @param Ctor - Custom PersistBase constructor
15105
+ * Registers a custom IPersistMemoryInstance constructor.
15106
+ * Clears the memoization cache so subsequent calls use the new adapter.
13891
15107
  *
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
- * ```
15108
+ * @param Ctor - Custom IPersistMemoryInstance constructor
13900
15109
  */
13901
- usePersistMemoryAdapter(Ctor: TPersistBaseCtor<string, MemoryData>): void;
15110
+ usePersistMemoryAdapter(Ctor: TPersistMemoryInstanceCtor): void;
13902
15111
  /**
13903
- * Initializes the storage for a given (signalId, bucketName) pair.
15112
+ * Initializes the memory storage for the given context.
15113
+ * Skips initialization when `initial` is false (used to gate first-time setup).
13904
15114
  *
13905
- * @param signalId - Signal identifier (entity folder name)
13906
- * @param bucketName - Bucket name (subfolder under memory/)
15115
+ * @param signalId - Signal identifier
15116
+ * @param bucketName - Bucket name
13907
15117
  * @param initial - Whether this is the first initialization
13908
15118
  * @returns Promise that resolves when initialization is complete
13909
15119
  */
13910
15120
  waitForInit: (signalId: string, bucketName: string, initial: boolean) => Promise<void>;
13911
15121
  /**
13912
- * Reads a memory entry from persistence storage.
15122
+ * Reads a memory entry for the given context and id.
15123
+ * Lazily initializes the instance on first access.
13913
15124
  *
13914
15125
  * @param signalId - Signal identifier
13915
15126
  * @param bucketName - Bucket name
13916
15127
  * @param memoryId - Memory entry identifier
13917
- * @returns Promise resolving to entry data or null if not found
15128
+ * @returns Promise resolving to entry data, or null if not found / soft-deleted
13918
15129
  */
13919
15130
  readMemoryData: (signalId: string, bucketName: string, memoryId: string) => Promise<MemoryData | null>;
13920
15131
  /**
13921
- * Checks if a memory entry exists in persistence storage.
15132
+ * Checks whether a memory entry exists on disk for the given context.
15133
+ * Lazily initializes the instance on first access.
13922
15134
  *
13923
15135
  * @param signalId - Signal identifier
13924
15136
  * @param bucketName - Bucket name
@@ -13927,7 +15139,8 @@ declare class PersistMemoryUtils {
13927
15139
  */
13928
15140
  hasMemoryData: (signalId: string, bucketName: string, memoryId: string) => Promise<boolean>;
13929
15141
  /**
13930
- * Writes a memory entry to disk with atomic file writes.
15142
+ * Writes a memory entry for the given context.
15143
+ * Lazily initializes the instance on first access.
13931
15144
  *
13932
15145
  * @param data - Entry data to persist
13933
15146
  * @param signalId - Signal identifier
@@ -13937,7 +15150,8 @@ declare class PersistMemoryUtils {
13937
15150
  */
13938
15151
  writeMemoryData: (data: MemoryData, signalId: string, bucketName: string, memoryId: string) => Promise<void>;
13939
15152
  /**
13940
- * Marks a memory entry as removed (soft delete — file is kept on disk).
15153
+ * Soft-deletes a memory entry for the given context.
15154
+ * Lazily initializes the instance on first access.
13941
15155
  *
13942
15156
  * @param signalId - Signal identifier
13943
15157
  * @param bucketName - Bucket name
@@ -13946,40 +15160,37 @@ declare class PersistMemoryUtils {
13946
15160
  */
13947
15161
  removeMemoryData: (signalId: string, bucketName: string, memoryId: string) => Promise<void>;
13948
15162
  /**
13949
- * Lists all memory entry IDs for a given (signalId, bucketName) pair.
15163
+ * Iterates all non-removed memory entries for the given context.
13950
15164
  * Used by MemoryPersistInstance to rebuild the BM25 index on init.
15165
+ * Lazily initializes the instance on first access.
13951
15166
  *
13952
15167
  * @param signalId - Signal identifier
13953
15168
  * @param bucketName - Bucket name
13954
- * @returns AsyncGenerator yielding memory entry IDs
15169
+ * @returns AsyncGenerator yielding `{ memoryId, data }` tuples
13955
15170
  */
13956
15171
  listMemoryData(signalId: string, bucketName: string): AsyncGenerator<{
13957
15172
  memoryId: string;
13958
15173
  data: MemoryData;
13959
15174
  }>;
13960
15175
  /**
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.
15176
+ * Clears the memoized instance cache.
15177
+ * Call when process.cwd() changes between strategy iterations.
13964
15178
  */
13965
15179
  clear: () => void;
13966
15180
  /**
13967
- * Disposes of the memory adapter and releases any resources.
13968
- * Call this when a signal is removed to clean up its associated storage.
15181
+ * Drops the memoized instance for the given context.
15182
+ * Call when a signal is removed to clean up its associated storage entry.
13969
15183
  *
13970
15184
  * @param signalId - Signal identifier
13971
15185
  * @param bucketName - Bucket name
13972
- * @returns void
13973
15186
  */
13974
15187
  dispose: (signalId: string, bucketName: string) => void;
13975
15188
  /**
13976
- * Switches to the default JSON persist adapter.
13977
- * All future persistence writes will use JSON storage.
15189
+ * Switches to the default file-based PersistMemoryInstance.
13978
15190
  */
13979
15191
  useJson(): void;
13980
15192
  /**
13981
- * Switches to a dummy persist adapter that discards all writes.
13982
- * All future persistence writes will be no-ops.
15193
+ * Switches to PersistMemoryDummyInstance (all operations are no-ops).
13983
15194
  */
13984
15195
  useDummy(): void;
13985
15196
  }
@@ -14005,6 +15216,96 @@ declare const PersistMemoryAdapter: PersistMemoryUtils;
14005
15216
  * Stores the latest active signal per context key.
14006
15217
  */
14007
15218
  type RecentData = IPublicSignalRow | null;
15219
+ /**
15220
+ * Per-context recent signal persistence instance interface.
15221
+ * Scoped to a specific (symbol, strategyName, exchangeName, frameName, backtest) tuple.
15222
+ *
15223
+ * Stores the latest active signal for the given context, allowing live/backtest
15224
+ * separation. Custom adapters should implement this interface to override the
15225
+ * default file-based recent signal behavior.
15226
+ */
15227
+ interface IPersistRecentInstance {
15228
+ /**
15229
+ * Initialize storage for this recent signal context.
15230
+ *
15231
+ * @param initial - Whether this is the first initialization
15232
+ * @returns Promise that resolves when initialization is complete
15233
+ */
15234
+ waitForInit(initial: boolean): Promise<void>;
15235
+ /**
15236
+ * Read the latest persisted recent signal for this context.
15237
+ *
15238
+ * @returns Promise resolving to recent signal or null if none persisted
15239
+ */
15240
+ readRecentData(): Promise<IPublicSignalRow | null>;
15241
+ /**
15242
+ * Write the latest recent signal for this context.
15243
+ *
15244
+ * @param signalRow - Recent signal data to persist
15245
+ * @returns Promise that resolves when write is complete
15246
+ */
15247
+ writeRecentData(signalRow: IPublicSignalRow): Promise<void>;
15248
+ }
15249
+ /**
15250
+ * Default file-based implementation of IPersistRecentInstance.
15251
+ *
15252
+ * Features:
15253
+ * - Wraps PersistBase for atomic JSON writes
15254
+ * - Uses symbol as entity ID within a per-context PersistBase
15255
+ * - Context key includes backtest/live mode and optional frameName
15256
+ *
15257
+ * @example
15258
+ * ```typescript
15259
+ * const instance = new PersistRecentInstance("BTCUSDT", "my-strategy", "binance", "frame-1", false);
15260
+ * await instance.waitForInit(true);
15261
+ * await instance.writeRecentData(publicSignalRow);
15262
+ * const recent = await instance.readRecentData();
15263
+ * ```
15264
+ */
15265
+ declare class PersistRecentInstance implements IPersistRecentInstance {
15266
+ readonly symbol: string;
15267
+ readonly strategyName: StrategyName;
15268
+ readonly exchangeName: ExchangeName;
15269
+ readonly frameName: FrameName;
15270
+ readonly backtest: boolean;
15271
+ /** Underlying file-based storage scoped to this context */
15272
+ private readonly _storage;
15273
+ /**
15274
+ * Creates new recent signal persistence instance.
15275
+ *
15276
+ * @param symbol - Trading pair symbol
15277
+ * @param strategyName - Strategy identifier
15278
+ * @param exchangeName - Exchange identifier
15279
+ * @param frameName - Frame identifier (may be empty for live mode)
15280
+ * @param backtest - True for backtest mode, false for live mode
15281
+ */
15282
+ constructor(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean);
15283
+ /**
15284
+ * Initializes the underlying PersistBase storage.
15285
+ *
15286
+ * @param initial - Whether this is the first initialization
15287
+ * @returns Promise that resolves when initialization is complete
15288
+ */
15289
+ waitForInit(initial: boolean): Promise<void>;
15290
+ /**
15291
+ * Reads the persisted recent signal using `symbol` as the entity key.
15292
+ *
15293
+ * @returns Promise resolving to recent signal or null if not found
15294
+ */
15295
+ readRecentData(): Promise<IPublicSignalRow | null>;
15296
+ /**
15297
+ * Writes the recent signal using `symbol` as the entity key.
15298
+ *
15299
+ * @param signalRow - Recent signal data to persist
15300
+ * @returns Promise that resolves when write is complete
15301
+ */
15302
+ writeRecentData(signalRow: IPublicSignalRow): Promise<void>;
15303
+ }
15304
+ /**
15305
+ * Constructor type for IPersistRecentInstance.
15306
+ * Used by PersistRecentUtils.usePersistRecentAdapter() to register custom adapters.
15307
+ */
15308
+ type TPersistRecentInstanceCtor = new (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean) => IPersistRecentInstance;
14008
15309
  /**
14009
15310
  * Utility class for managing recent signal persistence.
14010
15311
  *
@@ -14017,55 +15318,70 @@ type RecentData = IPublicSignalRow | null;
14017
15318
  * Used by RecentPersistBacktestUtils/RecentPersistLiveUtils for recent signal persistence.
14018
15319
  */
14019
15320
  declare class PersistRecentUtils {
14020
- private PersistRecentFactory;
14021
- private getStorage;
14022
- private createKeyParts;
14023
15321
  /**
14024
- * Registers a custom persistence adapter.
15322
+ * Constructor used to create per-context recent signal instances.
15323
+ * Replaceable via usePersistRecentAdapter() / useJson() / useDummy().
15324
+ */
15325
+ private PersistRecentInstanceCtor;
15326
+ /**
15327
+ * Builds the composite memoization key for a recent signal context.
15328
+ * Includes optional frameName and the backtest/live mode flag.
14025
15329
  *
14026
- * @param Ctor - Custom PersistBase constructor
15330
+ * @param symbol - Trading pair symbol
15331
+ * @param strategyName - Strategy identifier
15332
+ * @param exchangeName - Exchange identifier
15333
+ * @param frameName - Frame identifier (omitted from key if empty)
15334
+ * @param backtest - True for backtest mode, false for live mode
15335
+ * @returns Composite key string
15336
+ */
15337
+ private createKey;
15338
+ /**
15339
+ * Memoized factory creating one IPersistRecentInstance per context tuple.
14027
15340
  */
14028
- usePersistRecentAdapter(Ctor: TPersistBaseCtor<string, IPublicSignalRow>): void;
15341
+ private getStorage;
14029
15342
  /**
14030
- * Reads the latest persisted recent signal for a given context.
15343
+ * Registers a custom IPersistRecentInstance constructor.
15344
+ * Clears the memoization cache so subsequent calls use the new adapter.
14031
15345
  *
14032
- * Returns null if no recent signal exists.
15346
+ * @param Ctor - Custom IPersistRecentInstance constructor
15347
+ */
15348
+ usePersistRecentAdapter(Ctor: TPersistRecentInstanceCtor): void;
15349
+ /**
15350
+ * Reads the latest recent signal for the given context.
15351
+ * Lazily initializes the instance on first access.
14033
15352
  *
14034
15353
  * @param symbol - Trading pair symbol
14035
15354
  * @param strategyName - Strategy identifier
14036
15355
  * @param exchangeName - Exchange identifier
14037
- * @param frameName - Frame identifier
14038
- * @returns Promise resolving to recent signal or null
15356
+ * @param frameName - Frame identifier (may be empty)
15357
+ * @param backtest - True for backtest mode, false for live mode
15358
+ * @returns Promise resolving to recent signal or null if none persisted
14039
15359
  */
14040
15360
  readRecentData: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean) => Promise<IPublicSignalRow | null>;
14041
15361
  /**
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.
15362
+ * Writes the latest recent signal for the given context.
15363
+ * Lazily initializes the instance on first access.
14046
15364
  *
14047
15365
  * @param signalRow - Recent signal data to persist
14048
15366
  * @param symbol - Trading pair symbol
14049
15367
  * @param strategyName - Strategy identifier
14050
15368
  * @param exchangeName - Exchange identifier
14051
- * @param frameName - Frame identifier
15369
+ * @param frameName - Frame identifier (may be empty)
15370
+ * @param backtest - True for backtest mode, false for live mode
14052
15371
  * @returns Promise that resolves when write is complete
14053
15372
  */
14054
15373
  writeRecentData: (signalRow: IPublicSignalRow, symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean) => Promise<void>;
14055
15374
  /**
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.
15375
+ * Clears the memoized instance cache.
15376
+ * Call when process.cwd() changes between strategy iterations.
14059
15377
  */
14060
15378
  clear(): void;
14061
15379
  /**
14062
- * Switches to the default JSON persist adapter.
14063
- * All future persistence writes will use JSON storage.
15380
+ * Switches to the default file-based PersistRecentInstance.
14064
15381
  */
14065
15382
  useJson(): void;
14066
15383
  /**
14067
- * Switches to a dummy persist adapter that discards all writes.
14068
- * All future persistence writes will be no-ops.
15384
+ * Switches to PersistRecentDummyInstance (all operations are no-ops).
14069
15385
  */
14070
15386
  useDummy(): void;
14071
15387
  }
@@ -14081,7 +15397,102 @@ declare const PersistRecentAdapter: PersistRecentUtils;
14081
15397
  type StateData = {
14082
15398
  id: string;
14083
15399
  data: object;
15400
+ when: number;
14084
15401
  };
15402
+ /**
15403
+ * Per-context state persistence instance interface.
15404
+ * Scoped to a specific (signalId, bucketName) pair.
15405
+ *
15406
+ * Used by StatePersistInstance for crash-safe strategy state storage.
15407
+ * Custom adapters should implement this interface to override the default
15408
+ * file-based state behavior.
15409
+ */
15410
+ interface IPersistStateInstance {
15411
+ /**
15412
+ * Initialize storage for this state context.
15413
+ *
15414
+ * @param initial - Whether this is the first initialization
15415
+ * @returns Promise that resolves when initialization is complete
15416
+ */
15417
+ waitForInit(initial: boolean): Promise<void>;
15418
+ /**
15419
+ * Read persisted state for this context.
15420
+ *
15421
+ * @returns Promise resolving to state data or null if none persisted
15422
+ */
15423
+ readStateData(): Promise<StateData | null>;
15424
+ /**
15425
+ * Write state for this context.
15426
+ *
15427
+ * @param data - State data to persist
15428
+ * @returns Promise that resolves when write is complete
15429
+ */
15430
+ writeStateData(data: StateData): Promise<void>;
15431
+ /**
15432
+ * Release any resources held by this instance.
15433
+ * Default implementations may treat this as a no-op.
15434
+ */
15435
+ dispose(): void;
15436
+ }
15437
+ /**
15438
+ * Default file-based implementation of IPersistStateInstance.
15439
+ *
15440
+ * Features:
15441
+ * - Wraps PersistBase for atomic JSON writes
15442
+ * - Uses bucketName as entity ID within a per-signal PersistBase
15443
+ * - dispose is a no-op (memo cache is managed by PersistStateUtils)
15444
+ *
15445
+ * @example
15446
+ * ```typescript
15447
+ * const instance = new PersistStateInstance("signal-1", "counter");
15448
+ * await instance.waitForInit(true);
15449
+ * await instance.writeStateData({ id: "counter", data: { count: 1 } });
15450
+ * const state = await instance.readStateData();
15451
+ * ```
15452
+ */
15453
+ declare class PersistStateInstance implements IPersistStateInstance {
15454
+ readonly signalId: string;
15455
+ readonly bucketName: string;
15456
+ /** Underlying file-based storage scoped to this context */
15457
+ private readonly _storage;
15458
+ /**
15459
+ * Creates new state persistence instance.
15460
+ *
15461
+ * @param signalId - Signal identifier (folder name under state/)
15462
+ * @param bucketName - Bucket name (file name)
15463
+ */
15464
+ constructor(signalId: string, bucketName: string);
15465
+ /**
15466
+ * Initializes the underlying PersistBase storage.
15467
+ *
15468
+ * @param initial - Whether this is the first initialization
15469
+ * @returns Promise that resolves when initialization is complete
15470
+ */
15471
+ waitForInit(initial: boolean): Promise<void>;
15472
+ /**
15473
+ * Reads the persisted state using `bucketName` as the entity key.
15474
+ *
15475
+ * @returns Promise resolving to state data or null if not found
15476
+ */
15477
+ readStateData(): Promise<StateData | null>;
15478
+ /**
15479
+ * Writes the state using `bucketName` as the entity key.
15480
+ *
15481
+ * @param data - State data to persist
15482
+ * @returns Promise that resolves when write is complete
15483
+ */
15484
+ writeStateData(data: StateData): Promise<void>;
15485
+ /**
15486
+ * No-op for the default file-based implementation.
15487
+ * Resource cleanup (memo cache invalidation) is handled by PersistStateUtils.dispose().
15488
+ */
15489
+ dispose(): void;
15490
+ }
15491
+ /**
15492
+ * Constructor type for IPersistStateInstance.
15493
+ * Used by PersistStateUtils.usePersistStateAdapter() to register custom adapters.
15494
+ */
15495
+ type TPersistStateInstanceCtor = new (signalId: string, bucketName: string) => IPersistStateInstance;
14085
15496
  /**
14086
15497
  * Utility class for managing state persistence.
14087
15498
  *
@@ -14095,57 +15506,67 @@ type StateData = {
14095
15506
  * Used by StatePersistInstance for crash-safe state persistence.
14096
15507
  */
14097
15508
  declare class PersistStateUtils {
14098
- private PersistStateFactory;
15509
+ /**
15510
+ * Constructor used to create per-context state instances.
15511
+ * Replaceable via usePersistStateAdapter() / useJson() / useDummy().
15512
+ */
15513
+ private PersistStateInstanceCtor;
15514
+ /**
15515
+ * Memoized factory creating one IPersistStateInstance per (signalId, bucketName) pair.
15516
+ */
14099
15517
  private getStateStorage;
14100
15518
  /**
14101
- * Registers a custom persistence adapter.
15519
+ * Registers a custom IPersistStateInstance constructor.
15520
+ * Clears the memoization cache so subsequent calls use the new adapter.
14102
15521
  *
14103
- * @param Ctor - Custom PersistBase constructor
15522
+ * @param Ctor - Custom IPersistStateInstance constructor
14104
15523
  */
14105
- usePersistStateAdapter(Ctor: TPersistBaseCtor<string, StateData>): void;
15524
+ usePersistStateAdapter(Ctor: TPersistStateInstanceCtor): void;
14106
15525
  /**
14107
- * Initializes the storage for a given (signalId, bucketName) pair.
15526
+ * Initializes the state storage for the given context.
15527
+ * Skips initialization when `initial` is false (used to gate first-time setup).
14108
15528
  *
14109
15529
  * @param signalId - Signal identifier
14110
15530
  * @param bucketName - Bucket name
14111
15531
  * @param initial - Whether this is the first initialization
15532
+ * @returns Promise that resolves when initialization is complete
14112
15533
  */
14113
15534
  waitForInit: (signalId: string, bucketName: string, initial: boolean) => Promise<void>;
14114
15535
  /**
14115
- * Reads a state entry from persistence storage.
15536
+ * Reads persisted state for the given context.
15537
+ * Lazily initializes the instance on first access.
14116
15538
  *
14117
15539
  * @param signalId - Signal identifier
14118
15540
  * @param bucketName - Bucket name
14119
- * @returns Promise resolving to entry data or null if not found
15541
+ * @returns Promise resolving to state data or null if none persisted
14120
15542
  */
14121
15543
  readStateData: (signalId: string, bucketName: string) => Promise<StateData | null>;
14122
15544
  /**
14123
- * Writes a state entry to disk with atomic file writes.
15545
+ * Writes state for the given context.
15546
+ * Lazily initializes the instance on first access.
14124
15547
  *
14125
- * @param data - Entry data to persist
15548
+ * @param data - State data to persist
14126
15549
  * @param signalId - Signal identifier
14127
15550
  * @param bucketName - Bucket name
15551
+ * @returns Promise that resolves when write is complete
14128
15552
  */
14129
15553
  writeStateData: (data: StateData, signalId: string, bucketName: string) => Promise<void>;
14130
15554
  /**
14131
- * Switches to a dummy persist adapter that discards all writes.
14132
- * All future persistence writes will be no-ops.
15555
+ * Switches to PersistStateDummyInstance (all operations are no-ops).
14133
15556
  */
14134
15557
  useDummy: () => void;
14135
15558
  /**
14136
- * Switches to the default JSON persist adapter.
14137
- * All future persistence writes will use JSON storage.
15559
+ * Switches to the default file-based PersistStateInstance.
14138
15560
  */
14139
15561
  useJson: () => void;
14140
15562
  /**
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.
15563
+ * Clears the memoized instance cache.
15564
+ * Call when process.cwd() changes between strategy iterations.
14144
15565
  */
14145
15566
  clear: () => void;
14146
15567
  /**
14147
- * Disposes of the state adapter and releases any resources.
14148
- * Call this when a signal is removed to clean up its associated storage.
15568
+ * Drops the memoized instance for the given context.
15569
+ * Call when a signal is removed to clean up its associated storage entry.
14149
15570
  *
14150
15571
  * @param signalId - Signal identifier
14151
15572
  * @param bucketName - Bucket name
@@ -14164,7 +15585,104 @@ declare const PersistStateAdapter: PersistStateUtils;
14164
15585
  type SessionData = {
14165
15586
  id: string;
14166
15587
  data: object | null;
15588
+ when: number;
14167
15589
  };
15590
+ /**
15591
+ * Per-context session persistence instance interface.
15592
+ * Scoped to a specific (strategyName, exchangeName, frameName) triple.
15593
+ *
15594
+ * Used by SessionPersistInstance for crash-safe session storage.
15595
+ * Custom adapters should implement this interface to override the default
15596
+ * file-based session behavior.
15597
+ */
15598
+ interface IPersistSessionInstance {
15599
+ /**
15600
+ * Initialize storage for this session context.
15601
+ *
15602
+ * @param initial - Whether this is the first initialization
15603
+ * @returns Promise that resolves when initialization is complete
15604
+ */
15605
+ waitForInit(initial: boolean): Promise<void>;
15606
+ /**
15607
+ * Read persisted session data for this context.
15608
+ *
15609
+ * @returns Promise resolving to session data or null if none persisted
15610
+ */
15611
+ readSessionData(): Promise<SessionData | null>;
15612
+ /**
15613
+ * Write session data for this context.
15614
+ *
15615
+ * @param data - Session data to persist
15616
+ * @returns Promise that resolves when write is complete
15617
+ */
15618
+ writeSessionData(data: SessionData): Promise<void>;
15619
+ /**
15620
+ * Release any resources held by this instance.
15621
+ * Default implementations may treat this as a no-op.
15622
+ */
15623
+ dispose(): void;
15624
+ }
15625
+ /**
15626
+ * Default file-based implementation of IPersistSessionInstance.
15627
+ *
15628
+ * Features:
15629
+ * - Wraps PersistBase for atomic JSON writes
15630
+ * - Uses frameName as entity ID within a per-strategy/exchange PersistBase
15631
+ * - dispose is a no-op (memo cache is managed by PersistSessionUtils)
15632
+ *
15633
+ * @example
15634
+ * ```typescript
15635
+ * const instance = new PersistSessionInstance("my-strategy", "binance", "frame-1");
15636
+ * await instance.waitForInit(true);
15637
+ * await instance.writeSessionData({ id: "frame-1", data: { session: "state" } });
15638
+ * const session = await instance.readSessionData();
15639
+ * ```
15640
+ */
15641
+ declare class PersistSessionInstance implements IPersistSessionInstance {
15642
+ readonly strategyName: string;
15643
+ readonly exchangeName: string;
15644
+ readonly frameName: string;
15645
+ /** Underlying file-based storage scoped to this context */
15646
+ private readonly _storage;
15647
+ /**
15648
+ * Creates new session persistence instance.
15649
+ *
15650
+ * @param strategyName - Strategy identifier
15651
+ * @param exchangeName - Exchange identifier
15652
+ * @param frameName - Frame identifier (also used as entity ID)
15653
+ */
15654
+ constructor(strategyName: string, exchangeName: string, frameName: string);
15655
+ /**
15656
+ * Initializes the underlying PersistBase storage.
15657
+ *
15658
+ * @param initial - Whether this is the first initialization
15659
+ * @returns Promise that resolves when initialization is complete
15660
+ */
15661
+ waitForInit(initial: boolean): Promise<void>;
15662
+ /**
15663
+ * Reads the persisted session data using `frameName` as the entity key.
15664
+ *
15665
+ * @returns Promise resolving to session data or null if not found
15666
+ */
15667
+ readSessionData(): Promise<SessionData | null>;
15668
+ /**
15669
+ * Writes the session data using `frameName` as the entity key.
15670
+ *
15671
+ * @param data - Session data to persist
15672
+ * @returns Promise that resolves when write is complete
15673
+ */
15674
+ writeSessionData(data: SessionData): Promise<void>;
15675
+ /**
15676
+ * No-op for the default file-based implementation.
15677
+ * Resource cleanup (memo cache invalidation) is handled by PersistSessionUtils.dispose().
15678
+ */
15679
+ dispose(): void;
15680
+ }
15681
+ /**
15682
+ * Constructor type for IPersistSessionInstance.
15683
+ * Used by PersistSessionUtils.usePersistSessionAdapter() to register custom adapters.
15684
+ */
15685
+ type TPersistSessionInstanceCtor = new (strategyName: string, exchangeName: string, frameName: string) => IPersistSessionInstance;
14168
15686
  /**
14169
15687
  * Utility class for managing session persistence.
14170
15688
  *
@@ -14178,60 +15696,71 @@ type SessionData = {
14178
15696
  * Used by SessionPersistInstance for crash-safe session persistence.
14179
15697
  */
14180
15698
  declare class PersistSessionUtils {
14181
- private PersistSessionFactory;
15699
+ /**
15700
+ * Constructor used to create per-context session instances.
15701
+ * Replaceable via usePersistSessionAdapter() / useJson() / useDummy().
15702
+ */
15703
+ private PersistSessionInstanceCtor;
15704
+ /**
15705
+ * Memoized factory creating one IPersistSessionInstance per
15706
+ * (strategyName, exchangeName, frameName) triple.
15707
+ */
14182
15708
  private getSessionStorage;
14183
15709
  /**
14184
- * Registers a custom persistence adapter.
15710
+ * Registers a custom IPersistSessionInstance constructor.
15711
+ * Clears the memoization cache so subsequent calls use the new adapter.
14185
15712
  *
14186
- * @param Ctor - Custom PersistBase constructor
15713
+ * @param Ctor - Custom IPersistSessionInstance constructor
14187
15714
  */
14188
- usePersistSessionAdapter(Ctor: TPersistBaseCtor<string, SessionData>): void;
15715
+ usePersistSessionAdapter(Ctor: TPersistSessionInstanceCtor): void;
14189
15716
  /**
14190
- * Initializes the storage for a given (strategyName, exchangeName, frameName) triple.
15717
+ * Initializes the session storage for the given context.
15718
+ * Skips initialization when `initial` is false (used to gate first-time setup).
14191
15719
  *
14192
15720
  * @param strategyName - Strategy identifier
14193
15721
  * @param exchangeName - Exchange identifier
14194
15722
  * @param frameName - Frame identifier
14195
15723
  * @param initial - Whether this is the first initialization
15724
+ * @returns Promise that resolves when initialization is complete
14196
15725
  */
14197
15726
  waitForInit: (strategyName: string, exchangeName: string, frameName: string, initial: boolean) => Promise<void>;
14198
15727
  /**
14199
- * Reads a session entry from persistence storage.
15728
+ * Reads persisted session data for the given context.
15729
+ * Lazily initializes the instance on first access.
14200
15730
  *
14201
15731
  * @param strategyName - Strategy identifier
14202
15732
  * @param exchangeName - Exchange identifier
14203
15733
  * @param frameName - Frame identifier
14204
- * @returns Promise resolving to entry data or null if not found
15734
+ * @returns Promise resolving to session data or null if none persisted
14205
15735
  */
14206
15736
  readSessionData: (strategyName: string, exchangeName: string, frameName: string) => Promise<SessionData | null>;
14207
15737
  /**
14208
- * Writes a session entry to disk with atomic file writes.
15738
+ * Writes session data for the given context.
15739
+ * Lazily initializes the instance on first access.
14209
15740
  *
14210
- * @param data - Entry data to persist
15741
+ * @param data - Session data to persist
14211
15742
  * @param strategyName - Strategy identifier
14212
15743
  * @param exchangeName - Exchange identifier
14213
15744
  * @param frameName - Frame identifier
15745
+ * @returns Promise that resolves when write is complete
14214
15746
  */
14215
15747
  writeSessionData: (data: SessionData, strategyName: string, exchangeName: string, frameName: string) => Promise<void>;
14216
15748
  /**
14217
- * Switches to a dummy persist adapter that discards all writes.
14218
- * All future persistence writes will be no-ops.
15749
+ * Switches to PersistSessionDummyInstance (all operations are no-ops).
14219
15750
  */
14220
15751
  useDummy: () => void;
14221
15752
  /**
14222
- * Switches to the default JSON persist adapter.
14223
- * All future persistence writes will use JSON storage.
15753
+ * Switches to the default file-based PersistSessionInstance.
14224
15754
  */
14225
15755
  useJson: () => void;
14226
15756
  /**
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.
15757
+ * Clears the memoized instance cache.
15758
+ * Call when process.cwd() changes between strategy iterations.
14230
15759
  */
14231
15760
  clear: () => void;
14232
15761
  /**
14233
- * Disposes of the session adapter and releases any resources.
14234
- * Call this when a session is removed to clean up its associated storage.
15762
+ * Drops the memoized instance for the given context.
15763
+ * Call when a session is removed to clean up its associated storage entry.
14235
15764
  *
14236
15765
  * @param strategyName - Strategy identifier
14237
15766
  * @param exchangeName - Exchange identifier
@@ -15123,13 +16652,19 @@ interface ISessionInstance {
15123
16652
  /**
15124
16653
  * Write a new session value.
15125
16654
  * @param value - New value or null to clear
16655
+ * @param when - Logical timestamp this value belongs to.
16656
+ * A write with a smaller `when` overwrites an existing record —
16657
+ * that lets a restarted backtest reset live-written state.
15126
16658
  */
15127
- setData<Value extends object = object>(value: Value | null): Promise<void>;
16659
+ setData<Value extends object = object>(value: Value | null, when: Date): Promise<void>;
15128
16660
  /**
15129
16661
  * Read the current session value.
15130
- * @returns Current session value, or null if not set
16662
+ * Returns null when the stored `when` is greater than the requested `when`
16663
+ * (look-ahead bias protection).
16664
+ * @param when - Logical timestamp at which the read is happening
16665
+ * @returns Current session value, or null if not set / look-ahead
15131
16666
  */
15132
- getData<Value extends object = object>(): Promise<Value | null>;
16667
+ getData<Value extends object = object>(when: Date): Promise<Value | null>;
15133
16668
  /**
15134
16669
  * Releases any resources held by this instance.
15135
16670
  */
@@ -15166,13 +16701,14 @@ declare class SessionBacktestAdapter implements TSessionAdapter {
15166
16701
  * @param context.strategyName - Strategy identifier
15167
16702
  * @param context.exchangeName - Exchange identifier
15168
16703
  * @param context.frameName - Frame identifier
15169
- * @returns Current session value, or null if not set
16704
+ * @param when - Logical timestamp at which the read is happening (look-ahead guard)
16705
+ * @returns Current session value, or null if not set / look-ahead
15170
16706
  */
15171
16707
  getData: <Value extends object = object>(symbol: string, context: {
15172
16708
  strategyName: StrategyName;
15173
16709
  exchangeName: ExchangeName;
15174
16710
  frameName: FrameName;
15175
- }) => Promise<Value | null>;
16711
+ }, when: Date) => Promise<Value | null>;
15176
16712
  /**
15177
16713
  * Update the session value for a backtest run.
15178
16714
  * @param symbol - Trading pair symbol
@@ -15180,12 +16716,13 @@ declare class SessionBacktestAdapter implements TSessionAdapter {
15180
16716
  * @param context.strategyName - Strategy identifier
15181
16717
  * @param context.exchangeName - Exchange identifier
15182
16718
  * @param context.frameName - Frame identifier
16719
+ * @param when - Logical timestamp this value belongs to
15183
16720
  */
15184
16721
  setData: <Value extends object = object>(symbol: string, value: Value | null, context: {
15185
16722
  strategyName: StrategyName;
15186
16723
  exchangeName: ExchangeName;
15187
16724
  frameName: FrameName;
15188
- }) => Promise<void>;
16725
+ }, when: Date) => Promise<void>;
15189
16726
  /**
15190
16727
  * Switches to in-memory adapter (default).
15191
16728
  * All data lives in process memory only.
@@ -15231,13 +16768,14 @@ declare class SessionLiveAdapter implements TSessionAdapter {
15231
16768
  * @param context.strategyName - Strategy identifier
15232
16769
  * @param context.exchangeName - Exchange identifier
15233
16770
  * @param context.frameName - Frame identifier
15234
- * @returns Current session value, or null if not set
16771
+ * @param when - Logical timestamp at which the read is happening (look-ahead guard)
16772
+ * @returns Current session value, or null if not set / look-ahead
15235
16773
  */
15236
16774
  getData: <Value extends object = object>(symbol: string, context: {
15237
16775
  strategyName: StrategyName;
15238
16776
  exchangeName: ExchangeName;
15239
16777
  frameName: FrameName;
15240
- }) => Promise<Value | null>;
16778
+ }, when: Date) => Promise<Value | null>;
15241
16779
  /**
15242
16780
  * Update the session value for a live run.
15243
16781
  * @param symbol - Trading pair symbol
@@ -15245,12 +16783,13 @@ declare class SessionLiveAdapter implements TSessionAdapter {
15245
16783
  * @param context.strategyName - Strategy identifier
15246
16784
  * @param context.exchangeName - Exchange identifier
15247
16785
  * @param context.frameName - Frame identifier
16786
+ * @param when - Logical timestamp this value belongs to
15248
16787
  */
15249
16788
  setData: <Value extends object = object>(symbol: string, value: Value | null, context: {
15250
16789
  strategyName: StrategyName;
15251
16790
  exchangeName: ExchangeName;
15252
16791
  frameName: FrameName;
15253
- }) => Promise<void>;
16792
+ }, when: Date) => Promise<void>;
15254
16793
  /**
15255
16794
  * Switches to in-memory adapter.
15256
16795
  * All data lives in process memory only.
@@ -15292,13 +16831,14 @@ declare class SessionAdapter {
15292
16831
  * @param context.exchangeName - Exchange identifier
15293
16832
  * @param context.frameName - Frame identifier
15294
16833
  * @param backtest - Flag indicating if the context is backtest or live
15295
- * @returns Current session value, or null if not set
16834
+ * @param when - Logical timestamp at which the read is happening (look-ahead guard)
16835
+ * @returns Current session value, or null if not set / look-ahead
15296
16836
  */
15297
16837
  getData: <Value extends object = object>(symbol: string, context: {
15298
16838
  strategyName: StrategyName;
15299
16839
  exchangeName: ExchangeName;
15300
16840
  frameName: FrameName;
15301
- }, backtest: boolean) => Promise<Value | null>;
16841
+ }, backtest: boolean, when: Date) => Promise<Value | null>;
15302
16842
  /**
15303
16843
  * Update the session value for a signal.
15304
16844
  * Routes to SessionBacktest or SessionLive based on backtest.
@@ -15308,12 +16848,13 @@ declare class SessionAdapter {
15308
16848
  * @param context.exchangeName - Exchange identifier
15309
16849
  * @param context.frameName - Frame identifier
15310
16850
  * @param backtest - Flag indicating if the context is backtest or live
16851
+ * @param when - Logical timestamp this value belongs to
15311
16852
  */
15312
16853
  setData: <Value extends object = object>(symbol: string, value: Value | null, context: {
15313
16854
  strategyName: StrategyName;
15314
16855
  exchangeName: ExchangeName;
15315
16856
  frameName: FrameName;
15316
- }, backtest: boolean) => Promise<void>;
16857
+ }, backtest: boolean, when: Date) => Promise<void>;
15317
16858
  }
15318
16859
  /**
15319
16860
  * Global singleton instance of SessionAdapter.
@@ -22202,23 +23743,28 @@ interface IRecentUtils {
22202
23743
  handleActivePing(event: ActivePingContract): Promise<void>;
22203
23744
  /**
22204
23745
  * Retrieves the latest active signal for the given context.
23746
+ * Returns null if the stored signal's `timestamp` is greater than the requested `when`
23747
+ * (look-ahead bias protection).
22205
23748
  * @param symbol - Trading pair symbol
22206
23749
  * @param strategyName - Strategy identifier
22207
23750
  * @param exchangeName - Exchange identifier
22208
23751
  * @param frameName - Frame identifier
22209
23752
  * @param backtest - Flag indicating if the context is backtest or live
22210
- * @returns The latest signal or null if not found
23753
+ * @param when - Logical timestamp at which the read is happening (look-ahead guard)
23754
+ * @returns The latest signal or null if not found / shadowed by look-ahead
22211
23755
  */
22212
- getLatestSignal(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean): Promise<IPublicSignalRow | null>;
23756
+ getLatestSignal(symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, when: Date): Promise<IPublicSignalRow | null>;
22213
23757
  /**
22214
23758
  * Returns the number of minutes elapsed since the latest signal's timestamp.
23759
+ * `timestamp` doubles as the look-ahead cutoff — a signal whose `timestamp`
23760
+ * exceeds the requested one is treated as not yet visible.
23761
+ * @param timestamp - Current timestamp in milliseconds (also serves as look-ahead cutoff)
22215
23762
  * @param symbol - Trading pair symbol
22216
23763
  * @param strategyName - Strategy identifier
22217
23764
  * @param exchangeName - Exchange identifier
22218
23765
  * @param frameName - Frame identifier
22219
23766
  * @param backtest - Flag indicating if the context is backtest or live
22220
- * @param currentTimestamp - Current timestamp in milliseconds
22221
- * @returns Minutes since the latest signal, or null if no signal found
23767
+ * @returns Minutes since the latest signal, or null if no signal found / shadowed by look-ahead
22222
23768
  */
22223
23769
  getMinutesSinceLatestSignalCreated(timestamp: number, symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean): Promise<number | null>;
22224
23770
  }
@@ -22252,19 +23798,22 @@ declare class RecentBacktestAdapter implements IRecentUtils {
22252
23798
  * @param exchangeName - Exchange identifier
22253
23799
  * @param frameName - Frame identifier
22254
23800
  * @param backtest - Flag indicating if the context is backtest or live
22255
- * @returns The latest signal or null if not found
23801
+ * @param when - Logical timestamp at which the read is happening (look-ahead guard)
23802
+ * @returns The latest signal or null if not found / shadowed by look-ahead
22256
23803
  */
22257
- getLatestSignal: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean) => Promise<IPublicSignalRow | null>;
23804
+ getLatestSignal: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, when: Date) => Promise<IPublicSignalRow | null>;
22258
23805
  /**
22259
23806
  * Returns the number of whole minutes elapsed since the latest signal's creation timestamp.
22260
- * Proxies call to the underlying storage adapter.
22261
- * @param timestamp - Current timestamp in milliseconds
23807
+ * Proxies call to the underlying storage adapter. `timestamp` doubles as the
23808
+ * look-ahead cutoff a signal whose `timestamp` exceeds the requested one is
23809
+ * treated as not yet visible.
23810
+ * @param timestamp - Current timestamp in milliseconds (also serves as look-ahead cutoff)
22262
23811
  * @param symbol - Trading pair symbol
22263
23812
  * @param strategyName - Strategy identifier
22264
23813
  * @param exchangeName - Exchange identifier
22265
23814
  * @param frameName - Frame identifier
22266
23815
  * @param backtest - Flag indicating if the context is backtest or live
22267
- * @returns Whole minutes since the latest signal was created, or null if no signal found
23816
+ * @returns Whole minutes since the latest signal was created, or null if no signal found / shadowed by look-ahead
22268
23817
  */
22269
23818
  getMinutesSinceLatestSignalCreated: (timestamp: number, symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean) => Promise<number | null>;
22270
23819
  /**
@@ -22314,19 +23863,22 @@ declare class RecentLiveAdapter implements IRecentUtils {
22314
23863
  * @param exchangeName - Exchange identifier
22315
23864
  * @param frameName - Frame identifier
22316
23865
  * @param backtest - Flag indicating if the context is backtest or live
22317
- * @returns The latest signal or null if not found
23866
+ * @param when - Logical timestamp at which the read is happening (look-ahead guard)
23867
+ * @returns The latest signal or null if not found / shadowed by look-ahead
22318
23868
  */
22319
- getLatestSignal: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean) => Promise<IPublicSignalRow | null>;
23869
+ getLatestSignal: (symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean, when: Date) => Promise<IPublicSignalRow | null>;
22320
23870
  /**
22321
23871
  * Returns the number of whole minutes elapsed since the latest signal's creation timestamp.
22322
- * Proxies call to the underlying storage adapter.
22323
- * @param timestamp - Current timestamp in milliseconds
23872
+ * Proxies call to the underlying storage adapter. `timestamp` doubles as the
23873
+ * look-ahead cutoff a signal whose `timestamp` exceeds the requested one is
23874
+ * treated as not yet visible.
23875
+ * @param timestamp - Current timestamp in milliseconds (also serves as look-ahead cutoff)
22324
23876
  * @param symbol - Trading pair symbol
22325
23877
  * @param strategyName - Strategy identifier
22326
23878
  * @param exchangeName - Exchange identifier
22327
23879
  * @param frameName - Frame identifier
22328
23880
  * @param backtest - Flag indicating if the context is backtest or live
22329
- * @returns Whole minutes since the latest signal was created, or null if no signal found
23881
+ * @returns Whole minutes since the latest signal was created, or null if no signal found / shadowed by look-ahead
22330
23882
  */
22331
23883
  getMinutesSinceLatestSignalCreated: (timestamp: number, symbol: string, strategyName: StrategyName, exchangeName: ExchangeName, frameName: FrameName, backtest: boolean) => Promise<number | null>;
22332
23884
  /**
@@ -22375,32 +23927,37 @@ declare class RecentAdapter {
22375
23927
  /**
22376
23928
  * Retrieves the latest active signal for the given symbol and context.
22377
23929
  * Searches backtest storage first, then live storage.
23930
+ * Returns null if the stored signal's `timestamp` is greater than the requested `when`
23931
+ * (look-ahead bias protection).
22378
23932
  *
22379
23933
  * @param symbol - Trading pair symbol
22380
23934
  * @param context - Execution context with strategyName, exchangeName, and frameName
22381
- * @param backtest - Flag indicating if the context is backtest or live
22382
- * @returns The latest signal or null if not found
23935
+ * @param when - Logical timestamp at which the read is happening (look-ahead guard)
23936
+ * @returns The latest signal or null if not found / shadowed by look-ahead
22383
23937
  * @throws Error if RecentAdapter is not enabled
22384
23938
  */
22385
23939
  getLatestSignal: (symbol: string, context: {
22386
23940
  strategyName: StrategyName;
22387
23941
  exchangeName: ExchangeName;
22388
23942
  frameName: FrameName;
22389
- }) => Promise<IPublicSignalRow | null>;
23943
+ }, when: Date) => Promise<IPublicSignalRow | null>;
22390
23944
  /**
22391
23945
  * Returns the number of whole minutes elapsed since the latest signal's creation timestamp.
22392
23946
  * Searches backtest storage first, then live storage.
22393
- * @param timestamp - Current timestamp in milliseconds
23947
+ * `when` doubles as the look-ahead cutoff — a signal whose `timestamp` exceeds
23948
+ * `when.getTime()` is treated as not yet visible — and as the "now" against
23949
+ * which elapsed minutes are computed.
22394
23950
  * @param symbol - Trading pair symbol
22395
23951
  * @param context - Execution context with strategyName, exchangeName, and frameName
22396
- * @returns Whole minutes since the latest signal was created, or null if no signal found
23952
+ * @param when - Logical timestamp at which the read is happening (look-ahead cutoff + "now")
23953
+ * @returns Whole minutes since the latest signal was created, or null if no signal found / shadowed by look-ahead
22397
23954
  * @throws Error if RecentAdapter is not enabled
22398
23955
  */
22399
23956
  getMinutesSinceLatestSignalCreated: (symbol: string, context: {
22400
23957
  strategyName: StrategyName;
22401
23958
  exchangeName: ExchangeName;
22402
23959
  frameName: FrameName;
22403
- }) => Promise<number | null>;
23960
+ }, when: Date) => Promise<number | null>;
22404
23961
  }
22405
23962
  /**
22406
23963
  * Global singleton instance of RecentAdapter.
@@ -22895,38 +24452,46 @@ interface IMemoryInstance {
22895
24452
  * @param memoryId - Unique entry identifier
22896
24453
  * @param value - Value to store
22897
24454
  * @param description - Optional BM25 index string; defaults to JSON.stringify(value)
24455
+ * @param when - Logical timestamp this entry belongs to (look-ahead guard)
22898
24456
  */
22899
- writeMemory<T extends object = object>(memoryId: string, value: T, description: string): Promise<void>;
24457
+ writeMemory<T extends object = object>(memoryId: string, value: T, description: string, when: Date): Promise<void>;
22900
24458
  /**
22901
24459
  * Search memory using BM25 full-text scoring.
24460
+ * Filters out entries whose `when` is greater than the requested `when`.
22902
24461
  * @param query - Search query string
24462
+ * @param when - Logical timestamp at which the read is happening (look-ahead guard)
22903
24463
  * @returns Array of matching entries with scores
22904
24464
  */
22905
- searchMemory<T extends object = object>(query: string, settings?: SearchSettings): Promise<Array<{
24465
+ searchMemory<T extends object = object>(query: string, when: Date, settings?: SearchSettings): Promise<Array<{
22906
24466
  memoryId: string;
22907
24467
  score: number;
22908
24468
  content: T;
22909
24469
  }>>;
22910
24470
  /**
22911
24471
  * List all entries in memory.
24472
+ * Filters out entries whose `when` is greater than the requested `when`.
24473
+ * @param when - Logical timestamp at which the read is happening (look-ahead guard)
22912
24474
  * @returns Array of all stored entries
22913
24475
  */
22914
- listMemory<T extends object = object>(): Promise<Array<{
24476
+ listMemory<T extends object = object>(when: Date): Promise<Array<{
22915
24477
  memoryId: string;
22916
24478
  content: T;
22917
24479
  }>>;
22918
24480
  /**
22919
24481
  * Remove an entry from memory.
22920
24482
  * @param memoryId - Unique entry identifier
24483
+ * @param when - Logical timestamp (kept for API consistency; removal is by UUID)
22921
24484
  */
22922
- removeMemory(memoryId: string): Promise<void>;
24485
+ removeMemory(memoryId: string, when: Date): Promise<void>;
22923
24486
  /**
22924
24487
  * Read a single entry from memory.
24488
+ * Behaves as not-found if the stored `when` is greater than the requested `when`.
22925
24489
  * @param memoryId - Unique entry identifier
24490
+ * @param when - Logical timestamp at which the read is happening (look-ahead guard)
22926
24491
  * @returns Entry value
22927
- * @throws Error if entry not found
24492
+ * @throws Error if entry not found (or shadowed by look-ahead)
22928
24493
  */
22929
- readMemory<T extends object = object>(memoryId: string): Promise<T>;
24494
+ readMemory<T extends object = object>(memoryId: string, when: Date): Promise<T>;
22930
24495
  /**
22931
24496
  * Releases any resources held by this instance.
22932
24497
  */
@@ -22975,6 +24540,7 @@ declare class MemoryBacktestAdapter implements TMemoryInstance {
22975
24540
  * @param dto.signalId - Signal identifier
22976
24541
  * @param dto.bucketName - Bucket name
22977
24542
  * @param dto.description - BM25 index string; defaults to JSON.stringify(value)
24543
+ * @param dto.when - Logical timestamp this entry belongs to (look-ahead guard)
22978
24544
  */
22979
24545
  writeMemory: <T extends object = object>(dto: {
22980
24546
  memoryId: string;
@@ -22982,18 +24548,21 @@ declare class MemoryBacktestAdapter implements TMemoryInstance {
22982
24548
  signalId: string;
22983
24549
  bucketName: string;
22984
24550
  description: string;
24551
+ when: Date;
22985
24552
  }) => Promise<void>;
22986
24553
  /**
22987
24554
  * Search memory using BM25 full-text scoring.
22988
24555
  * @param dto.query - Search query string
22989
24556
  * @param dto.signalId - Signal identifier
22990
24557
  * @param dto.bucketName - Bucket name
24558
+ * @param dto.when - Logical timestamp at which the search is happening (look-ahead guard)
22991
24559
  * @returns Matching entries sorted by relevance score
22992
24560
  */
22993
24561
  searchMemory: <T extends object = object>(dto: {
22994
24562
  query: string;
22995
24563
  signalId: string;
22996
24564
  bucketName: string;
24565
+ when: Date;
22997
24566
  settings?: SearchSettings;
22998
24567
  }) => Promise<{
22999
24568
  memoryId: string;
@@ -23004,11 +24573,13 @@ declare class MemoryBacktestAdapter implements TMemoryInstance {
23004
24573
  * List all entries in memory.
23005
24574
  * @param dto.signalId - Signal identifier
23006
24575
  * @param dto.bucketName - Bucket name
24576
+ * @param dto.when - Logical timestamp at which the list is happening (look-ahead guard)
23007
24577
  * @returns Array of all stored entries
23008
24578
  */
23009
24579
  listMemory: <T extends object = object>(dto: {
23010
24580
  signalId: string;
23011
24581
  bucketName: string;
24582
+ when: Date;
23012
24583
  }) => Promise<{
23013
24584
  memoryId: string;
23014
24585
  content: T;
@@ -23018,17 +24589,20 @@ declare class MemoryBacktestAdapter implements TMemoryInstance {
23018
24589
  * @param dto.memoryId - Unique entry identifier
23019
24590
  * @param dto.signalId - Signal identifier
23020
24591
  * @param dto.bucketName - Bucket name
24592
+ * @param dto.when - Logical timestamp (kept for API consistency; removal is by UUID)
23021
24593
  */
23022
24594
  removeMemory: (dto: {
23023
24595
  memoryId: string;
23024
24596
  signalId: string;
23025
24597
  bucketName: string;
24598
+ when: Date;
23026
24599
  }) => Promise<void>;
23027
24600
  /**
23028
24601
  * Read a single entry from memory.
23029
24602
  * @param dto.memoryId - Unique entry identifier
23030
24603
  * @param dto.signalId - Signal identifier
23031
24604
  * @param dto.bucketName - Bucket name
24605
+ * @param dto.when - Logical timestamp at which the read is happening (look-ahead guard)
23032
24606
  * @returns Entry value
23033
24607
  * @throws Error if entry not found
23034
24608
  */
@@ -23036,6 +24610,7 @@ declare class MemoryBacktestAdapter implements TMemoryInstance {
23036
24610
  memoryId: string;
23037
24611
  signalId: string;
23038
24612
  bucketName: string;
24613
+ when: Date;
23039
24614
  }) => Promise<T>;
23040
24615
  /**
23041
24616
  * Switches to in-memory BM25 adapter (default).
@@ -23091,6 +24666,7 @@ declare class MemoryLiveAdapter implements TMemoryInstance {
23091
24666
  * @param dto.signalId - Signal identifier
23092
24667
  * @param dto.bucketName - Bucket name
23093
24668
  * @param dto.description - BM25 index string; defaults to JSON.stringify(value)
24669
+ * @param dto.when - Logical timestamp this entry belongs to (look-ahead guard)
23094
24670
  */
23095
24671
  writeMemory: <T extends object = object>(dto: {
23096
24672
  memoryId: string;
@@ -23098,18 +24674,21 @@ declare class MemoryLiveAdapter implements TMemoryInstance {
23098
24674
  signalId: string;
23099
24675
  bucketName: string;
23100
24676
  description: string;
24677
+ when: Date;
23101
24678
  }) => Promise<void>;
23102
24679
  /**
23103
24680
  * Search memory using BM25 full-text scoring.
23104
24681
  * @param dto.query - Search query string
23105
24682
  * @param dto.signalId - Signal identifier
23106
24683
  * @param dto.bucketName - Bucket name
24684
+ * @param dto.when - Logical timestamp at which the search is happening (look-ahead guard)
23107
24685
  * @returns Matching entries sorted by relevance score
23108
24686
  */
23109
24687
  searchMemory: <T extends object = object>(dto: {
23110
24688
  query: string;
23111
24689
  signalId: string;
23112
24690
  bucketName: string;
24691
+ when: Date;
23113
24692
  settings?: SearchSettings;
23114
24693
  }) => Promise<{
23115
24694
  memoryId: string;
@@ -23120,11 +24699,13 @@ declare class MemoryLiveAdapter implements TMemoryInstance {
23120
24699
  * List all entries in memory.
23121
24700
  * @param dto.signalId - Signal identifier
23122
24701
  * @param dto.bucketName - Bucket name
24702
+ * @param dto.when - Logical timestamp at which the list is happening (look-ahead guard)
23123
24703
  * @returns Array of all stored entries
23124
24704
  */
23125
24705
  listMemory: <T extends object = object>(dto: {
23126
24706
  signalId: string;
23127
24707
  bucketName: string;
24708
+ when: Date;
23128
24709
  }) => Promise<{
23129
24710
  memoryId: string;
23130
24711
  content: T;
@@ -23134,17 +24715,20 @@ declare class MemoryLiveAdapter implements TMemoryInstance {
23134
24715
  * @param dto.memoryId - Unique entry identifier
23135
24716
  * @param dto.signalId - Signal identifier
23136
24717
  * @param dto.bucketName - Bucket name
24718
+ * @param dto.when - Logical timestamp (kept for API consistency; removal is by UUID)
23137
24719
  */
23138
24720
  removeMemory: (dto: {
23139
24721
  memoryId: string;
23140
24722
  signalId: string;
23141
24723
  bucketName: string;
24724
+ when: Date;
23142
24725
  }) => Promise<void>;
23143
24726
  /**
23144
24727
  * Read a single entry from memory.
23145
24728
  * @param dto.memoryId - Unique entry identifier
23146
24729
  * @param dto.signalId - Signal identifier
23147
24730
  * @param dto.bucketName - Bucket name
24731
+ * @param dto.when - Logical timestamp at which the read is happening (look-ahead guard)
23148
24732
  * @returns Entry value
23149
24733
  * @throws Error if entry not found
23150
24734
  */
@@ -23152,6 +24736,7 @@ declare class MemoryLiveAdapter implements TMemoryInstance {
23152
24736
  memoryId: string;
23153
24737
  signalId: string;
23154
24738
  bucketName: string;
24739
+ when: Date;
23155
24740
  }) => Promise<T>;
23156
24741
  /**
23157
24742
  * Switches to in-memory BM25 adapter.
@@ -23212,6 +24797,7 @@ declare class MemoryAdapter {
23212
24797
  * @param dto.bucketName - Bucket name
23213
24798
  * @param dto.description - BM25 index string; defaults to JSON.stringify(value)
23214
24799
  * @param dto.backtest - Flag indicating if the context is backtest or live
24800
+ * @param dto.when - Logical timestamp this entry belongs to (look-ahead guard)
23215
24801
  */
23216
24802
  writeMemory: <T extends object = object>(dto: {
23217
24803
  memoryId: string;
@@ -23220,6 +24806,7 @@ declare class MemoryAdapter {
23220
24806
  bucketName: string;
23221
24807
  description: string;
23222
24808
  backtest: boolean;
24809
+ when: Date;
23223
24810
  }) => Promise<void>;
23224
24811
  /**
23225
24812
  * Search memory using BM25 full-text scoring.
@@ -23228,6 +24815,7 @@ declare class MemoryAdapter {
23228
24815
  * @param dto.signalId - Signal identifier
23229
24816
  * @param dto.bucketName - Bucket name
23230
24817
  * @param dto.backtest - Flag indicating if the context is backtest or live
24818
+ * @param dto.when - Logical timestamp at which the search is happening (look-ahead guard)
23231
24819
  * @returns Matching entries sorted by relevance score
23232
24820
  */
23233
24821
  searchMemory: <T extends object = object>(dto: {
@@ -23236,6 +24824,7 @@ declare class MemoryAdapter {
23236
24824
  bucketName: string;
23237
24825
  settings?: SearchSettings;
23238
24826
  backtest: boolean;
24827
+ when: Date;
23239
24828
  }) => Promise<{
23240
24829
  memoryId: string;
23241
24830
  score: number;
@@ -23247,12 +24836,14 @@ declare class MemoryAdapter {
23247
24836
  * @param dto.signalId - Signal identifier
23248
24837
  * @param dto.bucketName - Bucket name
23249
24838
  * @param dto.backtest - Flag indicating if the context is backtest or live
24839
+ * @param dto.when - Logical timestamp at which the list is happening (look-ahead guard)
23250
24840
  * @returns Array of all stored entries
23251
24841
  */
23252
24842
  listMemory: <T extends object = object>(dto: {
23253
24843
  signalId: string;
23254
24844
  bucketName: string;
23255
24845
  backtest: boolean;
24846
+ when: Date;
23256
24847
  }) => Promise<{
23257
24848
  memoryId: string;
23258
24849
  content: T;
@@ -23264,12 +24855,14 @@ declare class MemoryAdapter {
23264
24855
  * @param dto.signalId - Signal identifier
23265
24856
  * @param dto.bucketName - Bucket name
23266
24857
  * @param dto.backtest - Flag indicating if the context is backtest or live
24858
+ * @param dto.when - Logical timestamp (kept for API consistency; removal is by UUID)
23267
24859
  */
23268
24860
  removeMemory: (dto: {
23269
24861
  memoryId: string;
23270
24862
  signalId: string;
23271
24863
  bucketName: string;
23272
24864
  backtest: boolean;
24865
+ when: Date;
23273
24866
  }) => Promise<void>;
23274
24867
  /**
23275
24868
  * Read a single entry from memory.
@@ -23278,6 +24871,7 @@ declare class MemoryAdapter {
23278
24871
  * @param dto.signalId - Signal identifier
23279
24872
  * @param dto.bucketName - Bucket name
23280
24873
  * @param dto.backtest - Flag indicating if the context is backtest or live
24874
+ * @param dto.when - Logical timestamp at which the read is happening (look-ahead guard)
23281
24875
  * @returns Entry value
23282
24876
  * @throws Error if entry not found
23283
24877
  */
@@ -23286,6 +24880,7 @@ declare class MemoryAdapter {
23286
24880
  signalId: string;
23287
24881
  bucketName: string;
23288
24882
  backtest: boolean;
24883
+ when: Date;
23289
24884
  }) => Promise<T>;
23290
24885
  }
23291
24886
  /**
@@ -26547,6 +28142,15 @@ declare namespace emitters {
26547
28142
  */
26548
28143
  declare const alignToInterval: (date: Date, interval: CandleInterval) => Date;
26549
28144
 
28145
+ /**
28146
+ * Returns the step in milliseconds for a given candle interval.
28147
+ * For example, for "15m" interval, it returns 900000 (15 * 60 * 1000).
28148
+ *
28149
+ * @param interval - Candle interval (e.g., "1m", "15m", "1h")
28150
+ * @returns Step in milliseconds corresponding to the interval
28151
+ */
28152
+ declare const intervalStepMs: (interval: CandleInterval) => number;
28153
+
26550
28154
  /**
26551
28155
  * Waits for the next candle interval to start and returns the timestamp of the new candle.
26552
28156
  * @param {CandleInterval} interval - The candle interval (e.g., "1m", "1h") to wait for.
@@ -27309,7 +28913,33 @@ declare class ClientRisk implements IRisk {
27309
28913
  * @param params - Risk check arguments (passthrough from ClientStrategy)
27310
28914
  * @returns Promise resolving to true if allowed, false if rejected
27311
28915
  */
27312
- checkSignal: (params: IRiskCheckArgs) => Promise<boolean>;
28916
+ checkSignal: (params: IRiskCheckArgs, options?: Partial<IRiskCheckOptions>) => Promise<boolean>;
28917
+ /**
28918
+ * Concurrency-safe variant of {@link checkSignal}: validates the signal AND
28919
+ * reserves a placeholder slot in the active position map atomically.
28920
+ *
28921
+ * **Why this exists.** `checkSignal` followed later by `addSignal` is not
28922
+ * atomic — between the two calls the caller does signal setup work that
28923
+ * yields to the event loop (sync-open callback, persist writes, etc.). When
28924
+ * several strategies sharing the same risk profile run in parallel, all of
28925
+ * them can pass `checkSignal` while the active position map is still empty,
28926
+ * then each call `addSignal` and blow past the limit. Reserving inside the
28927
+ * lock guarantees the next concurrent caller observes the incremented size
28928
+ * before its own validation runs.
28929
+ *
28930
+ * The reservation uses the same map key as the eventual `addSignal` call
28931
+ * (`strategyName + exchangeName + symbol`), so `addSignal` overwrites the
28932
+ * placeholder rather than appending a duplicate.
28933
+ *
28934
+ * Callers MUST ensure that every successful return is followed by either
28935
+ * `addSignal` (overwrites the placeholder with real data) or `removeSignal`
28936
+ * (clears the placeholder if opening is aborted). Otherwise the riskMap
28937
+ * accumulates stale reservations.
28938
+ *
28939
+ * @param params - Risk check arguments (passthrough from ClientStrategy)
28940
+ * @returns Promise resolving to true if allowed (and reserved), false if rejected (no reservation)
28941
+ */
28942
+ checkSignalAndReserve: (params: IRiskCheckArgs) => Promise<boolean>;
27313
28943
  }
27314
28944
 
27315
28945
  /**
@@ -27728,6 +29358,26 @@ declare class RiskConnectionService implements TRisk$1 {
27728
29358
  exchangeName: ExchangeName;
27729
29359
  frameName: FrameName;
27730
29360
  backtest: boolean;
29361
+ }, options?: Partial<IRiskCheckOptions>) => Promise<boolean>;
29362
+ /**
29363
+ * Concurrency-safe variant of {@link checkSignal} — validates the signal AND
29364
+ * reserves a placeholder in the active position map atomically.
29365
+ *
29366
+ * Routes to the same ClientRisk instance as {@link checkSignal} but delegates
29367
+ * to its `checkSignalAndReserve` method. Use from execution paths where the
29368
+ * caller will follow up with `addSignal` on success — guarantees concurrent
29369
+ * callers cannot all pass validation against a stale empty map. See
29370
+ * {@link IRisk.checkSignalAndReserve} for the full rationale.
29371
+ *
29372
+ * @param params - Risk check arguments (portfolio state, position details)
29373
+ * @param payload - Execution payload with risk name, exchangeName, frameName and backtest mode
29374
+ * @returns Promise resolving to true if allowed (and reserved), false if rejected (no reservation)
29375
+ */
29376
+ checkSignalAndReserve: (params: IRiskCheckArgs, payload: {
29377
+ riskName: RiskName;
29378
+ exchangeName: ExchangeName;
29379
+ frameName: FrameName;
29380
+ backtest: boolean;
27731
29381
  }) => Promise<boolean>;
27732
29382
  /**
27733
29383
  * Registers an opened signal with the risk management system.
@@ -31404,6 +33054,25 @@ declare class RiskGlobalService implements TRisk {
31404
33054
  exchangeName: ExchangeName;
31405
33055
  frameName: FrameName;
31406
33056
  backtest: boolean;
33057
+ }, options?: Partial<IRiskCheckOptions>) => Promise<boolean>;
33058
+ /**
33059
+ * Concurrency-safe variant of {@link checkSignal} — validates the signal AND
33060
+ * reserves a placeholder in the active position map atomically.
33061
+ *
33062
+ * Use from strategy execution paths where the caller will follow up with
33063
+ * `addSignal` on success — guarantees concurrent callers cannot all pass
33064
+ * validation against a stale empty map. See {@link IRisk.checkSignalAndReserve}
33065
+ * for the full rationale.
33066
+ *
33067
+ * @param params - Risk check arguments (portfolio state, position details)
33068
+ * @param payload - Execution payload with risk name, exchangeName, frameName and backtest mode
33069
+ * @returns Promise resolving to true if allowed (and reserved), false if rejected (no reservation)
33070
+ */
33071
+ checkSignalAndReserve: (params: IRiskCheckArgs, payload: {
33072
+ riskName: RiskName;
33073
+ exchangeName: ExchangeName;
33074
+ frameName: FrameName;
33075
+ backtest: boolean;
31407
33076
  }) => Promise<boolean>;
31408
33077
  /**
31409
33078
  * Registers an opened signal with the risk management system.
@@ -34157,4 +35826,4 @@ declare const getTotalClosed: (signal: Signal) => {
34157
35826
  remainingCostBasis: number;
34158
35827
  };
34159
35828
 
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 };
35829
+ 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, intervalStepMs, 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 };