npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

ti-engine

v1.1.4

Published

WASM bindings for RustTI technical indicators for Node and browser

Readme

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


🚀 Quick Start

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

Browser (CDN - jsdelivr/unpkg)

<script type="module">
  // Note: Replace @latest with a specific version (e.g., @1.1.2) for production use
  import init, * as wasm from 'https://cdn.jsdelivr.net/npm/ti-engine@latest/dist/web/ti_engine.js';
  
  await init(); // Initialize WASM module
  
  // When using the web target directly, use the flat WASM exports
  const prices = [100.2, 100.46, 100.53, 100.38, 100.19];
  const rsi = wasm.momentum_single_relativeStrengthIndex(
    prices,
    wasm.ConstantModelType.SimpleMovingAverage
  );
  
  console.log("RSI:", rsi); // 49.2537313432832
  
  // Or use the index.web.js wrapper for the same namespaced API as bundlers
  // import init, { momentumIndicators, ConstantModelType } from 'https://cdn.jsdelivr.net/npm/[email protected]/index.web.js';
</script>

🧩 What You Get

  • 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.


📚 API Overview

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.


🧪 Usage Examples

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

🔌 Builds and Initialization

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.

🧠 Tips & Conventions

  • 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]).

📈 Performance

  • 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:


🧪 Parity Tests

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

🤝 Contributing

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.


📰 Release Notes

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


📄 License

MIT License. See LICENSE.