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/

    backtrader CCI bug

    Indicators/Strategies/Analyzers
    2
    2
    43
    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.
    • A
      avys last edited by

      Re: Differing CCI Outputs bta-lib vs Backtrader.Indicators

      Backtrader's CCI indicator has a bug, not computing the average absolute deviation in the right way. This results in different CCI values compared to CCI values in TradingView or compared tp the CCI values using TA-Lib (in backtrader).
      The bug actually resides in the class MeanDeviation(Indicator), in the deviations.py file. MeanDeviation is used only by CCI.
      attached is a cci.py that does not use MeanDeviation but implements the required logic directly. Another approach would be fixing MeanDeviation in deviations.py, but It would be less efficient.

      Does anybody know how to feed the change into github and backtrader?

      Thanks
      Avy

      #!/usr/bin/env python
      # -*- coding: utf-8; py-indent-offset:4 -*-
      ###############################################################################
      #
      # Copyright (C) 2015-2020 Daniel Rodriguez
      #
      # This program is free software: you can redistribute it and/or modify
      # it under the terms of the GNU General Public License as published by
      # the Free Software Foundation, either version 3 of the License, or
      # (at your option) any later version.
      #
      # This program is distributed in the hope that it will be useful,
      # but WITHOUT ANY WARRANTY; without even the implied warranty of
      # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      # GNU General Public License for more details.
      #
      # You should have received a copy of the GNU General Public License
      # along with this program.  If not, see <http://www.gnu.org/licenses/>.
      #
      # Implementation (of required average absolute deviation, or mean absolute deviation (MAD)) 
      # corrected on 2021-01-19 By Avy Strominger
      #
      ###############################################################################
      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      import backtrader
      from backtrader import Indicator, Max
      from backtrader.indicators import    MovAv
      
      
      class CommodityChannelIndex(Indicator):
          '''
          Introduced by Donald Lambert in 1980 to measure variations of the
          "typical price" (see below) from its mean to identify extremes and
          reversals
      
          Formula:
            - tp = typical_price = (high + low + close) / 3
            - tpmean = MovingAverage(tp, period)
            - deviation = tp - tpmean
            - meanabsdev = MeanAbsoluteDeviation(tp) (or average absolute deviation)
            - cci = deviation / (meanabsdev * factor)
      
          See:
            - https://en.wikipedia.org/wiki/Commodity_channel_index
          '''
          alias = ('CCI',)
      
          lines = ('cci',)
      
          params = (('period', 20),
                    ('factor', 0.015),
                    ('movav', MovAv.Simple),
                    ('upperband', 100.0),
                    ('lowerband', -100.0),)
      
          def _plotlabel(self):
              plabels = [self.p.period, self.p.factor]
              plabels += [self.p.movav] * self.p.notdefault('movav')
              return plabels
      
          def _plotinit(self):
              self.plotinfo.plotyhlines = [0.0, self.p.upperband, self.p.lowerband]
      
          def __init__(self):
              self.tp = (self.data.high + self.data.low + self.data.close) / 3.0
              self.tpmean = self.p.movav(self.tp, period=self.p.period)
      
          def next(self):
              AvgAbsDev = 0
              for i in range (int(-self.p.period+1), 1):
                  AvgAbsDev = AvgAbsDev + abs(self.tp[i] - self.tpmean[0])
              AvgAbsDev = AvgAbsDev / self.p.period
              self.cci[0] = (self.tp[0] - self.tpmean[0]) / (self.p.factor * AvgAbsDev)
      
              super(CommodityChannelIndex, self).__init__()
      
      
      vladisld 1 Reply Last reply Reply Quote 0
      • vladisld
        vladisld @avys last edited by

        @avys Thanks for reporting it. Please open an issue in the backtrader2 repo (https://github.com/backtrader2/backtrader/issues). It would be great if the following info could be provided:

        1. Link to the community discussion (this page)
        2. More technical description of the error in the existing code, possibly including the problematic code location if you have one.
        3. Example of the correct vs error calculation including the data set used for both
        4. If possible, a short test that could be used for reproducing the error.

        ( example issue: https://github.com/backtrader2/backtrader/issues/41 )

        1 Reply Last reply Reply Quote 0
        • 1 / 1
        • First post
          Last post
        Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
        $(document).ready(function () { app.coldLoad(); }); }