backtesting.py
backtesting.py copied to clipboard
SignalStrategy: 6 signals, 5 trades
Discussed in https://github.com/kernc/backtesting.py/discussions/486
Originally posted by AetherTL September 30, 2021
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
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?
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.