Optimized technical indicators built with OakScriptJS for use with lightweight-charts
npm install lightweight-charts-indicators70+ technical analysis indicators for TradingView's lightweight-charts library. PineScript v6 compatible and validated against TradingView's built-in indicators.
``bash`
npm install lightweight-charts-indicators oakscriptjs lightweight-charts
`typescript
import { SMA, RSI, MACD, BollingerBands } from 'lightweight-charts-indicators';
import type { Bar } from 'oakscriptjs';
const bars: Bar[] = [
{ time: 1, open: 100, high: 105, low: 95, close: 102, volume: 1000 },
// ... more bars
];
// Simple Moving Average
const smaResult = SMA.calculate(bars, { len: 14 });
// RSI
const rsiResult = RSI.calculate(bars, { length: 14 });
// MACD
const macdResult = MACD.calculate(bars, { fastLength: 12, slowLength: 26, signalLength: 9 });
// Bollinger Bands
const bbResult = BollingerBands.calculate(bars, { length: 20, mult: 2 });
`
Here's a complete example showing how to integrate indicators with TradingView's lightweight-charts:
`typescript
import { createChart, ColorType, LineSeries, CandlestickSeries } from 'lightweight-charts';
import { SMA, RSI, BollingerBands } from 'lightweight-charts-indicators';
import type { Bar } from 'oakscriptjs';
// Sample OHLCV data
const bars: Bar[] = [
{ time: 1609459200, open: 100, high: 105, low: 98, close: 103, volume: 1000 },
{ time: 1609545600, open: 103, high: 108, low: 101, close: 107, volume: 1200 },
{ time: 1609632000, open: 107, high: 110, low: 104, close: 105, volume: 900 },
// ... more bars
];
// Create the main chart
const chartContainer = document.getElementById('chart')!;
const chart = createChart(chartContainer, {
layout: {
background: { type: ColorType.Solid, color: '#1e1e1e' },
textColor: '#d1d4dc',
},
width: 800,
height: 400,
});
// Add candlestick series
const candlestickSeries = chart.addSeries(CandlestickSeries);
candlestickSeries.setData(bars.map(bar => ({
time: bar.time as number,
open: bar.open,
high: bar.high,
low: bar.low,
close: bar.close,
})));
// Calculate and add SMA overlay
const smaResult = SMA.calculate(bars, { len: 20, src: 'close' });
const smaSeries = chart.addSeries(LineSeries, { color: '#2962FF', lineWidth: 2 });
smaSeries.setData(smaResult.plots.plot0);
// Calculate and add Bollinger Bands
const bbResult = BollingerBands.calculate(bars, { length: 20, mult: 2 });
const bbUpperSeries = chart.addSeries(LineSeries, { color: '#787B86', lineWidth: 1 });
const bbMiddleSeries = chart.addSeries(LineSeries, { color: '#FF6D00', lineWidth: 1 });
const bbLowerSeries = chart.addSeries(LineSeries, { color: '#787B86', lineWidth: 1 });
bbUpperSeries.setData(bbResult.plots.plot0); // Upper band
bbMiddleSeries.setData(bbResult.plots.plot1); // Basis (middle)
bbLowerSeries.setData(bbResult.plots.plot2); // Lower band
// Create a separate pane for RSI (oscillator)
const rsiContainer = document.getElementById('rsi-chart')!;
const rsiChart = createChart(rsiContainer, {
layout: {
background: { type: ColorType.Solid, color: '#1e1e1e' },
textColor: '#d1d4dc',
},
width: 800,
height: 150,
});
const rsiResult = RSI.calculate(bars, { length: 14, src: 'close' });
const rsiSeries = rsiChart.addSeries(LineSeries, { color: '#7E57C2', lineWidth: 2 });
rsiSeries.setData(rsiResult.plots.plot0);
// Sync the time scales
chart.timeScale().subscribeVisibleLogicalRangeChange(range => {
if (range) rsiChart.timeScale().setVisibleLogicalRange(range);
});
`
| Indicator | Export | Description |
|-----------|--------|-------------|
| Simple Moving Average | SMA | Arithmetic mean over a specified period |EMA
| Exponential Moving Average | | Weighted average giving more weight to recent prices |WMA
| Weighted Moving Average | | Linearly increasing weights |RMA
| Smoothed Moving Average (RMA) | | Wilder smoothing (alpha = 1/length) |DEMA
| Double EMA | | Reduces lag by applying EMA twice |TEMA
| Triple EMA | | Further reduces lag with triple exponential smoothing |HMA
| Hull Moving Average | | Reduces lag while maintaining smoothness |LSMA
| Least Squares Moving Average | | Uses linear regression to fit a line |ALMA
| Arnaud Legoux Moving Average | | Gaussian distribution to reduce lag |VWMA
| Volume Weighted Moving Average | | Moving average weighted by volume |SMMA
| Smoothed Moving Average | | Wilder smoothing moving average |McGinleyDynamic
| McGinley Dynamic | | Adaptive moving average that adjusts to market speed |MACross
| MA Cross | | Two moving averages for crossover signals |MARibbon
| Moving Average Ribbon | | Multiple MAs showing trend direction and momentum |
| Indicator | Export | Description |
|-----------|--------|-------------|
| Relative Strength Index | RSI | Momentum oscillator (0-100) measuring price changes |Stochastic
| Stochastic | | Compares closing price to price range |StochRSI
| Stochastic RSI | | Stochastic applied to RSI values |CCI
| Commodity Channel Index | | Measures variation from statistical mean |WilliamsPercentRange
| Williams %R | | Momentum showing overbought/oversold levels |AwesomeOscillator
| Awesome Oscillator | | Market momentum using SMA difference |ChandeMO
| Chande Momentum Oscillator | | Momentum on a scale of -100 to +100 |DPO
| Detrended Price Oscillator | | Removes trend to identify cycles |RVI
| Relative Vigor Index | | Measures conviction of price action |SMIErgodic
| SMI Ergodic Indicator | | TSI-based momentum with signal line |SMIErgodicOscillator
| SMI Ergodic Oscillator | | SMI minus signal as histogram |TSI
| True Strength Index | | Double-smoothed momentum oscillator |WoodiesCCI
| Woodies CCI | | CCI with turbo for faster signals |BBPercentB
| Bollinger Bands %B | | Price position relative to BB (0=lower, 1=upper) |FisherTransform
| Fisher Transform | | Gaussian distribution for clearer turning points |UltimateOscillator
| Ultimate Oscillator | | Multi-timeframe weighted momentum |
| Indicator | Export | Description |
|-----------|--------|-------------|
| MACD | MACD | Relationship between two EMAs |Momentum
| Momentum | | Rate of change of price |ROC
| Rate of Change | | Percentage change over a period |BOP
| Balance of Power | | Strength of buyers vs sellers |BullBearPower
| Bull Bear Power | | Buying/selling pressure relative to EMA |ElderForceIndex
| Elder Force Index | | Combines price and volume |PriceOscillator
| Price Oscillator (PPO) | | MACD as percentage for comparison |CoppockCurve
| Coppock Curve | | Long-term momentum using ROC and WMA |TRIX
| TRIX | | Triple EMA rate of change, filters noise |
| Indicator | Export | Description |
|-----------|--------|-------------|
| Average Directional Index | ADX | Measures trend strength regardless of direction |DMI
| Directional Movement Index | | +DI, -DI, and ADX for trend direction/strength |IchimokuCloud
| Ichimoku Cloud | | Comprehensive trend system with support/resistance |ParabolicSAR
| Parabolic SAR | | Trend-following with entry/exit points |Supertrend
| Supertrend | | ATR-based dynamic support/resistance |Aroon
| Aroon | | Trend strength by time since high/low |BBTrend
| BBTrend | | Measures trend using Bollinger Bands |Choppiness
| Choppiness Index | | Market choppiness vs trending |MassIndex
| Mass Index | | Identifies reversals via high-low range |VortexIndicator
| Vortex Indicator | | Identifies trend start and direction |WilliamsAlligator
| Williams Alligator | | Three smoothed MAs for trend detection |ZigZag
| Zig Zag | | Connects pivot highs and lows |TrendStrengthIndex
| Trend Strength Index | | Trend strength based on directional movement |ChandeKrollStop
| Chande Kroll Stop | | ATR-based trailing stop system |
| Indicator | Export | Description |
|-----------|--------|-------------|
| Average True Range | ATR | Average range between high and low |ADR
| Average Day Range | | Average daily price range |StandardDeviation
| Standard Deviation | | Measures price volatility |HistoricalVolatility
| Historical Volatility | | Annualized standard deviation of log returns |BBBandWidth
| Bollinger BandWidth | | Width of Bollinger Bands as percentage |
| Indicator | Export | Description |
|-----------|--------|-------------|
| Bollinger Bands | BollingerBands | Volatility bands using standard deviation |KeltnerChannels
| Keltner Channels | | Volatility envelope using EMA and ATR |DonchianChannels
| Donchian Channels | | Highest high and lowest low over period |Envelope
| Envelope | | Moving average with fixed percentage bands |Median
| Median | | Median price with ATR bands |
| Indicator | Export | Description |
|-----------|--------|-------------|
| On Balance Volume | OBV | Cumulative volume based on price direction |MFI
| Money Flow Index | | Volume-weighted RSI |PVT
| Price Volume Trend | | Cumulative volume weighted by price changes |VolumeOscillator
| Volume Oscillator | | Percentage difference between volume EMAs |ChaikinMF
| Chaikin Money Flow | | Buying/selling pressure using price and volume |ChaikinOscillator
| Chaikin Oscillator | | Momentum of Accumulation/Distribution line |EaseOfMovement
| Ease of Movement | | Price change relative to volume |KlingerOscillator
| Klinger Oscillator | | Volume-based long-term money flow |
All indicators return an IndicatorResult object:
`typescript`
interface IndicatorResult {
metadata: {
title: string;
shortTitle: string;
overlay: boolean; // true = display on price chart, false = separate pane
};
plots: {
plot0: Array<{ time: number; value: number }>;
plot1?: Array<{ time: number; value: number }>;
// ... additional plots as needed
};
}
For dynamic indicator selection (e.g., building a UI), use the indicatorRegistry:
`typescript
import { indicatorRegistry } from 'lightweight-charts-indicators';
// List all indicators
indicatorRegistry.forEach(indicator => {
console.log(${indicator.name} (${indicator.category}));
});
// Get indicator by ID
const sma = indicatorRegistry.find(i => i.id === 'sma');
const result = sma?.calculate(bars, sma.defaultInputs);
// Filter by category
const oscillators = indicatorRegistry.filter(i => i.category === 'Oscillators');
`
`bash`
npm run build
`bash``
npm test
MIT