feat: ADX-Trendstärke-Filter (fix 20, nicht im Grid) gegen Chop-Whipsaw
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
44
src/server/indicators/adx.ts
Normal file
44
src/server/indicators/adx.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import type { Candle } from '../types';
|
||||
|
||||
/** Wilder ADX: +DM/−DM → Wilder-geglättet → DI± → DX → ADX. NaN vor Index 2×period−1. */
|
||||
export function adx(candles: Candle[], period: number): number[] {
|
||||
const n = candles.length;
|
||||
const out = new Array<number>(n).fill(NaN);
|
||||
if (n < 2 * period) return out;
|
||||
const plusDM = [0];
|
||||
const minusDM = [0];
|
||||
const tr = [candles[0].high - candles[0].low];
|
||||
for (let i = 1; i < n; i++) {
|
||||
const up = candles[i].high - candles[i - 1].high;
|
||||
const down = candles[i - 1].low - candles[i].low;
|
||||
plusDM.push(up > down && up > 0 ? up : 0);
|
||||
minusDM.push(down > up && down > 0 ? down : 0);
|
||||
tr.push(Math.max(
|
||||
candles[i].high - candles[i].low,
|
||||
Math.abs(candles[i].high - candles[i - 1].close),
|
||||
Math.abs(candles[i].low - candles[i - 1].close),
|
||||
));
|
||||
}
|
||||
let sTR = 0, sPlus = 0, sMinus = 0;
|
||||
for (let i = 1; i <= period; i++) { sTR += tr[i]; sPlus += plusDM[i]; sMinus += minusDM[i]; }
|
||||
const dx = new Array<number>(n).fill(NaN);
|
||||
const computeDx = () => {
|
||||
if (sTR === 0) return 0; // völlig flacher Markt
|
||||
const plusDI = (100 * sPlus) / sTR;
|
||||
const minusDI = (100 * sMinus) / sTR;
|
||||
const sum = plusDI + minusDI;
|
||||
return sum === 0 ? 0 : (100 * Math.abs(plusDI - minusDI)) / sum;
|
||||
};
|
||||
dx[period] = computeDx();
|
||||
for (let i = period + 1; i < n; i++) {
|
||||
sTR = sTR - sTR / period + tr[i];
|
||||
sPlus = sPlus - sPlus / period + plusDM[i];
|
||||
sMinus = sMinus - sMinus / period + minusDM[i];
|
||||
dx[i] = computeDx();
|
||||
}
|
||||
let sum = 0;
|
||||
for (let i = period; i < 2 * period; i++) sum += dx[i];
|
||||
out[2 * period - 1] = sum / period;
|
||||
for (let i = 2 * period; i < n; i++) out[i] = (out[i - 1] * (period - 1) + dx[i]) / period;
|
||||
return out;
|
||||
}
|
||||
Reference in New Issue
Block a user