MACD with Bollinger Bands Indicator for ThinkorSwim

I spent quite some time to tune this indicator for SPY daily chart, but the signals are not very good. It would be very appreciated if someone can share the parameters on this indicate for (SPX or SPY) daily chart.
Hi, @timing. I don't trade SPX or SPY but I do trade ES futures using this indicator. While the MACD BB is a personal favorite, I do NOT use it for signals. I use it help me interpret price movement.
 
Last edited by a moderator:
Does anyone understand how to convert this script so that a higher aggregation period can be used on a lower time frame? I've been told elsewhere online that this script references other scripts. I looked at the code and it appears it references the bollinger band and maybe the MACD(?). I copied those code inside this script and try to see if I could figure out how to do disambiguation, but I don't understand enough coding to understand how to remove the references so that the script can be made into a multi time frame script.
 
I would like to make a strategy base on this MACD-BB indicator to do backtesting.
  • When MACD is above zero and cross above BB upbound, take a long position; After entering a long posiiton, when MACD cross below mid-line of BB, exit the long position.

  • when MACD is below zero and cross below BB lowbound, take a short position; After entering a short position, when MACD cross above mid-lin of BB, exit the short position.
Do we already have code for this (or similar) strategy? I do not find one. Or would someone guide me on how to write strategy code?
 
Last edited:
I would like to make a strategy base on this MACD-BB indicator to do backtesting.
  • When MACD is above zero and cross above BB upbound, take a long position; After entering a long posiiton, when MACD cross below mid-line of BB, exit the long position.

  • when MACD is below zero and cross below BB lowbound, take a short position; After entering a short position, when MACD cross above mid-lin of BB, exit the short position.
Do we already have code for this (or similar) strategy? I do not find one. Or would someone guide me on how to write strategy code?
@BenTen : would you please help to make code for this strategy?
Thanks a lot!
 
@BenTen : would you please help to make code for this strategy?
Thanks a lot!

Research has shown that trending oscillators need to be tested with the following lookback periods (which are not available on the ToS app) to yield any viable results:
https://blog.quantinsti.com/backtes...d for backtesting,a reasonable amount of time.

Unless testing over the last 10 years, trending oscillators will indicate what you already know, that when the ticker is trending, trending oscillators show significant profit. When ranging, trending oscillators are rife with false signals.
Unfortunately, there is no way to know whether it will trend or range ahead of time.
 
Hello! I really like this indicator and all the updates made along the way. For further ease of use, keeping the entire code same, I have added Price Color - Green for Bullish, Red for Bearish and Gray for Neutral. Price Color can be turned on and off from Study parameters; default is set to No, make sure to set it to Yes if you want to see Price color.

Code:
# TS_MACD_BB

# By Eric Purdy, ThinkScripter LLC

# [URL]http://www.thinkscripter.com[/URL]

# [EMAIL][email protected][/EMAIL]

# Last Update 07 Feb 2011

# modification to color scheme by Rick_K 12/26/20.

# Added Price Color option by Prerak V. 05/15/2023.


declare lower;


input price = close;

input BBlength = 10;

input BBNum_Dev = 1.0;

input MACDfastLength = 12;

input MACDslowLength = 26;

input MACDLength = 5;

[B]input paintbars = No;[/B]

def MACD_Data = MACD(fastLength = MACDfastLength, slowLength = MACDslowLength, MACDLength = MACDLength);


plot MACD_Dots = MACD_Data;

plot MACD_Line = MACD_Data;


plot BB_Upper = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).UpperBand;

plot BB_Lower = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).Lowerband;

plot BB_Midline = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).MidLine;


BB_Upper.SetDefaultColor(Color.CYAN);

BB_Lower.SetDefaultColor(Color.CYAN);

#BB_Midline.SetDefaultColor(Color.GRAY);

#BB_Midline.SetStyle(Curve.SHORT_DASH);


#MACD_Line.AssignValueColor(if MACD_Line > MACD_Line[1] then color.green else color.red);

MACD_Line.AssignValueColor(if MACD_Line > MACD_Line[1] and MACD_Line >= BB_Upper then Color.GREEN else if MACD_Line < MACD_Line[1] and MACD_Line >= BB_Upper then Color.DARK_GREEN else if MACD_Line < MACD_Line[1] and MACD_Line <= BB_Lower then Color.RED else if MACD_Line > MACD_Line[1] and MACD_Line <= BB_Lower then Color.DARK_RED else Color.GRAY);

MACD_Line.SetLineWeight(1);


#MACD_Dots.AssignValueColor(if MACD_Line > MACD_Line[1] then Color.green else Color.RED);

MACD_Dots.AssignValueColor(if MACD_Line > MACD_Line[1] and MACD_Line > BB_Upper then Color.GREEN else if MACD_Line < MACD_Line[1] and MACD_Line > BB_Upper then Color.DARK_GREEN else if MACD_Line < MACD_Line[1] and MACD_Line < BB_Lower then Color.RED else if MACD_Line > MACD_Line[1] and MACD_Line < BB_Lower then Color.DARK_RED else Color.WHITE);

MACD_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);

MACD_Dots.SetLineWeight(2);


plot zero = 0;

zero.SetDefaultColor(Color.WHITE);

zero.SetStyle(Curve.SHORT_DASH);

zero.SetLineWeight(1);

[B]AssignPriceColor(if paintbars and MACD_Line > MACD_Line[1] and MACD_Line > BB_Upper then Color.GREEN else if paintbars and MACD_Line < MACD_Line[1] and MACD_Line > BB_Upper then Color.DARK_GREEN else if paintbars and MACD_Line < MACD_Line[1] and MACD_Line < BB_Lower then Color.RED else if paintbars and MACD_Line > MACD_Line[1] and MACD_Line < BB_Lower then Color.DARK_RED else Color.GRAY);[/B]

## end original (modified) code




######Add Squeeze Cloud##########


###### Keltner Channels


input displace = 0;

input factor = 1.5;

input length = 20;

input averageType = AverageType.EXPONENTIAL;

input trueRangeAverageType = AverageType.EXPONENTIAL;


def shift = factor * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);

def average = MovingAverage(averageType, price, length);

def Avg = average[-displace];

def Upper_Band = average[-displace] + shift[-displace];

def Lower_Band = average[-displace] - shift[-displace];


######## Bollinger Bands

input BBLength2 = 20;

input Num_Dev_Dn = -2.0;

input Num_Dev_up = 2.0;

input bb_averageType = AverageType.SIMPLE;


def sDev = StDev(data = price[-displace], length = BBLength2);


def MidLine = MovingAverage(bb_averageType, data = price[-displace], length = BBLength2);

def LowerBand = MidLine + Num_Dev_Dn * sDev;

def UpperBand = MidLine + Num_Dev_up * sDev;


### end of script

AddCloud(if UpperBand <= Upper_Band and LowerBand >= Lower_Band then BB_Upper else BB_Lower,  BB_Lower,  Color.yellow);


### END
 
Last edited by a moderator:
Thank you very much @BenTen for posting this and @Hypoluxa for sharing your strategy. It looks pretty solid.

I've been monkeying around with it today and became inspired. I'm generally a scalper, so I modified the color settings in the script a bit to guide me. Possibly it could help you or someone else here. It has a bit of a "don't diddle in the middle" vibe.

Edit: Since I posted this, I've made another addition. It is a cloud that displays when there is a standard bollinger/kelter squeeze (aka ttm_squeeze) going on. Just another confirm/deny layer. The new code is now displayed below but it is not displayed in the image shown.

View attachment 8844


Code:
# TS_MACD_BB

# By Eric Purdy, ThinkScripter LLC

# http://www.thinkscripter.com

# [email protected]

# Last Update 07 Feb 2011

# modification to color scheme by Rick_K 12/26/20.


declare lower;


input price = close;

input BBlength = 10;

input BBNum_Dev = 1.0;

input MACDfastLength = 12;

input MACDslowLength = 26;

input MACDLength = 5;


def MACD_Data = MACD(fastLength = MACDfastLength, slowLength = MACDslowLength, MACDLength = MACDLength);


plot MACD_Dots = MACD_Data;

plot MACD_Line = MACD_Data;


plot BB_Upper = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).UpperBand;

plot BB_Lower = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).Lowerband;

plot BB_Midline = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).MidLine;


BB_Upper.SetDefaultColor(Color.CYAN);

BB_Lower.SetDefaultColor(Color.CYAN);

#BB_Midline.SetDefaultColor(Color.GRAY);

#BB_Midline.SetStyle(Curve.SHORT_DASH);


#MACD_Line.AssignValueColor(if MACD_Line > MACD_Line[1] then color.green else color.red);

MACD_Line.AssignValueColor(if MACD_Line > MACD_Line[1] and MACD_Line >= BB_Upper then Color.GREEN else if MACD_Line < MACD_Line[1] and MACD_Line >= BB_Upper then Color.DARK_GREEN else if MACD_Line < MACD_Line[1] and MACD_Line <= BB_Lower then Color.RED else if MACD_Line > MACD_Line[1] and MACD_Line <= BB_Lower then Color.DARK_RED else Color.GRAY);

MACD_Line.SetLineWeight(1);


#MACD_Dots.AssignValueColor(if MACD_Line > MACD_Line[1] then Color.green else Color.RED);

MACD_Dots.AssignValueColor(if MACD_Line > MACD_Line[1] and MACD_Line > BB_Upper then Color.GREEN else if MACD_Line < MACD_Line[1] and MACD_Line > BB_Upper then Color.DARK_GREEN else if MACD_Line < MACD_Line[1] and MACD_Line < BB_Lower then Color.RED else if MACD_Line > MACD_Line[1] and MACD_Line < BB_Lower then Color.DARK_RED else Color.GRAY);

MACD_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);

MACD_Dots.SetLineWeight(2);


plot zero = 0;

zero.SetDefaultColor(Color.WHITE);

zero.SetStyle(Curve.SHORT_DASH);

zero.SetLineWeight(1);


## end original (modified) code




######Add Squeeze Cloud##########


###### Keltner Channels


input displace = 0;

input factor = 1.5;

input length = 20;

input averageType = AverageType.EXPONENTIAL;

input trueRangeAverageType = AverageType.EXPONENTIAL;


def shift = factor * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);

def average = MovingAverage(averageType, price, length);

def Avg = average[-displace];

def Upper_Band = average[-displace] + shift[-displace];

def Lower_Band = average[-displace] - shift[-displace];


######## Bollinger Bands

input BBLength2 = 20;

input Num_Dev_Dn = -2.0;

input Num_Dev_up = 2.0;

input bb_averageType = AverageType.SIMPLE;


def sDev = StDev(data = price[-displace], length = BBLength2);


def MidLine = MovingAverage(bb_averageType, data = price[-displace], length = BBLength2);

def LowerBand = MidLine + Num_Dev_Dn * sDev;

def UpperBand = MidLine + Num_Dev_up * sDev;


### end of script

AddCloud(if UpperBand <= Upper_Band and LowerBand >= Lower_Band then BB_Upper else BB_Lower,  BB_Lower,  Color.yellow);


### END
Great work on on this one! Can you please work on adding the Average Line of the MACD?
 
is there a way to duplicate your setup in my TOS?
Did you know that by clicking on a member's name, you can easily check when they were last seen on the uTS forum? It's a great way to keep track of who's been around recently, and who hasn't. Speaking of which, it looks like @salehz94 is no longer active. :(
 
Good Morning UTS Community,

I am testing out a strategy by @Hypoluxa and interested in one of the lower studies named TS MACD BB. I would like to be able to scan with it when it crosses above or below the zero line. Here is the code below.

Code:
# TS_MACD_BB

# By Eric Purdy, ThinkScripter LLC

# http://www.thinkscripter.com

# [email protected]

# Last Update 07 Feb 2011

# https://usethinkscript.com/threads/macd-with-bollinger-bands-bb-indicator-for-thinkorswim.287/post-1632



declare lower;



input price = close;

input BBlength = 10;

input BBNum_Dev = 1.0;

input MACDfastLength = 12;

input MACDslowLength = 26;

input MACDLength = 5;



def MACD_Data = MACD(fastLength = MACDfastLength, slowLength = MACDslowLength, MACDLength = MACDLength);



plot MACD_Dots = MACD_Data;

plot MACD_Line = MACD_Data;



plot BB_Upper = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).UpperBand;

plot BB_Lower = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).Lowerband;

plot BB_Midline = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).MidLine;



BB_Upper.SetDefaultColor(Color.GRAY);

BB_Lower.SetDefaultColor(Color.GRAY);

BB_Midline.SetDefaultColor(Color.GRAY);

BB_Midline.SetStyle(Curve.SHORT_DASH);



#MACD_Line.SetDefaultColor(Color.WHITE);



#MACD_Dots.SetStyle(Curve.POINTS);

#MACD_Dots.SetLineWeight(2);

#MACD_Dots.AssignValueColor(if MACD_Line > MACD_Line[1] then Color.White else Color.DARK_RED);



MACD_Line.AssignValueColor(if MACD_Line > MACD_Line[1] and MACD_Line >= BB_Upper then Color.GREEN else if MACD_Line < MACD_Line[1] and MACD_Line >= BB_Upper then Color.DARK_GREEN else if MACD_Line < MACD_Line[1] and MACD_Line <= BB_Lower then Color.RED else if MACD_Line > MACD_Line[1] and MACD_Line <= BB_Lower then Color.DARK_RED else Color.GRAY);

MACD_Line.SetLineWeight(1);



MACD_Dots.AssignValueColor(if MACD_Line > MACD_Line[1] and MACD_Line > BB_Upper then Color.GREEN else if MACD_Line < MACD_Line[1] and MACD_Line > BB_Upper then Color.DARK_GREEN else if MACD_Line < MACD_Line[1] and MACD_Line < BB_Lower then Color.RED else if MACD_Line > MACD_Line[1] and MACD_Line < BB_Lower then Color.DARK_RED else Color.GRAY);

MACD_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);

MACD_Dots.SetLineWeight(2);



plot zero = 0;

zero.AssignValueColor(if MACD_Line < 0 then Color.RED else Color.GREEN);

zero.SetLineWeight(2);
 
one of the lower studies named TS MACD BB. I would like to be able to scan with it when it crosses above or below the zero line. Here is the code below.

You did not identify what "it", you want to scan for.
If you are asking to scan for when MACD crosses zero.

MACD is already built-in, you don't need a custom study.
Select MACD in the scanner
change the settings to:
MACDfastLength = 12;
MACDslowLength = 26;
MACDLength = 5;

The scan condition is:
MACD crosses above 0

Here is a scan tutorial:
https://usethinkscript.com/threads/how-to-use-thinkorswim-stock-hacker-scans.284/
 
I'm sorry let me resay what I meant to say correctly how about when the MACD is at the zero line. How would I be able to scan for that.

Zero is true within 1 or 2 bars?
 
@yellowlogic I use this macd for arrows. You can use this macd script or use macd BB and use this script just for arrows but turn off all indicators. Hope this helps
Ruby:
#converted from mobisu macd to ppo
# this is actually macd and sqz indicator in one
# added pivots

declare lower;

input fastPeriod = 12; #9/18/6 for 5m
input slowPeriod = 26;
input signalPeriod = 9;
input price = close;
input show = yes;
input agg1 = AggregationPeriod.FIVE_MIN;

def fastEma = ExpAverage( price, fastPeriod );
def slowEma = ExpAverage( price, slowPeriod );
def periodOK = fastPeriod < slowPeriod;
AddLabel( !periodOK, "ERROR: fastPeriod MUST be less than slowPeriod" );
def _ppo = if periodOK then ((fastEma - slowEma) / slowEma) * 100 else 0;
def _signal = ExpAverage( _ppo, signalPeriod );

# generic plots wiht colors
plot pmain = _ppo;
pmain.SetDefaultColor( Color.BLUE );
pmain.SetLineWeight(2);
pmain.AssignValueColor(if pmain < 0 and pmain < pmain[1] then Color.RED
else if pmain < 0 and pmain > pmain[1] then Color.DARK_GREEN
else if pmain > 0 and pmain > pmain[1] then Color.GREEN
else Color.DARK_RED);
pmain.HideBubble();

plot mainEma = _signal;
mainEma.SetDefaultColor( Color.RED );
mainEma.HideBubble();
AddCloud(pmain, mainEma, Color.Green, Color.RED);

#diff as histogram
plot diff = _ppo - _signal;
diff.SetDefaultColor(GetColor(5));
diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
diff.SetLineWeight(3);
diff.DefineColor("Positive and Up", Color.GREEN);
diff.DefineColor("Positive and Down", Color.DARK_GREEN);
diff.DefineColor("Negative and Down", Color.RED);
diff.DefineColor("Negative and Up", Color.DARK_RED);
diff.AssignValueColor(if diff >= 0 then if diff > diff[1] then diff.Color("Positive and Up") else diff.Color("Positive and Down") else if diff < diff[1] then diff.Color("Negative and Down") else diff.Color("Negative and Up"));

#mobius divergence calc
def pmainh = CompoundValue(1,
if pmain < 0 then Double.NaN
else if pmain crosses above 0 then pmain
else if pmain > 0 and pmain > pmainh[1]
then pmain else pmainh[1], 0);

def Valueh = CompoundValue(1,
if pmain < 0 then Double.NaN
else if pmain crosses above 0 then high
else if pmain > 0 and high > Valueh[1] then high
else Valueh[1], 0);

plot divLowSignal = if pmain > 0 and high > Valueh[1] and pmain < pmainh[1] then 0
else Double.NaN;
divLowSignal.SetPaintingStrategy(PaintingStrategy.SQUARES);
divLowSignal.SetLineWeight(5);
divLowSignal.SetDefaultColor(Color.dark_orange);

def pmainL = CompoundValue(1, if pmain > 0 then Double.NaN
else if pmain crosses below 0 then pmain
else if pmain < 0 and pmain < pmainl[1] then pmain
else pmainl[1], 0);

def ValueL = CompoundValue(1, if pmain > 0 then Double.NaN
else if pmain crosses below 0 then low
else if pmain < 0 and low < Valuel[1] then low
else Valuel[1], 0);

plot divUpSignall = if pmain < 0 and low < Valuel[1] and pmain > pmainl[1] then 0
else Double.NaN;
divupSignall.SetPaintingStrategy(PaintingStrategy.SQUARES);
divUpSignall.SetLineWeight(5);
divUPSignall.SetDefaultColor(Color.blue);

#zeroline

plot zeroLine = 0;
zeroLine.SetPaintingStrategy(PaintingStrategy.LINE);
zeroLine.SetLineWeight(1);
zeroLine.SetDefaultColor(Color.Gray);

#pivots

def ptrend = pmain;
def prange = 2;
def pivotHigh = if IsNaN(ptrend[-1]) then 0 else Lowest(ptrend, prange)[1] > ptrend and Lowest(ptrend, prange)[-prange] > ptrend ;
def pivotLow = if IsNaN(ptrend[-1]) then 0 else Highest(ptrend, prange)[1] < ptrend and Highest(ptrend, prange)[-prange] < ptrend ;
#study
plot plotPH = if pivotHigh and show then ptrend else Double.NaN;
plotPH.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
plotPH.SetDefaultColor(Color.GREEN);

plot phline = if pivotHigh then pmain else Double.NaN;
phline.SetDefaultColor(Color.DARK_GREEN);
phline.EnableApproximation();phline.Hide();
#
plot plotPL = if pivotLow and show then ptrend else Double.NaN;
plotPL.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
plotPL.SetDefaultColor(Color.RED);

plot plline = if pivotLow then pmain else Double.NaN;
plline.SetDefaultColor(Color.RED);
plline.EnableApproximation(); plline.hide();

Wow this is very accurate arrow signals by any chance does this repaint?

I would love to be able to scan for the arrow confirmations if possible.
 
Thanks @MerryDay I'll test it out to see if I can get it to work. Based on my knowledge the pivot highs and lows would repaint if I was even able to scan with it.

Other than that the MACDBB is a game changer, holy cow. You guys are awesome!
The script you referenced is different from other pivot repainters.
With other pivot scripts, it is expected for pivots to repaint when the pivot point is broken through, allowing new support / resistance points to be created.

But with the script you referenced, uses future bars.
Meaning, it waits until the future to confirm the pivot happened and then goes back in time and repaints the pivot at the point it happened.

In answer to your question: yes, it repaints and it lags.
Which means the scanner filter in the above post had to be modified.

The scanner is set to look for pivots on the current candle, but in actuality they can be repainted much further back.

So the scan filter needs to be re-written:
plotPH is true within 10 bars
this will only find pivots repainted within the last 10 bars.
 
One of my favorite indicators as of yet. Can someone please help me with a watchlist for the zero line?

I guess I mean the zero line with the Bollinger Band 0 Line

Here is a screenshot of the Zero Line with the arrow pointing up and the column on the left of -10,0,10. I was wondering if I could get a watchlist collumn for the left column indicators.
Phoenix.png


One of my favorite indicators as of yet. Can someone please help me with a watchlist for the zero line?

I guess I mean the zero line with the Bollinger Band 0 Line

Here is a screenshot of the Zero Line with the arrow pointing up and the column on the left of -10,0,10. I was wondering if I could get a watchlist collumn for the left column indicators.
Phoenix.png

Is something like this possible to do on a column watchlist or no?
 

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
336 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