kernc / backtesting.py

:mag_right: :chart_with_upwards_trend: :snake: :moneybag: Backtest trading strategies in Python.

Home Page:https://kernc.github.io/backtesting.py/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Implementing Walkforward to a Strategy

chemcoder-2020 opened this issue · comments

I have a strategy class called VWAPBounceStrategy, in which the buys and sells are signaled by self.longs, self.shorts, self.longXs, and self.shortXs, which are outputs of a method called vwapbounce_signal.

I would like to implement walkforward analysis on this strategy. I looked at the ML notebook and some conversations on updating the optimal parameters. Here's a basic implementation. I would like to ask if this looks right, or is there something else needed. The workflow is retraining every month. This code does run.

`
class VWAPWalkForwardStrategy(VWAPBounceStrategy):
def next(self):
month = (
pd.Series(pd.DatetimeIndex(self.data.df.index).month)
.diff()
.abs().gt(0)
.cumsum()
.fillna(0)
)

      if month.iloc[-1] < N_TRAIN:
          return

      if month.iloc[-1] == month.iloc[-2]:
          return super().next()

      data = self.data.df.reset_index()[month.gt(month.iloc[-1] - N_TRAIN - 1)]
      data = data.set_index("date")[:-1]
      support_rejection = [True, False]
      resistance_rejection = [True, False]
      combo_choices = list(
          itertools.product(
              *[
                  support_rejection,
                  resistance_rejection,
              ]
          )
      )

      rets = {}
      print(data.iloc[0])
      print(data.iloc[-1])
      for option in combo_choices:
          bt = Backtest(data, VWAPBounceStrategy, commission=0, cash=30000)
          output = bt.run(
              support_rejection=option[0],
              resistance_rejection=option[1],
          )
          _target = output["Win Rate [%]"] * output["Avg. Trade WL Ratio"]
          rets[option] = _target
      rets = pd.Series(rets)
      best = rets.idxmax()
      print(best)

      # use best result
      self.support_rejection = best[0]
      self.resistance_rejection = best[1]
      (
          self.longs,
          self.shorts,
          self.longXs,
          self.shortXs,
          self.ma_mid,
          self.rsi,
          self.eod,
      ) = self.I(
          self.vwapbounce_signal,
          self.data.df,
          plot=False,
      )
      super().next()`

More specifically, should super().next() be before the (self.longs, ...) = self.I(...) update, or after that, as it is now.