OBV MACD Indicator For ThinkOrSwim

DigitsM

New member
VIP
This seems to work well.

++++++
"Notes by author:
So this script is my improvement to macd that we all know. It faster and more accurate with less lag
first is based on OBV as it primary source
next we convert the OBV to MA style format, in this case we can add all form of MA in order to calculate it. As you will see in settings it has many type of MA as each behave differently
I make the signal to be in linear form just to make it more sharp/ and in the end in order to make the signal I use Alex Grover method (this guy is a genius:))
in final step, we can make pivots point on our new for macd
end result is a faster, more accurate MACD and much more options for modification than the regular macd
this is volume indicator based, so in some graph where volume does not exist this will not wo
rk"
FYMz4gn.png

Here is the original Tradingview code:
https://www.tradingview.com/script/jXvqrU4q-OBV-MACD-Indicator/

For the new ThinkOrSwim code, you must scroll down to the next post
 
Last edited by a moderator:

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

This seem to work well and wanted to see if this can be converted to Thinkscript

++++++
https://www.tradingview.com/script/jXvqrU4q-OBV-MACD-Indicator/
Credits to RafaelZioni

"Notes by author:
So this script is my improvement to macd that we all know . it faster and more accurate with less lag
first is based on OBV as it primary source
next we convert the OBV to MA style format , in this case we can add all form of MA in order to calculate it . as you will see in settimgs it has many type of MA as each beahave differently
I make the signal to be in linear form jst to make it more sharp/ and in the end in order to make the signal i use Alex grover method (this guy is a genius:) )
in final step we can make pivots point on our new for macd
end resolt is a faster more accurate MACD and much more options fro modification then the regular macd
this is volume indicator based so in some graph where volume does not exist this will not wo
rk"

Open-source script​

In true TradingView spirit, the author of this script has published it open-source, so traders can understand and verify it. Cheers to the author! You may use it for free, but reuse of this code in publication is governed by House rules. You can favorite it to use it on a chart.

View attachment 23807

Code:

//@version=4
study("OBV MACD Indicator",overlay=false)
// MACD
src1 = close
window_len = 28
v_len = 14
price_spread = stdev(high-low, window_len)
v = cum(sign(change(src1)) * volume)
smooth = sma(v, v_len)
v_spread = stdev(v - smooth, window_len)
shadow = (v - smooth) / v_spread * price_spread
out = shadow > 0 ? high + shadow : low + shadow
//plot(out, style=line,linewidth=3, color=color)
len10=input(1,title="OBV Length ")
obvema=ema(out,len10)
//
src = obvema
type = input(defval="DEMA", title="MA Type", options=["TDEMA", "TTEMA", "TEMA", "DEMA", "EMA", "AVG", "THMA", "ZLEMA", "ZLDEMA", "ZLTEMA", "DZLEMA", "TZLEMA", "LLEMA", "NMA"])
showma = true
len = input(9, title="MA Length ")
showma1 = false
len1 = 26
showma2 =false
len2 = 52
nma(src, length1, length2) =>
lambda = length1 / length2
alpha = lambda * (length1 - 1) / (length1 - lambda)
ma1 = ema(src, length1)
ma2 = ema(ma1, length2)
nma = (1 + alpha) * ma1 - alpha * ma2

dema(src, len) =>
ma1 = ema(src, len)
ma2 = ema(ma1, len)
2 * ma1 - ma2
tema(src, len) =>
ma1 = ema(src, len)
ma2 = ema(ma1, len)
ma3 = ema(ma2, len)
3 * (ma1 - ma2) + ma3
tdema(src, len) =>
ma1 = dema(src, len)
ma2 = dema(ma1, len)
ma3 = dema(ma2, len)
3 * (ma1 - ma2) + ma3
ttema(src, len) =>
ma1 = tema(src, len)
ma2 = tema(ma1, len)
ma3 = tema(ma2, len)
3 * (ma1 - ma2) + ma3
tnma(src, len) =>
ma1 = nma(src, len, 3)
ma2 = nma(ma1, len, 3)
ma3 = nma(ma2, len, 3)
3 * (ma1 - ma2) + ma3
hma(src, len) => wma(2*wma(src, len/2)-wma(src, len), round(sqrt(len)))
thma(src, len) =>
ma1 = hma(src, len)
ma2 = hma(ma1, len)
ma3 = hma(ma2, len)
3 * (ma1 - ma2) + ma3
zlema(src, len) =>
lag = round((len - 1) / 2)
zlsrc = src + (src - src[lag])
ema(zlsrc, len)
zldema(src, len) =>
lag = round((len - 1) / 2)
zlsrc = src + (src - src[lag])
dema(zlsrc, len)

zltema(src, len) =>
lag = round((len - 1) / 2)
zlsrc = src + (src - src[lag])
tema(zlsrc, len)

dzlema(src, len) =>
ma1 = zlema(src, len)
ma2 = zlema(ma1, len)
2 * ma1 - ma2
tzlema(src, len) =>
ma1 = zlema(src, len)
ma2 = zlema(ma1, len)
ma3 = zlema(ma2, len)
3 * (ma1 - ma2) + ma3
llema(src, len) =>
srcnew = 0.25*src + 0.5*src[1] + 0.25*src[2]
ema(srcnew, len)

lltema(src, len) =>
srcnew = 0.25*src + 0.5*src[1] + 0.25*src[2]
tema(srcnew, len)
myma(src, len) =>
if type == "EMA"
ema(src, len)
else
if type == "DEMA"
dema(src, len)
else
if type == "TEMA"
tema(src, len)
else
if type == "TDEMA"
tdema(src, len)
else
if type == "TTEMA"
ttema(src, len)
else
if type == "THMA"
thma(src, len)
else
if type == "ZLEMA"
zlema(src, len)
else
if type == "ZLDEMA"
zldema(src, len)
else
if type == "ZLTEMA"
zltema(src, len)
else
if type == "DZLEMA"
dzlema(src, len)
else
if type == "TZLEMA"
tzlema(src, len)
else
if type == "LLEMA"
llema(src, len)
else
if type == "NMA"
nma(src, len, len1)
else
avg(ttema(src, len), tdema(src, len))

ma = showma ? myma(src, len) : na
slow_length = input(title="MACD Slow Length", type=input.integer, defval=26)
//signal_length = input(title="MACD Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9)
src12=close
plot(0,linewidth=3,color=color.black)
// Calculating MACD
slow_ma = ema(src12, slow_length)
macd =ma-slow_ma
//signal_length=input(9)
//signal = ema(macd, signal_length)
//plot(signal,linewidth=2)
src5 = macd
len5 = input(2)
offset = 0
calcSlope(src5, len5) =>
sumX = 0.0
sumY = 0.0
sumXSqr = 0.0
sumXY = 0.0
for i = 1 to len5
val = src5[len5-i]
per = i + 1.0
sumX := sumX + per
sumY := sumY + val
sumXSqr := sumXSqr + per * per
sumXY := sumXY + val * per


slope = (len5 * sumXY - sumX * sumY) / (len5 * sumXSqr - sumX * sumX)
average = sumY / len5
intercept = average - slope * sumX / len5 + slope
[slope, average, intercept]
var float tmp = na
[s, a5, i] = calcSlope(src5, len5)
tt1=(i + s * (len5 - offset))
////script based on alex grover from https://www.tradingview.com/script/KzTi6CZP-T-Channels/
p = 1,src15=tt1
b5 = 0.,dev5 = 0.,oc = 0
n5 = cum(1) - 1
a15 = cum(abs(src15 - nz(b5[1],src15)))/n5*p
b5 := src15 > nz(b5[1],src15) + a15 ? src15 : src15 < nz(b5[1],src15) - a15 ? src15 : nz(b5[1],src15)
//----
dev5 := change(b5) ? a15 : nz(dev5[1],a15)
//----
oc := change(b5) > 0 ? 1 : change(b5) < 0 ? -1 : nz(oc[1])
//----
cs = oc == 1 ? color.blue : color.red
//change(oc)>0
plot(b5,color=cs,linewidth=4,transp=50)
//
down = change(oc)<0
up = change(oc)>0
showsignal=input(false)
plot(showsignal and up ?tt1 :na, style=plot.style_cross, color=color.blue, linewidth=4, transp=0,offset=-1)
plot(showsignal and down ?tt1 :na, style=plot.style_cross, color=color.red, linewidth=4, transp=0,offset=-1)
//hist = macd - signal
//barColor =hist >= 0 and hist> signal ? color.teal : hist > 0 and hist < signal ? color.lime : hist < 0 and hist < signal ? color.red : color.orange
//plot(hist, color=barColor, style=plot.style_histogram, linewidth=3)


upper = tt1
lower = tt1
// DIVS code
piv = input(true, "Hide pivots?")
shrt = false
xbars = input(50, "period", input.integer, minval=1)
hb = abs(highestbars(upper, xbars))
lb = abs(lowestbars(lower, xbars))
max = float(na)
max_upper = float(na)
min = float(na)
min_lower = float(na)
pivoth = bool(na)
pivotl = bool(na)

max := hb == 0 ? close : na(max[1]) ? close : max[1]
max_upper := hb == 0 ? upper : na(max_upper[1]) ? upper : max_upper[1]
min := lb == 0 ? close : na(min[1]) ? close : min[1]
min_lower := lb == 0 ? lower : na(min_lower[1]) ? lower : min_lower[1]

if close > max
max := close
max
if upper > max_upper
max_upper := upper
max_upper
if close < min_lower
min_lower := lower
min_lower
if lower < min_lower
min_lower := lower
min_lower

pivoth := max_upper == max_upper[2] and max_upper[2] != max_upper[3] ? true : na
pivotl := min_lower == min_lower[2] and min_lower[2] != min_lower[3] ? true : na
plotshape(piv ? na : shrt ? na : pivoth ? max_upper + 2 : na, location=location.absolute, style=shape.labeldown, color=color.red, size=size.tiny, text="Pivot", textcolor=color.white, transp=0, offset=0)
plotshape(piv ? na : shrt ? na : pivotl ? min_lower - 2 : na, location=location.absolute, style=shape.labelup, color=color.blue, size=size.tiny, text="Pivot", textcolor=color.white, transp=0, offset=0)
check the below:

CSS:
#// Indicator for TOS
#// @RafaelZioni
#study("OBV MACD Indicator",overlay=false)
# Converted by Sam4Cok@Samer800    - 01/2025
declare lower;

input showsignal = no;
input showPivot = no; #, "Show pivots?")
input src = close;
input obvAverageLength = 14;
input stdevLength = 28;
input obvSmoothingLength = 1; #,title="OBV Length ")
input LinearRegLength = 2;
input movAvgType = {"TDEMA", "TTEMA", "TEMA",Default "DEMA", "EMA", "AVG", "THMA", "ZLEMA", "ZLDEMA", "ZLTEMA", "DZLEMA", "TZLEMA", "LLEMA", "NMA"};
input movAvgLength = 9; #, title="MA Length ")
input macdSrc = close;
input macdSlowLength = 26; #(title="MACD Slow Length", type=input.integer, defval=26)
input factor = 1.0;
input lookbackPeriod = 50; #, "period", input.integer, minval=1)

def na = Double.NaN;
def last = IsNaN(close);
#--Color
DefineGlobalColor("up" , CreateColor(33, 150, 243));
DefineGlobalColor("Dn", Color.DOWNTICK);

Script nma {
input src = close;
input length1 = 9;
input length2 = 26;
    def lambda = length1 / length2;
    def alpha = lambda * (length1 - 1) / (length1 - lambda);
    def ma1 = ExpAverage(src, length1);
    def ma2 = ExpAverage(ma1, length2);
    def nma = (1 + alpha) * ma1 - alpha * ma2;
    plot out = nma;
}
Script tdema {
input src = close;
input len = 9;
    def ma1 = dema(src, len);
    def ma2 = dema(ma1, len);
    def ma3 = dema(ma2, len);
    def tdema = 3 * (ma1 - ma2) + ma3;
    plot out = tdema;
}
Script ttema {
input src = close;
input len = 9;
    def ma1 = tema(src, len);
    def ma2 = tema(ma1, len);
    def ma3 = tema(ma2, len);
    def ttema = 3 * (ma1 - ma2) + ma3;
    plot out = ttema;
}
Script tnma {
input src = close;
input len = 9;
    def ma1 = nma(src, len, 3);
    def ma2 = nma(ma1, len, 3);
    def ma3 = nma(ma2, len, 3);
    def tnma = 3 * (ma1 - ma2) + ma3;
    plot out = tnma;
}
Script thma {
input src = close;
input len = 9;
    def ma1 = HullMovingAvg(src, len);
    def ma2 = HullMovingAvg(ma1, len);
    def ma3 = HullMovingAvg(ma2, len);
    def thma = 3 * (ma1 - ma2) + ma3;
    plot out = thma;
}
Script zlema {
input src = close;
input len = 9;
    def lag = round((len - 1) / 2, 0);
    def zlsrc = src + (src - src[lag]);
    def zelma = ExpAverage(zlsrc, len);
    plot out = zelma;
}
Script zldema {
input src = close;
input len = 9;
    def lag = round((len - 1) / 2, 0);
    def zlsrc = src + (src - src[lag]);
    def zldema = dema(zlsrc, len);
    plot out = zldema;
}
Script zltema {
input src = close;
input len = 9;
    def lag = round((len - 1) / 2, 0);
    def zlsrc = src + (src - src[lag]);
    def zltema = tema(zlsrc, len);
    plot out = zltema;
}
Script dzlema {
input src = close;
input len = 9;
    def ma1 = zlema(src, len);
    def ma2 = zlema(ma1, len);
    def dzlema = 2 * ma1 - ma2;
    plot out = dzlema;
}
Script tzlema {
input src = close;
input len = 9;
    def ma1 = zlema(src, len);
    def ma2 = zlema(ma1, len);
    def ma3 = zlema(ma2, len);
    def tzlema = 3 * (ma1 - ma2) + ma3;
    plot out = tzlema;
}
Script llema {
input src = close;
input len = 9;
    def srcnew = 0.25*src + 0.5*src[1] + 0.25*src[2];
    def llema = ExpAverage(srcnew, len);
    plot out = llema;
}
Script lltema {
input src = close;
input len = 9;
    def srcnew = 0.25*src + 0.5*src[1] + 0.25*src[2];
    def lltema = tema(srcnew, len);
    plot out = lltema;
}
def price_spread = stdev(high - low, stdevLength);
def v = if !v[1] then 1 else v[1] + (Sign(src - src[1]) * volume);
def smooth = Average(v, obvAverageLength);
def v_spread = StDev(v - smooth, stdevLength);
def shadow = (v - smooth) / v_spread * price_spread;
def obv = if IsNaN(shadow) then 0 else if shadow > 0 then high + shadow else low + shadow;
def obvema = ExpAverage(obv, obvSmoothingLength);
#input movAvgType = {"TDEMA", "TTEMA", "TEMA",Default "DEMA", "EMA", "AVG", "THMA", "ZLEMA", "ZLDEMA", "ZLTEMA", "DZLEMA", "TZLEMA", "LLEMA", "NMA"};
def ma;
Switch (movAvgType) {
Case "TDEMA" : ma = TDEMA(obvema, movAvgLength);
Case "TTEMA" : ma = TTEMA(obvema, movAvgLength);
Case "TEMA" : ma = TEMA(obvema, movAvgLength);
Case "EMA"  : ma = ExpAverage(obvema, movAvgLength);
Case "AVG"  : ma = (ttema(src, movAvgLength) + tdema(src, movAvgLength)) / 2;
Case "THMA" : ma = THMA(obvema, movAvgLength);
Case "ZLEMA"  : ma = ZLEMA(obvema, movAvgLength);
Case "ZLDEMA" : ma = ZLDEMA(obvema, movAvgLength);
Case "ZLTEMA" : ma = ZLTEMA(obvema, movAvgLength);
Case "DZLEMA" : ma = DZLEMA(obvema, movAvgLength);
Case "TZLEMA" : ma = TZLEMA(obvema, movAvgLength);
Case "LLEMA" : ma = LLEMA(obvema, movAvgLength);
Case "NMA"   : ma = nma(obvema, movAvgLength, macdSlowLength);
Default : ma = dema(obvema, movAvgLength);
}

#def ma = DEMA(obvema, movAvgLength);
#// Calculating MACD
def slow_ma = ExpAverage(macdSrc, macdSlowLength);
def macd = ma - slow_ma;
def linReg = Inertia(macd, LinearRegLength);
#////script based on alex grover from https://www.tradingview.com/script/KzTi6CZP-T-Channels/
#def src15 = if !last then tt1 else src15[1];
def b5;
def b51 = if IsNaN(b5[1]) then linReg else if !b5[1] then linReg else b5[1];
def n5 = n5[1] + 1;
def a15_ = a15_[1] + (AbsValue(linReg - b51));
def a15 = a15_ / (n5) * factor;
b5  = if linReg > (b51 + a15) then linReg else
          if linReg < (b51 - a15) then linReg else b51;
#//----
def dev5 = if !dev5[1] then a15 else if (b5 - b5[1]) then a15 else dev5[1];
#//----
def oc = if (b5 > b5[1]) then  1 else
         if (b5 < b5[1]) then -1 else oc[1];
#//----
def cs = oc == 1; # ? color.blue : color.red
#//change(oc)>0
plot line = if !last then b5 else na; #,color=cs,linewidth=4,transp=50)
plot zero = if !last then 0 else na;
line.SetLineWeight(2);
line.AssignValueColor(if cs then GlobalColor("up") else GlobalColor("dn"));
zero.SetDefaultColor(Color.GRAY);
zero.SetStyle(Curve.SHORT_DASH);
#// Signals
def down = (oc - oc[1]) < 0 ;
def up = (oc - oc[1]) > 0;
def SigUp = if showsignal and up[-1] then linReg else na;
def SigDn = if showsignal and down[-1] then linReg else na;

AddVerticalLine(SigUp, color = GlobalColor("up"));
AddVerticalLine(SigDn, color = GlobalColor("dn"));

#// DIVS code
def hb = linReg == Highest(linReg, lookbackPeriod);
def lb = linReg == Lowest(linReg, lookbackPeriod);
#def max; def min;
def max_upper;
def min_lower;

#def max1 = if hb == 0 then close else if max[1] then close else max[1];
def max_upper1 = if hb then linReg else max_upper[1]; #if max_upper[1] then upper else 0; #max_upper[1];
#def min1 = if lb == 0 then close else if min[1] then close else min[1];
def min_lower1 = if lb then linReg else min_lower[1]; #if min_lower[1] then lower else 0; #min_lower[1];

if linReg > max_upper1 {
    max_upper = linReg;
    min_lower = min_lower1;
} else if close < min_lower1 {
    max_upper = max_upper1;
    min_lower = linReg;
} else if linReg < min_lower1 {
    max_upper = max_upper1;
    min_lower = linReg;
} else {
    max_upper = max_upper1;
    min_lower = min_lower1;
}
def pivoth = showPivot and !last and max_upper == max_upper[2] and max_upper[2] != max_upper[3];
def pivotl = showPivot and !last and min_lower == min_lower[2] and min_lower[2] != min_lower[3];

AddChartBubble(pivoth and !pivoth[1], max_upper + 0.5, "Pvt", GlobalColor("dn"));
AddChartBubble(pivotl and !pivotl[1], min_lower - 0.5, "Pvt", GlobalColor("up"), no);

#-- End of CODE
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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