SHOW:
|
|
- or go back to the newest paste.
| 1 | // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ | |
| 2 | // © Alex | |
| 3 | ||
| 4 | //@version=5 | |
| 5 | indicator("My script",overlay=true, max_lines_count = 50, max_bars_back = 200)
| |
| 6 | ||
| 7 | ||
| 8 | line_limit = input(50) | |
| 9 | any_initial_signal = input.bool(true) | |
| 10 | ignore_motherbar_signals = input.bool(true) | |
| 11 | ignore_gaps = input.bool(false) | |
| 12 | show_entry_stop = input(true) | |
| 13 | unready_after_x_bars = input.int(5) | |
| 14 | doji_range_input = input(.2) | |
| 15 | dots = input.bool(false) | |
| 16 | paint_old_liquidity = input.bool(false) | |
| 17 | ||
| 18 | ||
| 19 | var high_liq_array = array.new_line() | |
| 20 | var low_liq_array = array.new_line() | |
| 21 | var line readied_level = na | |
| 22 | ||
| 23 | var bool readied_bull = false | |
| 24 | var bool setup_bull = false | |
| 25 | ||
| 26 | var bool readied_bear = false | |
| 27 | var bool setup_bear = false | |
| 28 | ||
| 29 | var line bull_entry_line = na | |
| 30 | var line bull_stop_line = na | |
| 31 | ||
| 32 | var line bear_entry_line = na | |
| 33 | var line bear_stop_line = na | |
| 34 | ||
| 35 | var line mother_bar_high_line = na | |
| 36 | var line mother_bar_low_line = na | |
| 37 | ||
| 38 | var label mother_bar_high_label = na | |
| 39 | var label mother_bar_low_label = na | |
| 40 | ||
| 41 | initial_signal = readied_bull[1] ? false : true | |
| 42 | ||
| 43 | ATRPeriod = input.int(12, "ATR Period", tooltip = "This is the number of bars back that the script uses to calculate the Average True Range.") | |
| 44 | ATRMultiplier = input.float(3, "ATR Multiplier", step=.1, tooltip = "This is the multiple of the ATR average that will function as the trail.") | |
| 45 | ||
| 46 | ATR = ta.atr(ATRPeriod) | |
| 47 | Stop = ATRMultiplier*ATR | |
| 48 | ||
| 49 | var ATRTrailingStop = 0.0 | |
| 50 | ATRTrailingStop := if close>ATRTrailingStop[1] and close[1]>ATRTrailingStop[1] | |
| 51 | math.max(ATRTrailingStop[1], close-Stop) | |
| 52 | else if close<ATRTrailingStop[1] and close[1]<ATRTrailingStop[1] | |
| 53 | math.min(ATRTrailingStop[1], close+Stop) | |
| 54 | else if close>ATRTrailingStop[1] | |
| 55 | close-Stop | |
| 56 | else | |
| 57 | close+Stop | |
| 58 | ||
| 59 | var Position = 0.0 | |
| 60 | Position := if close[1]<ATRTrailingStop[1] and close>ATRTrailingStop[1] | |
| 61 | 1 | |
| 62 | else if close[1]>ATRTrailingStop[1] and close<ATRTrailingStop[1] | |
| 63 | -1 | |
| 64 | else | |
| 65 | Position[1] | |
| 66 | ||
| 67 | current_candle_range = high-low | |
| 68 | doji_range = current_candle_range*doji_range_input | |
| 69 | ||
| 70 | ||
| 71 | low_formed = low[2] > low[1] and low[1] < low | |
| 72 | high_formed = high[2] < high[1] and high[1] > high | |
| 73 | ||
| 74 | mother_bar_formed = high[2] > high[1] and high[2] > high and low[2] < low[1] and low[2] < low | |
| 75 | ||
| 76 | ||
| 77 | if high_formed | |
| 78 | bull_line = line.new(bar_index[1],high[1],bar_index[0],high[1],extend=extend.right, color= color.red, style = line.style_solid) | |
| 79 | high_liq_array.push(bull_line) | |
| 80 | if low_formed | |
| 81 | bear_line = line.new(bar_index[1],low[1],bar_index[0],low[1],extend=extend.right,color = color.green, style = line.style_solid) | |
| 82 | low_liq_array.push(bear_line) | |
| 83 | if mother_bar_formed and na(mother_bar_high_line) and na(mother_bar_low_line) | |
| 84 | mother_bar_high_line:= line.new(bar_index[1],high[1],bar_index[0],high[1],extend=extend.right,color=color.black,style=line.style_dotted) | |
| 85 | mother_bar_low_line:= line.new(bar_index[1],low[1],bar_index[0],low[1],extend=extend.right,color=color.black,style=line.style_dotted) | |
| 86 | mother_bar_high_label:= label.new(bar_index+5,high[1],str.tostring(mother_bar_high_line.get_y1()), style = label.style_none) | |
| 87 | mother_bar_low_label:= label.new(bar_index+5,low[1],str.tostring(mother_bar_high_line.get_y1()), style= label.style_none) | |
| 88 | ||
| 89 | ||
| 90 | ||
| 91 | for [index,value] in high_liq_array | |
| 92 | linex = high_liq_array.get(index) | |
| 93 | if high >= linex.get_y1() and low < linex.get_y1() | |
| 94 | ||
| 95 | if paint_old_liquidity | |
| 96 | line.new(linex.get_x1(),linex.get_y1(),bar_index[0],linex.get_y1(),color=color.black) | |
| 97 | ||
| 98 | array.remove(high_liq_array,index) | |
| 99 | readied_level:=linex | |
| 100 | readied_bear:= true | |
| 101 | ||
| 102 | line.delete(linex) | |
| 103 | ||
| 104 | if na(mother_bar_high_line) == false and mother_bar_high_line.get_y1() < high | |
| 105 | readied_level:= mother_bar_low_line | |
| 106 | readied_bear:= true | |
| 107 | ||
| 108 | ||
| 109 | mother_bar_low_label.delete() | |
| 110 | mother_bar_high_label.delete() | |
| 111 | mother_bar_high_line.delete() | |
| 112 | mother_bar_low_line.delete() | |
| 113 | ||
| 114 | mother_bar_low_label:=na | |
| 115 | mother_bar_high_label:=na | |
| 116 | mother_bar_low_line:=na | |
| 117 | mother_bar_high_line:=na | |
| 118 | for [index,value] in low_liq_array | |
| 119 | linex = low_liq_array.get(index) | |
| 120 | ||
| 121 | if low < linex.get_y1() and high > linex.get_y1() | |
| 122 | ||
| 123 | if paint_old_liquidity | |
| 124 | line.new(linex.get_x1(),linex.get_y1(),bar_index[0],linex.get_y1(),color=color.black) | |
| 125 | ||
| 126 | ||
| 127 | array.remove(low_liq_array,index) | |
| 128 | readied_level:=linex | |
| 129 | readied_bull:= true | |
| 130 | ||
| 131 | line.delete(linex) | |
| 132 | ||
| 133 | if na(mother_bar_low_line) == false and mother_bar_low_line.get_y1() > low | |
| 134 | readied_level:= mother_bar_low_line | |
| 135 | readied_bull:= true | |
| 136 | ||
| 137 | ||
| 138 | mother_bar_low_label.delete() | |
| 139 | mother_bar_high_label.delete() | |
| 140 | mother_bar_high_line.delete() | |
| 141 | mother_bar_low_line.delete() | |
| 142 | ||
| 143 | mother_bar_low_label:= na | |
| 144 | mother_bar_high_label:=na | |
| 145 | mother_bar_low_line:=na | |
| 146 | mother_bar_high_line:=na | |
| 147 | ||
| 148 | ||
| 149 | inside_motherbar = na(mother_bar_high_line.get_y1()) == false and na(mother_bar_low_line.get_y1()) == false //True if both are not NA | |
| 150 | ||
| 151 | ||
| 152 | bear_stop = high | |
| 153 | bull_stop = low | |
| 154 | ||
| 155 | if readied_bull | |
| 156 | if open > bull_entry_line.get_y1() and ignore_gaps==true | |
| 157 | setup_bull:=false | |
| 158 | readied_bull:=false | |
| 159 | ||
| 160 | line.delete(bull_entry_line) | |
| 161 | line.delete(bull_stop_line) | |
| 162 | ||
| 163 | if low < low[1] and close > open and inside_motherbar == false | |
| 164 | setup_bull:= true | |
| 165 | ||
| 166 | if show_entry_stop | |
| 167 | line.delete(bull_entry_line) | |
| 168 | line.delete(bull_stop_line) | |
| 169 | bull_entry_line:= line.new(bar_index[0],high,bar_index[0]+3,high, color=color.orange) | |
| 170 | bull_stop_line:= line.new(bar_index[0],bull_stop,bar_index[0]+3,bull_stop,color =color.red) | |
| 171 | ||
| 172 | if high < high[1] and low > low[1] and inside_motherbar == false | |
| 173 | setup_bull:= true | |
| 174 | if show_entry_stop | |
| 175 | line.delete(bull_entry_line) | |
| 176 | line.delete(bull_stop_line) | |
| 177 | bull_entry_line:= line.new(bar_index[0],high,bar_index[0]+3,high, color=color.orange) | |
| 178 | bull_stop_line:= line.new(bar_index[0],bull_stop,bar_index[0]+3,bull_stop,color =color.red) | |
| 179 | if math.abs(close-open) <= doji_range and low<low[1] | |
| 180 | setup_bull:= true | |
| 181 | if show_entry_stop | |
| 182 | line.delete(bull_entry_line) | |
| 183 | line.delete(bull_stop_line) | |
| 184 | bull_entry_line:= line.new(bar_index[0],high,bar_index[0]+3,high, color=color.orange) | |
| 185 | bull_stop_line:= line.new(bar_index[0],bull_stop,bar_index[0]+3,bull_stop,color =color.red) | |
| 186 | ||
| 187 | if ignore_motherbar_signals==false and inside_motherbar == true | |
| 188 | setup_bull:= true | |
| 189 | if show_entry_stop | |
| 190 | line.delete(bull_entry_line) | |
| 191 | line.delete(bull_stop_line) | |
| 192 | bull_entry_line:= line.new(bar_index[0],high,bar_index[0]+3,high, color=color.orange, style = line.style_dashed) | |
| 193 | bull_stop_line:= line.new(bar_index[0],bull_stop,bar_index[0]+3,bull_stop,color =color.red) | |
| 194 | ||
| 195 | ||
| 196 | if any_initial_signal==true and initial_signal and low < low[1] | |
| 197 | setup_bull:=true | |
| 198 | if show_entry_stop | |
| 199 | line.delete(bull_entry_line) | |
| 200 | line.delete(bull_stop_line) | |
| 201 | bull_entry_line:= line.new(bar_index[0],high,bar_index[0]+3,high, color=color.orange, style = line.style_dashed) | |
| 202 | bull_stop_line:= line.new(bar_index[0],bull_stop,bar_index[0]+3,bull_stop,color =color.red) | |
| 203 | ||
| 204 | ||
| 205 | //Large Lower Wick | |
| 206 | if close>open and (math.abs(low-close) > math.abs(close-open)) and low < low[1] | |
| 207 | setup_bull:= true | |
| 208 | if show_entry_stop | |
| 209 | line.delete(bull_entry_line) | |
| 210 | line.delete(bull_stop_line) | |
| 211 | bull_entry_line:= line.new(bar_index[0],high,bar_index[0]+3,high, color=color.orange) | |
| 212 | bull_stop_line:= line.new(bar_index[0],bull_stop,bar_index[0]+3,bull_stop,color =color.red) | |
| 213 | ||
| 214 | //If it goes outside after the ready just negate it | |
| 215 | ||
| 216 | if high > high[1] and low < low[1] | |
| 217 | setup_bull:= false | |
| 218 | readied_bull:=false | |
| 219 | line.delete(bull_entry_line) | |
| 220 | line.delete(bull_stop_line) | |
| 221 | bull_entry_line:=na | |
| 222 | bull_stop_line:=na | |
| 223 | ||
| 224 | if readied_bear | |
| 225 | ||
| 226 | //Negate if gaps | |
| 227 | if open < bear_entry_line.get_y1() and ignore_gaps == true | |
| 228 | setup_bear:=false | |
| 229 | readied_bear:=false | |
| 230 | line.delete(bear_entry_line) | |
| 231 | line.delete(bear_stop_line) | |
| 232 | bear_entry_line:=na | |
| 233 | bear_stop_line:=na | |
| 234 | ||
| 235 | if high > high[1] and close < open and low > low[1] and inside_motherbar==false | |
| 236 | setup_bear:= true | |
| 237 | readied_bear:=false | |
| 238 | if show_entry_stop | |
| 239 | line.delete(bear_entry_line) | |
| 240 | line.delete(bear_stop_line) | |
| 241 | bear_entry_line:= line.new(bar_index[0],low,bar_index[0]+3,low, color=color.orange) | |
| 242 | bear_stop_line:= line.new(bar_index[0],bear_stop,bar_index[0]+3,bear_stop,color = color.red) | |
| 243 | ||
| 244 | if (math.abs(close-open) <= doji_range) and high > high[1] | |
| 245 | setup_bear:= true | |
| 246 | if show_entry_stop | |
| 247 | line.delete(bear_entry_line) | |
| 248 | line.delete(bear_stop_line) | |
| 249 | bear_entry_line:= line.new(bar_index[0],low,bar_index[0]+3,low, color=color.orange) | |
| 250 | bear_stop_line:= line.new(bar_index[0],bear_stop,bar_index[0]+3,bear_stop,color =color.red) | |
| 251 | ||
| 252 | //Large Upper Wick | |
| 253 | if close>open and (math.abs(high-close) > math.abs(close-open)) | |
| 254 | setup_bear:= true | |
| 255 | if show_entry_stop | |
| 256 | line.delete(bear_entry_line) | |
| 257 | line.delete(bear_stop_line) | |
| 258 | bear_entry_line:= line.new(bar_index[0],low,bar_index[0]+3,low, color=color.orange) | |
| 259 | bear_stop_line:= line.new(bar_index[0],bear_stop,bar_index[0]+3,bear_stop,color =color.red) | |
| 260 | ||
| 261 | ||
| 262 | //If it goes outside after the ready just negate it | |
| 263 | ||
| 264 | if high > high[1] and low < low[1] | |
| 265 | setup_bear:= false | |
| 266 | readied_bear:=false | |
| 267 | line.delete(bear_entry_line) | |
| 268 | line.delete(bear_stop_line) | |
| 269 | bear_entry_line:=na | |
| 270 | bear_stop_line:=na | |
| 271 | ||
| 272 | bull_trigger = setup_bull==true and high > bull_entry_line.get_y1() | |
| 273 | bear_trigger = setup_bear==true and low < bear_entry_line.get_y1() | |
| 274 | ||
| 275 | ||
| 276 | var table values_display = table.new(position.top_right,2,5,bgcolor = color.rgb(77, 109, 96),frame_color=color.white,frame_width=1,border_color=color.black,border_width=1) | |
| 277 | // We call `atr()` outside the `if` block so it executes on each bar. | |
| 278 | if barstate.islast | |
| 279 | // We only populate the table on the last bar. | |
| 280 | table.cell(values_display, 1,0, str.upper(str.tostring(readied_bull)),text_color = color.green) | |
| 281 | table.cell(values_display, 0,0,'Readied Bull') | |
| 282 | table.cell(values_display, 1,1, str.upper(str.tostring(readied_bear)),text_color = color.red) | |
| 283 | table.cell(values_display, 0,1, 'Readied Bear') | |
| 284 | table.cell(values_display, 0,2, 'MotherBar') | |
| 285 | table.cell(values_display, 1,2, str.upper(str.tostring(inside_motherbar))) | |
| 286 | table.cell(values_display, 0,3, 'Runners Direction') | |
| 287 | table.cell(values_display, 1,3, 'NaN') | |
| 288 | table.cell(values_display, 0,4, 'Setup Direction') | |
| 289 | table.cell(values_display, 1,4, (setup_bull ? 'Bull' : setup_bear ? 'Bear' : 'NaN')) | |
| 290 | ||
| 291 | plotshape(bull_trigger, "none",shape.arrowup,location.belowbar,color.green,offset=0) | |
| 292 | plotshape(bear_trigger, "none",shape.arrowdown,location.abovebar,color.red,offset=0) | |
| 293 | ||
| 294 | if bull_trigger | |
| 295 | readied_bull:= false | |
| 296 | setup_bull:=false | |
| 297 | ||
| 298 | bull_entry_line:=na | |
| 299 | bull_stop_line:=na | |
| 300 | ||
| 301 | //Initial setup negates | |
| 302 | ||
| 303 | if initial_signal | |
| 304 | line.delete(bull_entry_line) | |
| 305 | line.delete(bull_stop_line) | |
| 306 | ||
| 307 | bull_entry_line:=na | |
| 308 | bull_stop_line:=na | |
| 309 | ||
| 310 | ||
| 311 | if bear_trigger | |
| 312 | readied_bear:= false | |
| 313 | setup_bear:= false | |
| 314 | bear_entry_line:=na | |
| 315 | bear_stop_line:=na | |
| 316 | ||
| 317 | plotshape(low_formed and dots,"none",shape.circle,location.belowbar,color.green,offset=-1) | |
| 318 | plotshape(high_formed and dots, "none", shape.circle, location.abovebar,color.red,offset=-1) | |
| 319 | PlotColor = Position == -1 ? color.red: Position == 1 ? color.green : color.navy | |
| 320 | plot(ATRTrailingStop, color=PlotColor, linewidth=input(1, "Line Width"), title="ATR Trailing Stop") | |
| 321 |