feat: add new indicators (Decay, Edecay, MinusDi, MinusDm, PlusDi, PlusDm, Maxindex, Minindex, Sarext) and update pine scripts, core libs, validation tests, and python bindings
2026-03-09 13:45:46 -07:00
|
|
|
// Licensed under the Apache License, Version 2.0
|
2026-01-18 19:02:03 -08:00
|
|
|
// © mihakralj
|
|
|
|
|
//@version=6
|
|
|
|
|
indicator("Detrended Price Oscillator (DPO)", "DPO", overlay=false)
|
|
|
|
|
|
|
|
|
|
//@function Calculates Detrended Price Oscillator (DPO) by removing trend component from price
|
|
|
|
|
//@param source Series to calculate DPO from
|
|
|
|
|
//@param period Period for SMA calculation and displacement
|
|
|
|
|
//@returns DPO value (current price - displaced SMA)
|
|
|
|
|
dpo(series float source, simple int period) =>
|
|
|
|
|
if period <= 0
|
|
|
|
|
runtime.error("Period must be greater than 0")
|
|
|
|
|
int displacement = math.floor(period / 2) + 1
|
|
|
|
|
float sum = 0.0
|
|
|
|
|
for i = 0 to period - 1
|
|
|
|
|
sum += nz(source[i], source)
|
|
|
|
|
float sma = sum / period
|
|
|
|
|
float currentPrice = source
|
|
|
|
|
float displacedSMA = sma[displacement]
|
|
|
|
|
float result = na
|
|
|
|
|
if not na(displacedSMA)
|
|
|
|
|
result := currentPrice - displacedSMA
|
|
|
|
|
|
|
|
|
|
result
|
|
|
|
|
|
|
|
|
|
// ---------- Main loop ----------
|
|
|
|
|
|
|
|
|
|
// Inputs
|
|
|
|
|
i_source = input.source(close, "Source")
|
|
|
|
|
i_period = input.int(20, "Period", minval=1)
|
|
|
|
|
|
|
|
|
|
// Calculation
|
|
|
|
|
dpo_value = dpo(i_source, i_period)
|
|
|
|
|
|
|
|
|
|
// Plot
|
|
|
|
|
plot(dpo_value, "DPO", color=color.yellow, linewidth=2)
|
|
|
|
|
hline(0, "Zero Line", color.gray, hline.style_dotted)
|