Low Pass Channel [DW]
"Low Pass Channel [DW]" by DonovanWall, MPL-2.0. Ported to FloScript by FloSignals; modifications under MPL-2.0. Original: Low Pass Channel [DW] (v2.0), read 2026-10-12T15:59:02.634Z; source language v4.
Licence: Mozilla Public License 2.0 (MPL-2.0) — full text. The source is published with it, modifications included, under the same licence.
Low Pass Channel [DW] by DonovanWall, ported from Pine v4. Overlay indicator with 3 plots, 2 fills, bar/background colouring and 6 inputs.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © DonovanWall
//██████╗ ██╗ ██╗
//██╔══██╗██║ ██║
//██║ ██║██║ █╗ ██║
//██║ ██║██║███╗██║
//██████╔╝╚███╔███╔╝
//╚═════╝ ╚══╝╚══╝
// ------------------------------------------------------------------------------------------------
// Original author: DonovanWall
// Original title: Low Pass Channel [DW]
// Licence: MPL-2.0 (the header above is the original notice, kept verbatim)
// Pine version: 4
// Fetched: 2026-10-12
// Ported to FloScript by FloSignals; modifications under MPL-2.0.
// Converter: @flosignals/floscript 0.1.0, strict mode, score 100/100
// ------------------------------------------------------------------------------------------------
//@floscript=1
//@version=5
// Converted by the FloScript converter from a Pine-compatible v4 source.
indicator("Low Pass Channel [DW]", overlay=true)
//by Donovan Wall
//This is an experimental study designed to attenuate higher frequency oscillations in price and volatility with minimal lag.
//In this study, a single pole low pass filter is used. The low pass filter's cutoff period is determined either by a fixed user input, or by using an Instantaneous Frequency Measurement (IFM) algorithm.
//Most radar warning, electronic countermeasures, and electronic intelligence systems employ IFM to identify threats, map the electronic battlefield, and implement deceptive countermeasures.
//The IFM technique used for this study was devised by John Ehlers. It calculates In Phase and Quadrature (IQ) components using the Hilbert Transform and uses them to determine the dominant price cycle.
//To generate the channel, the same filter approach is applied to true range then added to and subtracted from the price filter.
//Custom bar colors are included for simple wave and trend indication.
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Updates:
// -> Stability Fix: Added correction for NaN values to stabilize initial states.
// -> Reorganized the script structure.
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Functions
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Dominant Cycle Detection Function Using In Phase & Quadrature IFM
dom_cycle(x, lim) =>
val1 = x - nz(x[7])
in_phase = 0.0
in_phase := 1.25 * (nz(val1[4]) - 0.635 * nz(val1[2])) + 0.635 * nz(in_phase[3])
quadrature = 0.0
quadrature := nz(val1[2]) - 0.338 * val1 + 0.338 * nz(quadrature[2])
real = 0.0
real := 0.2 * (in_phase * in_phase[1] + quadrature * quadrature[1]) + 0.8 * nz(real[1])
imag = 0.0
imag := 0.2 * (in_phase * quadrature[1] - in_phase[1] * quadrature) + 0.8 * nz(imag[1])
delta_phase = 0.0
if real != 0.0
delta_phase := math.atan(imag / real)
inst_per = 0.0
val2 = 0.0
for i = 0 to lim
val2 := val2 + (na(delta_phase[i]) ? delta_phase : nz(delta_phase[i]))
if val2 > 4 * math.asin(1) and inst_per == 0.0
inst_per := i
if inst_per == 0.0
inst_per := nz(inst_per[1])
dom_cycle = 0.0
dom_cycle := na(dom_cycle[1]) ? inst_per : 0.25 * inst_per + 0.75 * nz(dom_cycle[1], 1)
dom_cycle
//Single Pole Low Pass Filter
lp(x, t) =>
omega = 4 * math.asin(1) / t
alpha = (1 - math.sin(omega)) / math.cos(omega)
lp = 0.0
lp := na(lp[1]) ? x : 0.5 * (1 - alpha) * (x + x[1]) + alpha * nz(lp[1])
lp
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Inputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Source
src = input(defval=close, title="Source")
//Cutoff Period Type
cutoff_type = input.string(defval="Adaptive", options=["Adaptive", "Fixed"], title="Cutoff Period Type")
//Fixed Cutoff Period
fixed_per = input.int(defval=20, minval=3, title="Fixed Cutoff Period")
//Adaptive Cutoff Maximum Cycle Limit
max_cycle_limit = input.int(defval=60, minval=8, title="Adaptive Cutoff Maximum Cycle Limit")
//Adaptive Cutoff Period Multiplier
cycle_mult = input.float(defval=1.0, minval=0.5, title="Adaptive Cutoff Period Multiplier")
//True Range Multiplier
tr_mult = input.float(defval=1.0, minval=0, title="True Range Multiplier")
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Definitions
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Dominant Cycle
dc = dom_cycle(src, max_cycle_limit)
//Cutoff Period Type
per = cutoff_type == "Fixed" ? fixed_per : math.round(dc * cycle_mult)
//Low Pass Filter
filt = lp(src, per)
//Filtered True Range
TR = math.max(math.max(high - low, math.abs(close - low[1])), math.abs(close - high[1]))
ftr = lp(TR, per) * tr_mult
//Channel Bands
hband = filt + ftr
lband = filt - ftr
//Colors
filt_color = filt > filt[1] ? #38ff97 : filt < filt[1] ? #ff3874 : color.silver
bar_color = filt > filt[1] and src > src[1] and src > filt ? #38ff97 : filt > filt[1] and src <= src[1] and src > filt ? #007538 : filt < filt[1] and src < src[1] and src < filt ? #ff3874 : filt < filt[1] and src >= src[1] and src < filt ? #800026 : color.silver
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Outputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Filter Plot
filt_plot = plot(filt, color=color.new(filt_color, 0), linewidth=3, title="Filter")
//Band Plots
hband_plot = plot(hband, color=color.new(#38ff97, 0), linewidth=1, title="High Band")
lband_plot = plot(lband, color=color.new(#ff3874, 0), linewidth=1, title="Low Band")
//Fills
fill(filt_plot, hband_plot, color=color.new(#007538, 70), title="High Band Fill")
fill(filt_plot, lband_plot, color=color.new(#800026, 70), title="Low Band Fill")
//Bar Color
barcolor(bar_color)
This file is under the Mozilla Public License 2.0; it is a port of the original by DonovanWall, with the original licence header kept and the changes made for FloScript noted in the file.
- v2
Library refresh 2026-10-14
- v1
Library refresh 2026-10-12
Disclaimer. Scripts are written and published by members, or ported by FloSignals from open-source originals, and are their authors' own work and opinion. FloSignals does not review them for correctness and nothing in a script is financial advice or a recommendation to buy or sell anything — read the Risk Disclaimer. Posting here is under the Community Rules; a script that is not the poster's to post can be reported as the Copyright & Takedowns page says.

Comments (0)
No comments yet. Members can leave one.