Problem solved.
I trided to:
1) Subscribe HeikinAshi to consolidated daily bars with RegisterIndicator:
consolidator = TradeBarConsolidator(timedelta(1))
self.SubscriptionManager.AddConsolidator(self.symbol, consolidator)
self.ha = HeikinAshi()
self.RegisterIndicator(self.symbol, self.ha, consolidator)
This throws a runtime error SystemError : <bound method 'RegisterIndicator'> returned a result with an error set.
2) Update HeikinAshi on DataConsolidated event:
consolidator.DataConsolidated += self.OnDailyBarHandler
....
def OnDailyBarHandler(self, sender, bar):
self.ha.Update(bar)
This actually worked, but OnDailyBarHandler fires right after market open. My rebalancing happens before market open, so at that time I always have a one day lagged HeikinAshi candle.
I needed to have a completed daily candle right after market close, so I did the following:
3) Consoidate daily candle manually
def Initialize(self):
...
self.ha = HeikinAshi()
self.daily_candle = TradeBar()
self.Schedule.On(self.DateRules.EveryDay(self.symbol),
self.TimeRules.BeforeMarketClose(self.symbol, -1),
Action(self.AfterMarketClose))
def AfterMarketClose(self):
self.ha.Update(self.daily_candle)
if not self.ha.IsReady: return
# rebalance
...
def OnData(self, data):
bar = data[self.symbol]
if bar is None: return
if not bar.Time.day == self.daily_candle.Time.day: # new day
self.daily_candle = TradeBar()
self.daily_candle.Time = bar.Time
self.daily_candle.Period = timedelta(1)
self.daily_candle.Symbol = self.symbol
self.daily_candle.Open = bar.Open
self.daily_candle.High = bar.High
self.daily_candle.Low = bar.Low
self.daily_candle.Value = bar.Close
self.daily_candle.Volume = bar.Volume
else:
self.daily_candle.Time = bar.Time
self.daily_candle.High = max(self.daily_candle.High, bar.High)
self.daily_candle.Low = min(self.daily_candle.Low, bar.Low)
self.daily_candle.Close = bar.Close
self.daily_candle.Value = bar.Close
self.daily_candle.Volume += bar.Volume
Now I get very similar backtest results on any equity resolution.