Help understanding recursive def statement

MrBruceKA

New member
I nee some help to understand how date1 is determined by this def statement.

def date1 = if (expresn) then barnumber() else date1[1];

Actual results using Plot x=data1; with Data Box to see plot varable contents
Bar# expresn data1
1 False N/A
2 False N/A
3 True 3
4 False N/A
5 False N/A

I expected these results
Bar# expresn data1
1 False 0
2 False 0
3 True 3
4 False 3
5 False 3

I do not understanding the actual results vs. what i expect. Thanks for the explanation.

Bruce
 
Solution
Isn't date1 zero at the beginning of the program?


maybe...
i have seen some strange things , where variables did not initialize as i thought they should
( start at 0). so i got in the habit of adding this,
if barnumber() == 1 then 0
to most of my longer if then's , to initialize the variable

---------------------

i'll try one more time...
it is hard to 'fix' partial code.
please post your COMPLETE code.

databox displays variables from PLOT functions.
so far you have not included any plots in your code examples, so we don't know what you are doing.

when i use your code , it works fine for me. so you are doing something else and not telling us.

--------------------------

this test code below, works fine.
it has 2...
OK. Let's look at some example code and see if we can get to the bottom of this.
Code:
declare upper;

input x = 12;
def bn = barNumber();

def condition = if bn % x == 0 then 1 else 0;

def data = if condition == 1 then close else data[1];
plot bar_x_close = data;
bar_x_close.SetPaintingStrategy(paintingStrategy.HORIZONTAL);
This code will plot the close of every x-th bar and keep that horizontal line until the next x-th bar occurs.

First, we input a value for x, which I defaulted to 12.
Then we set a condition. if the modulus of the barnumber (stored in bn) is 0, then the condition is 1 (one -true) otherwise it is 0 (zero - false). I do not like to use the implicit true/false methods that ThinkScript allows. I find it makes code much harder to debug (as you are finding). We could have written this as
Code:
def condition = bn % x == 0;
but that goes agains the idea of explicitly defining both true and false values. Please make explicit true/false 1/0 etc... code your standard. You'll thank yourself later.
After that, we can use the point we know the condition is true (==1) to set our data to the close of that bar. The else clause here tells the interpreter to use the last value of data if the condition is false.

You've got the right idea, and I'm not certain why your code didn't behave as expected. Perhaps if you put your "expresn" in a post we can dissect it to see what's going on. The only other thing I can think is that using barnumber() in your def is not as efficient as using a defined series (bn in the case of my code above).

That was long winded, but perhaps helpful. I don't intend to belittle your code or your understanding by this simple example and explanation, only offer a few insights into ways to make it cleaner and perhaps more debuggable.

-mashume
 
I nee some help to understand how date1 is determined by this def statement.

def date1 = if (expresn) then barnumber() else date1[1];

Actual results using Plot x=data1; with Data Box to see plot varable contents
Bar# expresn data1
1 False N/A
2 False N/A
3 True 3
4 False N/A
5 False N/A

I expected these results
Bar# expresn data1
1 False 0
2 False 0
3 True 3
4 False 3
5 False 3

I do not understanding the actual results vs. what i expect. Thanks for the explanation.

Bruce

first, it is hard to diagnose code errors from partial code. we have no idea what values, (expresn) has.


If (expresn) is NA, then the formula can become NA, and cascade through all the future values.


if trying to read a previous bar and it is barnumber one, that can have strange effects. best to define something for bar number 1.


this tests if (expresn) is an error and if it is barnumber 1, before analizing (expresn). but it won't work as is, because you didn't tell us what (expresn) should be.
i included a bubble to display some variables.


Code:
def expresn = ...

def date1 = if isnan(expresn) then 0
else if barnumber()  == 1 then 0
else if (expresn) then barnumber() else date1[1];

addchartbubble(1, low,
barnumber() + "  bn\n" +
expresn + "  ex\n" +
date1 + "  d"
, color.yellow, no);
#
 
OK. Let's look at some example code and see if we can get to the bottom of this.
Code:
declare upper;

input x = 12;
def bn = barNumber();

def condition = if bn % x == 0 then 1 else 0;

def data = if condition == 1 then close else data[1];
plot bar_x_close = data;
bar_x_close.SetPaintingStrategy(paintingStrategy.HORIZONTAL);
This code will plot the close of every x-th bar and keep that horizontal line until the next x-th bar occurs.

First, we input a value for x, which I defaulted to 12.
Then we set a condition. if the modulus of the barnumber (stored in bn) is 0, then the condition is 1 (one -true) otherwise it is 0 (zero - false). I do not like to use the implicit true/false methods that ThinkScript allows. I find it makes code much harder to debug (as you are finding). We could have written this as
Code:
def condition = bn % x == 0;
but that goes agains the idea of explicitly defining both true and false values. Please make explicit true/false 1/0 etc... code your standard. You'll thank yourself later.
After that, we can use the point we know the condition is true (==1) to set our data to the close of that bar. The else clause here tells the interpreter to use the last value of data if the condition is false.

You've got the right idea, and I'm not certain why your code didn't behave as expected. Perhaps if you put your "expresn" in a post we can dissect it to see what's going on. The only other thing I can think is that using barnumber() in your def is not as efficient as using a defined series (bn in the case of my code above).

That was long winded, but perhaps helpful. I don't intend to belittle your code or your understanding by this simple example and explanation, only offer a few insights into ways to make it cleaner and perhaps more debuggable.

-mashume
Thank you for you’re well written and detailed explanation. It’s more than I could’ve hoped for and I really appreciate your detail description.

Here is the exact formula that I used:

def data1 = if barnumber() == 3 then barnumber() else data1[1];

my thinking was data1 was 0 at initialization of the script, and would be zero until I changed it. Then it would stay 3 as I set it. But that is not what I see using the Data Box.

I expected these results but I got these results
Bar# expresn data1 Bar# expresn data1
1 False 0 1 False N/A
2 False 0 2 False N/A
3 True 3 3 True 3
4 False 3 4 False N/A
5 False 3 5 False N/A
 
first, it is hard to diagnose code errors from partial code. we have no idea what values, (expresn) has.


If (expresn) is NA, then the formula can become NA, and cascade through all the future values.


if trying to read a previous bar and it is barnumber one, that can have strange effects. best to define something for bar number 1.


this tests if (expresn) is an error and if it is barnumber 1, before analizing (expresn). but it won't work as is, because you didn't tell us what (expresn) should be.
i included a bubble to display some variables.


Code:
def expresn = ...

def date1 = if isnan(expresn) then 0
else if barnumber()  == 1 then 0
else if (expresn) then barnumber() else date1[1];

addchartbubble(1, low,
barnumber() + "  bn\n" +
expresn + "  ex\n" +
date1 + "  d"
, color.yellow, no);
#
Isn't date1 zero at the beginning of the program?

expresn
Here is the exact formula that I used:

def data1 = if barnumber() == 3 then barnumber() else data1[1];
 
Isn't date1 zero at the beginning of the program?


maybe...
i have seen some strange things , where variables did not initialize as i thought they should
( start at 0). so i got in the habit of adding this,
if barnumber() == 1 then 0
to most of my longer if then's , to initialize the variable

---------------------

i'll try one more time...
it is hard to 'fix' partial code.
please post your COMPLETE code.

databox displays variables from PLOT functions.
so far you have not included any plots in your code examples, so we don't know what you are doing.

when i use your code , it works fine for me. so you are doing something else and not telling us.

--------------------------

this test code below, works fine.
it has 2 variables.
data1 - does not initialize a value of 0 on barnumber 1.
data2 - does initialize a value of 0 on barnumber 1.

there is a bubble to display the values.
there are 2 plots to generate data that can be displayed by the databox.

both variables have valid, expected values.
0,0,3,3,3,3,3,,,,,
so, that tells me, you have something funky in your plot code line.


Code:
# test_cnt_bubbles_00

def na = double.nan;
def bn = barnumber();

def data1 = if bn == 3 then bn else data1[1];
def data2 = if bn == 1 then 0 else if bn == 3 then bn else data1[1];

addchartbubble(1, low*0.995,
data1 + "  D1\n" +
data2 + "  D2"
, color.yellow, no);

# this works to display expected values in databox
plot z1 = data1;
plot z2 = data2;

#


on the 3rd bar, the values change from 0 to 3, and stay at 3
12rqwiA.jpg



"\n" - this forces a new line in a bubble. it doesn't work in a label.

i never use databox. since it only displays plotted values, it is useless to me for debugging, since i need to verify def variables. i just add a bubble to display some values.
 
Last edited:
Solution

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
466 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