Add Hurst Bands indicator with buy/sell signal markers

This commit is contained in:
DiTus
2026-03-03 08:36:26 +01:00
parent 9d7647fde5
commit cf1aca8855
5 changed files with 259 additions and 3 deletions

View File

@ -163,6 +163,36 @@ function findCrossoverMarkers(indicator, candles, results) {
text: sellShape === 'custom' ? sellCustom : ''
});
}
} else if (indicatorType === 'hurst') {
const upper = result.upper;
const lower = result.lower;
const prevUpper = prevResult?.upper;
const prevLower = prevResult?.lower;
if (upper === undefined || lower === undefined ||
prevUpper === undefined || prevLower === undefined) continue;
// BUY: price crosses down below lower band (was above, now below)
if (prevCandle.close > prevLower && candle.close < lower) {
markers.push({
time: candle.time,
position: 'belowBar',
color: buyColor,
shape: buyShape === 'custom' ? '' : buyShape,
text: buyShape === 'custom' ? buyCustom : ''
});
}
// SELL: price crosses down below upper band (was above, now below)
if (prevCandle.close > prevUpper && candle.close < upper) {
markers.push({
time: candle.time,
position: 'aboveBar',
color: sellColor,
shape: sellShape === 'custom' ? '' : sellShape,
text: sellShape === 'custom' ? sellCustom : ''
});
}
} else {
const ma = result.ma ?? result;
const prevMa = prevResult.ma ?? prevResult;

View File

@ -143,6 +143,28 @@ function calculateHistoricalCrossovers(activeIndicators, candles) {
lastSignalType = 'buy';
break;
}
} else if (indicatorType === 'hurst') {
// Hurst Bands: check price crossing bands
const upper = result.upper;
const lower = result.lower;
const prevUpper = prevResult.upper;
const prevLower = prevResult.lower;
if (upper === undefined || lower === undefined ||
prevUpper === undefined || prevLower === undefined) continue;
// BUY: price crossed down below lower band
if (prevCandle.close > prevLower && candle.close < lower) {
lastCrossoverTimestamp = candle.time;
lastSignalType = 'buy';
break;
}
// SELL: price crossed down below upper band
if (prevCandle.close > prevUpper && candle.close < upper) {
lastCrossoverTimestamp = candle.time;
lastSignalType = 'sell';
break;
}
} else {
// MA-style: check price crossing MA
const ma = result.ma !== undefined ? result.ma : result;
@ -188,6 +210,21 @@ function calculateHistoricalCrossovers(activeIndicators, candles) {
indicator.lastSignalType = rsi > overbought ? 'sell' : (rsi < oversold ? 'buy' : null);
indicator.lastSignalTimestamp = lastCandleTime;
}
} else if (indicatorType === 'hurst') {
// Hurst Bands: use price vs bands
const upper = lastResult?.upper;
const lower = lastResult?.lower;
const currentPrice = candles[candles.length - 1]?.close;
if (upper !== undefined && lower !== undefined && currentPrice !== undefined) {
if (currentPrice < lower) {
indicator.lastSignalType = 'buy';
} else if (currentPrice > upper) {
indicator.lastSignalType = 'sell';
} else {
indicator.lastSignalType = null;
}
indicator.lastSignalTimestamp = lastCandleTime;
}
} else {
// MA-style: use price vs MA
const ma = lastResult?.ma !== undefined ? lastResult.ma : lastResult;