UNPKG

stock-indicator

Version:

Stock Indicator Library

64 lines (57 loc) 1.6 kB
import { TMixed, checkArrayOfNumbers, checkNumber, funRound, funSMA, } from "../common"; /** * - KDJ 随机指标 * @param {number[]} CLOSE - 收盘价序列 * @param {number[]} HIGH - 最高价序列 * @param {number[]} LOW - 最低价序列 * @param {number} N - 周期,default: 9 * @param {number} M1 - 平滑参数,default: 3 * @param {number} M2 - 平滑参数,default: 3 * @returns {{ K: TMixed[]; D: TMixed[]; J: TMixed[] }} */ export function KDJ( CLOSE: number[], HIGH: number[], LOW: number[], N: number = 9, M1: number = 3, M2: number = 3 ): { K: TMixed[]; D: TMixed[]; J: TMixed[] } { // - check input parameters checkArrayOfNumbers(CLOSE, "CLOSE"); checkArrayOfNumbers(HIGH, "HIGH"); checkArrayOfNumbers(LOW, "LOW"); checkNumber(N, 1, CLOSE, "N", "CLOSE"); checkNumber(M1, 1, N, "M1", "N"); checkNumber(M2, 1, N, "M2", "N"); // - calculate KDJ const llv = LOW.reduce((prev: number[], cur, i) => { return [ ...prev, Math.min(...LOW.slice(Math.max(0, i - N + 1), i + 1).map((v) => v ?? 0)), ]; }, []); const hhv = HIGH.reduce((prev: number[], cur, i) => { return [ ...prev, Math.max(...HIGH.slice(Math.max(0, i - N + 1), i + 1).map((v) => v ?? 0)), ]; }, []); const RSV = CLOSE.map( (v, i) => (((v ?? 0) - llv[i]) / (hhv[i] - llv[i])) * 100 ); const K = funSMA(RSV, M1, 1); const D = funSMA(K, M2, 1); const J = K.map((v, i) => funRound(3 * (v ?? 0) - 2 * (D[i] ?? 0), 3)); return { K: K.map((v) => funRound(v, 3)), D: D.map((v) => funRound(v, 3)), J, }; }