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

Implement Connors RSI #737

Merged
merged 1 commit into from
Nov 29, 2023
Merged

Conversation

luisbarrancos
Copy link
Contributor

@luisbarrancos luisbarrancos commented Nov 24, 2023

Implement the Connors RSI using the Wilder's RSI indicator, as discussed in #349 .
This implementation is using Pandas-TA built-in (W)RSI for the closing price and streak RSI, and using NumPy for the streaks computation and percent rank computation.
It was tested with OHLCVA timeseries with 1 million entries, and timeit shows that for the native RSI without TA-lib we have

Total execution time for crsi: 4.437666 seconds
Average execution time for crsi: 0.221883 seconds

while with TA-lib we have:

Total execution time for crsi: 3.447122 seconds
Average execution time for crsi: 0.172356 seconds

for an average of 20 runs.
The screenshot below shows only 251 trading days of OHLCVA data of a security, and the lookback period is 100 (the defaults are 2/3/100 for this indicator)

crsi

@twopirllc for convenience both the calculations to calculate the streak and the percent rank are in their own functions with docstrings and doctests. I don't know if you prefer to remove the doctests or leave them since you have your own unit tests. The sources as discussed in #349 are An Introduction to ConnorsRSI, by Connors, L., Alvarez, C., Radtke, M. (2012), ISBN: 978-0-9853072-9-5, and i confirmed with the original author about the RSI used. It was Wilder's RSI from New Concepts in Technical Trading Systems, , ISBN 0-89459-027-8.
Do note that the lookback period for the percent rank is 100 periods, so if a series starts at $t=0$ then we would only get the first $\text{CRSI}$ value at $t=100$.

The previous notebook for the TMO indicator wasn't added to the development branch, I don't know if by omission or intention, but if there's interest in the notebook, i can submit another PR with a notebook that fixes the dates in the TMO notebook given earlier and that also adds the CRSI example from the screenshot above. The idea was to continue using this notebook to add more indicator examples as they're implemented.

@luisbarrancos luisbarrancos changed the base branch from main to development November 24, 2023 10:41
@luisbarrancos
Copy link
Contributor Author

luisbarrancos commented Nov 24, 2023

@twopirllc please don't merge yet since I'm still running tests, but any reviews or suggestions are most welcome.

Update: i'm done reviewing everything again. If there's the need for a TV compatibility mode, let me know so that i can update the PR.

@twopirllc
Copy link
Owner

@luisbarrancos

please don't merge yet since I'm still running tests, but any reviews or suggestions are most welcome.

Looks good to me! 😎
No worries. Whenever is cool.

Update: i'm done reviewing everything again. If there's the need for a TV compatibility mode, let me know so that i can update the PR.

If you don't mind. There seems to be of a lot TV users.

Thank you for helping.

@luisbarrancos
Copy link
Contributor Author

luisbarrancos commented Nov 27, 2023

@twopirllc If you don't mind dissecting this with me, there is a crucial ambiguity in the original text that can lead to different results, depending on how one interprets the lookback period. This forced me to re-evaluate my interpretation. Any feedback would be appreciated:

For example, if the look-back period is 20 days, then we would compare today's 2.0% return to the one-day returns from each of the previous 20 days.

Quoted from the 2nd paragraph, page 8 of the original document here.

Since $R_i = \frac{R_{i} - R_{i-1}}{R_{i-1}}$ and we need $n$ days to compute $n-1$ return values, then either the lookback is the period in days used to compute the $n-1$ returns and compare with the current return, or the lookback is the period in $n$ days with $n$ returns compared to the current return.

I think the authors are referring to the $n$ returns in the precending $n$ days in the lookback period, hence for a lookback period of 3 days, where the current day is 6, we would be comparing $R_i < R_6 \mid i \in \{3, 4, 5\}$.
Do you understand it in the same way? If so, then the PR needs an adjustment for the calculate_percent_rank function and we can skip the tvmode:bool flag.

With this update the results are for the same 1 million length OHLCVA dataframe, without TAlib

Total execution time for crsi: 4.519256 seconds
Average execution time for crsi: 0.225963 seconds

and with TAlib

Total execution time for crsi: 3.497563 seconds
Average execution time for crsi: 0.174878 seconds

Update: it's confirmed by the original author that this is indeed the case, so the PR is ready. Let me know if you want the notebook as well, where i group the TMO indicator, plotting backends and CRSI indicator. This can be used for some other indicators in the future as well.

Rely on Pandas-TA built-in Wilder's RSI indicator and TA-lib
counterparts, and implement percent_rank and streak calculation
functions using NumPy. This was tested against large time series with 1
million entries and found to be performant as detailed in the PR ticket.
Add separate streak and percent rank functions with doctests.
@twopirllc
Copy link
Owner

@luisbarrancos

Update: it's confirmed by the original author that this is indeed the case, so the PR is ready.

Awesome job! I'll try and merge before the end of the week.

Let me know if you want the notebook as well, where i group the TMO indicator, plotting backends and CRSI indicator. This can be used for some other indicators in the future as well.

Not right now, though maybe in the future. 🤷🏼‍♂️

I have been doing something similar though but with matplotlib notebook for each indicator. When I can finally update main, I plan to include the notebook in the examples directory.

😎

@luisbarrancos
Copy link
Contributor Author

luisbarrancos commented Nov 29, 2023

Not right now, though maybe in the future. 🤷🏼‍♂️

I have been doing something similar though but with matplotlib notebook for each indicator. When I can finally update main, I plan to include the notebook in the examples directory.

All right. I'll keep them in my fork under a branch notebooks. If at some point someone needs to build plots equivalent to the TV plots and the sometimes many variants of an indicator they can consult the notebooks there. I tried matplotlib, but I like the ability to transform a PlotLy plot into a DASH dashboard where you can just choose an asset, indicator(s) and see everything updated dynamically.

@twopirllc
Copy link
Owner

@luisbarrancos

All right. I'll keep them in my fork under a branch notebooks. If at some point someone needs to build plots equivalent to the TV plots and the sometimes many variants of an indicator they can consult the notebooks there.

On second thought, it would be great to include the notebook with Plotly implementations. Are you creating them for all the indicators or just some that are difficult/tricky to plot?

I am only doing matplotlib because of it's integration with pandas and it provides a minimal example so users can ensure that the indicators plot as expected.

twopirllc added a commit that referenced this pull request Nov 29, 2023
@twopirllc twopirllc merged commit dd0614b into twopirllc:development Nov 29, 2023
1 check passed
@luisbarrancos
Copy link
Contributor Author

@luisbarrancos

All right. I'll keep them in my fork under a branch notebooks. If at some point someone needs to build plots equivalent to the TV plots and the sometimes many variants of an indicator they can consult the notebooks there.

On second thought, it would be great to include the notebook with Plotly implementations. Are you creating them for all the indicators or just some that are difficult/tricky to plot?

So far i created for the TMO, CRSI indicators, and i have one for the Chande-Kroll stop indicator. The reason being that besides the official implementations given in the author's books, there are other parallel implementations in TV that have some extra options.
I thought users might want to see how you can plot these in order to replicate the TV charts, specially when there are many variants.

Answering your last question, so far i was adding only the ones that are tricky to plot, with dynamic/conditional shading, although I do have candlesticks, volume and moving average traces as well.

I am only doing matplotlib because of it's integration with pandas and it provides a minimal example so users can ensure that the indicators plot as expected.

It is a lot easier to do this in matplotlib, specially when you have dynamic shading, but for my use case (and eyesight) the ability to have zooming, panning, dynamic trace selection and the ability to do DASH dashboards makes it preferable to matplotlib, despite its countless idiossincracies.

I'll do this. I'll create a notebooks branch in my fork, based on Pandas-TA development, for long term development of notebooks, dashboards, and we can take it from there, either discussing there the need to plot a specific indicator to be plotted, or here even.

@luisbarrancos luisbarrancos deleted the issue_349 branch November 30, 2023 03:13
@sabbaticas
Copy link

@luisbarrancos - Are we waiting on the plotly examples before the crsi function be merged into the main from the development branch? I have been playing around with implementing my own CRSI, and then noticed this PR, the implementation is far more thorough than what i've coded this afternoon.

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.

3 participants