Created
August 3, 2020 08:45
-
-
Save CryptoMF/a2d7a77baa8f203a4eae68702fe6245c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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) |
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
Wicked Cool! So cool it's Frosty AF! :D