UNPKG

@thoshpathi/utils-smartapi

Version:

Extended utilities for Angel One's smartapi-javascript SDK, including custom methods and helpers for market data like candles, P&L, and more.

102 lines (100 loc) 3.13 kB
// src/ta_lib.ts function round4Decimal(n) { return Math.round(n * 1e4) / 1e4; } function arrayAverage(numArray) { const sum = numArray.reduce((pv, cv) => pv + cv, 0); const avg = sum / numArray.length; return round4Decimal(avg); } function smaSeries(prices, period = 14) { if (prices.length < period) return []; else if (period === 1) return prices; const sma = []; for (let i = period; i <= prices.length; i++) { const slice = prices.slice(i - period, i); sma.push(arrayAverage(slice)); } return sma; } function emaSeries(prices, period = 9) { if (prices.length < period) return []; else if (period === 1) return prices; const k = 2 / (period + 1); let prevEMA = arrayAverage(prices.slice(0, period)); const ema = [prevEMA]; for (let i = period; i < prices.length; i++) { prevEMA = (prices[i] - prevEMA) * k + prevEMA; ema.push(prevEMA); } return ema; } function emaCrossoverTrends(ohlcsArray, shortLength = 9, longLength = 20) { if (shortLength > longLength) [shortLength, longLength] = [longLength, shortLength]; if (!ohlcsArray || ohlcsArray.length < longLength) return []; const prices = ohlcsArray.map((v) => v.close); const longEmaSeries = emaSeries(prices, longLength); const loopLength = longEmaSeries.length; const shortEmaSeries = emaSeries(prices, shortLength).slice(-loopLength); ohlcsArray = ohlcsArray.slice(-loopLength); const signals = []; for (let i = 0; i < loopLength; i++) { const prevShort = shortEmaSeries[i - 1]; const prevLong = longEmaSeries[i - 1]; const currentShort = shortEmaSeries[i]; const currentLong = longEmaSeries[i]; const ohlc = ohlcsArray[i]; if (prevShort < prevLong && currentShort > currentLong) { signals.push({ date: ohlc.date, trend: "BUY", close: ohlc.close }); } else if (prevShort > prevLong && currentShort < currentLong) { signals.push({ date: ohlc.date, trend: "SELL", close: ohlc.close }); } } return signals; } function trSeries(ohlcArr, includeFirst = true) { if (ohlcArr.length === 0) return []; const trArr = []; if (includeFirst) { const { high, low } = ohlcArr[0]; trArr.push(high - low); } for (let i = 1; i < ohlcArr.length; i++) { const { high, low } = ohlcArr[i]; const { close: prevClose } = ohlcArr[i - 1]; trArr.push( Math.max( high - low, Math.abs(high - prevClose), Math.abs(low - prevClose) ) ); } return trArr; } function rmaSeries(prices, period = 15) { if (prices.length < period) return []; else if (period === 1) return prices; const k = 1 / period; let prevRMA = arrayAverage(prices.slice(0, period)); const rma = [prevRMA]; for (let i = period; i < prices.length; i++) { prevRMA = (prices[i] - prevRMA) * k + prevRMA; rma.push(prevRMA); } return rma; } function atrSeries(ohlcArr, period) { if (ohlcArr.length < period) return []; const trArr = trSeries(ohlcArr, true); return period === 1 ? trArr : rmaSeries(trArr, period); } export { smaSeries, emaSeries, emaCrossoverTrends, trSeries, rmaSeries, atrSeries };