Normalized MACD for ThinkorSwim

tomsk

Well-known member
VIP

Normalized MACD Example Study

There was some discussion in one of the sub forums regarding how to normalize plots. Rather than post it there, thought it might make it easier for future searches to find it here. Based on a normalizePlot function Mobius wrote several years ago, you can use that to normalize plots to whatever scale you like, e.g. 0 to 100, -100 to 100, etc.

Here is an example on how to normalize the MACD on a scale from -100 to 100.

First determine what data you're going to plot. In the example below I have chosen to plot the MACDAvg line. Place all the code into a script() routine, in my example I call this MACDScr(). Then run this through Mobius normalizePlot function and slap on whatever lipstick you need

Code:
# Normalized MACD
# tomsk
# 11.16.2019

declare lower;

input fastLength = 12;
input slowLength = 26;
input MACDLength = 9;
input OverBought = 80;
input OverSold = -80;

script normalizePlot {
    input data = close;
    input newRngMin =  -1;
    input newRngMax = 1;
    def hhData = HighestAll( data );
    def llData = LowestAll( data );
    plot nr = ((( newRngMax - newRngMin ) * ( data - llData )) / ( hhData - llData )) + newRngMin;
}

script MACDScr {
   input fastLength = 13;
   input slowLength = 21;
   input MACDLength  =  8;
   input data = close;
   def Value = ExpAverage(data, fastLength) - ExpAverage(data, slowLength);
   plot MACDAvg  = ExpAverage(Value, MACDLength);
}

plot MACDX = normalizePlot(MACDScr("fastLength" = fastLength, "slowLength" = slowLength, "MACDLength" = MACDLength, "data" = close), -100, 100);

plot OS = if !isNaN(close) then OverSold else Double.NaN;
OS.SetPaintingStrategy(PaintingStrategy.Line);
OS.SetLineWeight(2);
OS.SetDefaultColor(Color.Cyan);

plot OB = if !IsNaN(close) then OverBought else Double.NaN;
OB.SetPaintingStrategy(PaintingStrategy.Line);
OB.SetLineWeight(2);
OB.SetDefaultColor(Color.Cyan);

plot MID = if !isNaN(close) then 0 else Double.NaN;
MID.SetPaintingStrategy(PaintingStrategy.Dashes);
MID.SetLineWeight(2);
MID.SetDefaultColor(Color.Orange);

MACDX.SetPaintingStrategy(PaintingStrategy.Line);
MACDX.SetLineWeight(1);
MACDX.AssignValueColor(if MACDX >= 50 then if MACDX > MACDX[1] then Color.Light_Green else Color.Light_Red else if MACDX < MACDX[1] then Color.Light_Red else Color.Light_Green);
AddCloud(MACDX, MID, Color.Light_Green, Color.Light_Red);
# End Normalized MACD
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Can someone add an arrow to when script changes from green to red and vice versa. Thank you

Code:
# Normalized MACD
# tomsk
# 11.16.2019

declare lower;

input fastLength = 12;
input slowLength = 26;
input MACDLength = 9;
input OverBought = 80;
input OverSold = -80;

script normalizePlot {
    input data = close;
    input newRngMin =  -1;
    input newRngMax = 1;
    def hhData = HighestAll( data );
    def llData = LowestAll( data );
    plot nr = ((( newRngMax - newRngMin ) * ( data - llData )) / ( hhData - llData )) + newRngMin;
}

script MACDScr {
   input fastLength = 13;
   input slowLength = 21;
   input MACDLength  =  8;
   input data = close;
   def Value = ExpAverage(data, fastLength) - ExpAverage(data, slowLength);
   plot MACDAvg  = ExpAverage(Value, MACDLength);
}

plot MACDX = normalizePlot(MACDScr("fastLength" = fastLength, "slowLength" = slowLength, "MACDLength" = MACDLength, "data" = close), -100, 100);

plot OS = if !isNaN(close) then OverSold else Double.NaN;
OS.SetPaintingStrategy(PaintingStrategy.Line);
OS.SetLineWeight(2);
OS.SetDefaultColor(Color.Cyan);

plot OB = if !IsNaN(close) then OverBought else Double.NaN;
OB.SetPaintingStrategy(PaintingStrategy.Line);
OB.SetLineWeight(2);
OB.SetDefaultColor(Color.Cyan);

plot MID = if !isNaN(close) then 0 else Double.NaN;
MID.SetPaintingStrategy(PaintingStrategy.Dashes);
MID.SetLineWeight(2);
MID.SetDefaultColor(Color.Orange);

MACDX.SetPaintingStrategy(PaintingStrategy.Line);
MACDX.SetLineWeight(1);
MACDX.AssignValueColor(if MACDX >= 50 then if MACDX > MACDX[1] then Color.Light_Green else Color.Light_Red else if MACDX < MACDX[1] then Color.Light_Red else Color.Light_Green);
AddCloud(MACDX, MID, Color.Light_Green, Color.Light_Red);
# End Normalized MACD
 
Hello I was wondering if you know if anyone can convert this pinescript Normalized MACD to thinkscript? It has 2 lines instead of one and I've found it useful paired up with the RSI on tradingview. Thanks!
 
Last edited by a moderator:
Hello I was wondering if you know if anyone can convert this pinescript Normalized MACD to thinkscript? It looks different than the one on this post. It has 2 lines instead of one and I've found it useful paired up with the RSI on tradingview. Thanks!
@BenTen

here is my attempt at converting that pine study
it shows a histogram and 2 lines

Ruby:
# macd_normalized_2line_00

declare lower;
def na = double.nan;

#study("Normalized MACD",shorttitle='N MACD')

#sma = input(12,title='Fast MA')
input sma = 12;

#lma = input(21,title='Slow MA')
input lma = 21;

#tsp = input(9,title='Trigger')
input tsp = 9;

#np = input(50,title='Normalize')
input np = 50;

#h=input(true,title='Histogram')
input histo = yes;

#docol = input(false,title="Color Change")
input do_color = no;

#dofill=input(false,title="Fill")
input do_fill = no;

# -------------------------------
# pick avg type
# type = input(1,minval=1,maxval=3,title="1=Ema, 2=Wma, 3=Sma")

#sh = type == 1 ? ema(close,sma)
#: type == 2 ? wma(close, sma)
#: sma(close, sma)

#lon=type == 1 ? ema(close,lma)
#: type == 2 ? wma(close, lma)
#: sma(close, lma)

input avg_type =  AverageType.EXPONENTIAL;
def sh = MovingAverage(avg_type, close, sma);
def lon = MovingAverage(avg_type, close, lma);
# -------------------------------

#ratio = min(sh,lon)/max(sh,lon)
def ratio = min(sh,lon)/max(sh,lon);

# Mac = (iff(sh>lon,2-ratio,ratio)-1)
def Mac = if(sh > lon, 2-ratio, ratio)-1;

#MacNorm = ((Mac-lowest(Mac, np)) /(highest(Mac, np)-lowest(Mac, np)+.000001)*2)- 1
def MacNorm = ((Mac-lowest(Mac, np)) /(highest(Mac, np)-lowest(Mac, np)+.000001)*2)- 1;

#MacNorm2 = iff(np<2,Mac,MacNorm)
def MacNorm2 = if(np < 2, Mac, MacNorm);

#Trigger = wma(MacNorm2, tsp)
def Trigger = wma(MacNorm2, tsp);

#Hist = (MacNorm2-Trigger)
def Hist = (MacNorm2-Trigger);

#Hist2 = Hist>1?1:Hist<-1?-1:Hist
def Hist2 = if Hist > 1 then 1 else if Hist < -1 then -1 else Hist;

#swap=Hist2>Hist2[1]?green:red
#def swap = if Hist2 > Hist2[1] then green else red;

#swap2 = docol ? MacNorm2 > MacNorm2[1] ? #0094FF : #FF006E : red
#def swap2 = if docol then if MacNorm2 > MacNorm2[1] then 0094FF else FF006E else red;


#plot(h?Hist2:na,color=swap,style=columns,title='Hist',histbase=0)
plot z1 = if histo then Hist2 else na;
z1.SetPaintingStrategy(PaintingStrategy.histogram);
z1.AssignValueColor(if Hist2 > Hist2[1] then color.green else color.red);


#plot(MacNorm2,color=swap2,title='MacNorm')
plot z2 = MacNorm2;
z2.AssignValueColor(if do_color then if MacNorm2 > MacNorm2[1] then color.blue else color.light_red else color.red);
# 0094FF - blue
# FF006E - pink/red


#plot(dofill?MacNorm2:na,color=MacNorm2>0?green:red,style=columns)
plot z3 = if do_fill then MacNorm2 else na;
z3.AssignValueColor( if MacNorm2 > 0 then color.green else color.red);


#plot(Trigger,color=yellow,title='Trigger')
plot z4 = Trigger;
z4.SetDefaultColor(Color.yellow);


#hline(0)
plot z = 0;
z.SetDefaultColor(Color.GRAY);

#
 
I want to know when Z2 > Z4 and theyre down between -.8 and -1 and then the reverse when theyre crossed to downside and redlining btwn +.8 and +1... when these Z values are maxed out is when a reversal will happen. Im trying to add them to a study and have hit a wall

Ive tried types of combinations and it will NOT produce a true result on a chart

def test = z2 > z4 and Z2<(0-.8) and z4<(0-.8);

def test1 = z2 < z4 and Z2>.8 and z4>.8);

Suggestions?
 
I want to know when Z2 > Z4 and theyre down between -.8 and -1 and then the reverse when theyre crossed to downside and redlining btwn +.8 and +1... when these Z values are maxed out is when a reversal will happen. Im trying to add them to a study and have hit a wall

Ive tried types of combinations and it will NOT produce a true result on a chart

def test = z2 > z4 and Z2<(0-.8) and z4<(0-.8);

def test1 = z2 < z4 and Z2>.8 and z4>.8);

Suggestions?
Mobius solved it:

Add these lines of code to the bottom of your study:
Code:
plot cond_1 = if(z2 > z4 and between(z2, -1, -.8), z2, double.nan);
cond_1.SetStyle(Curve.Points);
cond_1.SetLineWeight(3);
cond_1.SetDefaultColor(Color.Cyan);
plot cond_2 = if(z2 < z4 and between(z2, .8, 1), z2, double.nan);
cond_2.SetStyle(Curve.Points);
cond_2.SetLineWeight(3);
cond_2.SetDefaultColor(Color.Pink);
Alert(cond_1, "Low reversal", Alert.Bar, Sound.Ring);
Alert(cond_2, "High reversal", Alert.Bar, Sound.Chimes);
 
Resurrecting an old thread.
I am trying to use a Normalized MACD in a watchlist.
When I set the timeframe of the watchlist to “Day” the normalization is calculated across 1 year.
If I set the watchlist timeframe to 4 hours, the normalization defaults to 180 days.
Is there any way to adjust the watchlist script so that I can stay on the daily timeframe but have the normalization only calculate across….say…..6 months? Or maybe 3 months?
Thx
 
Resurrecting an old thread.
I am trying to use a Normalized MACD in a watchlist.
When I set the timeframe of the watchlist to “Day” the normalization is calculated across 1 year.
If I set the watchlist timeframe to 4 hours, the normalization defaults to 180 days.
Is there any way to adjust the watchlist script so that I can stay on the daily timeframe but have the normalization only calculate across….say…..6 months? Or maybe 3 months?
Thx

try replacing these 2 lines,
def hhData = HighestAll( data );
def llData = LowestAll( data );

with highest(close, len)
and lowest(close, len),
with a desired len number.

there are about 252 days in a year, so calculate a length number from,
252/2 for 6 months,
or 252/4 for 3 months.
 
I like the signals from NMACD but the flatlining drives me nuts... Ive built signals for those zones but IMO when Z2/Z4 lines gets to ±.7/-.7 to 1/-1 its hard to gauge.

Does anyone use anything that produces the same signals but the oscillator wont flatline?
 
I like the signals from NMACD but the flatlining drives me nuts... Ive built signals for those zones but IMO when Z2/Z4 lines gets to ±.7/-.7 to 1/-1 its hard to gauge.

Does anyone use anything that produces the same signals but the oscillator wont flatline?
I know what you mean but unfortunately I don't think there's a version that doesn't flatline. Maybe increase the extremes in the code?
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
496 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top