@vulcan-js/indicators 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/trend/exponentialMovingAverage.ts","../src/momentum/absolutePriceOscillator.ts","../src/trend/simpleMovingAverage.ts","../src/momentum/awesomeOscillator.ts","../src/volume/accumulationDistribution.ts","../src/momentum/chaikinOscillator.ts","../src/momentum/commodityChannelIndex.ts","../src/momentum/percentagePriceOscillator.ts","../src/momentum/percentageVolumeOscillator.ts","../src/momentum/priceRateOfChange.ts","../src/trend/movingMax.ts","../src/trend/movingMin.ts","../src/momentum/randomIndex.ts","../src/trend/rollingMovingAverage.ts","../src/momentum/relativeStrengthIndex.ts","../src/momentum/stochasticOscillator.ts","../src/momentum/williamsR.ts","../src/trend/aroon.ts","../src/trend/balanceOfPower.ts","../src/trend/chandeForecastOscillator.ts","../src/trend/doubleExponentialMovingAverage.ts","../src/trend/ichimokuCloud.ts","../src/trend/macd.ts","../src/trend/movingSum.ts","../src/trend/parabolicSar.ts","../src/trend/qstick.ts","../src/trend/sinceChange.ts","../src/trend/triangularMovingAverage.ts","../src/trend/tripleExponentialAverage.ts","../src/trend/tripleExponentialMovingAverage.ts","../src/trend/typicalPrice.ts","../src/trend/volumeWeightedMovingAverage.ts","../src/trend/vortex.ts","../src/volatility/massIndex.ts"],"sourcesContent":["import type { Dnum, Numberish } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, divide, mul, subtract } from 'dnum'\n\nexport interface ExponentialMovingAverageOptions {\n period: number\n}\n\nexport const defaultExponentialMovingAverageOptions: ExponentialMovingAverageOptions = {\n period: 12,\n}\n\n/**\n * Exponential Moving Average (EMA)\n *\n * EMA = Price * k + PrevEMA * (1 - k)\n * Where k = 2 / (period + 1)\n */\nexport const ema = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const k = divide(constants.TWO, toDnum(1 + period), constants.DECIMALS)\n const m = subtract(constants.ONE, k)\n let prev: Dnum | undefined\n return (value: Numberish) => {\n if (prev === undefined) {\n prev = toDnum(value)\n return prev\n }\n prev = add(\n mul(value, k, constants.DECIMALS),\n mul(prev, m, constants.DECIMALS),\n )\n return prev\n }\n },\n defaultExponentialMovingAverageOptions,\n)\n\nexport { ema as exponentialMovingAverage }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal } from '@vulcan-js/core'\nimport { sub } from 'dnum'\nimport { ema } from '../trend/exponentialMovingAverage'\n\nexport interface AbsolutePriceOscillatorOptions {\n fastPeriod: number\n slowPeriod: number\n}\n\nexport const defaultAbsolutePriceOscillatorOptions: AbsolutePriceOscillatorOptions = {\n fastPeriod: 12,\n slowPeriod: 26,\n}\n\nexport const apo = createSignal(\n ({ fastPeriod, slowPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n const fastProc = ema.create({ period: fastPeriod })\n const slowProc = ema.create({ period: slowPeriod })\n return (value: Numberish) => sub(fastProc(value), slowProc(value))\n },\n defaultAbsolutePriceOscillatorOptions,\n)\n\nexport { apo as absolutePriceOscillator }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, div, subtract } from 'dnum'\n\nexport interface SimpleMovingAverageOptions {\n /**\n * The period for calculating the moving average\n * @default 2\n */\n period: number\n}\n\nexport const defaultSMAOptions: SimpleMovingAverageOptions = {\n period: 2,\n}\n\n/**\n * Simple Moving Average (SMA)\n *\n * Calculates the arithmetic mean of a set of values over a specified period.\n * The SMA is calculated by summing all values in the period and dividing by the period length.\n *\n * Formula: SMA = (P1 + P2 + ... + Pn) / n\n * Where: P = Price values, n = Period\n *\n * @param source - Iterable of price values\n * @param options - Configuration options\n * @param options.period - The period for calculating the moving average (default: 2)\n * @returns Generator yielding SMA values\n */\nexport const sma = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: Dnum[] = Array.from({ length: period })\n let head = 0\n let count = 0\n let runningSum: Dnum = constants.ZERO\n\n return (value: Numberish) => {\n const v = toDnum(value)\n if (count < period) {\n buffer[count] = v\n runningSum = add(runningSum, v)\n count++\n }\n else {\n runningSum = subtract(runningSum, buffer[head])\n runningSum = add(runningSum, v)\n buffer[head] = v\n head = (head + 1) % period\n }\n return div(runningSum, count, constants.DECIMALS)\n }\n },\n defaultSMAOptions,\n)\n\nexport { sma as simpleMovingAverage }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, div, sub } from 'dnum'\nimport { sma } from '../trend/simpleMovingAverage'\n\nexport interface AwesomeOscillatorOptions {\n fastPeriod: number\n slowPeriod: number\n}\n\nexport const defaultAwesomeOscillatorOptions: AwesomeOscillatorOptions = {\n fastPeriod: 5,\n slowPeriod: 34,\n}\n\n/**\n * Awesome Oscillator (AO)\n *\n * AO = SMA(median, fastPeriod) - SMA(median, slowPeriod)\n * Where median = (high + low) / 2\n */\nexport const ao = createSignal(\n ({ fastPeriod, slowPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n const fastProc = sma.create({ period: fastPeriod })\n const slowProc = sma.create({ period: slowPeriod })\n return (bar: RequiredProperties<CandleData, 'h' | 'l'>) => {\n const median = div(add(toDnum(bar.h), toDnum(bar.l)), 2, constants.DECIMALS)\n return sub(fastProc(median), slowProc(median))\n }\n },\n defaultAwesomeOscillatorOptions,\n)\n\nexport { ao as awesomeOscillator }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, divide, equal, multiply, subtract } from 'dnum'\n\n/**\n * Accumulation/Distribution Indicator (A/D). Cumulative indicator\n * that uses volume and price to assess whether a stock is\n * being accumulated or distributed.\n *\n * MFM = ((Closing - Low) - (High - Closing)) / (High - Low)\n * MFV = MFM * Period Volume\n * AD = Previous AD + CMFV\n */\nexport const ad = createSignal(\n () => {\n let prevAD: Dnum = constants.ZERO\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c' | 'v'>) => {\n const h = toDnum(bar.h)\n const l = toDnum(bar.l)\n const c = toDnum(bar.c)\n const v = toDnum(bar.v)\n\n const range = subtract(h, l)\n // When high equals low, the range is zero and MFM is undefined; treat as 0\n const mfm = equal(range, 0)\n ? constants.ZERO\n : divide(\n subtract(subtract(c, l), subtract(h, c)),\n range,\n constants.DECIMALS,\n )\n const mfv = multiply(mfm, v)\n prevAD = add(mfv, prevAD)\n return prevAD\n }\n },\n)\n\nexport { ad as accumulationDistribution }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { assert, createSignal } from '@vulcan-js/core'\nimport { sub } from 'dnum'\nimport { ema } from '../trend/exponentialMovingAverage'\nimport { ad } from '../volume/accumulationDistribution'\n\nexport interface ChaikinOscillatorOptions {\n fastPeriod: number\n slowPeriod: number\n}\n\nexport const defaultChaikinOscillatorOptions: ChaikinOscillatorOptions = {\n fastPeriod: 3,\n slowPeriod: 10,\n}\n\n/**\n * The ChaikinOscillator function measures the momentum of the\n * Accumulation/Distribution (A/D) using the Moving Average\n * Convergence Divergence (MACD) formula. It takes the\n * difference between fast and slow periods EMA of the A/D.\n * Cross above the A/D line indicates bullish.\n *\n * CO = Ema(fastPeriod, AD) - Ema(slowPeriod, AD)\n */\nexport const cmo = createSignal(\n ({ fastPeriod, slowPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n const adProc = ad.create()\n const fastProc = ema.create({ period: fastPeriod })\n const slowProc = ema.create({ period: slowPeriod })\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c' | 'v'>) => {\n const adVal = adProc(bar)\n return sub(fastProc(adVal), slowProc(adVal))\n }\n },\n defaultChaikinOscillatorOptions,\n)\n\nexport { cmo as chaikinOscillator }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { abs, add, divide, equal, subtract } from 'dnum'\n\nexport interface CommodityChannelIndexOptions {\n /**\n * The period for CCI calculation\n * @default 20\n */\n period: number\n}\n\nexport const defaultCCIOptions: CommodityChannelIndexOptions = {\n period: 20,\n}\n\n/**\n * Commodity Channel Index (CCI)\n *\n * Developed by Donald Lambert in 1980, CCI measures the deviation of the\n * typical price from its simple moving average, normalized by mean deviation.\n * The constant 0.015 ensures approximately 70-80% of CCI values fall between\n * +100 and -100.\n *\n * Formula:\n * TP = (High + Low + Close) / 3\n * CCI = (TP - SMA(TP, period)) / (0.015 * Mean Deviation)\n * Mean Deviation = SUM(|TP_i - SMA|) / period\n *\n * @param source - Iterable of OHLC candle data\n * @param options - Configuration options\n * @param options.period - The period for CCI calculation (default: 20)\n * @returns Generator yielding CCI values\n */\nexport const cci = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: Dnum[] = []\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = toDnum(bar.h)\n const l = toDnum(bar.l)\n const c = toDnum(bar.c)\n const tp = divide(add(add(h, l), c), 3, constants.DECIMALS)\n\n buffer.push(tp)\n if (buffer.length > period)\n buffer.shift()\n\n const n = buffer.length\n if (n < period) {\n return constants.ZERO\n }\n\n // SMA and Mean Deviation in a single pass\n let sum: Dnum = constants.ZERO\n for (const v of buffer) {\n sum = add(sum, v)\n }\n const smaVal = divide(sum, n, constants.DECIMALS)\n\n let devSum: Dnum = constants.ZERO\n for (const v of buffer) {\n devSum = add(devSum, abs(subtract(v, smaVal)))\n }\n const meanDev = divide(devSum, n, constants.DECIMALS)\n\n if (equal(meanDev, 0)) {\n return constants.ZERO\n }\n\n const currentTP = buffer[n - 1]\n const numerator = subtract(currentTP, smaVal)\n // 0.015 = 15/1000, the Lambert constant\n const lambertMeanDev = divide(\n [meanDev[0] * 15n, meanDev[1]],\n [1000n, 0],\n constants.DECIMALS,\n )\n return divide(numerator, lambertMeanDev, constants.DECIMALS)\n }\n },\n defaultCCIOptions,\n)\n\nexport { cci as commodityChannelIndex }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { div, eq, mul, sub } from 'dnum'\nimport { ema } from '../trend/exponentialMovingAverage'\n\nexport interface PercentagePriceOscillatorOptions {\n fastPeriod: number\n slowPeriod: number\n signalPeriod: number\n}\n\nexport const defaultPercentagePriceOscillatorOptions: PercentagePriceOscillatorOptions = {\n fastPeriod: 12,\n slowPeriod: 26,\n signalPeriod: 9,\n}\n\nexport interface PercentagePriceOscillatorPoint {\n ppo: Dnum\n signal: Dnum\n histogram: Dnum\n}\n\n/**\n * Percentage Price Oscillator (PPO)\n *\n * The Percentage Price Oscillator (PPO) is a momentum oscillator that measures the difference\n * between two moving averages as a percentage of the slower moving average. It consists of three components:\n * - PPO Line: ((Fast EMA - Slow EMA) / Slow EMA) * 100\n * - Signal Line: EMA of the PPO line\n * - Histogram: PPO - Signal\n *\n * Formula:\n * - PPO = ((EMA(fastPeriod, prices) - EMA(slowPeriod, prices)) / EMA(slowPeriod, prices)) * 100\n * - Signal = EMA(signalPeriod, PPO)\n * - Histogram = PPO - Signal\n *\n * @param source - Iterable of price values\n * @param options - Configuration options\n * @param options.fastPeriod - Period for the fast EMA (default: 12)\n * @param options.slowPeriod - Period for the slow EMA (default: 26)\n * @param options.signalPeriod - Period for the signal EMA (default: 9)\n * @returns Generator yielding PPO point objects\n */\nexport const ppo = createSignal(\n ({ fastPeriod, slowPeriod, signalPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n assert(Number.isInteger(signalPeriod) && signalPeriod >= 1, new RangeError(`Expected signalPeriod to be a positive integer, got ${signalPeriod}`))\n const fastProc = ema.create({ period: fastPeriod })\n const slowProc = ema.create({ period: slowPeriod })\n const signalProc = ema.create({ period: signalPeriod })\n return (value: Numberish) => {\n const fast = fastProc(toDnum(value))\n const slow = slowProc(toDnum(value))\n const ppoVal = eq(slow, 0) ? constants.ZERO : mul(div(sub(fast, slow), slow, constants.DECIMALS), 100, constants.DECIMALS)\n const sig = signalProc(ppoVal)\n return { ppo: ppoVal, signal: sig, histogram: sub(ppoVal, sig) }\n }\n },\n defaultPercentagePriceOscillatorOptions,\n)\n\nexport { ppo as percentagePriceOscillator }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { div, eq, mul, sub } from 'dnum'\nimport { ema } from '../trend/exponentialMovingAverage'\n\nexport interface PercentageVolumeOscillatorOptions {\n fastPeriod: number\n slowPeriod: number\n signalPeriod: number\n}\n\nexport const defaultPercentageVolumeOscillatorOptions: PercentageVolumeOscillatorOptions = {\n fastPeriod: 12,\n slowPeriod: 26,\n signalPeriod: 9,\n}\n\nexport interface PercentageVolumeOscillatorPoint {\n pvo: Dnum\n signal: Dnum\n histogram: Dnum\n}\n\n/**\n * Percentage Volume Oscillator (PVO)\n *\n * The Percentage Volume Oscillator (PVO) is a momentum oscillator that measures the difference\n * between two volume-based moving averages as a percentage of the slower moving average.\n * It consists of three components:\n * - PVO Line: ((Fast EMA - Slow EMA) / Slow EMA) * 100\n * - Signal Line: EMA of the PVO line\n * - Histogram: PVO - Signal\n *\n * The PVO is essentially the same as the Percentage Price Oscillator (PPO), but applied\n * to volume data instead of price data.\n *\n * Formula:\n * - PVO = ((EMA(fastPeriod, volume) - EMA(slowPeriod, volume)) / EMA(slowPeriod, volume)) * 100\n * - Signal = EMA(signalPeriod, PVO)\n * - Histogram = PVO - Signal\n *\n * @param source - Iterable of volume values\n * @param options - Configuration options\n * @param options.fastPeriod - Period for the fast EMA (default: 12)\n * @param options.slowPeriod - Period for the slow EMA (default: 26)\n * @param options.signalPeriod - Period for the signal EMA (default: 9)\n * @returns Generator yielding PVO point objects\n */\nexport const pvo = createSignal(\n ({ fastPeriod, slowPeriod, signalPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n assert(Number.isInteger(signalPeriod) && signalPeriod >= 1, new RangeError(`Expected signalPeriod to be a positive integer, got ${signalPeriod}`))\n const fastProc = ema.create({ period: fastPeriod })\n const slowProc = ema.create({ period: slowPeriod })\n const signalProc = ema.create({ period: signalPeriod })\n return (value: Numberish) => {\n const fast = fastProc(toDnum(value))\n const slow = slowProc(toDnum(value))\n const pvoVal = eq(slow, 0) ? constants.ZERO : mul(div(sub(fast, slow), slow, constants.DECIMALS), 100, constants.DECIMALS)\n const sig = signalProc(pvoVal)\n return { pvo: pvoVal, signal: sig, histogram: sub(pvoVal, sig) }\n }\n },\n defaultPercentageVolumeOscillatorOptions,\n)\n\nexport { pvo as percentageVolumeOscillator }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { div, eq, mul, sub } from 'dnum'\n\nexport interface PriceRateOfChangeOptions {\n period: number\n}\n\nexport const defaultPriceRateOfChangeOptions: PriceRateOfChangeOptions = {\n period: 12,\n}\n\n/**\n * Price Rate of Change (ROC)\n *\n * The Price Rate of Change (ROC) is a momentum oscillator that measures the percentage change\n * in price between the current price and the price n periods ago.\n *\n * Formula:\n * - ROC = ((Current Price - Price n periods ago) / Price n periods ago) * 100\n *\n * @param source - Iterable of price values\n * @param options - Configuration options\n * @param options.period - Number of periods to look back (default: 12)\n * @returns Generator yielding ROC values as Dnum\n */\nexport const roc = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: Dnum[] = Array.from({ length: period })\n let head = 0\n let count = 0\n\n return (value: Numberish) => {\n const v = toDnum(value)\n if (count < period) {\n buffer[count] = v\n count++\n return constants.ZERO\n }\n else {\n const oldest = buffer[head]\n buffer[head] = v\n head = (head + 1) % period\n return eq(oldest, 0) ? constants.ZERO : mul(div(sub(v, oldest), oldest, constants.DECIMALS), 100, constants.DECIMALS)\n }\n }\n },\n defaultPriceRateOfChangeOptions,\n)\n\nexport { roc as priceRateOfChange }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, createSignal, toDnum } from '@vulcan-js/core'\nimport { gt } from 'dnum'\n\nexport interface MovingMaxOptions {\n /**\n * period\n */\n period: number\n}\n\nexport const defaultMovingMaxOptions: MovingMaxOptions = {\n period: 4,\n}\n\n/**\n * Moving Maximum (MovingMax)\n */\nexport const mmax = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: Dnum[] = []\n return (value: Numberish) => {\n buffer.push(toDnum(value))\n if (buffer.length > period)\n buffer.shift()\n return buffer.reduce((max, cur) => gt(max, cur) ? max : cur)\n }\n },\n defaultMovingMaxOptions,\n)\n\nexport { mmax as movingMax }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, createSignal, toDnum } from '@vulcan-js/core'\nimport { lt } from 'dnum'\n\nexport interface MovingMinOptions {\n /**\n * period\n */\n period: number\n}\n\nexport const defaultMovingMinOptions: MovingMinOptions = {\n period: 4,\n}\n\n/**\n * Moving Minimum (MovingMin)\n */\nexport const mmin = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: Dnum[] = []\n return (value: Numberish) => {\n buffer.push(toDnum(value))\n if (buffer.length > period)\n buffer.shift()\n return buffer.reduce((min, cur) => lt(min, cur) ? min : cur)\n }\n },\n defaultMovingMinOptions,\n)\n\nexport { mmin as movingMin }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, div, eq, mul, sub } from 'dnum'\nimport { mmax } from '../trend/movingMax'\nimport { mmin } from '../trend/movingMin'\n\nexport interface RandomIndexOptions {\n /**\n * The lookback period for calculating RSV (Raw Stochastic Value)\n * @default 9\n */\n period: number\n /**\n * The smoothing period for K line\n * @default 3\n */\n kPeriod: number\n /**\n * The smoothing period for D line\n * @default 3\n */\n dPeriod: number\n}\n\nexport const defaultRandomIndexOptions: RandomIndexOptions = {\n period: 9,\n kPeriod: 3,\n dPeriod: 3,\n}\n\nexport interface KDJPoint {\n k: Dnum\n d: Dnum\n j: Dnum\n}\n\n/**\n * Random Index (KDJ)\n *\n * An extension of the Stochastic Oscillator that adds a J line to amplify\n * divergence between K and D. Uses exponential-weighted smoothing with\n * initial K and D values set to 50.\n *\n * Formula:\n * RSV = (Close - LowestLow(period)) / (HighestHigh(period) - LowestLow(period)) × 100\n * K = ((kPeriod - 1) / kPeriod) × prevK + (1 / kPeriod) × RSV\n * D = ((dPeriod - 1) / dPeriod) × prevD + (1 / dPeriod) × K\n * J = 3K - 2D\n *\n * Interpretation:\n * - K crossing above D is a bullish signal (golden cross)\n * - K crossing below D is a bearish signal (death cross)\n * - J below 0 indicates oversold, J above 100 indicates overbought\n *\n * @param source - Iterable of candle data with high, low, and close prices\n * @param options - Configuration options\n * @param options.period - The lookback period for RSV calculation (default: 9)\n * @param options.kPeriod - The smoothing period for K line (default: 3)\n * @param options.dPeriod - The smoothing period for D line (default: 3)\n * @returns Generator yielding KDJPoint values with k, d, and j as Dnum\n */\nexport const kdj = createSignal(\n ({ period, kPeriod, dPeriod }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n assert(Number.isInteger(kPeriod) && kPeriod >= 1, new RangeError(`Expected kPeriod to be a positive integer, got ${kPeriod}`))\n assert(Number.isInteger(dPeriod) && dPeriod >= 1, new RangeError(`Expected dPeriod to be a positive integer, got ${dPeriod}`))\n\n const mmaxProc = mmax.create({ period })\n const mminProc = mmin.create({ period })\n\n const INITIAL = toDnum(50)\n const THREE = toDnum(3)\n\n let prevK: Dnum = INITIAL\n let prevD: Dnum = INITIAL\n let isFirst = true\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = toDnum(bar.h)\n const l = toDnum(bar.l)\n const c = toDnum(bar.c)\n\n const highestHigh = mmaxProc(h)\n const lowestLow = mminProc(l)\n\n const range = sub(highestHigh, lowestLow, constants.DECIMALS)\n const rsv = eq(range, 0) ? constants.ZERO : mul(div(sub(c, lowestLow, constants.DECIMALS), range, constants.DECIMALS), constants.HUNDRED, constants.DECIMALS)\n\n let k: Dnum\n let d: Dnum\n\n if (isFirst) {\n // First bar: K = (2/3)*50 + (1/3)*RSV, D = (2/3)*50 + (1/3)*K\n k = add(mul(div(toDnum(kPeriod - 1), kPeriod, constants.DECIMALS), INITIAL, constants.DECIMALS), mul(div(constants.ONE, kPeriod, constants.DECIMALS), rsv, constants.DECIMALS))\n d = add(mul(div(toDnum(dPeriod - 1), dPeriod, constants.DECIMALS), INITIAL, constants.DECIMALS), mul(div(constants.ONE, dPeriod, constants.DECIMALS), k, constants.DECIMALS))\n isFirst = false\n }\n else {\n k = add(mul(div(toDnum(kPeriod - 1), kPeriod, constants.DECIMALS), prevK, constants.DECIMALS), mul(div(constants.ONE, kPeriod, constants.DECIMALS), rsv, constants.DECIMALS))\n d = add(mul(div(toDnum(dPeriod - 1), dPeriod, constants.DECIMALS), prevD, constants.DECIMALS), mul(div(constants.ONE, dPeriod, constants.DECIMALS), k, constants.DECIMALS))\n }\n\n const j = sub(mul(THREE, k, constants.DECIMALS), mul(constants.TWO, d, constants.DECIMALS), constants.DECIMALS)\n\n prevK = k\n prevD = d\n\n return { k, d, j }\n }\n },\n defaultRandomIndexOptions,\n)\n\nexport { kdj as randomIndex }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, constants, createSignal } from '@vulcan-js/core'\nimport { add, div, mul } from 'dnum'\n\nexport interface RMAOptions {\n /**\n * period\n */\n period: number\n}\n\nexport const defaultRMAOptions: RMAOptions = {\n period: 4,\n}\n\n/**\n * Rolling moving average (RMA).\n *\n * R[0] to R[p-1] is SMA(values)\n *\n * R[p] and after is R[i] = ((R[i-1]*(p-1)) + v[i]) / p\n */\nexport const rma = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n let count = 0\n let sum: Dnum = constants.ZERO\n let prev: Dnum = constants.ZERO\n\n return (value: Numberish) => {\n if (count < period) {\n sum = add(sum, value)\n count++\n prev = div(sum, count, constants.DECIMALS)\n return prev\n }\n prev = div(\n add(mul(prev, period - 1, constants.DECIMALS), value),\n period,\n constants.DECIMALS,\n )\n return prev\n }\n },\n defaultRMAOptions,\n)\n\nexport { rma as rollingMovingAverage }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, div, eq, gt, mul, sub } from 'dnum'\nimport { rma } from '../trend/rollingMovingAverage'\n\nexport interface RSIOptions {\n period: number\n}\n\nexport const defaultRSIOptions: RSIOptions = {\n period: 14,\n}\n\n/**\n * Relative Strength Index (RSI). It is a momentum indicator that measures the magnitude of\n * recent price changes to evaluate overbought and oversold conditions\n * using the given window period.\n *\n * RS = Average Gain / Average Loss\n *\n * RSI = 100 - (100 / (1 + RS))\n */\nexport const rsi = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const gainProc = rma.create({ period })\n const lossProc = rma.create({ period })\n let prev: Dnum | undefined\n\n return (value: Numberish) => {\n const price = toDnum(value)\n\n if (prev === undefined) {\n prev = price\n gainProc(constants.ZERO)\n lossProc(constants.ZERO)\n return constants.ZERO\n }\n\n const change = sub(price, prev)\n prev = price\n\n const gain = gt(change, 0) ? change : constants.ZERO\n const loss = gt(change, 0) ? constants.ZERO : mul(change, -1, constants.DECIMALS)\n\n const avgGain = gainProc(gain)\n const avgLoss = lossProc(loss)\n\n if (eq(avgLoss, 0)) {\n return constants.HUNDRED\n }\n\n const rs = div(avgGain, avgLoss, constants.DECIMALS)\n return sub(100, div(100, add(1, rs), constants.DECIMALS))\n }\n },\n defaultRSIOptions,\n)\n\nexport { rsi as relativeStrengthIndex }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { div, eq, mul, sub } from 'dnum'\nimport { mmax } from '../trend/movingMax'\nimport { mmin } from '../trend/movingMin'\nimport { sma } from '../trend/simpleMovingAverage'\n\nexport interface StochasticOscillatorOptions {\n /** The %k period */\n kPeriod: number\n /** The %k slowing period */\n slowingPeriod: number\n /** The %d period */\n dPeriod: number\n}\n\nexport const defaultStochasticOscillatorOptions: StochasticOscillatorOptions = {\n kPeriod: 14,\n slowingPeriod: 1,\n dPeriod: 3,\n}\n\nexport interface StochPoint {\n k: Dnum\n d: Dnum\n}\n\n/**\n * Stochastic Oscillator\n *\n * %K = ((Close - Lowest Low) / (Highest High - Lowest Low)) * 100\n * %D = SMA(%K, dPeriod)\n */\nexport const stoch = createSignal(\n ({ kPeriod, slowingPeriod, dPeriod }) => {\n assert(Number.isInteger(kPeriod) && kPeriod >= 1, new RangeError(`Expected kPeriod to be a positive integer, got ${kPeriod}`))\n assert(Number.isInteger(slowingPeriod) && slowingPeriod >= 1, new RangeError(`Expected slowingPeriod to be a positive integer, got ${slowingPeriod}`))\n assert(Number.isInteger(dPeriod) && dPeriod >= 1, new RangeError(`Expected dPeriod to be a positive integer, got ${dPeriod}`))\n const mmaxProc = mmax.create({ period: kPeriod })\n const mminProc = mmin.create({ period: kPeriod })\n const slowingProc = slowingPeriod > 1 ? sma.create({ period: slowingPeriod }) : null\n const dProc = sma.create({ period: dPeriod })\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = toDnum(bar.h)\n const l = toDnum(bar.l)\n const c = toDnum(bar.c)\n\n const highestHigh = mmaxProc(h)\n const lowestLow = mminProc(l)\n\n const range = sub(highestHigh, lowestLow, constants.DECIMALS)\n const rawK = eq(range, 0) ? constants.ZERO : mul(div(sub(c, lowestLow, constants.DECIMALS), range, constants.DECIMALS), 100, constants.DECIMALS)\n const k = slowingProc ? slowingProc(rawK) : rawK\n return { k, d: dProc(k) }\n }\n },\n defaultStochasticOscillatorOptions,\n)\n\nexport { stoch as stochasticOscillator }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { div, eq, mul, sub } from 'dnum'\nimport { mmax } from '../trend/movingMax'\nimport { mmin } from '../trend/movingMin'\n\nexport interface WilliamsROptions {\n /** Lookback period */\n period: number\n}\n\nexport const defaultWilliamsROptions: WilliamsROptions = {\n period: 14,\n}\n\n/**\n * Williams %R (WILLR)\n *\n * A momentum indicator that measures overbought and oversold conditions.\n * It shows the relationship between the closing price and the highest high / lowest low\n * over a specified period.\n *\n * Formula:\n * - %R = -100 × (Highest High - Close) / (Highest High - Lowest Low)\n *\n * Range: -100 to 0\n * - Above -20: Overbought\n * - Below -80: Oversold\n *\n * @param source - Iterable of candle data with high, low, and close\n * @param options - Configuration options\n * @param options.period - Lookback period (default: 14)\n * @returns Generator yielding Williams %R values as Dnum\n */\nexport const willr = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const mmaxProc = mmax.create({ period })\n const mminProc = mmin.create({ period })\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = toDnum(bar.h)\n const l = toDnum(bar.l)\n const c = toDnum(bar.c)\n\n const highestHigh = mmaxProc(h)\n const lowestLow = mminProc(l)\n\n const range = sub(highestHigh, lowestLow, constants.DECIMALS)\n return eq(range, 0)\n ? constants.ZERO\n : mul(div(sub(highestHigh, c, constants.DECIMALS), range, constants.DECIMALS), -100, constants.DECIMALS)\n }\n },\n defaultWilliamsROptions,\n)\n\nexport { willr as williamsR }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { divide, gt, lt, multiply, subtract } from 'dnum'\n\nexport interface AroonOptions {\n period: number\n}\n\nexport const defaultAroonOptions: AroonOptions = {\n period: 25,\n}\n\nexport interface AroonPoint {\n up: Dnum\n down: Dnum\n oscillator: Dnum\n}\n\n/**\n * Aroon Indicator\n *\n * Aroon Up = ((period - days since highest high) / period) * 100\n * Aroon Down = ((period - days since lowest low) / period) * 100\n * Oscillator = Aroon Up - Aroon Down\n */\nexport const aroon = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const highBuffer: Dnum[] = []\n const lowBuffer: Dnum[] = []\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l'>) => {\n const h = toDnum(bar.h)\n const l = toDnum(bar.l)\n\n highBuffer.push(h)\n lowBuffer.push(l)\n if (highBuffer.length > period + 1)\n highBuffer.shift()\n if (lowBuffer.length > period + 1)\n lowBuffer.shift()\n\n let highestIdx = 0\n let lowestIdx = 0\n for (let j = 1; j < highBuffer.length; j++) {\n if (!gt(highBuffer[highestIdx], highBuffer[j]))\n highestIdx = j\n if (!lt(lowBuffer[lowestIdx], lowBuffer[j]))\n lowestIdx = j\n }\n\n const daysSinceHigh = highBuffer.length - 1 - highestIdx\n const daysSinceLow = lowBuffer.length - 1 - lowestIdx\n\n const periodDnum = toDnum(period)\n const up = divide(multiply(toDnum(period - daysSinceHigh), 100, constants.DECIMALS), periodDnum, constants.DECIMALS)\n const down = divide(multiply(toDnum(period - daysSinceLow), 100, constants.DECIMALS), periodDnum, constants.DECIMALS)\n\n return {\n up,\n down,\n oscillator: subtract(up, down),\n }\n }\n },\n defaultAroonOptions,\n)\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { divide, equal, subtract } from 'dnum'\n\nexport const bop = createSignal(\n () => {\n return (bar: RequiredProperties<CandleData, 'o' | 'h' | 'l' | 'c'>) => {\n const o = toDnum(bar.o)\n const h = toDnum(bar.h)\n const l = toDnum(bar.l)\n const c = toDnum(bar.c)\n const range = subtract(h, l)\n if (equal(range, 0)) {\n return constants.ZERO\n }\n return divide(subtract(c, o), range, constants.DECIMALS)\n }\n },\n)\n\nexport { bop as balanceOfPower }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, divide, equal, multiply, subtract } from 'dnum'\n\nexport interface ChandeForecastOscillatorOptions {\n /**\n * The period for linear regression\n * @default 14\n */\n period: number\n}\n\nexport const defaultCFOOptions: ChandeForecastOscillatorOptions = {\n period: 14,\n}\n\n/**\n * Chande Forecast Oscillator (CFO)\n *\n * Measures the percentage difference between the actual close price and the\n * n-period linear regression forecast price. Positive values indicate bullish\n * momentum (price above forecast), negative values indicate bearish momentum.\n *\n * Formula: CFO = ((Close - Forecast) / Close) * 100\n * Where: Forecast = Linear regression value at current point\n *\n * @param source - Iterable of price values\n * @param options - Configuration options\n * @param options.period - The period for linear regression (default: 14)\n * @returns Generator yielding CFO values as percentages\n */\nexport const cfo = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: Dnum[] = []\n\n return (value: Numberish) => {\n buffer.push(toDnum(value))\n if (buffer.length > period)\n buffer.shift()\n\n const n = buffer.length\n if (n < 2) {\n return constants.ZERO\n }\n\n // Precompute X-related sums as plain integers\n const xSum = n * (n + 1) / 2\n const x2Sum = n * (n + 1) * (2 * n + 1) / 6\n const denom = n * x2Sum - xSum * xSum\n\n // Compute Y-dependent sums (keep all Dnum at 18 decimals)\n let sumY: Dnum = constants.ZERO\n let sumXY: Dnum = constants.ZERO\n for (let i = 0; i < n; i++) {\n sumY = add(sumY, buffer[i])\n sumXY = add(sumXY, multiply(buffer[i], i + 1))\n }\n\n // slope = (n * SUM(XY) - SUM(X) * SUM(Y)) / denom\n const num = subtract(multiply(sumXY, n), multiply(sumY, xSum))\n const slope = divide(num, denom, constants.DECIMALS)\n\n // intercept = (SUM(Y) - slope * SUM(X)) / n\n const intercept = divide(subtract(sumY, multiply(slope, xSum)), n, constants.DECIMALS)\n\n // forecast = slope * n + intercept\n const forecast = add(multiply(slope, n), intercept)\n\n const close = buffer[n - 1]\n if (equal(close, 0)) {\n return constants.ZERO\n }\n\n return divide(multiply(subtract(close, forecast), 100), close, constants.DECIMALS)\n }\n },\n defaultCFOOptions,\n)\n\nexport { cfo as chandeForecastOscillator }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal } from '@vulcan-js/core'\nimport { mul, sub } from 'dnum'\nimport { ema } from './exponentialMovingAverage'\n\nexport interface DoubleExponentialMovingAverageOptions {\n period: number\n}\n\nexport const defaultDoubleExponentialMovingAverageOptions: DoubleExponentialMovingAverageOptions = {\n period: 12,\n}\n\n/**\n * Double Exponential Moving Average (DEMA)\n *\n * DEMA reduces lag compared to a traditional EMA by applying the formula:\n * DEMA = 2 * EMA(data, period) - EMA(EMA(data, period), period)\n *\n * @param source - Iterable of input values\n * @param options - Configuration options\n * @param options.period - The lookback period (default: 12)\n * @returns Generator yielding DEMA values\n */\nexport const dema = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const ema1 = ema.create({ period })\n const ema2 = ema.create({ period })\n return (value: Numberish) => {\n const e1 = ema1(value)\n const e2 = ema2(e1)\n return sub(mul(e1, 2, 18), e2)\n }\n },\n defaultDoubleExponentialMovingAverageOptions,\n)\n\nexport { dema as doubleExponentialMovingAverage }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, createSignal } from '@vulcan-js/core'\nimport { add, div, from } from 'dnum'\nimport { mmax } from './movingMax'\nimport { mmin } from './movingMin'\n\nexport interface IchimokuCloudOptions {\n /** Conversion line period */\n conversionPeriod: number\n /** Base line period */\n basePeriod: number\n /** Leading span B period */\n leadingBPeriod: number\n}\n\nexport const defaultIchimokuCloudOptions: IchimokuCloudOptions = {\n conversionPeriod: 9,\n basePeriod: 26,\n leadingBPeriod: 52,\n}\n\nexport interface IchimokuCloudPoint {\n conversion: Dnum\n base: Dnum\n leadingA: Dnum\n leadingB: Dnum\n lagging: Dnum\n}\n\n/**\n * Ichimoku Cloud (Ichimoku Kinko Hyo)\n *\n * Computes raw values for each component. Displacement (shifting\n * Leading Spans forward and Lagging Span backward on the chart)\n * is a presentation concern left to the consumer.\n *\n * - Conversion (Tenkan-sen): (highest high + lowest low) / 2 over conversionPeriod\n * - Base (Kijun-sen): (highest high + lowest low) / 2 over basePeriod\n * - Leading Span A (Senkou A): (conversion + base) / 2\n * - Leading Span B (Senkou B): (highest high + lowest low) / 2 over leadingBPeriod\n * - Lagging (Chikou): current close price\n */\nexport const ichimokuCloud = createSignal(\n ({ conversionPeriod, basePeriod, leadingBPeriod }) => {\n assert(Number.isInteger(conversionPeriod) && conversionPeriod >= 1, new RangeError(`Expected conversionPeriod to be a positive integer, got ${conversionPeriod}`))\n assert(Number.isInteger(basePeriod) && basePeriod >= 1, new RangeError(`Expected basePeriod to be a positive integer, got ${basePeriod}`))\n assert(Number.isInteger(leadingBPeriod) && leadingBPeriod >= 1, new RangeError(`Expected leadingBPeriod to be a positive integer, got ${leadingBPeriod}`))\n const convHighProc = mmax.create({ period: conversionPeriod })\n const convLowProc = mmin.create({ period: conversionPeriod })\n const baseHighProc = mmax.create({ period: basePeriod })\n const baseLowProc = mmin.create({ period: basePeriod })\n const leadBHighProc = mmax.create({ period: leadingBPeriod })\n const leadBLowProc = mmin.create({ period: leadingBPeriod })\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = from(bar.h, 18)\n const l = from(bar.l, 18)\n\n const conversion = div(add(convHighProc(h), convLowProc(l)), 2, 18)\n const base = div(add(baseHighProc(h), baseLowProc(l)), 2, 18)\n const leadingA = div(add(conversion, base), 2, 18)\n const leadingB = div(add(leadBHighProc(h), leadBLowProc(l)), 2, 18)\n\n return { conversion, base, leadingA, leadingB, lagging: from(bar.c, 18) }\n }\n },\n defaultIchimokuCloudOptions,\n)\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, createSignal } from '@vulcan-js/core'\nimport { sub } from 'dnum'\nimport { ema } from './exponentialMovingAverage'\n\nexport interface MACDOptions {\n fastPeriod: number\n slowPeriod: number\n signalPeriod: number\n}\n\nexport const defaultMACDOptions: MACDOptions = {\n fastPeriod: 12,\n slowPeriod: 26,\n signalPeriod: 9,\n}\n\nexport interface MACDPoint {\n macd: Dnum\n signal: Dnum\n histogram: Dnum\n}\n\n/**\n * Moving Average Convergence Divergence (MACD)\n *\n * MACD is a trend-following momentum indicator that shows the relationship\n * between two exponential moving averages of prices. It consists of three components:\n * - MACD Line: Fast EMA - Slow EMA\n * - Signal Line: EMA of the MACD line\n * - Histogram: MACD - Signal\n *\n * Formula:\n * - MACD = EMA(fastPeriod, prices) - EMA(slowPeriod, prices)\n * - Signal = EMA(signalPeriod, MACD)\n * - Histogram = MACD - Signal\n *\n * @param source - Iterable of price values\n * @param options - Configuration options\n * @param options.fastPeriod - Period for the fast EMA (default: 12)\n * @param options.slowPeriod - Period for the slow EMA (default: 26)\n * @param options.signalPeriod - Period for the signal EMA (default: 9)\n * @returns Generator yielding MACDPoint objects\n */\nexport const macd = createSignal(\n ({ fastPeriod, slowPeriod, signalPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n assert(Number.isInteger(signalPeriod) && signalPeriod >= 1, new RangeError(`Expected signalPeriod to be a positive integer, got ${signalPeriod}`))\n const fastProc = ema.create({ period: fastPeriod })\n const slowProc = ema.create({ period: slowPeriod })\n const signalProc = ema.create({ period: signalPeriod })\n return (value: Numberish) => {\n const fast = fastProc(value)\n const slow = slowProc(value)\n const m = sub(fast, slow)\n const sig = signalProc(m)\n return { macd: m, signal: sig, histogram: sub(m, sig) }\n }\n },\n defaultMACDOptions,\n)\n\nexport { macd as movingAverageConvergenceDivergence }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, subtract } from 'dnum'\n\nexport interface MovingSumOptions {\n period: number\n}\n\nexport const defaultMovingSumOptions: MovingSumOptions = {\n period: 4,\n}\n\n/**\n * Moving Sum\n *\n * Calculates the sum of values in a sliding window of the specified period.\n */\nexport const msum = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: Dnum[] = Array.from({ length: period })\n let head = 0\n let count = 0\n let runningSum: Dnum = constants.ZERO\n\n return (value: Numberish) => {\n const v = toDnum(value)\n if (count < period) {\n buffer[count] = v\n runningSum = add(runningSum, v)\n count++\n }\n else {\n runningSum = subtract(runningSum, buffer[head])\n runningSum = add(runningSum, v)\n buffer[head] = v\n head = (head + 1) % period\n }\n return runningSum\n }\n },\n defaultMovingSumOptions,\n)\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, gt, lt, mul, sub } from 'dnum'\n\nexport interface ParabolicSarOptions {\n start: number\n increment: number\n max: number\n}\n\nexport const defaultParabolicSarOptions: ParabolicSarOptions = {\n start: 0.02,\n increment: 0.02,\n max: 0.2,\n}\n\nexport interface PSARPoint {\n psar: Dnum\n isUptrend: boolean\n}\n\n/**\n * Parabolic SAR (Stop and Reverse)\n *\n * Developed by J. Welles Wilder Jr. in 1978, the Parabolic SAR is a\n * trend-following indicator that provides potential entry and exit points.\n * It appears as a series of dots above or below the price, indicating\n * the current trend direction and potential reversal points.\n *\n * Formula:\n * SAR_new = SAR_prev + AF * (EP - SAR_prev)\n *\n * Where:\n * AF = Acceleration Factor (starts at `start`, increments by `increment`\n * on each new EP, capped at `max`)\n * EP = Extreme Point (highest high in uptrend, lowest low in downtrend)\n *\n * The SAR is clamped to not exceed the two prior bars' price range.\n * A reversal occurs when price penetrates the SAR level.\n *\n * @param source - Iterable of candle data with high and low prices\n * @param options - Configuration options\n * @param options.start - Initial acceleration factor (default: 0.02)\n * @param options.increment - AF increment per new extreme (default: 0.02)\n * @param options.max - Maximum acceleration factor (default: 0.2)\n * @returns Generator yielding PSARPoint objects with `psar` value and `isUptrend` flag\n */\nexport const psar = createSignal(\n ({ start, increment, max }) => {\n assert(start > 0, new RangeError(`Expected start to be positive, got ${start}`))\n assert(increment > 0, new RangeError(`Expected increment to be positive, got ${increment}`))\n assert(max > 0 && max >= start, new RangeError(`Expected max to be positive and >= start, got ${max}`))\n\n let count = 0\n let isUptrend = true\n let sar: Dnum\n let ep: Dnum\n let af: Dnum\n let prevHigh: Dnum\n let prevLow: Dnum\n let prevPrevHigh: Dnum\n let prevPrevLow: Dnum\n\n const afStart = toDnum(start)\n const afIncrement = toDnum(increment)\n const afMax = toDnum(max)\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l'>) => {\n const h = toDnum(bar.h)\n const l = toDnum(bar.l)\n count++\n\n // Bar 1: initialization\n if (count === 1) {\n isUptrend = true\n sar = l\n ep = h\n af = afStart\n prevHigh = h\n prevLow = l\n prevPrevHigh = h\n prevPrevLow = l\n return { psar: sar, isUptrend }\n }\n\n // Bar 2: determine initial trend\n if (count === 2) {\n if (gt(h, prevHigh)) {\n isUptrend = true\n sar = prevLow\n ep = h\n }\n else {\n isUptrend = false\n sar = prevHigh\n ep = l\n }\n af = afStart\n prevPrevHigh = prevHigh\n prevPrevLow = prevLow\n prevHigh = h\n prevLow = l\n return { psar: sar, isUptrend }\n }\n\n // Bar 3+: standard computation\n // Step A: calculate next SAR\n let nextSar = add(sar, mul(af, sub(ep, sar), constants.DECIMALS))\n\n // Step B: clamp SAR\n if (isUptrend) {\n if (gt(nextSar, prevLow))\n nextSar = prevLow\n if (gt(nextSar, prevPrevLow))\n nextSar = prevPrevLow\n }\n else {\n if (lt(nextSar, prevHigh))\n nextSar = prevHigh\n if (lt(nextSar, prevPrevHigh))\n nextSar = prevPrevHigh\n }\n\n sar = nextSar\n\n // Step C: check for reversal\n let reversed = false\n if (isUptrend && lt(l, sar)) {\n isUptrend = false\n sar = ep\n ep = l\n af = afStart\n reversed = true\n }\n else if (!isUptrend && gt(h, sar)) {\n isUptrend = true\n sar = ep\n ep = h\n af = afStart\n reversed = true\n }\n\n // Step D: update EP and AF (only if no reversal)\n if (!reversed) {\n if (isUptrend && gt(h, ep)) {\n ep = h\n const newAf = add(af, afIncrement)\n af = gt(newAf, afMax) ? afMax : newAf\n }\n else if (!isUptrend && lt(l, ep)) {\n ep = l\n const newAf = add(af, afIncrement)\n af = gt(newAf, afMax) ? afMax : newAf\n }\n }\n\n // Step E: update prev tracking\n prevPrevHigh = prevHigh\n prevPrevLow = prevLow\n prevHigh = h\n prevLow = l\n\n return { psar: sar, isUptrend }\n }\n },\n defaultParabolicSarOptions,\n)\n\nexport { psar as parabolicSar }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, divide, subtract } from 'dnum'\n\nexport interface QstickOptions {\n /**\n * The period for calculating the moving average of (Close - Open)\n * @default 14\n */\n period: number\n}\n\nexport const defaultQstickOptions: QstickOptions = {\n period: 14,\n}\n\n/**\n * Qstick Indicator\n *\n * Developed by Tushar Chande, the Qstick indicator measures the average\n * difference between closing and opening prices over a specified period.\n * It quantifies buying and selling pressure using a simple moving average\n * of (Close - Open).\n *\n * Formula: Qstick = SMA(Close - Open, period)\n *\n * Interpretation:\n * - Positive values indicate buying pressure (closes above opens)\n * - Negative values indicate selling pressure (closes below opens)\n * - Zero-line crossovers can signal trend changes\n *\n * @param source - Iterable of candle data with open and close prices\n * @param options - Configuration options\n * @param options.period - The period for the SMA calculation (default: 14)\n * @returns Generator yielding Qstick values as Dnum\n */\nexport const qstick = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n\n const buffer: Dnum[] = Array.from({ length: period })\n let head = 0\n let count = 0\n let runningSum: Dnum = constants.ZERO\n\n return (bar: RequiredProperties<CandleData, 'o' | 'c'>) => {\n const diff = subtract(toDnum(bar.c), toDnum(bar.o))\n\n if (count < period) {\n buffer[count] = diff\n runningSum = add(runningSum, diff)\n count++\n }\n else {\n runningSum = subtract(runningSum, buffer[head])\n runningSum = add(runningSum, diff)\n buffer[head] = diff\n head = (head + 1) % period\n }\n\n return divide(runningSum, count, constants.DECIMALS)\n }\n },\n defaultQstickOptions,\n)\n\nexport { qstick as qstickIndicator }\n","import type { Dnum, Numberish } from 'dnum'\nimport { constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, equal } from 'dnum'\n\n/**\n * Since Change\n *\n * Counts the number of periods since the input value last changed.\n * When the value changes, the counter resets to 0. When the value\n * remains the same, the counter increments by 1 each period.\n *\n * Example:\n * Input: [1, 1, 1, 2, 2, 3, 3, 3, 3]\n * Output: [0, 1, 2, 0, 1, 0, 1, 2, 3]\n *\n * @param source - Iterable of values\n * @returns Generator yielding the number of periods since the last change\n */\nexport const since = createSignal(\n () => {\n let last: Dnum | undefined\n let count: Dnum = constants.ZERO\n\n return (value: Numberish) => {\n const v = toDnum(value)\n\n if (last === undefined || !equal(last, v)) {\n last = v\n count = constants.ZERO\n }\n else {\n count = add(count, constants.ONE)\n }\n\n return count\n }\n },\n)\n\nexport { since as sinceChange }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal } from '@vulcan-js/core'\nimport { sma } from './simpleMovingAverage'\n\nexport interface TriangularMovingAverageOptions {\n period: number\n}\n\nexport const defaultTriangularMovingAverageOptions: TriangularMovingAverageOptions = {\n period: 4,\n}\n\nexport const trima = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n let n1: number\n let n2: number\n\n if (period % 2 === 0) {\n n1 = period / 2\n n2 = n1 + 1\n }\n else {\n n1 = (period + 1) / 2\n n2 = n1\n }\n\n const sma1 = sma.create({ period: n2 })\n const sma2 = sma.create({ period: n1 })\n\n return (value: Numberish) => {\n const s1 = sma1(value)\n return sma2(s1)\n }\n },\n defaultTriangularMovingAverageOptions,\n)\n\nexport { trima as triangularMovingAverage }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, constants, createSignal } from '@vulcan-js/core'\nimport { divide, multiply, subtract } from 'dnum'\nimport { ema } from './exponentialMovingAverage'\n\nexport interface TripleExponentialAverageOptions {\n period: number\n}\n\nexport const defaultTripleExponentialAverageOptions: TripleExponentialAverageOptions = {\n period: 15,\n}\n\n/**\n * Triple Exponential Average (TRIX)\n *\n * TRIX is a momentum oscillator that displays the percentage rate of change\n * of a triple exponentially smoothed moving average. It oscillates around zero,\n * filtering out insignificant price movements.\n *\n * TRIX = (EMA3_current - EMA3_previous) / EMA3_previous * 100\n *\n * Where EMA3 = EMA(EMA(EMA(source, period), period), period)\n *\n * @param source - Iterable of input values\n * @param options - Configuration options\n * @param options.period - The lookback period (default: 15)\n * @returns Generator yielding TRIX values as percentages\n */\nexport const trix = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const ema1 = ema.create({ period })\n const ema2 = ema.create({ period })\n const ema3 = ema.create({ period })\n let prevEma3: Dnum | null = null\n return (value: Numberish) => {\n const e1 = ema1(value)\n const e2 = ema2(e1)\n const e3 = ema3(e2)\n if (prevEma3 === null) {\n prevEma3 = e3\n return constants.ZERO\n }\n const result = multiply(divide(subtract(e3, prevEma3), prevEma3, constants.DECIMALS), 100, constants.DECIMALS)\n prevEma3 = e3\n return result\n }\n },\n defaultTripleExponentialAverageOptions,\n)\n\nexport { trix as tripleExponentialAverage }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal } from '@vulcan-js/core'\nimport { add, mul, sub } from 'dnum'\nimport { ema } from './exponentialMovingAverage'\n\nexport interface TripleExponentialMovingAverageOptions {\n period: number\n}\n\nexport const defaultTripleExponentialMovingAverageOptions: TripleExponentialMovingAverageOptions = {\n period: 12,\n}\n\n/**\n * Triple Exponential Moving Average (TEMA)\n *\n * TEMA further reduces lag compared to DEMA by applying the formula:\n * TEMA = 3 * EMA(data, period) - 3 * EMA(EMA(data, period), period) + EMA(EMA(EMA(data, period), period), period)\n *\n * @param source - Iterable of input values\n * @param options - Configuration options\n * @param options.period - The lookback period (default: 12)\n * @returns Generator yielding TEMA values\n */\nexport const tema = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const ema1 = ema.create({ period })\n const ema2 = ema.create({ period })\n const ema3 = ema.create({ period })\n return (value: Numberish) => {\n const e1 = ema1(value)\n const e2 = ema2(e1)\n const e3 = ema3(e2)\n // TEMA = 3 * EMA1 - 3 * EMA2 + EMA3\n return add(sub(mul(e1, 3, 18), mul(e2, 3, 18)), e3)\n }\n },\n defaultTripleExponentialMovingAverageOptions,\n)\n\nexport { tema as tripleExponentialMovingAverage }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { createSignal } from '@vulcan-js/core'\nimport { add, divide, from } from 'dnum'\n\n/**\n * Typical Price\n *\n * The Typical Price is a simple average of the high, low, and close prices\n * for a given period. It provides a single representative price for each bar\n * and is commonly used as input for other indicators such as CCI and MFI.\n *\n * Formula: Typical Price = (High + Low + Close) / 3\n *\n * @param source - Iterable of candle data with high, low, and close prices\n * @returns Generator yielding Typical Price values as Dnum\n */\nexport const typicalPrice = createSignal(\n () => {\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = from(bar.h, 18)\n const l = from(bar.l, 18)\n const c = from(bar.c, 18)\n\n return divide(add(add(h, l), c), 3, 18)\n }\n },\n)\n\nexport { typicalPrice as typicalPriceIndicator }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { add, divide, multiply, subtract } from 'dnum'\n\nexport interface VwmaOptions {\n /**\n * The number of periods for calculating the volume weighted moving average\n * @default 20\n */\n period: number\n}\n\nexport const defaultVwmaOptions: VwmaOptions = {\n period: 20,\n}\n\n/**\n * Volume Weighted Moving Average (VWMA)\n *\n * VWMA weights each price by its corresponding volume, giving more\n * influence to prices with higher trading activity. It is useful for\n * confirming trends and identifying divergences between price and volume.\n *\n * Formula: VWMA = Sum(Close × Volume, period) / Sum(Volume, period)\n *\n * Interpretation:\n * - When VWMA is below price, it suggests bullish sentiment (higher volume at higher prices)\n * - When VWMA is above price, it suggests bearish sentiment (higher volume at lower prices)\n * - Crossovers with SMA can signal volume-confirmed trend changes\n *\n * @param source - Iterable of candle data with close price and volume\n * @param options - Configuration options\n * @param options.period - The number of periods (default: 20)\n * @returns Generator yielding VWMA values as Dnum\n */\nexport const vwma = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n\n const pvBuffer: Dnum[] = Array.from({ length: period })\n const vBuffer: Dnum[] = Array.from({ length: period })\n let head = 0\n let count = 0\n let pvSum: Dnum = constants.ZERO\n let vSum: Dnum = constants.ZERO\n\n return (bar: RequiredProperties<CandleData, 'c' | 'v'>) => {\n const close = toDnum(bar.c)\n const volume = toDnum(bar.v)\n const pv = multiply(close, volume, constants.DECIMALS)\n\n if (count < period) {\n pvBuffer[count] = pv\n vBuffer[count] = volume\n pvSum = add(pvSum, pv)\n vSum = add(vSum, volume)\n count++\n }\n else {\n pvSum = subtract(pvSum, pvBuffer[head])\n vSum = subtract(vSum, vBuffer[head])\n pvBuffer[head] = pv\n vBuffer[head] = volume\n pvSum = add(pvSum, pv)\n vSum = add(vSum, volume)\n head = (head + 1) % period\n }\n\n return divide(pvSum, vSum, constants.DECIMALS)\n }\n },\n defaultVwmaOptions,\n)\n\nexport { vwma as volumeWeightedMovingAverage }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, constants, createSignal, toDnum } from '@vulcan-js/core'\nimport { abs, add, divide, gt, subtract } from 'dnum'\n\nexport interface VortexOptions {\n period: number\n}\n\nexport const defaultVortexOptions: VortexOptions = {\n period: 14,\n}\n\nexport interface VortexPoint {\n plus: Dnum\n minus: Dnum\n}\n\n/**\n * Vortex Indicator (VI)\n *\n * Identifies trend direction and potential reversals using two oscillating lines (VI+ and VI-).\n *\n * VM+(i) = |High(i) - Low(i-1)|\n * VM-(i) = |Low(i) - High(i-1)|\n * TR(i) = max(High(i) - Low(i), |High(i) - Close(i-1)|, |Low(i) - Close(i-1)|)\n * VI+ = SUM(VM+, period) / SUM(TR, period)\n * VI- = SUM(VM-, period) / SUM(TR, period)\n */\nexport const vortex = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n\n const vmPlusBuffer: Dnum[] = Array.from({ length: period })\n const vmMinusBuffer: Dnum[] = Array.from({ length: period })\n const trBuffer: Dnum[] = Array.from({ length: period })\n\n let head = 0\n let count = 0\n let sumVmPlus: Dnum = constants.ZERO\n let sumVmMinus: Dnum = constants.ZERO\n let sumTr: Dnum = constants.ZERO\n\n let prevHigh: Dnum | null = null\n let prevLow: Dnum | null = null\n let prevClose: Dnum | null = null\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = toDnum(bar.h)\n const l = toDnum(bar.l)\n const c = toDnum(bar.c)\n\n if (prevHigh === null || prevLow === null || prevClose === null) {\n prevHigh = h\n prevLow = l\n prevClose = c\n return { plus: constants.ZERO, minus: constants.ZERO }\n }\n\n const vmPlus = abs(subtract(h, prevLow))\n const vmMinus = abs(subtract(l, prevHigh))\n\n const hl = subtract(h, l)\n const hpc = abs(subtract(h, prevClose))\n const lpc = abs(subtract(l, prevClose))\n let tr = hl\n if (gt(hpc, tr))\n tr = hpc\n if (gt(lpc, tr))\n tr = lpc\n\n if (count < period) {\n vmPlusBuffer[count] = vmPlus\n vmMinusBuffer[count] = vmMinus\n trBuffer[count] = tr\n sumVmPlus = add(sumVmPlus, vmPlus)\n sumVmMinus = add(sumVmMinus, vmMinus)\n sumTr = add(sumTr, tr)\n count++\n }\n else {\n sumVmPlus = subtract(sumVmPlus, vmPlusBuffer[head])\n sumVmMinus = subtract(sumVmMinus, vmMinusBuffer[head])\n sumTr = subtract(sumTr, trBuffer[head])\n vmPlusBuffer[head] = vmPlus\n vmMinusBuffer[head] = vmMinus\n trBuffer[head] = tr\n sumVmPlus = add(sumVmPlus, vmPlus)\n sumVmMinus = add(sumVmMinus, vmMinus)\n sumTr = add(sumTr, tr)\n head = (head + 1) % period\n }\n\n prevHigh = h\n prevLow = l\n prevClose = c\n\n return {\n plus: divide(sumVmPlus, sumTr, constants.DECIMALS),\n minus: divide(sumVmMinus, sumTr, constants.DECIMALS),\n }\n }\n },\n defaultVortexOptions,\n)\n\nexport { vortex as vortexIndicator }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { assert, createSignal } from '@vulcan-js/core'\nimport { divide, from, subtract } from 'dnum'\nimport { ema } from '../trend/exponentialMovingAverage'\nimport { msum } from '../trend/movingSum'\n\nexport interface MassIndexOptions {\n /**\n * The period for EMA smoothing of the high-low range\n * @default 9\n */\n emaPeriod: number\n /**\n * The period for the moving sum of the EMA ratio\n * @default 25\n */\n miPeriod: number\n}\n\nexport const defaultMassIndexOptions: MassIndexOptions = {\n emaPeriod: 9,\n miPeriod: 25,\n}\n\n/**\n * Mass Index (MI)\n *\n * Developed by Donald Dorsey, the Mass Index uses the high-low range\n * to identify trend reversals based on range expansions. A \"reversal bulge\"\n * occurs when the Mass Index rises above 27 and then falls below 26.5.\n *\n * Formula:\n * Range = High - Low\n * EMA1 = EMA(Range, emaPeriod)\n * EMA2 = EMA(EMA1, emaPeriod)\n * Ratio = EMA1 / EMA2\n * MI = MovingSum(Ratio, miPeriod)\n *\n * @param source - Iterable of OHLC candle data (requires high and low)\n * @param options - Configuration options\n * @param options.emaPeriod - The EMA smoothing period (default: 9)\n * @param options.miPeriod - The moving sum period (default: 25)\n * @returns Generator yielding Mass Index values\n */\nexport const mi = createSignal(\n ({ emaPeriod, miPeriod }) => {\n assert(Number.isInteger(emaPeriod) && emaPeriod >= 1, new RangeError(`Expected emaPeriod to be a positive integer, got ${emaPeriod}`))\n assert(Number.isInteger(miPeriod) && miPeriod >= 1, new RangeError(`Expected miPeriod to be a positive integer, got ${miPeriod}`))\n const ema1Proc = ema.create({ period: emaPeriod })\n const ema2Proc = ema.create({ period: emaPeriod })\n const msumProc = msum.create({ period: miPeriod })\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l'>) => {\n const range = subtract(from(bar.h, 18), from(bar.l, 18))\n const e1 = ema1Proc(range)\n const e2 = ema2Proc(e1)\n const ratio = divide(e1, e2, 18)\n return msumProc(ratio)\n }\n },\n defaultMassIndexOptions,\n)\n\nexport { mi as massIndex }\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["ad","mmax","mmin","msum","rma","sma","prim.ewma","prim.sma","prim.ad","prim.ewma","prim.ewma","prim.ewma","prim.mmax","prim.mmin","prim.rma","prim.mmax","prim.mmin","prim.sma","prim.mmax","prim.mmin","prim.ewma","prim.ewma","prim.mmax","prim.mmin","prim.ewma","prim.mmax","prim.mmin","prim.msum","prim.rma","prim.sma","prim.sma","prim.ewma","prim.ewma","prim.ewma","prim.msum","prim.ad"],"sources":["../src/primitives/ad.ts","../src/primitives/ewma.ts","../src/primitives/mmax.ts","../src/primitives/mmin.ts","../src/primitives/msum.ts","../src/primitives/rma.ts","../src/primitives/sma.ts","../src/momentum/absolutePriceOscillator.ts","../src/momentum/awesomeOscillator.ts","../src/momentum/chaikinOscillator.ts","../src/momentum/commodityChannelIndex.ts","../src/momentum/percentagePriceOscillator.ts","../src/momentum/percentageVolumeOscillator.ts","../src/momentum/priceRateOfChange.ts","../src/momentum/randomIndex.ts","../src/momentum/relativeStrengthIndex.ts","../src/momentum/stochasticOscillator.ts","../src/momentum/williamsR.ts","../src/trend/aroon.ts","../src/trend/balanceOfPower.ts","../src/trend/chandeForecastOscillator.ts","../src/trend/doubleExponentialMovingAverage.ts","../src/trend/exponentialMovingAverage.ts","../src/trend/ichimokuCloud.ts","../src/trend/macd.ts","../src/trend/movingMax.ts","../src/trend/movingMin.ts","../src/trend/movingSum.ts","../src/trend/parabolicSar.ts","../src/trend/qstick.ts","../src/trend/rollingMovingAverage.ts","../src/trend/simpleMovingAverage.ts","../src/trend/sinceChange.ts","../src/trend/triangularMovingAverage.ts","../src/trend/tripleExponentialAverage.ts","../src/trend/tripleExponentialMovingAverage.ts","../src/trend/typicalPrice.ts","../src/trend/volumeWeightedMovingAverage.ts","../src/trend/vortex.ts","../src/volatility/massIndex.ts","../src/volume/accumulationDistribution.ts"],"sourcesContent":["import { fp18 } from '@vulcan-js/core'\n\n/**\n * Create an accumulation/distribution processor.\n *\n * MFM = ((C - L) - (H - C)) / (H - L)\n * MFV = MFM * Volume\n * AD = Previous AD + MFV\n */\nexport function ad(): (h: bigint, l: bigint, c: bigint, v: bigint) => bigint {\n let prevAD = fp18.ZERO\n\n return (h: bigint, l: bigint, c: bigint, v: bigint): bigint => {\n const range = h - l\n // When high equals low, the range is zero and MFM is undefined; treat as 0\n const mfm = range === fp18.ZERO\n ? fp18.ZERO\n : fp18.div((c - l) - (h - c), range)\n const mfv = fp18.mul(mfm, v)\n prevAD += mfv\n return prevAD\n }\n}\n","import { fp18 } from '@vulcan-js/core'\n\n/**\n * Create an exponentially weighted moving average (EWMA) processor.\n *\n * new = value * k + prev * (1 - k)\n *\n * @param k - Smoothing factor as fp18 bigint\n */\nexport function ewma(k: bigint): (value: bigint) => bigint {\n const m = fp18.ONE - k\n let prev: bigint | undefined\n return (value: bigint): bigint => {\n if (prev === undefined) {\n prev = value\n return prev\n }\n prev = (value * k + prev * m) / fp18.SCALE\n return prev\n }\n}\n\n/** Compute EMA smoothing factor: k = 2 / (period + 1) */\newma.k = (period: number): bigint => fp18.div(fp18.TWO, BigInt(1 + period) * fp18.SCALE)\n","import { assert } from '@vulcan-js/core'\n\n/**\n * Create a moving maximum processor.\n *\n * Tracks the maximum value in a sliding window of `period` values.\n */\nexport function mmax(period: number): (value: bigint) => bigint {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: bigint[] = []\n\n return (value: bigint): bigint => {\n buffer.push(value)\n if (buffer.length > period)\n buffer.shift()\n return buffer.reduce((max, cur) => cur > max ? cur : max)\n }\n}\n","import { assert } from '@vulcan-js/core'\n\n/**\n * Create a moving minimum processor.\n *\n * Tracks the minimum value in a sliding window of `period` values.\n */\nexport function mmin(period: number): (value: bigint) => bigint {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: bigint[] = []\n\n return (value: bigint): bigint => {\n buffer.push(value)\n if (buffer.length > period)\n buffer.shift()\n return buffer.reduce((min, cur) => cur < min ? cur : min)\n }\n}\n","import { assert, fp18 } from '@vulcan-js/core'\n\n/**\n * Create a moving sum processor.\n *\n * Uses a ring buffer to maintain a sliding window of `period` values.\n */\nexport function msum(period: number): (value: bigint) => bigint {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: bigint[] = Array.from({ length: period })\n let head = 0\n let count = 0\n let runningSum = fp18.ZERO\n\n return (value: bigint): bigint => {\n if (count < period) {\n buffer[count] = value\n runningSum += value\n count++\n }\n else {\n runningSum = runningSum - buffer[head] + value\n buffer[head] = value\n head = (head + 1) % period\n }\n return runningSum\n }\n}\n","import { assert, fp18 } from '@vulcan-js/core'\n\n/**\n * Create a rolling moving average (RMA) processor.\n *\n * Warm-up: running SMA for the first `period` values.\n * After: R[i] = (R[i-1] * (period - 1) + value) / period\n */\nexport function rma(period: number): (value: bigint) => bigint {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const periodBig = BigInt(period)\n let count = 0\n let sum = fp18.ZERO\n let prev = fp18.ZERO\n\n return (value: bigint): bigint => {\n if (count < period) {\n sum += value\n count++\n prev = sum / BigInt(count)\n return prev\n }\n prev = (prev * (periodBig - 1n) + value) / periodBig\n return prev\n }\n}\n","import { assert, fp18 } from '@vulcan-js/core'\n\n/**\n * Create a simple moving average (SMA) processor.\n *\n * Uses a ring buffer to maintain a sliding window of `period` values.\n * Returns the running average (sum / count) during warm-up.\n */\nexport function sma(period: number): (value: bigint) => bigint {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: bigint[] = Array.from({ length: period })\n let head = 0\n let count = 0\n let runningSum = fp18.ZERO\n\n return (value: bigint): bigint => {\n if (count < period) {\n buffer[count] = value\n runningSum += value\n count++\n }\n else {\n runningSum = runningSum - buffer[head] + value\n buffer[head] = value\n head = (head + 1) % period\n }\n return runningSum / BigInt(count)\n }\n}\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface AbsolutePriceOscillatorOptions {\n fastPeriod: number\n slowPeriod: number\n}\n\nexport const defaultAbsolutePriceOscillatorOptions: AbsolutePriceOscillatorOptions = {\n fastPeriod: 12,\n slowPeriod: 26,\n}\n\nexport const apo = createSignal(\n ({ fastPeriod, slowPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n const fastProc = prim.ewma(prim.ewma.k(fastPeriod))\n const slowProc = prim.ewma(prim.ewma.k(slowPeriod))\n return (value: Numberish) => {\n const v = fp18.toFp18(value)\n return fp18.toDnum(fastProc(v) - slowProc(v))\n }\n },\n defaultAbsolutePriceOscillatorOptions,\n)\n\nexport { apo as absolutePriceOscillator }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface AwesomeOscillatorOptions {\n fastPeriod: number\n slowPeriod: number\n}\n\nexport const defaultAwesomeOscillatorOptions: AwesomeOscillatorOptions = {\n fastPeriod: 5,\n slowPeriod: 34,\n}\n\n/**\n * Awesome Oscillator (AO)\n *\n * AO = SMA(median, fastPeriod) - SMA(median, slowPeriod)\n * Where median = (high + low) / 2\n */\nexport const ao = createSignal(\n ({ fastPeriod, slowPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n const fastProc = prim.sma(fastPeriod)\n const slowProc = prim.sma(slowPeriod)\n return (bar: RequiredProperties<CandleData, 'h' | 'l'>) => {\n const median = (fp18.toFp18(bar.h) + fp18.toFp18(bar.l)) / 2n\n return fp18.toDnum(fastProc(median) - slowProc(median))\n }\n },\n defaultAwesomeOscillatorOptions,\n)\n\nexport { ao as awesomeOscillator }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface ChaikinOscillatorOptions {\n fastPeriod: number\n slowPeriod: number\n}\n\nexport const defaultChaikinOscillatorOptions: ChaikinOscillatorOptions = {\n fastPeriod: 3,\n slowPeriod: 10,\n}\n\n/**\n * The ChaikinOscillator function measures the momentum of the\n * Accumulation/Distribution (A/D) using the Moving Average\n * Convergence Divergence (MACD) formula. It takes the\n * difference between fast and slow periods EMA of the A/D.\n * Cross above the A/D line indicates bullish.\n *\n * CO = Ema(fastPeriod, AD) - Ema(slowPeriod, AD)\n */\nexport const cmo = createSignal(\n ({ fastPeriod, slowPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n const adProc = prim.ad()\n const fastProc = prim.ewma(prim.ewma.k(fastPeriod))\n const slowProc = prim.ewma(prim.ewma.k(slowPeriod))\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c' | 'v'>) => {\n const adVal = adProc(\n fp18.toFp18(bar.h),\n fp18.toFp18(bar.l),\n fp18.toFp18(bar.c),\n fp18.toFp18(bar.v),\n )\n return fp18.toDnum(fastProc(adVal) - slowProc(adVal))\n }\n },\n defaultChaikinOscillatorOptions,\n)\n\nexport { cmo as chaikinOscillator }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\n\nexport interface CommodityChannelIndexOptions {\n /**\n * The period for CCI calculation\n * @default 20\n */\n period: number\n}\n\nexport const defaultCCIOptions: CommodityChannelIndexOptions = {\n period: 20,\n}\n\n// Lambert constant: 0.015 = 15 * SCALE / 1000\nconst LAMBERT = 15n * fp18.SCALE / 1000n\n\n/**\n * Commodity Channel Index (CCI)\n *\n * Developed by Donald Lambert in 1980, CCI measures the deviation of the\n * typical price from its simple moving average, normalized by mean deviation.\n * The constant 0.015 ensures approximately 70-80% of CCI values fall between\n * +100 and -100.\n *\n * Formula:\n * TP = (High + Low + Close) / 3\n * CCI = (TP - SMA(TP, period)) / (0.015 * Mean Deviation)\n * Mean Deviation = SUM(|TP_i - SMA|) / period\n *\n * @param source - Iterable of OHLC candle data\n * @param options - Configuration options\n * @param options.period - The period for CCI calculation (default: 20)\n * @returns Generator yielding CCI values\n */\nexport const cci = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: bigint[] = []\n const periodBig = BigInt(period)\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = fp18.toFp18(bar.h)\n const l = fp18.toFp18(bar.l)\n const c = fp18.toFp18(bar.c)\n const tp = (h + l + c) / 3n\n\n buffer.push(tp)\n if (buffer.length > period)\n buffer.shift()\n\n const n = buffer.length\n if (n < period) {\n return fp18.toDnum(fp18.ZERO)\n }\n\n // SMA and Mean Deviation in a single pass\n let sum = fp18.ZERO\n for (const v of buffer) {\n sum += v\n }\n const smaVal = sum / periodBig\n\n let devSum = fp18.ZERO\n for (const v of buffer) {\n devSum += fp18.abs(v - smaVal)\n }\n const meanDev = devSum / periodBig\n\n if (meanDev === fp18.ZERO) {\n return fp18.toDnum(fp18.ZERO)\n }\n\n const currentTP = buffer[n - 1]\n const numerator = currentTP - smaVal\n // CCI = numerator / (0.015 * meanDev)\n const lambertMeanDev = fp18.mul(LAMBERT, meanDev)\n return fp18.toDnum(fp18.div(numerator, lambertMeanDev))\n }\n },\n defaultCCIOptions,\n)\n\nexport { cci as commodityChannelIndex }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface PercentagePriceOscillatorOptions {\n fastPeriod: number\n slowPeriod: number\n signalPeriod: number\n}\n\nexport const defaultPercentagePriceOscillatorOptions: PercentagePriceOscillatorOptions = {\n fastPeriod: 12,\n slowPeriod: 26,\n signalPeriod: 9,\n}\n\nexport interface PercentagePriceOscillatorPoint {\n ppo: Dnum\n signal: Dnum\n histogram: Dnum\n}\n\n/**\n * Percentage Price Oscillator (PPO)\n *\n * The Percentage Price Oscillator (PPO) is a momentum oscillator that measures the difference\n * between two moving averages as a percentage of the slower moving average. It consists of three components:\n * - PPO Line: ((Fast EMA - Slow EMA) / Slow EMA) * 100\n * - Signal Line: EMA of the PPO line\n * - Histogram: PPO - Signal\n *\n * Formula:\n * - PPO = ((EMA(fastPeriod, prices) - EMA(slowPeriod, prices)) / EMA(slowPeriod, prices)) * 100\n * - Signal = EMA(signalPeriod, PPO)\n * - Histogram = PPO - Signal\n *\n * @param source - Iterable of price values\n * @param options - Configuration options\n * @param options.fastPeriod - Period for the fast EMA (default: 12)\n * @param options.slowPeriod - Period for the slow EMA (default: 26)\n * @param options.signalPeriod - Period for the signal EMA (default: 9)\n * @returns Generator yielding PPO point objects\n */\nexport const ppo = createSignal(\n ({ fastPeriod, slowPeriod, signalPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n assert(Number.isInteger(signalPeriod) && signalPeriod >= 1, new RangeError(`Expected signalPeriod to be a positive integer, got ${signalPeriod}`))\n const fastProc = prim.ewma(prim.ewma.k(fastPeriod))\n const slowProc = prim.ewma(prim.ewma.k(slowPeriod))\n const signalProc = prim.ewma(prim.ewma.k(signalPeriod))\n return (value: Numberish) => {\n const v = fp18.toFp18(value)\n const fast = fastProc(v)\n const slow = slowProc(v)\n const ppoVal = slow === fp18.ZERO ? fp18.ZERO : fp18.div((fast - slow) * 100n, slow)\n const sig = signalProc(ppoVal)\n return { ppo: fp18.toDnum(ppoVal), signal: fp18.toDnum(sig), histogram: fp18.toDnum(ppoVal - sig) }\n }\n },\n defaultPercentagePriceOscillatorOptions,\n)\n\nexport { ppo as percentagePriceOscillator }\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface PercentageVolumeOscillatorOptions {\n fastPeriod: number\n slowPeriod: number\n signalPeriod: number\n}\n\nexport const defaultPercentageVolumeOscillatorOptions: PercentageVolumeOscillatorOptions = {\n fastPeriod: 12,\n slowPeriod: 26,\n signalPeriod: 9,\n}\n\nexport interface PercentageVolumeOscillatorPoint {\n pvo: Dnum\n signal: Dnum\n histogram: Dnum\n}\n\n/**\n * Percentage Volume Oscillator (PVO)\n *\n * The Percentage Volume Oscillator (PVO) is a momentum oscillator that measures the difference\n * between two volume-based moving averages as a percentage of the slower moving average.\n * It consists of three components:\n * - PVO Line: ((Fast EMA - Slow EMA) / Slow EMA) * 100\n * - Signal Line: EMA of the PVO line\n * - Histogram: PVO - Signal\n *\n * The PVO is essentially the same as the Percentage Price Oscillator (PPO), but applied\n * to volume data instead of price data.\n *\n * Formula:\n * - PVO = ((EMA(fastPeriod, volume) - EMA(slowPeriod, volume)) / EMA(slowPeriod, volume)) * 100\n * - Signal = EMA(signalPeriod, PVO)\n * - Histogram = PVO - Signal\n *\n * @param source - Iterable of volume values\n * @param options - Configuration options\n * @param options.fastPeriod - Period for the fast EMA (default: 12)\n * @param options.slowPeriod - Period for the slow EMA (default: 26)\n * @param options.signalPeriod - Period for the signal EMA (default: 9)\n * @returns Generator yielding PVO point objects\n */\nexport const pvo = createSignal(\n ({ fastPeriod, slowPeriod, signalPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n assert(Number.isInteger(signalPeriod) && signalPeriod >= 1, new RangeError(`Expected signalPeriod to be a positive integer, got ${signalPeriod}`))\n const fastProc = prim.ewma(prim.ewma.k(fastPeriod))\n const slowProc = prim.ewma(prim.ewma.k(slowPeriod))\n const signalProc = prim.ewma(prim.ewma.k(signalPeriod))\n return (value: Numberish) => {\n const v = fp18.toFp18(value)\n const fast = fastProc(v)\n const slow = slowProc(v)\n const pvoVal = slow === fp18.ZERO ? fp18.ZERO : fp18.div((fast - slow) * 100n, slow)\n const sig = signalProc(pvoVal)\n return { pvo: fp18.toDnum(pvoVal), signal: fp18.toDnum(sig), histogram: fp18.toDnum(pvoVal - sig) }\n }\n },\n defaultPercentageVolumeOscillatorOptions,\n)\n\nexport { pvo as percentageVolumeOscillator }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\n\nexport interface PriceRateOfChangeOptions {\n period: number\n}\n\nexport const defaultPriceRateOfChangeOptions: PriceRateOfChangeOptions = {\n period: 12,\n}\n\n/**\n * Price Rate of Change (ROC)\n *\n * The Price Rate of Change (ROC) is a momentum oscillator that measures the percentage change\n * in price between the current price and the price n periods ago.\n *\n * Formula:\n * - ROC = ((Current Price - Price n periods ago) / Price n periods ago) * 100\n *\n * @param source - Iterable of price values\n * @param options - Configuration options\n * @param options.period - Number of periods to look back (default: 12)\n * @returns Generator yielding ROC values as Dnum\n */\nexport const roc = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: bigint[] = Array.from({ length: period })\n let head = 0\n let count = 0\n\n return (value: Numberish) => {\n const v = fp18.toFp18(value)\n if (count < period) {\n buffer[count] = v\n count++\n return fp18.toDnum(fp18.ZERO)\n }\n else {\n const oldest = buffer[head]\n buffer[head] = v\n head = (head + 1) % period\n if (oldest === fp18.ZERO)\n return fp18.toDnum(fp18.ZERO)\n return fp18.toDnum(fp18.div((v - oldest) * 100n, oldest))\n }\n }\n },\n defaultPriceRateOfChangeOptions,\n)\n\nexport { roc as priceRateOfChange }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface RandomIndexOptions {\n /**\n * The lookback period for calculating RSV (Raw Stochastic Value)\n * @default 9\n */\n period: number\n /**\n * The smoothing period for K line\n * @default 3\n */\n kPeriod: number\n /**\n * The smoothing period for D line\n * @default 3\n */\n dPeriod: number\n}\n\nexport const defaultRandomIndexOptions: RandomIndexOptions = {\n period: 9,\n kPeriod: 3,\n dPeriod: 3,\n}\n\nexport interface KDJPoint {\n k: Dnum\n d: Dnum\n j: Dnum\n}\n\n/**\n * Random Index (KDJ)\n *\n * An extension of the Stochastic Oscillator that adds a J line to amplify\n * divergence between K and D. Uses exponential-weighted smoothing with\n * initial K and D values set to 50.\n *\n * Formula:\n * RSV = (Close - LowestLow(period)) / (HighestHigh(period) - LowestLow(period)) * 100\n * K = ((kPeriod - 1) / kPeriod) * prevK + (1 / kPeriod) * RSV\n * D = ((dPeriod - 1) / dPeriod) * prevD + (1 / dPeriod) * K\n * J = 3K - 2D\n *\n * Interpretation:\n * - K crossing above D is a bullish signal (golden cross)\n * - K crossing below D is a bearish signal (death cross)\n * - J below 0 indicates oversold, J above 100 indicates overbought\n *\n * @param source - Iterable of candle data with high, low, and close prices\n * @param options - Configuration options\n * @param options.period - The lookback period for RSV calculation (default: 9)\n * @param options.kPeriod - The smoothing period for K line (default: 3)\n * @param options.dPeriod - The smoothing period for D line (default: 3)\n * @returns Generator yielding KDJPoint values with k, d, and j as Dnum\n */\nexport const kdj = createSignal(\n ({ period, kPeriod, dPeriod }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n assert(Number.isInteger(kPeriod) && kPeriod >= 1, new RangeError(`Expected kPeriod to be a positive integer, got ${kPeriod}`))\n assert(Number.isInteger(dPeriod) && dPeriod >= 1, new RangeError(`Expected dPeriod to be a positive integer, got ${dPeriod}`))\n\n const mmaxProc = prim.mmax(period)\n const mminProc = prim.mmin(period)\n\n const INITIAL = 50n * fp18.SCALE\n const kPeriodBig = BigInt(kPeriod)\n const dPeriodBig = BigInt(dPeriod)\n\n let prevK = INITIAL\n let prevD = INITIAL\n let isFirst = true\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = fp18.toFp18(bar.h)\n const l = fp18.toFp18(bar.l)\n const c = fp18.toFp18(bar.c)\n\n const highestHigh = mmaxProc(h)\n const lowestLow = mminProc(l)\n\n const range = highestHigh - lowestLow\n const rsv = range === fp18.ZERO ? fp18.ZERO : fp18.div((c - lowestLow) * 100n, range)\n\n let k: bigint\n let d: bigint\n\n if (isFirst) {\n k = INITIAL * (kPeriodBig - 1n) / kPeriodBig + rsv / kPeriodBig\n d = INITIAL * (dPeriodBig - 1n) / dPeriodBig + k / dPeriodBig\n isFirst = false\n }\n else {\n k = prevK * (kPeriodBig - 1n) / kPeriodBig + rsv / kPeriodBig\n d = prevD * (dPeriodBig - 1n) / dPeriodBig + k / dPeriodBig\n }\n\n const j = k * 3n - d * 2n\n\n prevK = k\n prevD = d\n\n return { k: fp18.toDnum(k), d: fp18.toDnum(d), j: fp18.toDnum(j) }\n }\n },\n defaultRandomIndexOptions,\n)\n\nexport { kdj as randomIndex }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface RSIOptions {\n period: number\n}\n\nexport const defaultRSIOptions: RSIOptions = {\n period: 14,\n}\n\n/**\n * Relative Strength Index (RSI). It is a momentum indicator that measures the magnitude of\n * recent price changes to evaluate overbought and oversold conditions\n * using the given window period.\n *\n * RS = Average Gain / Average Loss\n *\n * RSI = 100 - (100 / (1 + RS))\n */\nexport const rsi = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const gainProc = prim.rma(period)\n const lossProc = prim.rma(period)\n let prev: bigint | undefined\n\n return (value: Numberish) => {\n const price = fp18.toFp18(value)\n\n if (prev === undefined) {\n prev = price\n gainProc(fp18.ZERO)\n lossProc(fp18.ZERO)\n return fp18.toDnum(fp18.ZERO)\n }\n\n const change = price - prev\n prev = price\n\n const gain = change > fp18.ZERO ? change : fp18.ZERO\n const loss = change > fp18.ZERO ? fp18.ZERO : -change\n\n const avgGain = gainProc(gain)\n const avgLoss = lossProc(loss)\n\n if (avgLoss === fp18.ZERO) {\n return fp18.toDnum(fp18.HUNDRED)\n }\n\n const rs = fp18.div(avgGain, avgLoss)\n return fp18.toDnum(fp18.HUNDRED - fp18.div(fp18.HUNDRED, fp18.ONE + rs))\n }\n },\n defaultRSIOptions,\n)\n\nexport { rsi as relativeStrengthIndex }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface StochasticOscillatorOptions {\n /** The %k period */\n kPeriod: number\n /** The %k slowing period */\n slowingPeriod: number\n /** The %d period */\n dPeriod: number\n}\n\nexport const defaultStochasticOscillatorOptions: StochasticOscillatorOptions = {\n kPeriod: 14,\n slowingPeriod: 1,\n dPeriod: 3,\n}\n\nexport interface StochPoint {\n k: Dnum\n d: Dnum\n}\n\n/**\n * Stochastic Oscillator\n *\n * %K = ((Close - Lowest Low) / (Highest High - Lowest Low)) * 100\n * %D = SMA(%K, dPeriod)\n */\nexport const stoch = createSignal(\n ({ kPeriod, slowingPeriod, dPeriod }) => {\n assert(Number.isInteger(kPeriod) && kPeriod >= 1, new RangeError(`Expected kPeriod to be a positive integer, got ${kPeriod}`))\n assert(Number.isInteger(slowingPeriod) && slowingPeriod >= 1, new RangeError(`Expected slowingPeriod to be a positive integer, got ${slowingPeriod}`))\n assert(Number.isInteger(dPeriod) && dPeriod >= 1, new RangeError(`Expected dPeriod to be a positive integer, got ${dPeriod}`))\n const mmaxProc = prim.mmax(kPeriod)\n const mminProc = prim.mmin(kPeriod)\n const slowingProc = slowingPeriod > 1 ? prim.sma(slowingPeriod) : null\n const dProc = prim.sma(dPeriod)\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = fp18.toFp18(bar.h)\n const l = fp18.toFp18(bar.l)\n const c = fp18.toFp18(bar.c)\n\n const highestHigh = mmaxProc(h)\n const lowestLow = mminProc(l)\n\n const range = highestHigh - lowestLow\n const rawK = range === fp18.ZERO ? fp18.ZERO : fp18.div((c - lowestLow) * 100n, range)\n const k = slowingProc ? slowingProc(rawK) : rawK\n const d = dProc(k)\n return { k: fp18.toDnum(k), d: fp18.toDnum(d) }\n }\n },\n defaultStochasticOscillatorOptions,\n)\n\nexport { stoch as stochasticOscillator }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface WilliamsROptions {\n /** Lookback period */\n period: number\n}\n\nexport const defaultWilliamsROptions: WilliamsROptions = {\n period: 14,\n}\n\n/**\n * Williams %R (WILLR)\n *\n * A momentum indicator that measures overbought and oversold conditions.\n * It shows the relationship between the closing price and the highest high / lowest low\n * over a specified period.\n *\n * Formula:\n * - %R = -100 * (Highest High - Close) / (Highest High - Lowest Low)\n *\n * Range: -100 to 0\n * - Above -20: Overbought\n * - Below -80: Oversold\n *\n * @param source - Iterable of candle data with high, low, and close\n * @param options - Configuration options\n * @param options.period - Lookback period (default: 14)\n * @returns Generator yielding Williams %R values as Dnum\n */\nexport const willr = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const mmaxProc = prim.mmax(period)\n const mminProc = prim.mmin(period)\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = fp18.toFp18(bar.h)\n const l = fp18.toFp18(bar.l)\n const c = fp18.toFp18(bar.c)\n\n const highestHigh = mmaxProc(h)\n const lowestLow = mminProc(l)\n\n const range = highestHigh - lowestLow\n if (range === fp18.ZERO)\n return fp18.toDnum(fp18.ZERO)\n return fp18.toDnum(fp18.div((highestHigh - c) * -100n, range))\n }\n },\n defaultWilliamsROptions,\n)\n\nexport { willr as williamsR }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\n\nexport interface AroonOptions {\n period: number\n}\n\nexport const defaultAroonOptions: AroonOptions = {\n period: 25,\n}\n\nexport interface AroonPoint {\n up: Dnum\n down: Dnum\n oscillator: Dnum\n}\n\n/**\n * Aroon Indicator\n *\n * Aroon Up = ((period - days since highest high) / period) * 100\n * Aroon Down = ((period - days since lowest low) / period) * 100\n * Oscillator = Aroon Up - Aroon Down\n */\nexport const aroon = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const highBuffer: bigint[] = []\n const lowBuffer: bigint[] = []\n const periodBig = BigInt(period)\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l'>) => {\n const h = fp18.toFp18(bar.h)\n const l = fp18.toFp18(bar.l)\n\n highBuffer.push(h)\n lowBuffer.push(l)\n if (highBuffer.length > period + 1)\n highBuffer.shift()\n if (lowBuffer.length > period + 1)\n lowBuffer.shift()\n\n let highestIdx = 0\n let lowestIdx = 0\n for (let j = 1; j < highBuffer.length; j++) {\n if (highBuffer[j] >= highBuffer[highestIdx])\n highestIdx = j\n if (lowBuffer[j] <= lowBuffer[lowestIdx])\n lowestIdx = j\n }\n\n const daysSinceHigh = highBuffer.length - 1 - highestIdx\n const daysSinceLow = lowBuffer.length - 1 - lowestIdx\n\n const up = BigInt(period - daysSinceHigh) * fp18.HUNDRED / periodBig\n const down = BigInt(period - daysSinceLow) * fp18.HUNDRED / periodBig\n\n return {\n up: fp18.toDnum(up),\n down: fp18.toDnum(down),\n oscillator: fp18.toDnum(up - down),\n }\n }\n },\n defaultAroonOptions,\n)\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { createSignal, fp18 } from '@vulcan-js/core'\n\nexport const bop = createSignal(\n () => {\n return (bar: RequiredProperties<CandleData, 'o' | 'h' | 'l' | 'c'>) => {\n const o = fp18.toFp18(bar.o)\n const h = fp18.toFp18(bar.h)\n const l = fp18.toFp18(bar.l)\n const c = fp18.toFp18(bar.c)\n const range = h - l\n if (range === fp18.ZERO) {\n return fp18.toDnum(fp18.ZERO)\n }\n return fp18.toDnum(fp18.div(c - o, range))\n }\n },\n)\n\nexport { bop as balanceOfPower }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\n\nexport interface ChandeForecastOscillatorOptions {\n /**\n * The period for linear regression\n * @default 14\n */\n period: number\n}\n\nexport const defaultCFOOptions: ChandeForecastOscillatorOptions = {\n period: 14,\n}\n\n/**\n * Chande Forecast Oscillator (CFO)\n *\n * Measures the percentage difference between the actual close price and the\n * n-period linear regression forecast price. Positive values indicate bullish\n * momentum (price above forecast), negative values indicate bearish momentum.\n *\n * Formula: CFO = ((Close - Forecast) / Close) * 100\n * Where: Forecast = Linear regression value at current point\n *\n * @param source - Iterable of price values\n * @param options - Configuration options\n * @param options.period - The period for linear regression (default: 14)\n * @returns Generator yielding CFO values as percentages\n */\nexport const cfo = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const buffer: bigint[] = []\n\n return (value: Numberish) => {\n buffer.push(fp18.toFp18(value))\n if (buffer.length > period)\n buffer.shift()\n\n const n = buffer.length\n if (n < 2) {\n return fp18.toDnum(fp18.ZERO)\n }\n\n // Precompute X-related sums as plain integers\n const xSum = BigInt(n * (n + 1) / 2)\n const x2Sum = BigInt(n * (n + 1) * (2 * n + 1) / 6)\n const denom = BigInt(n) * x2Sum - xSum * xSum\n\n // Compute Y-dependent sums\n let sumY = fp18.ZERO\n let sumXY = fp18.ZERO\n for (let i = 0; i < n; i++) {\n sumY += buffer[i]\n sumXY += buffer[i] * BigInt(i + 1)\n }\n\n // slope = (n * SUM(XY) - SUM(X) * SUM(Y)) / denom\n const num = sumXY * BigInt(n) - sumY * xSum\n const slope = num / denom\n\n // intercept = (SUM(Y) - slope * SUM(X)) / n\n const intercept = (sumY - slope * xSum) / BigInt(n)\n\n // forecast = slope * n + intercept\n const forecast = slope * BigInt(n) + intercept\n\n const close = buffer[n - 1]\n if (close === fp18.ZERO) {\n return fp18.toDnum(fp18.ZERO)\n }\n\n return fp18.toDnum(fp18.div((close - forecast) * 100n, close))\n }\n },\n defaultCFOOptions,\n)\n\nexport { cfo as chandeForecastOscillator }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface DoubleExponentialMovingAverageOptions {\n period: number\n}\n\nexport const defaultDoubleExponentialMovingAverageOptions: DoubleExponentialMovingAverageOptions = {\n period: 12,\n}\n\n/**\n * Double Exponential Moving Average (DEMA)\n *\n * DEMA reduces lag compared to a traditional EMA by applying the formula:\n * DEMA = 2 * EMA(data, period) - EMA(EMA(data, period), period)\n *\n * @param source - Iterable of input values\n * @param options - Configuration options\n * @param options.period - The lookback period (default: 12)\n * @returns Generator yielding DEMA values\n */\nexport const dema = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const ema1 = prim.ewma(prim.ewma.k(period))\n const ema2 = prim.ewma(prim.ewma.k(period))\n return (value: Numberish) => {\n const e1 = ema1(fp18.toFp18(value))\n const e2 = ema2(e1)\n return fp18.toDnum(e1 * 2n - e2)\n }\n },\n defaultDoubleExponentialMovingAverageOptions,\n)\n\nexport { dema as doubleExponentialMovingAverage }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface ExponentialMovingAverageOptions {\n period: number\n}\n\nexport const defaultExponentialMovingAverageOptions: ExponentialMovingAverageOptions = {\n period: 12,\n}\n\n/**\n * Exponential Moving Average (EMA)\n *\n * EMA = Price * k + PrevEMA * (1 - k)\n * Where k = 2 / (period + 1)\n */\nexport const ema = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const proc = prim.ewma(prim.ewma.k(period))\n return (value: Numberish) => fp18.toDnum(proc(fp18.toFp18(value)))\n },\n defaultExponentialMovingAverageOptions,\n)\n\nexport { ema as exponentialMovingAverage }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface IchimokuCloudOptions {\n /** Conversion line period */\n conversionPeriod: number\n /** Base line period */\n basePeriod: number\n /** Leading span B period */\n leadingBPeriod: number\n}\n\nexport const defaultIchimokuCloudOptions: IchimokuCloudOptions = {\n conversionPeriod: 9,\n basePeriod: 26,\n leadingBPeriod: 52,\n}\n\nexport interface IchimokuCloudPoint {\n conversion: Dnum\n base: Dnum\n leadingA: Dnum\n leadingB: Dnum\n lagging: Dnum\n}\n\n/**\n * Ichimoku Cloud (Ichimoku Kinko Hyo)\n *\n * Computes raw values for each component. Displacement (shifting\n * Leading Spans forward and Lagging Span backward on the chart)\n * is a presentation concern left to the consumer.\n *\n * - Conversion (Tenkan-sen): (highest high + lowest low) / 2 over conversionPeriod\n * - Base (Kijun-sen): (highest high + lowest low) / 2 over basePeriod\n * - Leading Span A (Senkou A): (conversion + base) / 2\n * - Leading Span B (Senkou B): (highest high + lowest low) / 2 over leadingBPeriod\n * - Lagging (Chikou): current close price\n */\nexport const ichimokuCloud = createSignal(\n ({ conversionPeriod, basePeriod, leadingBPeriod }) => {\n assert(Number.isInteger(conversionPeriod) && conversionPeriod >= 1, new RangeError(`Expected conversionPeriod to be a positive integer, got ${conversionPeriod}`))\n assert(Number.isInteger(basePeriod) && basePeriod >= 1, new RangeError(`Expected basePeriod to be a positive integer, got ${basePeriod}`))\n assert(Number.isInteger(leadingBPeriod) && leadingBPeriod >= 1, new RangeError(`Expected leadingBPeriod to be a positive integer, got ${leadingBPeriod}`))\n const convHighProc = prim.mmax(conversionPeriod)\n const convLowProc = prim.mmin(conversionPeriod)\n const baseHighProc = prim.mmax(basePeriod)\n const baseLowProc = prim.mmin(basePeriod)\n const leadBHighProc = prim.mmax(leadingBPeriod)\n const leadBLowProc = prim.mmin(leadingBPeriod)\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = fp18.toFp18(bar.h)\n const l = fp18.toFp18(bar.l)\n\n const conversion = (convHighProc(h) + convLowProc(l)) / 2n\n const base = (baseHighProc(h) + baseLowProc(l)) / 2n\n const leadingA = (conversion + base) / 2n\n const leadingB = (leadBHighProc(h) + leadBLowProc(l)) / 2n\n\n return {\n conversion: fp18.toDnum(conversion),\n base: fp18.toDnum(base),\n leadingA: fp18.toDnum(leadingA),\n leadingB: fp18.toDnum(leadingB),\n lagging: fp18.toDnum(fp18.toFp18(bar.c)),\n }\n }\n },\n defaultIchimokuCloudOptions,\n)\n","import type { Dnum, Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface MACDOptions {\n fastPeriod: number\n slowPeriod: number\n signalPeriod: number\n}\n\nexport const defaultMACDOptions: MACDOptions = {\n fastPeriod: 12,\n slowPeriod: 26,\n signalPeriod: 9,\n}\n\nexport interface MACDPoint {\n macd: Dnum\n signal: Dnum\n histogram: Dnum\n}\n\n/**\n * Moving Average Convergence Divergence (MACD)\n *\n * MACD is a trend-following momentum indicator that shows the relationship\n * between two exponential moving averages of prices. It consists of three components:\n * - MACD Line: Fast EMA - Slow EMA\n * - Signal Line: EMA of the MACD line\n * - Histogram: MACD - Signal\n *\n * Formula:\n * - MACD = EMA(fastPeriod, prices) - EMA(slowPeriod, prices)\n * - Signal = EMA(signalPeriod, MACD)\n * - Histogram = MACD - Signal\n *\n * @param source - Iterable of price values\n * @param options - Configuration options\n * @param options.fastPeriod - Period for the fast EMA (default: 12)\n * @param options.slowPeriod - Period for the slow EMA (default: 26)\n * @param options.signalPeriod - Period for the signal EMA (default: 9)\n * @returns Generator yielding MACDPoint objects\n */\nexport const macd = createSignal(\n ({ fastPeriod, slowPeriod, signalPeriod }) => {\n assert(Number.isInteger(fastPeriod) && fastPeriod >= 1, new RangeError(`Expected fastPeriod to be a positive integer, got ${fastPeriod}`))\n assert(Number.isInteger(slowPeriod) && slowPeriod >= 1, new RangeError(`Expected slowPeriod to be a positive integer, got ${slowPeriod}`))\n assert(Number.isInteger(signalPeriod) && signalPeriod >= 1, new RangeError(`Expected signalPeriod to be a positive integer, got ${signalPeriod}`))\n const fastProc = prim.ewma(prim.ewma.k(fastPeriod))\n const slowProc = prim.ewma(prim.ewma.k(slowPeriod))\n const signalProc = prim.ewma(prim.ewma.k(signalPeriod))\n return (value: Numberish) => {\n const v = fp18.toFp18(value)\n const fast = fastProc(v)\n const slow = slowProc(v)\n const m = fast - slow\n const sig = signalProc(m)\n return { macd: fp18.toDnum(m), signal: fp18.toDnum(sig), histogram: fp18.toDnum(m - sig) }\n }\n },\n defaultMACDOptions,\n)\n\nexport { macd as movingAverageConvergenceDivergence }\n","import type { Numberish } from 'dnum'\nimport { createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface MovingMaxOptions {\n /**\n * period\n */\n period: number\n}\n\nexport const defaultMovingMaxOptions: MovingMaxOptions = {\n period: 4,\n}\n\n/**\n * Moving Maximum (MovingMax)\n */\nexport const mmax = createSignal(\n ({ period }) => {\n const proc = prim.mmax(period)\n return (value: Numberish) => fp18.toDnum(proc(fp18.toFp18(value)))\n },\n defaultMovingMaxOptions,\n)\n\nexport { mmax as movingMax }\n","import type { Numberish } from 'dnum'\nimport { createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface MovingMinOptions {\n /**\n * period\n */\n period: number\n}\n\nexport const defaultMovingMinOptions: MovingMinOptions = {\n period: 4,\n}\n\n/**\n * Moving Minimum (MovingMin)\n */\nexport const mmin = createSignal(\n ({ period }) => {\n const proc = prim.mmin(period)\n return (value: Numberish) => fp18.toDnum(proc(fp18.toFp18(value)))\n },\n defaultMovingMinOptions,\n)\n\nexport { mmin as movingMin }\n","import type { Numberish } from 'dnum'\nimport { createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface MovingSumOptions {\n period: number\n}\n\nexport const defaultMovingSumOptions: MovingSumOptions = {\n period: 4,\n}\n\n/**\n * Moving Sum\n *\n * Calculates the sum of values in a sliding window of the specified period.\n */\nexport const msum = createSignal(\n ({ period }) => {\n const proc = prim.msum(period)\n return (value: Numberish) => fp18.toDnum(proc(fp18.toFp18(value)))\n },\n defaultMovingSumOptions,\n)\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\n\nexport interface ParabolicSarOptions {\n start: number\n increment: number\n max: number\n}\n\nexport const defaultParabolicSarOptions: ParabolicSarOptions = {\n start: 0.02,\n increment: 0.02,\n max: 0.2,\n}\n\nexport interface PSARPoint {\n psar: Dnum\n isUptrend: boolean\n}\n\n/**\n * Parabolic SAR (Stop and Reverse)\n *\n * Developed by J. Welles Wilder Jr. in 1978, the Parabolic SAR is a\n * trend-following indicator that provides potential entry and exit points.\n * It appears as a series of dots above or below the price, indicating\n * the current trend direction and potential reversal points.\n *\n * Formula:\n * SAR_new = SAR_prev + AF * (EP - SAR_prev)\n *\n * Where:\n * AF = Acceleration Factor (starts at `start`, increments by `increment`\n * on each new EP, capped at `max`)\n * EP = Extreme Point (highest high in uptrend, lowest low in downtrend)\n *\n * The SAR is clamped to not exceed the two prior bars' price range.\n * A reversal occurs when price penetrates the SAR level.\n *\n * @param source - Iterable of candle data with high and low prices\n * @param options - Configuration options\n * @param options.start - Initial acceleration factor (default: 0.02)\n * @param options.increment - AF increment per new extreme (default: 0.02)\n * @param options.max - Maximum acceleration factor (default: 0.2)\n * @returns Generator yielding PSARPoint objects with `psar` value and `isUptrend` flag\n */\nexport const psar = createSignal(\n ({ start, increment, max }) => {\n assert(start > 0, new RangeError(`Expected start to be positive, got ${start}`))\n assert(increment > 0, new RangeError(`Expected increment to be positive, got ${increment}`))\n assert(max > 0 && max >= start, new RangeError(`Expected max to be positive and >= start, got ${max}`))\n\n let count = 0\n let isUptrend = true\n let sar: bigint\n let ep: bigint\n let af: bigint\n let prevHigh: bigint\n let prevLow: bigint\n let prevPrevHigh: bigint\n let prevPrevLow: bigint\n\n const afStart = fp18.toFp18(start)\n const afIncrement = fp18.toFp18(increment)\n const afMax = fp18.toFp18(max)\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l'>) => {\n const h = fp18.toFp18(bar.h)\n const l = fp18.toFp18(bar.l)\n count++\n\n // Bar 1: initialization\n if (count === 1) {\n isUptrend = true\n sar = l\n ep = h\n af = afStart\n prevHigh = h\n prevLow = l\n prevPrevHigh = h\n prevPrevLow = l\n return { psar: fp18.toDnum(sar), isUptrend }\n }\n\n // Bar 2: determine initial trend\n if (count === 2) {\n if (h > prevHigh) {\n isUptrend = true\n sar = prevLow\n ep = h\n }\n else {\n isUptrend = false\n sar = prevHigh\n ep = l\n }\n af = afStart\n prevPrevHigh = prevHigh\n prevPrevLow = prevLow\n prevHigh = h\n prevLow = l\n return { psar: fp18.toDnum(sar), isUptrend }\n }\n\n // Bar 3+: standard computation\n // Step A: calculate next SAR\n let nextSar = sar + fp18.mul(af, ep - sar)\n\n // Step B: clamp SAR\n if (isUptrend) {\n if (nextSar > prevLow)\n nextSar = prevLow\n if (nextSar > prevPrevLow)\n nextSar = prevPrevLow\n }\n else {\n if (nextSar < prevHigh)\n nextSar = prevHigh\n if (nextSar < prevPrevHigh)\n nextSar = prevPrevHigh\n }\n\n sar = nextSar\n\n // Step C: check for reversal\n let reversed = false\n if (isUptrend && l < sar) {\n isUptrend = false\n sar = ep\n ep = l\n af = afStart\n reversed = true\n }\n else if (!isUptrend && h > sar) {\n isUptrend = true\n sar = ep\n ep = h\n af = afStart\n reversed = true\n }\n\n // Step D: update EP and AF (only if no reversal)\n if (!reversed) {\n if (isUptrend && h > ep) {\n ep = h\n const newAf = af + afIncrement\n af = newAf > afMax ? afMax : newAf\n }\n else if (!isUptrend && l < ep) {\n ep = l\n const newAf = af + afIncrement\n af = newAf > afMax ? afMax : newAf\n }\n }\n\n // Step E: update prev tracking\n prevPrevHigh = prevHigh\n prevPrevLow = prevLow\n prevHigh = h\n prevLow = l\n\n return { psar: fp18.toDnum(sar), isUptrend }\n }\n },\n defaultParabolicSarOptions,\n)\n\nexport { psar as parabolicSar }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\n\nexport interface QstickOptions {\n /**\n * The period for calculating the moving average of (Close - Open)\n * @default 14\n */\n period: number\n}\n\nexport const defaultQstickOptions: QstickOptions = {\n period: 14,\n}\n\n/**\n * Qstick Indicator\n *\n * Developed by Tushar Chande, the Qstick indicator measures the average\n * difference between closing and opening prices over a specified period.\n * It quantifies buying and selling pressure using a simple moving average\n * of (Close - Open).\n *\n * Formula: Qstick = SMA(Close - Open, period)\n *\n * Interpretation:\n * - Positive values indicate buying pressure (closes above opens)\n * - Negative values indicate selling pressure (closes below opens)\n * - Zero-line crossovers can signal trend changes\n *\n * @param source - Iterable of candle data with open and close prices\n * @param options - Configuration options\n * @param options.period - The period for the SMA calculation (default: 14)\n * @returns Generator yielding Qstick values as Dnum\n */\nexport const qstick = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n\n const buffer: bigint[] = Array.from({ length: period })\n let head = 0\n let count = 0\n let runningSum = fp18.ZERO\n\n return (bar: RequiredProperties<CandleData, 'o' | 'c'>) => {\n const diff = fp18.toFp18(bar.c) - fp18.toFp18(bar.o)\n\n if (count < period) {\n buffer[count] = diff\n runningSum += diff\n count++\n }\n else {\n runningSum = runningSum - buffer[head] + diff\n buffer[head] = diff\n head = (head + 1) % period\n }\n\n return fp18.toDnum(runningSum / BigInt(count))\n }\n },\n defaultQstickOptions,\n)\n\nexport { qstick as qstickIndicator }\n","import type { Numberish } from 'dnum'\nimport { createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface RMAOptions {\n /**\n * period\n */\n period: number\n}\n\nexport const defaultRMAOptions: RMAOptions = {\n period: 4,\n}\n\n/**\n * Rolling moving average (RMA).\n *\n * R[0] to R[p-1] is SMA(values)\n *\n * R[p] and after is R[i] = ((R[i-1]*(p-1)) + v[i]) / p\n */\nexport const rma = createSignal(\n ({ period }) => {\n const proc = prim.rma(period)\n return (value: Numberish) => fp18.toDnum(proc(fp18.toFp18(value)))\n },\n defaultRMAOptions,\n)\n\nexport { rma as rollingMovingAverage }\n","import type { Numberish } from 'dnum'\nimport { createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface SimpleMovingAverageOptions {\n /**\n * The period for calculating the moving average\n * @default 2\n */\n period: number\n}\n\nexport const defaultSMAOptions: SimpleMovingAverageOptions = {\n period: 2,\n}\n\n/**\n * Simple Moving Average (SMA)\n *\n * Calculates the arithmetic mean of a set of values over a specified period.\n * The SMA is calculated by summing all values in the period and dividing by the period length.\n *\n * Formula: SMA = (P1 + P2 + ... + Pn) / n\n * Where: P = Price values, n = Period\n *\n * @param source - Iterable of price values\n * @param options - Configuration options\n * @param options.period - The period for calculating the moving average (default: 2)\n * @returns Generator yielding SMA values\n */\nexport const sma = createSignal(\n ({ period }) => {\n const proc = prim.sma(period)\n return (value: Numberish) => fp18.toDnum(proc(fp18.toFp18(value)))\n },\n defaultSMAOptions,\n)\n\nexport { sma as simpleMovingAverage }\n","import type { Numberish } from 'dnum'\nimport { createSignal, fp18 } from '@vulcan-js/core'\n\n/**\n * Since Change\n *\n * Counts the number of periods since the input value last changed.\n * When the value changes, the counter resets to 0. When the value\n * remains the same, the counter increments by 1 each period.\n *\n * Example:\n * Input: [1, 1, 1, 2, 2, 3, 3, 3, 3]\n * Output: [0, 1, 2, 0, 1, 0, 1, 2, 3]\n *\n * @param source - Iterable of values\n * @returns Generator yielding the number of periods since the last change\n */\nexport const since = createSignal(\n () => {\n let last: bigint | undefined\n let count = fp18.ZERO\n\n return (value: Numberish) => {\n const v = fp18.toFp18(value)\n\n if (last === undefined || last !== v) {\n last = v\n count = fp18.ZERO\n }\n else {\n count += fp18.ONE\n }\n\n return fp18.toDnum(count)\n }\n },\n)\n\nexport { since as sinceChange }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface TriangularMovingAverageOptions {\n period: number\n}\n\nexport const defaultTriangularMovingAverageOptions: TriangularMovingAverageOptions = {\n period: 4,\n}\n\nexport const trima = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n let n1: number\n let n2: number\n\n if (period % 2 === 0) {\n n1 = period / 2\n n2 = n1 + 1\n }\n else {\n n1 = (period + 1) / 2\n n2 = n1\n }\n\n const sma1 = prim.sma(n2)\n const sma2 = prim.sma(n1)\n\n return (value: Numberish) => {\n const s1 = sma1(fp18.toFp18(value))\n return fp18.toDnum(sma2(s1))\n }\n },\n defaultTriangularMovingAverageOptions,\n)\n\nexport { trima as triangularMovingAverage }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface TripleExponentialAverageOptions {\n period: number\n}\n\nexport const defaultTripleExponentialAverageOptions: TripleExponentialAverageOptions = {\n period: 15,\n}\n\n/**\n * Triple Exponential Average (TRIX)\n *\n * TRIX is a momentum oscillator that displays the percentage rate of change\n * of a triple exponentially smoothed moving average. It oscillates around zero,\n * filtering out insignificant price movements.\n *\n * TRIX = (EMA3_current - EMA3_previous) / EMA3_previous * 100\n *\n * Where EMA3 = EMA(EMA(EMA(source, period), period), period)\n *\n * @param source - Iterable of input values\n * @param options - Configuration options\n * @param options.period - The lookback period (default: 15)\n * @returns Generator yielding TRIX values as percentages\n */\nexport const trix = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const ema1 = prim.ewma(prim.ewma.k(period))\n const ema2 = prim.ewma(prim.ewma.k(period))\n const ema3 = prim.ewma(prim.ewma.k(period))\n let prevEma3: bigint | null = null\n return (value: Numberish) => {\n const e1 = ema1(fp18.toFp18(value))\n const e2 = ema2(e1)\n const e3 = ema3(e2)\n if (prevEma3 === null) {\n prevEma3 = e3\n return fp18.toDnum(fp18.ZERO)\n }\n const result = fp18.div((e3 - prevEma3) * 100n, prevEma3)\n prevEma3 = e3\n return fp18.toDnum(result)\n }\n },\n defaultTripleExponentialAverageOptions,\n)\n\nexport { trix as tripleExponentialAverage }\n","import type { Numberish } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface TripleExponentialMovingAverageOptions {\n period: number\n}\n\nexport const defaultTripleExponentialMovingAverageOptions: TripleExponentialMovingAverageOptions = {\n period: 12,\n}\n\n/**\n * Triple Exponential Moving Average (TEMA)\n *\n * TEMA further reduces lag compared to DEMA by applying the formula:\n * TEMA = 3 * EMA(data, period) - 3 * EMA(EMA(data, period), period) + EMA(EMA(EMA(data, period), period), period)\n *\n * @param source - Iterable of input values\n * @param options - Configuration options\n * @param options.period - The lookback period (default: 12)\n * @returns Generator yielding TEMA values\n */\nexport const tema = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n const ema1 = prim.ewma(prim.ewma.k(period))\n const ema2 = prim.ewma(prim.ewma.k(period))\n const ema3 = prim.ewma(prim.ewma.k(period))\n return (value: Numberish) => {\n const e1 = ema1(fp18.toFp18(value))\n const e2 = ema2(e1)\n const e3 = ema3(e2)\n // TEMA = 3 * EMA1 - 3 * EMA2 + EMA3\n return fp18.toDnum(e1 * 3n - e2 * 3n + e3)\n }\n },\n defaultTripleExponentialMovingAverageOptions,\n)\n\nexport { tema as tripleExponentialMovingAverage }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { createSignal, fp18 } from '@vulcan-js/core'\n\n/**\n * Typical Price\n *\n * The Typical Price is a simple average of the high, low, and close prices\n * for a given period. It provides a single representative price for each bar\n * and is commonly used as input for other indicators such as CCI and MFI.\n *\n * Formula: Typical Price = (High + Low + Close) / 3\n *\n * @param source - Iterable of candle data with high, low, and close prices\n * @returns Generator yielding Typical Price values as Dnum\n */\nexport const typicalPrice = createSignal(\n () => {\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = fp18.toFp18(bar.h)\n const l = fp18.toFp18(bar.l)\n const c = fp18.toFp18(bar.c)\n\n return fp18.toDnum((h + l + c) / 3n)\n }\n },\n)\n\nexport { typicalPrice as typicalPriceIndicator }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\n\nexport interface VwmaOptions {\n /**\n * The number of periods for calculating the volume weighted moving average\n * @default 20\n */\n period: number\n}\n\nexport const defaultVwmaOptions: VwmaOptions = {\n period: 20,\n}\n\n/**\n * Volume Weighted Moving Average (VWMA)\n *\n * VWMA weights each price by its corresponding volume, giving more\n * influence to prices with higher trading activity. It is useful for\n * confirming trends and identifying divergences between price and volume.\n *\n * Formula: VWMA = Sum(Close * Volume, period) / Sum(Volume, period)\n *\n * Interpretation:\n * - When VWMA is below price, it suggests bullish sentiment (higher volume at higher prices)\n * - When VWMA is above price, it suggests bearish sentiment (higher volume at lower prices)\n * - Crossovers with SMA can signal volume-confirmed trend changes\n *\n * @param source - Iterable of candle data with close price and volume\n * @param options - Configuration options\n * @param options.period - The number of periods (default: 20)\n * @returns Generator yielding VWMA values as Dnum\n */\nexport const vwma = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n\n const pvBuffer: bigint[] = Array.from({ length: period })\n const vBuffer: bigint[] = Array.from({ length: period })\n let head = 0\n let count = 0\n let pvSum = fp18.ZERO\n let vSum = fp18.ZERO\n\n return (bar: RequiredProperties<CandleData, 'c' | 'v'>) => {\n const close = fp18.toFp18(bar.c)\n const volume = fp18.toFp18(bar.v)\n const pv = fp18.mul(close, volume)\n\n if (count < period) {\n pvBuffer[count] = pv\n vBuffer[count] = volume\n pvSum += pv\n vSum += volume\n count++\n }\n else {\n pvSum -= pvBuffer[head]\n vSum -= vBuffer[head]\n pvBuffer[head] = pv\n vBuffer[head] = volume\n pvSum += pv\n vSum += volume\n head = (head + 1) % period\n }\n\n return fp18.toDnum(fp18.div(pvSum, vSum))\n }\n },\n defaultVwmaOptions,\n)\n\nexport { vwma as volumeWeightedMovingAverage }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport type { Dnum } from 'dnum'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\n\nexport interface VortexOptions {\n period: number\n}\n\nexport const defaultVortexOptions: VortexOptions = {\n period: 14,\n}\n\nexport interface VortexPoint {\n plus: Dnum\n minus: Dnum\n}\n\n/**\n * Vortex Indicator (VI)\n *\n * Identifies trend direction and potential reversals using two oscillating lines (VI+ and VI-).\n *\n * VM+(i) = |High(i) - Low(i-1)|\n * VM-(i) = |Low(i) - High(i-1)|\n * TR(i) = max(High(i) - Low(i), |High(i) - Close(i-1)|, |Low(i) - Close(i-1)|)\n * VI+ = SUM(VM+, period) / SUM(TR, period)\n * VI- = SUM(VM-, period) / SUM(TR, period)\n */\nexport const vortex = createSignal(\n ({ period }) => {\n assert(Number.isInteger(period) && period >= 1, new RangeError(`Expected period to be a positive integer, got ${period}`))\n\n const vmPlusBuffer: bigint[] = Array.from({ length: period })\n const vmMinusBuffer: bigint[] = Array.from({ length: period })\n const trBuffer: bigint[] = Array.from({ length: period })\n\n let head = 0\n let count = 0\n let sumVmPlus = fp18.ZERO\n let sumVmMinus = fp18.ZERO\n let sumTr = fp18.ZERO\n\n let prevHigh: bigint | null = null\n let prevLow: bigint | null = null\n let prevClose: bigint | null = null\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c'>) => {\n const h = fp18.toFp18(bar.h)\n const l = fp18.toFp18(bar.l)\n const c = fp18.toFp18(bar.c)\n\n if (prevHigh === null || prevLow === null || prevClose === null) {\n prevHigh = h\n prevLow = l\n prevClose = c\n return { plus: fp18.toDnum(fp18.ZERO), minus: fp18.toDnum(fp18.ZERO) }\n }\n\n const vmPlus = fp18.abs(h - prevLow)\n const vmMinus = fp18.abs(l - prevHigh)\n\n const hl = h - l\n const hpc = fp18.abs(h - prevClose)\n const lpc = fp18.abs(l - prevClose)\n let tr = hl\n if (hpc > tr)\n tr = hpc\n if (lpc > tr)\n tr = lpc\n\n if (count < period) {\n vmPlusBuffer[count] = vmPlus\n vmMinusBuffer[count] = vmMinus\n trBuffer[count] = tr\n sumVmPlus += vmPlus\n sumVmMinus += vmMinus\n sumTr += tr\n count++\n }\n else {\n sumVmPlus = sumVmPlus - vmPlusBuffer[head] + vmPlus\n sumVmMinus = sumVmMinus - vmMinusBuffer[head] + vmMinus\n sumTr = sumTr - trBuffer[head] + tr\n vmPlusBuffer[head] = vmPlus\n vmMinusBuffer[head] = vmMinus\n trBuffer[head] = tr\n head = (head + 1) % period\n }\n\n prevHigh = h\n prevLow = l\n prevClose = c\n\n return {\n plus: fp18.toDnum(fp18.div(sumVmPlus, sumTr)),\n minus: fp18.toDnum(fp18.div(sumVmMinus, sumTr)),\n }\n }\n },\n defaultVortexOptions,\n)\n\nexport { vortex as vortexIndicator }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { assert, createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\nexport interface MassIndexOptions {\n /**\n * The period for EMA smoothing of the high-low range\n * @default 9\n */\n emaPeriod: number\n /**\n * The period for the moving sum of the EMA ratio\n * @default 25\n */\n miPeriod: number\n}\n\nexport const defaultMassIndexOptions: MassIndexOptions = {\n emaPeriod: 9,\n miPeriod: 25,\n}\n\n/**\n * Mass Index (MI)\n *\n * Developed by Donald Dorsey, the Mass Index uses the high-low range\n * to identify trend reversals based on range expansions. A \"reversal bulge\"\n * occurs when the Mass Index rises above 27 and then falls below 26.5.\n *\n * Formula:\n * Range = High - Low\n * EMA1 = EMA(Range, emaPeriod)\n * EMA2 = EMA(EMA1, emaPeriod)\n * Ratio = EMA1 / EMA2\n * MI = MovingSum(Ratio, miPeriod)\n *\n * @param source - Iterable of OHLC candle data (requires high and low)\n * @param options - Configuration options\n * @param options.emaPeriod - The EMA smoothing period (default: 9)\n * @param options.miPeriod - The moving sum period (default: 25)\n * @returns Generator yielding Mass Index values\n */\nexport const mi = createSignal(\n ({ emaPeriod, miPeriod }) => {\n assert(Number.isInteger(emaPeriod) && emaPeriod >= 1, new RangeError(`Expected emaPeriod to be a positive integer, got ${emaPeriod}`))\n assert(Number.isInteger(miPeriod) && miPeriod >= 1, new RangeError(`Expected miPeriod to be a positive integer, got ${miPeriod}`))\n const ema1Proc = prim.ewma(prim.ewma.k(emaPeriod))\n const ema2Proc = prim.ewma(prim.ewma.k(emaPeriod))\n const msumProc = prim.msum(miPeriod)\n\n return (bar: RequiredProperties<CandleData, 'h' | 'l'>) => {\n const range = fp18.toFp18(bar.h) - fp18.toFp18(bar.l)\n const e1 = ema1Proc(range)\n const e2 = ema2Proc(e1)\n const ratio = fp18.div(e1, e2)\n return fp18.toDnum(msumProc(ratio))\n }\n },\n defaultMassIndexOptions,\n)\n\nexport { mi as massIndex }\n","import type { CandleData, RequiredProperties } from '@vulcan-js/core'\nimport { createSignal, fp18 } from '@vulcan-js/core'\nimport * as prim from '../primitives'\n\n/**\n * Accumulation/Distribution Indicator (A/D). Cumulative indicator\n * that uses volume and price to assess whether a stock is\n * being accumulated or distributed.\n *\n * MFM = ((Closing - Low) - (High - Closing)) / (High - Low)\n * MFV = MFM * Period Volume\n * AD = Previous AD + CMFV\n */\nexport const ad = createSignal(\n () => {\n const proc = prim.ad()\n return (bar: RequiredProperties<CandleData, 'h' | 'l' | 'c' | 'v'>) => {\n return fp18.toDnum(proc(\n fp18.toFp18(bar.h),\n fp18.toFp18(bar.l),\n fp18.toFp18(bar.c),\n fp18.toFp18(bar.v),\n ))\n }\n },\n)\n\nexport { ad as accumulationDistribution }\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vulcan-js/indicators",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.2.0",
5
5
  "description": "Technical analysis indicators with generator-based streaming and high-precision arithmetic",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -30,7 +30,7 @@
30
30
  ],
31
31
  "dependencies": {
32
32
  "dnum": "^2.17.0",
33
- "@vulcan-js/core": "^0.1.0"
33
+ "@vulcan-js/core": "^0.2.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "defu": "^6.1.4",