added more functions

This commit is contained in:
Bojan Kucera 2025-06-04 20:01:39 -04:00
parent a1c82ae0b8
commit cca9ac03dd
8 changed files with 1563 additions and 2 deletions

View file

@ -645,3 +645,196 @@ export function pivotPoints(ohlcv: OHLCVData[]): Array<{
return result;
}
/**
* Ichimoku Cloud
*/
export function ichimokuCloud(
ohlcv: OHLCVData[],
tenkanSenPeriod: number = 9,
kijunSenPeriod: number = 26,
senkouSpanBPeriod: number = 52
): {
tenkanSen: number[];
kijunSen: number[];
senkouSpanA: number[];
senkouSpanB: number[];
chikouSpan: number[];
} {
const { high, low, close } = {
high: ohlcv.map(item => item.high),
low: ohlcv.map(item => item.low),
close: ohlcv.map(item => item.close)
};
const tenkanSen = calculateTenkanSen(high, low, tenkanSenPeriod);
const kijunSen = calculateKijunSen(high, low, kijunSenPeriod);
const senkouSpanA = calculateSenkouSpanA(tenkanSen, kijunSen);
const senkouSpanB = calculateSenkouSpanB(high, low, senkouSpanBPeriod);
const chikouSpan = calculateChikouSpan(close, kijunSenPeriod);
return {
tenkanSen,
kijunSen,
senkouSpanA,
senkouSpanB,
chikouSpan
};
function calculateTenkanSen(high: number[], low: number[], period: number): number[] {
const tenkanSen: number[] = [];
for (let i = period - 1; i < high.length; i++) {
const sliceHigh = high.slice(i - period + 1, i + 1);
const sliceLow = low.slice(i - period + 1, i + 1);
const highestHigh = Math.max(...sliceHigh);
const lowestLow = Math.min(...sliceLow);
tenkanSen.push((highestHigh + lowestLow) / 2);
}
return tenkanSen;
}
function calculateKijunSen(high: number[], low: number[], period: number): number[] {
const kijunSen: number[] = [];
for (let i = period - 1; i < high.length; i++) {
const sliceHigh = high.slice(i - period + 1, i + 1);
const sliceLow = low.slice(i - period + 1, i + 1);
const highestHigh = Math.max(...sliceHigh);
const lowestLow = Math.min(...sliceLow);
kijunSen.push((highestHigh + lowestLow) / 2);
}
return kijunSen;
}
function calculateSenkouSpanA(tenkanSen: number[], kijunSen: number[]): number[] {
const senkouSpanA: number[] = [];
for (let i = 0; i < tenkanSen.length; i++) {
senkouSpanA.push((tenkanSen[i] + kijunSen[i]) / 2);
}
return senkouSpanA;
}
function calculateSenkouSpanB(high: number[], low: number[], period: number): number[] {
const senkouSpanB: number[] = [];
for (let i = period - 1; i < high.length; i++) {
const sliceHigh = high.slice(i - period + 1, i + 1);
const sliceLow = low.slice(i - period + 1, i + 1);
const highestHigh = Math.max(...sliceHigh);
const lowestLow = Math.min(...sliceLow);
senkouSpanB.push((highestHigh + lowestLow) / 2);
}
return senkouSpanB;
}
function calculateChikouSpan(close: number[], period: number): number[] {
const chikouSpan: number[] = [];
for (let i = 0; i < close.length - period; i++) {
chikouSpan.push(close[i]);
}
return chikouSpan;
}
}
/**
* Keltner Channels
*/
export function keltnerChannels(
ohlcv: OHLCVData[],
period: number = 20,
multiplier: number = 2
): {
upper: number[];
middle: number[];
lower: number[];
} {
const atrValues = atr(ohlcv, period);
const middle = sma(ohlcv.map(item => (item.high + item.low + item.close) / 3), period);
const upper: number[] = [];
const lower: number[] = [];
for (let i = 0; i < middle.length; i++) {
upper.push(middle[i] + multiplier * atrValues[i]);
lower.push(middle[i] - multiplier * atrValues[i]);
}
return {
upper,
middle,
lower
};
}
/**
* Donchian Channels
*/
export function donchianChannels(
ohlcv: OHLCVData[],
period: number = 20
): {
upper: number[];
middle: number[];
lower: number[];
} {
const upper: number[] = [];
const lower: number[] = [];
const middle: number[] = [];
for (let i = period - 1; i < ohlcv.length; i++) {
const slice = ohlcv.slice(i - period + 1, i + 1);
const highestHigh = Math.max(...slice.map(item => item.high));
const lowestLow = Math.min(...slice.map(item => item.low));
upper.push(highestHigh);
lower.push(lowestLow);
middle.push((highestHigh + lowestLow) / 2);
}
return {
upper,
middle,
lower
};
}
/**
* Elder-Ray Index
*/
export function elderRay(
ohlcv: OHLCVData[],
period: number = 13
): {
bullPower: number[];
bearPower: number[];
} {
const emaValues = ema(ohlcv.map(item => item.close), period);
const bullPower: number[] = [];
const bearPower: number[] = [];
for (let i = period - 1; i < ohlcv.length; i++) {
bullPower.push(ohlcv[i].high - emaValues[i - period + 1]);
bearPower.push(ohlcv[i].low - emaValues[i - period + 1]);
}
return {
bullPower,
bearPower
};
}
/**
* Force Index
*/
export function forceIndex(
ohlcv: OHLCVData[],
period: number = 13
): number[] {
const forceIndexValues: number[] = [];
for (let i = 1; i < ohlcv.length; i++) {
const change = ohlcv[i].close - ohlcv[i - 1].close;
const volume = ohlcv[i].volume;
forceIndexValues.push(change * volume);
}
const smaValues = sma(forceIndexValues, period);
return smaValues;
}