Skip to content

@livefolio/sdk / FeatureRuntime

Class: FeatureRuntime

Defined in: features/runtime.ts:164

Orchestrates indicator computation for a single backtest run or a live streaming session.

FeatureRuntime is the bridge between raw OHLCV data (via DataFeed) and the typed indicator functions registered in the feature registry. It handles:

  • Bar fetching (historical mode) — Calls DataFeed.bars once per (asset, range, freq) tuple and caches the resulting Series in memory for the lifetime of the instance. Concurrent calls for the same asset share a single in-flight promise; there is no redundant fetching even if compute is called from multiple Promise.all branches simultaneously.
  • Bar buffering (streaming mode) — Bars are pushed in via appendBar. compute reads directly from the in-memory buffer; DataFeed.bars is never called.
  • Indicator dispatch — Delegates computation to the function registered via defineFeature for the given FeatureSpec.kind.
  • Persistent caching (historical mode only) — Checks FeatureCache before computing. On a miss, the result is stored in the cache. Subsequent calls with the same (spec, asset) combination return instantly from cache without re-fetching bars.

Caching semantics:

  • Historical mode: cache keys incorporate spec, asset.id, range, and freq. Results are read from and written to featureCache.
  • Streaming mode: featureCache is bypassed entirely — every compute call recomputes from the growing in-memory bar buffer. The seriesCache (per-asset in-memory base-series cache) is the only cache layer; it is invalidated on each appendBar so the next compute sees the updated buffer.
  • Calling appendBar invalidates the in-memory series cache for that asset so the next compute call rebuilds the series from the updated buffer.

Examples

ts
import {
  FeatureRuntime,
  MemoryFeatureCache,
  seriesAt,
} from '@livefolio/sdk';

const runtime = new FeatureRuntime({
  dataFeed,
  featureCache: new MemoryFeatureCache(),
  range: { from: new Date('2022-01-01'), to: new Date('2023-12-31') },
  freq: '1d',
});

const spy = { kind: 'equity' as const, id: 'US:SPY', symbol: 'SPY' };
const smaSeries = await runtime.compute({ kind: 'sma', period: 20 }, spy);
const latestSma = seriesAt(smaSeries, new Date('2023-06-15'));
// => number | undefined
ts
const runtime = new FeatureRuntime({
  featureCache: new MemoryFeatureCache(),
  mode: 'streaming',
  freq: '1d',
  initialBars,         // optional seed from BacktestResult
});

runtime.appendBar(spy, latestBar);
const smaSeries = await runtime.compute({ kind: 'sma', period: 20 }, spy);

Constructors

Constructor

new FeatureRuntime(opts): FeatureRuntime

Defined in: features/runtime.ts:180

Parameters

ParameterType
optsFeatureRuntimeOptions

Returns

FeatureRuntime

Methods

appendBar()

appendBar(asset, bar): void

Defined in: features/runtime.ts:220

Appends a bar to the streaming buffer for the given asset.

Bars must be provided in non-decreasing t order per asset. A bar with the same t as the most recent buffered bar replaces it in place — this is the mark-to-market wiggle path used by runLive, where each incoming tick updates the running open/high/low/close of the in-flight session bar. A bar with t strictly greater than the buffered tail starts a fresh in-flight bar (e.g. at session boundaries). A bar with t strictly less than the buffered tail throws.

Also invalidates the in-memory series cache for the asset so the next compute call rebuilds the series from the updated buffer.

Parameters

ParameterType
assetAsset
barBar

Returns

void

Throws

If called on a historical-mode runtime.

Throws

If bar.t is strictly less than the last buffered bar's t.


compute()

compute(spec, asset): Promise<Series>

Defined in: features/runtime.ts:337

Computes (or retrieves from cache) the output Series for a given feature spec applied to a specific asset.

Historical mode: on the first call for a (spec, asset) pair:

  1. Fetches or reuses the in-memory base Series for the asset.
  2. Dispatches to the registered compute function for spec.kind.
  3. Stores the result in featureCache. On subsequent calls, returns the cached Series directly from featureCache.

Streaming mode: reads from the in-memory bar buffer populated via appendBar. DataFeed.bars is never called. The persistent featureCache is bypassed entirely — results are never read from or written to it. The in-memory seriesCache (base series per asset) is the only cache layer and is invalidated on each appendBar, so every compute after a new bar reflects the updated buffer.

Parameters

ParameterTypeDescription
specFeatureSpecThe feature specification describing which indicator to compute and its parameters (e.g. { kind: 'sma', period: 20 }).
assetAssetThe asset for which to compute the feature. The asset's id is used both for data fetching and cache key construction.

Returns

Promise<Series>

A promise that resolves to the computed Series. The series length is determined by the indicator's warmup: for example, SMA(20) returns series.length - 19 data points. Returns an empty array when the base series is shorter than the indicator's warmup period.

Example

ts
const spy = { kind: 'equity' as const, id: 'US:SPY', symbol: 'SPY' };

const [priceSeries, smaSeries] = await Promise.all([
  runtime.compute({ kind: 'price' }, spy),
  runtime.compute({ kind: 'sma', period: 20 }, spy),
]);

getAllBars()

getAllBars(): ReadonlyMap<string, readonly Bar[]>

Defined in: features/runtime.ts:284

Returns the full per-asset bar map (keyed by AssetId). Merges historical and streaming buffers (streaming wins on collision, but in practice an instance is in one mode at a time so collisions don't occur).

Returns a fresh Map — callers cannot mutate the internal state.

Returns

ReadonlyMap<string, readonly Bar[]>


getBars()

getBars(asset): readonly Bar[]

Defined in: features/runtime.ts:273

Returns the bar buffer for asset, or an empty array if none has been fetched/buffered yet.

In historical mode this is populated after the first compute call that triggers a bar fetch for the asset. In streaming mode it reflects all bars pushed via appendBar.

Parameters

ParameterType
assetAsset

Returns

readonly Bar[]

Released under the MIT License.