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

# 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

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

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)  # <- Value is 'nan', I wanna numeric

class NoStrategy(bt.Strategy):
def __init__(self):
HeikinAshi(self.data)

if __name__ == '__main__':
cerebro = bt.Cerebro()
data0 = bt.feeds.YahooFinanceData(dataname='YHOO', fromdate=datetime(2011, 1, 1),
todate=datetime(2012, 12, 31))

cerebro.run()
#cerebro.plot()
``````

• I resolve by myself :D

I use once method instead of next.

``````from datetime import datetime

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

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
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()
data0 = bt.feeds.YahooFinanceData(dataname='YHOO', fromdate=datetime(2011, 1, 1),
todate=datetime(2012, 12, 31))

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
``````

• ``````    self.ha_open = (self.ha_open(-1) + self.ha_close(-1)) / 2

def next(self):
print(self.ha_open)  # <- 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 fails

As such, the only value the platform can fill in advance is `NaN` and any calculation with `Nan` will return the same.

A seed value could be provided during `nextstart` or `oncestart`. It is what the `ExponentialMovingAverage` for example does, by using a `SimpleMovingAverage` as the seed value.

``````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
else:
ha_open[i] = (ha_open[i - 1] + ha_close[i - 1]) / 2
``````

Same here. `oncestart` is the one in which `ha_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` or `nextstart` wouldn't be good because the calculation is over when they are seen and the seed used for the calculation is `NaN` already. In any case the problem can be solved by seeding during the entire `prenext` phase.

``````    def prenext(self):
self.lines.ha_open = self.data.open
``````

When the indicator moves to `next`, there will be something at index `[-1]`, because values were recorded in the appropriate line by `prenext`.

• This indicator is now in the development branch

});