Ehlers Detrending Filter indicator free

by mfejza in category Oscilator at 28/02/2023
Description

This indicator builds upon Ehlers previous work by attempting to detrend the underlying source data that is used to calculate the final result. He was able to create a leading indicator by removing the trend data and by using his previous calculations to turn the source data into a leading indicator.

There are two ways to understand this indicator. First if the indicator is below the midline then it is in a mid to longterm downtrend and if it is above the midline then it is in a mid to longterm uptrend. Also this indicator shows great promise in predicting future trends so because of that aspect, it may give some false signals from time to time.

Using the ZScore indicator you can produce binary data from DetrendingFilter output data.

Notification Publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section you may use the Copyright Infringement Notification form to submit a claim.
Formula / Source Code
Language: C#
Trading Platform: cAlgocTrader
using System;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo
{
    [Levels(0)]
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class mEhlersDetrendingFilter : Indicator
    {
        [Parameter("Data Source (hlcc4)", DefaultValue = enumPriceTypes.hlcc4)]
        public enumPriceTypes inpPriceType { get; set; }
        [Parameter("Period (10)", DefaultValue = 10)]
        public int inpPeriod { get; set; }

        [Output("Ehlers Detrending Filter", LineColor = "Black", PlotType = PlotType.DiscontinuousLine, Thickness = 1)]
        public IndicatorDataSeries outEDF { get; set; }
        
        private IndicatorDataSeries _price, _edf, _filtq;
        private double _cosine, _filt, _coef;
        

        protected override void Initialize()
        {
            _price = CreateDataSeries();
            _edf = CreateDataSeries();
            _filtq = CreateDataSeries();
        }

        public override void Calculate(int i)
        {
            switch (inpPriceType)
            {
                case enumPriceTypes.Open:
                    _price[i] = Bars.OpenPrices[i];
                    break;
                case enumPriceTypes.Close:
                    _price[i] = Bars.ClosePrices[i];
                     break;
                case enumPriceTypes.High:
                     _price[i] = Bars.HighPrices[i];
                     break;
                case enumPriceTypes.Low:
                     _price[i] = Bars.LowPrices[i];
                     break;
                case enumPriceTypes.Median:
                     _price[i] = Bars.MedianPrices[i];
                     break;
                case enumPriceTypes.Typical:
                    _price[i] = Bars.TypicalPrices[i];
                    break;
                case enumPriceTypes.Weighted:
                    _price[i] = Bars.WeightedPrices[i];
                    break;
                case enumPriceTypes.hl2:
                    _price[i] = (Bars.HighPrices[i] + Bars.LowPrices[i]) / 2;
                    break;
                case enumPriceTypes.hlc3:
                    _price[i] = (Bars.HighPrices[i] + Bars.LowPrices[i] + Bars.ClosePrices[i]) / 3;
                    break;
                case enumPriceTypes.hlcc4:
                    _price[i] = (Bars.HighPrices[i] + Bars.LowPrices[i] + Bars.ClosePrices[i] + Bars.ClosePrices[i]) / 4;
                    break;
                case enumPriceTypes.ohlc4:
                    _price[i] = (Bars.OpenPrices[i] + Bars.HighPrices[i] + Bars.LowPrices[i] + Bars.ClosePrices[i]) / 4;
                    break;
                case enumPriceTypes.FIR:
                    _price[i] = i>4 ? (Bars.ClosePrices[i] + 2.0 * Bars.ClosePrices[i-1] + 2.0 * Bars.ClosePrices[i-2] + Bars.ClosePrices[i-3]) / 6.0 : Bars.ClosePrices[i];
                    break;
                default:
                    _price[i] = Bars.ClosePrices[i];
                     break;
            }

            _edf[i] = i>1 ? (0.95 * _price[i]) - (0.95 * _price[i-1]) + (0.95 * _edf[i-1]) : (0.95 * _price[i]);
            _filt = 0;
            _coef = 0;
            for (int j=1; j<=inpPeriod; j++)
            {
                _cosine = 1 - Math.Cos(2 * Math.PI * j / (inpPeriod + 1));
                _filt += _filt + (_cosine * _edf[i-j-1]);
                _coef += _coef + _cosine;
            } 
            _filtq[i] = _coef != 0 ? _filt / _coef : 0;
            
            outEDF[i] = _filtq[i];
        }
    }
    
    public enum enumPriceTypes
    {
        Open,
        Close,
        High,
        Low,
        Median,
        Typical,
        Weighted,
        hl2,
        hlc3,
        hlcc4,
        ohlc4,
        FIR
    }
}
Comments
0