Peaks Valleys Bar Questions

TNTrader5159

Active member
How would I call the BarNumber of a condition in its most recent occurrence prior to either the current bar or counting from x number of bars back? All I saw in the tutorial is that BarNumber() calls up the current bar. I do not understand what that means.

Let's say I want to call up the most recent occurrence of the Low being less than a defined reference in number of bars back, eg Low < Lowest(Low, 34)[1]. Thanks!
 
How would I call the BarNumber of a condition in its most recent occurrence prior to either the current bar or counting from x number of bars back? All I saw in the tutorial is that BarNumber() calls up the current bar. I do not understand what that means.

Let's say I want to call up the most recent occurrence of the Low being less than a defined reference in number of bars back, eg Low < Lowest(Low, 34)[1]. Thanks!
The bottom pane shows the following study denoting the occasions when the cond is true/1.

The same study on the upper shows the barnumbers, an arrow at the last true condition and a label with that barnumber. I also included the Pricechannel Indicator which uses the logic in your example.

Capture.jpg
Ruby:
plot Data = low < Lowest(low[1], 34);
plot bn    = BarNumber();
bn.setpaintingStrategy(paintingStrategy.VALUES_ABOVE);
def cond  = if Data then bn else cond[1];
AddLabel(1, cond);
plot x = if bn==highestall(cond) then 1 else double.nan;
x.setpaintingStrategy(paintingStrategy.BOOLEAN_ARROW_up);
 
Last edited:
The bottom pane shows the following study denoting the occasions when the cond is true/1.

The same study on the upper shows the barnumbers, an arrow at the last true condition and a label with that barnumber. I also included the Pricechannel Indicator which uses the logic in your example.
Thank you so much! This opens many possibilities for me. The tools are always just around the learning curve.
 
Is there a pre-defined way to code a Pivot point with a minimum x number of bars on each side? In EasyLanguage, it's like this:
Pivot(H, 144, 3, 3, 1, -1, oPivotPrice, oPivotBar).

will show a 10-minute tutorial on this function.

What is the best way to define a Pivot point in ThinkScript with variable strength sides? In this case...

L = part of the bars to look at (usually Low for a Low Pivot)
144 = (any number of) bars to look back for Pivots
3 = minimum left strength
3 = minimum right strength
1 = 1st retrospective instance
-1 = look for Low Pivots
oPivotPrice = price of the Pivot Point (returned)
oPivotBar = number of bars back it occurred (returned)

What is the best way to express this concept/function in ThinkScript? Thanks!
 
Is there a pre-defined way to code a Pivot point with a minimum x number of bars on each side? In EasyLanguage, it's like this:
Pivot(H, 144, 3, 3, 1, -1, oPivotPrice, oPivotBar).

will show a 10-minute tutorial on this function.

What is the best way to define a Pivot point in ThinkScript with variable strength sides? In this case...

L = part of the bars to look at (usually Low for a Low Pivot)
144 = (any number of) bars to look back for Pivots
3 = minimum left strength
3 = minimum right strength
1 = 1st retrospective instance
-1 = look for Low Pivots
oPivotPrice = price of the Pivot Point (returned)
oPivotBar = number of bars back it occurred (returned)

What is the best way to express this concept/function in ThinkScript? Thanks!

take a look at this, post10
it uses an offset variable, that changes as it gets closer to the last bar.
https://usethinkscript.com/threads/...y-demand-zones-for-thinkorswim.172/#post-7048
 
How would the code be written to find the bar number of the highest price over the 10 bars prior to the current bar?

Thanks in advance!

use an offset on high , high[1] , to start reading bars , 1 bar back.

Code:
input len = 10;
def off = GetMaxValueOffset(high[1], len);
def barnum = barnumber() - off;
 
I tried this and it worked fine, except for the input having to be a constant, as it needs to be a pre-defined variable.
Here's what I have that gets rejected for the input Len being a variable. The number 10 I gave as an example for the number of bars looked at was random.

declare lower;

def BN = BarNumber();

def EngBarsHigh = fold IndexHigh = 1 to bn with pHigh = 0
while GetValue(high, IndexHigh) < high do pHigh + 1;

def EngBarsLow = fold IndexLow = 1 to bn with pLow = 0
while GetValue(low, IndexLow) > low do pLow + 1;

def EngTotal = Min(EngBarsHigh, EngBarsLow);

input Len = EngTotal;

def OffsetHigh = GetMaxValueOffset(high[1], Len);

def BarNumHigh = BN - OffsetHigh;

def OffsetLow = GetMaxValueOffset(low[1], Len);

def BarNumLow = BN - OffsetLow;

plot ThrustFactor = BN - min(BarNumHigh, BarNumLow);
 
I tried this and it worked fine, except for the input having to be a constant, as it needs to be a defined variable.

you asked for 10, a constant, and that's what i made.

looking at your code, looks like you are looking for engulfing bars.

just a min..........
 
Last edited:
Here's what I have that gets rejected for the input Len being a variable. The number 10 I gave as an example for the number of bars looked at was random.


take a look at this and see if it helps
it finds engulfing bars


Code:
# outsidebars_01_engulf_cln

# engulfing pattern,
#  find qty of engulf bars, display in a bubble
#  draw lines to mother bar

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

input minimum_engulfed_bars = 3;
input show_engulfed_count_bubbles = yes;
input show_horizontal_engulf_lines = yes;
def lookback = 48;
#def offset = lookback;
def barup = (close > open);

# find engulfing bar
# look backwards for an engulfing bar
# count how many previous bars are smaller than the current bar
#def lookback = 48;
def bigbarcnt1 = fold k = 1 to lookback
  with p
  while (high >= getvalue(high, k) and low <= getvalue(low, k))
  do p + 1;

# disable engulfing bars with too few smaller bars
def bigbarcnt2 = if bigbarcnt1 >= minimum_engulfed_bars then bigbarcnt1 else 0;

# is the next future engulf bar, engulfing the current engulf bar?
# if yes , then disable current engulf bar
def bigbar_off2 = fold m = 1 to lookback
  with q = 1
  while getvalue(bigbarcnt2, -m) == 0
  do q + 1;

def bigbarcnt3;
if isnan( getvalue(high, -bigbar_off2) ) then {
  bigbarcnt3 = bigbarcnt2;
} else if (getvalue(high, -bigbar_off2) > high and getvalue(low, -bigbar_off2) < low) then {
  bigbarcnt3 = 0;
} else {
  bigbarcnt3 = bigbarcnt2;
}

def outbar = if (bigbarcnt3 >= minimum_engulfed_bars) then 1 else 0;

# bubble with qty of engulfed bars
addchartbubble(show_engulfed_count_bubbles and outbar,(low * 0.999), bigbarcnt3, if bigbarcnt3 == 0 then color.dark_gray else if barup then color.green else color.red, no);

# look ahead to find qty of bars to next mother bar
def engulf_off = fold n = 0 to lookback
  with r
  while getvalue(bigbarcnt3, -n) == 0
  do r + 1;

def gulf_hi = if (show_horizontal_engulf_lines and getvalue(bigbarcnt3, -engulf_off) >= engulf_off) then getvalue(high, -engulf_off) else na;
def gulf_lo = if (show_horizontal_engulf_lines and getvalue(bigbarcnt3, -engulf_off) >= engulf_off) then getvalue(low, -engulf_off) else na;
plot zhi = gulf_hi;
plot zlo = gulf_lo;
zhi.SetDefaultColor(Color.cyan);
zhi.hidebubble();
zlo.SetDefaultColor(Color.cyan);
zlo.hidebubble();


def engulf_first = bn - bigbarcnt3;
addchartbubble(show_engulfed_count_bubbles and outbar,(low * 0.999),
 bn + " this bn\n" +
 engulf_first + " first bn\n" 
, color.gray, no);


def line_start = if (isnan(gulf_hi[1]) and !isnan(gulf_hi)) then 1 else 0;
def start_bn = if line_start then bn else start_bn[1];


input show_first_bn = yes;
addchartbubble(show_first_bn and line_start, gulf_hi,
start_bn
, color.yellow, yes);


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

input test1 = no;
addchartbubble(test1 , high,
engulf_off + "\n" +
line_start + "\n" +
start_bn
, (if line_start then color.yellow else color.gray), yes);

input test2 = no;
addchartbubble(test2, (low * 0.999),
 bigbarcnt1 + "  1\n" +
 bigbarcnt2 + "  2\n" +
 bigbar_off2 + "  off2\n" +
 bigbarcnt3 + "  3\n" 
# engulf_off
, color.cyan, no);


#input test_bubbles1 = no;
def test_bubbles1 = 0;
addchartbubble((test_bubbles1 and bigbarcnt1 > 0),(low * 0.999), bigbarcnt1 + " 1", if bigbarcnt1 == 0 then color.dark_gray else if barup then color.green else color.red, no);

addchartbubble((test_bubbles1 and bigbarcnt2 >= minimum_engulfed_bars),(low * 0.999), bigbarcnt2 + " 2", if bigbarcnt2 == 0 then color.dark_gray else if barup then color.green else color.red, no);

addchartbubble((test_bubbles1 and bigbarcnt3 >= minimum_engulfed_bars),(low * 0.999), bigbarcnt3 + " 3", if bigbarcnt3 == 0 then color.dark_gray else if barup then color.green else color.red, no);
#

this has bubbles turned on,
yellow , to show start barnumber
gray , end bn and start bn
red , quantity of engulfed bars
68kQvMW.jpg
 
take a look at this and see if it helps
it finds engulfing bars


Code:
# outsidebars_01_engulf_cln

# engulfing pattern,
#  find qty of engulf bars, display in a bubble
#  draw lines to mother bar

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

input minimum_engulfed_bars = 3;
input show_engulfed_count_bubbles = yes;
input show_horizontal_engulf_lines = yes;
def lookback = 48;
#def offset = lookback;
def barup = (close > open);

# find engulfing bar
# look backwards for an engulfing bar
# count how many previous bars are smaller than the current bar
#def lookback = 48;
def bigbarcnt1 = fold k = 1 to lookback
  with p
  while (high >= getvalue(high, k) and low <= getvalue(low, k))
  do p + 1;

# disable engulfing bars with too few smaller bars
def bigbarcnt2 = if bigbarcnt1 >= minimum_engulfed_bars then bigbarcnt1 else 0;

# is the next future engulf bar, engulfing the current engulf bar?
# if yes , then disable current engulf bar
def bigbar_off2 = fold m = 1 to lookback
  with q = 1
  while getvalue(bigbarcnt2, -m) == 0
  do q + 1;

def bigbarcnt3;
if isnan( getvalue(high, -bigbar_off2) ) then {
  bigbarcnt3 = bigbarcnt2;
} else if (getvalue(high, -bigbar_off2) > high and getvalue(low, -bigbar_off2) < low) then {
  bigbarcnt3 = 0;
} else {
  bigbarcnt3 = bigbarcnt2;
}

def outbar = if (bigbarcnt3 >= minimum_engulfed_bars) then 1 else 0;

# bubble with qty of engulfed bars
addchartbubble(show_engulfed_count_bubbles and outbar,(low * 0.999), bigbarcnt3, if bigbarcnt3 == 0 then color.dark_gray else if barup then color.green else color.red, no);

# look ahead to find qty of bars to next mother bar
def engulf_off = fold n = 0 to lookback
  with r
  while getvalue(bigbarcnt3, -n) == 0
  do r + 1;

def gulf_hi = if (show_horizontal_engulf_lines and getvalue(bigbarcnt3, -engulf_off) >= engulf_off) then getvalue(high, -engulf_off) else na;
def gulf_lo = if (show_horizontal_engulf_lines and getvalue(bigbarcnt3, -engulf_off) >= engulf_off) then getvalue(low, -engulf_off) else na;
plot zhi = gulf_hi;
plot zlo = gulf_lo;
zhi.SetDefaultColor(Color.cyan);
zhi.hidebubble();
zlo.SetDefaultColor(Color.cyan);
zlo.hidebubble();


def engulf_first = bn - bigbarcnt3;
addchartbubble(show_engulfed_count_bubbles and outbar,(low * 0.999),
 bn + " this bn\n" +
 engulf_first + " first bn\n"
, color.gray, no);


def line_start = if (isnan(gulf_hi[1]) and !isnan(gulf_hi)) then 1 else 0;
def start_bn = if line_start then bn else start_bn[1];


input show_first_bn = yes;
addchartbubble(show_first_bn and line_start, gulf_hi,
start_bn
, color.yellow, yes);


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

input test1 = no;
addchartbubble(test1 , high,
engulf_off + "\n" +
line_start + "\n" +
start_bn
, (if line_start then color.yellow else color.gray), yes);

input test2 = no;
addchartbubble(test2, (low * 0.999),
 bigbarcnt1 + "  1\n" +
 bigbarcnt2 + "  2\n" +
 bigbar_off2 + "  off2\n" +
 bigbarcnt3 + "  3\n"
# engulf_off
, color.cyan, no);


#input test_bubbles1 = no;
def test_bubbles1 = 0;
addchartbubble((test_bubbles1 and bigbarcnt1 > 0),(low * 0.999), bigbarcnt1 + " 1", if bigbarcnt1 == 0 then color.dark_gray else if barup then color.green else color.red, no);

addchartbubble((test_bubbles1 and bigbarcnt2 >= minimum_engulfed_bars),(low * 0.999), bigbarcnt2 + " 2", if bigbarcnt2 == 0 then color.dark_gray else if barup then color.green else color.red, no);

addchartbubble((test_bubbles1 and bigbarcnt3 >= minimum_engulfed_bars),(low * 0.999), bigbarcnt3 + " 3", if bigbarcnt3 == 0 then color.dark_gray else if barup then color.green else color.red, no);
#

this has bubbles turned on,
yellow , to show start barnumber
gray , end bn and start bn
red , quantity of engulfed bars
68kQvMW.jpg
Yes, first to see HOW MANY bars the current bar may engulf.
<p>
Then to find the relative positions of the highest and lowest prices within the engulfed range.
<p>
Then to take the farther one back or lower bar number of those two prices, and subtract it from the current bar number.
<p>
This returns the final value I call the Thrust Factor. The Thrust Factor measures the strength of the pattern once a breakout to either the upside or downside of the engulfed range occurs in real time. And of course which occurs first is the key to trade direction. That's another matter though.
<p>
The Thrust Factor must be a minimum of 3 to qualify for a legit pattern per my definition. Otherwise it would be discarded from further qualifications for a trade, ie the Impedance Factor, which is irrelevant to the current discussion.
<p>
So for now, if I can determine the Thrust Factor, that part will be complete.
<p>
Your code shows the sizes of all engulfed ranges, which is good, and now only the highs and lows of those engulfed ranges need to be determined, with the bar number of the farther one back subtracted from the number of the engulfing bar to return the Thrust Factor.
<p>
It looks like the Thrust Factor of the first example on your chart with 21 total bars engulfed would be either 16 or 21, as it's hard to tell which of those two bars was higher. The second example with 7 total bars engulfed would be 6, with the high occurring on Bar 179 and the low on Bar 176 vs Bar 182 as the engulfing bar.
<p>
Both signals indicated taking Short positions.
 
Yes, first to see HOW MANY bars the current bar may engulf.
<p>
Then to find the relative positions of the highest and lowest prices within the engulfed range.
<p>
Then to take the farther one back or lower bar number of those two prices, and subtract it from the current bar number.
<p>
This returns the final value I call the Thrust Factor. The Thrust Factor measures the strength of the pattern once a breakout to either the upside or downside of the engulfed range occurs in real time. And of course which occurs first is the key to trade direction. That's another matter though.
<p>
The Thrust Factor must be a minimum of 3 to qualify for a legit pattern per my definition. Otherwise it would be discarded from further qualifications for a trade, ie the Impedance Factor, which is irrelevant to the current discussion.
<p>
So for now, if I can determine the Thrust Factor, that part will be complete.
<p>
Your code shows the sizes of all engulfed ranges, which is good, and now only the highs and lows of those engulfed ranges need to be determined, with the bar number of the farther one back subtracted from the number of the engulfing bar to return the Thrust Factor.
<p>
It looks like the Thrust Factor of the first example on your chart with 21 total bars engulfed would be either 16 or 21, as it's hard to tell which of those two bars was higher. The second example with 7 total bars engulfed would be 6, with the high occurring on Bar 179 and the low on Bar 176 vs Bar 182 as the engulfing bar.
<p>
Both signals indicated taking Short positions.

thanks for explaing it, again, i think i am getting it. thanks for being patient. this helps , talking about specs, related to a study.
 
thanks for explaing it, again, i think i am getting it. thanks for being patient. this helps , talking about specs, related to a study.
I should thank you for being patient with me.
<p>
I have been working with an EasyLanguage programmer so I can ultimately trade at TradeStation, where they support full automation and have very low commissions. For study, I seem to grasp ThinkScript better than I do EasyLanguage, and I like the TD Ameritrade platform better for doing research and illustrations.
<p>
Since this is to be my livelihood that must entail automation so I can stop looking at charts so much and have a life, I am seeking to code my indicator in ThinkScript to be able to use with TD Ameritrade but ideally have translated over to EasyLanguage for automated trading once everything is proven bulletproof. I have all requirement down to the last detail now, and now it's only a matter of writing them into code and see how they do in back-testing and simulated trading before fully automating them and retiring in a sense.
<p>
I cannot thank you enough for helping me over these humps that seem like mountains with my pain-wracked body and foggy brain!
 
I should thank you for being patient with me.
<p>
I have been working with an EasyLanguage programmer so I can ultimately trade at TradeStation, where they support full automation and have very low commissions. For study, I seem to grasp ThinkScript better than I do EasyLanguage, and I like the TD Ameritrade platform better for doing research and illustrations.
<p>
Since this is to be my livelihood that must entail automation so I can stop looking at charts so much and have a life, I am seeking to code my indicator in ThinkScript to be able to use with TD Ameritrade but ideally have translated over to EasyLanguage for automated trading once everything is proven bulletproof. I have all requirement down to the last detail now, and now it's only a matter of writing them into code and see how they do in back-testing and simulated trading before fully automating them and retiring in a sense.
<p>
I cannot thank you enough for helping me over these humps that seem like mountains with my pain-wracked body and foggy brain!


i think this is getting closer.
look at the bubbles and see if the numbers are what you want to find.


i started with code from post7.
copied the rules from post8, to the end of the code.
numbered the rules and added code for each rule.

find large engulfing bar.
count the bars that are engulfed, all the previous bars that are smaller.
within the engulfed bars, find the highest high and lowest low. draw dots at those prices
find which one occurs first


something for you to read and think about.
i wrote out some comments/questions after rule 4, and copied them up here.

i'm not sure what the 'breakout' bar is that you want to find.

# rule 4 questions
# you will have to define what a breakout is.
# there will be a highest price and a lowest price DURING a group of engulfed bars.
# but those 2 points are within the engulfed price range. they didn't 'breakout'.
#
# there is only 1 breakout during a group of engulfed bars, on the bar after the last, big, engulfing bar.
# ( we could call the first bar, a breakin )



Ruby:
# outsidebars_02b_engulf_cln

# mod with his rules
# rework engulf , # with thrust terms
# https://usethinkscript.com/threads/finding-the-bar-number-of-the-highest-price-within-a-known-group-of-bars.12721/#post-108393
# post10  TNTrader5159
#------------------------------------

# engulfing pattern,
#  find qty of engulf bars, display in a bubble
#  draw lines to mother bar

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

input minimum_engulfed_bars = 3;
input show_engulfed_count_bubbles = yes;
input show_horizontal_engulf_lines = yes;
def lookback = 48;
#def offset = lookback;
def barup = (close > open);

# find engulfing bar
# look backwards for an engulfing bar
# count how many previous bars are smaller than the current bar
#def lookback = 48;
def bigbarcnt1 = fold k = 1 to lookback
  with p
  while (high >= getvalue(high, k) and low <= getvalue(low, k))
  do p + 1;

# disable engulfing bars with too few smaller bars
def bigbarcnt2 = if bigbarcnt1 >= minimum_engulfed_bars then bigbarcnt1 else 0;

# is the next future engulf bar, engulfing the current engulf bar?
# if yes , then disable current engulf bar
def bigbar_off2 = fold m = 1 to lookback
  with q = 1
  while getvalue(bigbarcnt2, -m) == 0
  do q + 1;

def bigbarcnt3;
if isnan( getvalue(high, -bigbar_off2) ) then {
  bigbarcnt3 = bigbarcnt2;
} else if (getvalue(high, -bigbar_off2) > high and getvalue(low, -bigbar_off2) < low) then {
  bigbarcnt3 = 0;
} else {
  bigbarcnt3 = bigbarcnt2;
}

def outbar = if (bigbarcnt3 >= minimum_engulfed_bars) then 1 else 0;

# bubble with qty of engulfed bars
addchartbubble(show_engulfed_count_bubbles and outbar,(low * 0.999), bigbarcnt3, if bigbarcnt3 == 0 then color.dark_gray else if barup then color.green else color.red, no);

# look ahead to find qty of bars to next mother bar
def engulf_off = fold n = 0 to lookback
  with r
  while getvalue(bigbarcnt3, -n) == 0
  do r + 1;

def gulf_hi = if (show_horizontal_engulf_lines and getvalue(bigbarcnt3, -engulf_off) >= engulf_off) then getvalue(high, -engulf_off) else na;
def gulf_lo = if (show_horizontal_engulf_lines and getvalue(bigbarcnt3, -engulf_off) >= engulf_off) then getvalue(low, -engulf_off) else na;
plot zhi = gulf_hi;
plot zlo = gulf_lo;
zhi.SetDefaultColor(Color.cyan);
zhi.hidebubble();
zlo.SetDefaultColor(Color.cyan);
zlo.hidebubble();


def engulf_first = bn - bigbarcnt3;
input test_show_first_last_bns = yes;
addchartbubble(test_show_first_last_bns and outbar,(low * 0.999),
 bn + " this bn\n" +
 engulf_first + " first bn\n"
, color.gray, no);


# find the first bar in an engulfed line, which is the same as the engulfed group
def line_start = if (isnan(gulf_hi[1]) and !isnan(gulf_hi)) then 1 else 0;
def start_bn = if line_start then bn else start_bn[1];


input test_show_first_bn = yes;
addchartbubble(test_show_first_bn and line_start, gulf_hi,
start_bn + "  start bn\n" +
engulf_off + "  engulfed bars"
, color.yellow, yes);


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

input test1 = no;
addchartbubble(test1 , high,
engulf_off + "\n" +
line_start + "\n" +
start_bn
, (if line_start then color.yellow else color.gray), yes);

input test2 = no;
addchartbubble(test2, (low * 0.999),
 bigbarcnt1 + "  1\n" +
 bigbarcnt2 + "  2\n" +
 bigbar_off2 + "  off2\n" +
 bigbarcnt3 + "  3\n"
# engulf_off
, color.cyan, no);


#input test_bubbles1 = no;
def test_bubbles1 = 0;
addchartbubble((test_bubbles1 and bigbarcnt1 > 0),(low * 0.999), bigbarcnt1 + " 1", if bigbarcnt1 == 0 then color.dark_gray else if barup then color.green else color.red, no);

addchartbubble((test_bubbles1 and bigbarcnt2 >= minimum_engulfed_bars),(low * 0.999), bigbarcnt2 + " 2", if bigbarcnt2 == 0 then color.dark_gray else if barup then color.green else color.red, no);

addchartbubble((test_bubbles1 and bigbarcnt3 >= minimum_engulfed_bars),(low * 0.999), bigbarcnt3 + " 3", if bigbarcnt3 == 0 then color.dark_gray else if barup then color.green else color.red, no);
#




#------------------------------------
#------------------------------------
# mod with his rules in post#10
# rework engulf ,  with thrust terms
# https://usethinkscript.com/threads/finding-the-bar-number-of-the-highest-price-within-a-known-group-of-bars.12721/#post-108393
# post10  TNTrader5159
#------------------------------------
#------------------------------------

# make new vars, labels

# 1.  Yes, first to see HOW MANY bars the current bar may engulf.
# recent engulf quantity
def engulf_bars = if outbar then bigbarcnt3 else engulf_bars[1];
addlabel(1, "recent engulf bars, quantity " + engulf_bars, color.yellow);


# 2.  Then to find the relative positions of the highest and lowest prices within the engulfed range.

#  loop , from  line_start to outbar
#   loop ,   0 to engulf_off  ( the qty of engulded bars )

def engulfed_hi;
def engulfed_lo;
def engulfed_hibn;
def engulfed_lobn;
def xbn;
if line_start then {
  xbn = bn;
#  start at the 1st bar of an engulfed period,
#  look at future bars for the highest price
  engulfed_hi = fold g1 = 0 to (engulf_off-0)
  with g2
  while !isnan(gulf_hi)
  do (if getvalue(high, -g1) > g2 then getvalue(high, -g1) else g2);

#  look at future bars for the lowest price
  engulfed_lo = fold h1 = 0 to (engulf_off-0)
  with h2 = 99999
  while !isnan(gulf_hi)
  do (if getvalue(low, -h1) < h2 then getvalue(low, -h1) else h2);


# look for the highest and lowest price , and read the bn
  engulfed_hibn = fold g3 = 0 to (engulf_off - 0)
  with g4
  while !isnan(gulf_hi)
  do (if engulfed_hi == getvalue(high, -g3) then (bn + g3) else g4);

  engulfed_lobn = fold h3 = 0 to (engulf_off-0)
  with h4
  while !isnan(gulf_hi)
  do (if engulfed_lo == getvalue(low, -h3) then (bn + h3) else h4);

} else {
  engulfed_hi = engulfed_hi[1];
  engulfed_lo = engulfed_lo[1];
  engulfed_hibn = engulfed_hibn[1];
  engulfed_lobn = engulfed_lobn[1];
  xbn = xbn[1];
}


# plot points on highest and lowest prices, that are engulfed
input show_points_onhighest_lowest_in_engulfed_group = yes;
plot zenhi = if show_points_onhighest_lowest_in_engulfed_group and bn == engulfed_hibn then high else na;
 zenhi.SetPaintingStrategy(PaintingStrategy.POINTS);
 zenhi.SetDefaultColor(Color.white);
 zenhi.setlineweight(2);
 zenhi.hidebubble();

plot zenlo = if show_points_onhighest_lowest_in_engulfed_group and bn == engulfed_lobn then low else na;
#plot zenlo = if bn == xbn then low else na;
 zenlo.SetPaintingStrategy(PaintingStrategy.POINTS);
 zenlo.SetDefaultColor(Color.white);
 zenlo.setlineweight(2);
 zenlo.hidebubble();


input test_hi_lo_bns = yes;
addchartbubble(test_hi_lo_bns and line_start, gulf_lo*0.999,
"hi $" + engulfed_hi + " at bn: " + engulfed_hibn + "\n" +
"lo $" + engulfed_lo + " at bn: " + engulfed_lobn
, color.yellow, no);


# 3. Then to take the farther one back or lower bar number of those two prices, and subtract it from the current bar number.

def engulf_minbn = min( engulfed_hibn, engulfed_lobn);
def t = if line_start then ((bn + engulf_off) - engulf_minbn) else t[1];

# offset from first engulfed bar , to the first low/hi
def t_start_off  = engulf_minbn - bn;



# 4. This returns the final value I call the Thrust Factor.
# The Thrust Factor measures the strength of the pattern once a breakout to either the upside or downside of the engulfed range occurs in real time.
# And of course which occurs first is the key to trade direction. That's another matter though.


# is the offset t pointing to the highest price in the group?
def isfirst_hi = if getvalue(high, -t_start_off) == engulfed_hi then 1 else 0;

# show a green or red bubble, on the first bar of engulfed group, that lists which comes first, a low or a high.
addchartbubble(line_start, gulf_lo*0.999,
getvalue(high, -t_start_off) + " t hi\n" +
#engulfed_hi + " ehi\n" +
(if isfirst_hi then "High" else "Low") + "  is first"
, (if isfirst_hi then color.green else color.red), no);



# rule 4 questions
# you will have to define what a breakout is.
# there will be a highest price and a lowest price DURING a group of engulfed bars.
# but thos 2 points are within the engulfed price range. they didn't 'breakout'.

# there is only 1 breakout during a group of engulfed bars, on the bar after the last, big, engulfing bar.
# ( we could call the first bar, a breakin )





# 5. The Thrust Factor must be a minimum of 3 to qualify for a legit pattern per my definition. Otherwise it would be discarded from further qualifications for a trade, ie the Impedance Factor, which is irrelevant to the current discussion.

def t_min = 3;
def thrust_factor = if t < t_min then 0 else t;
def thrust_ratio = round(thrust_factor/ engulf_off,2);

addchartbubble(line_start, gulf_lo*0.999,
thrust_factor + " thrust_factor \n" +
#t + "\n" +
"out of\n" +
engulf_off + " engulfed bars\n" +
"is a ratio of\n" +
thrust_ratio + " : 1"
, (if isfirst_hi then color.green else color.red), no);


# 6. So for now, if I can determine the Thrust Factor, that part will be complete.

# 7  Your code shows the sizes of all engulfed ranges, which is good, and now only the highs and lows of those engulfed ranges need to be determined, with the bar number of the farther one back subtracted from the number of the engulfing bar to return the Thrust Factor.

# 8. It looks like the Thrust Factor of the first example on your chart with 21 total bars engulfed would be either 16 or 21, as it's hard to tell which of those two bars was higher. The second example with 7 total bars engulfed would be 6, with the high occurring on Bar 179 and the low on Bar 176 vs Bar 182 as the engulfing bar.

# 9. Both signals indicated taking Short positions.
#

ybSz0N7.jpg
 
i think this is getting closer.
look at the bubbles and see if the numbers are what you want to find.


i started with code from post7.
copied the rules from post8, to the end of the code.
numbered the rules and added code for each rule.

find large engulfing bar.
count the bars that are engulfed, all the previous bars that are smaller.
within the engulfed bars, find the highest high and lowest low. draw dots at those prices
find which one occurs first


something for you to read and think about.
i wrote out some comments/questions after rule 4, and copied them up here.

i'm not sure what the 'breakout' bar is that you want to find.

# rule 4 questions
# you will have to define what a breakout is.
# there will be a highest price and a lowest price DURING a group of engulfed bars.
# but those 2 points are within the engulfed price range. they didn't 'breakout'.
#
# there is only 1 breakout during a group of engulfed bars, on the bar after the last, big, engulfing bar.
# ( we could call the first bar, a breakin )



Ruby:
# outsidebars_02b_engulf_cln

# mod with his rules
# rework engulf , # with thrust terms
# https://usethinkscript.com/threads/finding-the-bar-number-of-the-highest-price-within-a-known-group-of-bars.12721/#post-108393
# post10  TNTrader5159
#------------------------------------

# engulfing pattern,
#  find qty of engulf bars, display in a bubble
#  draw lines to mother bar

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

input minimum_engulfed_bars = 3;
input show_engulfed_count_bubbles = yes;
input show_horizontal_engulf_lines = yes;
def lookback = 48;
#def offset = lookback;
def barup = (close > open);

# find engulfing bar
# look backwards for an engulfing bar
# count how many previous bars are smaller than the current bar
#def lookback = 48;
def bigbarcnt1 = fold k = 1 to lookback
  with p
  while (high >= getvalue(high, k) and low <= getvalue(low, k))
  do p + 1;

# disable engulfing bars with too few smaller bars
def bigbarcnt2 = if bigbarcnt1 >= minimum_engulfed_bars then bigbarcnt1 else 0;

# is the next future engulf bar, engulfing the current engulf bar?
# if yes , then disable current engulf bar
def bigbar_off2 = fold m = 1 to lookback
  with q = 1
  while getvalue(bigbarcnt2, -m) == 0
  do q + 1;

def bigbarcnt3;
if isnan( getvalue(high, -bigbar_off2) ) then {
  bigbarcnt3 = bigbarcnt2;
} else if (getvalue(high, -bigbar_off2) > high and getvalue(low, -bigbar_off2) < low) then {
  bigbarcnt3 = 0;
} else {
  bigbarcnt3 = bigbarcnt2;
}

def outbar = if (bigbarcnt3 >= minimum_engulfed_bars) then 1 else 0;

# bubble with qty of engulfed bars
addchartbubble(show_engulfed_count_bubbles and outbar,(low * 0.999), bigbarcnt3, if bigbarcnt3 == 0 then color.dark_gray else if barup then color.green else color.red, no);

# look ahead to find qty of bars to next mother bar
def engulf_off = fold n = 0 to lookback
  with r
  while getvalue(bigbarcnt3, -n) == 0
  do r + 1;

def gulf_hi = if (show_horizontal_engulf_lines and getvalue(bigbarcnt3, -engulf_off) >= engulf_off) then getvalue(high, -engulf_off) else na;
def gulf_lo = if (show_horizontal_engulf_lines and getvalue(bigbarcnt3, -engulf_off) >= engulf_off) then getvalue(low, -engulf_off) else na;
plot zhi = gulf_hi;
plot zlo = gulf_lo;
zhi.SetDefaultColor(Color.cyan);
zhi.hidebubble();
zlo.SetDefaultColor(Color.cyan);
zlo.hidebubble();


def engulf_first = bn - bigbarcnt3;
input test_show_first_last_bns = yes;
addchartbubble(test_show_first_last_bns and outbar,(low * 0.999),
 bn + " this bn\n" +
 engulf_first + " first bn\n"
, color.gray, no);


# find the first bar in an engulfed line, which is the same as the engulfed group
def line_start = if (isnan(gulf_hi[1]) and !isnan(gulf_hi)) then 1 else 0;
def start_bn = if line_start then bn else start_bn[1];


input test_show_first_bn = yes;
addchartbubble(test_show_first_bn and line_start, gulf_hi,
start_bn + "  start bn\n" +
engulf_off + "  engulfed bars"
, color.yellow, yes);


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

input test1 = no;
addchartbubble(test1 , high,
engulf_off + "\n" +
line_start + "\n" +
start_bn
, (if line_start then color.yellow else color.gray), yes);

input test2 = no;
addchartbubble(test2, (low * 0.999),
 bigbarcnt1 + "  1\n" +
 bigbarcnt2 + "  2\n" +
 bigbar_off2 + "  off2\n" +
 bigbarcnt3 + "  3\n"
# engulf_off
, color.cyan, no);


#input test_bubbles1 = no;
def test_bubbles1 = 0;
addchartbubble((test_bubbles1 and bigbarcnt1 > 0),(low * 0.999), bigbarcnt1 + " 1", if bigbarcnt1 == 0 then color.dark_gray else if barup then color.green else color.red, no);

addchartbubble((test_bubbles1 and bigbarcnt2 >= minimum_engulfed_bars),(low * 0.999), bigbarcnt2 + " 2", if bigbarcnt2 == 0 then color.dark_gray else if barup then color.green else color.red, no);

addchartbubble((test_bubbles1 and bigbarcnt3 >= minimum_engulfed_bars),(low * 0.999), bigbarcnt3 + " 3", if bigbarcnt3 == 0 then color.dark_gray else if barup then color.green else color.red, no);
#




#------------------------------------
#------------------------------------
# mod with his rules in post#10
# rework engulf ,  with thrust terms
# https://usethinkscript.com/threads/finding-the-bar-number-of-the-highest-price-within-a-known-group-of-bars.12721/#post-108393
# post10  TNTrader5159
#------------------------------------
#------------------------------------

# make new vars, labels

# 1.  Yes, first to see HOW MANY bars the current bar may engulf.
# recent engulf quantity
def engulf_bars = if outbar then bigbarcnt3 else engulf_bars[1];
addlabel(1, "recent engulf bars, quantity " + engulf_bars, color.yellow);


# 2.  Then to find the relative positions of the highest and lowest prices within the engulfed range.

#  loop , from  line_start to outbar
#   loop ,   0 to engulf_off  ( the qty of engulded bars )

def engulfed_hi;
def engulfed_lo;
def engulfed_hibn;
def engulfed_lobn;
def xbn;
if line_start then {
  xbn = bn;
#  start at the 1st bar of an engulfed period,
#  look at future bars for the highest price
  engulfed_hi = fold g1 = 0 to (engulf_off-0)
  with g2
  while !isnan(gulf_hi)
  do (if getvalue(high, -g1) > g2 then getvalue(high, -g1) else g2);

#  look at future bars for the lowest price
  engulfed_lo = fold h1 = 0 to (engulf_off-0)
  with h2 = 99999
  while !isnan(gulf_hi)
  do (if getvalue(low, -h1) < h2 then getvalue(low, -h1) else h2);


# look for the highest and lowest price , and read the bn
  engulfed_hibn = fold g3 = 0 to (engulf_off - 0)
  with g4
  while !isnan(gulf_hi)
  do (if engulfed_hi == getvalue(high, -g3) then (bn + g3) else g4);

  engulfed_lobn = fold h3 = 0 to (engulf_off-0)
  with h4
  while !isnan(gulf_hi)
  do (if engulfed_lo == getvalue(low, -h3) then (bn + h3) else h4);

} else {
  engulfed_hi = engulfed_hi[1];
  engulfed_lo = engulfed_lo[1];
  engulfed_hibn = engulfed_hibn[1];
  engulfed_lobn = engulfed_lobn[1];
  xbn = xbn[1];
}


# plot points on highest and lowest prices, that are engulfed
input show_points_onhighest_lowest_in_engulfed_group = yes;
plot zenhi = if show_points_onhighest_lowest_in_engulfed_group and bn == engulfed_hibn then high else na;
 zenhi.SetPaintingStrategy(PaintingStrategy.POINTS);
 zenhi.SetDefaultColor(Color.white);
 zenhi.setlineweight(2);
 zenhi.hidebubble();

plot zenlo = if show_points_onhighest_lowest_in_engulfed_group and bn == engulfed_lobn then low else na;
#plot zenlo = if bn == xbn then low else na;
 zenlo.SetPaintingStrategy(PaintingStrategy.POINTS);
 zenlo.SetDefaultColor(Color.white);
 zenlo.setlineweight(2);
 zenlo.hidebubble();


input test_hi_lo_bns = yes;
addchartbubble(test_hi_lo_bns and line_start, gulf_lo*0.999,
"hi $" + engulfed_hi + " at bn: " + engulfed_hibn + "\n" +
"lo $" + engulfed_lo + " at bn: " + engulfed_lobn
, color.yellow, no);


# 3. Then to take the farther one back or lower bar number of those two prices, and subtract it from the current bar number.

def engulf_minbn = min( engulfed_hibn, engulfed_lobn);
def t = if line_start then ((bn + engulf_off) - engulf_minbn) else t[1];

# offset from first engulfed bar , to the first low/hi
def t_start_off  = engulf_minbn - bn;



# 4. This returns the final value I call the Thrust Factor.
# The Thrust Factor measures the strength of the pattern once a breakout to either the upside or downside of the engulfed range occurs in real time.
# And of course which occurs first is the key to trade direction. That's another matter though.


# is the offset t pointing to the highest price in the group?
def isfirst_hi = if getvalue(high, -t_start_off) == engulfed_hi then 1 else 0;

# show a green or red bubble, on the first bar of engulfed group, that lists which comes first, a low or a high.
addchartbubble(line_start, gulf_lo*0.999,
getvalue(high, -t_start_off) + " t hi\n" +
#engulfed_hi + " ehi\n" +
(if isfirst_hi then "High" else "Low") + "  is first"
, (if isfirst_hi then color.green else color.red), no);



# rule 4 questions
# you will have to define what a breakout is.
# there will be a highest price and a lowest price DURING a group of engulfed bars.
# but thos 2 points are within the engulfed price range. they didn't 'breakout'.

# there is only 1 breakout during a group of engulfed bars, on the bar after the last, big, engulfing bar.
# ( we could call the first bar, a breakin )





# 5. The Thrust Factor must be a minimum of 3 to qualify for a legit pattern per my definition. Otherwise it would be discarded from further qualifications for a trade, ie the Impedance Factor, which is irrelevant to the current discussion.

def t_min = 3;
def thrust_factor = if t < t_min then 0 else t;
def thrust_ratio = round(thrust_factor/ engulf_off,2);

addchartbubble(line_start, gulf_lo*0.999,
thrust_factor + " thrust_factor \n" +
#t + "\n" +
"out of\n" +
engulf_off + " engulfed bars\n" +
"is a ratio of\n" +
thrust_ratio + " : 1"
, (if isfirst_hi then color.green else color.red), no);


# 6. So for now, if I can determine the Thrust Factor, that part will be complete.

# 7  Your code shows the sizes of all engulfed ranges, which is good, and now only the highs and lows of those engulfed ranges need to be determined, with the bar number of the farther one back subtracted from the number of the engulfing bar to return the Thrust Factor.

# 8. It looks like the Thrust Factor of the first example on your chart with 21 total bars engulfed would be either 16 or 21, as it's hard to tell which of those two bars was higher. The second example with 7 total bars engulfed would be 6, with the high occurring on Bar 179 and the low on Bar 176 vs Bar 182 as the engulfing bar.

# 9. Both signals indicated taking Short positions.
#

ybSz0N7.jpg
Wow! Awesome. Really all that's needed for actual monitoring and trading is to show whether or not the current bar is an engulfing bar and to issue a preliminary signal when it becomes so and all parameters are returned. This as shown is good for historical testing, though it will be most accurate when applied to a 1-minute bar chart for ANY time-frame desired.
<p>
I believe we can achieve high accuracy in determining whether the high or low of a range is eclipsed LAST to determine the direction of the trade signal. This is mission critical, though there is to my knowledge no time stamp on highs and lows callable to determine order of occurrence in ThinkScript.
<p>
If a market breaks ABOVE a range of bars FIRST (the fake) then breaks BELOW it on the same bar (the break), you have a SHORT signal. A LONG signal is generated when a market breaks BELOW the range FIRST then ABOVE it. Of course the minimum range for a signal is 3, and then the highest or lowest bar of that or any range must occur at least 3 bars back to yield a Thrust Factor of 3 or greater.
<p>
Once this is all down pat, the same ratio should be applied for any 2 bars engulfing at least 6, 3 bars engulfing at least 9, 4 engulfing at least 12 etc, etc on up to whatever number of 1-minute bars (or timeframe) desired to capture bigger moves. This frees us from depending upon bars that are fixed on the clock and makes for many more and more accurate trade signals. A lot can happen within say a 30-minute bar that will not show on a standard chart or reflect with standard indicators. And in real-time trading using bar-based indicators, we are handicapped by the current bar being immature and skewing our signals. On a 30-minute chart, you only have a true representation once every 30 minutes that lasts literally one tick.
<p>
The bottom line of this whole methodology is to seek a TIME RATIO of at least 3:1 with the same means as outlined for 1 bar engulfing at least 3. This makes entry points and profit objectives more adaptive to market conditions and not rigid rules that are far less accurate in determining good trades.
<p>
The occasional loss can almost always be more than recouped by taking the opposite position in the absence of prohibitive Impedance that would tell you to stay in the trade.
<p>
Impedance is the second of the two parts of this system. We can delve into how to calculate it once this pattern is established to determine Thrust Factors for trades. Thrust factors can also be dynamically updated with favorable market movement, but we can cover that later.
<p>
Thanks guys!
 
Wow! Awesome. Really all that's needed for actual monitoring and trading is to show whether or not the current bar is an engulfing bar and to issue a preliminary signal when it becomes so and all parameters are returned. This as shown is good for historical testing, though it will be most accurate when applied to a 1-minute bar chart for ANY time-frame desired.
<p>
I believe we can achieve high accuracy in determining whether the high or low of a range is eclipsed LAST to determine the direction of the trade signal. This is mission critical, though there is to my knowledge no time stamp on highs and lows callable to determine order of occurrence in ThinkScript.
<p>
If a market breaks ABOVE a range of bars FIRST (the fake) then breaks BELOW it on the same bar (the break), you have a SHORT signal. A LONG signal is generated when a market breaks BELOW the range FIRST then ABOVE it. Of course the minimum range for a signal is 3, and then the highest or lowest bar of that or any range must occur at least 3 bars back to yield a Thrust Factor of 3 or greater.
<p>
Once this is all down pat, the same ratio should be applied for any 2 bars engulfing at least 6, 3 bars engulfing at least 9, 4 engulfing at least 12 etc, etc on up to whatever number of 1-minute bars (or timeframe) desired to capture bigger moves. This frees us from depending upon bars that are fixed on the clock and makes for many more and more accurate trade signals. A lot can happen within say a 30-minute bar that will not show on a standard chart or reflect with standard indicators. And in real-time trading using bar-based indicators, we are handicapped by the current bar being immature and skewing our signals. On a 30-minute chart, you only have a true representation once every 30 minutes that lasts literally one tick.
<p>
The bottom line of this whole methodology is to seek a TIME RATIO of at least 3:1 with the same means as outlined for 1 bar engulfing at least 3. This makes entry points and profit objectives more adaptive to market conditions and not rigid rules that are far less accurate in determining good trades.
<p>
The occasional loss can almost always be more than recouped by taking the opposite position in the absence of prohibitive Impedance that would tell you to stay in the trade.
<p>
Impedance is the second of the two parts of this system. We can delve into how to calculate it once this pattern is established to determine Thrust Factors for trades. Thrust factors can also be dynamically updated with favorable market movement, but we can cover that later.
<p>
Thanks guys!
PS: You don't actually need the ratio of the Thrust Factor to the total bars engulfed. Just the Thrust Factor is sufficient. Sometimes they are one and the same, but it's the same Thrust Factor either way. Thanks.
 
This is a part of my Impedance Factor measuring support or resistance via Peaks, Valleys, and Congestion Zones. The formula for determining congestion zone strength is as follows:

<p>
At a given price, take the first bar back containing that price as 1. Any series of bars containing that price, broken or unbroken, would qualify as a Congestion Zone. Four additional bars behind the most recent occurrence, however far back that is, would make for 5 in a row or a strength of 5. If 2 bars are skipped before another one is reached, then you have 6 out of 8. The formula for determination of a broken or unbroken series is (Actual Matches / Total Bars) * Actual Matches. Six out of eight (6/8) would be .75 * 6 or a score of 4.5. It's a measure of density, and the chart can be scanned back however many bars desired to find a density ratio greater than the Thrust Factor of the pattern itself. Any move reaching a Congestion Zone greater than the Thrust Factor of the pattern that launched it would be exited MIT at that level.
<p>
This is part of an ongoing discussion that follows determination of the Thrust Factor of a completed pattern. It is used to help determine a profit objective or occasionally a Stop Loss point.
<p>
 
There are two kinds of peaks that act as Impedance, the generic name I give to support and resistance as a factor to compare with the Thrust Factor of a pattern that launched a move. They are:
<p>
1. Primary Peaks/Valleys that are untouched valleys for support and peaks for resistance
2. Secondary Peaks/Valleys that have been TOTALLY eclipsed by a number of bars greater than the number of the lesser side of the Peak or Valley. This number is divided by 2.
<p>
Bars straddling any peak or valley are not counted.
<p>
Peaks and Valleys (primary and secondary) are measured by the lesser sides in both height and number of bars. The height is compared to the height of the pattern as measured by engulfed bars plus the height of the difference in that and the high or low of the trigger bar, and the number of bars is compared to the Thrust Factor. These are compared as ratios and given equal weight in determining a final comparison to see if it will stop a favorable move 89% of the way to it (or any % chosen) or act as a Stop Loss.
<p>
I will post links to illustrations soon. Please feel free to ask any questions. THANKS for any help on coding this and my other formula for Congestion Zones to complete the Impedance Factor!
 

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
380 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