backtesting.py icon indicating copy to clipboard operation
backtesting.py copied to clipboard

SignalStrategy: 6 signals, 5 trades

Open kernc opened this issue 2 years ago • 2 comments

Discussed in https://github.com/kernc/backtesting.py/discussions/486

Originally posted by AetherTL September 30, 2021 截屏2021-09-30 上午10 17 05

The entry size plot shows a short signal was received at around March 1987, but no trade has been made, I don't know why

I was using the HSI index as the dataset, and the strategy is simple, if the Z-value < -threshold the short the index, if >threshold then long it, it works at Oct 87 but failed at March, I am confusing now

Issue: https://github.com/kernc/backtesting.py/discussions/486#discussioncomment-1422393 Example in https://colab.research.google.com/drive/1l4Ki7tcdlhjEqfcuhdETdxbupIwyB6KS?usp=sharing

kernc avatar Oct 04 '21 20:10 kernc

I got the same error when trying to use the code found in the page "Library of Composable Base Strategies" (https://kernc.github.io/backtesting.py/doc/examples/Strategies%20Library.html, class SmaCross) to replicate the results found in the "Quick Start User Guide" (https://kernc.github.io/backtesting.py/doc/examples/Quick%20Start%20User%20Guide.html, class SmaCross). The very first trade of the code which uses the SignalStrategy subclass is never performed, even for a test run with only one signal (no trade was performed in this case).

In the former code, the signals are generated in advance, in a vectored manner, and the subclass SignalStrategy is used. As far as I could investigate, the problem seems to be the following code found in the run() method of the Backtest class:

    # Skip first few candles where indicators are still "warming up"
    # +1 to have at least two entries available
    start = 1 + max((np.isnan(indicator.astype(float)).argmin(axis=-1).max()
                     for _, indicator in indicator_attrs), default=0)

The code above is used to skip the first few ticks in which the indicators all have NANs in them. So, the "+1" in front is used to ensure that there are at least two days in a row with no NANs in any indicator (not sure if this is necessary). It is all OK for a standard run, but in the case in which the SignalStrategy is used, the very first trade is always ignored.

Does it make sense?

ahentzjr avatar Mar 17 '23 18:03 ahentzjr

Thanks! The issue seems to be in SignalStrategy here: https://github.com/kernc/backtesting.py/blob/0ce24d80b1bcb8120d95d31dc3bb351b1052a27d/backtesting/lib.py#L411-L413 Since any zeros are replaced with NaNs, along with +1 in Backtest.run(), this skips past the first signal.

kernc avatar Apr 01 '23 12:04 kernc