Files
QuanTAlib/lib/momentum/apo/apo.pine
T
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

57 lines
2.0 KiB
Plaintext

// The MIT License (MIT)
// © mihakralj
//@version=6
indicator("Absolute Price Oscillator (APO)", "APO", overlay=false)
//@function Calculates Absolute Price Oscillator using compensated EMAs
//@doc https://github.com/mihakralj/pinescript/blob/main/indicators/momentum/apo.md
//@param src Source series to calculate APO for
//@param fast_len Fast EMA period
//@param slow_len Slow EMA period
//@returns APO value (difference between fast and slow EMAs)
//@optimized Uses embedded EMA with unified warmup compensation for accuracy from bar 1
apo(series float src, simple int fast_len, simple int slow_len) =>
if fast_len <= 0 or slow_len <= 0
runtime.error("Lengths must be greater than 0")
if fast_len >= slow_len
runtime.error("Fast length must be less than slow length")
float alpha_fast = 2.0 / (fast_len + 1)
float beta_fast = 1.0 - alpha_fast
float alpha_slow = 2.0 / (slow_len + 1)
float beta_slow = 1.0 - alpha_slow
var bool warmup = true
var float e_fast = 1.0
var float e_slow = 1.0
var float ema_fast = 0.0
var float ema_slow = 0.0
var float result_fast = src
var float result_slow = src
ema_fast := alpha_fast * (src - ema_fast) + ema_fast
ema_slow := alpha_slow * (src - ema_slow) + ema_slow
if warmup
e_fast *= beta_fast
e_slow *= beta_slow
float c_fast = 1.0 / (1.0 - e_fast)
float c_slow = 1.0 / (1.0 - e_slow)
result_fast := c_fast * ema_fast
result_slow := c_slow * ema_slow
warmup := e_fast > 1e-10 or e_slow > 1e-10
else
result_fast := ema_fast
result_slow := ema_slow
result_fast - result_slow
// ---------- Main loop ----------
// Inputs
i_source = input.source(close, "Source")
i_fast_len = input.int(12, "Fast Length", minval=1)
i_slow_len = input.int(26, "Slow Length", minval=1)
// Calculation
apo_value = apo(i_source, i_fast_len, i_slow_len)
// Plot
plot(apo_value, "APO", color=color.yellow, linewidth=2)
hline(0, "Zero", color=color.gray)