Pivot function results differ from TradingView

Question:

I’m using this code to calculate pivot points.

def pivots_low(osc, LBR, LBL):
    pivots = []
    for i in range(len(osc) - LBR):
        pivots.append(0)
        pivot = True
        if i > LBL:
            for j in range(1, LBR + 1):
                if osc[i] >= osc[i + j]:
                    pivot = False
            for j in range(1, LBL + 1):
                if osc[i] > osc[i - j]:
                    pivot = False
        if pivot is True:
            pivots[len(pivots) - 1] = osc[i]
    for i in range(LBR):
        pivots.append(0)
    return pivots

This returns an array with 0’s where there’s no pivots and the value of the pivot if there is one.

When Comparing the results to TradingView (downloaded csv with pivot points), the only time it matches exactly is when lookback left and right are both 5. Otherwise it deviates in the number of total pivots and the location of some.

But using this code to calculate pivot highs:

def pivots_high(osc, LBR, LBL):
    pivots = []
    for i in range(len(osc)-LBR):
        pivots.append(0)
        pivot = True
        if i > LBL:
            for j in range(1,LBL + 1):
                if osc[i] < osc[i-j]:
                    pivot = False
            for j in range(1,LBR + 1):
                if osc[i] <= osc[i+j]:
                    pivot = False
        if pivot is True:
            pivots[len(pivots)-1] = osc[i]
    for i in range(LBR):
        pivots.append(0)
    return pivots

the results are perfect regardless of lookback values. But the code is almost exactly the same besides comparison.

What is going wrong here? This is day 3 of having this problem and I just cant fix it

To Reproduce:

Load Data:

Full_Data = pd.read_csv(file)

use this simple function to check matches between calculated pivots and TradingView pivots.

def match_pivs(data, pivs_h, pivs_l): //Data is a DataFrame loaded from tradingview csv
    global lblh
    global lbrh
    global lbll
    global lbrl
    start = lbrh
    if lbrl > lbrh:
        start = lbrl
    match_h = 0
    tot_hd = 0
    tot_hp = 0
    match_l = 0
    tot_ld = 0
    tot_lp = 0
    for i in range(start, len(data)):
        if data['PivHigh'][i] != 0 and pivs_h[i-lbrh] != 0:
            match_h += 1
        if data['PivLow'][i] != 0 and pivs_l[i-lbrl] != 0:
            match_l += 1
        if data['PivHigh'][i] != 0:
            tot_hd += 1
        if data['PivLow'][i] != 0:
            tot_ld += 1
        if pivs_h[i] != 0:
            tot_hp += 1
        if pivs_l[i] != 0:
            tot_lp += 1
    print('PivsLow ' + str(tot_lp))
    print('DataLows ' + str(tot_ld))
    print('MatchesL ' + str(match_l))
    print('PivsHigh ' + str(tot_hp))
    print('DataHighs ' + str(tot_hd))
    print('MatchesH ' + str(match_h))

and to get csv from TradingView:

//@version=5
indicator("Data Script", overlay=true, max_labels_count=500)

leftLenL = input.int(title="Pivot Low", defval=10, minval=1, inline="Pivot Low", group=lengthGroupTitle)
rightLenL = input.int(title="/", defval=10, minval=1, inline="Pivot Low", group=lengthGroupTitle)
leftLenH = input.int(title="Pivot High", defval=10, minval=1, inline="Pivot High", group=lengthGroupTitle)
rightLenH = input.int(title="/", defval=10, minval=1, inline="Pivot High", group=lengthGroupTitle)
ph = ta.pivothigh(leftLenH, rightLenH)
pl = ta.pivotlow(leftLenL, rightLenL)
if not na(ph)
    plth := ph
else
    plth := 0.0
if not na(pl)
    pltl := pl
else
    pltl := 0.0
plot(plth, 'PivHigh')
plot(pltl, 'PivLow')

then just download csv with this script loaded.

Run program with these three lines:

pl = pivots_low(Full_Data['low'], lbll, lbrl)
ph = pivots_high(Full_Data['high'], lbrh, lblh)
match_pivs(Full_Data, ph, pl)
Asked By: Notmyname

||

Answers:

Finally found a way.

I still have no idea why that code does not work but I’ve made a different way that seems to be doing the job 100% to tradingview data.

def checkhl(data_back, data_forward, hl):
    if hl == 'high' or hl == 'High':
        ref = data_back[len(data_back)-1]
        for i in range(len(data_back)-1):
            if ref < data_back[i]:
                return 0
        for i in range(len(data_forward)):
            if ref <= data_forward[i]:
                return 0
        return 1
    if hl == 'low' or hl == 'Low':
        ref = data_back[len(data_back)-1]
        for i in range(len(data_back)-1):
            if ref > data_back[i]:
                return 0
        for i in range(len(data_forward)):
            if ref >= data_forward[i]:
                return 0
        return 1


def pivot(osc, LBL, LBR, highlow)
    left = []
    right = []
    for i in range(len(osc)):
        pivots.append(0.0)
        if i < LBL + 1:
            left.append(osc[i])
        if i > LBL:
            right.append(osc[i])
        if i > LBL + LBR:
            left.append(right[0])
            left.pop(0)
            right.pop(0)
            if checkhl(left, right, highlow):
                pivots[i - LBR] = osc[i - LBR]
    return pivots

then just do:

pivots_low = pivot(data, lbl, lbr, 'low')
pivots_high = pivot(data, lbl, lbr, 'high')

All the pivots will be in the actual position that they occur, not lbr bars after, otherwise the value will be 0.0

I’m not sure if this is efficient or not but it seems to work.

Answered By: Notmyname