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

Accessing custom indicator lines in strategy.



  • Hi, I made a custom indicator that contains two lines. I want to call this indicator, and then I want to take the EMA of both of the lines that the indicator creates. When I take the EMA of the indicator call directly it returns the EMA of one of the two lines, specifically the one first declared in the indicator class. If I try to access the indicator lines directly the EMA returns all NAN values. I have searched through the documentation and source on github many times now and have no idea why this is happening. Help would be appreciated, I will include the full code below.

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    import backtrader as bt
    import backtrader.feeds as btfeeds
    from backtrader.feeds import GenericCSVData 
    import backtrader.indicators as btind
    from backtrader import indicators
    import pandas as pd
    import numpy as np
    import datetime
    import math
    import time
    from datetime import timedelta
    start_time = time.time()
    
    
    
            
    class shiftedrange(bt.Indicator):
        lines = ('shiftedlow','shiftedhigh',)
        params = (('prevweeklyhigh',0),('prevweeklylow',0),)
    
        plotinfo=dict(plot=True,
                      subplot=False)
    
        
        def __init__(self):
            global currenthigh
            global currentlow
            self.high= self.p.prevweeklyhigh()
            self.low = self.p.prevweeklylow()
            
            
            
        def next(self):        
            if self.data.high[0] > self.high[-1] or self.data.high[0] > self.lines.shiftedhigh[-1]:
                if self.data.high[0] > self.lines.shiftedhigh[-1]:    
                    self.lines.shiftedhigh[0]=self.data.high[0]
                    self.lines.shiftedlow[0]=self.lines.shiftedlow[-1]+abs(self.data.high[0]-self.shiftedhigh[-1])
                else:
                   self.lines.shiftedhigh[0] = self.lines.shiftedhigh[-1]
                   self.lines.shiftedlow[0]=self.lines.shiftedlow[-1]
            else:
                if self.data.low[0] < self.low[-1] or self.data.low[0] < self.lines.shiftedlow[-1]:
                    if self.data.low[0] < self.lines.shiftedlow[-1]:
                        self.lines.shiftedlow[0] = self.data.low[0]
                        self.lines.shiftedhigh[0] = self.lines.shiftedhigh[-1] - abs(self.data.low[0]-self.shiftedlow[-1])
                    else:
                        self.lines.shiftedhigh[0] = self.lines.shiftedhigh[-1]
                        self.lines.shiftedlow[0]=self.lines.shiftedlow[-1]
                elif self.l.shiftedlow[-1] < self.low[-1] and self.l.shiftedhigh[-1] < self.high[-1]:
                    self.lines.shiftedhigh[0]=self.l.shiftedhigh[-1]
                    self.lines.shiftedlow[0]=self.l.shiftedlow[-1]
                elif self.l.shiftedhigh[-1] > self.high[-1] and self.l.shiftedlow[-1] > self.low[-1]:
                    self.lines.shiftedhigh[0]=self.l.shiftedhigh[-1]
                    self.lines.shiftedlow[0]=self.l.shiftedlow[-1]
                else:
                    self.lines.shiftedhigh[0]=self.high[0]
                    self.lines.shiftedlow[0] = self.low[0]
                
           
                    
    
    class ForexStrat(bt.Strategy):
        
        def __init__(self):
            self.lines.values = shiftedrange(self.data,prevweeklyhigh=self.data1.high(-1),prevweeklylow=self.data1.low(-1))
            self.ema = btind.ExponentialMovingAverage(self.values.lines.shiftedlow,period=10)
    
          
        
    if __name__ == '__main__':
        cerebro = bt.Cerebro(stdstats=False)
        
       
        
        datapath = 'C:/Users/Connor/Desktop/oandadata.csv'
        datapath1 = 'C:/Users/Connor/Desktop/oandadata1.csv'
        data = btfeeds.GenericCSVData(
            plot=True,
            plotskip=False,
            plotlines=dict(_method='bars'),  
            dataname=datapath,
            nullvalue=0.0,
            timeframe=bt.TimeFrame.Minutes,
            compression=60,
            dtformat=('%Y-%m-%d %H:%M:%S'),
            datetime=1,
            high=4,
            low=5,
            open=2,
            close=3,
            volume=6,
            openinterest=-1,
            reversed=False)
        
        weeklydata = btfeeds.GenericCSVData(
            plot=True,  
            plotlines=dict(_method='bar'),
            dataname=datapath1,
            nullvalue=0.0,
            timeframe=bt.TimeFrame.Weeks,
            compression=0,
            dtformat=('%Y-%m-%d %H:%M:%S'),
            datetime=1,
            high=4,
            low=5,
            open=2,
            close=3,
            volume=6,
            openinterest=-1,
            reversed=False)
        cerebro.adddata(data)
        cerebro.adddata(weeklydata)
        cerebro.addstrategy(ForexStrat)
        cerebro.run(runonce=False)
        cerebro.plot()
        print("--- %s seconds ---" % (time.time() - start_time))
    
    
                
        
    
    code_text
    

  • administrators

    You access values previous (-1) to the current point in time (0) without having added any minimum period restriction in __init__. This means that -1 wraps over to the current value before you fill it and the default value is NaN, which you copy over and over again.

    The code is cumbersome, but you can probably come around with self.addminperiod(1)


Log in to reply
 

});