Nested IF THEN syntax in thinkscript?

Thebtrader

Member
VIP
If I want to say the following: if A=true AND B=true then X else Y. How do I handle double conditionality of if-then statement in thinkscript?
 

evanevans

Active member
Sorry if this has been asked before, but I couldn't get to the bottom of searching for this because the words "if" and "then".

How can you use an IF THEN statement to condition several lines of code?

Example:

Code:
def x=true;
If x then {
code line 1;
code line 2;
code line 3;
};
 

JebFrenko

New member
I'm trying to duplicate a snippet I have on another platform but and running into a brick wall. I am basically trying to color a line one way on the first occurrence of a condition and keep that color until the first occurrence of a different condition. I am breaking the if's into nested singles but the first one errors out "if MyUpFlag = False then {" telling me I need double equal sign. Elsewhere the algorithm is simple:

Code:
Var:
    vHi(0),
    vLo(0),
    MyUpFlag(False),
    MyDnFlag(False),
    thePlotter(0);

If C > vHi and MyUpFlag = False then
Begin
    MyUpFlag = True;
    MyDnFlag = False;
    thePlotter = Green;
End
Else If C < vLo and MyDnFlag = False then
Begin
    MyUpFlag = False;
    MyDnFlag = True;
    thePlotter = Red;
End;

Here I can't even get to first base. Can anyone help or point me to some examples that might help
 

MatthewA

Active member
Hello @JebFrenko I don't know what you want condition you wish to plug in but here is a lower that counts the number of bar between when some event happens and then another event happens. You would use the state of the events to turn different colors or arrows on or off...

Code:
# ConsecutiveBarCount
# Comment out unnecessary portions to preserve TOS memory and enhance speed
declare lower;
declare once_per_bar;
def nan = Double.NaN;
#### What is the Up Flag and What is the Down Flag??? Use whatever you like... RSI MACD whichever
#[B](You can give me an example case to plugin here!) I don't care what but I can't think of anything HigherHigh Lower Low??)[/B]
#Var:
#   vHi(0),
#    vLo(0),                 
#    MyUpFlag(False),
#    MyDnFlag(False),
#    thePlotter(0);

def zeroLine = 0;
plot pZeroLine = zeroLine;
pZeroLine.SetDefaultColor(Color.WHITE);

def barUpCount = CompoundValue(1, if MyDnFlag && !MyUpFlag then barUpCount[1] + 1 else 0, 0);
def AscendedProfile = CompoundValue(1, if barUpCount && !MyDnFlag[1] then 1 else if MyUpFlag or MyDnFlag then 0 else if !MyDnFlag && !MyUpFlag && AscendedProfile[1]>0 then  AscendedProfile[1]+1 else 0,0);
plot pBarUpCount = if AscendedProfile > 0 within 1 bar && !MyUpFlag then AscendedProfile else 0;
pBarUpCount.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
pBarUpCount.AssignValueColor(Color.GREEN);

def barDownCount = CompoundValue(1, if !MyDnFlag && MyUpFlag then barUpCount[1] + 1 else 0, 0);
def DescendedProfile = CompoundValue(1, if barDownCount && !MyUpFlag[1] then 1 else if MyUpFlag or MyDnFlag then 0 else if !MyDnFlag && !MyUpFlag && AscendedProfile[1]>0 then  AscendedProfile[1]+1 else 0,0);
plot pBarDownCount = if AscendedProfile > 0 within 1 bar && !MyDnFlag then DescendedProfile else 0;
pBarUpCount.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
pBarUpCount.AssignValueColor(Color.Red); [CODE]

We can plug in anything you want. I am glad I bumped into you because I don't think manuals explain translation to this detail...
Are you from TradingView???
 

JebFrenko

New member
Thank you for the info, it should keep me busy over the long weekend. I do have a TradingView but I only use it when I am out and about. I come from TradeStation land. The high and low is basically a channel I paint. I can eyeball things and I have it on TS but I wanted to even things up on TOS. As simple as if / thens usually are - it is the one thing (and variables) that kick my rear. For coding if I have something to actually do I can usually get something working, until this. I appreciate the help.
 

MatthewA

Active member
I come from TradeStation land. The high and low is basically a channel I paint.
I could also do a lower with the [Concat]command and those lines of codes stay open and keep counting until a condition is met...
But those use up a lot of resources compared to the [CompoundValue] line I gave you... IDK if tradestation easylanguage has an equivalent of that so you would need to nest a whole lot of loops to do that without hand entering Support & Resistance...
On Thinkscript the complaint I hear what you have to look out for is it hates math and Java only likes logic. That's kinda cool TradeView interprets your drawings into logic...

If you want to make up a condition for HIGH or LOW I will plug those in... If you become a VIP member they have some new indicators called BuyTheDip & TakeProfits which are basically a community tested vLow(0) & vHigh(0). I am glad I became a VIP https://usethinkscript.com/p/get-vip/
 
I need some help figuring out why my if-else statement is not working correctly.

The following code is supposed to create a line which jumps up and down from the low to the high of candles based on which is farther from the value plotted from the previous day, but it always plots the line on the high of each candle:

Code:
def XR;
def highdiff;
def lowdiff;

if BarNumber() == 1
    {XR = hl2;
    highdiff = 0;
    lowdiff = 0;
    }
else
    {highdiff = AbsValue(high - XR[1]);
    lowdiff = AbsValue(low - XR[1]);
    if lowdiff < highdiff
        {XR = low;}
    else
        {XR = high;}
    }

plot XRI = XR;

In the line "if lowdiff < highdiff" should have XR set to the low in some cases and to the high in others, but it's always going to the 'else' code regardless.

In this almost identical code, I'm plotting the value of the condition "lowdiff < highdiff" directly - this is to verify that lowdiff and highdiff do in fact criss-cross above and below each other, and therefore the if-else statement does not always return false:

Code:
declare lower;
def XR;
def highdiff;
def lowdiff;

if BarNumber() == 1
    {XR = hl2;
    highdiff = 0;
    lowdiff = 0;
    }
else
    {highdiff = AbsValue(high - XR[1]);
    lowdiff = AbsValue(low - XR[1]);
    if lowdiff < highdiff
        {XR = low;}
    else
        {XR = high;}
    }

plot XRI = lowdiff < highdiff;

Here's an image of the two plotted together:

Code-01.jpg


Can anyone help me figure out why the condition I'm using is working, but the if-else always goes to else? My brain's fried after grinding on this for two hours...
 
Last edited:

XeoNoX

Well-known member
VIP
@MoneyMagnet it can be represented with the short code as well as the worded code, its up to the coder, for learnings purposes its always friendlier to write it out worded so its easier to learn from for those that choose to learn.
 
@MoneyMagnet Your condition for barnumber() == 1 is never satisfied except for the beginning. Add addlabel(yes, barnumber()) to your script and you'll see what barnumber() is returning.

Interesting suggestion, @generic, but I'm not sure how AddLabel() helps me here. When I add it, what I get is a display of the value of BarNumber() based on the current bar - how does it tell me what BarNumber() was when it was calculating the first bar? On the chart I'm using, BarNumber() for the current bar is 253; surely the numbers of earlier bars were different, no?

In any case, the image I showed clearly establishes that at any given bar, the value of XR is the high of that bar (upper plot), whereas the result of the condition "lowdiff < highdiff" frequently changes (sometime true(1) and sometimes false(0)). Since the value of XR for each bar is set by the if-else statement based on that condition, the value of XR should be changing from high to low to high, etc.
 
To be more clear and focus on the question at hand:

2020-12-29-text.jpg


My understanding is that since the value of the condition changes, the result of the if-else statement should change, too. When the condition is true, the statement "XR = low;" should run, and when the condition is false, the statement "XR = high;" should run. Instead, it's always running the second statement.

Somehow, I'm doing something wrong (or expecting something I shouldn't expect) but for the life of me I don't see why it's acting this way. I'm hoping someone more knowledgeable and experienced than me can help fill in the gaps in my knowledge.
 

generic

Active member
@MoneyMagnet Ohh okay you're talking about the nested if-else statement. The problem is with your math absvalue(high - xr[1]) is always lower than absvalue(low - xr[1]). Xr[1] = high so (high - xr[1]) = 0 which is always lower than absvalue(low - xr[1]).
 
@generic:
'high' refers to the high of the current bar, whereas XR[1] refers to the value set during the calculation of the previous bar. Even if XR[1] had been set to the high of the previous bar, that high would most likely not be the same as the high of the current bar, so your statement that 'AbsValue(high - XR[1]) = 0' is not correct, most of the time.
 
I got the result I was looking for with this code, which uses CompoundValue() to initialize the series variable instead of "if BarNumber() == 1".

Code:
def XR = CompoundValue(1, if AbsValue(low - XR[1]) > AbsValue(high - XR[1]) then low else high, high);

plot ZIGGY = XR;

I had read in this post by the estimable @korygill that one could use the "if BarNumber()" method instead of CompoundValue(), but if so I'm doing something wrong, so I'd still like to know how to make it work. For now, I'll just move on...

Thanks to all who joined this thread and added their perspectives!
 

korygill

Well-known member
VIP
@MoneyMagnet so you want to convert the CompoundValue call to use the BarNumber technique?

Post the full, working, code, and I might be able to help. From the above, I think it would be something like

Code:
def bn=BarNumber();
def XR;
#def XR = CompoundValue(1, if AbsValue(low - XR[1]) > AbsValue(high - XR[1]) then low else high, high);

if (bn==1) then {
XR = high;
} else {
if AbsValue(low - XR[1]) > AbsValue(high - XR[1]) then XR=low else XR=high
}
 
@korygill: Thanks for taking a look for me:)

This is the full working code - using CompoundValue():

Code:
def XR = CompoundValue(1, if AbsValue(low - XR[1]) > AbsValue(high - XR[1]) then low else high, high);
plot ZIGGY = XR;

It's merely intended to plot a line between highs and lows, each point based on which (high or low) is farthest from the previous bar's point.

Below is my code that attempts to do the same thing, but using BarNumber() to initialize XR (copied from the first post):

Code:
def XR;
def highdiff;
def lowdiff;

if BarNumber() == 1
    {XR = hl2;
    highdiff = 0;
    lowdiff = 0;
    }
else
    {highdiff = AbsValue(high - XR[1]);
    lowdiff = AbsValue(low - XR[1]);
    if lowdiff < highdiff
        {XR = low;}
    else
        {XR = high;}
    }

plot XRI = XR;

But here the plot stays always at the high; regardless of the result of the condition (lowdiff < highdiff), it always executes the "else" code, and never the "then" code.

Based on the code you posted, I created this version, which omits the unneeded variables for lowdiff and highdiff and adds a variable for bn... but the result is the same:

Code:
def bn = BarNumber();
def XR;

if bn == 1
    {XR = high;}
else
    {if AbsValue(low - XR[1]) > AbsValue(high - XR[1])
        {XR = low;}
    else
        {XR = high;}
    }
plot XRI = XR;

If you can help me figure out why this concept works when XR is initialized using CompoundValue() but acts incorrectly when XR is initialized using BarNumber(), I would be eternally grateful. For my immediate purposes, using CompoundValue() is sufficient, but it would be great to know what's going wrong when I try to use BarNumber() because
  1. Sometimes I want to assign values to an initialized series variable using more complex code - such as multiple statements or structured statements. I don't think you can do that within the second argument of a CompoundValue() function.
  2. As you (@korygill) stated in your other post, CompoundValue() may not always work if used more than once in a single code.
  3. As a student of thinkScript, I'd like to understand the BarNumber() function, and clearly there is something I'm missing...
 

korygill

Well-known member
VIP
+ @MoneyMagnet

This is totally messed up, and there is a serious bug in thinkscript. But it appears if you follow the (well my) best practice of always using variables for high/low/etc to reduce calls to the server, it works as expected.

+ @BenTen --> you might want to take note of always using the "v" variables I typically use like:
def vClose = close;

Use this study and you can see the bug and see it working by changing 2 lines. You can also see how I used AddChartBubble to debug this. I used a 6 period daily chart. I also made the c1 variable just to confirm the > operator was working as expected....

Code below with a comment to show you how to turn the bug on/off. (the code below is the working code)

Code:
declare lower;
declare once_per_bar;

def bn = BarNumber();
def vlow = low;
def vhigh = high;


def XR_C = CompoundValue(1, if AbsValue(low - XR_C[1]) > AbsValue(high - XR_C[1]) then low else high, high);

def XR;
def lowdiff;
def highdiff;
def c1; # condition 1

if (bn == 1) then {
    lowdiff = high-low;
    highdiff = 0;
    XR = high;
    c1 = 0;
} else {
    lowdiff = AbsValue(low - XR[1]);
    highdiff = AbsValue(high - XR[1]);
    c1 = lowdiff > highdiff;

    # strange BUG in thinkscript!
    # if you use low/high below, XR is always HIGH
    # using vlow and vhigh, works as expected!
    if c1==1 then {
        XR = vlow;       
    } else {
        XR = vhigh;
    }
}

plot ZIGGY = XR;
plot ZIGGY_C = XR_C;

AddChartBubble(
    yes,
    XR,
    "c1:"+c1+"\nld:"+lowdiff+"\nhd:"+highdiff+"\nxr:"+XR+"\nxr_c:"+XR_C+"\nh:"+high+"\nl:"+low,
    color.Gray,
    yes);
 

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.
Top