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)...
@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
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);
 
@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);
 
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!
 
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:
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.
 
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.
 
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);
 
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.
 
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:

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Thread starter Similar threads Forum Replies Date
S John Ehlers Zero Lag Indicator for ThinkorSwim Questions 6

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
562 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top