Bollinger OTT Spread For ThinkOrSwim

sunnybabu

Member
Plus
The author states: Bollinger OTT Spread (BOOTS) is a development combining Bollinger Bands with Optimized Trend Tracker (OTT) Indicator by Anıl Özekşi.

Bollinger Bands have originally 3 lines: Simple Moving Average (Middle Line), Upper Band and Lower Band.

BOOTS concentrates on the upper and lower Bollinger band lines.
First, it calculates the OTT using the UPPER and LOWER Bollinger Bands in a period of time (default lengths are 2) instead of closing prices.
After that, Upper and lower bands have more constant values.

There are 2 lines in BOOTS:
-The top (cyan) line is originally an OTT of the Upper Bollinger Band. (BOOTShigh)
-The bottom line (purple) is also an OTT line but conversely uses Lower Bollinger Band in the same period. (BOOTSlow)

Default values:
Bollinger Bands Moving AveragePeriod: 2 Bars
OTT Length: 2 Bars
OTT Optimizing coefficient (percent): %10
Bollinger Bands Standart Deviation Multiplier: 2 (not adjustable)
These values are designed for daily time frame, so they have to be optimized in other timeframes by the user. (Ex: Higher values can be considered in lower time frames)

Originally, Bollinger Bands used a Simple Moving Average in their calculation, but this time, Anıl Özekşi prefers VIDYA (Variable Dynamic Moving Average = VAR) instead of a Simple Moving Average.

Bollinger Bands cannot create significant BUY & SELL signals considering their original logic, but the primary purpose of BOOTS is to have substantial trading signals:

BUY when the price crosses above the BOOTSLower line (purple line)
STOP when the price crosses back below the BOOTSLower line (purple line)

SELL when the price crosses below the BOOTSUpper line (cyan line)
STOP when the price crosses back above the BOOTSUpper line (cyan line)

The price zone between the two lines is the flat zone; traders don't consider taking new positions in that area between the two lines.

Developer Anıl Özekşi advises that traders may have more accurate signals when using a short-period moving average instead of closing prices. So, I added a moving average with the same default length of 2 , which was used in Bollinger Bands calculation. You can check the "SHOW MOVING AVERAGE?" box on the settings tab of the indicator.

4fz3av5.png


original Tradingview code:
https://www.tradingview.com/script/hynBgzIQ/
New ThinkOrSwim code can be found in the next post
 
Last edited by a moderator:

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

check the below:

CSS:
#// Indicator for TOS
# https://usethinkscript.com/threads/bollinger-ott-spread-for-thinkorswim.19603/
#// © KivancOzbilgic
#//developer: ANIL ÖZEKŞİ
#//author: @kivancozbilgic
#indicator('Bollinger OTT Spread','BOOTS', overlay=true)
# Converted by Sam4Cok@Samer800    - 09/2024
declare upper;
input timeframe = AggregationPeriod.MIN;
input MovAvgType = {default VAR, SMA, EMA, WMA, DEMA, TMA, WWMA, ZLEMA, TSF, HULL};
input Source    = FundamentalType.CLOSE;#(close, title="Source")
input bbLength = 2; #,'Bollinger Bands MA Period', minval=1)
input bbMulti = 2.0;
input OttLength = 2;        # OTT Period
input OttPercent  = 2.0;      # OTT Optimization Coeff
input showSupportLine = no; # "Show Support Line?"
input ColorOttLine = no;    #="Show OTT Color Changes?"

def na = Double.NaN;
def current = GetAggregationPeriod();
def tf = Max(current, timeframe);
def c = Fundamental(Source, Period = tf);
############## theme 3########################################
DefineGlobalColor("Sky1" , Color.CYAN);  # >=90
DefineGlobalColor("Sky2" , CreateColor(0,137,137));  # >=80
DefineGlobalColor("Magenta1" , Color.MAGENTA);  # >=40
DefineGlobalColor("Magenta2" , Color.PLUM);  # >=30

#Var_Func(src, length) =>
script Var_Func {
    input src    = close;
    input length = 0;
    def valpha = 2 / (length + 1);
    def vud1 = if src > src[1] then src - src[1] else 0;
    def vdd1 = if src < src[1] then src[1] - src else 0;
    def vUD = Sum(vud1, 9);
    def vDD = Sum(vdd1, 9);
    def vCMO = ((vUD - vDD) / (vUD + vDD));
    def VAR;
    VAR = CompoundValue(1, valpha * AbsValue(vCMO) * src + (1 - valpha * AbsValue(vCMO)) * (VAR[1]), src);
    plot result = VAR;
}
#Wwma_Func(src, length) =>
script Wwma_Func {
    input src = close;
    input length = 0;
    def wwalpha = 1 / length;
    def WWMA;
    WWMA = wwalpha * src + (1 - wwalpha) * (WWMA[1]);
    plot return = WWMA;
}
#Zlema_Func(src, length) =>
script Zlema_Func {
    input src = close;
    input length = 0;
    def zxLag = if length / 2 == Round(length / 2) then length / 2 else (length - 1) / 2;
    def zxEMAData = src + src - src[zxLag];
    def ZLEMA = ExpAverage(zxEMAData, length);
    plot return = ZLEMA;
}
#Tsf_Func(src, length) =>
script Tsf_Func {
    input src = close;
    input length = 0;
    def lrc = Inertia(src, length);
    def lrc1 = Inertia(src[1], length);
    def lrs = lrc - lrc1;
    def TSF = Inertia(src, length) + lrs;
    plot retur = TSF;
}
#Var_Funcl(srcl, length) =>
script Var_Funcl {
    input srcl = close;
    input length = 0;
    def valphal = 2 / (length + 1);
    def vud1l = if srcl > srcl[1] then srcl - srcl[1] else 0;
    def vdd1l = if srcl < srcl[1] then srcl[1] - srcl else 0;
    def vUDl = Sum(vud1l, 9);
    def vDDl = Sum(vdd1l, 9);
    def vCMOl = ((vUDl - vDDl) / (vUDl + vDDl));
    def VARl;
    VARl = CompoundValue(1, (valphal * AbsValue(vCMOl) * srcl) + (1 - valphal * AbsValue(vCMOl)) * (VARl[1]), srcl);
    plot return = VARl;
}
#Wwma_Funcl(srcl, length) =>
script Wwma_Funcl {
    input srcl = close;
    input length = 0;
    def wwalpha = 1 / length;
    def WWMA;
    WWMA = CompoundValue(1, wwalpha * srcl + (1 - wwalpha) * (WWMA[1]), srcl);
    plot return = WWMA;
}
#Zlema_Funcl(srcl, length) =>
script Zlema_Funcl {
    input srcl = close;
    input length = 0;
    def zxLag = if length / 2 == Round(length / 2,0) then length / 2 else (length - 1) / 2;
    def zxEMAData = srcl + srcl - srcl[zxLag];
    def ZLEMA = ExpAverage(zxEMAData, length);
    plot return = ZLEMA;
}
#Tsf_Funcl(srcl, length) =>
script Tsf_Funcl {
    input srcl = close;
    input length = 0;
    def lrc = Inertia(srcl, length);
    def lrc1 = Inertia(srcl[1], length);
    def lrs = lrc - lrc1;
    def TSF = Inertia(srcl, length) + lrs;
    plot retur = TSF;
}
#getMA(src, length, type) =>
script getMA {
    input src = close;
    input length = 100;
    input type   = "SMA";
    def ma;
    ma = if type == "SMA" then Average(src, length) else
     if type == "EMA" then ExpAverage(src, length) else
     if type == "WMA" then WMA(src, length) else
     if type == "DEMA" then DEMA(src, length) else
     if type == "TMA" then Average(Average(src, Ceil(length / 2)), Floor(length / 2) + 1) else
     if type == "VAR" then Var_Func(src, length) else
     if type == "WWMA" then WWMA_Func(src, length) else
     if type == "ZLEMA" then Zlema_Func(src, length) else
     if type == "TSF" then Tsf_Func(src, length) else
     if type == "HULL" then HullMovingAvg(src, length) else Double.NaN;
    plot result = ma;
}
#OTT(Source, percent) =>
script OTT {
    input Source    = close;
    input percent   = 0;
    def fark = Source * percent * 0.01;
    def UP = Source + fark;
    def LW = Source - fark;
    def UP_Band = if ((UP < UP_Band[1]) or (Source[1] > UP_Band[1])) then UP else UP_Band[1];
    def LW_Band = if ((LW > LW_Band[1]) or (Source[1] < LW_Band[1])) then LW else LW_Band[1];
    def MT = if ((MT[1] == UP_Band[1]) and (Source < UP_Band)) then UP_Band
        else if ((MT[1] == UP_Band[1]) and (Source > UP_Band)) then LW_Band
        else if ((MT[1] == LW_Band[1]) and (Source > LW_Band)) then LW_Band
        else if ((MT[1] == LW_Band)    and (Source < LW_Band)) then UP_Band
        else LW_Band;
    plot return = MT;
}
def basis = getMA(c, bbLength, MovAvgType);
def dev = bbMulti * stdev(c, bbLength);
def upper = basis + dev;
def lower = basis - dev;
def MAvg = getMA(upper, OttLength, MovAvgType);
def MAvg1 = getMA(lower, OttLength, MovAvgType);
def MT   = OTT(MAvg, OttPercent);
def MT1   = OTT(MAvg1, OttPercent);
def OTT = if MAvg > MT then MT * (200 + OttPercent) / 200 else MT * (200 - OttPercent) / 200;
def OTT1 = if MAvg1 > MT1 then MT1 * (200 + OttPercent) / 200 else MT1 * (200 - OttPercent) / 200;

plot SupportLine = if(!showSupportLine,na, MAvg);    # "Support Line"
SupportLine.SetDefaultColor(CreateColor(5,133,225));
plot SupportLine1 = if(!showSupportLine,na, MAvg1);    # "Support Line"
SupportLine1.SetDefaultColor(Color.RED);

def OTTC = if OTT[2] > OTT[3] then 2 else
           if OTT[2] < OTT[3] then -2 else
           if OTT[2] == OTT[3] and  MAvg>OTT[2] then 1 else
           if OTT[2] == OTT[3] and  MAvg<OTT[2] then -1 else 0;
def OTTC1 = if OTT1[2] > OTT1[3] then 2 else
            if OTT1[2] < OTT1[3] then -2 else
            if OTT1[2] == OTT1[3] and  MAvg1>OTT1[2] then 1 else
            if OTT1[2] == OTT1[3] and  MAvg1<OTT1[2] then -1 else 0;

plot OttLine  = if(isNaN(c),na,OTT);             # "OTT LINE"
OttLine.SetHiding(yes);
plot OttLine1 = if(isNaN(c),na,OTT[1]);          # "OTT LINE"
OttLine1.SetHiding(yes);
plot OttLine2 = if(isNaN(c),na,OTT[2]);          # "OTT LINE"
#OttLine2.SetHiding(yes);
plot OttLine01  = if(isNaN(c),na,OTT1);             # "OTT LINE"
OttLine01.SetHiding(yes);
plot OttLine11 = if(isNaN(c),na,OTT1[1]);          # "OTT LINE"
OttLine11.SetHiding(yes);
plot OttLine21 = if(isNaN(c),na,OTT1[2]);          # "OTT LINE"
#OttLine2.SetHiding(yes);

OttLine2.SetLineWeight(2);
OttLine2.AssignValueColor(if !ColorOttLine then Color.CYAN else
                          if OTTC==2 then GlobalColor("Sky1") else
                          if OTTC==1 then GlobalColor("Sky2") else
                          if OTTC==-2 then GlobalColor("Magenta1") else
                          if OTTC==-1 then GlobalColor("Magenta2") else Color.GRAY);
OttLine21.SetLineWeight(2);
OttLine21.AssignValueColor(if !ColorOttLine then Color.MAGENTA else
                          if OTTC1==2 then GlobalColor("Sky1") else
                          if OTTC1==1 then GlobalColor("Sky2") else
                          if OTTC1==-2 then GlobalColor("Magenta1") else
                          if OTTC1==-1 then GlobalColor("Magenta2") else Color.GRAY);


### END of CODE
 
Last edited by a moderator:
The author states: Bollinger OTT Spread (BOOTS) is a development combining Bollinger Bands with Optimized Trend Tracker (OTT) Indicator by Anıl Özekşi.

Bollinger Bands have originally 3 lines: Simple Moving Average (Middle Line), Upper Band and Lower Band.

BOOTS concentrates on the upper and lower Bollinger band lines.
First, it calculates the OTT using the UPPER and LOWER Bollinger Bands in a period of time (default lengths are 2) instead of closing prices.
After that, Upper and lower bands have more constant values.

There are 2 lines in BOOTS:
-The top (cyan) line is originally an OTT of the Upper Bollinger Band. (BOOTShigh)
-The bottom line (purple) is also an OTT line but conversely uses Lower Bollinger Band in the same period. (BOOTSlow)

Default values:
Bollinger Bands Moving AveragePeriod: 2 Bars
OTT Length: 2 Bars
OTT Optimizing coefficient (percent): %10
Bollinger Bands Standart Deviation Multiplier: 2 (not adjustable)
These values are designed for daily time frame, so they have to be optimized in other timeframes by the user. (Ex: Higher values can be considered in lower time frames)

Originally, Bollinger Bands used a Simple Moving Average in their calculation, but this time, Anıl Özekşi prefers VIDYA (Variable Dynamic Moving Average = VAR) instead of a Simple Moving Average.

Bollinger Bands cannot create significant BUY & SELL signals considering their original logic, but the primary purpose of BOOTS is to have substantial trading signals:

BUY when the price crosses above the BOOTSLower line (purple line)
STOP when the price crosses back below the BOOTSLower line (purple line)

SELL when the price crosses below the BOOTSUpper line (cyan line)
STOP when the price crosses back above the BOOTSUpper line (cyan line)

The price zone between the two lines is the flat zone; traders don't consider taking new positions in that area between the two lines.

Developer Anıl Özekşi advises that traders may have more accurate signals when using a short-period moving average instead of closing prices. So, I added a moving average with the same default length of 2 , which was used in Bollinger Bands calculation. You can check the "SHOW MOVING AVERAGE?" box on the settings tab of the indicator.

4fz3av5.png


original Tradingview code:
https://www.tradingview.com/script/hynBgzIQ/
New ThinkOrSwim code can be found in the next post
Looks interesting. I tried to set up a scan with break of support line but it said will not work in real time. Suggestions?
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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