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
-
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 isNaN
, which you copy over and over again.The code is cumbersome, but you can probably come around with
self.addminperiod(1)