Congestion Zone

Department

New member
Hello! I need help creating this indicator for highlighting congestion.

Idea: Take candle body [open to close] and extend those prices levels forward. If x number (say 3) candles open or close in that range create a grey box from initial candle. Then stop the grey box once the first candle does not open/close inside the grey box around. (Grey box is = open/close of initial candle)

Here is an image of what is envisioned - /ES on March 10th, 2022, at 11:25am to 11:45am
ES-mar-10-22-zone.png


Requested Inputs:
1. Number of candles inside zone to begin painting
2. Maximum range of body to count as an initial candle (AKA prevent large bodied candles from triggering this as they are likely to engulf many candles)
2.1 I predict this to be a function of ATR of the last 5/10 candles.

Issues I predict might happen:
1. A candle after the initial candle will fit the criteria and create another grey box leading to overlapping boxes. I have no idea how to prevent this...
 
Solution
@halcyonguy
i reread your rules and realize i what i made is just inside bars. not this ...open or close in that range...
I had missed that too.. lol..
Kept looking at @Department screencap, thinking 'that's not right'.

Anyway after seeing that, here is a rough start, I've not been able to give this much attention yet.


fLPmenc.png

Ruby:
input rangeMin = 3;

#idk if defining these variables makes the code less intensive?
def upBoxOpen = open;
def upBoxClose = close;
def downBoxOpen = open;
def downBoxClose = close;

#green start - Checks if the future open/close are between the Open/close of initial bar.
def gct1 = if Between(close[-1], upBoxOpen, upBoxClose) or Between(open[-1], upBoxOpen, upBoxClose) then 1 else 0...
this version has 3 risk and 3 reward lines

Code:
# congestion_box_00d

#  add risk/reward lines , 3x
# https://usethinkscript.com/threads/congestion-zone.10503/#post-97560
# post 18

def na = double.nan;
def bn = barnumber();
#-------------------------------------
# choose wick or body price levels
input candle_levels = { default "wick" , "body" };
def highx;
def lowx;
switch (candle_levels) {
case "wick":
  highx = high;
  lowx = low;
case "body":
  highx = max(open, close);
  lowx = min(open, close);
}

def ht = highx - lowx;
#-----------------------------------
input min_inside_bars = 3;

input show_label__candle_levels = no;
addlabel(show_label__candle_levels, "Candle levels - " + candle_levels, color.yellow);

input show_label__min_inside_bars = no;
addlabel(show_label__min_inside_bars, "Min inside bars - " + min_inside_bars, color.yellow);
# --------------------------------
# test if a giant candle appears,  then ignore it
input ignore_big_candles = no;
input candle_ht_avg_multiplier_max = 5.0;
input candle_height_avg_len = 20;

def ht_avg = round(Average( ht[1], candle_height_avg_len),2);
def ht_avg_factor = round(ht / ht_avg, 1);

def ht_en = !ignore_big_candles or (ht < (ht_avg * candle_ht_avg_multiplier_max));
#----------------------------------
# inside bar , count smaller bars after the current bar
def max_bars = 70;
def future_bar_count = fold k = 1 to max_bars
  with q = 1
## congestion , 1 bar parameter within high/low
  while (ht_en and (between(getvalue(highx, -k), lowx, highx) or between(getvalue(lowx, -k), lowx, highx)))
## insidebars , top and bottom of bar is within high/low
# while (ht_en and highx[0] >= getvalue(highx, -k) and lowx[0] <= getvalue(lowx, -k))
  do q + 1;


# -------------------------------
# count down from mother bar, to last inside bar
def rev_cnt =
 if bn == 1 then 0
 else if rev_cnt[1] > 1 then (rev_cnt[1] - 1)
 else if future_bar_count >= min_inside_bars then future_bar_count
 else 0;

def inside_start = (rev_cnt[1] <= 1 and future_bar_count >= min_inside_bars);
def start_cnt = if bn == 1 then 0 else if inside_start then (start_cnt[1] + 1) else start_cnt[1];

#def vert = 0.0006;
def vert = 0.00;
input show_cloud = yes;
input show_bubble_pattern_bar_count = no;
addchartbubble(show_bubble_pattern_bar_count and inside_start, (high * (1 + vert)), future_bar_count, color.gray, yes);

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

# ----------------------------------
# plot lines

def inside_hi =
 if rev_cnt == 0 then na
 else if inside_start then highx
 else inside_hi[1];

def inside_lo =
 if rev_cnt == 0 then na
 else if inside_start then lowx
 else inside_lo[1];

plot zhi = inside_hi;
plot zlo = inside_lo;

zhi.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zhi.SetStyle(Curve.MEDIUM_DASH);
#zhi.SetDefaultColor(Color.cyan);
zhi.SetDefaultColor(Color.gray);
zhi.setlineweight(1);
zhi.hidebubble();

zlo.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zlo.SetStyle(Curve.MEDIUM_DASH);
#zlo.SetDefaultColor(Color.cyan);
zlo.SetDefaultColor(Color.gray);
zlo.setlineweight(1);
zlo.hidebubble();

# ---------------------------------------
# use 2 clouds, to avoid 2 adjacent patterns being connected
def iscnt_odd = ( start_cnt % 2 == 1 );

def zhiodd = if (show_cloud and iscnt_odd) then zhi else na;
addcloud(zhiodd, zlo, color.gray);
def zhieven = if (show_cloud and !iscnt_odd) then zhi else na;
addcloud(zhieven, zlo, color.gray);

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

input show_arrow_on_bar1 = no;
plot z1 = if show_arrow_on_bar1 and inside_start then (low * (1 - vert)) else na;
z1.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(2);
z1.hidebubble();
#
# ---------------------------------

# show risk/reward lines, a multiple of mother bar height

def rng = inside_hi - inside_lo;

input show_risk_reward_lines = yes;
def srr = show_risk_reward_lines;

plot reward1 = if srr then (inside_hi + (1 * rng)) else na;
reward1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
reward1.SetDefaultColor(Color.gray);
reward1.hidebubble();

plot reward2 = if srr then (inside_hi + (2 * rng)) else na;
reward2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
reward2.SetDefaultColor(Color.gray);
reward2.hidebubble();

plot reward3 = if srr then (inside_hi + (3 * rng)) else na;
reward3.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
reward3.SetDefaultColor(Color.gray);
reward3.hidebubble();


plot risk1 = if srr then (inside_lo - (1 * rng)) else na;
risk1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
risk1.SetDefaultColor(Color.gray);
risk1.hidebubble();

plot risk2 = if srr then (inside_lo - (2 * rng)) else na;
risk2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
risk2.SetDefaultColor(Color.gray);
risk2.hidebubble();

plot risk3 = if srr then (inside_lo - (3 * rng)) else na;
risk3.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
risk3.SetDefaultColor(Color.gray);
risk3.hidebubble();




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

# add horz lines at,
#  highest hi above box,
#  and lowest low below box
# iscnt_odd

input show_range_highest_lowest_lines = no;
def srl = show_range_highest_lowest_lines;

def toplimit;
if srl and inside_start then {
toplimit = fold t1 = 0 to max_bars
  with top1
  while t1 < future_bar_count
  do max(top1, getvalue(high, -t1));
} else if srl and rev_cnt > 0 then {
toplimit = toplimit[1];
} else {
toplimit = na;
}

plot zt = toplimit;
zt.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
zt.SetDefaultColor(Color.yellow);
#zt.setlineweight(1);
zt.hidebubble();


def botlimit;
if srl and inside_start then {
botlimit = fold b1 = 0 to max_bars
  with bot1 = 999999
  while b1 < future_bar_count
  do min(bot1, getvalue(low, -b1));
} else if srl and rev_cnt > 0 then {
botlimit = botlimit[1];
} else {
botlimit = na;
}

plot zb = botlimit;
zb.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
zb.SetDefaultColor(Color.yellow);
#zb.setlineweight(1);
zb.hidebubble();



# -----------------------------------
# -----------------------------------
# test stuff - and me


addchartbubble(0, low*0.996,
inside_start + "\n" +
toplimit + "\n" +
rev_cnt + "\n" +
high + "\n"
, ( if inside_start then color.yellow else color.gray), no);



def u = 0;
addchartbubble(u and inside_start, low,
start_cnt + " cnt\n" +
iscnt_odd + " odd"
, color.yellow, no);


# count how many patterns on chart
# if a stock has many, more opportuneties to catch a move



def cnt3 = if bn == 1 then 0 else if (inside_start and future_bar_count == 3) then (cnt3[1] + 1) else cnt3[1];
def cnt4 = if bn == 1 then 0 else if (inside_start and future_bar_count == 4) then (cnt4[1] + 1) else cnt4[1];
def cnt5 = if bn == 1 then 0 else if (inside_start and future_bar_count == 5) then (cnt5[1] + 1) else cnt5[1];
def cnt6 = if bn == 1 then 0 else if (inside_start and future_bar_count == 6) then (cnt6[1] + 1) else cnt6[1];
def cnt7 = if bn == 1 then 0 else if (inside_start and future_bar_count == 7) then (cnt7[1] + 1) else cnt7[1];
def cnt8 = if bn == 1 then 0 else if (inside_start and future_bar_count == 8) then (cnt8[1] + 1) else cnt8[1];
def cnt9 = if bn == 1 then 0 else if (inside_start and future_bar_count == 9) then (cnt9[1] + 1) else cnt9[1];

def cnt10 = if bn == 1 then 0 else if (inside_start and future_bar_count > 9) then (cnt10[1] + 1) else cnt10[1];

input cnt_labels = yes;
addlabel(cnt_labels, "      " , color.black);
addlabel(cnt_labels, "3 bars " + cnt3, color.yellow);
addlabel(cnt_labels, "4 bars " + cnt4, color.yellow);
addlabel(cnt_labels, "5 bars " + cnt5, color.yellow);
addlabel(cnt_labels, "6 bars " + cnt6, color.yellow);
addlabel(cnt_labels, "7 bars " + cnt7, color.yellow);
addlabel(cnt_labels, "8 bars " + cnt8, color.yellow);
addlabel(cnt_labels, "9 bars " + cnt9, color.yellow);
addlabel(cnt_labels, "10+ bars " + cnt10, color.yellow);

#
@halcyonguy I really love this indicator, thank you! I am wondering if it would be possible to have the candles change color so that they are gray when inside the congestion zone and green (up) or red (down) when they exit the congestion zone, and to stay that color as long as the candles are making higher highs and higher lows (green) or lower highs and lower lows (red), else stay gray. If this works it would be great. Thanks.
 
Last edited:
@halcyonguy I really love this indicator, thank you! I am wondering if it would be possible to have the candles change color so that they are gray when inside the congestion zone and green (up) or red (down) when they exit the congestion zone, and to stay that color as long as the candles are making higher highs and higher lows (green) or lower highs and lower lows (red), else stay gray. If this works it would be great. Thanks.

this version, gray bars during congestion zone.
colored bars after a congestion zone


Code:
# congestion_box_00d_colors

#  add risk/reward lines , 3x
# https://usethinkscript.com/threads/congestion-zone.10503/#post-97560
# post 18

def na = double.nan;
def bn = barnumber();
#-------------------------------------
# choose wick or body price levels
input candle_levels = { default "wick" , "body" };
def highx;
def lowx;
switch (candle_levels) {
case "wick":
  highx = high;
  lowx = low;
case "body":
  highx = max(open, close);
  lowx = min(open, close);
}

def ht = highx - lowx;
#-----------------------------------
input min_inside_bars = 3;

input show_label__candle_levels = no;
addlabel(show_label__candle_levels, "Candle levels - " + candle_levels, color.yellow);

input show_label__min_inside_bars = no;
addlabel(show_label__min_inside_bars, "Min inside bars - " + min_inside_bars, color.yellow);
# --------------------------------
# test if a giant candle appears,  then ignore it
input ignore_big_candles = no;
input candle_ht_avg_multiplier_max = 5.0;
input candle_height_avg_len = 20;

def ht_avg = round(Average( ht[1], candle_height_avg_len),2);
def ht_avg_factor = round(ht / ht_avg, 1);

def ht_en = !ignore_big_candles or (ht < (ht_avg * candle_ht_avg_multiplier_max));
#----------------------------------
# inside bar , count smaller bars after the current bar 
def max_bars = 70;
def future_bar_count = fold k = 1 to max_bars
  with q = 1
## congestion , 1 bar parameter within high/low
  while (ht_en and (between(getvalue(highx, -k), lowx, highx) or between(getvalue(lowx, -k), lowx, highx)))
## insidebars , top and bottom of bar is within high/low
# while (ht_en and highx[0] >= getvalue(highx, -k) and lowx[0] <= getvalue(lowx, -k))
  do q + 1;


# -------------------------------
# count down from mother bar, to last inside bar
def rev_cnt =
 if bn == 1 then 0
 else if rev_cnt[1] > 1 then (rev_cnt[1] - 1)
 else if future_bar_count >= min_inside_bars then future_bar_count
 else 0;

def inside_start = (rev_cnt[1] <= 1 and future_bar_count >= min_inside_bars);
def start_cnt = if bn == 1 then 0 else if inside_start then (start_cnt[1] + 1) else start_cnt[1];

#def vert = 0.0006;
def vert = 0.00;
input show_cloud = yes;
input show_bubble_pattern_bar_count = no;
addchartbubble(show_bubble_pattern_bar_count and inside_start, (high * (1 + vert)), future_bar_count, color.gray, yes);

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

# ----------------------------------
# plot lines

def inside_hi =
 if rev_cnt == 0 then na
 else if inside_start then highx
 else inside_hi[1];

def inside_lo =
 if rev_cnt == 0 then na
 else if inside_start then lowx
 else inside_lo[1];

plot zhi = inside_hi;
plot zlo = inside_lo;

zhi.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zhi.SetStyle(Curve.MEDIUM_DASH);
#zhi.SetDefaultColor(Color.cyan);
zhi.SetDefaultColor(Color.gray);
zhi.setlineweight(1);
zhi.hidebubble();

zlo.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zlo.SetStyle(Curve.MEDIUM_DASH);
#zlo.SetDefaultColor(Color.cyan);
zlo.SetDefaultColor(Color.gray);
zlo.setlineweight(1);
zlo.hidebubble();


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


addchartbubble(0, low,
rev_cnt + " rcnt\n" +
inside_hi + " hi\n" +
inside_lo + " lo"
, color.yellow, no);

# ----------------
# hi lo levels for bar colors
def inside_hi2 =
 if inside_start then highx
 else inside_hi2[1];

def inside_lo2 =
 if inside_start then lowx
 else inside_lo2[1];

AssignPriceColor(
 if rev_cnt == 0 and close > inside_hi2 then color.green
 else if rev_cnt == 0 and close < inside_lo2 then color.red
 else color.gray);




# ---------------------------------------
# use 2 clouds, to avoid 2 adjacent patterns being connected
def iscnt_odd = ( start_cnt % 2 == 1 );

def zhiodd = if (show_cloud and iscnt_odd) then zhi else na;
addcloud(zhiodd, zlo, color.gray);
def zhieven = if (show_cloud and !iscnt_odd) then zhi else na;
addcloud(zhieven, zlo, color.gray);

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

input show_arrow_on_bar1 = no;
plot z1 = if show_arrow_on_bar1 and inside_start then (low * (1 - vert)) else na;
z1.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(2);
z1.hidebubble();
#
# ---------------------------------

# show risk/reward lines, a multiple of mother bar height

def rng = inside_hi - inside_lo;

input show_risk_reward_lines = yes;
def srr = show_risk_reward_lines;

plot reward1 = if srr then (inside_hi + (1 * rng)) else na;
reward1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
reward1.SetDefaultColor(Color.gray);
reward1.hidebubble();

plot reward2 = if srr then (inside_hi + (2 * rng)) else na;
reward2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
reward2.SetDefaultColor(Color.gray);
reward2.hidebubble();

plot reward3 = if srr then (inside_hi + (3 * rng)) else na;
reward3.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
reward3.SetDefaultColor(Color.gray);
reward3.hidebubble();


plot risk1 = if srr then (inside_lo - (1 * rng)) else na;
risk1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
risk1.SetDefaultColor(Color.gray);
risk1.hidebubble();

plot risk2 = if srr then (inside_lo - (2 * rng)) else na;
risk2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
risk2.SetDefaultColor(Color.gray);
risk2.hidebubble();

plot risk3 = if srr then (inside_lo - (3 * rng)) else na;
risk3.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
risk3.SetDefaultColor(Color.gray);
risk3.hidebubble();


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

# add horz lines at,
#  highest hi above box,
#  and lowest low below box
# iscnt_odd

input show_range_highest_lowest_lines = no;
def srl = show_range_highest_lowest_lines;

def toplimit;
if srl and inside_start then {
toplimit = fold t1 = 0 to max_bars
  with top1
  while t1 < future_bar_count
  do max(top1, getvalue(high, -t1));
} else if srl and rev_cnt > 0 then {
toplimit = toplimit[1];
} else {
toplimit = na;
}

plot zt = toplimit;
zt.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
zt.SetDefaultColor(Color.yellow);
#zt.setlineweight(1);
zt.hidebubble();


def botlimit;
if srl and inside_start then {
botlimit = fold b1 = 0 to max_bars
  with bot1 = 999999
  while b1 < future_bar_count
  do min(bot1, getvalue(low, -b1));
} else if srl and rev_cnt > 0 then {
botlimit = botlimit[1];
} else {
botlimit = na;
}

plot zb = botlimit;
zb.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
zb.SetDefaultColor(Color.yellow);
#zb.setlineweight(1);
zb.hidebubble();
#

uNxtkKV.jpg
 
this is similar and might of interest , so i am posting it


i misunderstood the question and made this study, that finds sequential inside bars
it has just 1 line that is different from my congestion study


inside bars

this looks for a big candle (bar #1) and several smaller candles (inside bars) after it.
if a bar is big, but less than the first bar of an existing pattern, it is ignored.
when price moves beyond the price levels of bar #1, the pattern stops.

. choose price levels , wicks or body.
. choose a minimum quantity of smaller bars before a pattern will start. default is 3.
. choose to ignore big candles. a candle much bigger won't be used to start a pattern.
. based on comparing to an average.
. pick the height factor(5) and average length(20)

. show color shading, cloud.
. show labels, wick or body, min quantity of bars.
. show a bubble with the count of bars in the pattern.
. show an arrow under the 1st bar of pattern.

on each bar, it compares future bars to the current bar, to see if 3 or more are smaller.


Ruby:
# insidebars_congestion_box_00f

#https://usethinkscript.com/threads/congestion-zone.10503/#post-92890
# find a pattern of several inside bars, that don't start from an abnormally large bar.

def na = double.nan;
def bn = barnumber();
#-------------------------------------
# choose wick or body price levels
input candle_levels = { "wick" , default "body" };
def highx;
def lowx;
switch (candle_levels) {
case "wick":
  highx = high;
  lowx = low;
case "body":
  highx = max(open, close);
  lowx = min(open, close);
}

def ht = highx - lowx;
#-----------------------------------
input min_inside_bars = 3;

input show_label__candle_levels = no;
addlabel(show_label__candle_levels, "Candle levels - " + candle_levels, color.yellow);

input show_label__min_inside_bars = no;
addlabel(show_label__min_inside_bars, "Min inside bars - " + min_inside_bars, color.yellow);
# --------------------------------
# test if a giant candle appears,  then ignore it
input ignore_big_candles = no;
input candle_ht_avg_multiplier_max = 5.0;
input candle_height_avg_len = 20;

def ht_avg = round(Average( ht[1], candle_height_avg_len),2);
def ht_avg_factor = round(ht / ht_avg, 1);

def ht_en = !ignore_big_candles or (ht < (ht_avg * candle_ht_avg_multiplier_max));
#----------------------------------
# inside bar , count smaller bars after the current bar
def max_bars = 50;
def inside_bar_count = fold k = 1 to max_bars
  with q = 1
  while (ht_en and highx[0] >= getvalue(highx, -k) and lowx[0] <= getvalue(lowx, -k))
  do q + 1;

# -------------------------------
def rev_cnt =
 if bn == 1 then 0
 else if rev_cnt[1] > 1 then (rev_cnt[1] - 1)
 else if inside_bar_count >= min_inside_bars then inside_bar_count
 else 0;

def inside_start = (rev_cnt[1] <= 1 and inside_bar_count >= min_inside_bars);
def start_cnt = if bn == 1 then 0 else if inside_start then (start_cnt[1] + 1) else start_cnt[1];

#def vert = 0.0006;
def vert = 0.00;
input show_cloud = yes;
input show_bubble_pattern_bar_count = yes;
addchartbubble(show_bubble_pattern_bar_count and inside_start, (high * (1 + vert)), inside_bar_count, color.gray, yes);

# ----------------------------------
# plot lines

def inside_hi =
 if rev_cnt == 0 then na
 else if inside_start then highx
 else inside_hi[1];

def inside_lo =
 if rev_cnt == 0 then na
 else if inside_start then lowx
 else inside_lo[1];

plot zhi = inside_hi;
plot zlo = inside_lo;

zhi.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zhi.SetStyle(Curve.MEDIUM_DASH);
#zhi.SetDefaultColor(Color.cyan);
zhi.SetDefaultColor(Color.gray);
zhi.setlineweight(1);
zhi.hidebubble();

zlo.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zlo.SetStyle(Curve.MEDIUM_DASH);
#zlo.SetDefaultColor(Color.cyan);
zlo.SetDefaultColor(Color.gray);
zlo.setlineweight(1);
zlo.hidebubble();

# ---------------------------------------
# use 2 clouds, to avoid 2 adjacent patterns being connected
def iscnt_odd = ( start_cnt % 2 == 1 );
def zhiodd = if (show_cloud and iscnt_odd) then zhi else na;
addcloud(zhiodd, zlo, color.gray);
def zhieven = if (show_cloud and !iscnt_odd) then zhi else na;
addcloud(zhieven, zlo, color.gray);

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

input show_arrow_on_bar1 = no;
plot z1 = if show_arrow_on_bar1 and inside_start then (low * (1 - vert)) else na;
z1.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(2);
z1.hidebubble();
#


pattern bar count bubbles turned on
/ES 3/7 4day 1min
hMNJmmK.jpg

hal_inside
I wanna do a little tweak to refine this script. I know the logic but dunn to know how to exactly write the script

First find the big bar, this bar is just a factor*average range of past n bars. i can see The script already has done this perfectly

Next define the high of the first big bar found as highx, define the following or current bar high as high[0], v1=lowest(highx, high[0])
v2=highest(lowx,low[0]). Please note the high[0] or Low[0] CAN be outside the highx and lowx range of FIRST big bar.

Then v3=abs(v1-v2)/(high[0]-low[0]) and has to be greater than 0.9, which is a static number.
if above condition is met, then this bar is an inside bar and as long as this condition is met, keep counting inside bars. Let's day the first big bar is identified, then the second inside bar is also identified, the current bar has to met
v1=lowest(highx, high[0])
v2=highest(lowx, low[0]) and
v3=abs(v1-v2)/(high[0]-low[0])>0.9 again. Please note the high or low of the second bar is not used, i only care about the current bar and FIRST big bar relationship

If the condition is not met. Then this pattern ends.

Appreciate it if any help can be provided!
 
Last edited:
I wanna do a little tweak to refine this script. I know the logic but dunn to know how to exactly write the script

First find the big bar, this bar is just a factor*average range of past n bars. i can see The script already has done this perfectly

Next define the high of the first big bar found as highx, define the following or current bar high as high[0], v1=lowest(highx, high[0])
v2=highest(lowx,low[0]). Please note the high[0] or Low[0] CAN be outside the highx and lowx range of FIRST big bar.

Then v3=abs(v1-v2)/(high[0]-low[0]) and has to be greater than 0.9, which is a static number.
if above condition is met, then this bar is an inside bar and as long as this condition is met, keep counting inside bars. Let's day the first big bar is identified, then the second inside bar is also identified, the current bar has to met
v1=lowest(highx, high[0])
v2=highest(lowx, low[0]) and
v3=abs(v1-v2)/(high[0]-low[0])>0.9 again. Please note the high or low of the second bar is not used, i only care about the current bar and FIRST big bar relationship

If the condition is not met. Then this pattern ends.

Appreciate it if any help can be provided!

this mod seems to be almost identical to my original study

Ruby:
# insidebars_congestion_box_ratio_00

# start with copy of
# insidebars_congestion_box_00f

# ============================================
# ============================================

def na = double.nan;
def bn = barnumber();
#-------------------------------------
# choose wick or body price levels
input candle_levels = { "wick" , default "body" };
def highx;
def lowx;
switch (candle_levels) {
case "wick":
  highx = high;
  lowx = low;
case "body":
  highx = max(open, close);
  lowx = min(open, close);
}

def ht = highx - lowx;
#-----------------------------------
input min_inside_bars = 3;

input show_label__candle_levels = no;
addlabel(show_label__candle_levels, "Candle levels - " + candle_levels, color.yellow);

input show_label__min_inside_bars = no;
addlabel(show_label__min_inside_bars, "Min inside bars - " + min_inside_bars, color.yellow);
# --------------------------------


# --------------------------------
# test if a giant candle appears,  then ignore it
input ignore_big_candles = no;
input candle_ht_avg_multiplier_max = 5.0;
input candle_height_avg_len = 20;

def ht_avg = round(Average( ht[1], candle_height_avg_len),2);
def ht_avg_factor = round(ht / ht_avg, 1);

def ht_en = !ignore_big_candles or (ht < (ht_avg * candle_ht_avg_multiplier_max));
#----------------------------------


# new code here

# ============================================
# ============================================
# ============================================

# rewrite the rules

#----------------------------------
# inside bar , count smaller bars after the current bar

# finding bar1 will have to be rewritten, because there are new rules to determine what bars are in congestion. the large bar, bar1, is found by looking at future bars, not bars in the past.
# 1. First find the big bar, this bar is just a factor*average range of past n bars. i can see The script already has done this perfectly

# redo these formulas below
# inside_start , true/false
# start_cnt , incr counter, starts at 1 on bar1


# 2. Next define the high of the first big bar, bar1, found as
#  highx


# ///////////////////////////////////////

input ratio_min = 0.9;

# inside bar , count bars after the current bar that meet the rules
def max_bars = 50;
def inside_bar_count = fold k = 1 to max_bars
  with q = 1
#  while (ht_en and highx[0] >= getvalue(highx, -k) and lowx[0] <= getvalue(lowx, -k))
  while (ht_en and

# v1 = min(highx, getvalue(high, -k)
# v2 = max(lowx, getvalue(low, -k)
# v3 = absvalue(v1-v2)/(high[0]-low[0]);
(absvalue( min(highx, getvalue(high, -k)) - max(lowx, getvalue(low, -k))) / (getvalue(high, -k) - getvalue(low, -k))) >= ratio_min)
  do q + 1;



# need to put  3 to 6 within a fold loop that looks at future bars
# this is just comparing to itself
# 3. comapare bar1 high to current high, find min
#def v1 = min(highx, high[0]);


# 4. comapare bar1 low to current low, find max
#def v2 = max(lowx, low[0]);
#  Please note the high[0] or Low[0] CAN be outside the highx and lowx range of FIRST big bar.


# 5. calc a ratio and compare to some number
#def v3 = absvalue(v1-v2)/(high[0]-low[0]);


# 6. v3 has to be greater than 0.9, which is a static number.
#input ratio_min = 0.9;
#def v3_en = if v3 >= ratio_min then 1 else 0;

#////////////////////////////////////////

# 7. if above condition is met, v3_en is true, then this bar is an inside bar and as long as this condition is met, keep counting inside bars.


#Let's say the first big bar is identified, then the second inside bar is also identified, the current bar has to met
#v1=lowest(highx, high[0])
#v2=highest(lowx, low[0]) and
#v3=abs(v1-v2)/(high[0]-low[0])>0.9 again. Please note the high or low of the second bar is not used, i only care about the current bar and FIRST big bar relationship

#If the condition is not met. Then this pattern ends.


addchartbubble(0, low*0.997,
bn + "\n" +
inside_bar_count + "\n"

, color.cyan, no);


# ============================================
# ============================================
# ============================================


#----------------------------------
# inside bar , count smaller bars after the current bar
#def max_bars = 50;
#def inside_bar_count = fold k = 1 to max_bars
#  with q = 1
##  while (ht_en and highx[0] >= getvalue(highx, -k) and lowx[0] <= getvalue(lowx, -k))
#  while (ht_en and getvalue(v3_en, -k))
#  do q + 1;

# -------------------------------
def rev_cnt =
 if bn == 1 then 0
 else if rev_cnt[1] > 1 then (rev_cnt[1] - 1)
 else if inside_bar_count >= min_inside_bars then inside_bar_count
 else 0;

def inside_start = (rev_cnt[1] <= 1 and inside_bar_count >= min_inside_bars);
def start_cnt = if bn == 1 then 0 else if inside_start then (start_cnt[1] + 1) else start_cnt[1];

#def vert = 0.0006;
def vert = 0.00;
input show_cloud = yes;
input show_bubble_pattern_bar_count = yes;
addchartbubble(show_bubble_pattern_bar_count and inside_start, (high * (1 + vert)), inside_bar_count, color.gray, yes);

# ----------------------------------
# plot lines

def inside_hi =
 if rev_cnt == 0 then na
 else if inside_start then highx
 else inside_hi[1];

def inside_lo =
 if rev_cnt == 0 then na
 else if inside_start then lowx
 else inside_lo[1];

plot zhi = inside_hi;
plot zlo = inside_lo;

zhi.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zhi.SetStyle(Curve.MEDIUM_DASH);
#zhi.SetDefaultColor(Color.cyan);
zhi.SetDefaultColor(Color.gray);
zhi.setlineweight(1);
zhi.hidebubble();

zlo.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zlo.SetStyle(Curve.MEDIUM_DASH);
#zlo.SetDefaultColor(Color.cyan);
zlo.SetDefaultColor(Color.gray);
zlo.setlineweight(1);
zlo.hidebubble();

# ---------------------------------------
# use 2 clouds, to avoid 2 adjacent patterns being connected
def iscnt_odd = ( start_cnt % 2 == 1 );
def zhiodd = if (show_cloud and iscnt_odd) then zhi else na;
addcloud(zhiodd, zlo, color.gray);
def zhieven = if (show_cloud and !iscnt_odd) then zhi else na;
addcloud(zhieven, zlo, color.gray);

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

input show_arrow_on_bar1 = no;
plot z1 = if show_arrow_on_bar1 and inside_start then (low * (1 - vert)) else na;
z1.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(2);
z1.hidebubble();
#
#
 
this mod seems to be almost identical to my original study

Ruby:
# insidebars_congestion_box_ratio_00

# start with copy of
# insidebars_congestion_box_00f

# ============================================
# ============================================

def na = double.nan;
def bn = barnumber();
#-------------------------------------
# choose wick or body price levels
input candle_levels = { "wick" , default "body" };
def highx;
def lowx;
switch (candle_levels) {
case "wick":
  highx = high;
  lowx = low;
case "body":
  highx = max(open, close);
  lowx = min(open, close);
}

def ht = highx - lowx;
#-----------------------------------
input min_inside_bars = 3;

input show_label__candle_levels = no;
addlabel(show_label__candle_levels, "Candle levels - " + candle_levels, color.yellow);

input show_label__min_inside_bars = no;
addlabel(show_label__min_inside_bars, "Min inside bars - " + min_inside_bars, color.yellow);
# --------------------------------


# --------------------------------
# test if a giant candle appears,  then ignore it
input ignore_big_candles = no;
input candle_ht_avg_multiplier_max = 5.0;
input candle_height_avg_len = 20;

def ht_avg = round(Average( ht[1], candle_height_avg_len),2);
def ht_avg_factor = round(ht / ht_avg, 1);

def ht_en = !ignore_big_candles or (ht < (ht_avg * candle_ht_avg_multiplier_max));
#----------------------------------


# new code here

# ============================================
# ============================================
# ============================================

# rewrite the rules

#----------------------------------
# inside bar , count smaller bars after the current bar

# finding bar1 will have to be rewritten, because there are new rules to determine what bars are in congestion. the large bar, bar1, is found by looking at future bars, not bars in the past.
# 1. First find the big bar, this bar is just a factor*average range of past n bars. i can see The script already has done this perfectly

# redo these formulas below
# inside_start , true/false
# start_cnt , incr counter, starts at 1 on bar1


# 2. Next define the high of the first big bar, bar1, found as
#  highx


# ///////////////////////////////////////

input ratio_min = 0.9;

# inside bar , count bars after the current bar that meet the rules
def max_bars = 50;
def inside_bar_count = fold k = 1 to max_bars
  with q = 1
#  while (ht_en and highx[0] >= getvalue(highx, -k) and lowx[0] <= getvalue(lowx, -k))
  while (ht_en and

# v1 = min(highx, getvalue(high, -k)
# v2 = max(lowx, getvalue(low, -k)
# v3 = absvalue(v1-v2)/(high[0]-low[0]);
(absvalue( min(highx, getvalue(high, -k)) - max(lowx, getvalue(low, -k))) / (getvalue(high, -k) - getvalue(low, -k))) >= ratio_min)
  do q + 1;



# need to put  3 to 6 within a fold loop that looks at future bars
# this is just comparing to itself
# 3. comapare bar1 high to current high, find min
#def v1 = min(highx, high[0]);


# 4. comapare bar1 low to current low, find max
#def v2 = max(lowx, low[0]);
#  Please note the high[0] or Low[0] CAN be outside the highx and lowx range of FIRST big bar.


# 5. calc a ratio and compare to some number
#def v3 = absvalue(v1-v2)/(high[0]-low[0]);


# 6. v3 has to be greater than 0.9, which is a static number.
#input ratio_min = 0.9;
#def v3_en = if v3 >= ratio_min then 1 else 0;

#////////////////////////////////////////

# 7. if above condition is met, v3_en is true, then this bar is an inside bar and as long as this condition is met, keep counting inside bars.


#Let's say the first big bar is identified, then the second inside bar is also identified, the current bar has to met
#v1=lowest(highx, high[0])
#v2=highest(lowx, low[0]) and
#v3=abs(v1-v2)/(high[0]-low[0])>0.9 again. Please note the high or low of the second bar is not used, i only care about the current bar and FIRST big bar relationship

#If the condition is not met. Then this pattern ends.


addchartbubble(0, low*0.997,
bn + "\n" +
inside_bar_count + "\n"

, color.cyan, no);


# ============================================
# ============================================
# ============================================


#----------------------------------
# inside bar , count smaller bars after the current bar
#def max_bars = 50;
#def inside_bar_count = fold k = 1 to max_bars
#  with q = 1
##  while (ht_en and highx[0] >= getvalue(highx, -k) and lowx[0] <= getvalue(lowx, -k))
#  while (ht_en and getvalue(v3_en, -k))
#  do q + 1;

# -------------------------------
def rev_cnt =
 if bn == 1 then 0
 else if rev_cnt[1] > 1 then (rev_cnt[1] - 1)
 else if inside_bar_count >= min_inside_bars then inside_bar_count
 else 0;

def inside_start = (rev_cnt[1] <= 1 and inside_bar_count >= min_inside_bars);
def start_cnt = if bn == 1 then 0 else if inside_start then (start_cnt[1] + 1) else start_cnt[1];

#def vert = 0.0006;
def vert = 0.00;
input show_cloud = yes;
input show_bubble_pattern_bar_count = yes;
addchartbubble(show_bubble_pattern_bar_count and inside_start, (high * (1 + vert)), inside_bar_count, color.gray, yes);

# ----------------------------------
# plot lines

def inside_hi =
 if rev_cnt == 0 then na
 else if inside_start then highx
 else inside_hi[1];

def inside_lo =
 if rev_cnt == 0 then na
 else if inside_start then lowx
 else inside_lo[1];

plot zhi = inside_hi;
plot zlo = inside_lo;

zhi.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zhi.SetStyle(Curve.MEDIUM_DASH);
#zhi.SetDefaultColor(Color.cyan);
zhi.SetDefaultColor(Color.gray);
zhi.setlineweight(1);
zhi.hidebubble();

zlo.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zlo.SetStyle(Curve.MEDIUM_DASH);
#zlo.SetDefaultColor(Color.cyan);
zlo.SetDefaultColor(Color.gray);
zlo.setlineweight(1);
zlo.hidebubble();

# ---------------------------------------
# use 2 clouds, to avoid 2 adjacent patterns being connected
def iscnt_odd = ( start_cnt % 2 == 1 );
def zhiodd = if (show_cloud and iscnt_odd) then zhi else na;
addcloud(zhiodd, zlo, color.gray);
def zhieven = if (show_cloud and !iscnt_odd) then zhi else na;
addcloud(zhieven, zlo, color.gray);

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

input show_arrow_on_bar1 = no;
plot z1 = if show_arrow_on_bar1 and inside_start then (low * (1 - vert)) else na;
z1.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(2);
z1.hidebubble();
#
#
I found this code doesn't plot real time, yesterday i was day trading and there wasn't any plots, but i think after the day session is over, then the plots showed, please see below picture.

EaIcYSL.png


What could be the reason for this?
 
@halcyonguy

In the earlier version 00a, you have used the following and called the bar "future_bar":

Code:
ht_en and
(
    between(getvalue(highx, -k), lowx, highx) or
    between(getvalue(lowx, -k), lowx, highx))
)

But in the later version 00f, you have switched to the following, and renamed "future_bar" into "inside_bar":

Code:
ht_en and
highx[0] >= getvalue(highx, -k) and
lowx[0] <= getvalue(lowx, -k)

What is the reason for:
(a) the switch of logic, as it produces less congestion zones in 00f
(b) the renaming

Should we use 00a or 00f for your latest, optimized version?
 
Also I am trying to make the "paint bar" feature as a selectable input, but keep getting errors, any help will be great:

Code:
# -------------------------------------------------
# HI LO levels for bar colors

input show_bar_painted = yes;

def inside_hi2 =
 if inside_start then highx
 else inside_hi2[1];

def inside_lo2 =
 if inside_start then lowx
 else inside_lo2[1];

AssignPriceColor(
  if (show_bar_painted == yes)
  {
      if rev_cnt == 0 and close > inside_hi2 then color.green
      else if rev_cnt == 0 and close < inside_lo2 then color.red
      else color.gray;
  }
  else
  {
      if close > open then color.green
      else if close < open then color.red
      else color.gray;
  }
 );
 
Also I am trying to make the "paint bar" feature as a selectable input, but keep getting errors, any help will be great:

Code:
# -------------------------------------------------
# HI LO levels for bar colors

input show_bar_painted = yes;

def inside_hi2 =
 if inside_start then highx
 else inside_hi2[1];

def inside_lo2 =
 if inside_start then lowx
 else inside_lo2[1];

AssignPriceColor(
  if (show_bar_painted == yes)
  {
      if rev_cnt == 0 and close > inside_hi2 then color.green
      else if rev_cnt == 0 and close < inside_lo2 then color.red
      else color.gray;
  }
  else
  {
      if close > open then color.green
      else if close < open then color.red
      else color.gray;
  }
 );

sorry i haven't responded yet, will try to this week. i've been busy and away from computer. (i answer many posts on my cell. but for some questions , like this, i need to be at my computer).
 
I found this code doesn't plot real time, yesterday i was day trading and there wasn't any plots, but i think after the day session is over, then the plots showed, please see below picture.

EaIcYSL.png


What could be the reason for this

this mod seems to be almost identical to my original study

Ruby:
# insidebars_congestion_box_ratio_00

# start with copy of
# insidebars_congestion_box_00f

# ============================================
# ============================================

def na = double.nan;
def bn = barnumber();
#-------------------------------------
# choose wick or body price levels
input candle_levels = { "wick" , default "body" };
def highx;
def lowx;
switch (candle_levels) {
case "wick":
  highx = high;
  lowx = low;
case "body":
  highx = max(open, close);
  lowx = min(open, close);
}

def ht = highx - lowx;
#-----------------------------------
input min_inside_bars = 3;

input show_label__candle_levels = no;
addlabel(show_label__candle_levels, "Candle levels - " + candle_levels, color.yellow);

input show_label__min_inside_bars = no;
addlabel(show_label__min_inside_bars, "Min inside bars - " + min_inside_bars, color.yellow);
# --------------------------------


# --------------------------------
# test if a giant candle appears,  then ignore it
input ignore_big_candles = no;
input candle_ht_avg_multiplier_max = 5.0;
input candle_height_avg_len = 20;

def ht_avg = round(Average( ht[1], candle_height_avg_len),2);
def ht_avg_factor = round(ht / ht_avg, 1);

def ht_en = !ignore_big_candles or (ht < (ht_avg * candle_ht_avg_multiplier_max));
#----------------------------------


# new code here

# ============================================
# ============================================
# ============================================

# rewrite the rules

#----------------------------------
# inside bar , count smaller bars after the current bar

# finding bar1 will have to be rewritten, because there are new rules to determine what bars are in congestion. the large bar, bar1, is found by looking at future bars, not bars in the past.
# 1. First find the big bar, this bar is just a factor*average range of past n bars. i can see The script already has done this perfectly

# redo these formulas below
# inside_start , true/false
# start_cnt , incr counter, starts at 1 on bar1


# 2. Next define the high of the first big bar, bar1, found as
#  highx


# ///////////////////////////////////////

input ratio_min = 0.9;

# inside bar , count bars after the current bar that meet the rules
def max_bars = 50;
def inside_bar_count = fold k = 1 to max_bars
  with q = 1
#  while (ht_en and highx[0] >= getvalue(highx, -k) and lowx[0] <= getvalue(lowx, -k))
  while (ht_en and

# v1 = min(highx, getvalue(high, -k)
# v2 = max(lowx, getvalue(low, -k)
# v3 = absvalue(v1-v2)/(high[0]-low[0]);
(absvalue( min(highx, getvalue(high, -k)) - max(lowx, getvalue(low, -k))) / (getvalue(high, -k) - getvalue(low, -k))) >= ratio_min)
  do q + 1;



# need to put  3 to 6 within a fold loop that looks at future bars
# this is just comparing to itself
# 3. comapare bar1 high to current high, find min
#def v1 = min(highx, high[0]);


# 4. comapare bar1 low to current low, find max
#def v2 = max(lowx, low[0]);
#  Please note the high[0] or Low[0] CAN be outside the highx and lowx range of FIRST big bar.


# 5. calc a ratio and compare to some number
#def v3 = absvalue(v1-v2)/(high[0]-low[0]);


# 6. v3 has to be greater than 0.9, which is a static number.
#input ratio_min = 0.9;
#def v3_en = if v3 >= ratio_min then 1 else 0;

#////////////////////////////////////////

# 7. if above condition is met, v3_en is true, then this bar is an inside bar and as long as this condition is met, keep counting inside bars.


#Let's say the first big bar is identified, then the second inside bar is also identified, the current bar has to met
#v1=lowest(highx, high[0])
#v2=highest(lowx, low[0]) and
#v3=abs(v1-v2)/(high[0]-low[0])>0.9 again. Please note the high or low of the second bar is not used, i only care about the current bar and FIRST big bar relationship

#If the condition is not met. Then this pattern ends.


addchartbubble(0, low*0.997,
bn + "\n" +
inside_bar_count + "\n"

, color.cyan, no);


# ============================================
# ============================================
# ============================================


#----------------------------------
# inside bar , count smaller bars after the current bar
#def max_bars = 50;
#def inside_bar_count = fold k = 1 to max_bars
#  with q = 1
##  while (ht_en and highx[0] >= getvalue(highx, -k) and lowx[0] <= getvalue(lowx, -k))
#  while (ht_en and getvalue(v3_en, -k))
#  do q + 1;

# -------------------------------
def rev_cnt =
 if bn == 1 then 0
 else if rev_cnt[1] > 1 then (rev_cnt[1] - 1)
 else if inside_bar_count >= min_inside_bars then inside_bar_count
 else 0;

def inside_start = (rev_cnt[1] <= 1 and inside_bar_count >= min_inside_bars);
def start_cnt = if bn == 1 then 0 else if inside_start then (start_cnt[1] + 1) else start_cnt[1];

#def vert = 0.0006;
def vert = 0.00;
input show_cloud = yes;
input show_bubble_pattern_bar_count = yes;
addchartbubble(show_bubble_pattern_bar_count and inside_start, (high * (1 + vert)), inside_bar_count, color.gray, yes);

# ----------------------------------
# plot lines

def inside_hi =
 if rev_cnt == 0 then na
 else if inside_start then highx
 else inside_hi[1];

def inside_lo =
 if rev_cnt == 0 then na
 else if inside_start then lowx
 else inside_lo[1];

plot zhi = inside_hi;
plot zlo = inside_lo;

zhi.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zhi.SetStyle(Curve.MEDIUM_DASH);
#zhi.SetDefaultColor(Color.cyan);
zhi.SetDefaultColor(Color.gray);
zhi.setlineweight(1);
zhi.hidebubble();

zlo.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zlo.SetStyle(Curve.MEDIUM_DASH);
#zlo.SetDefaultColor(Color.cyan);
zlo.SetDefaultColor(Color.gray);
zlo.setlineweight(1);
zlo.hidebubble();

# ---------------------------------------
# use 2 clouds, to avoid 2 adjacent patterns being connected
def iscnt_odd = ( start_cnt % 2 == 1 );
def zhiodd = if (show_cloud and iscnt_odd) then zhi else na;
addcloud(zhiodd, zlo, color.gray);
def zhieven = if (show_cloud and !iscnt_odd) then zhi else na;
addcloud(zhieven, zlo, color.gray);

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

input show_arrow_on_bar1 = no;
plot z1 = if show_arrow_on_bar1 and inside_start then (low * (1 - vert)) else na;
z1.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(2);
z1.hidebubble();
#
#
I believe this code is correct, however, it doesn't plot in real time. I am not sure why this happens....
 
I found this code doesn't plot real time, yesterday i was day trading and there wasn't any plots, but i think after the day session is over, then the plots showed, please see below picture.
What could be the reason for this?

sorry, i have not seen this. a study may pause for a few seconds. but i haven't seen one that stays blank during a trading day.
you didn't say what stock or what timeframe.
 
@halcyonguy

In the earlier version 00a, you have used the following and called the bar "future_bar":

Code:
ht_en and
(
    between(getvalue(highx, -k), lowx, highx) or
    between(getvalue(lowx, -k), lowx, highx))
)

But in the later version 00f, you have switched to the following, and renamed "future_bar" into "inside_bar":

Code:
ht_en and
highx[0] >= getvalue(highx, -k) and
lowx[0] <= getvalue(lowx, -k)

What is the reason for:
(a) the switch of logic, as it produces less congestion zones in 00f
(b) the renaming

Should we use 00a or 00f for your latest, optimized version?

i don't have a good answer,
if i changed a study, it was probably because someone asked for a change to something.
please read through the thread and determine if a study fits your style of trading.
most of what i post, i make for others, i don't use, so i don't have an opinion on them.
 
Also I am trying to make the "paint bar" feature as a selectable input, but keep getting errors, any help will be great:

Code:
# -------------------------------------------------
# HI LO levels for bar colors

input show_bar_painted = yes;

def inside_hi2 =
 if inside_start then highx
 else inside_hi2[1];

def inside_lo2 =
 if inside_start then lowx
 else inside_lo2[1];

AssignPriceColor(
  if (show_bar_painted == yes)
  {
      if rev_cnt == 0 and close > inside_hi2 then color.green
      else if rev_cnt == 0 and close < inside_lo2 then color.red
      else color.gray;
  }
  else
  {
      if close > open then color.green
      else if close < open then color.red
      else color.gray;
  }
 );

i don't think you can use that kind of a IF structure within a plotting parameter
try this

Code:
input show_bar_painted = yes;
def sbp = show_bar_painted;

def inside_hi2 =
 if inside_start then highx
 else inside_hi2[1];

def inside_lo2 =
 if inside_start then lowx
 else inside_lo2[1];

AssignPriceColor(
     if (sbp and rev_cnt == 0 and close > inside_hi2) then Color.GREEN
else if (sbp and rev_cnt == 0 and close < inside_lo2) then Color.RED
else if (!sbp and close > open) then Color.GREEN
else if (!sbp and close < open) then Color.RED
else Color.GRAY);
#
 
sorry, i have not seen this. a study may pause for a few seconds. but i haven't seen one that stays blank during a trading day.
you didn't say what stock or what timeframe.
If you could please plot it on QQQ 1 min chart, it will plot. However, in real time these congestion box won't show up until a trading session has ended.
 
this version has 3 risk and 3 reward lines

Code:
# congestion_box_00d

#  add risk/reward lines , 3x
# https://usethinkscript.com/threads/congestion-zone.10503/#post-97560
# post 18

def na = double.nan;
def bn = barnumber();
#-------------------------------------
# choose wick or body price levels
input candle_levels = { default "wick" , "body" };
def highx;
def lowx;
switch (candle_levels) {
case "wick":
  highx = high;
  lowx = low;
case "body":
  highx = max(open, close);
  lowx = min(open, close);
}

def ht = highx - lowx;
#-----------------------------------
input min_inside_bars = 3;

input show_label__candle_levels = no;
addlabel(show_label__candle_levels, "Candle levels - " + candle_levels, color.yellow);

input show_label__min_inside_bars = no;
addlabel(show_label__min_inside_bars, "Min inside bars - " + min_inside_bars, color.yellow);
# --------------------------------
# test if a giant candle appears,  then ignore it
input ignore_big_candles = no;
input candle_ht_avg_multiplier_max = 5.0;
input candle_height_avg_len = 20;

def ht_avg = round(Average( ht[1], candle_height_avg_len),2);
def ht_avg_factor = round(ht / ht_avg, 1);

def ht_en = !ignore_big_candles or (ht < (ht_avg * candle_ht_avg_multiplier_max));
#----------------------------------
# inside bar , count smaller bars after the current bar
def max_bars = 70;
def future_bar_count = fold k = 1 to max_bars
  with q = 1
## congestion , 1 bar parameter within high/low
  while (ht_en and (between(getvalue(highx, -k), lowx, highx) or between(getvalue(lowx, -k), lowx, highx)))
## insidebars , top and bottom of bar is within high/low
# while (ht_en and highx[0] >= getvalue(highx, -k) and lowx[0] <= getvalue(lowx, -k))
  do q + 1;


# -------------------------------
# count down from mother bar, to last inside bar
def rev_cnt =
 if bn == 1 then 0
 else if rev_cnt[1] > 1 then (rev_cnt[1] - 1)
 else if future_bar_count >= min_inside_bars then future_bar_count
 else 0;

def inside_start = (rev_cnt[1] <= 1 and future_bar_count >= min_inside_bars);
def start_cnt = if bn == 1 then 0 else if inside_start then (start_cnt[1] + 1) else start_cnt[1];

#def vert = 0.0006;
def vert = 0.00;
input show_cloud = yes;
input show_bubble_pattern_bar_count = no;
addchartbubble(show_bubble_pattern_bar_count and inside_start, (high * (1 + vert)), future_bar_count, color.gray, yes);

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

# ----------------------------------
# plot lines

def inside_hi =
 if rev_cnt == 0 then na
 else if inside_start then highx
 else inside_hi[1];

def inside_lo =
 if rev_cnt == 0 then na
 else if inside_start then lowx
 else inside_lo[1];

plot zhi = inside_hi;
plot zlo = inside_lo;

zhi.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zhi.SetStyle(Curve.MEDIUM_DASH);
#zhi.SetDefaultColor(Color.cyan);
zhi.SetDefaultColor(Color.gray);
zhi.setlineweight(1);
zhi.hidebubble();

zlo.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#zlo.SetStyle(Curve.MEDIUM_DASH);
#zlo.SetDefaultColor(Color.cyan);
zlo.SetDefaultColor(Color.gray);
zlo.setlineweight(1);
zlo.hidebubble();

# ---------------------------------------
# use 2 clouds, to avoid 2 adjacent patterns being connected
def iscnt_odd = ( start_cnt % 2 == 1 );

def zhiodd = if (show_cloud and iscnt_odd) then zhi else na;
addcloud(zhiodd, zlo, color.gray);
def zhieven = if (show_cloud and !iscnt_odd) then zhi else na;
addcloud(zhieven, zlo, color.gray);

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

input show_arrow_on_bar1 = no;
plot z1 = if show_arrow_on_bar1 and inside_start then (low * (1 - vert)) else na;
z1.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
z1.SetDefaultColor(Color.cyan);
z1.setlineweight(2);
z1.hidebubble();
#
# ---------------------------------

# show risk/reward lines, a multiple of mother bar height

def rng = inside_hi - inside_lo;

input show_risk_reward_lines = yes;
def srr = show_risk_reward_lines;

plot reward1 = if srr then (inside_hi + (1 * rng)) else na;
reward1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
reward1.SetDefaultColor(Color.gray);
reward1.hidebubble();

plot reward2 = if srr then (inside_hi + (2 * rng)) else na;
reward2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
reward2.SetDefaultColor(Color.gray);
reward2.hidebubble();

plot reward3 = if srr then (inside_hi + (3 * rng)) else na;
reward3.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
reward3.SetDefaultColor(Color.gray);
reward3.hidebubble();


plot risk1 = if srr then (inside_lo - (1 * rng)) else na;
risk1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
risk1.SetDefaultColor(Color.gray);
risk1.hidebubble();

plot risk2 = if srr then (inside_lo - (2 * rng)) else na;
risk2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
risk2.SetDefaultColor(Color.gray);
risk2.hidebubble();

plot risk3 = if srr then (inside_lo - (3 * rng)) else na;
risk3.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
risk3.SetDefaultColor(Color.gray);
risk3.hidebubble();




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

# add horz lines at,
#  highest hi above box,
#  and lowest low below box
# iscnt_odd

input show_range_highest_lowest_lines = no;
def srl = show_range_highest_lowest_lines;

def toplimit;
if srl and inside_start then {
toplimit = fold t1 = 0 to max_bars
  with top1
  while t1 < future_bar_count
  do max(top1, getvalue(high, -t1));
} else if srl and rev_cnt > 0 then {
toplimit = toplimit[1];
} else {
toplimit = na;
}

plot zt = toplimit;
zt.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
zt.SetDefaultColor(Color.yellow);
#zt.setlineweight(1);
zt.hidebubble();


def botlimit;
if srl and inside_start then {
botlimit = fold b1 = 0 to max_bars
  with bot1 = 999999
  while b1 < future_bar_count
  do min(bot1, getvalue(low, -b1));
} else if srl and rev_cnt > 0 then {
botlimit = botlimit[1];
} else {
botlimit = na;
}

plot zb = botlimit;
zb.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
zb.SetDefaultColor(Color.yellow);
#zb.setlineweight(1);
zb.hidebubble();



# -----------------------------------
# -----------------------------------
# test stuff - and me


addchartbubble(0, low*0.996,
inside_start + "\n" +
toplimit + "\n" +
rev_cnt + "\n" +
high + "\n"
, ( if inside_start then color.yellow else color.gray), no);



def u = 0;
addchartbubble(u and inside_start, low,
start_cnt + " cnt\n" +
iscnt_odd + " odd"
, color.yellow, no);


# count how many patterns on chart
# if a stock has many, more opportuneties to catch a move



def cnt3 = if bn == 1 then 0 else if (inside_start and future_bar_count == 3) then (cnt3[1] + 1) else cnt3[1];
def cnt4 = if bn == 1 then 0 else if (inside_start and future_bar_count == 4) then (cnt4[1] + 1) else cnt4[1];
def cnt5 = if bn == 1 then 0 else if (inside_start and future_bar_count == 5) then (cnt5[1] + 1) else cnt5[1];
def cnt6 = if bn == 1 then 0 else if (inside_start and future_bar_count == 6) then (cnt6[1] + 1) else cnt6[1];
def cnt7 = if bn == 1 then 0 else if (inside_start and future_bar_count == 7) then (cnt7[1] + 1) else cnt7[1];
def cnt8 = if bn == 1 then 0 else if (inside_start and future_bar_count == 8) then (cnt8[1] + 1) else cnt8[1];
def cnt9 = if bn == 1 then 0 else if (inside_start and future_bar_count == 9) then (cnt9[1] + 1) else cnt9[1];

def cnt10 = if bn == 1 then 0 else if (inside_start and future_bar_count > 9) then (cnt10[1] + 1) else cnt10[1];

input cnt_labels = yes;
addlabel(cnt_labels, "      " , color.black);
addlabel(cnt_labels, "3 bars " + cnt3, color.yellow);
addlabel(cnt_labels, "4 bars " + cnt4, color.yellow);
addlabel(cnt_labels, "5 bars " + cnt5, color.yellow);
addlabel(cnt_labels, "6 bars " + cnt6, color.yellow);
addlabel(cnt_labels, "7 bars " + cnt7, color.yellow);
addlabel(cnt_labels, "8 bars " + cnt8, color.yellow);
addlabel(cnt_labels, "9 bars " + cnt9, color.yellow);
addlabel(cnt_labels, "10+ bars " + cnt10, color.yellow);

#
Is there a way to put an Arrow on the last bar that is exiting the congestion box?
 

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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