mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-27 17:27:43 +00:00
55 lines
2.3 KiB
Plaintext
55 lines
2.3 KiB
Plaintext
// Licensed under the Apache License, Version 2.0
|
|
// © mihakralj
|
|
//@version=6
|
|
// Ultimate Bands logic based on work by John F. Ehlers (c) 2024
|
|
indicator("Ehlers Ultimate Bands (UBANDS)", "UBANDS", overlay=true)
|
|
|
|
//@function Calculates Ultimate Bands
|
|
//@param src Source series for the bands
|
|
//@param length Lookback period for the Ehlers Ultrasmooth Filter and RMS
|
|
//@param mult RMS multiplier for band width
|
|
//@returns tuple [upperBand, middleBand, lowerBand]
|
|
ubands(series float src, simple int length, simple float mult) =>
|
|
var float usf_state = na, var float c1=0.0, var float c2=0.0, var float c3=0.0, var int prev_len = 0
|
|
if prev_len != length or na(c1)
|
|
float arg = (math.sqrt(2)*math.pi)/math.max(1,float(length))
|
|
float exp_arg = math.exp(-arg)
|
|
c2 := 2*exp_arg*math.cos(arg)
|
|
c3 := -exp_arg*exp_arg
|
|
c1 := (1+c2-c3)/4.0
|
|
prev_len := length
|
|
usf_state := na
|
|
float s = nz(src,src[1]), s1 = nz(src[1],s), s2 = nz(src[2],s1)
|
|
float current_usf = na(usf_state) or na(usf_state[1]) or na(usf_state[2]) ? s :
|
|
(1-c1)*s + (2*c1-c2)*s1 - (c1+c3)*s2 + c2*nz(usf_state[1],s1) + c3*nz(usf_state[2],s2)
|
|
usf_state := current_usf
|
|
float smooth = usf_state
|
|
series float residuals = src - smooth
|
|
float rms = 0.0
|
|
if length > 0
|
|
float sumSq_r = 0.0, int count_r = 0
|
|
for i = 0 to length - 1
|
|
float val_r = residuals[i]
|
|
if not na(val_r)
|
|
sumSq_r += val_r*val_r
|
|
count_r += 1
|
|
if count_r > 0
|
|
rms := math.sqrt(sumSq_r/count_r)
|
|
[smooth + mult*rms, smooth, smooth - mult*rms]
|
|
|
|
// ---------- Main loop ----------
|
|
|
|
// Inputs
|
|
i_source = input.source(close, "Source")
|
|
i_length = input.int(20, "Length", minval=1, tooltip="Lookback period for smoothing and RMS calculation.")
|
|
i_mult = input.float(1.0, "RMS Multiplier", minval=0.01, tooltip="Band width as multiple of RMS value.")
|
|
|
|
// Calculation
|
|
[upperBand, middleBand, lowerBand] = ubands(i_source, i_length, i_mult)
|
|
|
|
// Plot
|
|
plot(middleBand, "Middle Band", color=color.yellow, linewidth=2)
|
|
p1 = plot(upperBand, "Upper Band", color=color.yellow, linewidth=2)
|
|
p2 = plot(lowerBand, "Lower Band", color=color.yellow, linewidth=2)
|
|
fill(p1, p2, color=color.new(color.blue, 90), title="Band Fill")
|