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/

    Custom Indicator Help

    General Code/Help
    indicator pairs trading
    3
    5
    144
    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.
    • S
      SSbilis last edited by

      I want to calculate a moving average and rolling standard deviations(Kinda like Bollinger Bands) but I want to calculate this on the spread that I have calculated using the returns of two stocks. I tried using indicators such as bt.SMA and such but I kept getting errors. I eventually just manually calculated the deviation bands and MA but was hoping someone could show me what is the right way to do it, because the manual results doesn't look 100% correct either.
      Keep in mind this is part of an indicator class.

      
      def next(self):
             l0_pct_change = (
                      np.array(self.line0.get(ago=0, size=self.p.period_beta))
                      / np.array(self.line0.get(ago=-1, size=self.p.period_beta))
                      - 1
              )
             
              self.line1.idx = self.line0.idx 
      
              l1_pct_change = (
                      np.array(self.line1.get(ago=0, size=self.p.period_beta))
                      / np.array(self.line1.get(ago=-1, size=self.p.period_beta))
                      - 1
              )
              model = sm.OLS(l0_pct_change, l1_pct_change)
              self.l.beta[0] = model.fit().params
              self.l.spread[0] = l0_pct_change[0] - l1_pct_change[0]*self.l.beta[0]
      
      #These are the lines of code in question 
              datasum = math.fsum(self.l.spread.get(size=self.p.period_beta))
              self.l.spread_sma15[0] = datasum / self.p.period_beta
              self.l.spread_2sd[0] = ((((datasum-self.lines.spread_sma15)**2)/self.p.period_beta)**0.5)*2
              self.l.spread_m2sd[0] = ((((datasum - self.lines.spread_sma15) ** 2) / self.p.period_beta) ** 0.5) * -2
      run-out 1 Reply Last reply Reply Quote 0
      • run-out
        run-out @SSbilis last edited by

        @ssbilis I would like to ask a clarifying question if I may. Are you trying to do the following:

        1. Use two lines.
        2. Calculate the one (could be more than one) period return for each line.
        3. Create moving averages for each line and then subtract the lines from each other.
        4. Calcualate standard deviation bands on the result from three.

        Does this reflect what you are trying to do?

        RunBacktest.com

        S 1 Reply Last reply Reply Quote 0
        • S
          SSbilis @run-out last edited by

          @run-out Kinda.
          I want to create a pairs trading strategy.
          Where I calculate the spread using the returns of the two assets. Then I want to calculate the moving average and standard deviation of the spread.
          You get what I am saying?

          D 1 Reply Last reply Reply Quote 1
          • D
            davidavr @SSbilis last edited by

            @ssbilis I think you could do a lot of the calculations in your __init__ method and then just access them in next() to simplify things. Something like this (if I'm understanding what you are trying to do). Note, I'm faking the beta calculation since I'm not familiar with the statsmodel library.

            class St(bt.Strategy):
                def __init__(self):
                    self.amdrets = (self.datas[0].close / self.datas[0].close(-1) - 1)
                    self.intcrets = (self.datas[1].close / self.datas[1].close(-1) - 1)
                    beta = calc_beta(self.amdrets, self.intcrets)
                    self.spread = self.amdrets - self.intcrets * beta
                    self.spread_sma = MovingAverageSimple(self.spread, period=15)
                    self.spread_p2sd = StandardDeviation(self.spread_sma, period=15) * 2
                    self.spread_m2sd = -self.spread_p2sd
            
                def next(self):
                    print(f'amd: {self.amdrets[0]}, intc: {self.intcrets[0]}, spread: {self.spread[0]}, sma: {self.spread_sma[0]}, +2sd: {self.spread_p2sd[0]}, -2sd: {self.spread_m2sd[0]}')
            
            S 1 Reply Last reply Reply Quote 1
            • S
              SSbilis @davidavr last edited by

              @davidavr said in Custom Indicator Help:

                  self.spread_m2sd = -self.spread_p2sd
              

              This is actually very helpful thank you

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