AVWAP Oscillator

A custom indicator created by Bit Squeezer on TrendSpider. You can import this script into your TrendSpider account. Don't have TrendSpider? Create an account first, then import the script.

Chart featuring the AVWAP Oscillator indicator

This indicator is an oscillator which indicates how many AVWAPs anchored off recent Williams Fractals are currently above the last price and how many of them are below.

At every candle, it takes last 10 Fractal points, builds AVWAP from each of these and then computes how many of them are above/below the candle's Close price.

Source code

This indicator had been implemented by Bit Squeezer in JavaScript on TrendSpider. Check out the developer documentation to learn more about JS on TrendSpider.

describe_indicator('AVWAP Oscillator', 'lower', { decimals: 1, shortName: 'AVWAP Osc', mainColorInheritFrom: 'upper' });

const length = input('Length', 5, { min: 3, max: 31 });

const priceSource = input('Price source', 'close', constants.price_source_options);

// get a reference to the corresponding price data (open, high, close e.t.c.), as per user's choice
const price = prices[priceSource];

const numberOfAvwaps = 10;

const fractalHighs = indexed_points_of(fractal_high(high, length));
const fractalLows = indexed_points_of(fractal_low(low, length));

const highAvwaps = [];
const lowAvwaps = [];

const highValues = series_of(null);
const lowValues = series_of(null);

let latestHighAvwapIndex = null;
let latestLowAvwapIndex = null;

// If there are fractalHighs take the first one
let nextFractalHighCandleIndex = fractalHighs.length > 0 && fractalHighs.shift().candleIndex;
let nextFractalLowCandleIndex = fractalLows.length > 0 && fractalLows.shift().candleIndex;

for (let candleIndex = 0; candleIndex < close.length; candleIndex++) {
	// Check if there is a high fractal on this candle
	if (nextFractalHighCandleIndex == candleIndex) {
		// Find the start of the next AVWAP of this highAvwap element, which is -numberOfAvwaps- later.
		// There is no need to compute more elements of the current AVWAP after that index.
		const lastAvwapCandleIndex = fractalHighs.length < numberOfAvwaps ? null : fractalHighs[numberOfAvwaps - 1].candleIndex - 1;
		// Get the next AVWAPs starting candle index
		nextFractalHighCandleIndex = fractalHighs.length > 0 && fractalHighs.shift().candleIndex;

		// If there are still empty positions in the array add the new vwap
		if (highAvwaps.length != numberOfAvwaps) {
			highAvwaps.push(vwap(candleIndex, lastAvwapCandleIndex));
			latestHighAvwapIndex = highAvwaps.length - 1;
		}
		else {
			latestHighAvwapIndex++;
			// if the index reached the maximum length go back to the first element which is the oldest
			latestHighAvwapIndex %= numberOfAvwaps;
			highAvwaps[latestHighAvwapIndex] = vwap(candleIndex, lastAvwapCandleIndex);
		}
	}

	// Do the same for low fractals
	if (nextFractalLowCandleIndex == candleIndex) {
		const lastAvwapCandleIndex = fractalLows.length < numberOfAvwaps ? null : fractalLows[numberOfAvwaps - 1].candleIndex - 1;
		nextFractalLowCandleIndex = fractalLows.length > 0 && fractalLows.shift().candleIndex;

		if (lowAvwaps.length != numberOfAvwaps) {
			lowAvwaps.push(vwap(candleIndex, lastAvwapCandleIndex));
			latestLowAvwapIndex = lowAvwaps.length - 1;
		}
		else {
			latestLowAvwapIndex++;
			latestLowAvwapIndex %= numberOfAvwaps;
			lowAvwaps[latestLowAvwapIndex] = vwap(candleIndex, lastAvwapCandleIndex);
		}
	}

	let highAvwapsUnderPrice = 0;
	let lowAvwapsOverPrice = 0;

	for (let avwapIndex = 0; avwapIndex < highAvwaps.length; avwapIndex++) {
		if (highAvwaps[avwapIndex][candleIndex] < price[candleIndex]) {
			highAvwapsUnderPrice++;
		}
	}

	for (let avwapIndex = 0; avwapIndex < lowAvwaps.length; avwapIndex++) {
		if (lowAvwaps[avwapIndex][candleIndex] > price[candleIndex]) {
			lowAvwapsOverPrice++;
		}
	}

	highValues[candleIndex] = highAvwapsUnderPrice / highAvwaps.length;
	lowValues[candleIndex] = -1 * (lowAvwapsOverPrice / lowAvwaps.length);
}

paint(horizontal_line(1), 'L1', '#9d9c9d', 'dotted');
paint(horizontal_line(0.5), 'L0.5', '#9d9c9d', 'dotted');
paint(horizontal_line(0), 'L0', '#9d9c9d', 'dotted');
paint(horizontal_line(-0.5), 'L-0.5', '#9d9c9d', 'dotted');
paint(horizontal_line(-1), 'L-1', '#9d9c9d', 'dotted');

paint(highValues, 'Upper', '#2ca599', 'histogram');
paint(lowValues, 'Lower', '#ee5451', 'histogram');