FOLD Education

MrBruceKA

New member
I would use a FOR. . . NEXT or DO . . . WHILE statement, if I was writing in BASIC programming language. However, I can only find a FOLD statement in thinkScript to iterate through statements.

Could someone convert these SCAN statements into a FOLD statement for me. BUT, more important, please tell me, in detail, what is going on. I can't understand the example giving in the TOS Help.

Thanks for the education

# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
input PSprd = 3;
def Pcnt = PSprd/100;
input RunLen = 8;

# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Get the average of the midpoints
def MidPoint = (Open+Close)/2;
def RunAvg = Average(MidPoint,RunLen);

# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Calculate the Percentages
def P1 = AbsValue((MidPoint[(RunLen-1)]-RunAvg)/RunAvg);
def P2 = AbsValue((MidPoint[(RunLen-2)]-RunAvg)/RunAvg);
def P3 = AbsValue((MidPoint[(RunLen-3)]-RunAvg)/RunAvg);
def P4 = AbsValue((MidPoint[(RunLen-4)]-RunAvg)/RunAvg);
def P5 = AbsValue((MidPoint[(RunLen-5)]-RunAvg)/RunAvg);
def P6 = AbsValue((MidPoint[(RunLen-6)]-RunAvg)/RunAvg);
def P7 = AbsValue((MidPoint[(RunLen-7)]-RunAvg)/RunAvg);
def P8 = AbsValue((MidPoint[(RunLen-8)]-RunAvg)/RunAvg);

# See if all are below the PSprd value
Def Ans = P1<Pcnt And P2<Pcnt And P3<Pcnt And P4<Pcnt And P5<Pcnt And P6<Pcnt And P7<Pcnt And P8<Pcnt;
 
Solution
Adam:

You must be a teacher because your explanation is exactly what I was looking for to understand the FOLD statement.

I'll take your code and play with it for a while to make sure I understand what's happening.

Thanks, Bruce


@MrBruceKA, not a teacher exactly... at least not a school teacher like you might think.

Glad I could help. If you think my reply solves your issue, make sure to vote it up and mark it as the solution (if that is enabled for this post). That will flag the forum so others searching for it will be able to tell if your question was solved or not.

Let me know if you need anything else on FOLD. Like I said - it's tricky, but once you get it, it's pretty basic.
Hi @MrBruceKA,

Here's an example of how you could do this using fold. One thing to understand is that fold can be used in a variety of ways, so for the purpose you've outlined the process is rather simple, but just to make sure it's stated, it can be used in more powerful ways, but it is not as advanced as a for/next or do/while loop in a traditional programming language.

Here's the code - I'll explain it below.
Ruby:
declare lower;            # Made this a lower study for testing purposes

# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
input PSprd = 3;
def Pcnt = PSprd / 100;
input RunLen = 8;

# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Get the average of the midpoints
def MidPoint = MidBodyVal();            # Simplified to use MidBodyVal() instead of (open + close) / 2
def RunAvg = Average(MidPoint, RunLen);

# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Calculate the Percentages
def P1 = AbsValue((MidPoint[(RunLen - 1)] - RunAvg) / RunAvg);
def P2 = AbsValue((MidPoint[(RunLen - 2)] - RunAvg) / RunAvg);
def P3 = AbsValue((MidPoint[(RunLen - 3)] - RunAvg) / RunAvg);
def P4 = AbsValue((MidPoint[(RunLen - 4)] - RunAvg) / RunAvg);
def P5 = AbsValue((MidPoint[(RunLen - 5)] - RunAvg) / RunAvg);
def P6 = AbsValue((MidPoint[(RunLen - 6)] - RunAvg) / RunAvg);
def P7 = AbsValue((MidPoint[(RunLen - 7)] - RunAvg) / RunAvg);
def P8 = AbsValue((MidPoint[(RunLen - 8)] - RunAvg) / RunAvg);

# See if all are below the PSprd value
def Ans = P1 < Pcnt and P2 < Pcnt and P3 < Pcnt and P4 < Pcnt and P5 < Pcnt and P6 < Pcnt and P7 < Pcnt and P8 < Pcnt;

# New fold answer
def foldAns =
    fold i = 0 to RunLen
    with x = 0
    do
    x + (AbsValue((GetValue(MidPoint, i) - RunAvg) / RunAvg) < Pcnt);


# Plots to test calculations
plot test = (P1 < Pcnt) + (P2 < Pcnt) + (P3 < Pcnt) + (P4 < Pcnt) + (P5 < Pcnt) + (P6 < Pcnt) + (P7 < Pcnt) + (P8 < Pcnt);
test.SetDefaultColor(Color.YELLOW);

plot testFoldAns = foldAns == RunLen;
testFoldAns.SetDefaultColor(Color.BLUE);

plot oldAns = Ans;
oldAns.SetDefaultColor(Color.WHITE);

plot newAns = foldAns;
newAns.SetDefaultColor(Color.CYAN);


First, I modified your MidPoint variable to use MidBodyVal() as a function. This is a built-in TOS function that calculates (open + close) / 2.

Next, the foldAns variable I created does exactly the same thing as your P1...P8 variables do.

Fold i = 0 to RunLen i is like saying "For i = 0 to RunLen". It's identical in that way.

With x = 0 simply defines the starting value for x as 0. This is one of the ways fold can vary - it is not always necessary to specify a starting value, but in this case it is since we're going to increment x if it meets a condition.

Do x + (AbsValue.....) adds the prior value of x plus 1 since the AbsValue argument evaluates to 1 or 0, depending on whether it is true or false. It's like saying 'if condition = true then x = x + 1 else x".

As a final step, to evaluate the statement in the way you evaluate Ans, I have a line testFoldAns below that simply checks if foldAns = RunLen. In your test variable you check all 8 conditions and it evaluates TRUE if all 8 variables are TRUE. In my version, I check if x has reached 8 (RunLen).

I hope that helps. Fold is tricky to understand, but once you get it then it's pretty easy to use.

Let me know if you have any further questions.

Thanks,

Adam
 

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

Hi @MrBruceKA,

Here's an example of how you could do this using fold. One thing to understand is that fold can be used in a variety of ways, so for the purpose you've outlined the process is rather simple, but just to make sure it's stated, it can be used in more powerful ways, but it is not as advanced as a for/next or do/while loop in a traditional programming language.

Here's the code - I'll explain it below.
Ruby:
declare lower;            # Made this a lower study for testing purposes

# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
input PSprd = 3;
def Pcnt = PSprd / 100;
input RunLen = 8;

# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Get the average of the midpoints
def MidPoint = MidBodyVal();            # Simplified to use MidBodyVal() instead of (open + close) / 2
def RunAvg = Average(MidPoint, RunLen);

# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Calculate the Percentages
def P1 = AbsValue((MidPoint[(RunLen - 1)] - RunAvg) / RunAvg);
def P2 = AbsValue((MidPoint[(RunLen - 2)] - RunAvg) / RunAvg);
def P3 = AbsValue((MidPoint[(RunLen - 3)] - RunAvg) / RunAvg);
def P4 = AbsValue((MidPoint[(RunLen - 4)] - RunAvg) / RunAvg);
def P5 = AbsValue((MidPoint[(RunLen - 5)] - RunAvg) / RunAvg);
def P6 = AbsValue((MidPoint[(RunLen - 6)] - RunAvg) / RunAvg);
def P7 = AbsValue((MidPoint[(RunLen - 7)] - RunAvg) / RunAvg);
def P8 = AbsValue((MidPoint[(RunLen - 8)] - RunAvg) / RunAvg);

# See if all are below the PSprd value
def Ans = P1 < Pcnt and P2 < Pcnt and P3 < Pcnt and P4 < Pcnt and P5 < Pcnt and P6 < Pcnt and P7 < Pcnt and P8 < Pcnt;

# New fold answer
def foldAns =
    fold i = 0 to RunLen
    with x = 0
    do
    x + (AbsValue((GetValue(MidPoint, i) - RunAvg) / RunAvg) < Pcnt);


# Plots to test calculations
plot test = (P1 < Pcnt) + (P2 < Pcnt) + (P3 < Pcnt) + (P4 < Pcnt) + (P5 < Pcnt) + (P6 < Pcnt) + (P7 < Pcnt) + (P8 < Pcnt);
test.SetDefaultColor(Color.YELLOW);

plot testFoldAns = foldAns == RunLen;
testFoldAns.SetDefaultColor(Color.BLUE);

plot oldAns = Ans;
oldAns.SetDefaultColor(Color.WHITE);

plot newAns = foldAns;
newAns.SetDefaultColor(Color.CYAN);


First, I modified your MidPoint variable to use MidBodyVal() as a function. This is a built-in TOS function that calculates (open + close) / 2.

Next, the foldAns variable I created does exactly the same thing as your P1...P8 variables do.

Fold i = 0 to RunLen i is like saying "For i = 0 to RunLen". It's identical in that way.

With x = 0 simply defines the starting value for x as 0. This is one of the ways fold can vary - it is not always necessary to specify a starting value, but in this case it is since we're going to increment x if it meets a condition.

Do x + (AbsValue.....) adds the prior value of x plus 1 since the AbsValue argument evaluates to 1 or 0, depending on whether it is true or false. It's like saying 'if condition = true then x = x + 1 else x".

As a final step, to evaluate the statement in the way you evaluate Ans, I have a line testFoldAns below that simply checks if foldAns = RunLen. In your test variable you check all 8 conditions and it evaluates TRUE if all 8 variables are TRUE. In my version, I check if x has reached 8 (RunLen).

I hope that helps. Fold is tricky to understand, but once you get it then it's pretty easy to use.

Let me know if you have any further questions.

Thanks,

Adam
Adam:

You must be a teacher because your explanation is exactly what I was looking for to understand the FOLD statement.

I'll take your code and play with it for a while to make sure I understand what's happening.

Thanks, Bruce
 
Adam:

You must be a teacher because your explanation is exactly what I was looking for to understand the FOLD statement.

I'll take your code and play with it for a while to make sure I understand what's happening.

Thanks, Bruce


@MrBruceKA, not a teacher exactly... at least not a school teacher like you might think.

Glad I could help. If you think my reply solves your issue, make sure to vote it up and mark it as the solution (if that is enabled for this post). That will flag the forum so others searching for it will be able to tell if your question was solved or not.

Let me know if you need anything else on FOLD. Like I said - it's tricky, but once you get it, it's pretty basic.
 
Solution

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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