Files
QuanTAlib/lib/volume/aobv/aobv.pine
T
Miha Kralj 24e86d762a Add documentation links for various volatility indicators and channels
- Updated BBWN, BBWP, CCV, CV, CVI, EWMA, GKV, HLV, HV, Jvolty, JVOLTYN, MASSI, NATR, RSV, RV, RVI, TR, UI, VOV, VR, YZV indicators with documentation links.
- Added documentation links for Aberration, Acceleration Bands, Andrews' Pitchfork, Adaptive Price Zone, ATR Bands, Bollinger Bands, Center of Gravity, Donchian Channels, Decay Min-Max Channel, Detrended Synthetic Price, EACP, EBSW, HOMOD, Jurik Volatility Bands, Keltner Channel, MA Envelope, Min-Max Channel, Price Channel, Regression Channels, Standard Deviation Channel, Stoller Average Range Channel, Super Trend Bands, Ultimate Bands, Ultimate Channel, VWAP Bands, and VWAP with Standard Deviation Bands.
2026-02-18 11:55:48 -08:00

62 lines
2.4 KiB
Plaintext

// The MIT License (MIT)
// © mihakralj
//@version=6
indicator("AOBV - Archer On-Balance Volume (AOBV)", "AOBV", overlay=false)
//@function Computes AOBV Fast and Slow from OBV using custom EMA calculations without helper functions.
//@param src (series float) Price source.
//@param vol (series float) Volume data.
//@returns ([float, float]) Tuple with AOBV Fast and AOBV Slow values.
//@optimized Beta precomputation for EMA warmup compensation
aobv(src, vol) =>
var float prev_src = na
safe_src = not na(src) ? src : (not na(prev_src) ? prev_src : 0)
safe_vol = not na(vol) ? vol : 0
safe_prev = not na(prev_src) ? prev_src : safe_src
var float obv_val = 0.0
obv_val := bar_index == 0 ? (safe_src > safe_prev ? safe_vol : safe_src < safe_prev ? -safe_vol : 0) : obv_val + (safe_src > safe_prev ? safe_vol : safe_src < safe_prev ? -safe_vol : 0)
if not na(src)
prev_src := src
periods = array.from(4, 14)
var emaArr = array.new_float(2, na)
var eArr = array.new_float(2, 1.0)
var warmupArr = array.new_bool(2, true)
var betaArr = array.new_float(2, 0.0)
resArr = array.new_float(2, na)
for i = 0 to array.size(periods) - 1
period = array.get(periods, i)
alpha = 2.0 / math.max(period, 1)
beta = array.get(betaArr, i)
if beta == 0.0
beta := 1.0 - alpha
array.set(betaArr, i, beta)
ema_val = array.get(emaArr, i)
if na(ema_val)
ema_val := 0.0
array.set(emaArr, i, ema_val)
array.set(resArr, i, obv_val)
else
ema_val := alpha * (obv_val - ema_val) + ema_val
array.set(emaArr, i, ema_val)
if array.get(warmupArr, i)
new_e = array.get(eArr, i) * beta
array.set(eArr, i, new_e)
c = 1.0 / (1.0 - new_e)
array.set(resArr, i, c * ema_val)
if new_e <= 1e-10
array.set(warmupArr, i, false)
else
array.set(resArr, i, ema_val)
[array.get(resArr, 0), array.get(resArr, 1)]
// ---------- Inputs ----------
src = input(close, "Source")
vol = input(volume, "Volume")
// ---------- Calculations ----------
[aobvFast, aobvSlow] = aobv(src, vol)
// ---------- Plotting ----------
plot(aobvFast, "AOBV Fast", color.blue, linewidth=2)
plot(aobvSlow, "AOBV Slow", color.red, linewidth=2)