# How Is Trend Reversal Calculated

Status
Not open for further replies.

#### JLEE

##### New member
such as this:
Code:
``````input usemanualfibskip = no;#Hint usemanualfibskip: Select no to use preprogrammed fibskip amounts. Select no, to use the amount entered at input fibskip.
input fibskip = .50;#Hint fibskip: Set input usemanualfibskip == yes to use this amount versus preprogrammed amounts. Standard is 1.0. This is percentage difference between fib high and low before a new fib grid created.
def showBubblesfibratio = no;
def showFibLabel = no;#Hint showfibLabel: Select yes to show label of current fib level as of last price
def showfiblines = no;
def fib1level = .236;
def fib2level = .382;
def fibMlevel = .500;
def fib3level = .618;
def fib4level = .786;
#Fibs
def datacount2 = (HighestAll(data1) - data1[1]);
def numberfibretracementstoshow = 2;
def fibskipit = if usemanualfibskip == no then if close > 800 then .25 else .5 else fibskip;
def EIfibh = if EISave == priceh and AbsValue(EISave - EISave[1]) > priceh * fibskipit * .01 then priceh else EIfibh[1];
def EIfibl = if EISave == pricel and AbsValue(EISave - EISave[1]) > priceh * fibskipit * .01 then pricel else EIfibl[1];
def range = EIfibh - EIfibl;
def fibH = if showfiblines == no then Double.NaN else if datacount2 <= numberfibretracementstoshow then EIfibh else Double.NaN;
def fibL = if showfiblines == no then Double.NaN else if datacount2 <= numberfibretracementstoshow then EIfibl else Double.NaN;
def fibM = if showfiblines == no then Double.NaN else if datacount2 <= numberfibretracementstoshow then EIfibl + range * fibMlevel else Double.NaN;
def fib1 = if showfiblines == no then Double.NaN else if datacount2 <= numberfibretracementstoshow then EIfibl + range * fib1level else Double.NaN;
def fib2 = if showfiblines == no then Double.NaN else if datacount2 <= numberfibretracementstoshow then EIfibl + range * fib2level else Double.NaN;
def fib3 = if showfiblines == no then Double.NaN else if datacount2 <= numberfibretracementstoshow then EIfibl + range * fib3level else Double.NaN;
def fib4 = if showfiblines == no then Double.NaN else if datacount2 <= numberfibretracementstoshow then EIfibl + range * fib4level else Double.NaN;

AddLabel(showFibLabel, Concat( "Current Fib Level ", AsPercent((close - EIfibl) / (range))), if close > EIfibl then Color.GREEN else if EIfibh == close then Color.WHITE else Color.RED);

AddChartBubble(showBubblesfibratio and !IsNaN(EI) and BarNumber() != 1, if isUp then priceh * (1 + bubbleoffset) else pricel * (1 - bubbleoffset) , if isUp then AsPercent((priceh - EIfibl) / (range)) else AsPercent((pricel - EIfibl) / range), if isUp and chghigh > 0 then Color.DARK_GREEN else if isUp and chghigh < 0 then Color.DARK_RED else if isUp then Color.DARK_GREEN else if !isUp and chglow > 0 then Color.DARK_GREEN else if !isUp and chglow < 0 then Color.DARK_RED else Color.DARK_RED, isUp);``````

Last edited by a moderator:
Solution
@JLEE @MerryDay Maybe this can help - it removes a lot of unnecessary fluff from the indicator. The EMAs (the 9, 14, and 21) and fib retracements are extra for the indicator and are not shown. For instance, the three EMAs are only used for the color of the reversal bubbles, and the fib code itself is just dead weight, nothing is even plotted from the calculations. There are also a lot of bubbles and labels in the code that are turned off by default in the original indicator. There's a bunch of stuff that isnt being used in the original. I uncovered a few plots and added a bit to make the visuals easier. Not an expert, but hope this helps

Code:
``# used to switch between "zigzag based on high/low of price" and "zigzag based on...``
can you describe how the 1% fib works specially?

Also, i notice the drop down in set up asked to choose between the EMA and zigzagHighLow. odes this mean the ZigZag is not being considered if Moving Average is selected?

[/IMG]

@MerryDay my apology also for being confusing a bit. I also seeking to understand how the code works for Trend Reversal. Where in the code does it combine EMA, ZigZag, and Fib into the decision to offer up a signal? I stripped away Fib and ZigZag from code and signal is same with EMA alone as it is with all three. so am confused if Fib and ZigZag are actually being considered

@JLEE If you choose average, you get one set of signals.. When you choose highlow, you get both the average and the zigzag

ok this is very helpful indeed! i was stuck. so the fib section of code offers up the lines above and below the signals as appropriate is that correct?

sorry one more question. when i run the Average and then map onto it the lines EMA for 9, 14, 21 it is clear as the rules for EMA apply but I noticed that the conditions for a signal sometimes also apply to the previous period also and so wondering why the signal did not appear in the previous candle. i can show example if not clear

@JLEE The Fibonacci Lines are displayed for Support and Resistance. If a stock is dropping, the line below is the support line. If a stock is rising it is resistance. I draw my own S&R lines. But what Fibonacci lines have going for them is: a significant percentage of traders make decisions based on them. Therefore Fibonacci Lines become a self-fulfilling prophecy.

Last edited:
[/IMG]
So am running it here selecting EMA so zigzag is not in play. I added lines showing the EMA 9, 14, 21 to visualize what the study is doing. EMA9 is the lower line, EMA14 is the middle and EMA21 is the upper each using closing price. You can see that the lines never cross. YET i get a BUY trigger at 4354.25 and a SELL trigger a few candles later at 4362.25. When i look at the code for EMA i do not see what is triggering a BUY or SELL here

[/IMG]

is it the CompoundValue element? what is that?

@MerryDay thank you
do have a mathematical formula (set of formulas) that represents the Trend Reversal? would really help me bridge my understanding. I get the repainting point and am not bothered by that. What I am having trouble with is what exactly the Trend Reversal is doing with the data. if not a formula a written step by step of what it is doing (not the ZigZag only the EMA)

@JLEE Due to its recursive nature it takes intermediate data points that you cannot see.
but at each candle what is it calculating exactly? looking at each of the 3 EMAs and then taking average of the high and low of these three and then what? comparing to the last candle low or high or avg or what exactly? effectively what is it comparing the avg high low EMA too exactly. i get that it may repaint but in that moment to determine to signal or not what is it comparing the avg EMAs to precisely to signal a buy or sell? (BTW do you sleep haha)

@MerryDay specific to Trend Reversal code. can someone explain what is going on here..
[/IMG]

@JLEE @MerryDay Maybe this can help - it removes a lot of unnecessary fluff from the indicator. The EMAs (the 9, 14, and 21) and fib retracements are extra for the indicator and are not shown. For instance, the three EMAs are only used for the color of the reversal bubbles, and the fib code itself is just dead weight, nothing is even plotted from the calculations. There are also a lot of bubbles and labels in the code that are turned off by default in the original indicator. There's a bunch of stuff that isnt being used in the original. I uncovered a few plots and added a bit to make the visuals easier. Not an expert, but hope this helps

Code:
``````# used to switch between "zigzag based on high/low of price" and "zigzag based on then high/low of moving averages"
input method = {default average, high_low};

# data for the built-in zigzag indicator which is referenced in the study. To see the ZigZagHighLow() code, look for it in the built-in TOS studies
def bubbleoffset = .0005;
def percentamount = .01;
def revAmount = .05;
def atrreversal = 2.0;
def atrlength = 5;

# data for the moving averages
def pricehigh = high;
def pricelow = low;
def averagelength = 5;
def averagetype = AverageType.EXPONENTIAL;

# here are the moving averages used for the signals - changed to plots and given colors
plot mah = MovingAverage(averagetype, pricehigh, averagelength);
plot mal = MovingAverage(averagetype, pricelow, averagelength);
mah.setdefaultcolor(color.cyan);
mal.setdefaultcolor(color.cyan);

# continues the switch between the two different zigzag data points
def priceh = if method == method.high_low then pricehigh else mah;
def pricel = if method == method.high_low then pricelow else mal;

# references the built-in zigzag indicator
def EI = ZigZagHighLow("price h" = priceh, "price l" = pricel, "percentage reversal" = percentamount, "absolute reversal" = revAmount, "atr length" = atrlength, "atr reversal" = atrreversal);

# not very clear on how this exactly works - but the end result is to plot the zigzag lines
def reversalAmount = if (close * percentamount / 100) > Max(revAmount < atrreversal * reference ATR(atrlength), revAmount) then (close * percentamount / 100) else if revAmount < atrreversal * reference ATR(atrlength) then atrreversal * reference ATR(atrlength) else revAmount;
rec EISave = if !IsNaN(EI) then EI else GetValue(EISave, 1);
def chg = (if EISave == priceh then priceh else pricel) - GetValue(EISave, 1);
def isUp = chg >= 0;
rec isConf = AbsValue(chg) >= reversalAmount or (IsNaN(GetValue(EI, 1)) and GetValue(isConf, 1));
def EId = if isUp then 1 else 0;

# zigzag plot and colors
plot EnhancedLines = if EId <= 1 then EI else Double.NaN;
EnhancedLines.AssignValueColor(if EId == 1 then Color.GREEN else if EId == 0 then Color.RED else Color.DARK_ORANGE);
EnhancedLines.SetStyle(Curve.FIRM);
EnhancedLines.EnableApproximation();
EnhancedLines.HideBubble();

# calculates and plots the arrows
def EIL = if !IsNaN(EI) and !isUp then pricel else GetValue(EIL, 1);
def EIH = if !IsNaN(EI) and isUp then priceh else GetValue(EIH, 1);
def dir = CompoundValue(1, if EIL != EIL[1] or pricel == EIL[1] and pricel == EISave then 1 else if EIH != EIH[1] or priceh == EIH[1] and priceh == EISave then -1 else dir[1], 0);
def signal = CompoundValue(1, if dir > 0 and pricel > EIL then if signal[1] <= 0 then 1 else signal[1] else if dir < 0 and priceh < EIH then if signal[1] >= 0 then -1 else signal[1] else signal[1], 0);
def showarrows = yes;
plot U1 = showarrows and signal > 0 and signal[1] <= 0;
U1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
U1.SetDefaultColor(Color.GREEN);
U1.SetLineWeight(4);
plot D1 = showarrows and signal < 0 and signal[1] >= 0;
D1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
D1.SetDefaultColor(Color.RED);
D1.SetLineWeight(4);``````

As you can see, the 9, 14, and 21 EMAs are not even needed.

Edit: If you look at the code I posted, you can see the line `def showarrows = yes;`. The original code is full of these "defs" that probably were originally meant to be inputs instead. Someone has either changed the original code a lot before @BenTen found and posted it here in the forum, or its just a incomplete mish-mash of different codes. I have no idea

Last edited:
@JLEE @MerryDay Maybe this can help - it removes a lot of unnecessary fluff from the indicator. The EMAs (the 9, 14, and 21) and fib retracements are extra for the indicator and are not shown. For instance, the three EMAs are only used for the color of the reversal bubbles, and the fib code itself is just dead weight, nothing is even plotted from the calculations. There are also a lot of bubbles and labels in the code that are turned off by default in the original indicator. There's a bunch of stuff that isnt being used in the original. I uncovered a few plots and added a bit to make the visuals easier. Not an expert, but hope this helps

Code:
``````# used to switch between "zigzag based on high/low of price" and "zigzag based on then high/low of moving averages"
input method = {default average, high_low};

# data for the built-in zigzag indicator which is referenced in the study. To see the ZigZagHighLow() code, look for it in the built-in TOS studies
def bubbleoffset = .0005;
def percentamount = .01;
def revAmount = .05;
def atrreversal = 2.0;
def atrlength = 5;

# data for the moving averages
def pricehigh = high;
def pricelow = low;
def averagelength = 5;
def averagetype = AverageType.EXPONENTIAL;

# here are the moving averages used for the signals - changed to plots and given colors
plot mah = MovingAverage(averagetype, pricehigh, averagelength);
plot mal = MovingAverage(averagetype, pricelow, averagelength);
mah.setdefaultcolor(color.cyan);
mal.setdefaultcolor(color.cyan);

# continues the switch between the two different zigzag data points
def priceh = if method == method.high_low then pricehigh else mah;
def pricel = if method == method.high_low then pricelow else mal;

# references the built-in zigzag indicator
def EI = ZigZagHighLow("price h" = priceh, "price l" = pricel, "percentage reversal" = percentamount, "absolute reversal" = revAmount, "atr length" = atrlength, "atr reversal" = atrreversal);

# not very clear on how this exactly works - but the end result is to plot the zigzag lines
def reversalAmount = if (close * percentamount / 100) > Max(revAmount < atrreversal * reference ATR(atrlength), revAmount) then (close * percentamount / 100) else if revAmount < atrreversal * reference ATR(atrlength) then atrreversal * reference ATR(atrlength) else revAmount;
rec EISave = if !IsNaN(EI) then EI else GetValue(EISave, 1);
def chg = (if EISave == priceh then priceh else pricel) - GetValue(EISave, 1);
def isUp = chg >= 0;
rec isConf = AbsValue(chg) >= reversalAmount or (IsNaN(GetValue(EI, 1)) and GetValue(isConf, 1));
def EId = if isUp then 1 else 0;

# zigzag plot and colors
plot EnhancedLines = if EId <= 1 then EI else Double.NaN;
EnhancedLines.AssignValueColor(if EId == 1 then Color.GREEN else if EId == 0 then Color.RED else Color.DARK_ORANGE);
EnhancedLines.SetStyle(Curve.FIRM);
EnhancedLines.EnableApproximation();
EnhancedLines.HideBubble();

# calculates and plots the arrows
def EIL = if !IsNaN(EI) and !isUp then pricel else GetValue(EIL, 1);
def EIH = if !IsNaN(EI) and isUp then priceh else GetValue(EIH, 1);
def dir = CompoundValue(1, if EIL != EIL[1] or pricel == EIL[1] and pricel == EISave then 1 else if EIH != EIH[1] or priceh == EIH[1] and priceh == EISave then -1 else dir[1], 0);
def signal = CompoundValue(1, if dir > 0 and pricel > EIL then if signal[1] <= 0 then 1 else signal[1] else if dir < 0 and priceh < EIH then if signal[1] >= 0 then -1 else signal[1] else signal[1], 0);
def showarrows = yes;
plot U1 = showarrows and signal > 0 and signal[1] <= 0;
U1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
U1.SetDefaultColor(Color.GREEN);
U1.SetLineWeight(4);
plot D1 = showarrows and signal < 0 and signal[1] >= 0;
D1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
D1.SetDefaultColor(Color.RED);
D1.SetLineWeight(4);``````

As you can see, the 9, 14, and 21 EMAs are not even needed.

Edit: If you look at the code I posted, you can see the line `def showarrows = yes;`. The original code is full of these "defs" that probably were originally meant to be inputs instead. Someone has either changed the original code a lot before @BenTen found and posted it here in the forum, or its just a incomplete mish-mash of different codes. I have no idea

Crazy helpful. Can I ask you following questions once i go through this?

Crazy helpful. Can I ask you following questions once i go through this?
@Pensar I am trying to build a logic flow diagram for what you just re-created. is that something i could discuss with you off the public forum?

@Pensar thank you for posting a great solution to a muddy mess of a code that was sending my head spinning. I think my reply got deleted as i suggested a discussion offline. No need. Happy to have discussion in open forum. I am trying to build a logic flow chart of what you re-created. is that something you can help create?

Maybe this can help - it removes a lot of unnecessary fluff from the indicator. The EMAs (the 9, 14, and 21) and fib retracements are extra for the indicator and are not shown. For instance, the three EMAs are only used for the color of the reversal bubbles, and the fib code itself is just dead weight, nothing is even plotted from the calculations. There are also a lot of bubbles and labels in the code that are turned off by default in the original indicator. There's a bunch of stuff that isnt being used in the original. I uncovered a few plots and added a bit to make the visuals easier. Not an expert, but hope this helps

Code:
``````# used to switch between "zigzag based on high/low of price" and "zigzag based on then high/low of moving averages"
input method = {default average, high_low};

# data for the built-in zigzag indicator which is referenced in the study. To see the ZigZagHighLow() code, look for it in the built-in TOS studies
def bubbleoffset = .0005;
def percentamount = .01;
def revAmount = .05;
def atrreversal = 2.0;
def atrlength = 5;

# data for the moving averages
def pricehigh = high;
def pricelow = low;
def averagelength = 5;
def averagetype = AverageType.EXPONENTIAL;

# here are the moving averages used for the signals - changed to plots and given colors
plot mah = MovingAverage(averagetype, pricehigh, averagelength);
plot mal = MovingAverage(averagetype, pricelow, averagelength);
mah.setdefaultcolor(color.cyan);
mal.setdefaultcolor(color.cyan);

# continues the switch between the two different zigzag data points
def priceh = if method == method.high_low then pricehigh else mah;
def pricel = if method == method.high_low then pricelow else mal;

# references the built-in zigzag indicator
def EI = ZigZagHighLow("price h" = priceh, "price l" = pricel, "percentage reversal" = percentamount, "absolute reversal" = revAmount, "atr length" = atrlength, "atr reversal" = atrreversal);

# not very clear on how this exactly works - but the end result is to plot the zigzag lines
def reversalAmount = if (close * percentamount / 100) > Max(revAmount < atrreversal * reference ATR(atrlength), revAmount) then (close * percentamount / 100) else if revAmount < atrreversal * reference ATR(atrlength) then atrreversal * reference ATR(atrlength) else revAmount;
rec EISave = if !IsNaN(EI) then EI else GetValue(EISave, 1);
def chg = (if EISave == priceh then priceh else pricel) - GetValue(EISave, 1);
def isUp = chg >= 0;
rec isConf = AbsValue(chg) >= reversalAmount or (IsNaN(GetValue(EI, 1)) and GetValue(isConf, 1));
def EId = if isUp then 1 else 0;

# zigzag plot and colors
plot EnhancedLines = if EId <= 1 then EI else Double.NaN;
EnhancedLines.AssignValueColor(if EId == 1 then Color.GREEN else if EId == 0 then Color.RED else Color.DARK_ORANGE);
EnhancedLines.SetStyle(Curve.FIRM);
EnhancedLines.EnableApproximation();
EnhancedLines.HideBubble();

# calculates and plots the arrows
def EIL = if !IsNaN(EI) and !isUp then pricel else GetValue(EIL, 1);
def EIH = if !IsNaN(EI) and isUp then priceh else GetValue(EIH, 1);
def dir = CompoundValue(1, if EIL != EIL[1] or pricel == EIL[1] and pricel == EISave then 1 else if EIH != EIH[1] or priceh == EIH[1] and priceh == EISave then -1 else dir[1], 0);
def signal = CompoundValue(1, if dir > 0 and pricel > EIL then if signal[1] <= 0 then 1 else signal[1] else if dir < 0 and priceh < EIH then if signal[1] >= 0 then -1 else signal[1] else signal[1], 0);
def showarrows = yes;
plot U1 = showarrows and signal > 0 and signal[1] <= 0;
U1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
U1.SetDefaultColor(Color.GREEN);
U1.SetLineWeight(4);
plot D1 = showarrows and signal < 0 and signal[1] >= 0;
D1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
D1.SetDefaultColor(Color.RED);
D1.SetLineWeight(4);``````

As you can see, the 9, 14, and 21 EMAs are not even needed.

Edit: If you look at the code I posted, you can see the line `def showarrows = yes;`. The original code is full of these "defs" that probably were originally meant to be inputs instead. Someone has either changed the original code a lot before @BenTen found and posted it here in the forum, or its just a incomplete mish-mash of different codes. I have no idea

@Pensar Tremendous! Total superman! Couple of questions if I may:

working backwards, the beef is from line 45 calculating if an arrow is deserving or not and in what direction. It is making this decision using CompoundValue feature which i am still trying to figure out what it is actually doing in simple english (if you know how to do so I would be eternally grateful). I am really only interested in ZigZagMovingAverage option so from my read of code it means references in this "decision" section to EIL or EIH can be considered MAL or MAH respectively.

Where i am getting lost is in the CompoudValue formula there is reference to EISave which is defined on line 32. Can you explain what is going on in line 32 the code of which is

rec EISave = if !IsNaN(EI) then EI else GetValue(EISave, 1);

I know that EI is the ZZHL but what is !IsNaN(EI) ?

@Pensar I am trying to build a logic flow diagram for what you just re-created. is that something i could discuss with you off the public forum?
@JLEE Fortunately or unfortunately, it wouldn't be possible. I'm not on any other site, forum, or discord.
I learned what I know of ThinkScript after being frustrated by my inability to show what and how I wanted data displayed on the chart. The process was mainly through trial and error, looking at other's codes, and experimenting with the different methods. Many things I can do but not exactly explain the how or why it works. I probably wouldn't have the requisite skills or knowledge necessary to satisfy your desire for understanding.

That being said . . .
This is ThinkorSwim's explanation of IsNaN() - https://tlc.thinkorswim.com/center/reference/thinkScript/Functions/Math---Trig/IsNaN . Probably explains it better than I could. I go here - https://tlc.thinkorswim.com/center/reference/thinkScript - when I have a difficulty, although it can at times be lacking the in-depth explanation I'm looking for.

@Pensar

rec EISave = if !IsNaN(EI) then EI else GetValue(EISave, 1);

I know that EI is the ZZHL but what is !IsNaN(EI) ?

That line of code stores what is commonly called a "state" variable value... The !IsNaN(EI) part essentially checks to see whether EI is a number... IsNaN() checks to see whether EI Is Not a Number... By prepending the function with an exclamation mark "!" switches it Is Not a Number to mean Is a Number... This is the same as checking for whether a variable is NULL or not... So !IsNan(EI) is the same as saying EI != NULL... What the line of code essentially means is that if EI contains a value it should be store it in EISave and after that just keep storing the same number in EISave... The use if rec is not used much these days as def can be used for the same purpose these days...

Clear as mud...???

Status
Not open for further replies.

87k+ Posts
373 Online

## The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
• Exclusive indicators
• Proven strategies & setups
• Private Discord community
• Exclusive members-only content
• 1 full year of unlimited support

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?