For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

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[0] dataseries
        self.dataclose = self.datas[0].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[0])
    
        self.stake_to_cash = (1 / self.data.close[0])
        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[0])
            # 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[0]
            self.order = self.buy()
    
    
         # Gain/Loss
        # if self.buy_close != None and self.data.close[0] != None:
        #      x = self.data.close[0] / 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[0])
                    # 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.


Log in to reply
 

});