kernc / backtesting.py

:mag_right: :chart_with_upwards_trend: :snake: :moneybag: Backtest trading strategies in Python.
https://kernc.github.io/backtesting.py/
GNU Affero General Public License v3.0
5.45k stars 1.06k forks source link

How to back testing with customer signals? #369

Closed bergen288 closed 3 years ago

bergen288 commented 3 years ago

Expected Behavior

My sample SPY data has a signal column which is generated based on renkon chart:

             Open   High    Low  Close  Adj Close     Volume  signal
Date                                                                
2001-03-13 119.40 120.44 117.53 120.02      81.58   12888000   -1.00
2001-09-18 104.33 105.30 103.36 104.05      71.12   22029200   -1.00
2002-07-03  94.62  95.84  93.72  95.51      66.17   30565800   -1.00
2003-12-02 107.38 107.77 107.07 107.33      75.92   35352000    1.00
2004-12-14 120.18 120.96 120.18 120.79      87.08   41500700    1.00
2006-05-01 131.47 131.80 130.32 130.40      96.50   64990300    1.00
2008-01-23 127.09 134.19 126.84 133.86     102.35  511913000   -1.00
2008-09-18 118.05 121.79 113.80 120.07      92.72  776114700   -1.00
2008-10-07 106.84 107.33  99.65 100.03      77.69  540012100   -1.00
2009-07-22  94.96  96.13  94.89  95.55      75.78  196068100    1.00
2009-10-13 107.39 107.71 106.76 107.46      85.63  157692700    1.00
2010-04-12 119.70 120.05 119.56 119.74      96.32  110279000    1.00
2018-02-09 260.80 263.61 252.92 261.50     246.43  283565300   -1.00
2018-08-27 288.86 289.90 288.68 289.78     275.41   57072400    1.00
2018-12-17 259.40 260.65 253.53 255.36     243.79  165492300   -1.00
2018-12-21 246.74 249.71 239.98 240.70     231.14  255345600   -1.00
2018-12-26 235.97 246.18 233.76 246.18     236.40  218485400   -1.00
2019-01-18 264.98 266.98 263.00 266.46     255.88  127900300    1.00
2019-02-14 273.78 275.64 272.87 274.38     263.48   83234400    1.00
2019-04-05 287.92 288.63 287.60 288.57     278.33   58621700    1.00
2020-02-28 288.70 297.89 285.54 296.26     289.88  384975800   -1.00
2020-03-10 284.64 288.52 273.50 288.42     282.21  276444100   -1.00
2020-03-13 263.09 271.48 248.52 269.32     263.52  329566100   -1.00
2020-03-27 253.27 260.81 251.05 253.42     249.42  224341200    1.00
2020-04-07 274.21 275.03 264.89 265.13     260.95  201427200    1.00
2020-04-13 277.14 277.51 271.41 275.66     271.31  114839100    1.00

I would like to backtesting based on my signal:

from backtesting import Backtest, Strategy
class MyRenko(Strategy):
    def init(self):
        self.signal = self.data.signal
    def next(self):
        if self.signal == 1:
            self.buy()
        elif self.signal == -1:
            self.sell()

data = pd.read_pickle(file_name)
bt = Backtest(data, MyRenko, commission=.002, exclusive_orders=True)
stats = bt.run()
print(stats)

Unfortunately,, no trades happened. What's wrong with my class MyRenko? Is there a way to back testing customer signal?

Start                     2000-01-03 00:00:00
End                       2021-06-01 00:00:00
Duration                   7820 days 00:00:00
Exposure Time [%]                        0.00
Equity Final [$]                     10000.00
Equity Peak [$]                      10000.00
Return [%]                               0.00
Buy & Hold Return [%]                  188.56
Return (Ann.) [%]                        0.00
Volatility (Ann.) [%]                    0.00
Sharpe Ratio                              NaN
Sortino Ratio                             NaN
Calmar Ratio                              NaN
Max. Drawdown [%]                       -0.00
Avg. Drawdown [%]                         NaN
Max. Drawdown Duration                    NaN
Avg. Drawdown Duration                    NaN
# Trades                                    0
Win Rate [%]                              NaN
Best Trade [%]                            NaN
Worst Trade [%]                           NaN
Avg. Trade [%]                            NaN
Max. Trade Duration                       NaN
Avg. Trade Duration                       NaN
Profit Factor                             NaN
Expectancy [%]                            NaN
SQN                                       NaN
_strategy                             MyRenko
_equity_curve                          Equ...
_trades                   Empty DataFrame
...
dtype: object

Additional info

meetaco commented 3 years ago

buy() or sell() you wrote are not triggered because self.signal on next() is a list object, not integer one.

zlpatel commented 3 years ago

Below is what you need:

def next(self):
        index = len(self.data)-1
        if self.signal[index] == 1:
            self.buy()
        elif self.signal[index] == -1:
            self.sell()
bergen288 commented 3 years ago

Great, it works.

Thanks.

zlpatel commented 3 years ago

@bergen288 If my suggestion resolved your issue then please close this issue.