Adam1001
Pine Script Rookie
Pine Script Rookie
Posts: 1
Joined: July 13th, 2022

trying to convert an indicator into a strategy, get buys 2 bars later than indicator signal

I'm trying to convert this indicator:

OBV MACD Indicator by Rafael Zioni

to a strategy, this is what I have so far:

Code: Select all

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Modified from OBV MACD Indicator by Rafael Zioni


// Converted indicator to version 5
//@version=5

// changed function to STRATEGY
strategy("Test 1 OBV MACD Strategy", overlay=true, margin_long=100, margin_short=100)



// MACD
src1 = close
window_len = 28

v_len = 14
price_spread = ta.stdev(high - low, window_len)

v = ta.cum(math.sign(ta.change(src1)) * volume)
smooth = ta.sma(v, v_len)
v_spread = ta.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 = ta.ema(out, len10)

//
src = obvema

type = input.string(defval='DZLEMA', 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 = ta.ema(src, length1)
    ma2 = ta.ema(ma1, length2)
    nma = (1 + alpha) * ma1 - alpha * ma2
    nma

dema(src, len) =>
    ma1 = ta.ema(src, len)
    ma2 = ta.ema(ma1, len)
    2 * ma1 - ma2

tema(src, len) =>
    ma1 = ta.ema(src, len)
    ma2 = ta.ema(ma1, len)
    ma3 = ta.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 = ta.hma(src, len)
    ma2 = ta.hma(ma1, len)
    ma3 = ta.hma(ma2, len)
    3 * (ma1 - ma2) + ma3

zlema(src, len) =>
    lag = math.round((len - 1) / 2)
    zlsrc = src + src - src[lag]
    ta.ema(zlsrc, len)

zldema(src, len) =>
    lag = math.round((len - 1) / 2)
    zlsrc = src + src - src[lag]
    dema(zlsrc, len)

zltema(src, len) =>
    lag = math.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]
    ta.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'
        ta.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
                                                        math.avg(ttema(src, len), tdema(src, len))

ma = showma ? myma(src, len) : na
slow_length = input(title='MACD Slow Length', defval=26)
//signal_length = input(title="MACD Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9)
src12 = close


////PLOTS THE 0 LINE
plot(0, linewidth=3, color=color.new(color.black, 0))

// Calculating MACD
slow_ma = ta.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 by 1
        val = src5[len5 - i]
        per = i + 1.0
        sumX += per
        sumY += val
        sumXSqr += per * per
        sumXY += val * per
        sumXY


    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 = ta.cum(1) - 1
a15 = ta.cum(math.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 := ta.change(b5) ? a15 : nz(dev5[1], a15)

//----
oc := ta.change(b5) > 0 ? 1 : ta.change(b5) < 0 ? -1 : nz(oc[1])
//----
cs = oc == 1 ? color.blue : color.red

//// THIS PLOTS THE LINES
//change(oc)>0
plot(b5, color=cs, linewidth=4, transp=50)




down = ta.change(oc) < 0
up = ta.change(oc) > 0
showsignal = input(true)

//// THIS PLOTS THE "+" SIGNS
plot(showsignal and up ? tt1 : na, style=plot.style_cross, color=color.new(color.blue, 0), linewidth=4, offset=-1)
plot(showsignal and down ? tt1 : na, style=plot.style_cross, color=color.new(color.red, 0), linewidth=4, offset=-1)


//  I want a buy and sell order on the above signals
// Submit entry orders
if up
    //
    strategy.entry("BUY", strategy.long, 1000 ) // enter long by market if current open great then previous high

// Submit exit orders
if down
    strategy.close_all()




//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.int(50, 'period', minval=1)
hb = math.abs(ta.highestbars(upper, xbars))
lb = math.abs(ta.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

// we are not plotting anything in the strategy so these are commented out
//plotshape(piv ? na : shrt ? na : pivoth ? max_upper + 2 : na, location=location.absolute, style=shape.labeldown, color=color.new(color.red, 0), size=size.tiny, text='Pivot', textcolor=color.new(color.white, 0), offset=0)
//plotshape(piv ? na : shrt ? na : pivotl ? min_lower - 2 : na, location=location.absolute, style=shape.labelup, color=color.new(color.blue, 0), size=size.tiny, text='Pivot', textcolor=color.new(color.white, 0), offset=0)
It works in that it produces buy and sell orders on the chart and I can back test it. However my buy and sell orders appear on the chart 2 bars after the "+" signals on the indicator, by this point the entries and exits are too late as the price had changed. I only want to use this for back testing, so is there a way to get the entries and exits to match the red and blue "+" of the indicator, that is move them back 2 bars? the relevant lines of code are on lines 235 to 249.

I have been trying to solve this problem for a week with no joy, any help would be greatly appreciated.

Return to “Pine Script Q&A”