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

Zigzag indicator implementation using numba will close issue #443 and complete pr #693 #761

Merged
merged 3 commits into from
Jun 15, 2024

Conversation

aligheshlaghi97
Copy link

Hello @twopirllc

I'm pleased to present a new pull request for the completion of the zigzag indicator.
In this update, I've utilized Numba for implementation, as opposed to the previous approach which relied on Pandas. and compared the results with TradingView's default zigzag indicator and everything seems to be so much similar.

Below, you'll find the outcome of applying a deviation of 5% and a pivot leg of 10 to the BTCUSD daily chart:
Screenshot from 2024-02-07 14-08-49

Compare this with the result of the new implementation under the same configuration:
Screenshot from 2024-02-07 14-08-26

In order to test it yourself, use the following code:

import sys
import importlib
import numpy as np
from numba import njit
import yfinance as yf
import plotly.graph_objects as go

sys.path.insert(1, '/path-to/pandas-ta')
from pandas_ta import zigzag

ticker = "BTC-USD"
start = "2020-01-01"
interval = "1d"

# Retrieve the stock data using yfinance
data = yf.download(ticker, start, interval=interval)

# Extract the OHLC data
ohlc_data = data.loc[:, ["Open", "High", "Low", "Close"]]

highs = ohlc_data['High']
lows = ohlc_data['Low']

df = zigzag(high=highs, low=lows, pivot_leg=10, price_deviation=5)

high_pivots = df[(df['ZIGZAGt_5%_10'].notna()) & (df['ZIGZAGt_5%_10']==1)]
low_pivots = df[(df['ZIGZAGt_5%_10'].notna()) & (df['ZIGZAGt_5%_10']==-1)]
all_pivots = df[df['ZIGZAGt_5%_10'].notna()]

fig = go.Figure()

fig.add_trace(
    go.Candlestick(
        x=data.index,
        open=ohlc_data["Open"],
        high=ohlc_data["High"],
        low=ohlc_data["Low"],
        close=ohlc_data["Close"],
        name="OHLC",
    )
)

fig.add_trace(go.Scatter(
    x=high_pivots.index, 
    y=high_pivots['ZIGZAGv_5%_10'], 
    mode="markers", 
    name="zigzag highs", 
    marker_color='rgba(0, 152, 0, .8)',
    marker_size=10,
))

fig.add_trace(go.Scatter(
    x=low_pivots.index, 
    y=low_pivots['ZIGZAGv_5%_10'], 
    mode="markers", 
    name="zigzag lows", 
    marker_color='rgba(152, 0, 0, .8)', 
    marker_size=10
))

fig.add_trace(go.Scatter(
    x=all_pivots.index, 
    y=all_pivots['ZIGZAGv_5%_10'], 
    mode="lines", 
    name="zigzag",
    line_color='rgba(0, 0, 152, 0.8)'
))

# Set the layout
fig.update_layout(
    title="ZigZag Indicator Implementations",
    xaxis_rangeslider_visible=False,
    xaxis_title="Date",
    yaxis_title="Price",
    legend=dict(x=0.9, y=1, bgcolor="rgba(255, 255, 255, 0.5)", bordercolor="rgba(0, 0, 0, 0.5)"),
    showlegend=True,
)

# Show the plot
fig.show()

Additionally, I believe this code snippet could prove beneficial for @AureliusMarcusHu and @KilianB in their Pandas-TA coding endeavors.

@twopirllc
Copy link
Owner

@aligheshlaghi97

Great! Will check it out when I can. 😎

@dmastapkovich
Copy link

@aligheshlaghi97

Check the tests, please. That's a very cool improvement.

@aligheshlaghi97
Copy link
Author

@dmastapkovich

I reviewed the logs and it seems that the issues aren't stemming from my implementation. Can you confirm, @twopirllc ?

@twopirllc
Copy link
Owner

@aligheshlaghi97 & @dmastapkovich

Failed Tests

These fails occur after adding/removing indicators, so yes adding zigzag creates the following
errors because the column counts were not updated in test_studies.py. But these are minor issues and a simple fix and I can take care of them after I have reviewed and made any touch ups before merging zigzag into development.

FAILED tests/test_studies.py::test_study_category_columns[trend-30] - assert ...
FAILED tests/test_studies.py::test_study_category_columns[all-323] - assert 3...
FAILED tests/test_studies.py::test_study_all_multirun_talib[False] - assert 6...
FAILED tests/test_studies.py::test_study_all_multirun_talib[True] - assert 62...

I suppose some additional testing code can be added to determine column counts automatically to avoid
these minor fails but it is not a priority.

*Warnings

Lastly, you can ignore the Warnings as most of them will be taken care of on the next development update. The only remaining Warning I have to figure out is:

../env11/lib/python3.11/site-packages/pandas_datareader/compat/__init__.py:11: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.
    PANDAS_VERSION = LooseVersion(pd.__version__)

Supposedly it is still an open issue for pandas-datareader until a new release comes out.

@KilianB
Copy link

KilianB commented May 21, 2024

Thank you very much for the improved version. It looks promising and I'll play a around with it a bit more once I have a bit more time.
One small odity in your example above are two low pivots back to back without a high in between

2021-09-07 00:00:00 | -1.0 | 43285.20703125 | 14.256289283356438
2021-09-13 00:00:00 | -1.0 | 43591.3203125 | 17.524664899408478

image

@aligheshlaghi97 aligheshlaghi97 mentioned this pull request May 21, 2024
@einarjohnson
Copy link

this is awesome. when will this be merged into the development branch?

twopirllc added a commit that referenced this pull request Jun 15, 2024
@twopirllc twopirllc merged commit 43ce3e5 into twopirllc:development Jun 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants