Files
QuanTAlib/lib/dynamics/vortex/vortex.pine
T

59 lines
2.1 KiB
Plaintext

// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("Vortex Indicator", "VORTEX", overlay=false)
//@function Calculates Vortex Indicator (VI+ and VI-)
//@param period Lookback period for summing vortex movements and true range
//@returns Tuple [vi_plus, vi_minus] normalized vortex indicator values
//@optimized Uses running sums for O(1) complexity with circular buffer
vortex(simple int period) =>
if period <= 0
runtime.error("Period must be greater than 0")
var int head = 0
var array<float> vmPlusBuffer = array.new_float(period, na)
var array<float> vmMinusBuffer = array.new_float(period, na)
var array<float> trBuffer = array.new_float(period, na)
var float sumVMPlus = 0.0
var float sumVMMinus = 0.0
var float sumTR = 0.0
var int count = 0
float tr1 = high - low
float tr2 = na(close[1]) ? 0 : math.abs(high - close[1])
float tr3 = na(close[1]) ? 0 : math.abs(low - close[1])
float tr = math.max(tr1, math.max(tr2, tr3))
float vmPlus = na(low[1]) ? tr : math.abs(high - low[1])
float vmMinus = na(high[1]) ? tr : math.abs(low - high[1])
float oldVMPlus = array.get(vmPlusBuffer, head)
float oldVMMinus = array.get(vmMinusBuffer, head)
float oldTR = array.get(trBuffer, head)
if not na(oldVMPlus)
sumVMPlus -= oldVMPlus
sumVMMinus -= oldVMMinus
sumTR -= oldTR
else
count += 1
sumVMPlus += vmPlus
sumVMMinus += vmMinus
sumTR += tr
array.set(vmPlusBuffer, head, vmPlus)
array.set(vmMinusBuffer, head, vmMinus)
array.set(trBuffer, head, tr)
head := (head + 1) % period
float viPlus = sumTR > 0 ? sumVMPlus / sumTR : 0
float viMinus = sumTR > 0 ? sumVMMinus / sumTR : 0
[viPlus, viMinus]
// ---------- Main loop ----------
// Inputs
i_period = input.int(14, "Period", minval=1)
// Calculation
[vi_plus, vi_minus] = vortex(i_period)
// Plot
plot(vi_plus, "VI+", color=color.green, linewidth=2)
plot(vi_minus, "VI-", color=color.red, linewidth=2)
hline(1.0, "Reference", color=color.gray, linestyle=hline.style_dotted)