Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different SuperTrend results #867

Open
sussyboiiii opened this issue Dec 23, 2024 · 6 comments
Open

Different SuperTrend results #867

sussyboiiii opened this issue Dec 23, 2024 · 6 comments
Labels
bug Something isn't working duplicate This issue or pull request already exists help wanted Extra attention is needed

Comments

@sussyboiiii
Copy link

sussyboiiii commented Dec 23, 2024

Which version are you running? The lastest version is on Github. Pip is for major releases.
0.3.14b0

Do you have TA Lib also installed in your environment?
Yes

Have you tried the development version? Did it resolve the issue?
No

Describe the bug
When using a different source for the supertrend the results are different from the TradingView counterpart. Also it can happen that the close price of a candle is above the upperband but the signal comes the day later.

To Reproduce

def st_calc(close, upperband, lowerband):
    """Indicator: Supertrend"""
    # Calculate Results
    m = close.size
    dir_, trend = [1] * m, [0] * m
    long, short = [np.nan] * m, [np.nan] * m

    for i in range(1, m):
        if close.iloc[i] > upperband.iloc[i - 1]:
            dir_[i] = 1
        elif close.iloc[i] < lowerband.iloc[i - 1]:
            dir_[i] = -1
        else:
            dir_[i] = dir_[i - 1]
            if dir_[i] > 0 and lowerband.iloc[i] < lowerband.iloc[i - 1]:
                lowerband.iloc[i] = lowerband.iloc[i - 1]
            if dir_[i] < 0 and upperband.iloc[i] > upperband.iloc[i - 1]:
                upperband.iloc[i] = upperband.iloc[i - 1]

        if dir_[i] > 0:
            trend[i] = long[i] = lowerband.iloc[i]
        else:
            trend[i] = short[i] = upperband.iloc[i]

    return trend, dir_, lowerband, upperband

def supertrend(high, low, close, len=20, factor=3):
    # Custom Upper & Lower Bands
    src = ta.DEMA((high+low)/2, len)
    atr = ta.STDDEV(src, len)

    upper = close + atr * factor
    lower = close - atr * factor

    return st_calc(close, upper, lower)

if __name__ == "__main__":

    df = pd.read_csv("./data/INDEX_ETHUSD.csv",
        engine="c",
        parse_dates=["datetime"],
        index_col="datetime",
        usecols=["datetime", "open", "high", "low", "close", "volume"],
    )
    df = df.loc["06-01-2017":]

    trend, dir_, lower, upper = supertrend(df["high"], df["low"], df["close"])

Expected behavior
I would have expected it to behave the same way as the TradingView SuperTrend when changing the source and the atr to standard deviation.

Screenshots
I have two screenshots which show the Python and Pine SuperTrend results on INDEX:ETHUSD with the same settings.
Screenshot 2024-12-23 at 21 59 26
Screenshot 2024-12-23 at 21 54 16

Additional context
Here is the equivalent Pine code:

src = ta.dema(hl2, 20)
sd = ta.stdev(src, 20)
upperBand = src + factor * sd
lowerBand = src - factor * sd
prevLowerBand = nz(lowerBand[1])
prevUpperBand = nz(upperBand[1])
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
int _direction = 1
float superTrend = na
prevSuperTrend = superTrend[1]

if prevSuperTrend == prevUpperBand
    _direction := close > upperBand ? -1 : 1
else
    _direction := close < lowerBand ? 1 : -1
superTrend := _direction == -1 ? lowerBand : upperBand

plot(superTrend, force_overlay = true)

Here the INDEX:ETHUSD data for Python.
INDEX_ETHUSD.csv

@sussyboiiii sussyboiiii added the bug Something isn't working label Dec 23, 2024
@twopirllc twopirllc removed their assignment Dec 24, 2024
@twopirllc twopirllc added duplicate This issue or pull request already exists help wanted Extra attention is needed labels Dec 24, 2024
@sussyboiiii
Copy link
Author

What fixed this for me was to add a check at the end to see if the result actually makes sense and the closing price is not above or below any band it shouldnt be.

I also used a numpy only version as its faster but the idea is the same.

Screenshot 2024-12-26 at 17 26 28

@twopirllc
Copy link
Owner

Hello @sussyboiiii

Thanks for the info and suggestions. 👍🏼

Most beneficial is the actual exported TV supertrend values included in the INDEX_ETHUSD.csv for a more exact comparison (instead of relying on charts) if you are able to. 😎

Happy Holidays
KJ

@sussyboiiii
Copy link
Author

Merry Christmas,

the behavior is slightly different but the signals are the same now, I have compared it to the TradingView SuperTrend plotting it.

Without the extra check:
image

With it added:
image

@praveencqr
Copy link

praveencqr commented Dec 28, 2024

I used the following code and it gives me 100% same results as shown in TradingView.

import pandas_ta as pta

def calculate_supertrend(df, supertrend_length, supertrend_multiplier, type):
    st_values = f'{supertrend_length}_{supertrend_multiplier}'
    supertrend = pta.supertrend(df['ha_high'], df['ha_low'], df['ha_close'], length=supertrend_length,
                                multiplier=supertrend_multiplier)
    df[f'ST_l_{type}'] = supertrend[f'SUPERTl_{st_values}']
    df[f'ST_s_{type}'] = supertrend[f'SUPERTs_{st_values}']
    df[f'ST_{type}'] = supertrend[f'SUPERT_{st_values}']
    df[f'ST_d_{type}'] = supertrend[f'SUPERTd_{st_values}']
    return df

@twopirllc
Copy link
Owner

@praveencqr

Which pta version?

@praveencqr
Copy link

@twopirllc
Version: 0.3.14b0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working duplicate This issue or pull request already exists help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants