EngineMarket Data

Getting started

Inspect the observations reaching SJS with a bounded, observation-only diagnostic.

Start with a short Agent Lab backtest using one instrument and a known data period. Record the instrument, interval, UTC bounds, timezone, and session settings before running.

Observe the current frame

Save your strategy before replacing its SJS source with this diagnostic. Use a fresh experiment without other execution layers if you want an observation-only run: this script makes no order requests, but it does not disable configured algorithms or L3 actions.

The script logs the first five invocations and keeps counters after that. A valid observation here means a usable timestamp and finite numeric close; it does not mean that all OHLCV fields or exchange-session coverage have been validated.

export async function app({ context, bar, log }) {
  const state = (context.sjsState ??= {}).marketDataProbe ??= {
    seen: 0, invalid: 0, increasing: 0, repeated: 0, older: 0,
  };
  state.seen += 1;
  const timestamp = bar?.date == null ? NaN : new Date(bar.date).getTime();
  const valid = Number.isFinite(timestamp)
    && typeof bar?.close === "number" && Number.isFinite(bar.close);
  let kind = "invalid";
  if (!valid) {
    state.invalid += 1;
  } else if (state.latestTimestamp == null || timestamp > state.latestTimestamp) {
    kind = "increasing";
    state.increasing += 1;
    state.latestTimestamp = timestamp;
  } else if (timestamp === state.latestTimestamp) {
    kind = "repeated";
    state.repeated += 1;
  } else {
    kind = "older";
    state.older += 1;
  }
  if (state.seen <= 5) {
    log?.("market-data-probe", {
      frame: state.seen, kind,
      timestamp: valid ? new Date(timestamp).toISOString() : null,
      close: valid ? bar.close : null,
      latestTimestamp: state.latestTimestamp ?? null,
    });
  }
}

Check the expected behavior

For this input sequence, the classifications should be:

InvocationTimestampCloseClassification
110:00 UTC100increasing
210:00 UTC101repeated
309:59 UTC99older
410:01 UTCmissinginvalid
510:01 UTC102increasing

The repeated observation can contain a changed price. The script classifies it by timestamp; it does not decide whether it is a completed candle. Invalid and older inputs never move the latest valid timestamp backwards or forwards.

Inspect the result

Open Logs for the selected run and compare its first five probe records with the input data. The counters live in context.sjsState; do not expect Agent Lab's saved results to include the entire state object. If the first frames explain too little, adapt the logging to a specific interval rather than logging every field on every frame.

Save the diagnostic as its own revision. Restore the original trading source before evaluating trading behavior.

Next, verify instrument identity, then define your sampling rule.

On this page