Files
QuanTAlib/quantower/lib/sine.pine
T

49 lines
2.0 KiB
Plaintext
Raw Normal View History

// The MIT License (MIT)
// © mihakralj
//@version=6
indicator("Ehlers Sine Wave (SINE)", "SINE", overlay=false)
//@function Calculates Ehlers original Sine Wave using a twopole HighPass, a SuperSmoother,
// and a Hilberttransform FIR pair (InphaseI / QuadratureQ).
//@doc https://github.com/mihakralj/pinescript/blob/main/indicators/cycles/sine.md
//@param src Series to calculate the Sine Wave from
//@param hpLength HighPass filter length (detrending period)
//@param ssfLength SuperSmoother filter length (cycle smoothing period)
//@returns single normalized sinewave value in [1 … +1]
sine(series float src, simple int hpLength, simple int ssfLength) =>
if hpLength <= 0 or ssfLength <= 0
runtime.error("Periods must be >0")
float pi = 2 * math.asin(1)
float angHP = 2 * pi / hpLength
float aHP = (1 - math.sin(angHP)) / math.cos(angHP)
var float hp = 0.0
hp := 0.5 * (1 + aHP) * (src - nz(src[1])) + aHP * nz(hp[1])
float angSSF = math.sqrt(2) * pi / ssfLength
float aSSF = math.exp(-angSSF)
float bSSF = 2 * aSSF * math.cos(angSSF)
float c2 = bSSF
float c3 = -aSSF * aSSF
float c1 = 1 - c2 - c3
var float filt = 0.0
filt := c1 * (hp + nz(hp[1])) / 2 + c2 * nz(filt[1]) + c3 * nz(filt[2])
float Q = 0.0962 * nz(filt[3]) + 0.5769 * nz(filt[1])
- 0.5769 * nz(filt[5]) - 0.0962 * nz(filt[7])
float I = filt
float pwr = I*I + Q*Q
float sineWave = pwr == 0 ? 0 : I / math.sqrt(pwr)
math.min(1, math.max(-1, sineWave))
// ---------- Main loop ----------
// Inputs
i_source = input.source(close, "Source")
i_hpLength = input.int(40, "HighPass Filter Length", minval=1)
i_ssfLength = input.int(10, "SuperSmoother Filter Length", minval=1)
// Calculation
sine_wave = sine(i_source, i_hpLength, i_ssfLength)
// Plot
plot(sine_wave, "SINE", color=color.yellow, linewidth=2)
hline(0, "Zero Line", color.gray, linestyle=hline.style_dashed)