Move snippets and strategies folders to misc directory
This commit is contained in:
304
misc/snippets/Bull_Bear_Flag_Finder_v6
Normal file
304
misc/snippets/Bull_Bear_Flag_Finder_v6
Normal file
@@ -0,0 +1,304 @@
|
||||
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
|
||||
// © Amphibiantrading
|
||||
|
||||
//@version=6
|
||||
indicator('Flag Finder', overlay = true, max_lines_count = 500)
|
||||
|
||||
//inputs
|
||||
//user controlled settings for the indicator, separated into 4 different groups
|
||||
var g1 = 'Bull Flag Criteria'
|
||||
|
||||
max_depth = input.float(7.5, 'Max Flag Depth', step = .25, minval = .25, group = g1, tooltip = 'Maximum pullback allowed from flag high to flag low')
|
||||
max_flag = input.int(10, 'Max Flag Length', group = g1, tooltip = 'The maximum number of bars the flag can last')
|
||||
min_flag = input.int(4, 'Min Flag Length', group = g1, tooltip = 'The minimum number of bars required for the flag')
|
||||
poleMin = input.float(20.0, 'Prior Uptrend Minimum', step = .50, minval = .25, group = g1, tooltip = 'The minimum percentage gain required before a flag forms')
|
||||
poleMaxLen = input.int(15, 'Max Flag Pole Length', minval = 1, group = g1, tooltip = 'The maximum number of bars the flagpole can be')
|
||||
poleMinLen = input.int(5, 'Min Flag Pole Length', minval = 1, group = g1, tooltip = 'The minimum number of bars required for the flag pole')
|
||||
|
||||
var g2 = 'Bear Flag Criteria'
|
||||
|
||||
max_rally = input.float(10, 'Max Flag Rally', step = .25, minval = .25, group = g2, tooltip = 'Maximum rally allowed from flag low to flag low')
|
||||
max_flagBear = input.int(10, 'Max Flag Length', group = g2, tooltip = 'The maximum number of bars the flag can last')
|
||||
min_flagBear = input.int(4, 'Min Flag Length', group = g2, tooltip = 'The minimum number of bars required for the flag')
|
||||
poleMinBear = input.float(15.0, 'Prior Downtrend Minimum', step = .50, minval = .25, group = g2, tooltip = 'The minimum percentage loss required before a flag forms')
|
||||
poleMaxLenBear = input.int(15, 'Max Flag Pole Length', minval = 1, group = g2, tooltip = 'The maximum number of bars the flagpole can be')
|
||||
poleMinLenBear = input.int(3, 'Min Flag Pole Length', minval = 1, group = g2, tooltip = 'The minimum number of bars required for the flag pole')
|
||||
|
||||
var g3 = 'Bull Flag Display Options'
|
||||
|
||||
showF = input.bool(true, 'Show Bull Flags', group = g3)
|
||||
showBO = input.bool(true, 'Show Bull Flag Breakouts', group = g3)
|
||||
lineColor = input.color(color.green, 'Bull Line Color', group = g3)
|
||||
lineWidth = input.int(2, 'Bull Line Width', minval = 1, maxval = 5, group = g3)
|
||||
|
||||
var g4 = 'Bear Flag Display Options'
|
||||
|
||||
showBF = input.bool(true, 'Show Bear Flags', group = g4)
|
||||
showBD = input.bool(true, 'Show Bear Flag Breakdowns', group = g4)
|
||||
lineColorBear = input.color(color.red, 'Bear Flag Line Color', group = g4)
|
||||
lineWidthBear = input.int(2, 'Bear Flag Line Width', minval = 1, maxval = 5, group = g4)
|
||||
|
||||
//variables
|
||||
//declare starting variables used for identfying flags
|
||||
var baseHigh = high
|
||||
var startIndex = 0
|
||||
var flagLength = 0
|
||||
var baseLow = low
|
||||
var lowIndex = 0
|
||||
var flagBool = false
|
||||
var poleLow = 0.0
|
||||
var poleLowIndex = 0
|
||||
var line flagHLine = na
|
||||
var line flagLLine = na
|
||||
var line flagPLine = na
|
||||
|
||||
// bear flag variables
|
||||
var flagLowBear = high
|
||||
var startIndexBear = 0
|
||||
var flagLengthBear = 0
|
||||
var flagHigh = low
|
||||
var highIndex = 0
|
||||
var flagBoolBear = false
|
||||
var poleHigh = 0.0
|
||||
var polehighIndex = 0
|
||||
var line flagBearHLine = na
|
||||
var line flagBearLLine = na
|
||||
var line flagBearPLine = na
|
||||
|
||||
//find bull flag highs
|
||||
// check to see if the current bars price is higher than the previous base high or na and then sets the variables needed for flag detection
|
||||
if high > baseHigh or na(baseHigh)
|
||||
baseHigh := high
|
||||
startIndex := bar_index
|
||||
flagLength := 0
|
||||
baseLow := low
|
||||
lowIndex := bar_index
|
||||
lowIndex
|
||||
// check to see if the low of the current bar is lower than the base low, if it is set the base low to the low
|
||||
if high <= baseHigh and low < baseLow
|
||||
baseLow := low
|
||||
lowIndex := bar_index
|
||||
lowIndex
|
||||
// moves the base low from the base high bar_index to prevent the high and low being the same bar
|
||||
if high <= baseHigh and lowIndex == startIndex
|
||||
baseLow := low
|
||||
lowIndex := bar_index
|
||||
lowIndex
|
||||
|
||||
//find bear flag lows
|
||||
// check to see if the current bars price is lower than the previous flag low or na and then sets the variables needed for flag detection
|
||||
if low < flagLowBear or na(flagLowBear)
|
||||
flagLowBear := low
|
||||
startIndexBear := bar_index
|
||||
flagLengthBear := 0
|
||||
flagHigh := high
|
||||
highIndex := bar_index
|
||||
highIndex
|
||||
// check to see if the high of the current bar is higher than the flag high, if it is set the flag high to the high
|
||||
if low >= flagLowBear and high > flagHigh
|
||||
flagHigh := high
|
||||
highIndex := bar_index
|
||||
highIndex
|
||||
// moves the flag high from the flag low bar_index to prevent the high and low being the same bar
|
||||
if low >= flagLowBear and highIndex == startIndexBear
|
||||
flagHigh := high
|
||||
highIndex := bar_index
|
||||
highIndex
|
||||
|
||||
//calulations bullish
|
||||
findDepth = math.abs((baseLow / baseHigh - 1) * 100) //calculate the depth of the flag
|
||||
poleDepth = (baseHigh / poleLow - 1) * 100 // calculate the low of the flag pole to the base high
|
||||
lower_close = close < close[1] // defines a lower close
|
||||
|
||||
//calculations bearish
|
||||
findRally = math.abs((flagHigh / flagLowBear - 1) * 100) //calculate the rally of the flag
|
||||
poleDepthBear = (flagLowBear / poleHigh - 1) * 100 // calculate the high of the flag pole to the low high
|
||||
higher_close = close > close[1] // defines a higher close
|
||||
|
||||
//start the counters
|
||||
// begins starting bars once a high is less than the flag high
|
||||
if high < baseHigh and findDepth <= max_depth or high == baseHigh and lower_close
|
||||
flagLength := flagLength + 1
|
||||
flagLength
|
||||
else
|
||||
flagLength := 0
|
||||
flagLength
|
||||
|
||||
// begins starting bars once a low is higher than the flag low
|
||||
if low > flagLowBear and findRally <= max_rally or low == flagLowBear and higher_close
|
||||
flagLengthBear := flagLengthBear + 1
|
||||
flagLengthBear
|
||||
else
|
||||
flagLengthBear := 0
|
||||
flagLengthBear
|
||||
|
||||
// check for prior uptrend / downtrend to meet requirements
|
||||
// loops through all the bars from the minimum pole length to the maximum pole length to check if the prior uptrend requirements are met and sets the variables to their new values
|
||||
if high == baseHigh
|
||||
for i = poleMinLen to poleMaxLen by 1
|
||||
if (high / low[i] - 1) * 100 >= poleMin
|
||||
flagBool := true
|
||||
poleLow := low[i]
|
||||
poleLowIndex := bar_index[i]
|
||||
break
|
||||
|
||||
// loops through all the bars from the minimum pole length to the maximum pole length to check if the prior downtrend requirements are met and sets the variables to their new values
|
||||
if low == flagLowBear
|
||||
for i = poleMinLenBear to poleMaxLenBear by 1
|
||||
if math.abs((low / high[i] - 1) * 100) >= poleMinBear
|
||||
flagBoolBear := true
|
||||
poleHigh := high[i]
|
||||
polehighIndex := bar_index[i]
|
||||
break
|
||||
|
||||
|
||||
// reset variables if criteria for a flag is broken
|
||||
// if the depth of the bull flag is greater than the maximum depth limit or the flag lasts longer than the maximum length everything is reset to beging looking for a new flag
|
||||
if findDepth >= max_depth or flagLength > max_flag
|
||||
flagBool := false
|
||||
flagLength := 0
|
||||
baseHigh := na
|
||||
startIndex := na
|
||||
lowIndex := na
|
||||
baseLow := na
|
||||
baseLow
|
||||
|
||||
// if the rally of the bear flag is greater than the maximum rally limit or the flag lasts longer than the maximum length everything is reset to beging looking for a new flag
|
||||
if findRally >= max_rally or flagLengthBear > max_flagBear
|
||||
flagBoolBear := false
|
||||
flagLengthBear := 0
|
||||
flagLowBear := na
|
||||
startIndexBear := na
|
||||
highIndex := na
|
||||
flagHigh := na
|
||||
flagHigh
|
||||
|
||||
// reset the variables and begin looking for a new bull flag if price continues higher before the minimum flag length requirement is met
|
||||
if high > baseHigh[1] and flagLength < min_flag
|
||||
baseHigh := high
|
||||
flagLength := 0
|
||||
startIndex := bar_index
|
||||
lowIndex := bar_index
|
||||
baseLow := low
|
||||
baseLow
|
||||
|
||||
// reset the variables and begin looking for a new bear flag if price continues lower before the minimum bear flag length requirement is met
|
||||
if low < flagLowBear[1] and flagLengthBear < min_flagBear
|
||||
flagLowBear := low
|
||||
flagLengthBear := 0
|
||||
startIndexBear := bar_index
|
||||
highIndex := bar_index
|
||||
flagHigh := high
|
||||
flagHigh
|
||||
|
||||
|
||||
//define the flags
|
||||
// if all requirements are met a bull flag is true, flagBool is true, flag length is less than maximum set length and more than miminum required. The prior run up also meets the requirements for length and price
|
||||
flag = flagBool == true and flagLength < max_flag and findDepth < max_depth and flagLength >= min_flag and startIndex - poleLowIndex <= poleMaxLen
|
||||
|
||||
// if all requirements are met a bear flag is true, flagBoolBear is true, flag length is less than maximum set length and more than miminum required. The prior downtrend also meets the requirements for length and price
|
||||
bearFlag = flagBoolBear == true and flagLengthBear < max_flagBear and findRally < max_rally and flagLengthBear >= min_flagBear and startIndexBear - polehighIndex <= poleMaxLen
|
||||
|
||||
|
||||
//define flags, breakouts, breadowns
|
||||
// a breakout is defined as the high going above the flag high and the length of the flag is greater than the minimum requirement. The flag boolean must also be true
|
||||
breakout = high > baseHigh[1] and flagLength >= min_flag and flagBool == true
|
||||
//a breakdown is defined as the depth of the flag being larger than user set parameter or the length of the flag exceeded the maximum flag length
|
||||
breakdown = findDepth >= max_depth or flagLength > max_flag
|
||||
// a separate variable to have breakouts only plot once using a plotshape
|
||||
plotBO = flag[1] and high > baseHigh[1] and flagLength[1] >= min_flag and flagBool == true
|
||||
|
||||
// a bear flag breakout is defined as the low going below the flag low and the length of the flag is greater than the minimum requirement. The flag boolean must also be true
|
||||
breakoutBear = low < flagLowBear[1] and flagLengthBear >= min_flagBear and flagBoolBear == true
|
||||
//a breakdown is defined as the rally of the flag being larger than user set parameter or the length of the flag exceeded the maximum flag length
|
||||
breakdownBear = findRally >= max_rally or flagLengthBear > max_flagBear
|
||||
// a separate variable to have breakouts only plot once using a plotshape
|
||||
plotBD = bearFlag[1] and low < flagLowBear[1] and flagLengthBear[1] >= min_flagBear and flagBoolBear == true
|
||||
|
||||
// if a bul flag is detected and the user has bull flags selected from the settings menu draw it on the chart
|
||||
if flag and showF
|
||||
//if a flag was detected on the previous bar, delete those lines and allow for new lines to be drawn
|
||||
if flag[1]
|
||||
line.delete(flagHLine[1])
|
||||
line.delete(flagLLine[1])
|
||||
line.delete(flagPLine[1])
|
||||
//draw new lines
|
||||
flagHLine := line.new(startIndex, baseHigh, bar_index, baseHigh, color = lineColor, width = lineWidth)
|
||||
flagLLine := line.new(startIndex, baseLow, bar_index, baseLow, color = lineColor, width = lineWidth)
|
||||
flagPLine := line.new(poleLowIndex + 1, poleLow, startIndex, baseLow, color = lineColor, width = lineWidth)
|
||||
flagPLine
|
||||
|
||||
// if a bear flag is detected and the user has bear flags selected from the settings menu draw it on the chart
|
||||
if bearFlag and showBF
|
||||
//if a bear flag was detected on the previous bar, delete those lines and allow for new lines to be drawn
|
||||
if bearFlag[1]
|
||||
line.delete(flagBearHLine[1])
|
||||
line.delete(flagBearLLine[1])
|
||||
line.delete(flagBearPLine[1])
|
||||
//draw new lines
|
||||
flagBearHLine := line.new(startIndexBear, flagHigh, bar_index, flagHigh, color = lineColorBear, width = lineWidthBear)
|
||||
flagBearLLine := line.new(startIndexBear, flagLowBear, bar_index, flagLowBear, color = lineColorBear, width = lineWidthBear)
|
||||
flagBearPLine := line.new(polehighIndex + 1, poleHigh, startIndexBear, flagHigh, color = lineColorBear, width = lineWidthBear)
|
||||
flagBearPLine
|
||||
|
||||
//reset variables if a breakout occurs
|
||||
if breakout // bull flag - high gets above flag high
|
||||
flagLength := 0
|
||||
baseHigh := high
|
||||
startIndex := bar_index
|
||||
lowIndex := bar_index
|
||||
baseLow := low
|
||||
baseLow
|
||||
|
||||
if breakoutBear // bear flag - low gets below flag low
|
||||
flagLengthBear := 0
|
||||
flagLowBear := low
|
||||
startIndexBear := bar_index
|
||||
highIndex := bar_index
|
||||
flagHigh := high
|
||||
flagHigh
|
||||
|
||||
//reset the variables and highs from a failed bull flag. This allows stocks below previous highs to find new flags
|
||||
highest = ta.highest(high, 10) // built in variable that finds the highest high lookingback the past 10 bars
|
||||
if breakdown or flagLength == max_flag
|
||||
flagBool := false
|
||||
baseHigh := highest
|
||||
startIndex := bar_index
|
||||
lowIndex := bar_index
|
||||
baseLow := low
|
||||
baseLow
|
||||
|
||||
//reset the variables and lows from a failed bear flag. This allows stocks above previous lows to find new flags
|
||||
lowest = ta.lowest(low, 10) // built in variable that finds the lowest low lookingback the past 10 bars
|
||||
if breakdownBear or flagLengthBear == max_flagBear
|
||||
flagBoolBear := false
|
||||
flagLowBear := lowest
|
||||
startIndexBear := bar_index
|
||||
highIndex := bar_index
|
||||
flagHigh := high
|
||||
flagHigh
|
||||
|
||||
// if a flag breakdowns remove the lines from the chart
|
||||
if breakdown and flag[1]
|
||||
line.delete(flagHLine)
|
||||
line.delete(flagLLine)
|
||||
line.delete(flagPLine)
|
||||
|
||||
if breakdownBear and bearFlag[1]
|
||||
line.delete(flagBearHLine)
|
||||
line.delete(flagBearLLine)
|
||||
line.delete(flagBearPLine)
|
||||
|
||||
//plot breakouts
|
||||
// use a plotshape to check if there is a breakout and the show breakout option is selected. If both requirements are met plot a shape at the breakout bar
|
||||
plotshape(plotBO and showBO and showF, 'Breakout', shape.triangleup, location.belowbar, color.green, display = display.pane)
|
||||
|
||||
// use a plotshape to check if there is a breakout and the show breakout option is selected. If both requirements are met plot a shape at the breakout bar
|
||||
plotshape(plotBD and showBD and showBF, 'Breakout', shape.triangledown, location.abovebar, color.red, display = display.pane)
|
||||
|
||||
//alerts
|
||||
// add alerts for two conditions, a breakout and when a new flag is formed meeting all requirements.
|
||||
alertcondition(plotBO, 'Bull Flag Breakout', '{{ticker}} Breaking Out from Bull Flag')
|
||||
alertcondition(flag, 'New Bull Flag', '{{ticker}} has formed a bull flag')
|
||||
alertcondition(plotBD, 'Bear Flag Breakout', '{{ticker}} Breaking Out from Bear Flag')
|
||||
alertcondition(bearFlag, 'New Bear Flag', '{{ticker}} has formed a bear flag')
|
||||
Reference in New Issue
Block a user