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/

    BollingerBands Squeeze

    Indicators/Strategies/Analyzers
    2
    3
    1447
    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.
    • D
      dasch last edited by

      If anyone needs this, here is a BBSqueeze indicator.

      implementation is based on this: https://www.netpicks.com/squeeze-out-the-chop/

      BBSqueeze

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      import backtrader as bt
      
      from . import KeltnerChannel
      
      
      class BBSqueeze(bt.Indicator):
      
          '''
          https://www.netpicks.com/squeeze-out-the-chop/
      
          Both indicators are symmetrical, meaning that the upper and lower bands or channel lines are the same distance from the moving average. That means that we can focus on only one side in developing our indicator. In our case, we’ll just consider the upper lines.
      
          The basic formulas we need are:
      
              Bollinger Band = Moving Average + (Number of standard deviations X Standard Deviation)
              Keltner Channel = Moving Average + (Number of ATR’s X ATR)
      
          Or if we translate this into pseudo-code:
      
              BBUpper = Avg(close, period) + (BBDevs X StdDev(close, period))
              KCUpper = Avg(close, period) + (KCDevs X ATR(period))
      
          The squeeze is calculated by taking the difference between these two values:
      
              Squeeze = BBUpper – KCUpper
      
          Which simplifies down to this:
      
              Squeeze = (BBDevs X StdDev(close, period)) – (KCDevs X ATR(period))
          '''
      
          lines = ('squeeze',)
          params = (('period', 20), ('devfactor', 2.0), ('movav', bt.ind.MovAv.Simple),)
      
          plotinfo = dict(subplot=True)
      
          def _plotlabel(self):
              plabels = [self.p.period, self.p.devfactor]
              plabels += [self.p.movav] * self.p.notdefault('movav')
              return plabels
      
          def __init__(self):
              bb = bt.ind.BollingerBands(
                  period=self.p.period, devfactor=self.p.devfactor, movav=self.p.movav)
              kc = KeltnerChannel(
                  period=self.p.period, devfactor=self.p.devfactor, movav=self.p.movav)
              self.lines.squeeze = bb.top - kc.top
      

      KeltnerChannel

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      import backtrader as bt
      
      
      class KeltnerChannel(bt.Indicator):
      
          lines = ('mid', 'top', 'bot',)
          params = (('period', 20), ('devfactor', 1.5),
                    ('movav', bt.ind.MovAv.Simple),)
      
          plotinfo = dict(subplot=False)
          plotlines = dict(
              mid=dict(ls='--'),
              top=dict(_samecolor=True),
              bot=dict(_samecolor=True),
          )
      
          def _plotlabel(self):
              plabels = [self.p.period, self.p.devfactor]
              plabels += [self.p.movav] * self.p.notdefault('movav')
              return plabels
      
          def __init__(self):
              self.lines.mid = ma = self.p.movav(self.data, period=self.p.period)
              atr = self.p.devfactor * bt.ind.ATR(self.data, period=self.p.period)
              self.lines.top = ma + atr
              self.lines.bot = ma - atr
      
      1 Reply Last reply Reply Quote 3
      • D
        dasch last edited by

        BBSqueeze with configureable multiplicators for bb and keltner

        from __future__ import (absolute_import, division, print_function,
                                unicode_literals)
        
        import backtrader as bt
        
        from . import KeltnerChannel
        
        
        class BBSqueeze(bt.Indicator):
        
            '''
            https://www.netpicks.com/squeeze-out-the-chop/
        
            Both indicators are symmetrical, meaning that the upper and lower bands or channel lines are the same distance from the moving average. That means that we can focus on only one side in developing our indicator. In our case, we’ll just consider the upper lines.
        
            The basic formulas we need are:
        
                Bollinger Band = Moving Average + (Number of standard deviations X Standard Deviation)
                Keltner Channel = Moving Average + (Number of ATR’s X ATR)
        
            Or if we translate this into pseudo-code:
        
                BBUpper = Avg(close, period) + (BBDevs X StdDev(close, period))
                KCUpper = Avg(close, period) + (KCDevs X ATR(period))
        
            The squeeze is calculated by taking the difference between these two values:
        
                Squeeze = BBUpper – KCUpper
        
            Which simplifies down to this:
        
                Squeeze = (BBDevs X StdDev(close, period)) – (KCDevs X ATR(period))
            '''
        
            lines = ('squeeze',)
            params = (('period', 20), ('bbdevs', 2.0), ('kcdevs', 1.5), ('movav', bt.ind.MovAv.Simple),)
        
            plotinfo = dict(subplot=True)
        
            def _plotlabel(self):
                plabels = [self.p.period, self.p.bbdevs, self.p.kcdevs]
                plabels += [self.p.movav] * self.p.notdefault('movav')
                return plabels
        
            def __init__(self):
                bb = bt.ind.BollingerBands(
                    period=self.p.period, devfactor=self.p.bbdevs, movav=self.p.movav)
                kc = KeltnerChannel(
                    period=self.p.period, devfactor=self.p.kcdevs, movav=self.p.movav)
                self.lines.squeeze = bb.top - kc.top
        
        
        1 Reply Last reply Reply Quote 3
        • mics
          mics last edited by

          Thanks for sharing this @dasch.

          Flipping positions between BBands is a part of my primary strategy whilst waiting for breakouts to occur. I've been using price action relative to dynamic highs and lows to identify breakouts from choppy zones.

          I'll see how introducing the Keltner Channel performs.

          M

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