Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    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.

    General Code/Help
    2
    2
    1266
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • C
      chives last edited by backtrader

      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
      
      1 Reply Last reply Reply Quote 0
      • B
        backtrader administrators last edited by

        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)

        1 Reply Last reply Reply Quote 0
        • 1 / 1
        • First post
          Last post
        Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors