Bpa
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © yohtza

//@version=5

// @description library of Brooks Price Action concepts
library("Bpa", overlay=true)

// @function check if the bar is a breakout based on the specified conditions
// @param atr atr value
// @param high high price
// @param low low price
// @param close close price 
// @param open open price
// @param tail decimal value for a percent that represent the size of the tail of the bar that cant be preceeded to be considered strong close
// @param size decimal value for a percent that represents by how much the breakout bar should be bigger than others to be considered one
// @returns boolean value, true if breakout bar, false otherwise
export isBreakoutBar(float atr, float high, float low, float close, float open, float tail, float size) =>
	open < close ? ((high - close) / (high - low)) < tail and (high - low) > size * atr : open > close ? ((close - low) / (high - low)) < tail and (high - low) > size * atr : false

// @function check if bull microchannel
// @returns boolean value, true if microchannel bar, false otherwise
export bullMicrochannel() =>
	low > low[1] and low[1] > low[2]

// @function check if bear microchannel
// @returns boolean value, true if microchannel, false otherwise
export bearMicrochannel() =>
	high < high[1] and high[1] < high[2]

//@function check if the bar has a strong close based on the length of tail
// @param tail decimal value representing the length of the tail
// @returns boolean, true if strong close, false otherwise
export isStrongClose(float tail) =>
	open < close ? ((high - close) / (high - low)) < tail : open > close ? ((close - low) / (high - low)) < tail : false

// @function check if the bar is a breakout based on the specified conditions
// @param atr atr value
// @param tail decimal value for a percent that represent the size of the tail of the bar that cant be preceeded to be considered strong close
// @param size decimal value for a percent that represents by how much the breakout bar should be bigger than others to be considered one
// @returns boolean value, true if breakout bar, false otherwise
export isBreakoutBar2(float atr, float tail, float size) =>
	open < close ? ((high - close) / (high - low)) < tail and (high - low) > size * atr : open > close ? ((close - low) / (high - low)) < tail and (high - low) > size * atr : false

// @function check if the bar is breaking out above a specified number of previous bars
// @param lookback number of previous bars to lookback
// @returns boolean value
export breakoutAbove(int lookback) =>
	highestClose = ta.highest(close, lookback)
    highestHigh = ta.highest(high, lookback)
    close > highestHigh[1] and close == highestClose

// @function check if the bar is breaking below a specified number of previous bars
// @param lookback number of previous bars to lookback
// @returns boolean value
export breakoutBelow(int lookback) =>
	lowestClose = ta.lowest(close, lookback)
    lowestLow = ta.lowest(low, lookback)
    close < lowestLow[1] and close == lowestClose

// @function check if there's followthrough after a breakout
// @param atr value for breakout bar
// @param tail decimal value for a percent that represent the size of the tail of the bar that cant be preceeded to be considered strong close
// @param size decimal value for a percent that represents by how much the breakout bar should be bigger than others to be considered one
// @returns boolean value
export breakoutFollowthrough(float atr, float tail, float size) =>
	open[1] < close[1] ? ((high[1] - close[1]) / (high[1] - low[1])) < tail and (high[1] - low[1]) > size * atr and open < close : open[1] > close[1] ? ((close[1] - low[1]) / (high[1] - low[1])) < tail and (high[1] - low[1]) > size * atr and open > close : false

// @function check for minimal followthrough needed after breakout
// @returns boolean 
export minFollowthrough() =>
	open[1] < close[1] ? open < close : open[1] > close[1] ? open > close : false 

// @function check if the bar is a trend bar
// @returns boolean 
export isTrendBar()=> math.abs(open-close) / (high - low) > 0.5

// @function check if the bar is a doji bar
// @returns boolean 
export isDoji() => math.abs(open-close) / (high - low) < 0.5

// @function check if the bar is a bull trend bar
// @returns boolean 
export isBullTrendBar()=> math.abs(open-close) / (high - low) > 0.5 and open < close

// @function check if the bar is a bear trend bar
// @returns boolean 
export isBearTrendBar()=> math.abs(open-close) / (high - low) > 0.5 and open > close