Moving Average Cross anytime in the last X price candles

Trendie

New member
I have years of programming experience but I'm very new to thinkScript. I'm trying to write both an upper study and a scan for price crossing above or below a user-configurable moving average in the last X number of price bars (X also user-configurable, if possible) on any time frame (For my example I'm using 1-min). Let's say X = 20 candles. On the chart I'd like to mark up to 20 candles since the first crossover in some way. I would want to plot up to 20 bars only as long as price didn't cross back over the MA.

What's the motivation for this? I often see price cross above or below an MA, then return to the MA to backtest the cross. From there you can see a really nice trend develop (up or down) as it bounces off the MA. I know I don't have the skills yet to program a backtest, so, for now, I'm just trying to manually build a watchlist of stocks that might be ready (soon) to begin a trend in a new direction. Why the X number of candles back? I'd like to screen out stocks that just pop above/below the MA and then retreat back to the other side. Besides, the backtest takes a while to develop anyway.

I started with code from the TOS PriceAverageCrossover function which plots a single up or down arrow when price crosses an MA. The up/down arrow it uses is fine to mark the up to 20 bars, or something different/better - just not a fan of studies that change the candle colors since that interferes with the visual interpretation of candle patterns. I can't figure out a clean, concise way to code it and I'm sure I'm writing WAY TOO MUCH code (which isn't working at all right now anyway - no output). Your help would be greatly appreciated.

"He's intelligent but not experienced. His pattern indicates two-dimensional thinking." - Spock, The Wrath of Khan, speaking about my inability to code this.
 
Solution
I'm trying to write both an upper study and a scan for price crossing above or below a user-configurable moving average in the last X number of price bars (X also user-configurable, if possible) on any time frame (For my example I'm using 1-min). Let's say X = 20 candles. On the chart I'd like to mark up to 20 candles since the first crossover in some way. I would want to plot up to 20 bars only as long as price didn't cross back over the MA.


i think this will do what you asked for,

identify the last x quantity of bars on a chart. default is 20.
within that group of bars, find the first crossing of an average. default is simple, length = 11
draws small arrows until a 2nd crossing. arrows are colored based on close being >...
I'm trying to write both an upper study and a scan for price crossing above or below a user-configurable moving average in the last X number of price bars (X also user-configurable, if possible) on any time frame (For my example I'm using 1-min). Let's say X = 20 candles. On the chart I'd like to mark up to 20 candles since the first crossover in some way. I would want to plot up to 20 bars only as long as price didn't cross back over the MA.


i think this will do what you asked for,

identify the last x quantity of bars on a chart. default is 20.
within that group of bars, find the first crossing of an average. default is simple, length = 11
draws small arrows until a 2nd crossing. arrows are colored based on close being > or < than average.
draws vertical lines at the crossings.

it finds a crossing then saves the barnumber of it.
then compares that number to the current barnumber, to determine where the current bar is.


Code:
# cross_ma_xbars_0

#https://usethinkscript.com/threads/moving-average-cross-anytime-in-the-last-x-price-candles.12512/
#Moving Average Cross anytime in the last X price candles

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

input bars = 20;

# this makes it complex
#def lastbn = highestall(if isnan(close) then 0 else bn);
#def islastx_bars = ( bn >= (lastbn-bars) and bn <= lastbn);

# this seems to work
def islastx_bars = (!isnan(close) and isnan(close[-bars]));

addlabel(1, " " , color.black);
addlabel(1, "bars back " + bars, color.yellow);

# last bar  ( most recent)
#def lastbar = !isnan(close[0]) and isnan(close[-1]);

def price = close;
input MA1_len = 11;
#input MA1_type =  AverageType.EXPONENTIAL;
input MA1_type =  AverageType.simple;
def ma1 = MovingAverage(ma1_type, price, ma1_len);

addlabel(1, "average length " + ma1_len, color.yellow);

input show_ma = yes;
plot zma1 = if show_ma then ma1 else na;

def ma1_cross = close crosses ma1;

# find 1st ma crossing, in last x bars
def x = if bn == 1 then 0
else if x[1] > 0 then x[1]
else if islastx_bars and ma1_cross then bn
else x[1];

def x_dir = if ma1_cross and close < ma1 then -1
else if ma1_cross and close > ma1 then 1
else x_dir[1];

# find 2nd ma crossing, in last x bars
def x2 = if bn == 1 then 0
else if x2[1] > 0 then x2[1]
else if islastx_bars and ma1_cross and bn > x then bn
else x2[1];

# draw wedges after 1st crossing, up
plot z1up = if (x > 0 and bn >= x and x_dir > 0 and (x2 == 0 or bn < x2)) then 1 else 0;
z1up.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_up);
z1up.SetDefaultColor(Color.green);
z1up.setlineweight(2);

# draw wedges after 1st crossing , down
plot z1dwn = if (x > 0 and bn >= x and x_dir < 0 and (x2 == 0 or bn < x2)) then 1 else 0;
z1dwn.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_down);
z1dwn.SetDefaultColor(Color.red);
z1dwn.setlineweight(2);


# draw points after 1st crossing
input show_points = no;
plot z1 = if (show_points and x > 0 and bn >= x) then low * 0.99 else na;
z1.SetPaintingStrategy(PaintingStrategy.POINTS);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(1);
z1.hidebubble();


# 1st crossing
input show_vertical_lines = yes;
addverticalline( bn == x, "-", (if x_dir > 0 then color.green else color.red));
# 2nd crossing
addverticalline( bn == x2, "-", (if x_dir > 0 then color.green else color.red));


# ---------------------------
# test stuff

input test_vert_lines = no;
addverticalline(test_vert_lines and islastx_bars, "-", color.gray);


input test2 = no;
addchartbubble(test2, low, 
bn + "\n" +
x
, color.yellow, no);
#

SNDL 15 min
finds 1st crossing in the last 20 bars
draws small arrows until a 2nd crossing
oY8t1fQ.jpg
 
Solution

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

i think this will do what you asked for,

identify the last x quantity of bars on a chart. default is 20.
within that group of bars, find the first crossing of an average. default is simple, length = 11
draws small arrows until a 2nd crossing. arrows are colored based on close being > or < than average.
draws vertical lines at the crossings.

it finds a crossing then saves the barnumber of it.
then compares that number to the current barnumber, to determine where the current bar is.


Code:
# cross_ma_xbars_0

#https://usethinkscript.com/threads/moving-average-cross-anytime-in-the-last-x-price-candles.12512/
#Moving Average Cross anytime in the last X price candles

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

input bars = 20;

# this makes it complex
#def lastbn = highestall(if isnan(close) then 0 else bn);
#def islastx_bars = ( bn >= (lastbn-bars) and bn <= lastbn);

# this seems to work
def islastx_bars = (!isnan(close) and isnan(close[-bars]));

addlabel(1, " " , color.black);
addlabel(1, "bars back " + bars, color.yellow);

# last bar  ( most recent)
#def lastbar = !isnan(close[0]) and isnan(close[-1]);

def price = close;
input MA1_len = 11;
#input MA1_type =  AverageType.EXPONENTIAL;
input MA1_type =  AverageType.simple;
def ma1 = MovingAverage(ma1_type, price, ma1_len);

addlabel(1, "average length " + ma1_len, color.yellow);

input show_ma = yes;
plot zma1 = if show_ma then ma1 else na;

def ma1_cross = close crosses ma1;

# find 1st ma crossing, in last x bars
def x = if bn == 1 then 0
else if x[1] > 0 then x[1]
else if islastx_bars and ma1_cross then bn
else x[1];

def x_dir = if ma1_cross and close < ma1 then -1
else if ma1_cross and close > ma1 then 1
else x_dir[1];

# find 2nd ma crossing, in last x bars
def x2 = if bn == 1 then 0
else if x2[1] > 0 then x2[1]
else if islastx_bars and ma1_cross and bn > x then bn
else x2[1];

# draw wedges after 1st crossing, up
plot z1up = if (x > 0 and bn >= x and x_dir > 0 and (x2 == 0 or bn < x2)) then 1 else 0;
z1up.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_up);
z1up.SetDefaultColor(Color.green);
z1up.setlineweight(2);

# draw wedges after 1st crossing , down
plot z1dwn = if (x > 0 and bn >= x and x_dir < 0 and (x2 == 0 or bn < x2)) then 1 else 0;
z1dwn.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_down);
z1dwn.SetDefaultColor(Color.red);
z1dwn.setlineweight(2);


# draw points after 1st crossing
input show_points = no;
plot z1 = if (show_points and x > 0 and bn >= x) then low * 0.99 else na;
z1.SetPaintingStrategy(PaintingStrategy.POINTS);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(1);
z1.hidebubble();


# 1st crossing
input show_vertical_lines = yes;
addverticalline( bn == x, "-", (if x_dir > 0 then color.green else color.red));
# 2nd crossing
addverticalline( bn == x2, "-", (if x_dir > 0 then color.green else color.red));


# ---------------------------
# test stuff

input test_vert_lines = no;
addverticalline(test_vert_lines and islastx_bars, "-", color.gray);


input test2 = no;
addchartbubble(test2, low,
bn + "\n" +
x
, color.yellow, no);
#

SNDL 15 min
finds 1st crossing in the last 20 bars
draws small arrows until a 2nd crossing
oY8t1fQ.jpg
Thanks for the reply and the code. I'd just finished getting my version working but it's nothing but repetitive statements copied and modified over and over. The output is the same as yours, but I wasn't able to scale it (say, going from 20 bars to 30) without modifying the code. I knew that was the wrong way to get it done but I don't know the language well enough yet to do much more than that. I'll study your code to learn how to code this more efficiently!
 
i think this will do what you asked for,

identify the last x quantity of bars on a chart. default is 20.
within that group of bars, find the first crossing of an average. default is simple, length = 11
draws small arrows until a 2nd crossing. arrows are colored based on close being > or < than average.
draws vertical lines at the crossings.

it finds a crossing then saves the barnumber of it.
then compares that number to the current barnumber, to determine where the current bar is.


Code:
# cross_ma_xbars_0

#https://usethinkscript.com/threads/moving-average-cross-anytime-in-the-last-x-price-candles.12512/
#Moving Average Cross anytime in the last X price candles

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

input bars = 20;

# this makes it complex
#def lastbn = highestall(if isnan(close) then 0 else bn);
#def islastx_bars = ( bn >= (lastbn-bars) and bn <= lastbn);

# this seems to work
def islastx_bars = (!isnan(close) and isnan(close[-bars]));

addlabel(1, " " , color.black);
addlabel(1, "bars back " + bars, color.yellow);

# last bar  ( most recent)
#def lastbar = !isnan(close[0]) and isnan(close[-1]);

def price = close;
input MA1_len = 11;
#input MA1_type =  AverageType.EXPONENTIAL;
input MA1_type =  AverageType.simple;
def ma1 = MovingAverage(ma1_type, price, ma1_len);

addlabel(1, "average length " + ma1_len, color.yellow);

input show_ma = yes;
plot zma1 = if show_ma then ma1 else na;

def ma1_cross = close crosses ma1;

# find 1st ma crossing, in last x bars
def x = if bn == 1 then 0
else if x[1] > 0 then x[1]
else if islastx_bars and ma1_cross then bn
else x[1];

def x_dir = if ma1_cross and close < ma1 then -1
else if ma1_cross and close > ma1 then 1
else x_dir[1];

# find 2nd ma crossing, in last x bars
def x2 = if bn == 1 then 0
else if x2[1] > 0 then x2[1]
else if islastx_bars and ma1_cross and bn > x then bn
else x2[1];

# draw wedges after 1st crossing, up
plot z1up = if (x > 0 and bn >= x and x_dir > 0 and (x2 == 0 or bn < x2)) then 1 else 0;
z1up.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_up);
z1up.SetDefaultColor(Color.green);
z1up.setlineweight(2);

# draw wedges after 1st crossing , down
plot z1dwn = if (x > 0 and bn >= x and x_dir < 0 and (x2 == 0 or bn < x2)) then 1 else 0;
z1dwn.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_down);
z1dwn.SetDefaultColor(Color.red);
z1dwn.setlineweight(2);


# draw points after 1st crossing
input show_points = no;
plot z1 = if (show_points and x > 0 and bn >= x) then low * 0.99 else na;
z1.SetPaintingStrategy(PaintingStrategy.POINTS);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(1);
z1.hidebubble();


# 1st crossing
input show_vertical_lines = yes;
addverticalline( bn == x, "-", (if x_dir > 0 then color.green else color.red));
# 2nd crossing
addverticalline( bn == x2, "-", (if x_dir > 0 then color.green else color.red));


# ---------------------------
# test stuff

input test_vert_lines = no;
addverticalline(test_vert_lines and islastx_bars, "-", color.gray);


input test2 = no;
addchartbubble(test2, low,
bn + "\n" +
x
, color.yellow, no);
#

SNDL 15 min
finds 1st crossing in the last 20 bars
draws small arrows until a 2nd crossing
oY8t1fQ.jpg
thank you halcyonguy for the this code.
I tried to use this code to make scan searching for the (last) crossing in past 20 bars but I couldn't.
would you please help me?.
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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