John Ehlers Trendflex and Reflex for ThinkorSwim

borntostun

New member
Lifetime
So the latest S&C includes an intriguing, new indicator from John Ehlers -- the Trendflex. Code is provided in Trader's Tips, but I've also located a modified version over on TradingView that has some options and tricks that are attractive.

I'm curious if anyone could assist in translating the pinescript to thinkscript? Thanks all!

Code:
//@version=4
study("TrendFlex Oscillator - Dr. John Ehlers", "TFO", false, format.price, 2)

bgcolor(color.new(#000000,15), title="Dark Background")

trendflex(Series, PeriodSS, PeriodTrendFlex, PeriodEMA) =>
    var SQRT2xPI = sqrt(8.0) * asin(1.0) // 4.44288293815 Constant
    alpha = SQRT2xPI / PeriodSS
    beta = exp(-alpha)
    gamma = -beta * beta
    delta = 2.0 * beta * cos(alpha)
    float superSmooth = na, superSmooth := (1.0 - delta - gamma) * (Series + nz(Series[1])) * 0.5 + delta * nz(superSmooth[1]) + gamma * nz(superSmooth[2])
    E = 0.0
    for i=1 to PeriodTrendFlex
        E := E + superSmooth - nz(superSmooth)
    epsilon = E / PeriodTrendFlex
    zeta = 2.0 / (PeriodEMA + 1.0)
    float EMA = na, EMA := zeta * epsilon * epsilon + (1.0 - zeta) * nz(EMA[1])
    return = EMA==0.0 ? 0.0 : epsilon / sqrt(EMA)

source                  = input( close,                              "Source", input.source)
periodTrendFlex         = input(    20,                    "TrendFlex Period", input.integer, minval=2)
useSuperSmootherOveride = input( false, "Apply SuperSmoother Override Below*", input.bool)
periodSuperSmoother     = input(   8.0,               "SuperSmoother Period*", input.float  , minval=4.0, step=0.5)
postSmooth              = input(  33.0,                "Post Smooth Period**", input.float  , minval=1.0, step=0.5)
lineThickness           = input(     2,            "---- Line Thickness ----", input.integer, options=[1,2,3])
showArea                = input("Show",                        "Display Area", input.string , options=["Show","Hide"])
upperLevel              = input(   1.0,                         "Upper Level", input.float  , minval= 0.1, maxval= 2.0, step=0.1)
lowerLevel              = input(  -1.0,                         "Lower Level", input.float  , minval=-2.0, maxval=-0.1, step=0.1)
var HIDE_AREA = not (showArea=="Show")
if(not useSuperSmootherOveride)
    periodSuperSmoother := periodTrendFlex * 0.5

trendFlexOscillator = trendflex(source, periodSuperSmoother, periodTrendFlex, postSmooth)

plot(        0.0, color=#FFFFFF22, linewidth=7            , editable=false)
hline(       0.0, color=#FFFFFFff, title=           "Zero", editable=false)
hline(upperLevel, color=#FF0000ff, title="Upper Threshold")
hline(lowerLevel, color=#00FF00ff, title="Lower Threshold")

plot(HIDE_AREA ? na : trendFlexOscillator, color=#AA00FF  , transp=80, style=plot.style_area, title="TrendFlex Area")
plot(                 trendFlexOscillator, color=#AA00FFff, linewidth=lineThickness         , title="TrendFlex")

https://www.tradingview.com/script/8ZSALctc-TrendFlex-Oscillator-Dr-John-Ehlers/
 
Last edited by a moderator:
Solution
@borntostun TASC published 2 scripts in their Feb issue. They put together a pair of studies based on the article by John Ehlers, “Reflex: A New Zero-Lag Indicator.” The first script is called Reflex and the second script is called Trendflex. Here are the links that TASC published

Reflex

Code:
declare lower;

input length = 20;

def filter = reference EhlersSuperSmootherFilter("cutoff length" = length / 2);
def slope = (filter[length] - filter) / length;
def average = (fold i = 1 to length + 1 with sum do sum + (filter + i * slope) - filter[i]) / length;
def rms = Sqrt(ExpAverage(Sqr(average), 50));

plot Reflex = average / rms;
plot ZeroLine = 0;

Reflex.SetDefaultColor(color = Color.DOWNTICK)...

tomsk

Well-known member
VIP
@borntostun TASC published 2 scripts in their Feb issue. They put together a pair of studies based on the article by John Ehlers, “Reflex: A New Zero-Lag Indicator.” The first script is called Reflex and the second script is called Trendflex. Here are the links that TASC published

Reflex

Code:
declare lower;

input length = 20;

def filter = reference EhlersSuperSmootherFilter("cutoff length" = length / 2);
def slope = (filter[length] - filter) / length;
def average = (fold i = 1 to length + 1 with sum do sum + (filter + i * slope) - filter[i]) / length;
def rms = Sqrt(ExpAverage(Sqr(average), 50));

plot Reflex = average / rms;
plot ZeroLine = 0;

Reflex.SetDefaultColor(color = Color.DOWNTICK);
ZeroLine.SetDefaultColor(color = Color.GRAY);

Trendflex

Code:
declare lower;

input length = 20;

def filter = reference EhlersSuperSmootherFilter("cutoff length" = length / 2);
def average = (fold i = 1 to length + 1 with sum do sum + filter - filter[i]) / length;
def rms = Sqrt(ExpAverage(Sqr(average), 50));

plot Trendflex = average / rms;
plot ZeroLine = 0;

Trendflex.SetDefaultColor(color = Color.DOWNTICK);
ZeroLine.SetDefaultColor(color = Color.GRAY);
 
Solution

borntostun

New member
Lifetime
Ya, I got those . . . I just like how the TradingView scipt has some added features? ;) .

Apologies, I'm no coder.

Any help/teaching as to how to make some simple changes to the code provided from S&C?

I'd love to place a dashed horizontal line at -1 (in green) and +1 (in red) on this indicator -- with alerts on cross ups of green and cross downs of red.

Code:
declare lower;

input length = 20;

def filter = reference EhlersSuperSmootherFilter("cutoff length" = length / 2);
def average = (fold i = 1 to length + 1 with sum do sum + filter - filter) / length;
def rms = Sqrt(ExpAverage(Sqr(average), 50));

plot Trendflex = average / rms;
plot ZeroLine = 0;

Trendflex.SetDefaultColor(color = Color.DOWNTICK);
ZeroLine.SetDefaultColor(color = Color.GRAY);
 

tomsk

Well-known member
VIP
@borntostun Here are the modifications for lines and alerts to your study, as requested

Code:
declare lower;

input length = 20;

def filter = reference EhlersSuperSmootherFilter("cutoff length" = length / 2);
def average = (fold i = 1 to length + 1 with sum do sum + filter - filter[i]) / length;
def rms = Sqrt(ExpAverage(Sqr(average), 50));

plot Trendflex = average / rms;
plot ZeroLine = 0;
plot one = 1;
plot minusOne = -1;

Trendflex.SetDefaultColor(color = Color.DOWNTICK);
ZeroLine.SetDefaultColor(color = Color.GRAY);
one.SetDefaultColor(Color.Red);
minusOne.SetDefaultColor(Color.Green);

Alert(Trendflex crosses above minusOne, "Cross above -1", Alert.Bar, Sound.Ring);
Alert(Trendflex crosses below one, "Cross below +1", Alert.Bar, Sound.Bell);
 

tomsk

Well-known member
VIP
You already have the right syntax, so why not go ahead and implement your change - that is always the best way to learn the effects of your changes!
 

dolomick

Member
Look here

JVA9GYB.png


Reflex is on top, then Trendflex, then RSI, shown in that order The red shows a divergence that could be used to short. The yellow shows the overall trend and a long entry. RSI not giving nearly that much information, no obvious entries shown.
 
Last edited by a moderator:

horserider

Well-known member
VIP
Thanks for the example. That should help those interested in this indicator. I will say the RSI can supply lots of information. Careful not to discount it too quickly.
 

diazlaz

Well-known member
2019 Donor
VIP
There are a number of new studies and strategies in the April 2020 Release of TOS. Take a look at it and share you're experiences and let's let's see how they pair up?

Anyone?

LeavittConvolutionAcceleration

The Leavitt Convolution Acceleration study is a technical indicator designed by Jay A. Leavitt, PhD. Based on linear regression, this indicator estimates the momentum of the projected price change.

LeavittConvolution

The Leavitt Convolution study is a technical indicator designed by Jay A. Leavitt, PhD. It calculates the extrapolation of the extrapolated price value for the upcoming bars.

OnBalanceVolumeModified

The OnBalanceVolumeModified (OBVM) study is a technical indicator introduced by Vitali Apirine. It is a variation of OnBalanceVolume (OBV). In the modified version, OBV is given a smoothing (by an exponential moving average, by default). In addition, a signal line is introduced. The signal line is a slower moving average of the smoothed-out OBV.

Reflex

The Reflex indicator helps reveal market data cycles. It is based on a model that regards market data as a combination of data cycles and short-term trends. In this model, trends start at a cycle peak or valley and end at the adjacent peak or valley, correspondingly. Carefully selecting the projected cycle length and analyzing the values of the Reflex indicator, one can identify the turning points as stipulated by this model.

RSMK

RSMK is a technical indicator introduced by Markos Katsanos in an attempt to improve existing relative strength-based indicators. RSMK calculates the strength of a security relative to another security or index. It can be used to analyze intermarket relationships.

Trendflex

The Trendflex indicator is a variation of the Reflex study. It is an oscillator that helps reveal market data cycles. It is based on a model that regards market data as a combination of data cycles and short-term trends. This model is slightly different than the model used in Reflex: in Trendflex, trendlines are always horizontal, ending at the most recent peak or valley and starting above or below the previous peak or valley. Carefully selecting the projected cycle length and analyzing the values of the Trendflex indicator, one can identify the turning points as stipulated by this model.

GandalfProjectResearchSystem

GandalfProjectResearchSystem is a trading strategy developed by Domenico D'Errico and Giovanni Trombetta. This strategy uses such data as candle average price (ohlc4), median price, and mid-body value to spot the points of price weakness to add entry signals. Sell signals are added after a certain time or price condition is met.

RSMKStrat

RSMKStrat is a strategy introduced by Markos Katsanos. It is based on the eponymous technical indicator, which calculates the strength of a security relative to another security or index. The strategy adds a buy to open simulated order when RSMK crosses above the zero level (which signifies that the primary security starts to outperform the secondary one). This simulated order is automatically closed by an opposite simulated order after a specified number of bars elapses since the entry.
 

tradebyday

Active member
Modified TrendFlex with an HMA overlay. Set HMA plot to dots, width 2. Better than the original TOS is giving for me but maybe play with the moving average overlays if you wish
Code:
declare lower;

input length = 100;

def filter = reference EhlersSuperSmootherFilter("cutoff length" = length / 2);
def average = (fold i = 1 to length + 1 with sum do sum + filter - filter[i]) / length;
def rms = Sqrt(ExpAverage(Sqr(average), 50));

plot Trendflex = average / rms;
plot ZeroLine = 0;

input length2 = 5;
input displace = 0;

plot HMA = MovingAverage(AverageType.HULL, TrendFlex, length2)[-displace];

HMA.DefineColor("Up", GetColor(1));
HMA.DefineColor("Down", GetColor(0));
HMA.AssignValueColor(if HMA > HMA[1] then HMA.color("Up") else HMA.color("Down"));

Trendflex.SetDefaultColor(color = Color.DOWNTICK);
ZeroLine.SetDefaultColor(color = Color.GRAY);
 

irishgold

Member
I found this zero lag indicator by John Elder see link https://fxstill.com/indikators/john-ehlers-reflex-a-new-zero-lag-indicator

I understand most of the code but not sure how to do a loop using the "fold" operator.

Here is ninjascript:

Code:
double sq = Math.Sqrt(2);
                   double a1 = Math.Exp(-sq * Math.PI / (0.5 * Length));
                   double b1 = 2 * a1 * Math.Cos(sq * Math.PI / (0.5 * Length));
                c2 = b1;
                c3 = -a1 * a1;
                c1 = 1 - c2 - c3;              
            }
            else if (State == State.DataLoaded)
            {              
                fl = new Series<double>(this);
                ts = new Series<double>(this);
                rs = new Series<double>(this);
            }
        }


        protected override void OnBarUpdate()
        {
            if(CurrentBar < 3) return;
            fl[0] = c1 * (Close[0] + Close[1]) / 2 + c2 * fl[1] + c3 * fl[2];
            if(CurrentBar < Length) return;
               double sum0 = 0, sum1 = 0;
               double slope = (fl[Length] - fl[0]) / Length;      
            for(int i = 1; i <= Length; i++) {
                sum0 += fl[0] - fl[i];
                sum1 += (fl[0] + i * slope) - fl[i];
            }
           
            sum0 /= Length;
            sum1 /= Length;      
           
            ts[0] = 0.04 * sum0 * sum0 + 0.96 * ts[1];
            rs[0] = 0.04 * sum1 * sum1 + 0.96 * rs[1];  
           
            if(ts[0] != 0) Trendflex[0] = sum0/Math.Sqrt(ts[0]);
            if(rs[0] != 0) Reflex[0]    = sum1/Math.Sqrt(rs[0]);


The for loop is what I am trying to convert primarily if possible.

What I have so far:

Code:
input length = 20;
# code from Ninjatrader
def sq = Sqrt(2);
def a1 = Exp(-sq * Double.Pi / (0.5 * length));
def b1 = 2 * a1 * Cos(sq * Double.Pi / (0.5 * length));
def c2 = b1;
def c3 = -a1 * a1;
def c1 = 1 - c2 - c3;
def sum0 =double.naN;
def sum1 = double.NaN;

def f1 = c1 * (close[0] + close[1]) / 2 + c2 * f1[1] + c3 * f1[2];
def slope = (f1[length] - f1[0]) / length;

Creating the loop is what I am not sure how to code? I know I need to use the fold operator to recursively compute sum0 over the last 20 bars = length

If anyone sees a solution I would appreciate some guidance.
 

BillW

New member
I've been playing with Reflex Oscillator with modifications by including a define color script and painting strategy set to histogram as scalper on a 1minute /MNQ I use TRIX default for trend

Code:
#
# TD Ameritrade IP Company, Inc. (c) 2020-2021
#

declare lower;

input length = 20;

def filter = reference EhlersSuperSmootherFilter("cutoff length" = length / 2);
def slope = (filter[length] - filter) / length;
def average = filter + slope * (length + 1) / 2 - Sum(filter, length)[1] / length;
def rms = Sqrt(ExpAverage(Sqr(average), 50));

plot Reflex = average / rms;
plot ZeroLine = 0;

Reflex.SetDefaultColor(color = Color.DOWNTICK);
ZeroLine.SetDefaultColor(color = Color.GRAY);

reflex.DefineColor("Up", Color.green);
reflex.DefineColor("Down", Color.magenta);
reflex.DefineColor("Even", Color.WHITE);
reflex.AssignValueColor(if reflex > reflex[1] then reflex.Color("Up") else (if reflex == reflex[1] then reflex.Color("Even") else reflex.Color("Down")));
reflex.SetLineWeight(3);
reflex.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
 
Last edited:

Similar threads

Top