The Ultimate Buy and Sell Indicator for ThinkOrSwim

samer800

Moderator - Expert
VIP
Lifetime
ufBI3YC.png


Author Message:
The indicator mainly relies on the RSI indicator with Bollinger Bands for signals. (Though not entirely)
More Details : https://www.tradingview.com/v/hoFpcO04/

CODE:

CSS:
#// https://www.tradingview.com/v/hoFpcO04/
#//@Sherlock_MacGyver
#indicator(shorttitle="Ultimate", title="Ultimate Buy and Sell Indicator", overlay=true
# Converted by sam4Cok@Samer800    - 12/2023

input src = close;#, title="Data Source for Price", group=group1)
input showRSICandleColors = yes; # "RSI Colored Candles"
input highlightBackgroundState = yes; # "Bought/Sold State Background"
input showAllMovAvg = no;#, title="Moving Averages"
input showBbBasisLine = no;# "Bollinger Band Basis"
input showBollingerBands = yes;# "Bollinger Bands"
input showWatchSignals = yes;# "All Watch Signals"
input showSignals = yes; # "Show Buy/Sell Signals"
input showSignalBackground = yes; # "Buy/Sell Signal Warning Background"
input showAtrFill = yes; # "Show ATR fill color zone"
input showAtrLines = no; # "Show ATR Moving Average and band lines"
input watchSignalLookback = 35; #, title="Length to use Watch Signals"
input useSignalWaiting = no; # "Use Signal wait period?"
input signalWaitPeriod = 20; # "# of bars before signals allowed "
input rsiMaType = {"SMA", "EMA", "WMA", "HMA", "VWMA", default "RMA"}; # "Calculate RSI with"
input rsiSource = close; # "RSI Data Source"
input rsiLength = 32; # "RSI Length"
input rsiBbMaType = {default "SMA", "EMA", "WMA", "HMA", "VWMA", "RMA"}; # "Rsi Basis Moving Average Type"
input rsiBasisLength = 32; # "RSI Basis Length"
input rsiMultiplier = 2.0; #  "RSI Band Multiplier"
input useWmaSmoothing = no; # "Use Smoothing"
input smoothingLength = 5; # "Smoothing Length"
input bbMaType = {default "SMA", "EMA", "WMA", "HMA", "VWMA", "RMA"}; # "Moving Average Type"
input bbBasisLength = 20; # "Price BBand Basis Length"
input bbInnerMultiplier = 2.0; # "Price Inner BB Multiplier"
input bbOuterMultiplier = 2.5; # "Price Outer BB Multiplier"
input atrPeriod = 30; # "ATR Period"
input atrMaPeriod = 10; # "ATR MA Period"
input atrMult = 1.5; # "ATR Band multiplier"
input atrMaType = {"SMA", "EMA", default "WMA", "HMA", "VWMA", "RMA"}; # "ATR Moving Average Type"
input useAtrWatchSignals = no; # "Use ATR for watch signals"
input maType = {default "SMA", "EMA", "WMA", "HMA", "VWMA", "RMA"}; # "Moving Average Type for Chart"
input showMA5 = no; # "Show 5 MA"
input showMA10 = no; # "Show 10 MA"
input showMA20 = no; # "Show 20 MA"
input showMA50 = yes; # "Show 50 MA"
input showMA100 = yes; # "Show 100 MA"
input showMA200 = yes; # "Show 200 MA"
input showCustomMa = no; # "Show Custom MA"
input customMa = 300; # "Custom Moving Average Length"
input forceAlternating = no; # "Force alternating buy/sell"
input useRsiSignals = yes; # "RSI crossing Basis"
input usePriceSignals = no; # "Price crossing BBand basis"
input useAtrSignals = no; # "Price crossing ATR Bands"
input useMacdSignals = no; # "MACD Signals"
input use75Signals = yes; # "RSI crossing under 75"
input use50Signals = no; # "RSI crossing over/under 50"
input use25Signals = yes; # "RSI crossing over 25"
input bbLookbackPeriod = 500; # "Lookback Period for Band Width Calculation"
input useRsiBasis = yes; # "Use RSI Basis for Bollinger Band Trend Coloring"
input BarsBackToDetermineRsiTrend = 4; # "Bars Back to Determine RSI Trend"
input usePriceBandWatchSignals = no; # "Use Price Bollinger Bands for Watch Signals"
input useYellowRsiFilter = no; # "Use Yellow RSI Filter"
input yellowRsiFilterType = {default "Basis", "RSI", "Either"}; # "Filter when _ is in RSI range"
input yellowRsiFilterHigh = 55; # "Yellow RSI Filter High"
input yellowRsiFilterLow = 45; # "Yellow RSI Filter Low"
input filterBuySell = yes; # "Filter Buys and Sells"
input filterWatches = no; # "Filter Watch signals"
input macdMaType = {"SMA", default "EMA", "WMA", "HMA", "VWMA", "RMA"}; # "MACD Line MA Type"
input macdSignalType = {"SMA", default "EMA", "WMA", "HMA", "VWMA", "RMA"}; # "Signal Line MA Type"
input macdFastLength = 12; # "Fast Length"
input macdSlowLength = 26; # "Slow Length"
input macdSignalLength = 9; # "Smoothing"
input showDivergence = yes; # "Show Divergence"
input lookbackRight = 5; # "Lookback Right"
input lookbackLeft = 5; # "Lookback Left"
input rangeUpper = 60; # "Range Upper"
input rangeLower = 5; # "Range Lower"

DefineGlobalColor("bandColor1",  Color.GREEN); # "Rsi Trend Up color"
DefineGlobalColor("bandColor2",  Color.RED); # "Rsi Trend Down color"
DefineGlobalColor("basisColor",  Color.ORANGE); # "Basis color"
DefineGlobalColor("atrFillColor",  CreateColor(115, 84, 101)); # "ATR zone fill color"
DefineGlobalColor("atrLineColor",  CreateColor(255, 59, 173)); # "ATR line color"
DefineGlobalColor("ma5Color",  Color.WHITE); # "ma5"
DefineGlobalColor("ma10Color",  Color.YELLOW); # "ma10"
DefineGlobalColor("ma20Color",  Color.GREEN); # "ma20"
DefineGlobalColor("ma50Color",  Color.RED); # "ma50"
DefineGlobalColor("ma100Color", Color.MAGENTA); # "ma100"
DefineGlobalColor("ma200Color",  Color.CYAN); # "ma200"
DefineGlobalColor("customMaColor", Color.GRAY); # "customMa"
DefineGlobalColor("bearColor",  CreateColor(255,82,82)); # "Bearish Divergence Color"
DefineGlobalColor("bullColor", Color.GREEN); # "Bullish DivergenceColor"

def na = Double.NaN;
def isconfirmed = !IsNaN(close);
def bar_index = AbsValue(BarNumber());
def pos = Double.POSITIVE_INFINITY;
def neg = Double.NEGATIVE_INFINITY;
#vwma(source, length)
script VWMA {
    input src = close;
    input len = 14;
    input vol = volume;
    def nom = Average(src * vol, len);
    def den = Average(vol, len);
    def VWMA = nom / den;
    plot result = VWMA;
}
script maType {
    input src = close;
    input length = 14;
    input type = "SMA";
    def maType =
        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 == "HMA" then HullMovingAvg(src, length) else
        if type == "VWMA" then vwma(src, length) else
        if type == "RMA" then WildersAverage(src, length) else Average(src, length);
    plot out = maType;
}
#/// MACD Calculations (MACD NOT VISIBLE ON CHART) ///
def fast_ma = maType(src, macdFastLength, macdMaType);
def slow_ma = maType(src, macdSlowLength, macdMaType);
def macd = fast_ma - slow_ma;
def signal = maType(macd, macdSignalLength, macdSignalType);
def hist = macd - signal;
#/// Calculate RSI with 2 Bollinger Bands [Not visible on chart] ///
def chgRsi = rsiSource - rsiSource[1];
def upRsi = Max(chgRsi, 0);
def dnRsi = - Min(chgRsi, 0);
def up = maType(upRsi, rsiLength, rsiMaType);
def dn = maType(dnRsi, rsiLength, rsiMaType);
def rsi = if dn == 0 then 100 else if up == 0 then 0 else 100 - (100 / (1 + up / dn));
def rsiBasis = maType(rsi, rsiBasisLength, rsibbMaType);
def rsiDeviation = StDev(rsi, rsiBasisLength);
def rsiBasisDeviation = StDev(rsiBasis, rsiBasisLength);
def rsiBasisExtendedUp = (rsiBasis + 0.75 * rsiBasisDeviation);
def rsiBasisExtendedDown = (rsiBasis - 0.75 * rsiBasisDeviation);
#// Inner RSI Bands
def upperRsi = rsiBasis + rsiMultiplier * rsiDeviation;
def lowerRsi = rsiBasis - rsiMultiplier * rsiDeviation;
#// Calculate the WMA of RSI and switch to smoothed RSI if smoothing is enabled
def wmaRsi =  WMA(rsi, smoothingLength);
def smoothedRsi = if useWmaSmoothing then wmaRsi else rsi;

#/// Calculate 2 Bollinger Bands for the Price ///
#// Function to calculate Bollinger Bands with flexibility to change MA type
script bb {
    input src = close;
    input priceBasisLength = 20;
    input priceInnerMultiplier = 1;
    input priceOuterMultiplier = 2;
    input priceMaType = yes;
    def priceBasis = maType(src, priceBasisLength, priceMaType);
    def priceInnerDeviation = priceInnerMultiplier * StDev(src, priceBasisLength);
    def priceOuterDeviation = priceOuterMultiplier * StDev(src, priceBasisLength);
    def upperPriceInner = priceBasis + priceInnerDeviation;
    def lowerPriceInner = priceBasis - priceInnerDeviation;
    def upperPriceOuter = priceBasis + priceOuterDeviation;
    def lowerPriceOuter = priceBasis - priceOuterDeviation;
    plot basis = priceBasis;
    plot upIn = upperPriceInner;
    plot loIn = lowerPriceInner;
    plot upOut = upperPriceOuter;
    plot loOut = lowerPriceOuter;
}
#// Using calculateBollingerBands function for the basis lines
def priceBasis = bb(src, bbBasisLength, bbInnerMultiplier, bbOuterMultiplier, bbMaType).basis;
def upperPriceInner = bb(src, bbBasisLength, bbInnerMultiplier, bbOuterMultiplier, bbMaType).upIn;
def lowerPriceInner = bb(src, bbBasisLength, bbInnerMultiplier, bbOuterMultiplier, bbMaType).loIn;
def upperPriceOuter = bb(src, bbBasisLength, bbInnerMultiplier, bbOuterMultiplier, bbMaType).upOut;
def lowerPriceOuter = bb(src, bbBasisLength, bbInnerMultiplier, bbOuterMultiplier, bbMaType).loOut;
#/// Trend Analysis and Visualization
def rsiTrend = maType(smoothedRsi, BarsBackToDetermineRsiTrend, rsiMaType);
def rsiMaTrend = maType(rsiBasis, BarsBackToDetermineRsiTrend, rsiMaType);
def priceMaTrend = maType(src, BarsBackToDetermineRsiTrend, bbMaType);
#// Determine the uptrend or downtrend based on either the Basis or RSI.
def rsiMaTrend5 = maType(rsiMaTrend, 5, rsiMaType);
def rsiTrend5   = maType(rsiTrend, 5, rsiMaType);
def rsiUptrend = if useRsiBasis then rsiMaTrend > rsiMaTrend5 else rsiTrend > rsiTrend5;
def rsiDowntrend = if useRsiBasis then rsiMaTrend < rsiMaTrend5 else rsiTrend < rsiTrend5;
#// Price moving average trend
def priceMaTrend5 = maType(priceMaTrend, 5, bbMaType);
def priceUptrend = priceMaTrend > priceMaTrend5;
def priceDowntrend = priceMaTrend < priceMaTrend5;
#// Calculate the distance between the Inner Bands of the Bollinger Bands to set transparency levels
def price_band_distance = upperPriceInner - lowerPriceInner;
def price_max_distance = Highest(price_band_distance, bbLookbackPeriod);
def price_transparency = (100 * (price_band_distance / price_max_distance));
#// Renaming for code clarity
def priceBandWidth = price_transparency;
def rgb = if IsNaN(priceBandWidth) then 0 else
          if priceBandWidth > 100 then 100 else
          if priceBandWidth < 0 then 0 else priceBandWidth;
#// Plot invisible lines for the Upper and Lower Bollinger Bands for use in fill function
def bbU1 = if showBollingerBands then upperPriceInner else na;
def bbL1 = if showBollingerBands then lowerPriceInner else na;
def bbU2 = if showBollingerBands then upperPriceOuter else na;
def bbL2 = if showBollingerBands then lowerPriceOuter else na;

def bbTrend = if rsiUptrend then 1 else
              if rsiDowntrend then 0 else bbTrend[1];
def upbbT = (bbTrend or bbTrend[1]);
def dnbbT = (!bbTrend or !bbTrend[1]);
def extUp  = upbbT and rgb > 75;
def extDn  = dnbbT and rgb < 25;
def normUp = upbbT and rgb > 55;
def normDn = dnbbT and rgb < 45;
AddCloud(if upbbT then bbU2 else na, bbU1, Color.DARK_GREEN);
AddCloud(if upbbT then bbL1 else na, bbL2, Color.DARK_GREEN);
AddCloud(if dnbbT then bbU2 else na, bbU1, Color.DARK_RED);
AddCloud(if dnbbT then bbL1 else na, bbL2, Color.DARK_RED);
AddCloud(if normDn then bbU2 else na, bbU1, Color.DARK_RED);
AddCloud(if normUp then bbU2 else na, bbU1, Color.DARK_GREEN);
AddCloud(if normDn then bbL1 else na, bbL2, Color.DARK_RED);
AddCloud(if normUp then bbL1 else na, bbL2, Color.DARK_GREEN);
AddCloud(if extDn then bbU2 else na, bbU1, Color.RED);
AddCloud(if extUp then bbU2 else na, bbU1, Color.GREEN);
AddCloud(if extDn then bbL1 else na, bbL2, Color.RED);
AddCloud(if extUp then bbL1 else na, bbL2, Color.GREEN);

#// Plot the Basis line, but only if the user has enabled 'showBollingerBands' and 'showBasisPlot'
plot bbBasisLine = if showBbBasisLine then priceBasis else na; # "Price Basis"
bbBasisLine.SetDefaultColor(GlobalColor("basisColor"));
#/// Popular moving averages ///
#// Calculate moving averages based on the selected type
def ma5 = maType(close, 5, maType);
def ma10 = maType(close, 10, maType);
def ma20 = maType(close, 20, maType);
def ma50 = maType(close, 50, maType);
def ma100 = maType(close, 100, maType);
def ma200 = maType(close, 200, maType);
def custom = maType(close, customMa, maType);
#// Plot moving averages based on user-selected type
plot ma5Line = if showAllMovAvg and showMA5 then ma5 else na;#, "5 MA", color=color.white)
plot ma10Line = if showAllMovAvg and showMA10 then ma10 else na;#, "10 MA", color=color.yellow)
plot ma20Line = if showAllMovAvg and showMA20 then ma20 else na;#, "20 MA", color=color.green)
plot ma50Line = if showAllMovAvg and showMA50 then ma50 else na;#, "50 MA", color=color.red)
plot ma100Line = if showAllMovAvg and showMA100 then ma100 else na;#, "100 MA", color=color.purple)
plot ma200Line = if showAllMovAvg and showMA200 then ma200 else na;#, "200 MA", color=color.blue)
plot maCustLine = if showAllMovAvg and showCustomMa then custom else na;#, "Custom", color=customMaColor)
ma5Line.SetDefaultColor(GlobalColor("ma5Color"));
ma10Line.SetDefaultColor(GlobalColor("ma10Color"));
ma20Line.SetDefaultColor(GlobalColor("ma20Color"));
ma50Line.SetDefaultColor(GlobalColor("ma50Color"));
ma100Line.SetDefaultColor(GlobalColor("ma100Color"));
ma200Line.SetDefaultColor(GlobalColor("ma200Color"));
maCustLine.SetDefaultColor(GlobalColor("customMaColor"));
#// ATR //
#// Calculate the ATR and selected type of Moving Average
def atrValue = ATR(Length = atrPeriod);
def atrMaValue = maType(close, atrMaPeriod, atrMaType);
#// Calculate upper, middle, and lower ATR bands
def upperAtrBand  = atrMaValue + atrValue * atrMult;
def lowerAtrBand  = atrMaValue - atrValue * atrMult;
#// Plots used for fill
def atrMiddle = atrMaValue;
def atrUpper =  upperAtrBand;
def atrLower =  lowerAtrBand;

plot upperAtrPlot = if showAtrLines then atrUpper else na;#, color=adjustedLineColor)
plot middleAtrPlot = if showAtrLines then atrMiddle else na;#, color=adjustedLineColor)
plot lowerAtrPlot = if showAtrLines then atrLower else na;#, color=adjustedLineColor)
upperAtrPlot.SetDefaultColor(GlobalColor("atrLineColor"));
middleAtrPlot.SetDefaultColor(GlobalColor("atrLineColor"));
lowerAtrPlot.SetDefaultColor(GlobalColor("atrLineColor"));

AddCloud(if showAtrFill then atrUpper else na, atrLower, GlobalColor("atrFillColor"));

#/ TRADE SIGNAL EVENTS //
#// Price band crosses
def priceCrossOverInner = Crosses(src, lowerPriceInner, CrossingDirection.ABOVE);# Price over outer band
def priceCrossUnderInner = Crosses(src, upperPriceInner, CrossingDirection.BELOW);# Price under outer band
#//RSI Band crosses
def rsiCrossOverLower = Crosses(smoothedRsi, lowerRsi, CrossingDirection.ABOVE);# // RSI over lower band
def rsiCrossUnderUpper = Crosses(smoothedRsi, upperRsi, CrossingDirection.BELOW);# // RSI under upper band
#// RSI Cross Basis
def rsiCrossOverBasis = Crosses(smoothedRsi, rsiBasis, CrossingDirection.ABOVE);
def rsiCrossUnderBasis = Crosses(smoothedRsi, rsiBasis, CrossingDirection.BELOW);
#// RSI Value Crosses
def rsiCrossUnder75 = Crosses(smoothedRsi, 75, CrossingDirection.BELOW);# // RSI crossunder 75
def rsiCrossUnder70 = Crosses(smoothedRsi, 70, CrossingDirection.BELOW);# // RSI crossunder 70
def rsiCrossUnder50 = Crosses(smoothedRsi, 50, CrossingDirection.BELOW);# // RSI crossover 50
def rsiCrossOver50 = Crosses(smoothedRsi, 50, CrossingDirection.ABOVE);# // RSI crossover 50
def rsiCrossOver30 = Crosses(smoothedRsi, 30, CrossingDirection.ABOVE);# // RSI crossover 30
def rsiCrossOver25 = Crosses(smoothedRsi, 25, CrossingDirection.ABOVE);# // RSI crossover 25
#// Price crossing Bollinger Band Basis
def priceCrossOverBasis = Crosses(close, priceBasis, CrossingDirection.ABOVE);
def priceCrossUnderBasis = Crosses(close, priceBasis, CrossingDirection.BELOW);
#// MACD crosses
def macdBuy = Crosses(macd, signal, CrossingDirection.ABOVE);
def macdSell = Crosses(macd, signal, CrossingDirection.BELOW);
#//Candle High and Low ATR band crosses
#// For ATR buy and sell signals
def lowOverAtrLower = Crosses(low, lowerAtrBand, CrossingDirection.ABOVE);
def highUnderAtrUpper = Crosses(high, upperAtrBand, CrossingDirection.BELOW);
#// For Watch signals
def highUnderAtrLower = Crosses(high, lowerAtrBand, CrossingDirection.BELOW);
def lowOverAtrUpper = Crosses(low, upperAtrBand, CrossingDirection.ABOVE);

#// Yellow RSI Filter //
#// RSI Yellow Filter
def rsiOverYellowFilterLow = smoothedRsi > yellowRsiFilterLow;
def rsiUnderYellowFilterHigh = smoothedRsi < yellowRsiFilterHigh;
def rsiSlowOverYellowFilterLow = rsiBasis > yellowRsiFilterLow;
def rsiSlowUnderYellowFilterHigh = rsiBasis < yellowRsiFilterHigh;
#// Slow Rsi Basis or RSI between low and high range
def rsiBasisInYellow = rsiSlowOverYellowFilterLow and rsiSlowUnderYellowFilterHigh;
def rsiInYellow = rsiOverYellowFilterLow and rsiUnderYellowFilterHigh;
#// When to filter based on the following being in yellow filter range
def inYellowRsi;
switch (yellowRsiFilterType) {
case "RSI"    :
    inYellowRsi = rsiInYellow;
case "Either" :
    inYellowRsi = rsiBasisInYellow or rsiInYellow;
default       :
    inYellowRsi = rsiBasisInYellow;
}
def watchesInsideYellowRsi = if useYellowRsiFilter and filterWatches then inYellowRsi else no;
def buyAndSellInsideYellowRsi = if useYellowRsiFilter and filterBuySell then inYellowRsi else no;

#// Trade Logic //
def bought;# = false
def sold;# = false
def signalsBlocked;# = false

def alternateBuying = ((!forceAlternating) or (!bought[1] and forceAlternating));
def alternateSelling = ((!forceAlternating) or (!sold[1] and forceAlternating));
#// Green diamonds
def buyWatch1 = (usePriceBandWatchSignals and (priceCrossOverInner and !rsiCrossOverLower) and isconfirmed and (alternateBuying) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def buyWatch2 = ((rsiCrossOverLower and !priceCrossOverInner) and (isconfirmed) and (alternateBuying) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def buyWatch3 = (usePriceBandWatchSignals and (priceCrossOverInner and rsiCrossOverLower) and (isconfirmed) and (alternateBuying) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def buyWatch4 = (usePriceBandWatchSignals and (priceCrossOverInner and isconfirmed) and (alternateBuying) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def buyWatch5 = ((rsiCrossOverLower and isconfirmed) and (alternateBuying) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def buyWatch6 = ((rsiCrossOver25 and isconfirmed) and (alternateBuying) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def buyWatch7 = (useAtrWatchSignals and (highUnderAtrLower and isconfirmed) and (alternateBuying) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
#// Red diamonds
def sellWatch1 = (usePriceBandWatchSignals and (priceCrossUnderInner and !rsiCrossUnderUpper) and (isconfirmed) and (alternateSelling) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def sellWatch2 = ((rsiCrossUnderUpper and !priceCrossUnderInner) and (isconfirmed) and (alternateSelling) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def sellWatch3 = (usePriceBandWatchSignals and (priceCrossUnderInner and rsiCrossUnderUpper) and (isconfirmed) and (alternateSelling) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def sellWatch4 = (usePriceBandWatchSignals and (priceCrossUnderInner and isconfirmed) and (alternateSelling) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def sellWatch5 = ((rsiCrossUnderUpper and isconfirmed) and (alternateSelling) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def sellWatch6 = ((rsiCrossUnder75 and isconfirmed) and (alternateSelling) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def sellWatch7 = (useAtrWatchSignals and (lowOverAtrUpper and isconfirmed) and (alternateSelling) and (!watchesInsideYellowRsi) and (!signalsBlocked[1]));
def buyWatched = (buyWatch1) or (buyWatch2) or (buyWatch3) or (buyWatch4) or (buyWatch5) or (buyWatch6) or (buyWatch7);
def sellWatched = (sellWatch1) or (sellWatch2) or (sellWatch3) or (sellWatch4) or (sellWatch5) or (sellWatch6) or (sellWatch7);
#// Requires a watch signal
def buySignal1 = (useRsiSignals) and (rsiCrossOverBasis);
def buySignal2 = (usePriceSignals) and (priceCrossOverBasis);
def buySignal3 = (use50Signals) and (rsiCrossOver50);
def buySignal4 = (use25Signals) and (rsiCrossOver25);
def buySignal5 = (useMacdSignals) and (macdBuy);
def buySignal6 = (useAtrSignals) and (lowOverAtrLower);
#// Requires a sell watch signal
def sellSignal1 = (useRsiSignals) and (rsiCrossUnderBasis);
def sellSignal2 = (use50Signals) and (rsiCrossUnder50);
def sellSignal3 = (usePriceSignals) and (priceCrossUnderBasis);
def sellSignal4 = (use75Signals) and (rsiCrossUnder75);
def sellSignal5 = (useMacdSignals) and (macdSell);
def sellSignal6 = (useAtrSignals) and (highUnderAtrUpper);
def buyWatched1 = if isNaN(buyWatched) then 0 else buyWatched;
def sellWatched1 = if isNaN(sellWatched) then 0 else sellWatched;
def buyWatchArray; def sellWatchArray;
def buyCnt = if buyWatchArray[1] > watchSignalLookback then 0 else
             if buyWatched1 then buyWatchArray[1] + 1 else buyWatchArray[1];
def sellCnt = if sellWatchArray[1] > watchSignalLookback then 0 else
              if sellWatched1 then sellWatchArray[1] + 1 else sellWatchArray[1];
def buyWatchMet = buyCnt >= 1;
def sellWatchMet = sellCnt >= 1;

def buySignals = ((buyWatchMet) and (buySignal1 or buySignal2 or buySignal3 or buySignal4 or buySignal5 or buySignal6));
def sellSignals = ((sellWatchMet) and (sellSignal1 or sellSignal2 or sellSignal3 or sellSignal4 or sellSignal5 or sellSignal6));

def plotBuyBG; def plotSellBG;
if (buySignals) and (!buyAndSellInsideYellowRsi) and (!buyWatched) and (!signalsBlocked[1]) {
    plotBuyBG = yes;
    plotSellBG = no;
    } else
if (sellSignals) and (!buyAndSellInsideYellowRsi) and (!sellWatched) and (!signalsBlocked[1]) {
    plotBuyBG = no;
    plotSellBG = yes;
    } else {
    plotBuyBG = no;
    plotSellBG = no;
}
def plotBuy;def plotSell;def lastSignalBarIndex;
if (buySignals) and (isconfirmed) and (!buyAndSellInsideYellowRsi) and (!buyWatched) and (!signalsBlocked[1]) {
    bought = yes;
    sold = no;
    plotBuy = yes;
    plotSell = no;
    lastSignalBarIndex = bar_index;
    buyWatchArray = 0;
    sellWatchArray = 0;
    } else
if (sellSignals) and (isconfirmed) and (!buyAndSellInsideYellowRsi) and (!sellWatched) and (!signalsBlocked[1]) {
    sold = yes;
    bought = no;
    plotBuy = no;
    plotSell = yes;
    lastSignalBarIndex = bar_index;
    sellWatchArray = 0;
    buyWatchArray = 0;
    } else {
    bought = bought[1];
    sold = sold[1];
    plotBuy = no;
    plotSell = no;
    lastSignalBarIndex = lastSignalBarIndex[1];
    buyWatchArray = buyCnt;
    sellWatchArray = sellCnt;
}
#/ Check if the current bar is within the wait period after a buy or sell signal
if useSignalWaiting {
    signalsBlocked = lastSignalBarIndex and bar_index - highestAll(lastSignalBarIndex) <= signalWaitPeriod;
    } else {
    signalsBlocked = no;
}
def bougBg = isconfirmed and highlightBackgroundState and (bought or bought[1]);
def soldBg = isconfirmed and highlightBackgroundState and (sold or sold[1]);
def sigUpBg = showSignalBackground and showSignals and (plotBuyBG or plotBuyBG[1]);
def sigDnBg = showSignalBackground and showSignals and (plotSellBG or plotSellBG[1]);
AddChartBubble(showSignals and plotBuy, low, "B", CreateColor(175, 245, 153),no);
AddChartBubble(showSignals and plotSell, high, "S", CreateColor(252, 159, 159));

AddCloud(if sigUpBg then pos else na, neg, Color.VIOLET);
AddCloud(if sigDnBg then pos else na, neg, Color.PLUM);
AddCloud(if bougBg then pos else na, neg, CreateColor(1, 25, 16));
AddCloud(if soldBg then pos else na, neg, CreateColor(41, 1, 16));

#// Plot Watch signals based on filters
plot buyWatchSig = if showWatchSignals and buyWatched and !signalsBlocked then low else na;
plot sellWatchSig = if showWatchSignals and sellWatched and !signalsBlocked then high else na;
buyWatchSig.SetDefaultColor(color.CYAN);
sellWatchSig.SetDefaultColor(color.MAGENTA);
buyWatchSig.SetPaintingStrategy(PaintingStrategy.SQUARES);
sellWatchSig.SetPaintingStrategy(PaintingStrategy.SQUARES);

#/// Colored candles and candle backgrounds (RSI levels, Bollinger Band Levels, Buy/Sell signals) ///
#// Color Conditions
def boughtIt = plotBuy and showRSICandleColors;
def soldIt = plotSell and showRSICandleColors;
def isNot = !boughtIt and !soldIt;
#// Define 9 color zones
def oneHundredTo85 = isNot and showRSICandleColors and smoothedRsi <= 100 and smoothedRsi >= 85;
def eightyFiveTo75 = isNot and showRSICandleColors and smoothedRsi < 85 and smoothedRsi >= 75;
def seventyFiveTo70 = isNot and showRSICandleColors and smoothedRsi < 75 and smoothedRsi >= 70;
def seventyTo65 = isNot and showRSICandleColors and smoothedRsi < 70 and smoothedRsi >= 65;
def sixtyFiveTo60 = isNot and showRSICandleColors and smoothedRsi < 65 and smoothedRsi >= 60;
def sixtyToYellowHigh = isNot and showRSICandleColors and smoothedRsi < 60 and smoothedRsi >= yellowRsiFilterHigh;
def yellowHighToYellowLow = isNot and showRSICandleColors and smoothedRsi < yellowRsiFilterHigh and smoothedRsi >= yellowRsiFilterLow;
def yellowLowTo40 = isNot and showRSICandleColors and smoothedRsi < yellowRsiFilterLow and smoothedRsi >= 40;
def fourtyTo35 = isNot and showRSICandleColors and smoothedRsi < 40 and smoothedRsi >= 35;
def thirtyFiveTo30 = isNot and showRSICandleColors and smoothedRsi < 35 and smoothedRsi >= 30;
def thirtyTo25 = isNot and showRSICandleColors and smoothedRsi < 30 and smoothedRsi >= 25;
def twentyFiveTo15 = isNot and showRSICandleColors and smoothedRsi < 25 and smoothedRsi >= 15;
def fifteenTo0 = isNot and showRSICandleColors and smoothedRsi < 15 and smoothedRsi >= 0;
#// Assign colors based on conditions

AssignPriceColor(if !showRSICandleColors then Color.CURRENT else
                 if plotBuy then Color.CYAN else
                 if plotSell then Color.MAGENTA else
                 if oneHundredTo85 then Color.GRAY else
                 if eightyFiveTo75 then CreateColor(71,210,71) else
                 if seventyFiveTo70 then CreateColor(50, 205, 50) else
                 if seventyTo65 then CreateColor(45, 185, 45) else
                 if sixtyFiveTo60 then CreateColor(40, 164, 40) else
                 if sixtyToYellowHigh then CreateColor(35, 144, 35) else
                 if yellowHighToYellowLow then CreateColor(204, 204, 0) else
                 if yellowLowTo40 then CreateColor(179, 0, 0) else
                 if fourtyTo35 then CreateColor(204, 0, 0) else
                 if thirtyFiveTo30 then CreateColor(230, 0, 0) else
                 if thirtyTo25 then CreateColor(255, 0, 0) else
                 if twentyFiveTo15 then CreateColor(255, 26, 26) else Color.GRAY);

#// Divergence //

def divSrc = smoothedRsi;

def h = high;
def l = low;

script FindPivots {
    input dat = close; # default data or study being evaluated
    input HL  = 0;    # default high or low pivot designation, -1 low, +1 high
    input lbL  = 5;    # default Pivot Lookback Left
    input lbR  = 1;    # default Pivot Lookback Right
    ##############
    def _nan;    # used for non-number returns
    def _BN;     # the current barnumber
    def _VStop;  # confirms that the lookforward period continues the pivot trend
    def _V;      # the Value at the actual pivot point
    ##############
    _BN  = BarNumber();
    _nan = Double.NaN;
    _VStop = if !isNaN(dat) and lbr > 0 and lbl > 0 then
                fold a = 1 to lbR + 1 with b=1 while b do
                    if HL > 0 then dat > GetValue(dat,-a) else dat < GetValue(dat,-a) else _nan;
   if (HL > 0) {
        _V = if _BN > lbL + 1 and dat == Highest(dat, lbL + 1) and _VStop
            then dat else _nan;
    } else {
        _V = if _BN > lbL + 1 and dat == Lowest(dat, lbL + 1) and _VStop
            then dat else _nan;
    }
    plot result = if !IsNaN(_V) and _VStop then _V else _nan;
}
#_inRange(cond) =>
script _inRange {
    input cond = yes;
    input rangeUpper = 60;
    input rangeLower = 5;
        def bars = if cond then 0 else bars[1] + 1;
        def inrange =  (rangeLower <= bars) and (bars <= rangeUpper);
plot retrun = inRange;
}
def pl_ = findpivots(divSrc,-1, LookBackLeft, LookBackRight);
def ph_ = findpivots(divSrc, 1, LookBackLeft, LookBackRight);
def pl = !isNaN(pl_);
def ph = !isNaN(ph_);
def pll = lowest(divSrc,LookBackLeft);
def phh = highest(divSrc,LookBackLeft);
def sll = lowest(l, LookBackLeft);
def shh = highest(h, LookBackLeft);
#-- Pvt Low
def plStart  = if pl then yes else plStart[1];
def plFound  = if (plStart and pl) then 1 else 0;
def vlFound1 = if plFound then divSrc else vlFound1[1];
def vlFound_ = if vlFound1!=vlFound1[1] then vlFound1[1] else vlFound_[1];
def vlFound  = if !vlFound_ then pll else vlFound_;
def plPrice1 = if plFound then l else plPrice1[1];
def plPrice_ = if plPrice1!=plPrice1[1] then plPrice1[1] else plPrice_[1];
def plPrice  = if !plPrice_ then sll else plPrice_;
#-- Pvt High
def phStart = if ph then yes else phStart[1];
def phFound = if (phStart and ph) then 1 else 0;
def vhFound1 = if phFound then divSrc else vhFound1[1];
def vhFound_ = if vhFound1!=vhFound1[1] then vhFound1[1] else vhFound_[1];
def vhFound = if !vhFound_ then phh else vhFound_;
def phPrice1 = if phFound then h else phPrice1[1];
def phPrice_ = if phPrice1!=phPrice1[1] then phPrice1[1] else phPrice_[1];
def phPrice = if !phPrice_ then sll else phPrice_;
#// Regular Bullish
def inRangePl = _inRange(plFound[1],rangeUpper,rangeLower);
def oscHL = divSrc > vlFound and inRangePl;
def priceLL = l < plPrice;
def bullCond = plFound and oscHL and priceLL;
#// Regular Bearish
def inRangePh = _inRange(phFound[1],rangeUpper,rangeLower);
def oscLH   = divSrc < vhFound and inRangePh;
def priceHH = h > phPrice;
def bearCond = phFound and oscLH and priceHH;

#------ Bubbles
def bullBub  = showDivergence and bullCond;
def bearBub  = showDivergence and bearCond;

addchartbubble(bullBub, l, "Div", color.GREEN, no);
addchartbubble(bearBub, h, "Div", GlobalColor("bearColor"), yes);

##### Lines

#-- Bear Line
def lastPhBar = if ph then bar_index else lastPhBar[1];
def prePhBar = if lastPhBar!=lastPhBar[1] then lastPhBar[1] else prePhBar[1];
def priorPHBar = if bearCond then prePhBar else priorPHBar[1];
#-- Bull Line
def lastPlBar = if pl then bar_index else lastPlBar[1];
def prePlBar = if lastPlBar!=lastPlBar[1] then lastPlBar[1] else prePlBar[1];
def priorPLBar = if bullCond then prePlBar else priorPLBar[1];

def lastBullBar = if bullCond then bar_index else lastBullBar[1];
def lastBearBar = if bearCond then bar_index else lastBearBar[1];

def HighPivots = ph and bar_index >= HighestAll(priorPHBar) and bar_index <= HighestAll(lastBearBar);
def LowPivots  = pl and bar_index >= HighestAll(priorPLBar) and bar_index <= HighestAll(lastBullBar);

def pivotHigh = if HighPivots then h else na;
def pivotLow  = if LowPivots  then l else na;

plot PlotHline = if showDivergence then pivotHigh else na;
PlotHline.EnableApproximation();
PlotHline.SetDefaultColor(GlobalColor("bearColor"));

plot PlotLline = if showDivergence then pivotLow else na;
PlotLline.EnableApproximation();
PlotLline.SetDefaultColor(GlobalColor("bullColor"));

#-- END of CODE
 
I loaded the script into Scan that resulted in error: TooComplexException
Is it designed only for Charts?
 
Unless indicated otherwise, the 1st post in the thread is created for use on charts.

While no script is "too complex" to plot on the chart; Schwab does throttle the use of complex scripts in scans, watchlists, and conditional orders to prevent high load runs on the servers.

Many of the more complex scripts found on this forum, can only be used on charts.
They cannot be used in other widgets; such as: scans, watchlists, conditional orders, etc...

Yes, the error: TooComplexException indicates that the Ultimate Buy and Sell Indicator cannot be utilized in any of the ToS widgets.
 
Last edited:
I have a strange issue where an alert for one study
https://usethinkscript.com/threads/the-ultimate-buy-and-sell-indicator-for-thinkorswim.17349/
is only triggering an alert some of the time, but plots the bubble every time. I am assuming I am coding something incorrectly for the alerts since I am a beginner ToS code writer still. Code, screenshots of example 1 minute charts from this morning and my message center alerts pictured below. Any help greatly appreciated as I have had some great success with my current setup, but some alerts would be greatly helpful.

Since market open today I only received 2 alerts at 8:44 which plotted the yellow S bubble on the 2 min QQQ chart on the left 2nd from the top, and temporarily plotted a yellow S on the top 1 min QQQ chart that disappeared right at candle close because I believe the criteria for the alert were no longer met. These worked correctly.

Alerts Missed
1m QQQ 8:38 Blue B
1m QQQ 8:47 Yellow S
2m QQQ 8:38 Blue B
1m SPY 8:43 Yellow S
2m SPY 8:46 Yellow S

The study is from here: https://usethinkscript.com/threads/the-ultimate-buy-and-sell-indicator-for-thinkorswim.17349/

The code for alerts I am using are below

For the B/S signal shown as yellow/blue bubbles in the charts they plot from the below code and my alert code is below. This works sometimes but not always.
AddChartBubble(showSignals and plotBuy, low, "B", Color.BLUE,no);
AddChartBubble(showSignals and plotSell, high, "S", Color.Yellow);

Alert(showSignals and plotBuy, "Buy Signal!", Alert.BAR, Sound.Ring);
Alert(showSignals and plotSell, "Sell Signal!", Alert.BAR, Sound.Ring);

For the Divergence indicator which I can't ever get to trigger it is plotted with the below two sections and my attempt at an alert below. It appeared on the 2m QQQ premarket.
def bullBub = showDivergence and bullCond;
def bearBub = showDivergence and bearCond;

addchartbubble(bullBub, l, "Div", color.GREEN, no);
addchartbubble(bearBub, h, "Div", GlobalColor("bearColor"), yes);

Alert(bullbub, "Buy Div", Alert.BAR, Sound.Ring);
Alert(bearbub, "Sell Div", Alert.BAR, Sound.Ring);

Screenshot 2024-12-20 085408.png



Screenshot 2024-12-20 085456.png
 
Last edited by a moderator:
solved!
I did figure out why the B/S alerts weren't triggering all the time. The full code is flagged as too complex. After I trimmed like 75% of the code out down to just the key indicator code I wanted; the alerts are triggering properly with the code I wrote now.
 
Last edited by a moderator:

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
343 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