
Research
/Security News
Mini Shai-Hulud Campaign Hits Red Hat Cloud Services npm Packages
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.
@junduck/trading-indi
Advanced tools
A TypeScript library providing 80+ technical indicators for trading, designed for incremental, stateful calculation perfect for intraday and realtime trading applications
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.
Traditional technical indicator libraries recalculate entire datasets on each new data point. trading-indi is a complete framework for building sophisticated trading algorithms:
trading-indi is built for speed and efficiency, making it ideal for real-time trading applications:
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.
Install the package from npm:
npm install @junduck/trading-indi
# or
yarn add @junduck/trading-indi
# or
pnpm add @junduck/trading-indi
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 |
┌─────────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────────┘
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 });
});
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);
}
| 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} |
| 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 |
| 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} |
| 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} |
| 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 |
| Indicator | Parameters | Output |
|---|---|---|
| STOCH | k_period?, k_slowing?, d_period? | {k, d} |
| STOCHRSI | period | number |
| WILLR | period | number |
| 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} |
| 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 |
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 |
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');
});
Build custom calculations using composable primitive operators. These are the building blocks for creating complex trading logic in the DAG flow system.
| 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) |
| 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 |
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.
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);
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}`);
}
}
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)}`);
}
});
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);
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';
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);
}
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.
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)
});
}
});
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)
}));
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}`);
}
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}`);
}
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 |
See CHANGELOG.md for a detailed history of changes.
MIT
FAQs
A TypeScript library providing 80+ technical indicators for trading, designed for incremental, stateful calculation perfect for intraday and realtime trading applications
We found that @junduck/trading-indi demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.

Research
/Security News
The North Korean malware loader hides in a Packagist-listed package and its GitHub branch to fetch and execute remote code in a likely Contagious Interview-style lure.

Security News
The Rust project is moving toward formal rules on LLM use in contributions after months of internal debate over maintainer burden, code quality, and contributor experience.