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

@junduck/trading-indi

v0.998.2

Published

A TypeScript library providing 80+ technical indicators for trading, designed for incremental, stateful calculation perfect for intraday and realtime trading applications

Readme

trading-indi

A comprehensive TypeScript library for incremental trading computations, featuring 80+ technical indicators, candlestick pattern recognition, composable computation primitives, and a powerful DAG-based flow system for building complex trading algorithms.

Why trading-indi?

Traditional technical indicator libraries recalculate entire datasets on each new data point. trading-indi is a complete framework for building sophisticated trading algorithms:

  • 80+ Technical Indicators: Foundation, Statistics, Volatility, Momentum, Oscillators, Stochastic, Trend, and Volume indicators
  • Pattern Recognition: 10+ candlestick pattern heuristics (Doji, Hammer, Marubozu, etc.)
  • Computation Primitives: 40+ arithmetic and logical operators for custom calculations
  • DAG Flow System: Build complex multi-indicator strategies with topological execution
  • Incremental Calculation: Stateful, online algorithms that update efficiently with each tick
  • Perfect for Realtime Trading: Designed for WebSocket streams, tick data, and intraday strategies
  • Memory Efficient: Uses sliding windows and online algorithms
  • Consistent API: Every operator follows the same class/hook pattern
  • Zero Dependencies: Clean, modern TypeScript

Performance

trading-indi is built for speed and efficiency, making it ideal for real-time trading applications:

Benchmark Results

  • Processing Speed: 2+ million indicator calculations per second
  • Latency: ~0.03ms to process a single bar with all 64 indicators
  • Memory Efficiency: ~2.5KB per indicator instance
  • Real-time Capability: Can handle tick data (1000+ bars/second) with ease

Real-time Trading Suitability

All trading strategies tested are feasible for real-time trading:

| Strategy | Indicators | Time per Bar | Max Bars/sec | Status | |----------|------------|--------------|--------------|--------| | Scalping | 5 | 0.0017ms | 590,935 | ✅ FEASIBLE | | Swing Trading | 6 | 0.0020ms | 502,162 | ✅ FEASIBLE | | Trend Following | 6 | 0.0017ms | 597,488 | ✅ FEASIBLE | | Mean Reversion | 6 | 0.0020ms | 488,757 | ✅ FEASIBLE | | Volume Analysis | 6 | 0.0005ms | 1,840,082 | ✅ FEASIBLE | | Multi-Timeframe | 11 | 0.0028ms | 358,709 | ✅ FEASIBLE |

The library can easily handle real-time trading scenarios, including tick data processing, with minimal memory footprint and excellent performance characteristics.

Installation

Install the package from npm:

npm install @junduck/trading-indi
# or
yarn add @junduck/trading-indi
# or
pnpm add @junduck/trading-indi

Library Capabilities

trading-indi is more than just an indicator library - it's a complete framework for building trading algorithms:

| Capability | Components | Use Case | |------------|------------|----------| | Technical Indicators | 80+ indicators across 8 categories | Calculate standard technical indicators incrementally | | Pattern Recognition | 10+ candlestick patterns | Detect chart patterns in realtime | | Computation Primitives | 40+ arithmetic & logical operators | Build custom calculations and trading logic | | DAG Flow System | GraphExec, OpRegistry, Schema validation | Compose complex multi-indicator strategies with automatic dependency resolution |

Architecture Overview

┌─────────────────────────────────────────────────────┐
│                   Your Strategy                     │
├─────────────────────────────────────────────────────┤
│  DAG Flow System (GraphExec + OpRegistry)               │
│  ├─ Topological execution                           │
│  ├─ JSON serialization                              │
│  └─ Forward reference resolution                    │
├─────────────────────────────────────────────────────┤
│  Operators (Stateful, Incremental)                  │
│  ├─ Technical Indicators (80+)                      │
│  ├─ Pattern Recognition (10+)                       │
│  └─ Computation Primitives (40+)                    │
├─────────────────────────────────────────────────────┤
│  Foundation (from @junduck/trading-core)            │
│  └─ Sliding windows, online algorithms              │
└─────────────────────────────────────────────────────┘

Quick Start

Class-Based Usage (Stateful)

import { RSI, EMA, MACD, ATR, BBANDS, ADX } from '@junduck/trading-indi';

const rsi = new RSI({ period: 14 });
const ema = new EMA({ period: 20 });
const macd = new MACD({
  period_fast: 12,
  period_slow: 26,
  period_signal: 9
});
const atr = new ATR({ period: 14 });
const bbands = new BBANDS({ period: 20, stddev: 2 });
const adx = new ADX({ period: 14 });

// Process streaming data
priceStream.on('data', (bar) => {
  const rsiValue = rsi.onData(bar);
  const emaValue = ema.onData(bar.close);
  const { macd: macdLine, signal, histogram } = macd.onData(bar);
  const atrValue = atr.onData(bar);
  const { upper, middle, lower } = bbands.onData(bar.close);
  const adxValue = adx.onData(bar);

  console.log({ rsiValue, emaValue, macdLine, atrValue, bbands: { upper, middle, lower }, adxValue });
});

Functional Usage (Hooks)

import { useRSI, useEMA, useMACD, useATR, useBBANDS, useADX } from '@junduck/trading-indi';

const getRSI = useRSI({ period: 14 });
const getEMA = useEMA({ period: 20 });
const getMACD = useMACD({
  period_fast: 12,
  period_slow: 26,
  period_signal: 9
});
const getATR = useATR({ period: 14 });
const getBBANDS = useBBANDS({ period: 20, stddev: 2 });
const getADX = useADX({ period: 14 });

for (const bar of historicalData) {
  const rsiValue = getRSI(bar);
  const emaValue = getEMA(bar.close);
  const { macd, signal, histogram } = getMACD(bar);
  const atrValue = getATR(bar);
  const { upper, middle, lower } = getBBANDS(bar.close);
  const adxValue = getADX(bar);
}

Available Indicators

Foundation

| Indicator | Parameters | Output | |-----------|------------|--------| | EMA | period or alpha | number | | EWMA | period | number | | SMA | period | number | | Variance | period, ddof? | {mean: number, variance: number} | | Stddev | period, ddof? | {mean: number, stddev: number} | | Min | period | number | | Max | period | number | | Sum | period | number | | MinMax | period | {min: number, max: number} |

Statistics

| Indicator | Parameters | Output | |-----------|------------|--------| | VarianceEW | period or alpha, ddof? | {mean: number, variance: number} | | Cov | period, ddof? | {meanX: number, meanY: number, covariance: number} | | Corr | period, ddof? | {meanX: number, meanY: number, covariance: number, correlation: number} | | Beta | period, ddof? | {meanX: number, meanY: number, covariance: number, beta: number} | | ZSCORE | period | number | | CORRELATION | period | number | | BETA | period | number |

Volatility

| Indicator | Parameters | Output | |-----------|------------|--------| | VOLATILITY | period, annualizedDays? | number | | CVI | period | number | | MASS | period | number | | TR | none | number | | ATR | period | number | | NATR | period | number | | PriceChannel | period | {upper, lower} | | BBANDS | period, stddev? | {upper, middle, lower} | | KC | period, multiplier? | {upper, middle, lower} | | DC | period | {upper, middle, lower} |

Momentum

| Indicator | Parameters | Output | |-----------|------------|--------| | BOP | none | number | | MOM | period | number | | ROC | period | number | | ROCR | period | number | | RSI | period | number | | CMO | period | number | | WAD | none | number | | RVI | period | {rvi, signal} | | TSI | long_period?, short_period?, signal_period? | {tsi, signal} | | BBPOWER | period | {bull_power, bear_power} |

Oscillators

| Indicator | Parameters | Output | |-----------|------------|--------| | AO | none | number | | APO | period_fast, period_slow | number | | DPO | period | number | | Fisher | period | number | | MACD | period_fast, period_slow, period_signal | {macd, signal, histogram} | | PPO | period_fast, period_slow | number | | QSTICK | period | number | | TRIX | period | number | | ULTOSC | period_fast, period_med, period_slow | number |

Stochastic

| Indicator | Parameters | Output | |-----------|------------|--------| | STOCH | k_period?, k_slowing?, d_period? | {k, d} | | STOCHRSI | period | number | | WILLR | period | number |

Trend

| Indicator | Parameters | Output | |-----------|------------|--------| | AROON | period | {up, down} | | AROONOSC | period | number | | CCI | period | number | | VHF | period | number | | DM | period | {plus, minus} | | DI | period | {plus, minus} | | DX | period | number | | ADX | period | number | | ADXR | period | number | | SAR | acceleration?, maximum? | number | | VI | period | {vi_plus, vi_minus} | | ICHIMOKU | tenkan_period?, kijun_period?, senkou_b_period?, displacement? | {tenkan, kijun, senkou_a, senkou_b, chikou} |

Volume

| Indicator | Parameters | Output | |-----------|------------|--------| | AD | none | number | | ADOSC | period_fast, period_slow | number | | KVO | period_fast?, period_slow? | number | | NVI | none | number | | OBV | none | number | | PVI | none | number | | MFI | period | number | | EMV | none | number | | MARKETFI | none | number | | VOSC | period_fast, period_slow | number | | CMF | period | number | | CHO | period_fast, period_slow | number | | PVO | period_fast, period_slow, period_signal? | {pvo, signal, histogram} | | FI | period | number | | VROC | period | number | | PVT | none | number |

Pattern Recognition Heuristics

trading-indi includes candlestick pattern recognition for identifying common chart patterns:

| Pattern | Parameters | Output | Description | |---------|------------|--------|-------------| | Doji | dojiThres? | boolean | Open and close at nearly the same price | | LongLeggedDoji | period? | boolean | Doji with very long shadows | | DragonflyDoji | lowerShadowThres?, upperShadowThres? | boolean | Doji with long lower shadow, no upper shadow | | GravestoneDoji | upperShadowThres?, lowerShadowThres? | boolean | Doji with long upper shadow, no lower shadow | | SpinningTop | period?, rangeMultiplier?, bodyThres? | boolean | Small body with long upper and lower shadows | | MarubozuWhite | period?, shadowThres? | boolean | Long white candle with minimal shadows | | MarubozuBlack | period?, shadowThres? | boolean | Long black candle with minimal shadows | | Hammer | bodyThres?, lowerShadowThres?, upperShadowThres? | boolean | Small body at top with long lower shadow | | InvertedHammer | bodyThres?, upperShadowThres?, lowerShadowThres? | boolean | Small body at bottom with long upper shadow | | HighWave | period?, rangeMultiplier?, bodyThres?, shadowThres? | boolean | Very long shadows in both directions with small body |

Example: Pattern Recognition

import { Hammer, Doji, MarubozuWhite } from '@junduck/trading-indi';

const hammer = new Hammer();
const doji = new Doji();
const marubozu = new MarubozuWhite();

websocket.on('tick', (bar) => {
  const isHammer = hammer.onData(bar);
  const isDoji = doji.onData(bar);
  const isMarubozu = marubozu.onData(bar);

  if (isHammer) console.log('Hammer pattern detected - potential reversal');
  if (isDoji) console.log('Doji pattern detected - indecision');
  if (isMarubozu) console.log('Marubozu White - strong bullish momentum');
});

Computation Primitives

Build custom calculations using composable primitive operators. These are the building blocks for creating complex trading logic in the DAG flow system.

Arithmetic Operators

| Operator | Input | Output | Description | |----------|-------|--------|-------------| | Add | lhs, rhs | number | Addition | | Sub | lhs, rhs | number | Subtraction | | Mul | lhs, rhs | number | Multiplication | | Div | lhs, rhs | number | Division (safe from divide-by-zero) | | Mod | lhs, rhs | number | Modulo | | Pow | base, exp | number | Power | | Min | lhs, rhs | number | Minimum of two values | | Max | lhs, rhs | number | Maximum of two values | | Negate | x | number | Negation | | Abs | x | number | Absolute value | | Sign | x | -1, 0, 1 | Sign of number | | Floor | x | number | Floor function | | Ceil | x | number | Ceiling function | | Round | x | number | Round to nearest integer | | Sqrt | x | number | Square root | | Log | x | number | Natural logarithm | | Exp | x | number | Exponential (e^x) | | Log1p | x | number | log(1 + x) | | Expm1 | x | number | exp(x) - 1 | | Reciprocal | x | number | 1/x | | Clamp | x, min, max | number | Clamp value between min and max | | Lerp | a, b, t | number | Linear interpolation | | InvLerp | a, b, v | number | Inverse linear interpolation | | SumOf | ...inputs | number | Sum of multiple values | | ProdOf | ...inputs | number | Product of multiple values | | AvgOf | ...inputs | number | Average of multiple values | | MinOf | ...inputs | number | Minimum of multiple values | | MaxOf | ...inputs | number | Maximum of multiple values | | RelDist | a, b | number | Relative distance: abs(a-b)/abs(b) |

Logical Operators

| Operator | Input | Output | Description | |----------|-------|--------|-------------| | LT | lhs, rhs | boolean | Less than | | GT | lhs, rhs | boolean | Greater than | | LTE | lhs, rhs | boolean | Less than or equal | | GTE | lhs, rhs | boolean | Greater than or equal | | EQ | lhs, rhs | boolean | Equal | | NEQ | lhs, rhs | boolean | Not equal | | Between | x, lo, hi | boolean | Check if x is between lo and hi | | Outside | x, lo, hi | boolean | Check if x is outside lo and hi | | And | lhs, rhs | boolean | Logical AND | | Or | lhs, rhs | boolean | Logical OR | | Not | x | boolean | Logical NOT | | Xor | lhs, rhs | boolean | Logical XOR | | AllOf | ...inputs | boolean | All inputs are true | | AnyOf | ...inputs | boolean | Any input is true | | NoneOf | ...inputs | boolean | No inputs are true | | IsNaN | x | boolean | Check if NaN | | IsFinite | x | boolean | Check if finite | | IsPositive | x | boolean | Check if positive | | IsNegative | x | boolean | Check if negative | | IsZero | x | boolean | Check if zero | | IfThenElse | cond, thenVal, elseVal | T | Conditional selection | | Gate | cond, val | T \| undefined | Pass value if condition is true | | Coalesce | ...inputs | T \| undefined | Return first non-null value |

DAG Flow System

The GraphExec and OpRegistry provide a powerful DAG (Directed Acyclic GraphExec) execution engine for building complex, composable trading strategies. Define your computation as a graph of operators with dependencies, and the system handles topological sorting and execution.

Key Features

  • Topological Execution: Automatically determines correct execution order
  • Type Safety: Zod-based schema validation
  • JSON Serialization: Save and load graphs as JSON
  • Forward References: Support for future node references
  • High Performance: Index-based adjacency lists, 2M+ ops/sec
  • AI-Friendly: Schema designed for AI agent code generation

Example: Multi-Indicator Strategy with DAG

import { GraphExec, OpRegistry } from '@junduck/trading-indi';

// Register all operators you want to use
OpRegistry.registerDefaults();

// Define your strategy as a graph
const graph = new GraphExec('trading-strategy');

// Input nodes
graph.addNode('close', 'Input', []);
graph.addNode('high', 'Input', []);
graph.addNode('low', 'Input', []);

// Calculate indicators
graph.addNode('rsi', 'RSI', ['close'], { period: 14 });
graph.addNode('ema20', 'EMA', ['close'], { period: 20 });
graph.addNode('ema50', 'EMA', ['close'], { period: 50 });

// Build trading logic with primitives
graph.addNode('rsi_oversold', 'LT', ['rsi', 30]);  // RSI < 30
graph.addNode('ema_bullish', 'GT', ['ema20', 'ema50']);  // EMA20 > EMA50
graph.addNode('buy_signal', 'And', ['rsi_oversold', 'ema_bullish']);

// Process streaming data
websocket.on('tick', (bar) => {
  graph.update('close', bar.close);
  graph.update('high', bar.high);
  graph.update('low', bar.low);

  const buySignal = graph.read('buy_signal');
  const rsi = graph.read('rsi');

  if (buySignal) {
    console.log(`BUY SIGNAL: RSI=${rsi}`);
  }
});

// Serialize to JSON for storage or AI agent generation
const schema = graph.exportSchema();
console.log(JSON.stringify(schema, null, 2));

// Load from JSON
const restoredGraph = GraphExec.fromSchema(schema);

Example: Complex Strategy with Multiple Outputs

import { GraphExec, OpRegistry } from '@junduck/trading-indi';

OpRegistry.registerDefaults();

const graph = new GraphExec('advanced-strategy');

// Inputs
graph.addNode('bar', 'Input', []);

// Multiple indicators
graph.addNode('rsi', 'RSI', ['bar'], { period: 14 });
graph.addNode('macd_result', 'MACD', ['bar'], {
  period_fast: 12,
  period_slow: 26,
  period_signal: 9
});
graph.addNode('atr', 'ATR', ['bar'], { period: 14 });

// Extract MACD components
graph.addNode('macd_line', 'GetField', ['macd_result', 'macd']);
graph.addNode('signal_line', 'GetField', ['macd_result', 'signal']);

// Build complex conditions
graph.addNode('rsi_bullish', 'Between', ['rsi', 30, 50]);
graph.addNode('macd_crossover', 'GT', ['macd_line', 'signal_line']);
graph.addNode('strong_signal', 'And', ['rsi_bullish', 'macd_crossover']);

// Calculate position sizing based on ATR
graph.addNode('atr_multiplier', 'Mul', ['atr', 2]);
graph.addNode('position_size', 'Div', [1000, 'atr_multiplier']);

// Update with streaming data
for (const bar of streamingData) {
  graph.update('bar', bar);

  const signal = graph.read('strong_signal');
  const posSize = graph.read('position_size');
  const atr = graph.read('atr');

  if (signal) {
    console.log(`Entry Signal - Position Size: ${posSize}, Stop Loss: ${atr * 2}`);
  }
}

Real-World Example: Intraday Strategy

import { RSI, ATR, EMA, BBANDS, ADX, MACD, VOLUME } from '@junduck/trading-indi';

const rsi = new RSI({ period: 14 });
const atr = new ATR({ period: 14 });
const ema20 = new EMA({ period: 20 });
const ema50 = new EMA({ period: 50 });
const bbands = new BBANDS({ period: 20, stddev: 2 });
const adx = new ADX({ period: 14 });
const macd = new MACD({ period_fast: 12, period_slow: 26, period_signal: 9 });
const obv = new OBV();

websocket.on('tick', (bar) => {
  const rsiValue = rsi.onData(bar);
  const atrValue = atr.onData(bar);
  const shortEMA = ema20.onData(bar.close);
  const longEMA = ema50.onData(bar.close);
  const { upper, middle, lower } = bbands.onData(bar.close);
  const adxValue = adx.onData(bar);
  const { macd: macdLine, signal, histogram } = macd.onData(bar);
  const obvValue = obv.onData(bar);

  // Multi-indicator strategy
  const isOversold = rsiValue < 30;
  const isBullishTrend = shortEMA > longEMA;
  const isStrongTrend = adxValue > 25;
  const isNearSupport = bar.close <= lower * 1.02; // Within 2% of lower band
  const isMACDBullish = macdLine > signal && histogram > 0;
  const isVolumeConfirming = obvValue > 0; // Positive volume flow

  if (isOversold && isBullishTrend && isStrongTrend && isNearSupport && isMACDBullish && isVolumeConfirming) {
    console.log('Strong Buy Signal - Multiple Confirmations');
    console.log(`Entry: ${bar.close}`);
    console.log(`Stop Loss: ${bar.close - (atrValue * 2)}`);
    console.log(`Target: ${bar.close + (atrValue * 3)}`);
    console.log(`RSI: ${rsiValue}, ADX: ${adxValue}, MACD: ${macdLine}`);
  }

  // Exit signal
  const isOverbought = rsiValue > 70;
  const isBearishMACD = macdLine < signal && histogram < 0;
  const isNearResistance = bar.close >= upper * 0.98; // Within 2% of upper band

  if (isOverbought || isBearishMACD || isNearResistance) {
    console.log('Exit Signal - Consider Taking Profits');
    console.log(`Current Price: ${bar.close}`);
    console.log(`RSI: ${rsiValue}, MACD: ${macdLine}, BB Position: ${(bar.close - lower) / (upper - lower)}`);
  }
});

Statistical Analysis

The library includes advanced statistical indicators for quantitative analysis:

import { Corr, Beta, ZSCORE } from '@junduck/trading-indi';

// Correlation between two assets
const correlation = new Corr({ period: 20 });
const corrValue = correlation.onData(assetPrice, benchmarkPrice);

// Beta calculation for risk analysis
const beta = new Beta({ period: 252 }); // Daily data for 1 year
const betaValue = beta.onData(stockPrice, marketIndexPrice);

// Z-Score for statistical arbitrage
const zscore = new ZSCORE({ period: 20 });
const zValue = zscore.onData(price);

API Reference

Exports

The library exports all its capabilities from the main package:

// Technical Indicators (80+)
import {
  // Foundation
  SMA, EMA, EWMA, Variance, Stddev, Min, Max, Sum, MinMax,

  // Statistics
  VarianceEW, Cov, Corr, Beta, ZSCORE, CORRELATION,

  // Volatility
  VOLATILITY, CVI, MASS, TR, ATR, NATR, PriceChannel, BBANDS, KC, DC,

  // Momentum
  BOP, MOM, ROC, ROCR, RSI, CMO, WAD, RVI, TSI, BBPOWER,

  // Oscillators
  AO, APO, DPO, Fisher, MACD, PPO, QSTICK, TRIX, ULTOSC,

  // Stochastic
  STOCH, STOCHRSI, WILLR,

  // Trend
  AROON, AROONOSC, CCI, VHF, DM, DI, DX, ADX, ADXR, SAR, VI, ICHIMOKU,

  // Volume
  AD, ADOSC, KVO, NVI, OBV, PVI, MFI, EMV, MarketFI, VOSC, CMF, CHO, PVO, FI, VROC, PVT
} from '@junduck/trading-indi';

// Pattern Recognition
import {
  Doji, LongLeggedDoji, DragonflyDoji, GravestoneDoji,
  SpinningTop, MarubozuWhite, MarubozuBlack,
  Hammer, InvertedHammer, HighWave
} from '@junduck/trading-indi';

// Computation Primitives
import {
  // Arithmetic
  Add, Sub, Mul, Div, Mod, Pow, Min, Max,
  Negate, Abs, Sign, Floor, Ceil, Round, Sqrt, Log, Exp,
  Log1p, Expm1, Reciprocal, Clamp, Lerp, InvLerp,
  SumOf, ProdOf, AvgOf, MinOf, MaxOf, RelDist,

  // Logical
  LT, GT, LTE, GTE, EQ, NEQ, Between, Outside,
  And, Or, Not, Xor, AllOf, AnyOf, NoneOf,
  IsNaN, IsFinite, IsPositive, IsNegative, IsZero,
  IfThenElse, Gate, Coalesce
} from '@junduck/trading-indi';

// DAG Flow System
import {
  GraphExec, OpRegistry,
  validateGraphSchema, formatValidationError, graphComplexity, graphDiff
} from '@junduck/trading-indi';

// Types
import type {
  NodeSchema, GraphSchema, GraphSchemaValidationResult, GraphError, GraphDiff,
  BarData, BarWith, PeriodOptions
} from '@junduck/trading-indi';

Hook Pattern

Every class-based operator has a corresponding functional hook:

import { useRSI, useSMA, useHammer } from '@junduck/trading-indi';

const getRSI = useRSI({ period: 14 });
const getSMA = useSMA({ period: 20 });
const isHammer = useHammer();

for (const bar of data) {
  const rsi = getRSI(bar);
  const sma = getSMA(bar.close);
  const hammer = isHammer(bar);
}

Bar Data Types

Most indicators accept BarData with these properties:

interface BarData {
  open?: number;
  high?: number;
  low?: number;
  close: number;
  volume?: number;
}

Each indicator only requires the fields it needs. Check TypeScript types for specific requirements.

Use Cases

1. Realtime Trading Bot

import { RSI, MACD, ATR, Hammer } from '@junduck/trading-indi';

const rsi = new RSI({ period: 14 });
const macd = new MACD({ period_fast: 12, period_slow: 26, period_signal: 9 });
const atr = new ATR({ period: 14 });
const hammer = new Hammer();

websocket.on('message', (bar) => {
  const rsiValue = rsi.onData(bar);
  const macdData = macd.onData(bar);
  const atrValue = atr.onData(bar);
  const isHammer = hammer.onData(bar);

  if (rsiValue < 30 && macdData.histogram > 0 && isHammer) {
    placeOrder({
      type: 'BUY',
      stopLoss: bar.close - (atr * 2),
      takeProfit: bar.close + (atr * 3)
    });
  }
});

2. Backtesting Engine

import { useSMA, useEMA, useRSI } from '@junduck/trading-indi';

const getSMA = useSMA({ period: 50 });
const getEMA = useEMA({ period: 20 });
const getRSI = useRSI({ period: 14 });

const results = historicalData.map(bar => ({
  timestamp: bar.timestamp,
  close: bar.close,
  sma50: getSMA(bar.close),
  ema20: getEMA(bar.close),
  rsi: getRSI(bar)
}));

3. Custom Indicator with DAG

import { GraphExec, OpRegistry } from '@junduck/trading-indi';

OpRegistry.registerDefaults();

// Build a custom "Trend Strength" indicator
const graph = new GraphExec('trend-strength');

graph.addNode('close', 'Input', []);
graph.addNode('ema20', 'EMA', ['close'], { period: 20 });
graph.addNode('ema50', 'EMA', ['close'], { period: 50 });
graph.addNode('rsi', 'RSI', ['close'], { period: 14 });
graph.addNode('adx', 'ADX', ['bar'], { period: 14 });

// Calculate trend strength: (EMA20 - EMA50) * RSI/100 * ADX/100
graph.addNode('ema_diff', 'Sub', ['ema20', 'ema50']);
graph.addNode('rsi_norm', 'Div', ['rsi', 100]);
graph.addNode('adx_norm', 'Div', ['adx', 100]);
graph.addNode('strength', 'Mul', ['ema_diff', 'rsi_norm']);
graph.addNode('trend_strength', 'Mul', ['strength', 'adx_norm']);

// Use it
for (const bar of data) {
  graph.update('close', bar.close);
  graph.update('bar', bar);

  const trendStrength = graph.read('trend_strength');
  console.log(`Trend Strength: ${trendStrength}`);
}

4. Multi-Asset Correlation Analysis

import { Corr, Beta } from '@junduck/trading-indi';

const correlation = new Corr({ period: 20 });
const beta = new Beta({ period: 252 });

for (let i = 0; i < assetPrices.length; i++) {
  const corr = correlation.onData(assetPrices[i], benchmarkPrices[i]);
  const betaValue = beta.onData(assetPrices[i], benchmarkPrices[i]);

  console.log(`Correlation: ${corr.correlation}, Beta: ${betaValue.beta}`);
}

Summary

trading-indi provides a complete framework for building incremental trading algorithms:

| Category | Count | Highlights | |----------|-------|------------| | Technical Indicators | 80+ | SMA, EMA, RSI, MACD, ATR, BBANDS, ADX, Ichimoku, and more | | Pattern Recognition | 10+ | Doji, Hammer, Marubozu, Spinning Top, High Wave | | Arithmetic Primitives | 28 | Add, Sub, Mul, Div, Pow, Sqrt, Log, Clamp, Lerp, SumOf, AvgOf, etc. | | Logical Primitives | 23 | LT, GT, EQ, And, Or, Not, Between, IfThenElse, AllOf, AnyOf, etc. | | Flow System | 1 DAG engine | GraphExec, OpRegistry, Schema validation, JSON serialization |

Key Features

  • Incremental Calculation: All operators maintain state and update efficiently
  • High Performance: 2M+ operations/sec, suitable for tick data
  • Memory Efficient: Sliding windows and online algorithms
  • Type Safe: Full TypeScript support with strict typing
  • Composable: Build complex strategies from simple building blocks
  • AI-Friendly: OperatorDoc schema for AI agent code generation
  • Zero Dependencies: Clean, modern TypeScript

Getting Started

  1. Simple indicator: Use class-based or hook pattern for individual indicators
  2. Pattern recognition: Detect candlestick patterns in realtime
  3. Custom calculations: Combine primitives for custom logic
  4. Complex strategies: Use DAG flow system to compose multi-indicator strategies
  5. Serialization: Save/load strategies as JSON for portability

Changelog

See CHANGELOG.md for a detailed history of changes.

License

MIT