typescript
import { computeEmaSeries } from "./computeEma";
import { computeSmaSeries } from "./computeSma";
export type MaCrossSignal =
| "neutral"
| "bullish"
| "bearish"
| "bullish-cross"
| "bearish-cross";
export type MaCrossResult = {
fast: number;
slow: number;
signal: MaCrossSignal;
};
export function computeMaCross(
values: number[],
type: "sma" | "ema",
fastPeriod: number,
slowPeriod: number
): MaCrossResult | null {
if (values.length < slowPeriod) return null;
const fastSeries =
type === "ema"
? computeEmaSeries(values, fastPeriod)
: computeSmaSeries(values, fastPeriod);
const slowSeries =
type === "ema"
? computeEmaSeries(values, slowPeriod)
: computeSmaSeries(values, slowPeriod);
if (fastSeries.length === 0 || slowSeries.length === 0) return null;
const offset = fastSeries.length - slowSeries.length;
if (offset < 0) return null;
const lastIndex = slowSeries.length - 1;
const fastNow = fastSeries[lastIndex + offset];
const slowNow = slowSeries[lastIndex];
const prevIndex = lastIndex - 1;
const fastPrev = prevIndex >= 0 ? fastSeries[prevIndex + offset] : null;
const slowPrev = prevIndex >= 0 ? slowSeries[prevIndex] : null;
let signal: MaCrossSignal = "neutral";
if (fastPrev != null && slowPrev != null) {
if (fastPrev <= slowPrev && fastNow > slowNow) {
signal = "bullish-cross";
} else if (fastPrev >= slowPrev && fastNow < slowNow) {
signal = "bearish-cross";
} else if (fastNow > slowNow) {
signal = "bullish";
} else if (fastNow < slowNow) {
signal = "bearish";
}
} else if (fastNow > slowNow) {
signal = "bullish";
} else if (fastNow < slowNow) {
signal = "bearish";
}
return { fast: fastNow, slow: slowNow, signal };
}