# find_x_lowestlows_over_past_x_bars
#https://usethinkscript.com/threads/lowest-lows-of-a-period.16185/
#lowest lows of a period
def bn = barnumber();
def na = double.nan;
def lastbn = HighestAll(If(IsNaN(close), 0, bn));
def lastbar = if (bn == lastbn) then 1 else 0;
# def lastbar = !isnan(close[0]) and isnan(close[-1]);
def big = 99999;
input bars_back = 60;
def xback = (!isnan(close[-(bars_back-1)]) and isnan(close[-(bars_back+0)]));
#def bbbn = if bn == 1 then big else if xback then bn else bbbn[1];
def xbackbn = lastbn - bars_back + 1;
input show_vert_line = yes;
addverticalline(show_vert_line and xback, "-", color.cyan);
#---------------------------------------
# ref code
# rank the last 10 volume values
# https://usethinkscript.com/threads/rank-volume-1-10.9504/
input data = low;
def qty = bars_back;
def rank = fold i = 1 to qty
with rankcounter = 1
do if data > GetValue(data, i) then rankcounter + 1 else rankcounter;
def FinalBar_c = fold c = 0 to lastbn
while !IsNaN(GetValue(close, -c))
do c + bn;
def rank1 = fold r = (0 - (lastbn - BarNumber() )) to qty - (lastbn - BarNumber())
with rcounter = 1
do if data > GetValue(data, r) then rcounter + 1 else rcounter;
def rngbar1 = lastbn - qty + 1;
def cntdwn_in_rng = lastbn - bn + 1;
# bn, countup thru the rng, 1st bar = 1 , last bar = qty
def cntup_in_rng = qty - cntdwn_in_rng + 1;
def rank2 = if bn >= rngbar1 then rank1 else 0;
# find dup #s and make an offset
def dup1 = fold g = 1 to qty
with h
do h + (if rank2 == getvalue(rank2, g) then 1 else 0);
# adjusted rank, add dup offset, all unique #s
def rank3 = if bn >= rngbar1 then (rank2 + dup1) else rank2;
# rank3 numbers, 1 = lowest price. 2 = 2nd lowest price,...
#-------------------------------------
# plot dots under lowest lows, a qty of rank3 numbers
input qty_of_lows = 4;
def lolo = (rank3 <= qty_of_lows) and (bn >= xbackbn);
def lolowest = (rank3 == qty_of_lows) and (bn >= xbackbn);
def vert2 = 0.001;
input show_low_dots = yes;
plot zl = if show_low_dots and lolo then low*(1-vert2) else na;
zl.SetPaintingStrategy(PaintingStrategy.points);
zl.SetDefaultColor(Color.yellow);
zl.setlineweight(2);
zl.hidebubble();
plot zl2 = if show_low_dots and lolowest then low*(1-vert2) else na;
zl2.SetPaintingStrategy(PaintingStrategy.squares);
zl2.SetDefaultColor(Color.white);
zl2.setlineweight(4);
zl2.hidebubble();
#--------------------
# find offset back to highest low
def f;
if bn == 1 or isnan(close) then {
f = 0;
} else if lastbar then {
f = fold j = 0 to bars_back
with q
while getvalue(rank3, j) != qty_of_lows
do q + 1;
} else {
f = f[1];
}
# read low from highest low , in qty group
def f2 = highestall( if lastbar then getvalue(data, f) else 0);
# plot horz line at xth qty
input show_horz_line_highest_low = yes;
plot hz = if show_horz_line_highest_low and (bn >= xbackbn) and !isnan(close) then f2 else na;
hz.setdefaultcolor(color.magenta);
#-------------------------------
input test3 = no;
addchartbubble(test3, low*0.994,
rank3 + "\n" +
f2 + "\n" +
qty_of_lows + "\n" +
xbackbn
, (if rank3 == qty_of_lows then color.yellow else color.gray), no);
#, color.yellow, no);
input test1 = no;
addchartbubble(test1, 0,
bn + " bn\n" +
# finalbar + " f\n" +
#e + " e\n" +
finalbar_c + " c\n"
, color.yellow, yes);
input test_show_ranking_bubbles = no;
AddChartBubble(test_show_ranking_bubbles, high, rank1, color.gray, yes);
addchartbubble(test_show_ranking_bubbles and bn >= rngbar1, high, dup1 , (if dup1 > 0 then color.cyan else color.gray), yes);
addchartbubble(test_show_ranking_bubbles and bn >= rngbar1, high, rank3 , color.green, yes);
#------------------------------
#input test_ranked_data = no;
#addchartbubble(test_ranked_data and bn >= rngbar1, low*0.998,
# cntup_in_rng + "\n" +
# data_rank
# , color.yellow, no);
input test_rng_counts_data = no;
addchartbubble(test_rng_counts_data and bn >= rngbar1, low*0.998,
bn + "\n" +
data + " dat\n" +
rngbar1 + "\n" +
cntdwn_in_rng + "\n" +
cntup_in_rng + "\n"
# +
#data_rank
, color.yellow, no);
#