twopirllc / pandas-ta

Technical Analysis Indicators - Pandas TA is an easy to use Python 3 Pandas Extension with 150+ Indicators
https://twopirllc.github.io/pandas-ta/
MIT License
5.4k stars 1.05k forks source link

tsignals generating wrong single with more than 2 indicator in strategy #294

Open codesutras opened 3 years ago

codesutras commented 3 years ago

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

panda-ta=0.2.75b

Describe the bug tsignals indicator is giving few wrong trade entry/exits in case of using multiple indicators. I've tried to use MACD with two SMA. And results are varying as per the chart.

To Reproduce

#dump the attached csv file (it have close column)
dump_df  #with strategy applied data
cnd = (dump_df['MACD_13_21_8'] >= dump_df['MACDs_13_21_8']) & (dump_df['close'] >= dump_df['SMA_13']) & (dump_df['close'] >= dump_df['SMA_21'])
dump_df.ta.tsignals(trend=cnd, append=True)

Expected behavior the column generated through np.where in attached sheet have a correct trade. tsignals should match the same value.

eg : since it's the AND condition. Thus,final signal (s) should be only valid if all the indicator signal are the same
s = (s_1 & s3 & s_3)

Additional context Note: Problem has experienced in case of more than 2 indicators in strategy. I've generated the actual signals through np. where with below condition and generated column s, which has been generated through s_0,s_1,s_2. column s_0,s_1,s_2 are respectively a signal for each indicator And it has an expected result.

dump_df['signal'] = np.where((dump_df['s_1'].astype(int) == dump_df['s_0'].astype(int)) & (dump_df['s_2'].astype(int) == dump_df['s_1'].astype(int)),test_dump_df['s_2'],0)
S* = 0 (No Trade)
S* = 1 (Buy Trade)  #in tsignal terminology entry
S* = -1 (Short Trade)  #in tsignal terminology exit

Thanks in advance !!

test-signal.xlsx

twopirllc commented 3 years ago

Hi @codesutras,

Thanks for providing data to work with. I'll check it out as soon as I can.

Thanks, KJ

codesutras commented 3 years ago

@twopirllc Thanks for acknowledging this issue.

Another thing is that pretty much no correct result we can achieve with tsignal, if I have to generate a signal with simple RSI indicator. eg : BUY when RSI(14) < 20 and sell when RSI(14) >80.

Results are not correct when RSI is between 20-80. What tsignal is doing that it's keeping this condition as a false, which basically put you out of great entries :smile:

For reference, you can use the same attached sheet for data.

You made this module (tsignal) a great utility. And I know the importance of it. That's the reason, I'm going to provide as much as possible feedback and support.

Let me know if you need anything.

Thanks in advance !!

twopirllc commented 3 years ago

Hey @codesutras,

So the data you provided, I can not fully replicate since you excluded nearly 21 prior rows of data.

However, I know that is not the most important part. I think I was missing an Event Signals method.

Trading Signals

There are at least two basic techniques, that I am aware of, to generate Signals (Entries and Exits) for Trades. They are based on Trends (or States) or Events. If there are other ways, please let me know so they can be incorporated. 😎 The good news is, Events can simply be converted to Trends/States.

Trend/State Signals

The only requirement to be a Trend/State Signal is that it is a binary series like: 00001111111100010011111....

Examples

Calculating this State is simple by using comparison operators such as (<, <=, ...). 1) close > ema10 1) macdh > 0 1) 20 < rsi14 < 80 1) ...

Event Signals

Event Signals on the other hand are slightly different and can be more complicated to construct. They depend on when a specific event begins (a) and when it ends (b) such that a < b or a happens before b. Typically these Events are created by signal that crosses above (xa) or crosses below (xb) some value.

Examples

These four RSI Conditions are not necessarily equivalent. 1) a) rsi_14 xa 20 and b) rsi_14 xa 80 1) a) rsi_14 xa 20 and b) rsi_14 xb 80 1) a) rsi_14 xb 20 and b) rsi_14 xa 80 1) a) rsi_14 xb 20 and b) rsi_14 xb 80

Similarily for Conditions of a ZSCORE: 1) a) zscore_30 xb -3 and b) zscore_30 xa 3 1) ...

Luckily Event Signals are easily converted to Trend/State Signals! To this end, I created ta.xsignals() (beta) which wraps ta.tsignals(). For more info see: help(ta.xsignals).

For example:

df = # ohlcv
rsi = df.ta.rsi(append=True)

# Returns tsignal DataFrame when RSI crosses below 20 and then above 80
# RSI Example #3 above
xs = ta.xsignals(rsi, 20, 80, above=False)
print(xs)

Also, I will be emailing you a Jupyter Notebook "hopefully" soon (after I clean it up and add more cases). It will also have examples using Trend and Event Signals using your original example consisting of:

cnd = (dump_df['MACD_13_21_8'] >= dump_df['MACDs_13_21_8']) & (dump_df['close'] >= dump_df['SMA_13']) & (dump_df['close'] >= dump_df['SMA_21'])

Thoughts? Know of any other was to generate Signals?

Kind Regards, KJ

codesutras commented 3 years ago

Hi @twopirllc ,

I have the same thought as you about signal identification. I've quickly checked ta.xsignals, but I can't conclude whether the results are correct or not.

Looking forward to working with your shared notebook with some different signals for more test coverage.

Thanks, Jayant

twopirllc commented 3 years ago

@codesutras,

When writing my prior response I realized two things that are missing. 🤦🏼 I forget to include Barrier Signals (Exits when Target, Loss, or Time/Bars is hit) and as well as the two other conditions for Event Signals; I've implemented two of four conditions. I'll send you the Notebook soon of what I currently have minus what I have forgotten and we can start from there.

I know there is some Barrier Signal code somewhere, so I will have to source and implement it or figure it out for the package. Trailing Stops are also a Single Barrier Events, so maybe that can be implemented as well. 🤷🏼‍♂️

KJ

eervin123 commented 2 years ago

The notebook you reference above would be great to see in the examples. @twopirllc Thank you for all of your work on such a great project.

twopirllc commented 2 years ago

Hello @eervin123,

Thank you! And thanks for being a sponsor!

Last I checked, only have two of the four conditions for ta.xsignals() somewhere in an exploratory notebook. As soon as I get some pending PRs taken care of and doing some additional research and analysis, I will post a Notebook that covers tsignals() and xsignals().

KJ

eervin123 commented 2 years ago

Thank you Kevin. Much appreciated. I just started digging in to the project so I'm probably not the best person to contribute in other ways, but I will indeed do what I can. I will also encourage our devs and interns to assist wherever they are able for bug fixes, etc. so you can get back to the fun stuff. In the meantime, enjoy a coffee or half of a beer. each month on me. ;)

twopirllc commented 2 years ago

@eervin123,

Sounds great! Much appreciated.

PilotGFX commented 3 months ago

My belief regarding tsignals in this library, is that it is necessary to perform ffill before diff to avoid giving entry when already in a position and vice versa. else it only works on strategies that are always true or 0 by themself (ie short ma above long ma, is always true or false, but rsi < 10 is not always true or false ).

it seems not alot of people are using it or very active here, but i have concern about that people will use it in the faith that it will generate their entries and exits properly, which at least to my experience with some simple buy/sell above/below a treshhold, was not the case. i know that a ma50/ma200 will work, because ffill is not necessary in this type of signal(binary(1,0) vs tertiary(-1,0,1))