Files
QuanTAlib/quantower/lib/accbands.pine
T
Miha Kralj 86fe32a682 SIMD Refactor: Merge simd-dev into dev (#55)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
Co-authored-by: Warp <agent@warp.dev>
2026-01-18 19:02:03 -08:00

65 lines
2.4 KiB
Plaintext

// 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<float> bufferHigh = array.new_float(p, na)
var array<float> bufferLow = array.new_float(p, na)
var array<float> 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")