Problem with Using Scan and Fold

Code:
# QUESTION
def length = 15;
def greenStreak = fold counter = 1 to length with greenBar while (getValue(close,counter)-getValue(open,counter))>0 do if
                ((getValue(close, counter) - getValue(open, counter)) > 0)
            then greenBar + 1
            else greenBar;
def minimumGreenStreak = 3
plot scanQuery = if (greenstreak >= minimumGreenStreak)
                 then 1
                 else 0;
Hey guys so im working on a scanner that finds multiple green days in a row. I know this script works because it works as a label for counting the green days however when I try to put it in a scanner it fails. I think it has something to do with the FOLD function that scans don't like but what do you think?
 
Solution
@tradingwithmiggy You don't need a fold to count forwards, just set up a simple counter to increment on green bars and reset on red bars;

Ruby:
def GreenStreak = if close<open then 0 else if close>open then GreenStreak[1]+1 else GreenStreak[1];
def minimumGreenStreak = 3;
plot scanQuery = if (greenstreak >= minimumGreenStreak) then 1 else 0;
scanQuery.Hide();
@tradingwithmiggy You don't need a fold to count forwards, just set up a simple counter to increment on green bars and reset on red bars;

Ruby:
def GreenStreak = if close<open then 0 else if close>open then GreenStreak[1]+1 else GreenStreak[1];
def minimumGreenStreak = 3;
plot scanQuery = if (greenstreak >= minimumGreenStreak) then 1 else 0;
scanQuery.Hide();
 
Solution

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

Code:
# QUESTION
def length = 15;
def greenStreak = fold counter = 1 to length with greenBar while (getValue(close,counter)-getValue(open,counter))>0 do if
                ((getValue(close, counter) - getValue(open, counter)) > 0)
            then greenBar + 1
            else greenBar;
def minimumGreenStreak = 3
plot scanQuery = if (greenstreak >= minimumGreenStreak)
                 then 1
                 else 0;
Hey guys so im working on a scanner that finds multiple green days in a row. I know this script works because it works as a label for counting the green days however when I try to put it in a scanner it fails. I think it has something to do with the FOLD function that scans don't like but what do you think?

post#2 svanoy , has the correct answer.


not sure if it will help, but having the same condition in while and do is redundant.
i removed the subtraction.

Code:
def greenStreak = fold counter = 1 to length
 with greenBar
 while (getValue(close,counter) > getValue(open,counter))
 do greenBar + 1;

an idea, if scan still stalls, maybe add an if then, to only run the fold on the last bar.
 
Last edited:
not sure if it will help, but having the same condition in while and do is redundant.
i removed the subtraction.

Code:
def greenStreak = fold counter = 1 to length
 with greenBar
 while (getValue(close,counter) > getValue(open,counter))
 do greenBar + 1;

an idea, if scan still stalls, maybe add an if then, to only run the fold on the last bar.
Thanks! Actually while I was writing this I noticed it too and you're completely right it looks a lot cleaner.
Also i'll try that!
 
@tradingwithmiggy You don't need a fold to count forwards, just set up a simple counter to increment on green bars and reset on red bars;

Ruby:
def GreenStreak = if close<open then 0 else if close>open then GreenStreak[1]+1 else GreenStreak[1];
def minimumGreenStreak = 3;
plot scanQuery = if (greenstreak >= minimumGreenStreak) then 1 else 0;
scanQuery.Hide();
I think im just trying to practice using fold right now because there are harder scans that I want to do later. But seeing that i'm having problems with some of the simple fold scans is frustrating. So yeah not really looking to make this query work, but I want to know how to use fold more properly when it comes to scanning.
 
Explain exactly what you want the fold to accomplish, in plain English, in as much detail as possible. Its not as obvious as it may seem. Your larger length setting, relative to the small number of green bars you're seeking, and the way the fold terminates, all suggest something different.

For example, do you want to just count the number of consecutive green bars from the point of origin? Or are you looking for a set of 3 consecutive green bars to appear anywhere within the last 15 bars? I can't tell where you made a mistake versus what is intentional.
 
Explain exactly what you want the fold to accomplish, in plain English, in as much detail as possible. Its not as obvious as it may seem. Your larger length setting, relative to the small number of green bars you're seeking, and the way the fold terminates, all suggest something different.

For example, do you want to just count the number of consecutive green bars from the point of origin? Or are you looking for a set of 3 consecutive green bars to appear anywhere within the last 15 bars? I can't tell where you made a mistake versus what is intentional.
The scan that I want to make is to find stocks that have had 3 consecutive green bars anywhere within the last 15 days. So if today is 10/06/2022 I want to check if there was a green streak all the way back till 09/15/2022.

Eventually I want to do a scan where it filters stocks of that date range if the total % gain (from the bottom of where that green streak started to the end of the green streak) of that run was more than 50%. Thanks!
 
The scan that I want to make is to find stocks that have had 3 consecutive green bars anywhere within the last 15 days. So if today is 10/06/2022 I want to check if there was a green streak all the way back till 09/15/2022.

Eventually I want to do a scan where it filters stocks of that date range if the total % gain (from the bottom of where that green streak started to the end of the green streak) of that run was more than 50%. Thanks!

these studies will help with your first part. i didn't work on the 2nd part, involving the 50%

you don't need a fold loop to check if a sequence of a condition exists.
you can use sum()

test with a daily chart , INTC, and MRK

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

test code , upper
find all sequences of x green bars on the chart

..cyan dot below candles, sequence of x green bars
..blue dot above candles, a complete sequence happened WITHIN the past y bars
..starts counting after a sequence was found.

if the sequence = 3
and the past bars = 15,
then it will count bars, after a sequence of 3 was found, up to 12. 3+12 = 15

Code:
# greenbars_xqty_past_ybars_00_upper

#https://usethinkscript.com/threads/problem-with-using-scan-and-fold.12917/#post-109696
#post7

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

input min_green_seq_qty = 3;
input lookback_bars = 15;

def green = (close > open);

# check if x bars in a row are green , 3
def grnseq = (sum(green, min_green_seq_qty) == min_green_seq_qty);

# check if a seq happened within the lookback_bars. completely, not partially
def barz = lookback_bars - min_green_seq_qty + 1;
def past_grn_bars = (sum(grnseq, barz) > 0);

def vert = 0.1;
input test1_seq = yes;
plot z1 = if test1_seq and grnseq then low*(1-vert) else na;
z1.SetPaintingStrategy(PaintingStrategy.points);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(2);

input test2_pastxbars = yes;
plot z2 = if test2_pastxbars and past_grn_bars then high*(1+vert) else na;
z2.SetPaintingStrategy(PaintingStrategy.points);
z2.SetDefaultColor(Color.blue);
z2.setlineweight(2);

# count bars after a sequence
def grncnt = if bn == 1 then 0
  else if grnseq[1] and !grnseq[0] then 1
  else if !grnseq and past_grn_bars > 0 then grncnt[1] + 1
  else 0;

# show the count of bars after a sequence
input test3_cnt = yes;
plot z3 = if test3_cnt and grncnt > 0 then grncnt else na;
z3.SetPaintingStrategy(PaintingStrategy.values_above);
z3.SetDefaultColor(Color.white);
#

nhX11da.jpg



=================================


lower study
this should be able to be used as a scan (not tested)

add code to only check for a sequence, within the last x bars, only from the last bar


Code:
# greenbars_xqty_past_ybars_00_lower

#https://usethinkscript.com/threads/problem-with-using-scan-and-fold.12917/#post-109696
# post7

declare lower;

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

input min_green_seq_qty = 3;
input lookback_bars = 15;

# makes it complex
#def lastbn = HighestAll(If(IsNaN(close), 0, bn));

# this should work to find last bar
def lastbar = (!isnan(close) and isnan(close[-1]));
def lastbn = if lastbar then bn else 0;
def green = (close > open);

# check if x bars in a row are green , 3
def grnseq = (sum(green, min_green_seq_qty) == min_green_seq_qty);

# check if a seq happened within the lookback_bars. completely, not partially
def barz = lookback_bars - min_green_seq_qty + 1;

plot z1 = if (bn == lastbn and sum(grnseq, barz) > 0) then 1 else 0;
#

https://tlc.thinkorswim.com/center/reference/thinkScript/Functions/Math---Trig/Sum
 
Last edited:
these studies will help with your first part. i didn't work on the 2nd part, involving the 50%

you don't need a fold loop to check if a sequence of a condition exists.
you can use sum()

test with a daily chart , INTC, and MRK

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

test code , upper
find all sequences of x green bars on the chart

..cyan dot below candles, sequence of x green bars
..blue dot above candles, a complete sequence happened WITHIN the past y bars
..starts counting after a sequence was found.

if the sequence = 3
and the past bars = 15,
then it will count bars, after a sequence of 3 was found, up to 12. 3+12 = 15

Code:
# greenbars_xqty_past_ybars_00_upper

#https://usethinkscript.com/threads/problem-with-using-scan-and-fold.12917/#post-109696
#post7

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

input min_green_seq_qty = 3;
input lookback_bars = 15;

def green = (close > open);

# check if x bars in a row are green , 3
def grnseq = (sum(green, min_green_seq_qty) == min_green_seq_qty);

# check if a seq happened within the lookback_bars. completely, not partially
def barz = lookback_bars - min_green_seq_qty + 1;
def past_grn_bars = (sum(grnseq, barz) > 0);

def vert = 0.1;
input test1_seq = yes;
plot z1 = if test1_seq and grnseq then low*(1-vert) else na;
z1.SetPaintingStrategy(PaintingStrategy.points);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(2);

input test2_pastxbars = yes;
plot z2 = if test2_pastxbars and past_grn_bars then high*(1+vert) else na;
z2.SetPaintingStrategy(PaintingStrategy.points);
z2.SetDefaultColor(Color.blue);
z2.setlineweight(2);

# count bars after a sequence
def grncnt = if bn == 1 then 0
  else if grnseq[1] and !grnseq[0] then 1
  else if !grnseq and past_grn_bars > 0 then grncnt[1] + 1
  else 0;

# show the count of bars after a sequence
input test3_cnt = yes;
plot z3 = if test3_cnt and grncnt > 0 then grncnt else na;
z3.SetPaintingStrategy(PaintingStrategy.values_above);
z3.SetDefaultColor(Color.white);
#

nhX11da.jpg



=================================


lower study
this should be able to be used as a scan (not tested)

add code to only check for a sequence, within the last x bars, only from the last bar


Code:
# greenbars_xqty_past_ybars_00_lower

#https://usethinkscript.com/threads/problem-with-using-scan-and-fold.12917/#post-109696
# post7

declare lower;

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

input min_green_seq_qty = 3;
input lookback_bars = 15;

# makes it complex
#def lastbn = HighestAll(If(IsNaN(close), 0, bn));

# this should work to find last bar
def lastbar = (!isnan(close) and isnan(close[-1]));
def lastbn = if lastbar then bn else 0;
def green = (close > open);

# check if x bars in a row are green , 3
def grnseq = (sum(green, min_green_seq_qty) == min_green_seq_qty);

# check if a seq happened within the lookback_bars. completely, not partially
def barz = lookback_bars - min_green_seq_qty + 1;

plot z1 = if (bn == lastbn and sum(grnseq, barz) > 0) then 1 else 0;
#

https://tlc.thinkorswim.com/center/reference/thinkScript/Functions/Math---Trig/Sum
Thanks it worked as a scan! Ahh thank you! I know that sum inherently has a fold statement in it. So I guess my fold statements that i'm writing just ****. But now if I wanted to keep track of the first bar in that green sequence and the last bar in that green sequence and then how do you suppose i do that?
 
Thanks it worked as a scan! Ahh thank you! I know that sum inherently has a fold statement in it. So I guess my fold statements that i'm writing just ****. But now if I wanted to keep track of the first bar in that green sequence and the last bar in that green sequence and then how do you suppose i do that?


find the first and last bar, in a group of green bars.

i don't know how you want to use the first / last bar info.
so i modified my upper study to show the barnumbers in bubbles and list them in 2 labels.

this doesn't check if the first and last are within the last 15 bars.


Code:
# greenbars_xqty_past_ybars_01_upper

# https://usethinkscript.com/threads/problem-with-using-scan-and-fold.12917/#post-109709
# post9

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

input min_green_seq_qty = 3;
input lookback_bars = 15;

def green = (close > open);

# check if x bars in a row are green , 3
def grnseq = (sum(green, min_green_seq_qty) == min_green_seq_qty);

# check if a seq happened within the lookback_bars. completely, not partially
def barz = lookback_bars - min_green_seq_qty + 1;
def past_grn_bars = (sum(grnseq, barz) > 0);

def vert = 0.1;
input test1_seq = yes;
plot z1 = if test1_seq and grnseq then low*(1-vert) else na;
z1.SetPaintingStrategy(PaintingStrategy.points);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(2);

input test2_pastxbars = yes;
plot z2 = if test2_pastxbars and past_grn_bars then high*(1+vert) else na;
z2.SetPaintingStrategy(PaintingStrategy.points);
z2.SetDefaultColor(Color.blue);
z2.setlineweight(2);

# count bars after a sequence
def grncnt = if bn == 1 then 0
  else if grnseq[1] and !grnseq[0] then 1
  else if !grnseq and past_grn_bars > 0 then grncnt[1] + 1
  else 0;

# show the count of bars after a sequence
input test3_cnt = yes;
plot z3 = if test3_cnt and grncnt > 0 then grncnt else na;
z3.SetPaintingStrategy(PaintingStrategy.values_above);
z3.SetDefaultColor(Color.white);
#

#  find first bar, of a group of green bars
def grn_first = if bn == 1 then 0
else if isnan(close[-min_green_seq_qty]) then grn_first[1]
else if !green[1] and green and grnseq[-(min_green_seq_qty-1)] then bn
else grn_first[1];

#  find last bar, of a group of green bars
def grn_last = if bn == 1 then 0
else if !green and isnan(close[-1]) then grn_last[1]
else if green and isnan(close[-1]) then bn
else if green and !green[-1] and grnseq then bn
else grn_last[1];


addchartbubble(1, low*0.98,
bn + "\n" +
grn_first + "\n" +
grn_last
, (if bn == grn_first then color.green else if bn == grn_last then color.blue else color.gray), no);

addlabel(1, "first bar, of last green group " + grn_first, color.yellow);
addlabel(1, "last bar, of last green group " + grn_last, color.yellow);
#


K7Rl0IU.jpg
 
post#2 svanoy , has the correct answer.


not sure if it will help, but having the same condition in while and do is redundant.
i removed the subtraction.

Code:
def greenStreak = fold counter = 1 to length
 with greenBar
 while (getValue(close,counter) > getValue(open,counter))
 do greenBar + 1;

an idea, if scan still stalls, maybe add an if then, to only run the fold on the last bar.
Okay so i've been testing things out and it seems that whenever you use getValue and scanning then it doesn't return any results. Which kinda ****s. So now i've been trying to get something like return any stocks that have gapped up over 100% in the past year.

Code:
def length = 250;
def gapUpDay = fold counter = 0 to length with previousDay = 0 do
                if (open[counter] - close[counter+1]) / close[counter+1]*100 >= 100
                then 1
                else previousDay;


plot trigger = gapUpDay;

I also tried this code using getvalue

Code:
def length = 250;
def gapUpDay = fold counter = 0 to length with previousDay = 0 do
                if (getValue(open, counter) - getValue(close, counter+1)) / getValue(close,counter+1)*100 >= 100
                then 1
                else previousDay;


plot trigger = gapUpDay;

and I feel like this definitely should work. But the getValue version doesnt return anything as a scan and the one using open[] close[] says that you cant do math in the brackets. So kinda stuck. If there was a way to do calculation before the brackets that would help a lot.
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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