npm package: @junduck/trading-indi
Description: A TypeScript library providing 80+ technical indicators for trading, designed for incremental, stateful calculation perfect for intraday and realtime trading applications
Author: Jun
Latest version: 0.999.0

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

```bash
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

```text
┌─────────────────────────────────────────────────────┐
│                   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)

```typescript
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)

```typescript
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

```typescript
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

```typescript
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

```typescript
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

```typescript
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:

```typescript
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:

```typescript
// 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:

```typescript
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:

```typescript
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

```typescript
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

```typescript
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

```typescript
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

```typescript
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](CHANGELOG.md) for a detailed history of changes.

## License

MIT