Initializing Indicator Changes Portfolio Value Without Touching Buy/Sell Logic
Inside strategy I initialized a few new indicators but have not touched the buy/sell logic. Yet, my final portfolio value changes. Tested it multiple times and it is a consistent change. I cannot stress this enough, after I added these indicators to def init I never touched buy/sell logic. I keep toggling comment on and off the "Check long term trends" portion in init and get different results. If anyone can see something I am doing wrong, it would be much appreciated.
def __init__(self): # Keep a reference to the "close" line in the data dataseries self.dataclose = self.datas.close # To keep track of pending orders and buy price/commission self.order = None self.buyprice = None self.buycomm = None self.buy_close = None self.counter1 = 0 self.stake_to_cash = None self.six_thousand = None self.cash_to_trade = 6000 self.sell_check = 0 # Add a BBand indicator self.bband = bt.indicators.BBands(self.data.close, period=self.params.BBandsperiod) # Check long term trends # self.fast_moving_average = bt.indicators.SMA( # self.data.close, period=self.params.fast, plotname='50 day moving average' # ) # self.slow_moving_average = bt.indicators.SMA( # self.data.close, period=self.params.slow, plotname='200 day moving average' # ) # # self.crossover = bt.indicators.CrossOver(self.fast_moving_average, self.slow_moving_average) def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose) self.stake_to_cash = (1 / self.data.close) self.six_thousand = self.cash_to_trade * self.stake_to_cash self.six_thousand = math.floor(self.six_thousand) # Check if an order is pending ... if yes, we cannot send a 2nd one if self.order: return if self.dataclose <= self.bband.lines.bot and not self.position: # BUY, BUY, BUY!!! (with all possible default parameters) self.log('BUY CREATE, %.2f' % self.dataclose) # Keep track of the created order to avoid a 2nd order # if self.broker.cash >=6000: # self.order = self.buy(size=self.six_thousand) # else: # self.order = self.buy(size=math.floor(self.broker.cash * self.stake_to_cash)) self.buy_close = self.data.close self.order = self.buy() # Gain/Loss # if self.buy_close != None and self.data.close != None: # x = self.data.close / self.buy_close # print(str(x)) # print('Ratio') # Acceptable gain stop if self.position: self.sell_check = 0 if (self.dataclose / self.buy_close) > 1.025: self.order = self.sell() # print('dskjlsdskljnsfkjnfskjnfdkjndfkjndfkjnfd') self.sell_check = 1 # Check if pos has already been sold if self.sell_check != 1: # Check if we need to sell because it hit upper band if self.dataclose >= self.bband.lines.top and self.position: # SELL, SELL, SELL!!! (with all possible default parameters) self.log('SELL CREATE, %.2f' % self.dataclose) # Keep track of the created order to avoid a 2nd order self.order = self.sell()
With the new indicator you introduce longer period of waiting to get long term indicator value. Therefore in your backtest you have less trades open and therefore different PnL.