mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-28 01:37:43 +00:00
50 lines
1.8 KiB
Plaintext
50 lines
1.8 KiB
Plaintext
// Licensed under the Apache License, Version 2.0
|
|
// © mihakralj
|
|
//@version=6
|
|
indicator("Absolute Price Oscillator (APO)", "APO", overlay=false)
|
|
|
|
//@function Calculates Absolute Price Oscillator (APO) as difference between fast and slow EMAs
|
|
//@param source Series to calculate APO from
|
|
//@param fastLength Period for fast EMA
|
|
//@param slowLength Period for slow EMA
|
|
//@returns APO value (fast EMA - slow EMA)
|
|
apo(series float source, simple int fastLength, simple int slowLength) =>
|
|
if fastLength <= 0 or slowLength <= 0
|
|
runtime.error("Lengths must be greater than 0")
|
|
if fastLength >= slowLength
|
|
runtime.error("Fast length must be less than slow length")
|
|
float alphaFast = 2.0 / (fastLength + 1.0)
|
|
float alphaSlow = 2.0 / (slowLength + 1.0)
|
|
var float emaFast = na var float emaSlow = na, var float e = 1.0
|
|
var bool warmup = true, var float result = na
|
|
if not na(source)
|
|
if na(emaFast)
|
|
emaFast := source, emaSlow := source, result := 0
|
|
else
|
|
emaFast := alphaFast * (source - emaFast) + emaFast
|
|
emaSlow := alphaSlow * (source - emaSlow) + emaSlow
|
|
if warmup
|
|
e *= (1.0 - alphaSlow)
|
|
float c = e > 1e-10 ? 1.0 / (1.0 - e) : 1.0
|
|
float aFast = emaFast * c
|
|
float aSlow = emaSlow * c
|
|
result := aFast - aSlow
|
|
if e <= 1e-10
|
|
warmup := false
|
|
else
|
|
result := emaFast - emaSlow
|
|
result
|
|
|
|
// ---------- Main loop ----------
|
|
|
|
// Inputs
|
|
i_source = input.source(close, "Source")
|
|
i_fastLength = input.int(12, "Fast Length", minval=1)
|
|
i_slowLength = input.int(26, "Slow Length", minval=1)
|
|
|
|
// Calculation
|
|
apo_value = apo(i_source, i_fastLength, i_slowLength)
|
|
|
|
// Plot
|
|
plot(apo_value, "APO", color.new(color.yellow, 0), 2)
|