Skip to content

Instantly share code, notes, and snippets.

@CryptoMF
Created August 3, 2020 08:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save CryptoMF/a2d7a77baa8f203a4eae68702fe6245c to your computer and use it in GitHub Desktop.
Save CryptoMF/a2d7a77baa8f203a4eae68702fe6245c to your computer and use it in GitHub Desktop.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © CryptoMF
//@version=4
study("MF_S&R", overlay=true)
// Inputs
ln = input(7, title="Pivot Length", type=input.integer) // Number of bars to use to calculate pivot
mb = input(3, title="Max Breaks", type=input.integer) // Maximum number of times a line can be broken before it's invalidated
md = input(50, title="Max Distance %", type=input.integer) // Maximum distance PA can move away from line before it's invalidated
fo = input(2, title="Frontrun/Overshoot Threshold %", type=input.integer) // If PA reverses within this distance of an existing S&R line, consider it a frontrun / overshoot
cl = input("Blue", title="Line Colour", options=["Blue", "Black", "Silver", "Gray", "White", "Maroon", "Red", "Purple", "Fuchsia", "Green", "Lime", "Olive", "Yellow", "Navy", "Teal", "Aqua", "Orange"])
// Line colors
lc = cl == "Blue" ? color.blue : cl == "Black" ? color.black : cl == "Silver" ? color.silver : cl == "Gray" ? color.gray : cl == "White" ? color.white : cl == "Maroon" ? color.maroon : cl == "Red" ? color.red : cl == "Purple" ? color.purple : cl == "Fuchsia" ? color.fuchsia : cl == "Green" ? color.green : cl == "Lime" ? color.lime : cl == "Olive" ? color.olive : cl == "Yellow" ? color.yellow : cl == "Navy" ? color.navy : cl == "Teal" ? color.teal : cl == "Aqua" ? color.aqua : cl == "Orange" ? color.orange : color.blue
// S&R Levels
var float sr01 = na
var float sr02 = na
var float sr03 = na
var float sr04 = na
var float sr05 = na
var float sr06 = na
var float sr07 = na
var float sr08 = na
var float sr09 = na
var float sr10 = na
var float sr11 = na
var float sr12 = na
var float sr13 = na
var float sr14 = na
var float sr15 = na
// S&R Lines
var line l01 = na
var line l02 = na
var line l03 = na
var line l04 = na
var line l05 = na
var line l06 = na
var line l07 = na
var line l08 = na
var line l09 = na
var line l10 = na
var line l11 = na
var line l12 = na
var line l13 = na
var line l14 = na
var line l15 = na
// S&R Break Counters
var br01 = 0
var br02 = 0
var br03 = 0
var br04 = 0
var br05 = 0
var br06 = 0
var br07 = 0
var br08 = 0
var br09 = 0
var br10 = 0
var br11 = 0
var br12 = 0
var br13 = 0
var br14 = 0
var br15 = 0
// Check if a pivot is actually just a swing failure off an existing S&R level
issfp(level) =>
((open[ln] < level) and (high[ln] > level) and (close[ln] < level)) or ((open[ln] > level) and (low[ln] < level) and (close[ln] > level)) or ((open[ln+1] < level) and (high[ln+1] > level) and (close[ln+1] < level)) or ((open[ln+1] > level) and (low[ln+1] < level) and (close[ln+1] > level))
// Check if pivot is actually just a frontrun or overshoot of an existing S&R level (<1% diff)
isfros(level) =>
((open[ln] < level) and ((abs(level - high[ln]) / level) * 100 < fo) and (close[ln] < level)) or ((open[ln] > level) and ((abs(low[ln] - level) / level) * 100 < fo) and (close[ln] > level)) or ((open[ln-1] < level) and ((abs(level - high[ln-1]) / level) * 100 < fo) and (close[ln-1] < level)) or ((open[ln-1] > level) and ((abs(low[ln-1] - level) / level) * 100 < fo) and (close[ln-1] > level))
// Check for level break failure (frontrun or sfp)
isbreakfailure() =>
issfp(sr01) ? true : issfp(sr02) ? true : issfp(sr03) ? true : issfp(sr04) ? true : issfp(sr05) ? true : issfp(sr06) ? true : issfp(sr07) ? true : issfp(sr08) ? true : issfp(sr09) ? true : issfp(sr10) ? true : issfp(sr11) ? true : issfp(sr12) ? true : issfp(sr13) ? true : issfp(sr14) ? true : issfp(sr15) ? true : isfros(sr01) ? true : isfros(sr02) ? true : isfros(sr03) ? true : isfros(sr04) ? true : isfros(sr05) ? true : isfros(sr06) ? true : isfros(sr07) ? true : isfros(sr08) ? true : isfros(sr09) ? true : isfros(sr10) ? true : isfros(sr11) ? true : isfros(sr12) ? true : isfros(sr13) ? true : isfros(sr14) ? true : isfros(sr15) ? true : false
// Custom Pivot Function
pv() =>
c = close
br = 0
bl = ln * 2 + 1
m = c[ln]
ph = m == highest(c, bl) ? true : false
pl = m == lowest(c, bl) ? true : false
(ph or pl) and not isbreakfailure() ? c[ln] : na
p = pv() // Get pivot
lb = ln // Offset of pivot line
// Find an unused pivot level and use it
if not na(p)
if na(sr01)
l01 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr01 := p
else
if na(sr02)
l02 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr02 := p
else
if na(sr03)
l03 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr03 := p
else
if na(sr04)
l04 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr04 := p
else
if na(sr05)
l05 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr05 := p
else
if na(sr06)
l06 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr06 := p
else
if na(sr07)
l07 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr07 := p
else
if na(sr08)
l08 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr08 := p
else
if na(sr09)
l09 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr09 := p
else
if na(sr10)
l10 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr10 := p
else
if na(sr11)
l11 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr11 := p
else
if na(sr12)
l12 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr12 := p
else
if na(sr13)
l13 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr13 := p
else
if na(sr14)
l14 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr14 := p
else
if na(sr15)
l15 := line.new(bar_index - lb, p, bar_index, p, extend=extend.right, color=lc)
sr15 := p
// Count number of times a S&R line has been broken
if ((open < sr01) and (close > sr01)) or ((open > sr01) and (close < sr01))
br01 := br01 + 1
if ((open < sr02) and (close > sr02)) or ((open > sr02) and (close < sr02))
br02 := br02 + 1
if ((open < sr03) and (close > sr03)) or ((open > sr03) and (close < sr03))
br03 := br03 + 1
if ((open < sr04) and (close > sr04)) or ((open > sr04) and (close < sr04))
br04 := br04 + 1
if ((open < sr05) and (close > sr05)) or ((open > sr05) and (close < sr05))
br05 := br05 + 1
if ((open < sr06) and (close > sr06)) or ((open > sr06) and (close < sr06))
br06 := br06 + 1
if ((open < sr07) and (close > sr07)) or ((open > sr07) and (close < sr07))
br07 := br07 + 1
if ((open < sr08) and (close > sr08)) or ((open > sr08) and (close < sr08))
br08 := br08 + 1
if ((open < sr09) and (close > sr09)) or ((open > sr09) and (close < sr09))
br09 := br09 + 1
if ((open < sr10) and (close > sr10)) or ((open > sr10) and (close < sr10))
br10 := br10 + 1
if ((open < sr11) and (close > sr11)) or ((open > sr11) and (close < sr11))
br11 := br11 + 1
if ((open < sr12) and (close > sr12)) or ((open > sr12) and (close < sr12))
br12 := br12 + 1
if ((open < sr13) and (close > sr13)) or ((open > sr13) and (close < sr13))
br13 := br13 + 1
if ((open < sr14) and (close > sr14)) or ((open > sr14) and (close < sr14))
br14 := br14 + 1
if ((open < sr15) and (close > sr15)) or ((open > sr15) and (close < sr15))
br15 := br15 + 1
// Check number of times an S&R line has been broken, or calculate distance to current PA and invalidate the S&R level if necessary
if br01 >= mb or (abs(sr01 - close) / close) * 100 >= md
sr01 := na
br01 := 0
line.delete(l01)
if br02 >= mb or (abs(sr02 - close) / close) * 100 >= md
sr02 := na
br02 := 0
line.delete(l02)
if br03 >= mb or (abs(sr03 - close) / close) * 100 >= md
sr03 := na
br03 := 0
line.delete(l03)
if br04 >= mb or (abs(sr04 - close) / close) * 100 >= md
sr04 := na
br04 := 0
line.delete(l04)
if br05 >= mb or (abs(sr05 - close) / close) * 100 >= md
sr05 := na
br05 := 0
line.delete(l05)
if br06 >= mb or (abs(sr06 - close) / close) * 100 >= md
sr06 := na
br06 := 0
line.delete(l06)
if br07 >= mb or (abs(sr07 - close) / close) * 100 >= md
sr07 := na
br07 := 0
line.delete(l07)
if br08 >= mb or (abs(sr08 - close) / close) * 100 >= md
sr08 := na
br08 := 0
line.delete(l08)
if br09 >= mb or (abs(sr09 - close) / close) * 100 >= md
sr09 := na
br09 := 0
line.delete(l09)
if br10 >= mb or (abs(sr10 - close) / close) * 100 >= md
sr10 := na
br10 := 0
line.delete(l10)
if br11 >= mb or (abs(sr11 - close) / close) * 100 >= md
sr11 := na
br11 := 0
line.delete(l11)
if br12 >= mb or (abs(sr12 - close) / close) * 100 >= md
sr12 := na
br12 := 0
line.delete(l12)
if br13 >= mb or (abs(sr13 - close) / close) * 100 >= md
sr13 := na
br13 := 0
line.delete(l13)
if br14 >= mb or (abs(sr14 - close) / close) * 100 >= md
sr14 := na
br14 := 0
line.delete(l14)
if br15 >= mb or (abs(sr15 - close) / close) * 100 >= md
sr15 := na
br15 := 0
line.delete(l15)
@uneqorn
Copy link

uneqorn commented Aug 3, 2020

Wicked Cool! So cool it's Frosty AF! :D

@metapodcod
Copy link

Processing script...
line 88: The function 'isfros' should be called on each calculation for consistency. It is recommended to extract the call from the ternary operator or from the scope.
line 88: The function 'issfp' should be called on each calculation for consistency. It is recommended to extract the call from the ternary operator or from the scope.
Script 'MF_S&R' has been saved
line 88: The function 'isfros' should be called on each calculation for consistency. It is recommended to extract the call from the ternary operator or from the scope.
line 88: The function 'issfp' should be called on each calculation for consistency. It is recommended to extract the call from the ternary operator or from the scope.
Script study added to the chart

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment