ema7=ta.
ema(close,7)
plot(ema7,color=color.rgb(11, 10, 11),linewidth=2)
sma200=ta.sma(close,200)
ema200=ta.ema(close,200)
plot(ema200,color=#0e0c0c,linewidth=3)
sma20=ta.sma(close,20)
plot(sma20,color=color.rgb(16, 119, 222),linewidth=2)
plot(sma200,color=color.black,linewidth=1)
//---------------------------------------------------------------------------------
------------------------------------}
// This source code is subject to the terms of the Mozilla Public License 2.0 at
https://mozilla.org/MPL/2.0/
// © 2024 crypto-with-joe. Inspired by LonesomeTheBlue.
//@version=5
//indicator("Praying Mantis - Dynamic Support & Resistance Levels by Joe",
shorttitle = "Mantis", overlay = true, max_bars_back = 501, max_labels_count = 150)
// Agreement
indi_ver = "1.2"
indi_name = "Praying Mantis"
indi_agree = input.bool(false, "By using this indicator, I agree that it has no
guarantees and is only for entertainment and educational use.", group = indi_name +
" v" + indi_ver, confirm = true)
// Options
// ================
// Support & Resistance Levels
pm_srlevel_width = input.int(5, "Maximum Level Height %", minval =
1, maxval = 8, group = "𝌆 Support & Resistance Levels")
pm_srlevel_stren_min = input.int(2, "Minimum Strength", minval =
1, group = "𝌆 Support & Resistance Levels", tooltip = "Channel
must contain at least 2 pivot points.")
pm_srlevels_max = input.int(9, "Maximum Number of Levels (1-10)", minval =
1, maxval = 10, group = "𝌆 Support & Resistance Levels", tooltip = "Maximum
number of support/resistance channels to show.") - 1
pm_srlevels_lb = input.int(288, "Lookback Period", minval =
48, maxval = 410, group = "𝌆 Support & Resistance Levels", tooltip = 'How many
bars to look back when calculating support/resistance levels. If using a lookback
period of 288 on various timeframes,...\n\t• 5m - 24 hours\n\t• 15m - 3 days\n\t•
1h - 12 days\n\t• 1d - 288 days')
// Support & Resistance Colors
pm_sup_color = input.color(color.new(#a1afb3, 92), "Support",
group = "✎ Support & Resistance Styles", inline = "Colors")
pm_res_color = input.color(color.new(#a1afb3, 92), "Resistance",
group = "✎ Support & Resistance Styles", inline = "Colors")
pm_in_color = input.color(color.new(#00a9d4, 92), "Price In Channel",
group = "✎ Support & Resistance Styles", inline = "Colors")
pm_srlevels_extend = input.string("Right", "Extend Level on Chart",
group = "✎ Support & Resistance Styles", options = ['No', 'Right', 'Left', 'Both'],
tooltip = "Extend the S/R levels to the right and/or left on chart.")
pm_srlevels_border_width = input.int (1, "Box Border Width (0-1)", maxval =
1, group = "✎ Support & Resistance Styles",
tooltip = "If set to 0, some minor levels may be invisible.")
// Extras
pm_labels_show = input.bool (true, "Price Labels",
group = "✱ Support & Resistance Extras", inline = "Labels")
pm_labels_color = input.color (#787b86, "",
group = "✱ Support & Resistance Extras", inline = "Labels")
pm_labels_size = input.string("Tiny", "Text Size",
group = "✱ Support & Resistance Extras", inline = "Labels", options = ['Tiny',
'Small', 'Medium', 'Large', 'X-Large'])
pm_labels_extend = input.int (10, "Push Labels ____ Bars to the Right (0-
100)", maxval = 100, group = "✱ Support & Resistance Extras",
tooltip = "Use to prevent price labels from overlapping price bars.")
// Pivot Points
pm_pp_show = input.bool (true, "Pivot Points",
group = "▲▼ Pivot Points", inline = "PP1")
pm_pp_period = input.int (10, "— Period", minval = 2, maxval =
50, group = "▲▼ Pivot Points", inline = "PP1",
tooltip = "Used while calculating pivot points, checks past and future bars.\nPivot
points will not show up until this number of bars have printed on the chart.\
nTherefore, larger values will result in more delayed pivot points being printed.")
pm_pp_source = input.string("High/Low", "Source",
group = "▲▼ Pivot Points", inline = "PP1", options = ['High/Low', 'Open/Close'],
tooltip = "Source for pivot points")
pm_pp_price_show = input.bool (true, "Show Price",
group = "▲▼ Pivot Points", inline = "PP2")
pm_pp_price_size = input.string("Tiny", "— Text Size",
group = "▲▼ Pivot Points", inline = "PP2", options = ['Tiny', 'Small', 'Medium',
'Large', 'X-Large', 'Auto'])
pm_pp_price_label_text_color = input.color(color.new(color.white, 0), "",
group = "▲▼ Pivot Points", inline = "PP2")
pm_pp_price_h_label_color = input.color(color.new(color.gray, 100), "",
group = "▲▼ Pivot Points", inline = "PP2")
pm_pp_price_l_label_color = input.color(color.new(color.gray, 100), "",
group = "▲▼ Pivot Points", inline = "PP2")
// Calculations
// ================
// Get Pivot Highs & Lows
// ----------------
float src1 = pm_pp_source == 'High/Low' ? high : math.max(close, open)
float src2 = pm_pp_source == 'High/Low' ? low : math.min(close, open)
float ph = ta.pivothigh(src1, pm_pp_period, pm_pp_period)
float pl = ta.pivotlow (src2, pm_pp_period, pm_pp_period)
// Draw Pivot Points
// ----------------
drawLabel(_offset, _pivot, _style, _color, _textColor) =>
if not na(_pivot) and pm_pp_price_show
price_size = pm_pp_price_size == "Tiny" ? size.tiny : pm_pp_price_size ==
"Small" ? size.small : pm_pp_price_size == "Medium" ? size.normal :
pm_pp_price_size == "Large" ? size.large : pm_pp_price_size == "X-Large" ?
size.huge : size.auto
label.new(bar_index[_offset], _pivot, str.tostring(_pivot, format.mintick),
style=_style, color=_color, textcolor=_textColor, size = price_size)
drawLabel(pm_pp_period, ph, label.style_label_down, pm_pp_price_h_label_color,
pm_pp_price_label_text_color)
drawLabel(pm_pp_period, pl, label.style_label_up, pm_pp_price_l_label_color,
pm_pp_price_label_text_color)
plotshape(indi_agree and ph and pm_pp_show and not(pm_pp_price_show), text = "",
style = shape.triangledown, color = color.red, textcolor = color.red, location =
location.abovebar, offset = - pm_pp_period)
plotshape(indi_agree and pl and pm_pp_show and not(pm_pp_price_show), text = "",
style = shape.triangleup, color = color.lime, textcolor = color.lime, location =
location.belowbar, offset = - pm_pp_period)
// Calculate maximum S/R channel width
prdhighest = ta.highest(300)
prdlowest = ta.lowest(300)
cwidth = (prdhighest - prdlowest) * pm_srlevel_width / 100
// Get/Keep Pivot Levels
var pivotvals = array.new_float(0)
var pivotlocs = array.new_float(0)
if ph or pl
array.unshift(pivotvals, ph ? ph : pl)
array.unshift(pivotlocs, bar_index)
for x = array.size(pivotvals) - 1 to 0
if bar_index - array.get(pivotlocs, x) > pm_srlevels_lb // remove old pivot
points
array.pop(pivotvals)
array.pop(pivotlocs)
continue
break
// Find/Create SR Level of a Pivot Point
get_sr_vals(ind)=>
float lo = array.get(pivotvals, ind)
float hi = lo
int numpp = 0
for y = 0 to array.size(pivotvals) - 1
float cpp = array.get(pivotvals, y)
float wdth = cpp <= hi ? hi - cpp : cpp - lo
if wdth <= cwidth // Fits the max channel width?
if cpp <= hi
lo := math.min(lo, cpp)
else
hi := math.max(hi, cpp)
numpp := numpp + 20 // Each pivot point added as 20
[hi, lo, numpp]
// Keep Old SR Levels and Calculate/Sort New Channels if We Get New Pivot Point
var supportresistance = array.new_float(20, 0) // Min/max levels
changeit(x, y)=>
tmp = array.get(supportresistance, y * 2)
array.set(supportresistance, y * 2, array.get(supportresistance, x * 2))
array.set(supportresistance, x * 2, tmp)
tmp := array.get(supportresistance, y * 2 + 1)
array.set(supportresistance, y * 2 + 1, array.get(supportresistance, x * 2 +
1))
array.set(supportresistance, x * 2 + 1, tmp)
if ph or pl
supres = array.new_float(0) // Number of pivot, strength, min/max levels
stren = array.new_float(10, 0)
// Get levels and strengths
for x = 0 to array.size(pivotvals) - 1
[hi, lo, strength] = get_sr_vals(x)
array.push(supres, strength)
array.push(supres, hi)
array.push(supres, lo)
// Add Each HL and LH to Strength
for x = 0 to array.size(pivotvals) - 1
h = array.get(supres, x * 3 + 1)
l = array.get(supres, x * 3 + 2)
s = 0
for y = 0 to pm_srlevels_lb
if (high[y] <= h and high[y] >= l) or
(low[y] <= h and low[y] >= l)
s := s + 1
array.set(supres, x * 3, array.get(supres, x * 3) + s)
// Reset SR Levels
array.fill(supportresistance, 0)
// Get strongest SRs
src = 0
for x = 0 to array.size(pivotvals) - 1
stv = -1. // value
stl = -1 // location
for y = 0 to array.size(pivotvals) - 1
if array.get(supres, y * 3) > stv and array.get(supres, y * 3) >=
pm_srlevel_stren_min * 20
stv := array.get(supres, y * 3)
stl := y
if stl >= 0
//get sr level
hh = array.get(supres, stl * 3 + 1)
ll = array.get(supres, stl * 3 + 2)
array.set(supportresistance, src * 2, hh)
array.set(supportresistance, src * 2 + 1, ll)
array.set(stren, src, array.get(supres, stl * 3))
// Make included pivot points' strength zero
for y = 0 to array.size(pivotvals) - 1
if (array.get(supres, y * 3 + 1) <= hh and array.get(supres, y * 3
+ 1) >= ll) or
(array.get(supres, y * 3 + 2) <= hh and array.get(supres, y * 3
+ 2) >= ll)
array.set(supres, y * 3, -1)
src += 1
if src >= 10
break
for x = 0 to 8
for y = x + 1 to 9
if array.get(stren, y) > array.get(stren, x)
tmp = array.get(stren, y)
array.set(stren, y, array.get(stren, x))
changeit(x, y)
get_level(ind)=>
float ret = na
if ind < array.size(supportresistance)
if array.get(supportresistance, ind) != 0
ret := array.get(supportresistance, ind)
ret
get_color(ind)=>
color ret = na
if ind < array.size(supportresistance)
if array.get(supportresistance, ind) != 0
ret := array.get(supportresistance, ind) > close and
array.get(supportresistance, ind + 1) > close ? pm_res_color :
array.get(supportresistance, ind) < close and
array.get(supportresistance, ind + 1) < close ? pm_sup_color :
pm_in_color
ret
var srchannels = array.new_box(10)
for x = 0 to math.min(9, pm_srlevels_max)
box.delete(array.get(srchannels, x))
srcol = get_color(x * 2)
sr_label = math.round(((get_level(x * 2) + get_level(x * 2 + 1)) / 2) /
syminfo.mintick) * syminfo.mintick
if not na(srcol) and indi_agree
array.set(srchannels, x,
box.new(left = bar_index - pm_srlevels_lb, top = get_level(x *
2), right = pm_labels_show ? bar_index + pm_labels_extend : bar_index, bottom =
get_level(x * 2 + 1),
border_color = srcol,
border_width = pm_srlevels_border_width,
extend = pm_srlevels_extend == "Both" ? extend.both :
pm_srlevels_extend == "Right" ? extend.right : pm_srlevels_extend == "Left" ?
extend.left : extend.none,
bgcolor = srcol,
text = pm_labels_show ? str.tostring(sr_label, "0.00") :
na,
text_size = pm_labels_size == "Tiny" ? size.tiny :
pm_labels_size == "Small" ? size.small : pm_labels_size == "Medium" ? size.normal :
pm_labels_size == "Large" ? size.large : size.huge,
text_color = pm_labels_color,
text_halign = text.align_right))
resistancebroken = false
supportbroken = false
// Check if price is not in a channel
not_in_a_channel = true
for x = 0 to math.min(9, pm_srlevels_max)
if close <= array.get(supportresistance, x * 2) and close >=
array.get(supportresistance, x * 2 + 1)
not_in_a_channel := false
// If price is not in a channel, then check broken ones
if not_in_a_channel
for x = 0 to math.min(9, pm_srlevels_max)
if close[1] <= array.get(supportresistance, x * 2) and close >
array.get(supportresistance, x * 2)
resistancebroken := true
if close[1] >= array.get(supportresistance, x * 2 + 1) and close <
array.get(supportresistance, x * 2 + 1)
supportbroken := true