Develop Heikinashi Indicators
-
Thank you for develop best backtrading app!
I have problem when I develop Heikin-Ashi Indicators.
I can't get value that i want.
when i want develop autocorrelation indicators, what should I do?My code show below
from datetime import datetime import backtrader as bt class HeikinAshi(bt.indicators.PeriodN): """ Heikin Ashi candlesticks: Parameter: No needs Description: Heikin-Ashi candlesticks are a weighted version of candlesticks calculated with the following formula Formula: h_close = (open + high + low + close) / 4 h_high = maximum of high, open, or close (whichever is highest) h_low = minimum of low, open, or close (whichever is lowest) h_open = (open of previous bar + close of previous bar) / 2 See also: https://en.wikipedia.org/wiki/Candlestick_chart#Heikin_Ashi_candlesticks http://stockcharts.com/school/doku.php?id=chart_school:chart_analysis:heikin_ashi """ lines = ('signal', 'ha_close', 'ha_open') def __init__(self): super(HeikinAshi, self).__init__() open = self.data.open high = self.data.high low = self.data.low close = self.data.close self.ha_close = (open + high + low + close) / 4 # h_high = bt.Max(open, high, low, close) # h_low = bt.Min(open, high, low, close) self.ha_open = (self.ha_open(-1) + self.ha_close(-1)) / 2 def next(self): print(self.ha_open[0]) # <- Value is 'nan', I wanna numeric class NoStrategy(bt.Strategy): def __init__(self): HeikinAshi(self.data) if __name__ == '__main__': cerebro = bt.Cerebro() cerebro.addstrategy(NoStrategy) data0 = bt.feeds.YahooFinanceData(dataname='YHOO', fromdate=datetime(2011, 1, 1), todate=datetime(2012, 12, 31)) cerebro.adddata(data0) cerebro.run() #cerebro.plot()
-
I resolve by myself :D
I use once method instead of next.
from datetime import datetime import backtrader as bt class HeikinAshi(bt.Indicator): """ Heikin Ashi candlesticks: Parameter: No needs Description: Heikin-Ashi candlesticks are a weighted version of candlesticks calculated with the following formula Formula: h_close = (open + high + low + close) / 4 h_high = maximum of high, open, or close (whichever is highest) h_low = minimum of low, open, or close (whichever is lowest) h_open = (open of previous bar + close of previous bar) / 2 See also: https://en.wikipedia.org/wiki/Candlestick_chart#Heikin_Ashi_candlesticks http://stockcharts.com/school/doku.php?id=chart_school:chart_analysis:heikin_ashi """ lines = ('signal', 'ha_close', 'ha_open') def __init__(self): super(HeikinAshi, self).__init__() open = self.data.open high = self.data.high low = self.data.low close = self.data.close self.ha_close = (open + high + low + close) / 4 # h_high = bt.Max(open, high, low, close) # h_low = bt.Min(open, high, low, close) def once(self, start, end): ha_close = self.ha_close.array ha_open = self.ha_open.array for i in range(start, end): if i == 1: ha_open[i] = self.data.open[0] else: ha_open[i] = (ha_open[i - 1] + ha_close[i - 1]) / 2 class NoStrategy(bt.Strategy): def __init__(self): HeikinAshi(self.data) if __name__ == '__main__': cerebro = bt.Cerebro() cerebro.addstrategy(NoStrategy) data0 = bt.feeds.YahooFinanceData(dataname='YHOO', fromdate=datetime(2011, 1, 1), todate=datetime(2012, 12, 31)) cerebro.adddata(data0) cerebro.run() #cerebro.plot()
-
I noticed simple code below.
I think once method doesn't work when I use resampledata.def __init__(self): super(HeikinAshi, self).__init__() open = self.data.open high = self.data.high low = self.data.low close = self.data.close self.ha_open = open self.ha_close = (open + high + low + close) / 4 # h_high = bt.Max(open, high, low, close) # h_low = bt.Min(open, high, low, close) self.ha_open = (self.ha_open(-1) + self.ha_close(-1)) / 2
-
@santa3 said in Develop Heikinashi Indicators:
self.ha_open = (self.ha_open(-1) + self.ha_close(-1)) / 2 def next(self): print(self.ha_open[0]) # <- Value is 'nan', I wanna numeric
The initial problem here is:
-
ha_open(-1)
needs a seed value which is not being provided and the recursive calculation failsAs such, the only value the platform can fill in advance is
NaN
and any calculation withNan
will return the same.A seed value could be provided during
nextstart
oroncestart
. It is what theExponentialMovingAverage
for example does, by using aSimpleMovingAverage
as the seed value.
@santa3 said in Develop Heikinashi Indicators:
def once(self, start, end): ha_close = self.ha_close.array ha_open = self.ha_open.array for i in range(start, end): if i == 1: ha_open[i] = self.data.open[0] else: ha_open[i] = (ha_open[i - 1] + ha_close[i - 1]) / 2
Same here.
oncestart
is the one in whichha_open
should be seeded and not here.But the major problem is here:
@santa3 said in Develop Heikinashi Indicators:self.ha_close = (open + high + low + close) / 4 self.ha_open = (self.ha_open(-1) + self.ha_close(-1)) / 2
Because the calculations are not being assigned to the lines but simply to an attribute of the class. This should be
> self.lines.ha_close = (open + high + low + close) / 4 > self.lines.ha_open = (self.lines.ha_open(-1) + self.lines.ha_close(-1)) / 2
Which still doesn't solve the problem of the recursive calculation and the seed. And in this case
oncestart
ornextstart
wouldn't be good because the calculation is over when they are seen and the seed used for the calculation isNaN
already. In any case the problem can be solved by seeding during the entireprenext
phase.def prenext(self): self.lines.ha_open[0] = self.data.open[0]
When the indicator moves to
next
, there will be something at index[-1]
, because values were recorded in the appropriate line byprenext
. -
-
This indicator is now in the development branch