/**
* Awesome Oscillator Indicator
* Momentum oscillator using difference between fast and slow SMA of median price
*/
import { calculateSMA } from './moving-averages';
export function calculateAwesomeOscillator(highs, lows, fastPeriod = 5, slowPeriod = 34) {
// Minimum 3 data points required for basic calculation
if (highs.length < 3 || lows.length < 3) {
return {
ao: null,
signal: null,
histogram: null,
};
}
// Use adaptive periods if not enough data
const effectiveSlowPeriod = Math.min(slowPeriod, Math.max(3, highs.length - 1));
const effectiveFastPeriod = Math.min(fastPeriod, Math.max(2, Math.floor(effectiveSlowPeriod / 2)));
// Calculate median price (H+L)/2
const medianPrices = [];
for (let i = 0; i < highs.length; i++) {
medianPrices.push((highs[i] + lows[i]) / 2);
}
// Calculate fast and slow SMA of median prices using effective periods
const fastSMA = calculateSMA(medianPrices, effectiveFastPeriod);
const slowSMA = calculateSMA(medianPrices, effectiveSlowPeriod);
// Fallback: if SMA calculation fails, use simple averages
let ao;
if (fastSMA.length === 0 || slowSMA.length === 0) {
// Simple fallback: average of recent vs older median prices
const recentMedian = medianPrices.slice(-Math.min(3, medianPrices.length));
const olderMedian = medianPrices.slice(0, Math.max(1, medianPrices.length - 3));
const recentAvg = recentMedian.reduce((a, b) => a + b, 0) / recentMedian.length;
const olderAvg = olderMedian.reduce((a, b) => a + b, 0) / olderMedian.length;
ao = recentAvg - olderAvg;
}
else {
// AO = Fast SMA - Slow SMA
const currentFastSMA = fastSMA[fastSMA.length - 1];
const currentSlowSMA = slowSMA[slowSMA.length - 1];
ao = currentFastSMA - currentSlowSMA;
}
// Determine histogram color (green when AO > 0, red when AO < 0)
let histogram;
if (ao > 0)
histogram = 'green';
else if (ao < 0)
histogram = 'red';
else
histogram = 'zero';
// Determine signal based on AO movement
let signal;
if (histogram === 'green')
signal = 'bullish';
else if (histogram === 'red')
signal = 'bearish';
else
signal = 'neutral';
return {
ao,
signal,
histogram,
};
}