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

How to Calculate ATR On First Index on CSV



  • I have some EMA + ATR Crossover Strategies, but i need help to make this strategy.

    my code is like this:

    class MAcrossover(bt.Strategy):
    #   Moving Average + ATR Parameters
      params = (
          ('smafast',50),
          ('smaslow',20),
          ('atrperiod',5),
          ('multiplier',3.5),
      )
        
      def log(self,txt,dt=None):
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(),txt))
        
      def __init__(self):
        self.dataclose = self.datas[0].close
        # Order variable
        self.order = 0.0
        # Instantiate Exponential Moving Averages
        self.slow_sma = bt.indicators.EMA(self.datas[0].close, period=self.params.smaslow)
        self.fast_sma = bt.indicators.EMA(self.datas[0].close, period=self.params.smafast)
        self.crossover = bt.indicators.CrossOver(self.slow_sma, self.fast_sma)   
        self.atr = bt.indicators.ATR(self.datas[0] ,period=self.params.atrperiod)
        self.nloss = self.atr*self.params.multiplier      
        self.xATRTrailingStop = []
    
      def prenext(self):
        # Preassign
        xATRTrailingStop = 0
        nloss = self.nloss
        # Check for NULL
        close = 0
        prevClose = 0
        if len(self.datas) >0:
            close = self.datas[0].close
        if len(self.datas)>1:
            prevClose = self.datas[-1].close
        # Check for NULL
        prevxATRTrailingStop =0
        if(hasattr(self,'xATRTrailingStop')==True):
            if len(self.xATRTrailingStop)>1:
                prevxATRTrailingStop = self.xATRTrailingStop[-1]
                
        xATRTrailingStop = bt.If(bt.And(close>prevxATRTrailingStop ,prevClose > prevxATRTrailingStop ), bt.Max(prevxATRTrailingStop,(close-nloss)),bt.If(bt.And(close<prevxATRTrailingStop,prevClose<prevxATRTrailingStop),bt.Min(prevxATRTrailingStop,(close+nloss)),bt.If(close >prevxATRTrailingStop ,close-nloss,close+nloss)))
        self.xATRTrailingStop = xATRTrailingStop
        
        self.next()
        
      def notify_order(self,order):    
        if order.status in [order.Submitted, order.Accepted]:
            #Active Buy/Sell order submitted/accepted - Nothing to do
            return
        #Check if an order has been completed
        
        #Attention: broker could reject order if not enough cash
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log('BUY EXECUTED, Price: {0:8.2f}, Size: {1:8.2f} Cost: {2:8.2f}, Comm: {3:8.2f}'.format(
                        order.executed.price,
                        order.executed.size,
                        order.executed.value,
                        order.executed.comm))
                    
                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            elif order.issell():
                self.log('SELL EXECUTED, {0:8.2f}, Size: {1:8.2f} Cost: {2:8.2f}, Comm{3:8.2f}'.format(
                        order.executed.price, 
                        order.executed.size, 
                        order.executed.value,
                        order.executed.comm))
                
                self.bar_executed = len(self) #when was trade executed
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')
        #Reset orders  
        self.order = None
        
      def next(self):
        print(self.dataclose[0])
        
        if(hasattr(self,'xATRTrailingStop')==True):
            if len(self.xATRTrailingStop)>1:
                print(self.xATRTrailingStop[0])
                
        if self.order:
            return
    #     self.close()
        if self.crossover > 0: # Fast ma crosses above slow ma
    #         self.log('BUY CREATE, %.2f' % self.dataclose[0])
            self.order = self.buy()
        elif self.crossover < 0: # Fast ma crosses below slow ma
    #         self.log('SELL CREATE, %.2f' % self.dataclose[0])
            self.order = self.sell()
        else:
            return
      def stop(self):
    #     print(self.xATRTrailingStop)
        super().stop()
    

    the issue is, since i'm using EMA fast at 50 period, but i want to calculate the defined xATRTrailingStop since the first line of CSV.

    using this code, the xATRTrailingStop is defined after 50 lines , since i'm using EMA fast 50 period.

    thank you.



    • you can't define xATRTrailingStop from the first line, it uses ATR with period 5, so only from line 6
    • bt.If, bt.Max etc can be used only in __init__()
    • self.xATRTrailingStop is defined in __init()__ so thishasattr(self,'xATRTrailingStop')` is always True
    • len(self.datas) returns numbr of the data feeds added to cerebro
    • self.datas[-1] - i don't think this object exists
    • xATRTrailingStop = bt.If(...) I don't think this line returns any meaningful results

    I would recommend to review documentation one more time, go thru the Quick Start yo understand how to work with the data feeds and arrays in bt.


Log in to reply
 

});