Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/theonetrade/backtest-kit-redis-mongo-docker/llms.txt

Use this file to discover all available pages before exploring further.

These three adapters manage the runtime lifecycle of a strategy. Recent stores the most recently published signal for a specific trading context — the value a subscriber would see if they queried right now. State provides named data buckets scoped to an individual signal, enabling complex stateful strategies to persist intermediate computations across bars. Session holds a single active session record per unique strategy configuration, persisting across restarts. Both State and Session implement a dispose() no-op for lifecycle interface compatibility.

Recent Adapter

The Recent adapter has the most complex context key of any adapter: five fields including a backtest: boolean flag. This ensures that a backtest run and a live run for the same symbol and strategy never overwrite each other’s most-recent signal.

Constructor

class implements IPersistRecentInstance {
  constructor(
    readonly symbol: string,
    readonly strategyName: string,
    readonly exchangeName: string,
    readonly frameName: string,
    readonly backtest: boolean,
  ) {}
}
symbol
string
required
The trading pair symbol, e.g. "BTCUSDT".
strategyName
string
required
The unique name of the strategy instance.
exchangeName
string
required
The exchange identifier, e.g. "binance".
frameName
string
required
The name of the strategy frame or timeframe variant, e.g. "4h-frame".
backtest
boolean
required
true for backtest mode; false for live or paper trading.

readRecentData

Fetches the most recently written signal payload for this context. Returns null when no record exists.
async readRecentData(): Promise<RecentData> {
  const row = await ioc.recentDbService.findByContext(
    this.symbol, this.strategyName, this.exchangeName,
    this.frameName, this.backtest,
  );
  return row ? row.payload : null;
}
Returns: RecentData — the stored payload, or null if no record exists.

writeRecentData

Upserts the most recent signal payload for this context, storing when alongside it.
async writeRecentData(signalRow: NonNullable<RecentData>, when: Date): Promise<void> {
  await ioc.recentDbService.upsert(
    this.symbol, this.strategyName, this.exchangeName,
    this.frameName, this.backtest, signalRow, when,
  );
}
signalRow
NonNullable<RecentData>
required
The signal payload to store. Must be non-null — use the Signal adapter to clear signal state.
when
Date
required
The bar time at which this signal was published.
writeRecentData accepts NonNullable<RecentData> — it is not possible to write null to the Recent adapter. The Recent record persists until overwritten by a newer signal.

Redis Cache Key Pattern

recent_cache:<symbol>:<strategyName>:<exchangeName>:<frameName>:<backtest>

State Adapter

The State adapter provides a single named data bucket per (signalId, bucketName) pair. It is used by strategies that need to persist complex intermediate state — such as a running average, a Fibonacci level, or a sequence of bar patterns — scoped to the lifecycle of an individual signal.

Constructor

class implements IPersistStateInstance {
  constructor(
    readonly signalId: string,
    readonly bucketName: string,
  ) {}
}
signalId
string
required
The unique ID of the signal that owns this state bucket.
bucketName
string
required
A label for this state slot, e.g. "entry-analysis" or "trailing-data".

readStateData

Fetches the state payload for this context. Returns null when no state has been written yet.
async readStateData(): Promise<StateData | null> {
  const row = await ioc.stateDbService.findByContext(
    this.signalId, this.bucketName,
  );
  return row ? row.payload : null;
}
Returns: StateData | null

writeStateData

Upserts the state payload for this context, storing when alongside it.
async writeStateData(data: StateData, when: Date): Promise<void> {
  await ioc.stateDbService.upsert(
    this.signalId, this.bucketName, data, when,
  );
}
data
StateData
required
The state payload to persist.
when
Date
required
The bar time at which this state was written.

dispose

A no-op lifecycle method required by the IPersistStateInstance interface.
dispose(): void { void 0; }

Session Adapter

The Session adapter persists one active session record per unique strategy configuration. Unlike the State adapter (which is scoped to a signal), a session lives as long as the strategy configuration is running. On restart, the strategy reads its session back and resumes from where it left off. The context key is (strategyName, exchangeName, frameName).

Constructor

class implements IPersistSessionInstance {
  constructor(
    readonly strategyName: string,
    readonly exchangeName: string,
    readonly frameName: string,
  ) {}
}
strategyName
string
required
The name of the strategy configuration, e.g. "momentum-v2".
exchangeName
string
required
The exchange on which the strategy is running.
frameName
string
required
The frame or timeframe variant, e.g. "1h". Together with strategyName and exchangeName, this uniquely identifies one running strategy configuration.

readSessionData

Fetches the active session payload for this strategy configuration. Returns null on first startup before any session has been written.
async readSessionData(): Promise<SessionData | null> {
  const row = await ioc.sessionDbService.findByContext(
    this.strategyName, this.exchangeName, this.frameName,
  );
  return row ? row.payload : null;
}
Returns: SessionData | null

writeSessionData

Upserts the session payload for this strategy configuration.
async writeSessionData(data: SessionData, when: Date): Promise<void> {
  await ioc.sessionDbService.upsert(
    this.strategyName, this.exchangeName, this.frameName, data, when,
  );
}
data
SessionData
required
The session state to persist.
when
Date
required
The bar time at which the session was last updated.

dispose

A no-op lifecycle method required by the IPersistSessionInstance interface.
dispose(): void { void 0; }
Because Session is keyed by (strategyName, exchangeName, frameName) without a signal ID or backtest flag, there is exactly one session document per running strategy configuration. Starting a new backtest run will overwrite the session from a previous run for the same configuration unless you use distinct strategyName or frameName values.

Collection Summary

AdapterCollectionContext Keydispose()Null Write
Recentrecent-items(symbol, strategyName, exchangeName, frameName, backtest)NoNot supported
Statestate-items(signalId, bucketName)Yes (no-op)Not applicable
Sessionsession-items(strategyName, exchangeName, frameName)Yes (no-op)Not applicable
State and Session both implement dispose() as a no-op (void 0). This satisfies the lifecycle interface contract used by the backtest-kit framework when tearing down adapter instances at the end of a run.

Build docs developers (and LLMs) love