Repaints Al Brooks Price Action Indicators For ThinkOrSwim

Repaints

Jaaackjack

New member
Al Brooks / Brooks Price Action Indicators I Found Interesting and Useful

I wanted to share some interesting indicators I've either come across through a lot of searching, or indicators I've modified or created. I personally am not a huge fan of most indicators and I found all of these price action based indicators to be particularly interesting to say the least and I wanted to make it easier for someone to find them.

In the following posts, I credit the user that created the indicator if the creator was known.

The post links have a summary of how each indicator works and the entire code.

The most interesting and possibly useful indicators are the Brooks Price Action (BPA for short) Buy and Sell Set Up indicators, and there are several.

BPA Set Ups
https://usethinkscript.com/threads/al-brooks-style-h1-h2-or-l1-l2-indicator.14037/#post-130003
This plots High 1, High 2, High 3, High 4, etc. and Low 1, Low 2, Low 3, Low 4, etc. set ups on whatever timeframe chart you are using. They are essentially bull flags and bear flags but more nuanced - this indicator specifically looks for a move up or down, and then marks the first bar to break the prior bar's high (or low) which would be a High 1 Buy Set Up or a Low 1 Sell Set Up, as defined by Al Brooks.

But it isn't perfect and it does not accurately number the set ups (for example, if you use the numerical setting, it will not always reset the count as it should be reset after new BO's, and it fails in tight trading ranges) and it does not plot every instance of a buy set up or sell set up occurring, and it marks inside bar set ups (which I am not sure qualify as a text book definition of a buy or sell set up) but it does a very good job overall and it's very interesting. I personally think using Boolean arrows is more helpful and then it's up to the trader to decide what the count is, what the trend is, and whether or not its a good signal. Boolean arrows are the default setting on all of the BPA indicators for this reason.

BPA Above or Below the Open of the Day (shown in pic)
https://usethinkscript.com/threads/...indicators-for-thinkorswim.17208/#post-134318
I wanted to see what would happen if I only saw sell set ups when price was below the open of the day, and buy set ups when price was above the open of the day. It's very interesting, not fool proof, but it is very interesting to say the least. You wouldn't want to use this on a trading range day, but definitely powerful for trend days. You cannot adjust the aggregate period (I tried to incorporate that setting but failed) so it's just above or below the open of the current day.

BPA Above or Below the EMA (with Higher Time Frames)
https://usethinkscript.com/threads/...indicators-for-thinkorswim.17208/#post-134319
This is another modified BPA indicator that only shows buy set ups when price is above the EMA, and sell set ups when price is below the EMA. You can adjust the length and aggregate period of the EMA so you can use any EMA from any time frame. It also plots the EMA on the chart.

Bar Count (shown in pic)
https://usethinkscript.com/threads/...indicators-for-thinkorswim.17208/#post-134320
This plots the bar number on the 5-minute chart but it only plots every 3rd number in white (15-min chart reference) and then it colors every 12th bar cyan (60-minute chart reference).

Current Bar Size
https://usethinkscript.com/threads/...indicators-for-thinkorswim.17208/#post-134321
Just tells you the current bar's size in points (high - low), useful for quickly calculating risk.

Higher Timeframe EMA (shown in Pic)
https://usethinkscript.com/threads/...indicators-for-thinkorswim.17208/#post-134322
This allows you to plot a higher time frame EMA on a lower time frame chart, like the hourly ema on the 5-min chart for example.

Prior Bar Size
https://usethinkscript.com/threads/...indicators-for-thinkorswim.17208/#post-134323
This just tells you the size of the prior bar in points (high - low), useful for quickly calculating risk.

Prior OHLC
https://usethinkscript.com/threads/...indicators-for-thinkorswim.17208/#post-134324
This plots the prior Open, High, Low, and Close on your chart, aggregate period is set to Day by default, but adjustable to any timeframe you choose, like weekly, monthly, quarterly, and yearly, etc.

Swing or Scalp
VIP https://usethinkscript.com/threads/...-directional-options.15954/page-9#post-134236
This tells you how far price has moved so far today, like if it's nearing an average day's range or if it's above or below the average day's range of price movement. It's just an ATR based indicator, I believe the ATR is based on Days and then you can select the lookback period (ATR period) to compare with Today's range. Created by user khpro, I modified the labels to tell me literally if it's more likely to get a swing or scalp out of the market at any given time during the day.

ZigZag Leg Counter
https://usethinkscript.com/threads/...indicators-for-thinkorswim.17208/#post-134325
Never really used this one but it does an excellent job of plotting legs of the trend from top to bottom of the chart. Helpful for visualizing legs on the chart. As price action traders, Leg 1 and Leg 2 are the highest probability set up that we have out of all possible set ups.


thinkorswim_ge0v8zEMyb.png
 
Last edited:
BPA Above or Below the Open of the Day
Ruby:
#"BPA Above-Below Open of Day"
#Modified BPA indicator showing buy set ups when above the opening price of the day and sell set ups when below the open of the day.


# DESCRIPTION
# This study plots H1, H2, etc. and L1, L2, etc. labels above or below
# those signal bars based on Al Brooks' description of the setups.

# DECLARATIONS
declare upper;

# USER INPUTS
input resetCountOnDTorDB = yes;
input barsBack = 10;

# DEFINITIONS AND CALCULATIONS
## Variable List
def isFlatTopSBEligible;
def isBullSB;
def lastBullSBLow;
def isHBar;
def lastHBarLow;
def isPushUp;
def lastPushUp;
def resetHCount;
def isHCountStillReset;
def hCount;

def isFlatBottomSBEligible;
def isBearSB;
def lastBearSBHigh;
def isLBar;
def lastLBarHigh;
def isPushDown;
def lastPushDown;
def resetLCount;
def isLCountStillReset;
def lCount;

## Standard variable calculations
### H Counting
isFlatTopSBEligible =
    fold hFold = 1 to barsBack
    with dt = Double.NaN
    while IsNaN(dt)
    do
    if GetValue(high, hFold) == high then
        Double.NaN
    else if GetValue(high, hFold) > high then
        yes
    else
        no;

isBullSB = (high[1] > high and high[-1] > high)                                 #Standard bull SB
            or (isFlatTopSBEligible and high[-1] > high);                       #DT to the left

lastBullSBLow = if isBullSB then low else lastBullSBLow[1];

isHBar = (low < lastBullSBLow[1] and isBullSB) or (isBullSB and isHCountStillReset);

lastHBarLow = CompoundValue(1, if isHBar then low else lastHBarLow[1], low);

isPushUp = if isHBar then yes else if isPushUp[1] and high >= high[1] then yes else no;

lastPushUp = if isPushUp[1] and !isPushUp then high[1]
             else if high > lastPushUp[1] then high
             else lastPushUp[1];

resetHCount = high > lastPushUp[1]
              or ( resetCountOnDTorDB and high == lastPushUp[1] );

isHCountStillReset = if !isBullSB and resetHCount then yes else isHCountStillReset[1];

hCount = CompoundValue(1,
         if isHBar and !resetHCount then hCount[1] + 1
         else if resetHCount then 0
         else hCount[1]
         , 0);

### L Counting
isFlatBottomSBEligible =
    fold lFold = 1 to barsBack
    with db = Double.NaN
    while IsNaN(db)
    do
    if GetValue(low, lFold) == low then
        Double.NaN
    else if GetValue(low, lFold) < low then
        yes
    else
        no;

isBearSB = (low[1] < low and low[-1] < low)                                 #Standard bear SB
            or (isFlatBottomSBEligible and low[-1] < low);                        #Db to the left

lastBearSBHigh = if isBearSB then high else lastBearSBHigh[1];

isLBar = (high > lastBearSBHigh[1] and isBearSB) or (isBearSB and isLCountStillReset);

lastLBarHigh = CompoundValue(1, if isLBar then high else lastLBarHigh[1], high);

isPushDown = if isLBar then yes else if isPushDown[1] and low <= low[1] then yes else no;

lastPushDown = if isPushDown[1] and !isPushDown then low[1]
             else if low < lastPushDown[1] then low
             else lastPushDown[1];

resetLCount = low < lastPushDown[1]
              or ( resetCountOnDTorDB and low == lastPushDown[1] );

isLCountStillReset = if !isBearSB and resetLCount then yes else isLCountStillReset[1];

lCount = CompoundValue(1,
         if isLBar and !resetLCount then lCount[1] + 1
         else if resetLCount then 0
         else lCount[1]
         , 0);

# Calculate the day's opening price
def openPrice = if GetDay() != GetDay()[1] then open else openPrice[1];

# PLOTS
plot hSetup = if hCount <> hCount[1] and hCount <> 0 and close > openPrice then hCount else Double.NaN;
plot lSetup = if lCount <> lCount[1] and lCount <> 0 and close < openPrice then lCount else Double.NaN;

# GLOBAL COLOR DEFINITIONS
DefineGlobalColor("Blue" , CreateColor(33, 150, 243));
DefineGlobalColor("Green", CreateColor(0, 155, 0));
DefineGlobalColor("Red", CreateColor(225, 105, 105));
DefineGlobalColor("Gray", CreateColor(181, 181, 181));
DefineGlobalColor("White", CreateColor(255, 255, 255));

# FORMATTING
hSetup.SetPaintingStrategy(PaintingStrategy.VALUES_BELOW);
hSetup.SetDefaultColor(GlobalColor("Green"));
hSetup.SetLineWeight(2);
hSetup.HideBubble();

lSetup.SetPaintingStrategy(PaintingStrategy.VALUES_ABOVE);
lSetup.SetDefaultColor(GlobalColor("Red"));
lSetup.SetLineWeight(2);
lSetup.HideBubble();

I wanted to see what would happen if I only saw sell set ups when price was below the open of the day, and buy set ups when price was above the open of the day. It's very interesting, not fool proof, but it is very interesting to say the least. You wouldn't want to use this on a trading range day, but definitely powerful for trend days. You cannot adjust the aggregate period (I tried to incorporate that setting but failed) so it's just above or below the open of the current day.
 
Last edited by a moderator:
BPA Above or Below the EMA (with Higher Time Frames)
Ruby:
#BPA Above-Below EMA (w/HTF)
#This modified BPA indicator only shows buy set ups when price is above the EMA and only shows sell set ups when price is below the EMA. 
#The EMA can be customized to different lengths, and it can be an EMA from a Higher Timeframe.
#The EMA is plotted on the chart in addition to the signals.


# DESCRIPTION
# This study plots H1, H2, etc. and L1, L2, etc. labels above or below
# those signal bars based on Al Brooks' description of the setups.

# DECLARATIONS
declare upper;

# USER INPUTS
input resetCountOnDTorDB = yes;
input barsBack = 10;
input emaLength = 20;
input emaType = {default Simple, Exponential, Wilders};
input aggregatePeriod = AggregationPeriod.DAY;  # Select the desired aggregate period

# EMA Calculation
def emaValue;
switch (emaType) {
    case Simple:
        emaValue = ExpAverage(close(period = aggregatePeriod), emaLength);
    case Exponential:
        emaValue = ExpAverage(close(period = aggregatePeriod), emaLength);
    case Wilders:
        emaValue = WildersAverage(close(period = aggregatePeriod), emaLength);
}

# DEFINITIONS AND CALCULATIONS
## Variable List
def isFlatTopSBEligible;
def isBullSB;
def lastBullSBLow;
def isHBar;
def lastHBarLow;
def isPushUp;
def lastPushUp;
def resetHCount;
def isHCountStillReset;
def hCount;

def isFlatBottomSBEligible;
def isBearSB;
def lastBearSBHigh;
def isLBar;
def lastLBarHigh;
def isPushDown;
def lastPushDown;
def resetLCount;
def isLCountStillReset;
def lCount;

## Standard variable calculations
### H Counting
isFlatTopSBEligible =
    fold hFold = 1 to barsBack
    with dt = Double.NaN
    while IsNaN(dt)
    do
    if GetValue(high, hFold) == high then
        Double.NaN
    else if GetValue(high, hFold) > high then
        yes
    else
        no;

isBullSB = (high[1] > high and high[-1] > high)                                 #Standard bull SB
            or (isFlatTopSBEligible and high[-1] > high);                       #DT to the left

lastBullSBLow = if isBullSB then low else lastBullSBLow[1];

isHBar = (low < lastBullSBLow[1] and isBullSB) or (isBullSB and isHCountStillReset);

lastHBarLow = CompoundValue(1, if isHBar then low else lastHBarLow[1], low);

isPushUp = if isHBar then yes else if isPushUp[1] and high >= high[1] then yes else no;

lastPushUp = if isPushUp[1] and !isPushUp then high[1]
             else if high > lastPushUp[1] then high
             else lastPushUp[1];

resetHCount = high > lastPushUp[1]
              or ( resetCountOnDTorDB and high == lastPushUp[1] );

isHCountStillReset = if !isBullSB and resetHCount then yes else isHCountStillReset[1];

hCount = CompoundValue(1,
         if isHBar and !resetHCount then hCount[1] + 1
         else if resetHCount then 0
         else hCount[1]
         , 0);

### L Counting
isFlatBottomSBEligible =
    fold lFold = 1 to barsBack
    with db = Double.NaN
    while IsNaN(db)
    do
    if GetValue(low, lFold) == low then
        Double.NaN
    else if GetValue(low, lFold) < low then
        yes
    else
        no;

isBearSB = (low[1] < low and low[-1] < low)                                 #Standard bear SB
            or (isFlatBottomSBEligible and low[-1] < low);                        #Db to the left

lastBearSBHigh = if isBearSB then high else lastBearSBHigh[1];

isLBar = (high > lastBearSBHigh[1] and isBearSB) or (isBearSB and isLCountStillReset);

lastLBarHigh = CompoundValue(1, if isLBar then high else lastLBarHigh[1], high);

isPushDown = if isLBar then yes else if isPushDown[1] and low <= low[1] then yes else no;

lastPushDown = if isPushDown[1] and !isPushDown then low[1]
             else if low < lastPushDown[1] then low
             else lastPushDown[1];

resetLCount = low < lastPushDown[1]
              or ( resetCountOnDTorDB and low == lastPushDown[1] );

isLCountStillReset = if !isBearSB and resetLCount then yes else isLCountStillReset[1];

lCount = CompoundValue(1,
         if isLBar and !resetLCount then lCount[1] + 1
         else if resetLCount then 0
         else lCount[1]
         , 0);

# Price Above/Below EMA
def priceAboveEMA = close > emaValue;
def priceBelowEMA = close < emaValue;

# PLOTS
plot hSetup = if hCount <> hCount[1] and hCount <> 0 and priceAboveEMA then hCount else Double.NaN;
plot lSetup = if lCount <> lCount[1] and lCount <> 0 and priceBelowEMA then lCount else Double.NaN;

# Plot the EMA
plot emaPlot = emaValue;
emaPlot.AssignValueColor(Color.cyan);  # Adjust the color here
emaPlot.SetStyle(Curve.FIRM);  # Adjust the style here

# GLOBAL COLOR DEFINITIONS
DefineGlobalColor("Blue", CreateColor(33, 150, 243));
DefineGlobalColor("Green", CreateColor(0, 155, 0));
DefineGlobalColor("Red", CreateColor(225, 105, 105));
DefineGlobalColor("Gray", CreateColor(181, 181, 181));
DefineGlobalColor("White", CreateColor(255, 255, 255));

# FORMATTING
hSetup.SetPaintingStrategy(PaintingStrategy.VALUES_BELOW);
hSetup.SetDefaultColor(GlobalColor("Green"));
hSetup.SetLineWeight(2);
hSetup.HideBubble();

lSetup.SetPaintingStrategy(PaintingStrategy.VALUES_ABOVE);
lSetup.SetDefaultColor(GlobalColor("Red"));
lSetup.SetLineWeight(2);
lSetup.HideBubble();

This is another modified BPA indicator that only shows buy set ups when price is above the EMA, and sell set ups when price is below the EMA. You can adjust the length and aggregate period of the EMA so you can use any EMA from any time frame. It also plots the EMA on the chart.
 
Last edited by a moderator:
Bar Count
Ruby:
#Bar Count (Based on 5-min Chart)

#This shows you the number of bars on the chart but only shows every 3rd number (correlating to the 15-min chart) and every 6th bar is cyan (correlating to the hourly chart)


# plot bar number using seconds since open at 0930 EST
def barNum = 1 + (secondsFromTime(0930) / 300);

# Plot only specific numbers and set color
plot filteredBarNumCyan = if barNum == 12 or barNum == 24 or barNum == 36 or barNum == 48 or barNum == 60 or  barNum == 72 then barNum else Double.NaN;
filteredBarNumCyan.SetPaintingStrategy(PaintingStrategy.VALUES_BELOW);
filteredBarNumCyan.SetDefaultColor(Color.CYAN);

plot filteredBarNumWhite = if barNum == 3 or barNum == 6 or barNum == 9 or barNum == 15 or barNum == 18 or barNum == 21 or barNum == 27 or barNum == 30 or barNum == 33 or barNum == 39 or barNum == 42 or barNum == 45 or barNum == 51 or barNum == 54 or barNum == 57 or barNum == 63 or barNum == 66 or barNum == 69 or barNum == 75 or barNum == 78 or barNum == 81 then barNum else Double.NaN;
filteredBarNumWhite.SetPaintingStrategy(PaintingStrategy.VALUES_BELOW);
filteredBarNumWhite.SetDefaultColor(Color.WHITE);

This plots the bar number on the 5-minute chart but it only plots every 3rd number in white (15-min chart reference) and then it colors every 12th bar cyan (60-minute chart reference).
 
Last edited by a moderator:
Current Bar Size
Ruby:
#Current Bar Size
#This just tells you the current bar's size (High - Low)

declare upper;

# Calculate the range of the current bar
def currentRange = high - low;

# Round the range to the nearest penny
def roundedRange = Round(currentRange, 2);

# Print the result to the chart
AddLabel(yes, "This Bar  " + roundedRange, Color.WHITE);

Just tells you the current bar's size in points (high - low), useful for quickly calculating risk.
 
Last edited by a moderator:
Higher Timeframe EMA
Ruby:
#Higher Timeframe EMA
#This will plot the EMA from a higher timeframe on to a lower time frame chart, such as the Hourly EMA on the 5-minute chart.

input agg = AggregationPeriod.HOUR;

input length = 20;

plot EMA = ExpAverage(close(period = agg), length);


This allows you to plot a higher time frame EMA on a lower time frame chart, like the hourly ema on the 5-min chart for example.
 
Last edited by a moderator:
Prior Bar Size
Ruby:
#Prior Bar Size
#This just tells you the prior bar's High - Low, helpful for stop placement / deciding on how much to risk based on a potential signal bar size.

def rng = high - low;
addlabel(1, "Prior Bar Range: " + rng, color.white);


This just tells you the size of the prior bar in points (high - low), useful for quickly calculating risk.
 
Last edited by a moderator:
Prior OHLC
Ruby:
#Prior OHLC

#This will plot lines that show the prior Day's Open, High, Low, and Close.   You can change the aggregate period to see Week, or Month, or Quarter, or Year, etc.

# Prior Day's High, Low, Close, and Open
# This script plots lines for the prior day's high, low, close, and open on your chart.

declare upper;

input aggregationPeriod = AggregationPeriod.DAY;  # Set the aggregation period to daily
input showOnlyLastPeriod = no;

# Calculate the prior day's high, low, close, and open
def priorDayHigh = high(period = aggregationPeriod)[1];
def priorDayLow = low(period = aggregationPeriod)[1];
def priorDayClose = close(period = aggregationPeriod)[1];
def priorDayOpen = open(period = aggregationPeriod)[1];

# Plot lines for the prior day's high, low, close, and open
plot PriorDayHighLine = priorDayHigh;
PriorDayHighLine.SetDefaultColor(GetColor(1));  # Color for the high line
plot PriorDayLowLine = priorDayLow;
PriorDayLowLine.SetDefaultColor(GetColor(2));   # Color for the low line
plot PriorDayCloseLine = priorDayClose;
PriorDayCloseLine.SetDefaultColor(GetColor(3));  # Color for the close line
plot PriorDayOpenLine = priorDayOpen;
PriorDayOpenLine.SetDefaultColor(GetColor(4));   # Color for the open line

This plots the prior Open, High, Low, and Close on your chart, aggregate period is set to Day by default, but adjustable to any timeframe you choose, like weekly, monthly, quarterly, and yearly, etc.
 
Last edited by a moderator:

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

Thread starter Similar threads Forum Replies Date
congamike Screaming Price Moves For ThinkOrSwim Strategies & Chart Setups 14

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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