added more functions

This commit is contained in:
Bojan Kucera 2025-06-04 19:27:11 -04:00
parent a53d8d13ca
commit a1c82ae0b8
7 changed files with 648 additions and 177 deletions

View file

@ -497,3 +497,151 @@ export function aroon(ohlcv: OHLCVData[], period: number = 14): { up: number[],
return { up, down };
}
/**
* Average Directional Movement Index (ADX) and Directional Movement Indicators (DMI)
*/
export function adx(ohlcv: OHLCVData[], period: number = 14): { adx: number[], plusDI: number[], minusDI: number[] } {
if (period >= ohlcv.length) return { adx: [], plusDI: [], minusDI: [] };
const trueRanges: number[] = [];
const plusDM: number[] = [];
const minusDM: number[] = [];
// Calculate True Range and Directional Movements
for (let i = 1; i < ohlcv.length; i++) {
const current = ohlcv[i];
const previous = ohlcv[i - 1];
// True Range
const tr = Math.max(
current.high - current.low,
Math.abs(current.high - previous.close),
Math.abs(current.low - previous.close)
);
trueRanges.push(tr);
// Directional Movements
const highDiff = current.high - previous.high;
const lowDiff = previous.low - current.low;
const plusDMValue = (highDiff > lowDiff && highDiff > 0) ? highDiff : 0;
const minusDMValue = (lowDiff > highDiff && lowDiff > 0) ? lowDiff : 0;
plusDM.push(plusDMValue);
minusDM.push(minusDMValue);
}
// Calculate smoothed averages
const atrValues = sma(trueRanges, period);
const smoothedPlusDM = sma(plusDM, period);
const smoothedMinusDM = sma(minusDM, period);
const plusDI: number[] = [];
const minusDI: number[] = [];
const dx: number[] = [];
// Calculate DI+ and DI-
for (let i = 0; i < atrValues.length; i++) {
const diPlus = atrValues[i] > 0 ? (smoothedPlusDM[i] / atrValues[i]) * 100 : 0;
const diMinus = atrValues[i] > 0 ? (smoothedMinusDM[i] / atrValues[i]) * 100 : 0;
plusDI.push(diPlus);
minusDI.push(diMinus);
// Calculate DX
const diSum = diPlus + diMinus;
const dxValue = diSum > 0 ? (Math.abs(diPlus - diMinus) / diSum) * 100 : 0;
dx.push(dxValue);
}
// Calculate ADX (smoothed DX)
const adxValues = sma(dx, period);
return {
adx: adxValues,
plusDI: plusDI.slice(period - 1),
minusDI: minusDI.slice(period - 1)
};
}
/**
* Volume Weighted Moving Average (VWMA)
*/
export function vwma(ohlcv: OHLCVData[], period: number = 20): number[] {
if (period >= ohlcv.length) return [];
const result: number[] = [];
for (let i = period - 1; i < ohlcv.length; i++) {
const slice = ohlcv.slice(i - period + 1, i + 1);
let totalVolumePrice = 0;
let totalVolume = 0;
for (const candle of slice) {
const typicalPrice = (candle.high + candle.low + candle.close) / 3;
totalVolumePrice += typicalPrice * candle.volume;
totalVolume += candle.volume;
}
const vwmaValue = totalVolume > 0 ? totalVolumePrice / totalVolume : 0;
result.push(vwmaValue);
}
return result;
}
/**
* Pivot Points (Standard)
*/
export function pivotPoints(ohlcv: OHLCVData[]): Array<{
pivot: number;
resistance1: number;
resistance2: number;
resistance3: number;
support1: number;
support2: number;
support3: number;
}> {
if (ohlcv.length === 0) return [];
const result: Array<{
pivot: number;
resistance1: number;
resistance2: number;
resistance3: number;
support1: number;
support2: number;
support3: number;
}> = [];
for (let i = 0; i < ohlcv.length; i++) {
const candle = ohlcv[i];
// Calculate pivot point
const pivot = (candle.high + candle.low + candle.close) / 3;
// Calculate resistance and support levels
const resistance1 = (2 * pivot) - candle.low;
const support1 = (2 * pivot) - candle.high;
const resistance2 = pivot + (candle.high - candle.low);
const support2 = pivot - (candle.high - candle.low);
const resistance3 = candle.high + 2 * (pivot - candle.low);
const support3 = candle.low - 2 * (candle.high - pivot);
result.push({
pivot,
resistance1,
resistance2,
resistance3,
support1,
support2,
support3
});
}
return result;
}