ti-engine
    Preparing search index...

    ti-engine

    npm version npm downloads Bundle size Node

    WASM TypeScript Docs CI License

    ti-engine

    ti-engine is a WebAssembly-powered, JS/TS-idiomatic wrapper around RustTI — a high‑performance, pure‑Rust technical indicators library.

    • Production‑grade indicators, ported from battle‑tested Rust code
    • First‑class TypeScript types and clean, namespaced API
    • Works in Node and modern browsers (bundler + web builds)
    • Identical results to RustTI (with parity tests for core functions)

    Looking for the Rust crate? See: ChironMind/RustTI

    Looking for the Python version? See: ChironMind/PyTechnicalIndicators


    Install from your package manager (example: local/private package)

    # npm
    npm install ti-engine

    # yarn
    yarn add ti-engine

    # pnpm
    pnpm add ti-engine

    Initialize and use (Node)

    import init, {
    momentumIndicators,
    ConstantModelType,
    } from "ti-engine";

    // Node: init() is a no-op, but safe to call
    await init();

    const prices = [100.2, 100.46, 100.53, 100.38, 100.19];

    const rsi = momentumIndicators.single.relativeStrengthIndex(
    prices,
    ConstantModelType.SimpleMovingAverage
    );

    console.log("RSI:", rsi); // 49.2537313432832

    Browser (bundlers)

    import init, { movingAverage, MovingAverageType } from "ti-engine";

    await init(); // Required to load the WASM module in browsers

    const sma = movingAverage.single.movingAverage(
    [100.2, 100.46, 100.53, 100.38, 100.19],
    MovingAverageType.Simple
    );

    console.log("SMA:", sma); // 100.352

    • Same math and deterministic outputs as RustTI
    • Two styles for almost every indicator:
      • single: full-window, scalar output
      • bulk: rolling windows, vector output
    • Clean naming and nested namespaces:
      • candleIndicators, chartTrends, correlationIndicators, momentumIndicators, movingAverage, otherIndicators, standardIndicators, strengthIndicators, trendIndicators, volatilityIndicators

    Fully typed with ambient declarations — enjoy rich editor hints and autocomplete.


    All indicator namespaces expose:

    • single: functions that compute a single value from the whole input
    • bulk: functions that compute rolling outputs (arrays)

    Common enums:

    • ConstantModelType: SimpleMovingAverage, SmoothedMovingAverage, ExponentialMovingAverage, SimpleMovingMedian, SimpleMovingMode, PersonalisedMovingAverage
    • DeviationModel: StandardDeviation, MeanAbsoluteDeviation, MedianAbsoluteDeviation, ModeAbsoluteDeviation, UlcerIndex
    • Position: Long, Short (for SAR-like systems)
    • MovingAverageType: Simple, Smoothed, Exponential (for generic moving average helpers)

    Top namespaces:

    • movingAverage: generic MAs and McGinley Dynamic
    • momentumIndicators: RSI, Stochastic, MACD variants, PPO, MFI, OBV, CCI, Williams %R, Chaikin, CMO
    • strengthIndicators: Accumulation/Distribution, PVI, NVI, RVI
    • trendIndicators: Aroon (Up/Down/Oscillator), Parabolic Time Price System, Directional Movement System (+DI, –DI, ADX/ADXR), VPT, TSI
    • volatilityIndicators: Ulcer Index, Wilder’s volatility system
    • candleIndicators: Bands/Envelopes, Ichimoku, Donchian, Keltner, Supertrend
    • correlationIndicators: Asset correlation
    • chartTrends: Peaks/Valleys, trend lines, segmentation
    • otherIndicators: ROI, True Range / ATR, Internal Bar Strength, Positivity Indicator

    See the full set of function signatures via your editor or the included index.d.ts.


    Relative Strength Index (RSI)

    import init, { momentumIndicators, ConstantModelType } from "ti-engine";
    await init();

    const prices = [100.2, 100.46, 100.53, 100.38, 100.19, 100.21, 100.32, 100.28];

    // Full window (single)
    const rsi = momentumIndicators.single.relativeStrengthIndex(
    prices.slice(0, 5),
    ConstantModelType.SimpleMovingAverage
    );
    // -> 49.2537313432832

    // Rolling (bulk), period = 5
    const rsiSeries = momentumIndicators.bulk.relativeStrengthIndex(
    prices,
    ConstantModelType.SimpleMovingAverage,
    5
    );
    // -> [49.2537..., 20.9302..., 27.6595..., 36.1111...]

    MACD (EMA/EMA)

    import { momentumIndicators, ConstantModelType } from "ti-engine";

    const macdLine = momentumIndicators.single.macdLine(
    [100.46, 100.53, 100.38, 100.19, 100.21],
    3,
    ConstantModelType.ExponentialMovingAverage,
    ConstantModelType.ExponentialMovingAverage
    );
    // -> -0.06067027758972188

    const signal = momentumIndicators.single.signalLine(
    [-0.06067027758972188, -0.022417061611406552, 0.005788761002008869],
    ConstantModelType.ExponentialMovingAverage
    );
    // -> -0.011764193829214216

    Parabolic Time Price System (SAR)

    import { trendIndicators, Position, ConstantModelType } from "ti-engine";

    // Long SAR track with rolling outputs
    const sars = trendIndicators.bulk.parabolicTimePriceSystem(
    [100.64, 102.39, 101.51, 99.48, 96.93], // highs
    [95.92, 96.77, 95.84, 91.22, 89.12], // lows
    0.02, 0.2, 0.02, // AF start, max, step
    Position.Long, // starting side
    0.0 // previous SAR (seed)
    );
    // -> [95.92, 95.92, 102.39, 101.9432, 101.17380800000001]

    Ulcer Index (volatility)

    import { volatilityIndicators } from "ti-engine";

    const ui = volatilityIndicators.single.ulcerIndex(
    [100.46, 100.53, 100.38, 100.19, 100.21]
    );
    // -> 0.21816086938686668

    Moving Average helpers

    import { movingAverage, MovingAverageType } from "ti-engine";

    const sma = movingAverage.single.movingAverage(
    [100.2, 100.46, 100.53, 100.38, 100.19],
    MovingAverageType.Simple
    );
    // -> 100.352

    This package includes three targets out of the box:

    • Node: dist/node/ti_engine.js (CommonJS require via index.node.js)
    • Bundler: dist/bundler/ti_engine.js (ESM, for Vite/Webpack/Rollup)
    • Web: dist/web/ti_engine.js (ESM + separate .wasm)

    Import surfaces:

    • Node: import init, * as api from "ti-engine/index.node.js"; (or default import from package root)
    • Bundler/Web: import init, * as api from "ti-engine";

    Initialization:

    • Web/Bundlers: You MUST await init() before calling indicators (it fetches/instantiates WASM).
    • Node: init() is a no‑op, safe to call for parity in shared code paths.

    • Input validation mirrors RustTI: many functions panic for empty arrays or mismatched lengths. In JS, this surfaces as a thrown error.
    • Use Float64Array or number[]. Internally, values are copied into WASM memory; consider chunking for very large series.
    • Bulk functions typically return arrays of length L - N + 1 where N is the rolling period (or long period for dual-period indicators).
    • All outputs are plain JS arrays for easy consumption; tuples are represented as small arrays (e.g., [lower, middle, upper]).

    • All math is executed in highly optimized Rust and compiled to WebAssembly.
    • In Node, performance is near-native for numeric workloads.
    • In browsers, expect excellent performance; account for WASM boundary crossings (amortize by passing larger slices).

    For raw Rust benchmarks and methodology, see:


    This repo includes value parity tests that assert equality with RustTI for a selection of indicators across modules. Run them in Node:

    npm test
    # or
    node --test ti-engine/test/*.test.js

    Contributions, bug reports, and feature requests are welcome!

    • Open an issue or discussion
    • Submit a PR with tests (value parity preferred)
    • Suggestions for new high‑value wrappers and DX improvements are appreciated

    Please see CONTRIBUTING.md.


    See Git history and changelog for details. We follow semver where possible for API changes.


    MIT License. See LICENSE.