#// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
#// © ceyhun
#//Original Code https://tr.tradingview.com/v/x8ZRlmof/
#study("Murrey Math Lines", shorttitle="MML", overlay=true)
# Converted by [email protected] - 05/2023
#//-- get inputs
input ShowLines = yes;
input useChartTimeframe = {default "Yes", "No"};
input ManualTimeframe = AggregationPeriod.FIFTEEN_MIN; # "Resolution"
input frameSize = 64; # "Frame Size"
input FrameMultiplier = 1.5; # "Frame Multiplier"
input IgnoreWicks = yes; # "Ignore Wicks?"
def na = Double.NaN;
#//-- defines
def logTen = Log(10);
def log8 = Log(8);
def log2 = Log(2);
def lookback = Round(frameSize * FrameMultiplier, 0);
def o;
def c;
def h;
def l;
switch (useChartTimeframe) {
case "Yes":
o = open;
c = close;
h = high;
l = low;
case "No":
o = open(Period = ManualTimeframe);
c = close(Period = ManualTimeframe);
h = high(Period = ManualTimeframe);
l = low(Period = ManualTimeframe);
}
def uPrice = if IgnoreWicks then Max(o, c) else h;
def lPrice = if IgnoreWicks then Min(o, c) else l;
#//-- find highest/lowest price over specified lookback
def vLow1 = Lowest(lPrice, lookback);
def vHigh1 = Highest(uPrice, lookback);
def vLow = vLow1;#security(ss, res, vLow1)
def vHigh = vHigh1;#security(ss, res, vHigh1)
def vDist = vHigh - vLow;
#//-- if low price is < 0 then adjust accordingly
def tmpHigh = if vLow < 0 then 0 - vLow else vHigh;
def tmpLow = if vLow < 0 then 0 - vLow - vDist else vLow;
#//-- determine if price shift is in place
def shift = vLow < 0;
#//-- calculate scale frame
def sfVar = Log(0.4 * tmpHigh) / logTen - Floor(Log(0.4 * tmpHigh) / logTen);
def SR = if tmpHigh > 25 then
if sfVar > 0 then Exp(logTen * (Floor(Log(0.4 * tmpHigh) / logTen) + 1)) else
Exp(logTen * Floor(Log(0.4 * tmpHigh) / logTen)) else
100 * Exp(log8 * Floor(Log(0.005 * tmpHigh) / log8));
def nVar1 = Log(SR / (tmpHigh - tmpLow)) / log8;
def nVar2 = nVar1 - Floor(nVar1);
def N = if nVar1 <= 0 then 0 else if nVar2 == 0 then Floor(nVar1) else Floor(nVar1) + 1;
#//-- calculate scale interval and temporary frame top and bottom
def SI = SR * Exp(-N * log8);
def M = Floor(1.0 / log2 * Log((tmpHigh - tmpLow) / SI) + 0.0000001);
def I = Round((tmpHigh + tmpLow) * 0.5 / (SI * Exp((M - 1) * log2)), 0);
def Bot = (I - 1) * SI * Exp((M - 1) * log2);
def Top = (I + 1) * SI * Exp((M - 1) * log2);
#//-- determine if frame shift is required
def doShift = tmpHigh - Top > 0.25 * (Top - Bot) or Bot - tmpLow > 0.25 * (Top - Bot);
def ER = if doShift then 1 else 0;
def MM = if ER == 0 then M else if ER == 1 and M < 2 then M + 1 else 0;
def NN = if ER == 0 then N else if ER == 1 and M < 2 then N else N - 1;
#//-- recalculate scale interval and top and bottom of frame, if necessary
def finalSI = if ER == 1 then SR * Exp(-NN * log8) else SI;
def finalI = if ER == 1 then Round((tmpHigh + tmpLow) * 0.5 / (finalSI * Exp((MM - 1) * log2)), 0) else I;
def finalBot = if ER == 1 then (finalI - 1) * finalSI * Exp((MM - 1) * log2) else Bot;
def finalTop = if ER == 1 then (finalI + 1) * finalSI * Exp((MM - 1) * log2) else Top;
#//-- determine the increment
def Increment = (finalTop - finalBot) / 8;
#//-- determine the absolute top
def absTop = if shift then -(finalBot - 3 * Increment) else finalTop + 3 * Increment;
#//-- create our Murrey line variables based on absolute top and the increment
def Plus38 = absTop;
def Plus28 = absTop - Increment;
def Plus18 = absTop - 2 * Increment;
def EightEight = absTop - 3 * Increment;
def SevenEight = absTop - 4 * Increment;
def SixEight = absTop - 5 * Increment;
def FiveEight = absTop - 6 * Increment;
def FourEight = absTop - 7 * Increment;
def ThreeEight = absTop - 8 * Increment;
def TwoEight = absTop - 9 * Increment;
def OneEight = absTop - 10 * Increment;
def ZeroEight = absTop - 11 * Increment;
def Minus18 = absTop - 12 * Increment;
def Minus28 = absTop - 13 * Increment;
def Minus38 = absTop - 14 * Increment;
#//-- plot the lines and we are done
plot P83 = if !ShowLines then na else Plus38; # "+3/8 Imminent Bearish reversal"
plot P82 = if !ShowLines then na else Plus28; # "+2/8 Extreme Overshoot conditions, can reverse anytime"
plot P81 = Plus18; # "+1/8 Overshoot conditions"
plot N88 = EightEight; # "8/8 Ultimate resistance, extremely overbought conditions"
plot N87 = SevenEight; # "7/8 Weak level, place to stop and reverse"
plot N86 = if !ShowLines then na else SixEight; # "6/8 Strong pivot reverse"
plot N85 = FiveEight; # "5/8 Top of trading range"
plot N84 = FourEight; # "4/8 Major support/resistance pivot point"
plot N83 = ThreeEight; # "3/8 Bottom of trading range"
plot N82 = if !ShowLines then na else TwoEight; # "2/8 Strong, Pivot, reverse"
plot N81 = OneEight; # "1/8 Weak, place to stop and reverse"
plot N80 = ZeroEight; # "0/8 Hardest line to fall below, oversold conditions"
plot M81 = Minus18; # "-1/8 Oversold conditions"
plot M82 = if !ShowLines then na else Minus28; # "-2/8 Extreme oversold conditions, can reverse anytime"
plot M83 = if !ShowLines then na else Minus38; # "-3/8 Imminent bullish reversal"
P81.SetDefaultColor(Color.DARK_RED);
P82.SetDefaultColor(Color.DARK_RED);
P83.SetDefaultColor(Color.DARK_RED);
M81.SetDefaultColor(Color.DARK_GREEN);
M82.SetDefaultColor(Color.DARK_GREEN);
M83.SetDefaultColor(Color.DARK_GREEN);
N80.SetDefaultColor(Color.GREEN);
N81.SetDefaultColor(Color.DARK_GREEN);
N82.SetDefaultColor(Color.DARK_GRAY);
N83.SetDefaultColor(Color.DARK_GRAY);
N84.SetDefaultColor(Color.GRAY);
N85.SetDefaultColor(Color.DARK_GRAY);
N86.SetDefaultColor(Color.DARK_GRAY);
N87.SetDefaultColor(Color.DARK_RED);
N88.SetDefaultColor(Color.RED);
P81.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
P82.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
P83.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
M81.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
M82.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
M83.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
N80.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
N81.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
N82.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
N83.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
N84.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
N85.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
N86.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
N87.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
N88.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
AddCloud(OneEight, Minus18, Color.DARK_GREEN); # "Oversold Zone"
AddCloud(FiveEight, ThreeEight, Color.DARK_GRAY); # "Balance Zone"
AddCloud(Plus18, SevenEight, Color.DARK_RED); # "Overbought Zone"
#--- END of CODE