function realtimeConvolution(
timeframe: Timeframes,
data: Candle,
currentState: RealtimeState,
): {
candle: Candle | undefined;
state: RealtimeState;
} {
const timeframeSeconds = getTimeframeSeconds(timeframe);
const { previousTime, sessionStart } = currentState;
if (
previousTime === null ||
sessionStart === null ||
data.time - previousTime > timeframeSeconds
) {
const state: RealtimeState = {
previousTime: data.time,
candles: [data],
sessionStart: data.time,
};
return {
candle: aggregateCandles(state.candles, data.time),
state,
};
}
const previousBucketStart =
sessionStart + Math.floor((previousTime - sessionStart) / timeframeSeconds) * timeframeSeconds;
const currentBucketStart =
sessionStart + Math.floor((data.time - sessionStart) / timeframeSeconds) * timeframeSeconds;
let candles: Candle[];
if (currentBucketStart !== previousBucketStart) {
candles = [data];
} else {
const candleIndex = currentState.candles.findIndex((candle) => candle.time === data.time);
if (candleIndex === -1) {
candles = [...currentState.candles, data];
} else {
candles = [...currentState.candles];
candles[candleIndex] = data;
}
}
const state: RealtimeState = {
previousTime: data.time,
candles,
sessionStart,
};
return {
candle: aggregateCandles(candles, currentBucketStart),
state,
};
}