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/

    Returns Volatility Indicator

    Indicators/Strategies/Analyzers
    1
    1
    251
    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.
    • Mariano Volpedo
      Mariano Volpedo last edited by

      Hey, dear community !

      Building volatility targeting strategies, I found that this relevant indicator is missing.

      You could find more about this here:
      https://quantpedia.com/an-introduction-to-volatility-targeting/#:~:text=Volatility target is the level,volatility is easier to predict.

      Hope this helps. Comments?

      PS: GARCH implementation for the next version but literature says it's expensive and you get similar results using faster EWMA

      class StdDevReturns(bt.Indicator):
      
          lines = ('stddev',)
          params = dict(
                          method="simple", # or ewma_pd or ewma_np
                          annualized = True,
                          period=20,
                          alpha=0.06, # only for ewma
                          adjust=True, # only for ewma_pd
                          trading_year_days=252,
                      )
          
          def __init__(self):
              self.addminperiod(self.params.period + 2)
              if self.p.annualized:
                  self.annualized = self.p.trading_year_days ** (1 / 2)
              else:
                  self.annualized = 1
              
          def next(self):
              returns = self.Returns(self.data0.get(size=self.p.period))
              
              if self.p.method == "simple":
                  self.lines.stddev[0] = returns.std() * self.annualized
              elif self.p.method == "ewma_pd":
                  data = pd.DataFrame(returns)
                  self.lines.stddev[0] = data.ewm(alpha=self.p.alpha, adjust= self.p.adjust).std().iloc[-1][0] * self.annualized
              elif self.p.method == "ewma_np":            
                  self.lines.stddev[0] = self.CalculateEWMAVol(returns, 1 - self.p.alpha) * self.annualized
      
          def Returns(self, prices):
              return np.diff(np.log(prices)) #np.diff(prices) / prices[1:]
          
          def CalculateEWMAVol(self, returns, _lambda):   
              period = len(returns)
              average_returns = returns.mean()
          
              e = np.arange(period-1, -1, -1)
              r = np.repeat(_lambda, period)
              vector_lambda = np.power(r, e)
          
              sxxewm = (np.power(returns - average_returns, 2) * vector_lambda).sum()
              Vart = sxxewm/vector_lambda.sum()
              EWMAVol = math.sqrt(Vart)
          
              return EWMAVol
      1 Reply Last reply Reply Quote 1
      • 1 / 1
      • First post
        Last post
      Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors