simplified crossover detection: find first candle where price crosses MA
This commit is contained in:
@ -94,9 +94,6 @@ export function calculateSummarySignal(signals) {
|
|||||||
function calculateHistoricalCrossovers(activeIndicators, candles) {
|
function calculateHistoricalCrossovers(activeIndicators, candles) {
|
||||||
activeIndicators.forEach(indicator => {
|
activeIndicators.forEach(indicator => {
|
||||||
const indicatorType = indicator.type || indicator.indicatorType;
|
const indicatorType = indicator.type || indicator.indicatorType;
|
||||||
const SignalFunction = getSignalFunction(indicatorType);
|
|
||||||
|
|
||||||
if (!SignalFunction) return;
|
|
||||||
|
|
||||||
// Recalculate indicator values for all candles
|
// Recalculate indicator values for all candles
|
||||||
const IndicatorClass = IndicatorRegistry[indicatorType];
|
const IndicatorClass = IndicatorRegistry[indicatorType];
|
||||||
@ -107,46 +104,43 @@ function calculateHistoricalCrossovers(activeIndicators, candles) {
|
|||||||
|
|
||||||
if (!results || results.length === 0) return;
|
if (!results || results.length === 0) return;
|
||||||
|
|
||||||
// Track the last crossover timestamp
|
// Find the most recent crossover by going backwards from the newest candle
|
||||||
let lastCrossoverTimestamp = indicator.lastSignalTimestamp || null;
|
// candles are sorted oldest first, newest last
|
||||||
let crossoverCount = 0;
|
let lastCrossoverTimestamp = null;
|
||||||
|
|
||||||
// Iterate through candles to find crossovers (from newest to oldest)
|
for (let i = candles.length - 1; i > 0; i--) {
|
||||||
// We start from the end and go backwards to find the most recent crossover
|
const candle = candles[i]; // newer candle
|
||||||
for (let i = candles.length - 2; i >= 0; i--) {
|
const prevCandle = candles[i-1]; // older candle
|
||||||
// Skip if we don't have data for these candles
|
|
||||||
if (!results[i] || !results[i + 1]) continue;
|
|
||||||
|
|
||||||
const candle = candles[i];
|
const result = results[i];
|
||||||
const prevCandle = candles[i + 1];
|
const prevResult = results[i-1];
|
||||||
|
|
||||||
const valuesThis = typeof results[i] === 'object' ? results[i] : { ma: results[i] };
|
if (!result || !prevResult) continue;
|
||||||
const valuesPrev = typeof results[i + 1] === 'object' ? results[i + 1] : { ma: results[i + 1] };
|
|
||||||
|
|
||||||
const closeThis = candles[i].close;
|
// Get MA value (handle both object and number formats)
|
||||||
const closePrev = candles[i + 1].close;
|
const ma = result.ma !== undefined ? result.ma : result;
|
||||||
const maThis = valuesThis.ma;
|
const prevMa = prevResult.ma !== undefined ? prevResult.ma : prevResult;
|
||||||
const maPrev = valuesPrev.ma;
|
|
||||||
|
|
||||||
// Check for BUY→SELL crossover (was above, now below)
|
if (ma === undefined || prevMa === undefined) continue;
|
||||||
if (closePrev > maPrev && closeThis < maThis) {
|
|
||||||
console.log(`[HistoricalCross] ${indicatorType} BUY→SELL crossover at candle ${i}, time: ${prevCandle.time}`);
|
// Check crossover: price was on one side of MA, now on the other side
|
||||||
lastCrossoverTimestamp = prevCandle.time;
|
const priceAbovePrev = prevCandle.close > prevMa;
|
||||||
crossoverCount++;
|
const priceAboveNow = candle.close > ma;
|
||||||
break; // Found most recent crossover
|
|
||||||
|
// SELL signal: price crossed from above to below MA
|
||||||
|
if (priceAbovePrev && !priceAboveNow) {
|
||||||
|
lastCrossoverTimestamp = candle.time;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// Check for SELL→BUY crossover (was below, now above)
|
// BUY signal: price crossed from below to above MA
|
||||||
else if (closePrev < maPrev && closeThis > maThis) {
|
if (!priceAbovePrev && priceAboveNow) {
|
||||||
console.log(`[HistoricalCross] ${indicatorType} SELL→BUY crossover at candle ${i}, time: ${prevCandle.time}`);
|
lastCrossoverTimestamp = candle.time;
|
||||||
lastCrossoverTimestamp = prevCandle.time;
|
break;
|
||||||
crossoverCount++;
|
|
||||||
break; // Found most recent crossover
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (crossoverCount > 0) {
|
if (lastCrossoverTimestamp) {
|
||||||
console.log(`[HistoricalCross] ${indicatorType}: Found crossover at ${new Date(lastCrossoverTimestamp * 1000).toLocaleString()}`);
|
console.log(`[HistoricalCross] ${indicatorType}: Found crossover at ${new Date(lastCrossoverTimestamp * 1000).toLocaleString()}`);
|
||||||
// Update the indicator's lastSignalTimestamp
|
|
||||||
indicator.lastSignalTimestamp = lastCrossoverTimestamp;
|
indicator.lastSignalTimestamp = lastCrossoverTimestamp;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user