From 3ffec846dc01233220564770f4c2260ae487900f Mon Sep 17 00:00:00 2001 From: DiTus Date: Mon, 2 Mar 2026 09:09:20 +0100 Subject: [PATCH] added RSI crossover detection in historical crossovers for timestamp --- .../static/js/ui/signals-calculator.js | 90 +++++++++++++------ 1 file changed, 63 insertions(+), 27 deletions(-) diff --git a/src/api/dashboard/static/js/ui/signals-calculator.js b/src/api/dashboard/static/js/ui/signals-calculator.js index 018f174..711dd3d 100644 --- a/src/api/dashboard/static/js/ui/signals-calculator.js +++ b/src/api/dashboard/static/js/ui/signals-calculator.js @@ -110,6 +110,10 @@ function calculateHistoricalCrossovers(activeIndicators, candles) { let lastCrossoverTimestamp = null; let lastSignalType = null; + // Get indicator-specific parameters + const overbought = indicator.params?.overbought || 70; + const oversold = indicator.params?.oversold || 30; + for (let i = candles.length - 1; i > 0; i--) { const candle = candles[i]; // newer candle const prevCandle = candles[i-1]; // older candle @@ -119,27 +123,49 @@ function calculateHistoricalCrossovers(activeIndicators, candles) { if (!result || !prevResult) continue; - // Get MA value (handle both object and number formats) - const ma = result.ma !== undefined ? result.ma : result; - const prevMa = prevResult.ma !== undefined ? prevResult.ma : prevResult; - - if (ma === undefined || prevMa === undefined) continue; - - // Check crossover: price was on one side of MA, now on the other side - const priceAbovePrev = prevCandle.close > prevMa; - const priceAboveNow = candle.close > ma; - - // SELL signal: price crossed from above to below MA - if (priceAbovePrev && !priceAboveNow) { - lastCrossoverTimestamp = candle.time; - lastSignalType = 'sell'; - break; - } - // BUY signal: price crossed from below to above MA - if (!priceAbovePrev && priceAboveNow) { - lastCrossoverTimestamp = candle.time; - lastSignalType = 'buy'; - break; + // Handle different indicator types + if (indicatorType === 'rsi' || indicatorType === 'stoch') { + // RSI/Stochastic: check crossing overbought/oversold levels + const rsi = result.rsi !== undefined ? result.rsi : result; + const prevRsi = prevResult.rsi !== undefined ? prevResult.rsi : prevResult; + + if (rsi === undefined || prevRsi === undefined) continue; + + // SELL: crossed down through overbought (was above, now below) + if (prevRsi > overbought && rsi <= overbought) { + lastCrossoverTimestamp = candle.time; + lastSignalType = 'sell'; + break; + } + // BUY: crossed up through oversold (was below, now above) + if (prevRsi < oversold && rsi >= oversold) { + lastCrossoverTimestamp = candle.time; + lastSignalType = 'buy'; + break; + } + } else { + // MA-style: check price crossing MA + const ma = result.ma !== undefined ? result.ma : result; + const prevMa = prevResult.ma !== undefined ? prevResult.ma : prevResult; + + if (ma === undefined || prevMa === undefined) continue; + + // Check crossover: price was on one side of MA, now on the other side + const priceAbovePrev = prevCandle.close > prevMa; + const priceAboveNow = candle.close > ma; + + // SELL signal: price crossed from above to below MA + if (priceAbovePrev && !priceAboveNow) { + lastCrossoverTimestamp = candle.time; + lastSignalType = 'sell'; + break; + } + // BUY signal: price crossed from below to above MA + if (!priceAbovePrev && priceAboveNow) { + lastCrossoverTimestamp = candle.time; + lastSignalType = 'buy'; + break; + } } } @@ -153,13 +179,23 @@ function calculateHistoricalCrossovers(activeIndicators, candles) { // No crossover found - use last candle time const lastCandleTime = candles[candles.length - 1]?.time; if (lastCandleTime) { - // Determine current signal direction const lastResult = results[results.length - 1]; - const ma = lastResult?.ma !== undefined ? lastResult.ma : lastResult; - if (ma !== undefined) { - const isAbove = candles[candles.length - 1].close > ma; - indicator.lastSignalType = isAbove ? 'buy' : 'sell'; - indicator.lastSignalTimestamp = lastCandleTime; + + if (indicatorType === 'rsi' || indicatorType === 'stoch') { + // RSI/Stochastic: use RSI level to determine signal + const rsi = lastResult?.rsi !== undefined ? lastResult.rsi : lastResult; + if (rsi !== undefined) { + indicator.lastSignalType = rsi > overbought ? 'sell' : (rsi < oversold ? 'buy' : null); + indicator.lastSignalTimestamp = lastCandleTime; + } + } else { + // MA-style: use price vs MA + const ma = lastResult?.ma !== undefined ? lastResult.ma : lastResult; + if (ma !== undefined) { + const isAbove = candles[candles.length - 1].close > ma; + indicator.lastSignalType = isAbove ? 'buy' : 'sell'; + indicator.lastSignalTimestamp = lastCandleTime; + } } } }