Skip to main content

Documentation Index

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

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

These three adapters track risk management state during a live or paper trading session. Risk holds a snapshot of all active positions grouped under a named risk manager on a given exchange. Partial holds the per-signal partial profit/loss level map — which partial targets have been hit for a given open signal. Breakeven tracks whether the breakeven level has been reached for each open signal. Together they give the risk layer a durable, resumable view of the current exposure and take-profit progress across restarts.
The writePositionData, writePartialData, and writeBreakevenData methods all accept a when: Date parameter. This timestamp is persisted inside the stored document (when field, stored as epoch milliseconds) for audit and ordering purposes, but it does not become part of the MinIO object key. Keys for all three adapters are deterministic functions of context fields only — a write is always a single idempotent PUT at the same key regardless of when it is called.
Both Partial and Breakeven include signalId as the final segment of their object key (symbol/strategyName/exchangeName/signalId). This means every open signal gets its own isolated state bucket — partial levels for signal A never overwrite those for signal B, even when they run under the same strategy context.

Risk adapter

Purpose

The Risk adapter persists the RiskData snapshot — an array of active position records — for a (riskName, exchangeName) pair. backtest-kit writes this snapshot after every position mutation made by the risk manager, and reads it on startup to restore the in-memory position list. One MinIO object per risk/exchange pair tracks the full current exposure. The underlying service stores objects under the backtest-kit/risk-items/ prefix (bucket backtest-kit, folder risk-items).

Constructor context

src/config/setup.ts
PersistRiskAdapter.usePersistRiskAdapter(class implements IPersistRiskInstance {
  constructor(
    readonly riskName: string,
    readonly exchangeName: string,
  ) {}
  // ...
});
riskName is the identifier of the risk manager instance (e.g. a named portfolio or risk policy), and exchangeName is the exchange it operates on. These two fields uniquely address one risk snapshot object.

Object key pattern

{riskName}/{exchangeName}
For example, a risk manager named MainRisk on the ccxt exchange resolves to:
backtest-kit/risk-items/MainRisk/ccxt

Interface methods

src/config/setup.ts
async readPositionData(_when: Date): Promise<RiskData> {
  const row = await ioc.riskDataService.findByContext(
    this.riskName,
    this.exchangeName,
  );
  return row ? row.positions : [];
}

async writePositionData(positions: RiskData, when: Date): Promise<void> {
  await ioc.riskDataService.upsert(
    this.riskName,
    this.exchangeName,
    positions,
    when,
  );
}
readPositionData returns the stored RiskData array, or an empty array [] if no snapshot has been written yet. The _when argument on the read side is accepted for interface compatibility but not used — the read always returns the latest upserted value. writePositionData persists both the positions array and the when timestamp inside the stored document.

Schema

src/schema/Risk.schema.ts
import { RiskData } from "backtest-kit";

interface IRiskDto {
  riskName: string;
  exchangeName: string;
  positions: RiskData;  // array of active position records
  when: number;         // epoch ms from the when: Date passed to writePositionData
}

interface IRiskRow extends IRiskDto {
  id: string;           // equals the object key: riskName/exchangeName
  createDate: Date;
  updatedDate: Date;
}
RiskData is the backtest-kit type representing the collection of active risk positions. when is stored as epoch milliseconds and can be used downstream for staleness checks or audit logging.

Adapter registration

src/config/setup.ts
PersistRiskAdapter.usePersistRiskAdapter(class implements IPersistRiskInstance {
  constructor(
    readonly riskName: string,
    readonly exchangeName: string,
  ) {}

  async waitForInit(initial: boolean) {
    if (!initial) {
      return;
    }
    await waitForInfra();
  }

  async readPositionData(_when: Date): Promise<RiskData> {
    const row = await ioc.riskDataService.findByContext(
      this.riskName,
      this.exchangeName,
    );
    return row ? row.positions : [];
  }

  async writePositionData(positions: RiskData, when: Date): Promise<void> {
    await ioc.riskDataService.upsert(
      this.riskName,
      this.exchangeName,
      positions,
      when,
    );
  }
});

Partial adapter

Purpose

The Partial adapter persists the PartialData map for a specific open signal — a record of which partial profit/loss levels have been triggered. It is scoped to (symbol, strategyName, exchangeName) at the constructor level, with signalId supplied at read/write time to address the per-signal bucket. backtest-kit writes after each partial hit and reads when resuming a signal mid-flight. The underlying service stores objects under the backtest-kit/partial-items/ prefix.

Constructor context

src/config/setup.ts
PersistPartialAdapter.usePersistPartialAdapter(class implements IPersistPartialInstance {
  constructor(
    readonly symbol: string,
    readonly strategyName: string,
    readonly exchangeName: string,
  ) {}
  // ...
});
The constructor captures the trading context. The individual signal is addressed dynamically via the signalId parameter on readPartialData and writePartialData.

Object key pattern

{symbol}/{strategyName}/{exchangeName}/{signalId}
For example, signal sig-abc123 on TRXUSDT / Jan2026Strategy / ccxt:
backtest-kit/partial-items/TRXUSDT/Jan2026Strategy/ccxt/sig-abc123
Each open signal gets its own dedicated object. Closing a signal does not automatically remove this object — it persists until a new signal takes the same signalId, at which point it is overwritten.

Interface methods

src/config/setup.ts
async readPartialData(signalId: string, _when: Date): Promise<PartialData> {
  const row = await ioc.partialDataService.findByContext(
    this.symbol,
    this.strategyName,
    this.exchangeName,
    signalId,
  );
  return row ? row.payload : {};
}

async writePartialData(data: PartialData, signalId: string, when: Date): Promise<void> {
  await ioc.partialDataService.upsert(
    this.symbol,
    this.strategyName,
    this.exchangeName,
    signalId,
    data,
    when,
  );
}
readPartialData returns the stored PartialData map for the given signalId, defaulting to an empty object {} when no entry exists. The _when parameter is accepted for interface compatibility but is unused on reads. writePartialData records both the partial data and the when timestamp in the stored document.

Schema

src/schema/Partial.schema.ts
import { PartialData } from "backtest-kit";

interface IPartialDto {
  symbol: string;
  strategyName: string;
  exchangeName: string;
  signalId: string;
  payload: PartialData;  // map of partial level identifiers to their hit state
  when: number;          // epoch ms from the when: Date passed to writePartialData
}

interface IPartialRow extends IPartialDto {
  id: string;            // equals the object key: symbol/strategyName/exchangeName/signalId
  createDate: Date;
  updatedDate: Date;
}
PartialData is the backtest-kit type that maps partial target names or indices to their execution state. when is stored as epoch milliseconds.

Adapter registration

src/config/setup.ts
PersistPartialAdapter.usePersistPartialAdapter(class implements IPersistPartialInstance {
  constructor(
    readonly symbol: string,
    readonly strategyName: string,
    readonly exchangeName: string,
  ) {}

  async waitForInit(initial: boolean) {
    if (!initial) {
      return;
    }
    await waitForInfra();
  }

  async readPartialData(signalId: string, _when: Date): Promise<PartialData> {
    const row = await ioc.partialDataService.findByContext(
      this.symbol,
      this.strategyName,
      this.exchangeName,
      signalId,
    );
    return row ? row.payload : {};
  }

  async writePartialData(data: PartialData, signalId: string, when: Date): Promise<void> {
    await ioc.partialDataService.upsert(
      this.symbol,
      this.strategyName,
      this.exchangeName,
      signalId,
      data,
      when,
    );
  }
});

Breakeven adapter

Purpose

The Breakeven adapter persists the BreakevenData record for a specific open signal — a map of flags indicating whether each breakeven level has been reached. Like the Partial adapter it is constructed with the trading context and addressed per-signal at runtime. backtest-kit writes after a breakeven trigger fires and reads when resuming a live session to avoid re-triggering already-activated breakevens. The underlying service stores objects under the backtest-kit/breakeven-items/ prefix.

Constructor context

src/config/setup.ts
PersistBreakevenAdapter.usePersistBreakevenAdapter(class implements IPersistBreakevenInstance {
  constructor(
    readonly symbol: string,
    readonly strategyName: string,
    readonly exchangeName: string,
  ) {}
  // ...
});
Constructor shape mirrors the Partial adapter — trading context is fixed at construction; signalId is passed at read/write time.

Object key pattern

{symbol}/{strategyName}/{exchangeName}/{signalId}
For example, signal sig-abc123 on TRXUSDT / Jan2026Strategy / ccxt:
backtest-kit/breakeven-items/TRXUSDT/Jan2026Strategy/ccxt/sig-abc123
The per-signal isolation from the Partial adapter applies here too — each signal has its own independent breakeven state object.

Interface methods

src/config/setup.ts
async readBreakevenData(signalId: string, _when: Date): Promise<BreakevenData> {
  const row = await ioc.breakevenDataService.findByContext(
    this.symbol,
    this.strategyName,
    this.exchangeName,
    signalId,
  );
  return row ? row.payload : {};
}

async writeBreakevenData(data: BreakevenData, signalId: string, when: Date): Promise<void> {
  await ioc.breakevenDataService.upsert(
    this.symbol,
    this.strategyName,
    this.exchangeName,
    signalId,
    data,
    when,
  );
}
readBreakevenData returns the stored BreakevenData map for the given signalId, defaulting to an empty object {} if no record exists yet. The _when parameter is unused on reads. writeBreakevenData records both the breakeven state and the when timestamp in the stored document.

Schema

src/schema/Breakeven.schema.ts
import { BreakevenData } from "backtest-kit";

interface IBreakevenDto {
  symbol: string;
  strategyName: string;
  exchangeName: string;
  signalId: string;
  payload: BreakevenData;  // map of breakeven level identifiers to their activation state
  when: number;            // epoch ms from the when: Date passed to writeBreakevenData
}

interface IBreakevenRow extends IBreakevenDto {
  id: string;              // equals the object key: symbol/strategyName/exchangeName/signalId
  createDate: Date;
  updatedDate: Date;
}
BreakevenData is the backtest-kit type that maps breakeven target names or indices to their triggered state. when is stored as epoch milliseconds.

Adapter registration

src/config/setup.ts
PersistBreakevenAdapter.usePersistBreakevenAdapter(class implements IPersistBreakevenInstance {
  constructor(
    readonly symbol: string,
    readonly strategyName: string,
    readonly exchangeName: string,
  ) {}

  async waitForInit(initial: boolean) {
    if (!initial) {
      return;
    }
    await waitForInfra();
  }

  async readBreakevenData(signalId: string, _when: Date): Promise<BreakevenData> {
    const row = await ioc.breakevenDataService.findByContext(
      this.symbol,
      this.strategyName,
      this.exchangeName,
      signalId,
    );
    return row ? row.payload : {};
  }

  async writeBreakevenData(data: BreakevenData, signalId: string, when: Date): Promise<void> {
    await ioc.breakevenDataService.upsert(
      this.symbol,
      this.strategyName,
      this.exchangeName,
      signalId,
      data,
      when,
    );
  }
});

Build docs developers (and LLMs) love