stock-indicator
Version:
Stock Indicator Library
65 lines (60 loc) • 1.25 kB
text/typescript
import {
aEqB,
aGtB,
checkArrayOfNumbers,
checkNumber,
funMA,
funRound,
TMixed,
} from "../common";
/**
*
* @param CLOSE
* @param VOL
* @param M
* @returns
* 传入的VOL 单位为股,需要转换为手
*/
export function OBV(
CLOSE: number[],
VOL: number[],
M: number = 30
): {
OBV: TMixed[];
MAOBV: TMixed[];
[key: string]: TMixed[];
} {
// check input data
checkArrayOfNumbers(CLOSE, "CLOSE");
checkArrayOfNumbers(VOL, "VOL");
checkNumber(M, 2, CLOSE, "M", "CLOSE");
VOL = VOL.map((v) => v / 100);
// calculate OBV and MAOBV
// VA:=IF(CLOSE>REF(CLOSE,1),VOL,-VOL);
const VA = [
null,
...CLOSE.slice(1).map((v, i) =>
aGtB(v, CLOSE[i]) ? VOL[i + 1] : -VOL[i + 1]
),
];
// OBV:SUM(IF(CLOSE=REF(CLOSE,1),0,VA),0);
const OBV: TMixed[] = [
null,
...CLOSE.slice(1).map((v, i) => {
return aEqB(v, CLOSE[i]) ? 0 : VA[i + 1];
}),
].reduce((acc: TMixed[], cur, i) => {
if (i === 0) {
acc.push(null);
return acc;
}
acc.push((cur ?? 0) + (acc[i - 1] ?? 0));
return acc;
}, []);
// MAOBV:MA(OBV,M);
const MAOBV = funMA(OBV, M).map((v) => funRound(v, 3));
return {
OBV: OBV.map((v) => funRound(v, 3)),
MAOBV,
};
}