Indicator Request: Stock is up at-least 4 days of the past 7 RTD

Musk335im3

New member
Hi everyone; OG coders specially.

How do I code this?
Conditions
1. Daily aggregation
2. Ticker is up at-least 4 days of the past 7 regular trading days.

I am looking to make a upper chart indicator and also a scan.

Thanks in advanced.
 
Solution
How do I code this?
Conditions
1. Daily aggregation
2. Ticker is up at-least 4 days of the past 7 regular trading days.
I am looking to make a upper chart indicator and also a scan.

this will check if there were x up bars, in the previous y bars.
default is 4 of 7.
...draw an up arrow on all of these signals or just the first in a series of them.
...draw a green dot above just the up bars that are before the first arrow.

i started by using 2nd aggregation, but was getting odd results , so removed it.
set the chart to the desired time.

you didn't define what an up bar is, so i added an option to pick 1 of 2 methods,
bar close > previous bar close
close > open


upper chart

Ruby:
# up4in7bars_upper_00c

# Indicator Request...

halcyonguy

Well-known member
VIP
Lifetime
How do I code this?
Conditions
1. Daily aggregation
2. Ticker is up at-least 4 days of the past 7 regular trading days.
I am looking to make a upper chart indicator and also a scan.

this will check if there were x up bars, in the previous y bars.
default is 4 of 7.
...draw an up arrow on all of these signals or just the first in a series of them.
...draw a green dot above just the up bars that are before the first arrow.

i started by using 2nd aggregation, but was getting odd results , so removed it.
set the chart to the desired time.

you didn't define what an up bar is, so i added an option to pick 1 of 2 methods,
bar close > previous bar close
close > open


upper chart

Ruby:
# up4in7bars_upper_00c

# Indicator Request: Stock is up at-least 4 days of the past 7 RTD

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

input min_up_days = 4;
input time_span_days = 7;

input up_type = { default bar_to_bar_close , open_to_close };
def up;
switch (up_type){
case bar_to_bar_close:
  up = if bn == 1 then 0 else if close > close[1] then 1 else 0;
case open_to_close:
  up = if bn == 1 then 0 else if close > open then 1 else 0;
}


# up is true, if today close is > yesterday close
#def up = if bn == 1 then 0
#  else if  close > close[1] then 1
#  else 0;

def isminup = (sum(up, time_span_days) >= min_up_days);

input show_only_first_arrow = yes;
def firstbar = (!isminup[1] and isminup);
def firstbn = if firstbar then bn else 0;

def arrow_bars = if bn == 1 then 0
  else if !show_only_first_arrow then isminup
  else if show_only_first_arrow and firstbar then 1
  else 0;

plot z1 = arrow_bars;
z1.setdefaultcolor(color.cyan);
z1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
z1.setlineweight(2);

# dots on up bars before the 1st bar of a series
def isfirst = (sum(firstbar[-(time_span_days-1)], time_span_days) >= 1);
def early_ups = up and isfirst;

input dots_on_up_bars_before_first = yes;
plot z2 = if dots_on_up_bars_before_first and early_ups then high*1.01 else na;
z2.setdefaultcolor(color.green);
z2.SetPaintingStrategy(PaintingStrategy.points);
z2.setlineweight(4);

#--------------------

# info labels
input show_description_labels = yes;

addlabel(show_description_labels, "find " + min_up_days + " up bars, in the past " + time_span_days, color.cyan);
addlabel(show_description_labels, up_type, color.yellow);
addlabel(show_description_labels and show_only_first_arrow, "show only first arrow in a series", color.cyan);
addlabel(show_description_labels and dots_on_up_bars_before_first, "show dots above the up bars, that are before the first up bar in a series", color.green);
#

BK day chart
set to show just the first arrow in a series
BDImUha.jpg




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

i didn't test this as a scan, just as a lower study.

with column or scan codes, the user has to edit the code to change an input.
to make it easier, i make a copy of an input line for each possible value. i set each of the copies to equal one of the possible values, then disable the code line copies with #
then to change an input , add and remove a #.
see below, where i added a copy of the input up_type = ... line, and set it to have a different default.

scan
Ruby:
# up4in7bars_lower_00c

# https://usethinkscript.com/threads/indicator-request-stock-is-up-at-least-4-days-of-the-past-7-rtd.12163/
# Indicator Request: Stock is up at-least 4 days of the past 7 RTD

#declare lower;
def bn = barnumber();
def na = double.nan;

input min_up_days = 4;
input time_span_days = 7;

# enable one of these lines
input up_type = { default bar_to_bar_close , open_to_close };
#input up_type = { bar_to_bar_close , default open_to_close };

def up;
switch (up_type){
case bar_to_bar_close:
  up = if bn == 1 then 0 else if close > close[1] then 1 else 0;
case open_to_close:
  up = if bn == 1 then 0 else if close > open then 1 else 0;
}


def isminup = (sum(up, time_span_days) >= min_up_days);

input show_only_first_arrow = yes;
def firstbar = (!isminup[1] and isminup);
def firstbn = if firstbar then bn else 0;

def arrow_bars = if bn == 1 then 0
  else if !show_only_first_arrow then isminup
  else if show_only_first_arrow and firstbar then 1
  else 0;

plot z1 = arrow_bars;
#z1.setdefaultcolor(color.cyan);
#z1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#z1.setlineweight(2);
#


used as a lower study, to verify output
spikes line up with arrows.
arrows set to show just the first one.
SmfaQgr.jpg



if all arrows are shown
c1xs2vQ.jpg
 
Last edited:
Solution

Musk335im3

New member
Bro, I owe you a very big one. Initial look of what was posted appeared super great, but I have yet to compare to a prop strategy backtest that I got hold of to make a good comparison
I really didn't realize that the code would be this complicated (thought would be just a couple of lines), but you made was super elegant. Will go over this tonight (or following days) and will post here the final code.
 

halcyonguy

Well-known member
VIP
Lifetime
Bro, I owe you a very big one. Initial look of what was posted appeared super great, but I have yet to compare to a prop strategy backtest that I got hold of to make a good comparison
I really didn't realize that the code would be this complicated (thought would be just a couple of lines), but you made was super elegant. Will go over this tonight (or following days) and will post here the final code.

i am a visual guy. so sometimes i add in shapes and lines, that i would want to see, and to show others what can be done.
 

Musk335im3

New member
@halcyonguy
Finally got some live results in but due to that the general market being bearish right now good long entries were limited (and too early) to fully give a better picture (sharpe ratio and stuff). It seems like it works with the major indices, etf's, and mega caps. Plus the 5 by 7 condition looks to be better (see chart below).
On mid cap stocks no good picture yet since good swing trade long entry set-ups are few and far between.

Two questions though:
1. How do we code an additional option to hide the older first-day arrows -say limit it within the last 50 trading days- (i.e ability to toggle on/off) to de-clutter the chart a bit since there are other upper chart indicator(s) being compared it to without removing them entirely/ permanently.
2. How do we code an additional condition where the count re-starts the day after the latest first-day arrow (where the last first-day arrow is zero day).
The chart below shows an arrow (gray circle) that occurred too close from the previous one. This we hope will make it less noisy in the long run.
- The rest of the code is working as designed so far.

(Purpose) Based off an internal live and backtest I've seen from some private fund run by some TA-leaning traders, the 4 x 7 daily rule is a basic but good guide for:
1. Booking partial gains on a highly up trending stock.
The study was done mainly due to the fact that most swing traders either sell too early (coz some indicator tells them to do so). Or too late since the 20-25% gain rule that we see being preached by most of swing trading books seemed to have stopped working since 2018.
2. Bullishness/bearishness of the stock: As long as the current price doesn't go below 1.5 ATR (it's 1 ATR) below the CLOSE of the bar with the last arrow within 5 days, the remaining position can be maintained unless closed/ stopped out by some other rule.
3. It apparently works in both long and short trades.

Anyhow, the 5 by 7 rule "seems" to be the one working on our end.

Thanks in advanced for the help.

NOTE: We are using the original code indicator at the very top as made by @halcyonguy @MerryDay. The settings inside the indicator were the one adjusted and nothing else; so I'm not sure why you deleted the image.

The other simple indicator used in the image is: https://usethinkscript.com/threads/moving-average-crossovers-for-thinkorswim.229/
 
Last edited:

Musk335im3

New member
Figured out the #1 code request on my previous post (trading day limiter). Found the idea here. https://usethinkscript.com/threads/lookback-date-for-label.9084/ Thanks @SleepyZ

#2 (counter re-start) was still beyond my powers. Hoping @halcyonguy or somebody else be able to chime in.

Updated code (adjusted defaults to 5 by 7 and a 50 day limiter which all can be adjusted in the settings input:

Code:
# Indicator Request: Stock is up at-least 5 days of the past 7 RTD
# Made by @halcyonguy # Other source code by @SleepyZ # Requested by Musk335im3

# Start

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

input min_up_days = 5;
input time_span_days = 7;

input up_type = { default bar_to_bar_close , open_to_close };
def up;
switch (up_type){
case bar_to_bar_close:
  up = if bn == 1 then 0 else if close > close[1] then 1 else 0;
case open_to_close:
  up = if bn == 1 then 0 else if close > open then 1 else 0;
}


# up is true, if today close is > yesterday close
#def up = if bn == 1 then 0
#  else if  close > close[1] then 1
#  else 0;

def isminup = (sum(up, time_span_days) >= min_up_days);

input show_only_first_arrow = yes;
def firstbar = (!isminup[1] and isminup);
def firstbn = if firstbar then bn else 0;

def arrow_bars = if bn == 1 then 0
  else if !show_only_first_arrow then isminup
  else if show_only_first_arrow and firstbar then 1
  else 0;

######################## bar counter ###############################

def hbn = if isnan(close[-1]) and !isnan(close) then barnumber() else double.nan;
# addlabel(1,hbn);

def counter = compoundValue(1,if barnumber()==1 then highestall(hbn) else if counter[1]>1 then counter[1]-1 else 0, highestall(hbn));

def bar_counter = counter;
# bar_counter.setpaintingStrategy(paintingStrategy.VALUES_BELOW);

input bar_limit = 50;
def RTDLimit = if (bar_counter >= bar_limit) then 0 else 1;
def pre_z1 = if (arrow_bars and RTDLimit) is true then 1 else 0;
plot z1 = pre_z1;

######################## end of add on #############################

# plot z1 = arrow_bars;
z1.setdefaultcolor(color.cyan);
z1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
z1.setlineweight(2);




# dots on up bars before the 1st bar of a series
def isfirst = (sum(firstbar[-(time_span_days-1)], time_span_days) >= 1);
def early_ups = up and isfirst;

input dots_on_up_bars_before_first = yes;
plot z2 = if dots_on_up_bars_before_first and early_ups then high*1.01 else na;
z2.setdefaultcolor(color.green);
z2.SetPaintingStrategy(PaintingStrategy.points);
z2.setlineweight(4);

#--------------------

# info labels
input show_description_labels = yes;

addlabel(show_description_labels, "find " + min_up_days + " up bars, in the past " + time_span_days, color.cyan);
addlabel(show_description_labels, up_type, color.yellow);
addlabel(show_description_labels and show_only_first_arrow, "show only first arrow in a series", color.cyan);
addlabel(show_description_labels and dots_on_up_bars_before_first, "show dots above the up bars, that are before the first up bar in a series", color.green);


# End


Sample image w/ additional moving average crossover indicator (found here: https://usethinkscript.com/threads/moving-average-crossovers-for-thinkorswim.229/) Again, thanks to @halcyonguy and @SleepyZ

p29ZZ9M.png



Day limiter expanded to 150 RTDs.

oQvhG6i.png
 
Last edited:

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