// The MIT License (MIT) // © mihakralj //@version=6 indicator("Acceleration Bands (ACCBANDS)", "ACCBANDS", overlay=true) //@function Calculates Acceleration Bands using SMAs of high, low, close prices //@param high Series of high prices //@param low Series of low prices //@param close Series of close prices //@param period Lookback period for the moving average //@param factor Multiplier for band width calculation //@returns tuple with [middle, upper, lower] band values //@optimized Uses circular buffers with O(1) complexity per bar accbands(series float high, series float low, series float close, simple int period, simple float factor = 2.0) => if period <= 0 or factor <= 0.0 runtime.error("Period and factor must be greater than 0") var int p = math.max(1, period) var int head = 0 var int count = 0 var array bufferHigh = array.new_float(p, na) var array bufferLow = array.new_float(p, na) var array bufferClose = array.new_float(p, na) var float sumHigh = 0.0 var float sumLow = 0.0 var float sumClose = 0.0 float oldestHigh = array.get(bufferHigh, head) float oldestLow = array.get(bufferLow, head) float oldestClose = array.get(bufferClose, head) if not na(oldestHigh) sumHigh -= oldestHigh sumLow -= oldestLow sumClose -= oldestClose count -= 1 float currentHigh = nz(high) float currentLow = nz(low) float currentClose = nz(close) sumHigh += currentHigh sumLow += currentLow sumClose += currentClose count += 1 array.set(bufferHigh, head, currentHigh) array.set(bufferLow, head, currentLow) array.set(bufferClose, head, currentClose) head := (head + 1) % p float smaHigh = nz(sumHigh / count) float smaLow = nz(sumLow / count) float smaClose = nz(sumClose / count) float bandWidth = (smaHigh - smaLow) * factor [smaClose, smaHigh + bandWidth, smaLow - bandWidth] // ---------- Main loop ---------- // Inputs i_period = input.int(20, "Period", minval=1) i_factor = input.float(2.0, "Factor", minval=0.001) // Calculation [middle, upper, lower] = accbands(high, low, close, i_period, i_factor) // Plot plot(middle, "Middle", color=color.yellow, linewidth=2) p1 = plot(upper, "Upper", color=color.yellow, linewidth=2) p2 = plot(lower, "Lower", color=color.yellow, linewidth=2) fill(p1, p2, color=color.new(color.blue, 90), title="Band Fill")