added RSI crossover detection in historical crossovers for timestamp
This commit is contained in:
@ -110,6 +110,10 @@ function calculateHistoricalCrossovers(activeIndicators, candles) {
|
|||||||
let lastCrossoverTimestamp = null;
|
let lastCrossoverTimestamp = null;
|
||||||
let lastSignalType = 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--) {
|
for (let i = candles.length - 1; i > 0; i--) {
|
||||||
const candle = candles[i]; // newer candle
|
const candle = candles[i]; // newer candle
|
||||||
const prevCandle = candles[i-1]; // older candle
|
const prevCandle = candles[i-1]; // older candle
|
||||||
@ -119,27 +123,49 @@ function calculateHistoricalCrossovers(activeIndicators, candles) {
|
|||||||
|
|
||||||
if (!result || !prevResult) continue;
|
if (!result || !prevResult) continue;
|
||||||
|
|
||||||
// Get MA value (handle both object and number formats)
|
// Handle different indicator types
|
||||||
const ma = result.ma !== undefined ? result.ma : result;
|
if (indicatorType === 'rsi' || indicatorType === 'stoch') {
|
||||||
const prevMa = prevResult.ma !== undefined ? prevResult.ma : prevResult;
|
// RSI/Stochastic: check crossing overbought/oversold levels
|
||||||
|
const rsi = result.rsi !== undefined ? result.rsi : result;
|
||||||
if (ma === undefined || prevMa === undefined) continue;
|
const prevRsi = prevResult.rsi !== undefined ? prevResult.rsi : prevResult;
|
||||||
|
|
||||||
// Check crossover: price was on one side of MA, now on the other side
|
if (rsi === undefined || prevRsi === undefined) continue;
|
||||||
const priceAbovePrev = prevCandle.close > prevMa;
|
|
||||||
const priceAboveNow = candle.close > ma;
|
// SELL: crossed down through overbought (was above, now below)
|
||||||
|
if (prevRsi > overbought && rsi <= overbought) {
|
||||||
// SELL signal: price crossed from above to below MA
|
lastCrossoverTimestamp = candle.time;
|
||||||
if (priceAbovePrev && !priceAboveNow) {
|
lastSignalType = 'sell';
|
||||||
lastCrossoverTimestamp = candle.time;
|
break;
|
||||||
lastSignalType = 'sell';
|
}
|
||||||
break;
|
// BUY: crossed up through oversold (was below, now above)
|
||||||
}
|
if (prevRsi < oversold && rsi >= oversold) {
|
||||||
// BUY signal: price crossed from below to above MA
|
lastCrossoverTimestamp = candle.time;
|
||||||
if (!priceAbovePrev && priceAboveNow) {
|
lastSignalType = 'buy';
|
||||||
lastCrossoverTimestamp = candle.time;
|
break;
|
||||||
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
|
// No crossover found - use last candle time
|
||||||
const lastCandleTime = candles[candles.length - 1]?.time;
|
const lastCandleTime = candles[candles.length - 1]?.time;
|
||||||
if (lastCandleTime) {
|
if (lastCandleTime) {
|
||||||
// Determine current signal direction
|
|
||||||
const lastResult = results[results.length - 1];
|
const lastResult = results[results.length - 1];
|
||||||
const ma = lastResult?.ma !== undefined ? lastResult.ma : lastResult;
|
|
||||||
if (ma !== undefined) {
|
if (indicatorType === 'rsi' || indicatorType === 'stoch') {
|
||||||
const isAbove = candles[candles.length - 1].close > ma;
|
// RSI/Stochastic: use RSI level to determine signal
|
||||||
indicator.lastSignalType = isAbove ? 'buy' : 'sell';
|
const rsi = lastResult?.rsi !== undefined ? lastResult.rsi : lastResult;
|
||||||
indicator.lastSignalTimestamp = lastCandleTime;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user