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/

    Heikin Ashi Delta indicator - Work but get warnings.

    Indicators/Strategies/Analyzers
    indicator heikin ashi hadelta
    2
    10
    5529
    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.
    • Paduel Gerion
      Paduel Gerion last edited by Paduel Gerion

      Hi. With the addition of the filter for the Heikin Ashi candles, I have written code for the Heikin Ashi Delta, which was included in the original article by Dan Valcu in the Stocks & Commodities magazine of February 2014.

      The indicator works fine, but I wanted to include a colored area using _fill_gt and _fill_lt, for a better visualization of it.

      When I use it it colors correctly, but I receive these two warnings:

      .../python2.7/site-packages/backtrader/plot/plot.py:475: RuntimeWarning: invalid value encountered in greater
        kwargs['where'] = fop(y1, y2)
      .../python2.7/site-packages/backtrader/plot/plot.py:475: RuntimeWarning: invalid value encountered in less
        kwargs['where'] = fop(y1, y2)
      

      But if I remove _fill_gt and _fill_lt, from the code, the warnings disappear.

      The haDelta indicator code:

      #!/usr/bin/env python
      # -*- coding: utf-8; py-indent-offset:4 -*-
      
      
      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      from backtrader import Indicator
      from backtrader.indicators import MovAv
      
       '''
          Heikin Ashi Delta. Defined by Dan Valcu in his book "Heikin-Ashi: How to Trade Without Candlestick Patterns ".
      
          This indicator measures difference between Heikin Ashi close and open of Heikin Ashi candles,
          the body of the candle.
      
          To get signals add haDelta smoothed by 3 period moving average.
      
          For correct use, the data for the indicator must have been previously passed by the Heikin Ahsi filter.
      
      
          Formula:
            - haDelta = Heikin Ashi close - Heikin Ashi open
            - smoothed = movav(haDelta, period)
          '''
      
      class haDelta(Indicator):
          
          alias = ('haD')
          
          lines = ('haDelta', 'smoothed')
      
          params = (('period', 3),
                    ('movav', MovAv.SMA),)
      
          plotinfo = dict(subplot=True, )
      
          plotlines = dict(haDelta=dict(color='red'),
                           smoothed=dict(color='grey',
                                    _fill_gt=(0, 'green'),
                                    _fill_lt=(0, 'red'), ), )
      
          def __init__(self):
              self.lines.haDelta = self.data.close - self.data.open
              self.lines.smoothed = self.p.movav(self.lines.haDelta, period=self.p.period)
              super(haDelta, self).__init__()
      
      

      Chart of a test :

      0_1498131005804_haDelta_test.png

      I know it is not very relevant, but by debugging the code and by the way learn something about plot in Backtrader, any idea of why the warnings?

      And if you consider it appropriate, it could be incorporated into the Backtrader indicators.

      1 Reply Last reply Reply Quote 0
      • B
        backtrader administrators last edited by

        The chart below is made with an unmodified copy of your indicators (and using the same data source)

        No warnings at all. Because the filling is done using numpy arrays, the suspicion would be that your installation of numpy is the one producing the warnings.

        In any case it is difficult to imagine which values could actually be wrong there (there are no 'NaN' values)

        0_1498155427729_820414da-d0da-47f2-9cf3-921b54b0259a-image.png

        1 Reply Last reply Reply Quote 0
        • Paduel Gerion
          Paduel Gerion last edited by

          As I said, except for the warnings the indicator works well.

          I'm glad to know that the indicator did not give you any warnings when using it.
          I'll test it in another environment.

          Thanks for checking it.

          1 Reply Last reply Reply Quote 0
          • B
            backtrader administrators last edited by

            There has been some rewrite and some new functionality added, because the HeikinAshi indicator (not the filter) is defined on a recursive basis and needs to disable runonce (or else let the users find about it)

            The haDelta included will automatically instantiate a HeikinAshi indicator unless autoheikin=False. With this in mind the user doesn't have to add the HeikinAshi filter to use haDelta and several other indicators can be applied to the same data feed.

            If all indicators have to be applied to data feed with a HeikinAshi filter, then autoheikin=False will avoid the automatic invocation of the indicator.

            1 Reply Last reply Reply Quote 0
            • B
              backtrader administrators last edited by backtrader

              This is a chart in which the haDelta is applied to two data feeds

              • The first is the raw version and the autoheikin is left with the default value of True
              • The second is the data feed with a HeikinAshi filter and here the indicator is applied with autoheikin=False

              No difference is appreciated except for the 1st bar. That's because the indicator declares a minimum period of 2 (to account for the recursive definition of ha_open) where the filter simply takes the values from the data feed to create a 1st artificial bar.

              0_1498470675852_8686dd62-c042-45e6-883d-33ec1fb60fd2-image.png

              1 Reply Last reply Reply Quote 0
              • Paduel Gerion
                Paduel Gerion last edited by

                This is great!

                I was trying to code the HACO indicator and the HACOLT, which use both price series data, and the opening and closing of Heikin Ashi candles. For which I had written a similar code, but this way you raise is simpler.

                Thanks for including the haDelta in Backtrader.

                1 Reply Last reply Reply Quote 0
                • B
                  backtrader administrators last edited by

                  This is apparently the original calculation (Source)

                  In this formula I am using the heikin ashi average closing price:
                  haC
                  haOpen:=(Ref((O+H+L+C)/4,-1) + PREV)/2;
                  haC:=((O+H+L+C)/4+haOpen+Max(H,haOpen)+Min(L,haOpen))/4;
                  
                  This is the HACO digital formula: HACO
                  
                  avg:=Input("Up TEMA average: ",1,100,34);
                  avgdn:=Input("Down TEMA Average: ",1,100,34);
                  haOpen:=(Ref((O+H+L+C)/4,-1) + PREV)/2;
                  haC:=((O+H+L+C)/4+haOpen+Max(H,haOpen)+Min(L,haOpen))/4;
                  TMA1:= Tema(haC,avg);
                  TMA2:= Tema(TMA1,avg);
                  Diff:= TMA1 - TMA2;
                  ZlHa:= TMA1 + Diff;
                  TMA1:= Tema((H+L)/2,avg);
                  TMA2:= Tema(TMA1,avg);
                  Diff:= TMA1 - TMA2;
                  ZlCl:= TMA1 + Diff;
                  ZlDif:=ZlCl-ZlHa;
                  keep1:=Alert(haC>=haOpen,2);
                  keep2:=ZlDif>=0;
                  keeping:=(keep1 OR keep2);
                  keepall:=keeping OR (Ref(keeping,-1) AND (C>=O) OR C>=Ref(C,-1));
                  keep3:=(Abs(C-O)<(H-L)*.35 AND  H>=Ref(L,-1));
                  utr:=Keepall OR (Ref(keepall,-1) AND keep3);
                  TMA1:= Tema(haC,avgdn);
                  TMA2:= Tema(TMA1,avgdn);
                  Diff:= TMA1 - TMA2;
                  ZlHa:= TMA1 + Diff;
                  TMA1:= Tema((H+L)/2,avgdn);
                  TMA2:= Tema(TMA1,avgdn);
                  Diff:= TMA1 - TMA2;
                  ZlCl:= TMA1 + Diff;
                  ZlDif:=ZlCl-ZlHa;
                  keep1:=Alert(haC<haOpen,2);
                  keep2:=ZlDif<0;
                  keep3:=Abs(C-O)<(H-L)*.35 AND L<=Ref(H,-1);
                  keeping:=keep1 OR keep2;
                  keepall:=keeping OR (Ref(keeping,-1) AND (C<O) OR C<Ref(C,-1));
                  dtr:=If(Keepall OR (Ref(keepall,-1) AND keep3)=1,1,0);
                  upw:=dtr=0 AND Ref(dtr,-1) AND utr;
                  dnw:=utr=0 AND Ref(utr,-1) AND dtr;
                  result:=If(upw,1,If(dnw,0,PREV));
                  result
                  

                  Without having ever spoken Metastock it seems that Ref(x, -idx) returns the value for the given x from idx periods ago.

                  1 Reply Last reply Reply Quote 0
                  • Paduel Gerion
                    Paduel Gerion last edited by Paduel Gerion

                    Thank you.

                    I get the formula here, there are for several frameworks.

                    I have some problems with the code, I will try to solve when have more time.

                    1 Reply Last reply Reply Quote 0
                    • B
                      backtrader administrators last edited by backtrader

                      The most challenging part of that calculation is:

                      upw = dtr = false and dtr[1] and utr ;
                      dnw = utr = false and utr[1] and dtr ;
                      

                      Because both statements seem to always yield: False

                      A very liberal interpretation would be:

                      • If dtr[1] and utr[1] are not yet available (there is only 1 bar) the result will be false (or 0)
                      1 Reply Last reply Reply Quote 0
                      • Paduel Gerion
                        Paduel Gerion last edited by Paduel Gerion

                        That I thought, Pythonized:

                        upw = dtr==false and dtr[-1] and utr
                        dnw = utr==false and dtr[-1] and dtr
                        

                        Meaning upw is true if current dtr is false and utr is true and the previous dtr is false. This would mark an upward trend change.

                        The same

                        upw = (not dtr) & dtr[-1] & utr
                        dnw = (not dtr) & dtr[-1] & utr
                        

                        In Metastock:

                        Assignation :=
                        Comparison =

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