Oscillator Workbench [LucF] for ThinkOrSwim

samer800

Moderator - Expert
VIP
Lifetime
yrKWF5z.png


This is great indicator with a lot of options. I didn't convert in full, I just converted what I feel can benefit from. pls test it since I couldn't test all features.

Author Message: https://www.tradingview.com/script/BY9mAioc-Oscillator-Workbench-Chart-LucF/

You specify here:
 • The method used to color chart bars, if you choose to do so.
 • If you want to hollow out the bodies of bars where volume has not increased since the last bar.

CODE:
CSS:
#// This source code is subject to the terms of thse 2.0 at https://mozilla.org/MPL/2.0/
#// © LucF
#indicator("Oscillator Workbench — Chart [LucF]", "OWC", true, precision = 4, max_bars_back = 1000)
#Converted by Sam4Cok@Samer800 - 12/2022 * Not Exact Conv
input colorBarMode = {"None", "On divergences Only", default "On the state oscillator channel", "On the state of divergence channel", "On the combined state of both channels"};
input barsEmptyOnDecVol = no;
input osc1TypeInput = {default RSI, CCI, MACD, ChandeMomOsc, STOCH, StochRSI, MFI, UltimateOsc, Williams, TSI, STC, TrueRange, IntradayMomIndex, FisherTransform};
input osc1Source = close;
input osc1Length = 20;
input osc2TypeInput = {default None, RSI, CCI, MACD, ChandeMomOsc, STOCH, StochRSI, MFI, UltimateOsc, Williams, TSI, STC, TrueRange, IntradayMomIndex, FisherTransform};
input osc2Source = close;
input osc2Length = 20;
input oscXInput  = no;
input oscXSource = close;
input oscXCenterInput = 0;
input useRelVolWeight = no;
input relVolLookback = 100;
input divChannelBias = no;
input divLinesShow   = yes;
input divChannelShow = no;
input refTypeInput  = {SMA, EMA, WMA, SMMA, VWMA, default ALMA, SWMA, HMA};
input refSource = close;
input refLength = 20;
input osclLineShow = no;
input oscChannelCap = 3.0;
input oscChannelCapMode = {default "Standard deviations", "Multiples of ATR"};
input divChannelBreaches = {default low, high, close, open, hl2, hlc3, hlcc4, ohlc4};# "Breaches are determined using"
input divChannelLevels   = {default "High/Low", "Close Candle"};
input divDetectionMode   = {default Weighted, Oscillator};
input reflLineShow = no;
input oscChannelShow = no;

def na = Double.NaN;
def v = volume;
def c = close;
def o = open;
def l = low;
def h = high;
def divChannelHiSrc = if divChannelLevels == divChannelLevels."High/Low" then h else Max(o, c);
def divChannelLoSrc = if divChannelLevels == divChannelLevels."High/Low" then l  else Min(o, c);
def colorMode = if colorBarMode == colorBarMode."On divergences Only" then 1 else
                if colorBarMode == colorBarMode."On the state oscillator channel" then 2 else
                if colorBarMode == colorBarMode."On the state of divergence channel" then 3 else
                if colorBarMode == colorBarMode."On the combined state of both channels" then 4 else 0;
#-----Color----
DefineGlobalColor("lime"    , CreateColor(0, 255, 0));
DefineGlobalColor("lime_md" , CreateColor(0, 204, 0));
DefineGlobalColor("lime_lt" , CreateColor(0, 152, 0));
DefineGlobalColor("teal"    , CreateColor(0, 128, 128)); #
DefineGlobalColor("teal_md" , CreateColor(0, 101, 102));
DefineGlobalColor("teal_lt" , CreateColor(0, 75, 76));
DefineGlobalColor("pink"    , CreateColor(255, 0, 128));
DefineGlobalColor("pink_md"  , CreateColor(204, 0, 96));
DefineGlobalColor("pink_lt"  , CreateColor(126, 0, 59));
DefineGlobalColor("maroon"   , CreateColor(128, 0, 0));
DefineGlobalColor("maroon_md"  , CreateColor(102, 0, 0));
DefineGlobalColor("maroon_lt"  , CreateColor(76, 0, 0));
DefineGlobalColor("orange"  , CreateColor(197, 102, 6));
#// Breach sources
script nz {
    input data  = close;
    input repl  = 0;
    def ret_val = if IsNaN(data) then repl else data;
    plot return = ret_val;
}
script zero {
    input data  = close;
    input repl  = 0;
    def ret_val = if data == 0 then repl else data;
    plot return = ret_val;
}
#fixnan(data)
script fixnan {
    input data1 = 0;
    def data2;
    if BarNumber() == 1   {
        data2 = 0;
    } else
    if IsNaN(data1)  {
        data2 = data2[1];
    } else {
        data2 = data1;
    }
    plot valid = data2;
}
#MACD(src)
script mac {
    input src = close;
    def fast_length = 12;
    def slow_length = 26;
    def signal_length = 9;
    def fast_ma = ExpAverage(src, fast_length);
    def slow_ma = ExpAverage(src, slow_length);
    def macd = fast_ma - slow_ma;
    def signal = ExpAverage(macd, signal_length);
    def hist = macd - signal;
    plot return = hist;
}
# stoch(source, high, low, length) =>
script stoch {
    input src = close;
    input h = high;
    input l = low;
    input len = 10;
    def stoch = 100 * (src - Lowest(l, len)) / (Highest(h, len) - Lowest(l, len));
    plot return = stoch;
}
##xport stc(src, fast, slow, cycle, d1, d2) =>
script stc {
    input src = close;
    input fast = 20;
    input slow = 40;
    input cycle = 10;
    input d1 = 3;
    input d2 = 3;
    def macd   = ExpAverage(src, fast) - ExpAverage(src, slow);
    def k      = nz(fixnan(stoch(macd, macd, macd, cycle)));
    def d      = ExpAverage(k, d1);
    def kd     = nz(fixnan(stoch(d, d, d, cycle)));
    def stc    = ExpAverage(kd, d2);
    def result = Max(Min(stc, 100), 0);
    plot return = result;
}
#uoAverage(bp, trange, length) =>
script uoAverage {
    input bp = 1;
    input trange = 0.1;
    input length = 10;
    def result = Sum(bp, length) / Sum(trange, length);
    plot return = result;
}
#xport uo(simple int fastLen, simple int midLen, simple int slowLen) =>
script uo {
    input fastLen = 10;
    input midLen  = 20;
    input slowLen = 50;
    def tMax   = Max(high, close[1]);
    def tMin   = Min(low,  close[1]);
    def tr     = tMax  - tMin;
    def bp     = close - tMin;
    def avg1   = uoAverage(bp, tr, fastLen);
    def avg2   = uoAverage(bp, tr, midLen);
    def avg3   = uoAverage(bp, tr, slowLen);
    def result = 100 * (4 * avg1 + 2 * avg2 + avg3) / 7;
    plot return = result;
}
#// Breach sources
def divBreachHiSrc;
def divBreachLoSrc;
switch (divChannelBreaches) {
case low:
    divBreachHiSrc = low;
    divBreachLoSrc = high;
case high:
    divBreachHiSrc = high;
    divBreachLoSrc = low;
case close:
    divBreachHiSrc = close;
    divBreachLoSrc = close;
case open:
    divBreachHiSrc = open;
    divBreachLoSrc = open;
case hl2:
    divBreachHiSrc = hl2;
    divBreachLoSrc = hl2;
case hlc3:
    divBreachHiSrc = hlc3;
    divBreachLoSrc = hlc3;
case hlcc4:
    divBreachHiSrc = (high + low + close + close) / 4;
    divBreachLoSrc = (high + low + close + close) / 4;
case ohlc4:
    divBreachHiSrc = ohlc4;
    divBreachLoSrc = ohlc4;
}
def osc1Type;
def tr = TrueRange(h, c, l);
def nRSI1 = RSI(Price = osc1Source, Length = osc1Length);
switch (osc1TypeInput) {
case RSI:
    osc1Type = nRSI1;
case CCI:
    osc1Type = CCI(Length = osc1Length);
case MACD:
    osc1Type = MAC(osc1Source);
case ChandeMomOsc:
    osc1Type = ChandeMomentumOscillator(osc1Length);
case STOCH:
    osc1Type = stoch(osc1Source, h, l, osc1Length);
case StochRSI:
    osc1Type = Average(stoch(nRSI1, nRSI1, nRSI1, osc1Length), 3);
case MFI:
    osc1Type = MoneyFlowIndex(Length = osc1Length);
case UltimateOsc:
    osc1Type = uo(osc1Length / 2, osc1Length, osc1Length * 2);
case Williams:
    osc1Type = WilliamsPercentR(Length = osc1Length);
case TSI:
    osc1Type = TrueStrengthIndex(longLength = osc1Length * 2, shortLength = osc1Length);
case STC:
    osc1Type = stc(osc1Source, osc1Length, osc1Length * 2, osc1Length / 2, 3, 3);
case TrueRange:
    osc1Type = tr * Sign(osc1Source - osc1Source[1]);
case IntradayMomIndex:
    osc1Type = IntradayMomentumIndex(Length = osc1Length);
case FisherTransform:
    osc1Type = FisherTransform(Price = osc1Source, Length = osc1Length).FT;
}
def osc2Type;
def nRSI2 = RSI(Price = osc2Source, Length = osc2Length);
switch (osc2TypeInput) {
case None:
    osc2Type = na;
case RSI:
    osc2Type = nRSI2;
case CCI:
    osc2Type = CCI(Length = osc2Length);
case MACD:
    osc2Type = MAC(osc2Source);
case ChandeMomOsc:
    osc2Type = ChandeMomentumOscillator(osc2Length);
case STOCH:
    osc2Type = stoch(osc2Source, h, l, osc2Length);
case StochRSI:
    osc2Type = Average(stoch(nRSI2, nRSI2, nRSI2, osc2Length), 3);
case MFI:
    osc2Type = MoneyFlowIndex(Length = osc2Length);
case UltimateOsc:
    osc2Type = uo(osc2Length / 2, osc2Length, osc2Length * 2);
case Williams:
    osc2Type = WilliamsPercentR(Length = osc2Length);
case TSI:
    osc2Type = TrueStrengthIndex(longLength = osc2Length * 2, shortLength = osc2Length);
case STC:
    osc2Type = stc(osc2Source, osc2Length, osc2Length * 2, osc2Length / 2, 3, 3);
case TrueRange:
    osc2Type = tr * Sign(osc2Source - osc2Source[1]);
case IntradayMomIndex:
    osc2Type = IntradayMomentumIndex(Length = osc2Length);
case FisherTransform:
    osc2Type = FisherTransform(Price = osc2Source, Length = osc2Length).FT;
}
#vwma(source, length)
script VWMA {
    input src = close;
    input len = 15;
    def v = volume;
    def VWMA = SimpleMovingAvg(src * v, len) / SimpleMovingAvg(v, len);
    plot result = VWMA;
}
#pine_swma(source) =>
script swma {
    input source = close;
    def swma = source[3] * 1 / 6 + source[2] * 2 / 6 +  source[1] * 2 / 6 + source[0] * 1 / 6;
    plot retun = swma;
}
script ALMA {
    input series = close;
    input windowsize = 9;
    input offset = 0.85;
    input sigma  = 6;
    def m = offset * (windowsize - 1);
    def s = windowsize / sigma;
    def norm;# = 0.0
    def sum;# = 0.0
    norm = fold i = 0 to windowsize with p do
           p +  Exp(-1 * Power(i - m, 2) / (2 * Power(s, 2)));
    sum = fold j = 0 to  windowsize with r do
          r + GetValue(series, windowsize - j - 1) * Exp(-1 * Power(j - m, 2) / (2 * Power(s, 2)));
    def alma = sum / norm;
    plot return = alma;
}
#export multiMa(float source, simple int length, string type) =>
script ma {
    input type = "SMA";
    input source = close;
    input length = 20;
    def multiMa =
        if type == "SMA"  then SimpleMovingAvg(source, length) else
        if type == "EMA"  then ExpAverage(source, length) else
        if type == "SMMA" then WildersAverage(source, length) else
        if type == "WMA"  then WMA(source, length) else
        if type == "VWMA" then vwma(source, length) else
        if type == "ALMA" then ALMA(source, length) else
        if type == "SWMA" then SWMA(source) else
        if type == "HMA"  then  HullMovingAvg(source, length ) else Double.NaN;
    plot return = multiMa;
}
#percentrank(Source, length) =>
script percentrank {
    input src = close;
    input len = 10;
    def percentRankCount = fold i = 1 to len + 1 with count=0 do
                           if src[i] <= src then count + 1 else count;
    def percentRank = (percentRankCount / len) * 100;
    plot return = percentRank;
}
#oscWeight(osc, center = 0.0) =>
script oscWeight {
    input osc = 1;
    input center = 0.0;
    def normalizedOsc = osc - center;
    def historicalMax = AbsValue(HighestAll(normalizedOsc));
    def historicalMin = AbsValue(LowestAll(normalizedOsc));
    def result = if osc > center then normalizedOsc / historicalMax else
                 if osc < center then - AbsValue(normalizedOsc / historicalMin) else 0;
    plot return = result;
}
#oscCenter(simple string type) =>
script oscCenter {
    input type = "RSI";
    def result = if type == "RSI" then 50 else
                 if type == "STOCH" then 50 else
                 if type == "StochRSI" then 50 else
                 if type == "MFI" then 50 else
                 if type == "Williams" then -50 else
                 if type == "UltimateOsc" then 50 else
                 if type == "STC" then 50 else 0;
    plot return = result;
}
def osc1Center = oscCenter(osc1TypeInput);
def osc2Center = oscCenter(osc2TypeInput);
def oscXCenter = oscXCenterInput;
def osc1 = osc1Type;
def osc2 = osc2Type;
def oscX = if oscXInput then oscXSource else na;

def qtyOfOscillators = (If(!IsNaN(osc1), 1, 0)) + (If(!IsNaN(osc2), 1, 0)) + (If(!IsNaN(oscX), 1, 0));
def weight1 = if IsNaN(osc1) then 0 else oscWeight(osc1, osc1Center);
def weight2 = if IsNaN(osc2) then 0 else oscWeight(osc2, osc2Center);
def weightX = if IsNaN(oscX) then 0 else oscWeight(oscX, oscXCenter);
def weight = (weight1 + weight2 + weightX) / qtyOfOscillators;

#// Relative volume weight
def relVolPctRank   = percentrank(v, relVolLookback) / 100;
def relVolumeWeight = if useRelVolWeight and !IsNaN(v) then relVolPctRank else 1;
#// Combined weight
def combinedWeight  = weight * relVolumeWeight;
#// MAs of reference source and capped weighted source.
def capUnits = if oscChannelCapMode == oscChannelCapMode."Standard deviations" then
                  StDev(refSource, refLength) else ATR(Length = 20);
def weightedSource = refSource + (Sign(combinedWeight) * Min(refSource * AbsValue(combinedWeight), capUnits*oscChannelCap));
def refer       = ma(refTypeInput, refSource, refLength);
def weightedRef = ma(refTypeInput, weightedSource, refLength);
#/ Determine bull/bear and strong bull/bear states of the oscillator channel.
def oscChannelBull = weightedRef > refer;
def oscChannelBear = !oscChannelBull;
def oscChannelBullStrong = oscChannelBull and c > refer and refer > refer[1] and weightedRef > weightedRef[1];
def oscChannelBearStrong = oscChannelBear and c < refer and refer < refer[1] and weightedRef < weightedRef[1];

#// ————— Divergence channel
def div = if divDetectionMode == divDetectionMode.Weighted then
             Sign((refer - refer[1])) != Sign((weightedRef - weightedRef[1])) else
             Sign((combinedWeight - combinedWeight[1])) != Sign((c - c[1]));
#// Level sources

# divergenceChannel(divergence, hiSrc, loSrc, breachHiSrc, breachLoSrc) =>
def divergence = div;
def hiSrc = divChannelHiSrc;
def loSrc = divChannelLoSrc;
def breachHiSrc = divBreachHiSrc;
def breachLoSrc = divBreachLoSrc;
def levelChangeUp;
def levelChangeDn;
def channelHi;
def channelLo;
def channelWasBreached;
def preBreachUpChange;
def preBreachDnChange;
def newChannel;
def channelIsBull;
def channelIsBear;
def hiChannel;
def loChannel;
def priceBreachesChannel = !divergence and !channelWasBreached[1] and
                           (breachHiSrc > channelHi[1] or breachLoSrc < channelLo[1]);
def Breached = channelWasBreached[1] or priceBreachesChannel;
#    // We only change levels on divergences.
if divergence {
    if Breached and !divergence[1] {
        channelHi           = hiSrc;
        channelLo           = loSrc;
        hiChannel           = hiSrc;
        loChannel           = loSrc;
        channelIsBull       = no;
        channelIsBear       = no;
        channelWasBreached  = no;
        newChannel          = yes;
        levelChangeUp       = AbsValue(Sign(channelHi - channelHi[1]));
        levelChangeDn       = AbsValue(Sign(channelLo - channelLo[1]));
        preBreachUpChange   = 0;
        preBreachDnChange   = 0;
    } else {
        channelHi           = Max(zero(channelHi[1], hiSrc), hiSrc);
        channelLo           = Min(zero(channelLo[1], loSrc), loSrc);
        hiChannel           = Max(zero(hiChannel[1], hiSrc), hiSrc);
        loChannel           = Min(zero(loChannel[1], loSrc), loSrc);
        channelIsBull       = breachHiSrc > channelHi and !divergence;
        channelIsBear       = breachLoSrc < channelLo and !divergence;
        channelWasBreached  = channelWasBreached[1] or priceBreachesChannel;
        newChannel          = no;
        levelChangeUp       = AbsValue(Sign(channelHi - channelHi[1]));
        levelChangeDn       = AbsValue(Sign(channelLo - channelLo[1]));
        preBreachUpChange = if !(channelWasBreached or newChannel) then
                               preBreachUpChange[1] + levelChangeUp else 0;
        preBreachDnChange = if !(channelWasBreached or newChannel) then
                               preBreachDnChange[1] + levelChangeDn else 0;
    }
} else {
    channelHi           = channelHi[1];
    channelLo           = channelLo[1];
    hiChannel           = na;
    loChannel           = na;
    channelIsBull       = breachHiSrc > channelHi and !divergence;
    channelIsBear       = breachLoSrc < channelLo and !divergence;
    channelWasBreached  = channelWasBreached[1] or priceBreachesChannel;
    newChannel          = no;
    levelChangeUp       = AbsValue(Sign(channelHi - channelHi[1]));
    levelChangeDn       = AbsValue(Sign(channelLo - channelLo[1]));
    preBreachUpChange = if !(channelWasBreached or newChannel) then
                           preBreachUpChange[1] + levelChangeUp else 0;
    preBreachDnChange = if !(channelWasBreached or newChannel) then
                           preBreachDnChange[1] + levelChangeDn else 0;
}
def divChannelHi = channelHi;
def divChannelLo = channelLo;
def divChannelBull = channelIsBull;
def divChannelBear = channelIsBear;
def divChannelBreached = channelWasBreached;
def newDivChannel = newChannel;
def preBreachUpChanges = preBreachUpChange;
def preBreachDnChanges = preBreachDnChange;
def HidivChannel = hiChannel;
def LodivChannel = loChannel;

#/ If needed, take a guess on the state of the channel when it has not yet been breached.
def preBreachBiasBull = !divChannelBreached and divChannelBias and preBreachUpChanges > preBreachDnChanges;
def preBreachBiasBear = !divChannelBreached and divChannelBias and preBreachUpChanges < preBreachDnChanges;

#// Strong bull/bear states occur when the divergence channel's bull/bear state matches that of the oscillator channel.
def divChannelBullStrong = divChannelBull and oscChannelBullStrong;
def divChannelBearStrong = divChannelBear and oscChannelBearStrong;
def plotDivLineValues = divLinesShow or divChannelShow;

#// ————— Oscillator Channel lines and fill.
#// Determine colors.
def refLineColor;
if oscChannelBullStrong {
    refLineColor    = 2;
} else {
    if oscChannelBearStrong {
        refLineColor    = -2;
    } else {
        if oscChannelBull {
            refLineColor    = 1;
        } else {
            if oscChannelBear {
                refLineColor    = -1;
            } else {
                refLineColor    = 0;
            }
        }
    }
}
def oscColor = if combinedWeight > 0 then 2 else
               if combinedWeight < 0 then -2 else 0;

#// Plot lines and fill them.
def plotOscLineValues = reflLineShow or osclLineShow or oscChannelShow;
plot weightedPlot = if plotOscLineValues then weightedRef else na; #"Weighted Reference"
weightedPlot.AssignValueColor( if osclLineShow then
                               if refLineColor == 2 then GlobalColor("lime") else
                               if refLineColor == 1 then GlobalColor("teal") else
                               if refLineColor == -2 then GlobalColor("pink") else
                               if refLineColor == -1 then GlobalColor("maroon") else Color.GRAY else Color.GRAY);
weightedPlot.SetLineWeight(2);

plot refPlot = if plotOscLineValues and !IsNaN(combinedWeight) then refer else na;# "Reference",
refPlot.AssignValueColor( if reflLineShow then
                          if refLineColor == 2 then GlobalColor("lime") else
                          if refLineColor == 1 then GlobalColor("teal") else
                          if refLineColor == -2 then GlobalColor("pink") else
                          if refLineColor == -1 then GlobalColor("maroon") else Color.GRAY else Color.GRAY);

AddCloud(If(refLineColor == 2 or refLineColor == -2, weightedPlot, na), refPlot, GlobalColor("lime_md"), GlobalColor("pink_md"));
AddCloud(If(refLineColor == 1 or refLineColor == -1, weightedPlot, na), refPlot, GlobalColor("teal_md"), GlobalColor("maroon_md"));

#/ ————— Divergence channel lines and fill.
#// Determine colors.
def divChannelColor;
if divChannelBreached {
    if divChannelBullStrong {
        divChannelColor  = 2;
    } else {
        if divChannelBearStrong {
            divChannelColor  = -2;
        } else {
            if divChannelBull {
                divChannelColor  = 1;
            } else {
                if divChannelBear {
                    divChannelColor  = -1;
                } else {
                    divChannelColor  = 0;
                }
            }
        }
    }
} else {
    if (divChannelBias and preBreachBiasBull) {
        divChannelColor = 1;
    } else {
        if (divChannelBias and preBreachBiasBear) {
            divChannelColor = -1;
        } else {
            divChannelColor  = 0;
        }
    }
}
#------------------------
plot HiPlotSrc  = if plotDivLineValues then HidivChannel else na;
plot LoPlotSrc  = if plotDivLineValues then LodivChannel else na;#
HiPlotSrc.AssignValueColor(if !divChannelBias then Color.GRAY else
                           if divChannelColor == 1 then GlobalColor("teal") else
                           if divChannelColor == -1 then GlobalColor("maroon") else Color.GRAY);
LoPlotSrc.AssignValueColor(if !divChannelBias then Color.GRAY else
                           if divChannelColor == 1 then GlobalColor("teal") else
                           if divChannelColor == -1 then GlobalColor("maroon") else Color.GRAY);
#---------------------------------------
def HiPlot = if IsNaN(c) or !IsNaN(HiPlotSrc) then na else divChannelHi;
def LoPlot = if IsNaN(c) or !IsNaN(LoPlotSrc) then na else divChannelLo;

plot divChannelHiPlot  = if plotDivLineValues then HiPlot else na;#, "Divergence Channel Hi"
divChannelHiPlot.AssignValueColor(if (!newDivChannel and divLinesShow) then
                          if divChannelColor == 2 then GlobalColor("lime") else
                          if divChannelColor == 1 then GlobalColor("teal") else
                          if divChannelColor == -2 then GlobalColor("pink") else
                          if divChannelColor == -1 then GlobalColor("maroon") else
                              Color.GRAY else Color.GRAY);
plot divChannelLoPlot  = if plotDivLineValues then LoPlot else na;#, "Divergence Channel Lo"
divChannelLoPlot.AssignValueColor(if (!newDivChannel and divLinesShow) then
                          if divChannelColor == 2 then GlobalColor("lime") else
                          if divChannelColor == 1 then GlobalColor("teal") else
                          if divChannelColor == -2 then GlobalColor("pink") else
                          if divChannelColor == -1 then GlobalColor("maroon") else
                              Color.GRAY else Color.GRAY);

AddCloud(if !divChannelShow then na else If(divChannelColor == 2 , divChannelHiPlot, na), divChannelLoPlot, GlobalColor("lime_md"));
AddCloud(if !divChannelShow then na else If(divChannelColor == 1 , divChannelHiPlot, na), divChannelLoPlot, GlobalColor("teal_md"));
AddCloud(if !divChannelShow then na else If(divChannelColor == -1, divChannelHiPlot, na), divChannelLoPlot, GlobalColor("maroon_md"));
AddCloud(if !divChannelShow then na else If(divChannelColor == -2, divChannelHiPlot, na), divChannelLoPlot, GlobalColor("pink_md"));

#--- Bar Color
def barColor;
if barsEmptyOnDecVol and v < v[1] and !divergence {
    barColor = -3;
} else {
    if colorMode == 1 {
        barColor = if divergence then 3 else -3;
    } else {
        if colorMode == 2 {
            barColor = if divergence then 3 else
                     if oscChannelBullStrong then 2 else
                     if oscChannelBearStrong then -2 else
                     if oscChannelBull then 1 else
                     if oscChannelBear then -1 else 0;
        } else {
            if colorMode == 3 {
                barColor = if divergence then 3 else
                     if divChannelBullStrong then 2 else
                     if divChannelBearStrong then -2 else
                     if divChannelBull then 1 else
                     if divChannelBear then -1 else 0;
            } else {
                if colorMode == 4 {
                    barColor = if divergence then 3 else
                     if oscChannelBullStrong and divChannelBullStrong then 2 else
                     if oscChannelBearStrong and divChannelBearStrong then -2 else
                     if (oscChannelBull or oscChannelBullStrong) and (divChannelBull or divChannelBullStrong) then 1 else
                     if (oscChannelBear or oscChannelBearStrong) and (divChannelBear or divChannelBearStrong) then -1 else 0;
                } else {
                    barColor = 0;
                }
            }
        }
    }
}
AssignPriceColor( if !colorMode or barColor == -3 then Color.CURRENT else
                  if barColor == 3 then GlobalColor("orange") else
                  if barColor == 2 then GlobalColor("lime") else
                  if barColor == -2 then GlobalColor("pink") else
                  if barColor == 1  then GlobalColor("teal") else
                  if barColor == -1 then GlobalColor("maroon") else
                  Color.GRAY);


#--- END Code
 
Last edited by a moderator:

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

This took a lot of work.... for that I'm appreciative of your time.
A couple of quick questions, I was looking through the bar colors and was wondering what the orange bar color represents. Also does the "refl line show" represent the line on the chart that would show the divergences that plot the channels?
thanks!
 
Thank you, @samer800, for the generosity of your time and the substantial efforts expended on the many TV conversions you have done...It is truly a great service to this community...

As you have requested, I have done some preliminary testing and the indicator seems to function as advertised...I will continue to test and let you know if anything changes...
 
This took a lot of work.... for that I'm appreciative of your time.
A couple of quick questions, I was looking through the bar colors and was wondering what the orange bar color represents. Also does the "refl line show" represent the line on the chart that would show the divergences that plot the channels?
thanks!
orange bar color represents the divergences bars. the indicator has two parts. the oscillator channel and the divergence channel. you may go through below explanation from the creator.

Oscillator Channel

The oscillator channel is the space between two moving averages: the reference line and a weighted version of that line. The reference line is a moving average of a type, source and length which you select. The weighted line uses the same settings, but it averages the oscillator-weighted price source.

The weight applied to the source of the reference line can also include the relative size of the bar's volume in relation to previous bars. The effect of this is that the oscillator's weight on bars with higher total volume will carry greater weight than those with lesser volume.

The oscillator channel can be in one of four states, each having its corresponding color:
 • Bull (teal): The weighted line is above the reference line.
 • Strong bull (lime): The bull condition is fulfilled and the bar's close is above the reference line and both the reference and the weighted lines are rising.
 • Bear (maroon): The weighted line is below the reference line.
 • Strong bear (pink): The bear condition is fulfilled and the bar's close is below the reference line and both the reference and the weighted lines are falling.


Divergences

In the context of this indicator, a divergence is any bar where the slope of the reference line does not match that of the weighted line. No directional bias is assigned to divergences when they occur. You can also choose to define divergences as differences in polarity between the oscillator's slope and the polarity of close-to-close values. This indicator's divergences are designed to identify transition levels. They have no polarity; their bullish/bearish bias is determined by the behavior of price relative to the divergence channel after the divergence channel is built.


Divergence Channel

The divergence channel is the space between two levels (by default, the bar's low and high) saved when divergences occur. When price has breached a channel and a new divergence occurs, a new channel is created. Until that new channel is breached, bars where additional divergences occur will expand the channel's levels if the bar's price points are outside the channel.

Price breaches of the divergence channel will change its state. Divergence channels can be in one of five different states:
 • Bull (teal): Price has breached the channel to the upside.
 • Strong bull (lime): The bull condition is fulfilled and the oscillator channel is in the strong bull state.
 • Bear (maroon): Price has breached the channel to the downside.
 • Strong bear (pink): The bear condition is fulfilled and the oscillator channel is in the strong bear state.
 • Neutral (gray): The channel has not been breached.
 
Last edited by a moderator:
Good God man, this thing is AWESOME!!! I just modified a divergence script yesterday and this blows them all out of the water. Thank you for sharing this.
 
One request. can you change the color of the clouds, flip the pink and red, and the candle colors from pink to red?
 
One request. can you change the color of the clouds, flip the pink and red, and the candle colors from pink to red?
  1. click on the gear to the right of the study on your chart
  2. scroll down to the bottom of the customizer box that opened
  3. click on Globals
  4. click on the color you want to change
  5. change the colors to anything you want
  6. click on save as default at the top of the box (this will permanently save your colors into the study)
DmNnZAf.png
 
orange bar color represents the divergences bars. the indicator has two parts. the oscillator channel and the divergence channel. you may go through below explanation from the creator.

Oscillator Channel

The oscillator channel is the space between two moving averages: the reference line and a weighted version of that line. The reference line is a moving average of a type, source and length which you select. The weighted line uses the same settings, but it averages the oscillator-weighted price source.

The weight applied to the source of the reference line can also include the relative size of the bar's volume in relation to previous bars. The effect of this is that the oscillator's weight on bars with higher total volume will carry greater weight than those with lesser volume.

The oscillator channel can be in one of four states, each having its corresponding color:
 • Bull (teal): The weighted line is above the reference line.
 • Strong bull (lime): The bull condition is fulfilled and the bar's close is above the reference line and both the reference and the weighted lines are rising.
 • Bear (maroon): The weighted line is below the reference line.
 • Strong bear (pink): The bear condition is fulfilled and the bar's close is below the reference line and both the reference and the weighted lines are falling.


Divergences

In the context of this indicator, a divergence is any bar where the slope of the reference line does not match that of the weighted line. No directional bias is assigned to divergences when they occur. You can also choose to define divergences as differences in polarity between the oscillator's slope and the polarity of close-to-close values. This indicator's divergences are designed to identify transition levels. They have no polarity; their bullish/bearish bias is determined by the behavior of price relative to the divergence channel after the divergence channel is built.


Divergence Channel

The divergence channel is the space between two levels (by default, the bar's low and high) saved when divergences occur. When price has breached a channel and a new divergence occurs, a new channel is created. Until that new channel is breached, bars where additional divergences occur will expand the channel's levels if the bar's price points are outside the channel.

Price breaches of the divergence channel will change its state. Divergence channels can be in one of five different states:
 • Bull (teal): Price has breached the channel to the upside.
 • Strong bull (lime): The bull condition is fulfilled and the oscillator channel is in the strong bull state.
 • Bear (maroon): Price has breached the channel to the downside.
 • Strong bear (pink): The bear condition is fulfilled and the oscillator channel is in the strong bear state.
 • Neutral (gray): The channel has not been breached.
A great indicator. I have used it with great success and wanted to give you a shout out. The channels the indicator produces are very valuable to the way I trade.

However, is there a way to have a second Aggergation within the indicator? I use the Workbench on a fifteen-minute chart but would love to be able to see the longer (hour) signals the indicator produces on the same chart.

This would be outstanding! Thanks
 
A great indicator. I have used it with great success and wanted to give you a shout out. The channels the indicator produces are very valuable to the way I trade.

However, is there a way to have a second Aggergation within the indicator? I use the Workbench on a fifteen-minute chart but would love to be able to see the longer (hour) signals the indicator produces on the same chart.

This would be outstanding! Thanks
Can you post chart illustrations of your entries and exits?
 
Can you post chart illustrations of your entries and exits?
Hello, I use the Workbench Indicator mostly as a support and resistance detector. It also shows the trend within the oscillator, which is helpful of course. But mostly I find the channels produced by the divergences most useful.

I use the channels as support and resistance, as well as areas for possible breakouts or breakdowns depending on price action and momentum.

I also use the B3 Consolidation Box indicator on my charts as well, as they show slightly different periods of consolidation. But together with the Workbench, they produce great support and resistance trading strategies.


GCfaHpG.png
 
Nice work, but the hollow (not solid like above) Maroon candle is almost impossible to see, even on the blackest screen. I tried modifying it in "Edit Sources" (did not see the gear option shown above), and I lose the whole thing.
How can I change it?
 

Attachments

  • GCfaHpG.png
    GCfaHpG.png
    208.2 KB · Views: 173
Last edited by a moderator:

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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