# mvp_01
# -----------------
# halcyonguy
# 21-08-25
# -----------------
# Momentum, Volume and Price (MVP)
#https://usethinkscript.com/threads/ants-%E2%80%94-momentum-volume-and-price-mvp.7497/
#I saw this very interesting custom indicator on TradingView.
#https://www.tradingview.com/script/uEaFv7tm-Ants-Momentum-Volume-and-Price-MVP/
#The Ants indicator is based on the research of David Ryan, three-time winner of the U.S. Investing Championship. David came up with the idea for the indicator while managing the New USA Growth Fund at William O’Neil + Company. David was interested to understand what drove some stocks higher once they were extended from their most recent base, while others had only moderate moves up.
#What David found during his research was that stocks making the biggest moves often had consistent buying on volume over a period of 12 to 15 trading days. Stocks with these characteristics may be under institutional accumulation, where it may take days to weeks to fill a position.
# — Momentum, Volume And Price ( MVP ) —
# The Ants indicator looks for the following:
# 1... Momentum - The stock is up at least 12 of the past 15 days.
# 2... Volume - The volume has increased over the past 15 days by 20% to 25%.
# 3... Price - The price is up at least 20% over the past 15 days.
# colored squares, above the candles:
# Gray - Momen requirement met.
# Blue - Momen and price requirement met.
# Yellow - Momen and vol requirement met.
# Green - Momen and vol and price requirement met.
#/////////////////////////////////////
def na = Double.NaN;
def bn = barnumber();
# ======================================
input OOOOOO_Momentum_OOOOOOO = yes;
# MVP
# 1... Momentum - The stock is up at least 12 of the past 15 days.
# it tests if current bar close > previous close
input series_max = 15;
input series_min = 12;
def momen_max = series_max;
def momen_min = series_min;
#input momentum_qty = 15;
#input momentum_min = 12;
def chgup = close > close[1];
def squares_price_offset = 0.02;
def vert = squares_price_offset;
# min series , when there are 'min' quantity of bars or greater, within a 'qty' set of bars.
# ex. if there are 12 min bars, within 15 qty bars.
AddLabel(1, "MVP qtys " + momen_min + "/" + momen_max, Color.cyan);
# --------------------------------
# nested fold.
# test if x min bars, or more, are true , out of y qty bars
# loop1 , start at current bar, loops to future bars.
# loop2 , on each bar of loop1, it looks back at 'momentum_qty' quantity of bars and counts the times chgup is true.
# when done, if the count is > momentum_min, then a 1 is passed on to loop1.
# if momupx > 0, then at least 1 valid series was found, to go across the bar.
# add this to remove errors on last few bars, when bar is within (min-1) bars to the last bar,
# while !isnan( getvalue(close, -loop1) )
def momupx = fold loop1 = 0 to momen_max
with one
while !isnan( getvalue(close, -loop1) )
do one + if (fold loop2 = 0 to momen_max
with two
do two + if GetValue(chgup , (-loop1 + loop2) ) then 1 else 0) >= momen_min then 1 else 0;
# was there at least 1 min series found ?
def momup = if momupx > 0 then 1 else 0;
# line under bars
#def offset1 = 0.999;
def offset1 = 1.0;
def htper = 0.2;
def cldht = round( (htper/100) * close, 1 );
def cldtop = if !momup[1] and momup then (low * offset1) else if momup then cldtop[1] else na;
def cldbot = cldtop - cldht;
# addcloud(cldtop, cldbot, color.cyan, color.cyan);
input momen_series_horz_line = yes;
plot ddd = if momen_series_horz_line then cldtop else na;
ddd.setlineweight(2);
ddd.SetDefaultColor(Color.light_gray);
# ======================================
# ======================================
input OOOOOO_Volume_OOOOOOO = yes;
# 2... Volume - The volume has increased over the past 15 days by 20% to 25%.
# the 15 day average daily volume is 20% or greater than the 50 day average.
input volume_increase_percent = 20.0;
def vip = volume_increase_percent/100;
#input vol_qty = 15;
#input vol_min = 12;
#def vol_max = series_max;
#def vol_min = series_min;
input vol_avg_short_len = 15;
input vol_avg_long_len = 50;
def vol_avgshort = average(volume, vol_avg_short_len);
def vol_avglong = average(volume, vol_avg_long_len);
# compare vol15avg to (vol50avg * x%)
def volupx = if ( vol_avgshort > (vol_avglong * (1 + vip)) ) then 1 else 0;
def volup = volupx;
# ======================================
input OOOOOO_Price_OOOOOOO = yes;
# 3... Price - The price is up at least 20% over the past 15 days.
#input price_increase_percent = 20.0;
input price_increase_percent = 6.0;
def prp = price_increase_percent/100;
#input pr_max = 15;
#input pr_min = 12;
def pr_max = series_max;
def pr_min = series_min;
input price_avg_short_len = 15;
input price_avg_long_len = 50;
def pr_avgshort = average(close, price_avg_short_len);
def pr_avglong = average(close, price_avg_long_len);
def prupx = if ( pr_avgshort > (pr_avglong * (1 + prp)) ) then 1 else 0;
def prup = prupx;
# //////////////////////////////////////
# //////////////////////////////////////
# draw squares, above candles, when a cond is true
# -- when candle is part of a min momen series
# colored squares, above the candles:
# Gray - Momen requirement met.
# Blue - Momen and price requirement met.
# Yellow - Momen and vol requirement met.
# Green - Momen and vol and price requirement met.
def mom = (momup and !volup and !prup);
def mompr = (momup and !volup and prup);
def momvol = (momup and volup and !prup);
def momvolpr = (momup and volup and prup);
#def sqr = (momup or volup or prup);
def sqr = (mom or mompr or momvol or momvolpr);
# //////////////////////////////////////
# plot a square above candles
plot t = if sqr then (high * (1 + (1*vert))) else na;
t.DefineColor("cmom", color.light_gray);
t.DefineColor("cmompr", color.blue);
t.DefineColor("cmomvol", color.yellow);
t.DefineColor("cmomvolpr", color.green);
t.DefineColor("cnon", color.current);
t.AssignValueColor(
if momvolpr then t.color("cmomvolpr")
else if momvol then t.color("cmomvol")
else if mompr then t.color("cmompr")
else if mom then t.color("cmom")
else t.color("cnon"));
t.SetPaintingStrategy(PaintingStrategy.SQUARES);
t.SetLineWeight(4);
# -------------------------------------
# legend
input show_color_legend = yes;
input legend_bar_offset = 4;
input legend_vert_percent = 97;
def v = (legend_vert_percent/100) * (close[legend_bar_offset]);
def k = !isnan(close[legend_bar_offset]) and isnan(close[(legend_bar_offset-1)]);
addchartbubble(show_color_legend and k, v, "Gray - Momen", color.light_gray, yes);
addchartbubble(show_color_legend and k, v, "Blue - Momen, price", color.blue, yes);
addchartbubble(show_color_legend and k, v, "Yellow - Momen, vol", color.yellow, yes);
addchartbubble(show_color_legend and k, v, "Green - Momen, vol, price", color.green, yes);
# test data , show test squares below the candles
input test_momen_series_quantities = no;
# show counts of momen min series
plot mx = if test_momen_series_quantities then momupx else na;
mx.SetPaintingStrategy(PaintingStrategy.VALUES_below);
mx.SetDefaultColor(Color.WHITE);
input test_momen_up_lower_gray = no;
plot my = if (test_momen_up_lower_gray and momup) then (low * (1 - (1*vert))) else na;
my.SetDefaultColor(Color.light_gray);
my.SetPaintingStrategy(PaintingStrategy.SQUARES);
my.SetLineWeight(4);
input test_volume_up_lower_purple = no;
plot vy = if (test_volume_up_lower_purple and volup) then (low * (1 - (2*vert))) else na;
vy.SetDefaultColor(Color.magenta);
vy.SetPaintingStrategy(PaintingStrategy.SQUARES);
vy.SetLineWeight(4);
input test_price_up_lower_blue = no;
plot py = if (test_price_up_lower_blue and prup) then (low * (1 - (3*vert))) else na;
py.SetDefaultColor(Color.blue);
py.SetPaintingStrategy(PaintingStrategy.SQUARES);
py.SetLineWeight(4);
input test_all_up = no;
plot all = if (test_all_up and momvolpr) then (low * (1 - (4*vert))) else na;
all.SetDefaultColor(Color.green);
all.SetPaintingStrategy(PaintingStrategy.SQUARES);
all.SetLineWeight(4);
input test_price_average_lines = no;
plot prs = if test_price_average_lines then pr_avgshort else na;
plot prl = if test_price_average_lines then pr_avglong else na;
prs.SetDefaultColor(Color.green);
prl.SetDefaultColor(Color.magenta);
#