Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    1. Home
    2. Mariano Volpedo
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
    • Profile
    • Following 0
    • Followers 0
    • Topics 3
    • Posts 11
    • Best 4
    • Groups 0

    Mariano Volpedo

    @Mariano Volpedo

    8
    Reputation
    45
    Profile views
    11
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Mariano Volpedo Unfollow Follow

    Best posts made by Mariano Volpedo

    • MMI: Market Meanness Index

      Hi,

      To develop momentum strategies, its relevant to understand is the trend is strong or a mean reversion is coming. Tipically, Hurst Exponent claims to work, but unfortunally I dont see value on this indicator with my data (latinamerican mutual funds).

      Finally I found the MMI as an alternative with better results to implement in my strategies. You can get the explanation and several backtestings on https://financial-hacker.com/the-market-meanness-index/ (ps: you can read there with 55 is important)

      This is my implementation on backtrader, pls your feedback is welcome

      class MMI(bt.Indicator):
          lines = ('mmi',)
          plotinfo = dict(plothlines=[55])
          params = dict(period=100,)
      
          def __init__(self):
              self.m = Average(self.data.close, period = self.p.period) #replace with median
              
          def next(self):
                  nl = 0
                  nh = 0
      
                  for j in range(self.p.period-1):
                      if j < 1:
                          continue
                      i=j * -1
                      if (self.data.close[i] > self.m[0]) and (self.data.close[i] > self.data.close[i-1]) :
                          nl += 1
                      if (self.data.close[i] < self.m[0]) and (self.data.close[i] < self.data.close[i-1]) :
                          nh += 1
                  self.l.mmi[0] = 100.0 * (nl+nh)/(self.p.period - 1)
      posted in Indicators/Strategies/Analyzers
      Mariano Volpedo
      Mariano Volpedo
    • RE: How to output plots in a dark theme?

      This is my whole dark theme, I´ve tried to emulate TradingView schema.

      plt.style.use('fivethirtyeight')
      
      plt.rcParams["figure.figsize"] = (10, 6)
      plt.rcParams['lines.linewidth'] = 1
      
      SIZE = 7
      plt.rcParams['axes.labelsize'] = SIZE
      plt.rcParams['ytick.labelsize'] = SIZE
      plt.rcParams['xtick.labelsize'] = SIZE
      plt.rcParams["font.size"] = SIZE
      
      COLOR = '1'
      plt.rcParams['text.color'] = COLOR
      plt.rcParams['axes.labelcolor'] = COLOR
      plt.rcParams['xtick.color'] = COLOR
      plt.rcParams['ytick.color'] = COLOR
      
      
      plt.rcParams['grid.linewidth']=0.1
      plt.rcParams['grid.color']="0.2"
      plt.rcParams['lines.color']="0.5"
      plt.rcParams['axes.edgecolor']="0.2"
      plt.rcParams['axes.linewidth']=0.5
      
      plt.rcParams['figure.facecolor']="#101622"
      plt.rcParams['axes.facecolor']="#101622"
      plt.rcParams["savefig.dpi"]=120
      dpi = plt.rcParams["savefig.dpi"]
      width = 700
      height = 1200
      plt.rcParams['figure.figsize'] = height/dpi, width/dpi
      plt.rcParams["savefig.facecolor"] ="#101622"
      plt.rcParams["savefig.edgecolor"]="#101622"
      
      plt.rcParams['legend.fontsize'] = SIZE
      plt.rcParams['legend.title_fontsize'] = SIZE + 1
      plt.rcParams['legend.labelspacing'] =0.25
      plt.rcParams['image.cmap']='tab10'
      
      posted in General Discussion
      Mariano Volpedo
      Mariano Volpedo
    • RE: Video based resource for Backtrader

      @sid_vishnu you will found severals backtrader vids on Part Time Larry channel. Hope this help.

      https://www.youtube.com/channel/UCY2ifv8iH1Dsgjrz-h3lWLQ

      posted in General Code/Help
      Mariano Volpedo
      Mariano Volpedo
    • Returns Volatility Indicator

      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
      posted in Indicators/Strategies/Analyzers
      Mariano Volpedo
      Mariano Volpedo

    Latest posts made by Mariano Volpedo

    • RE: A new IB integration using ib_insync

      @jason-1 based on my IB and ib_insync knowledge, this is a setup into IB, no impact on order fullfilment, as this piece of code try to solve.

      posted in General Code/Help
      Mariano Volpedo
      Mariano Volpedo
    • RE: Video based resource for Backtrader

      @sid_vishnu you will found severals backtrader vids on Part Time Larry channel. Hope this help.

      https://www.youtube.com/channel/UCY2ifv8iH1Dsgjrz-h3lWLQ

      posted in General Code/Help
      Mariano Volpedo
      Mariano Volpedo
    • Returns Volatility Indicator

      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
      posted in Indicators/Strategies/Analyzers
      Mariano Volpedo
      Mariano Volpedo
    • RE: LUCID - a social investment platform built on backtrader

      @farch-investment very interesting, we are working on the same direction, lets talk !

      posted in General Discussion
      Mariano Volpedo
      Mariano Volpedo
    • RE: bt.analyzers.PyFolio: IndexError: array index out of range

      @zoutain I see that you are trying to generate a tearsheet using quantstats instead of pyfolio, I strongly suggest to read this https://community.backtrader.com/topic/2506/how-to-create-pyfolio-round-trip-tearsheet/18

      You need to change the analyzer and implement a new one.

      posted in General Discussion
      Mariano Volpedo
      Mariano Volpedo
    • RE: Dark/night mode for chart

      This is my dark color scheme simulating tradingview theme just adjusting general matplotlib defaults.

      SIZE = 6
      COLOR = 'white'
      BACKGROUND = "#101622"
      GRID="0.4"
      
      def default_colors(color=COLOR, size=SIZE, background=BACKGROUND, grid=GRID):
          matplotlib.use('Agg')
          plt.style.use('fivethirtyeight')    
          plt.rcParams["figure.figsize"] = (10, 6)
          plt.rcParams['lines.linewidth'] = 0.5
          plt.rcParams['lines.color']="0.5"
          
          plt.rcParams["font.size"] = size
          plt.rcParams['axes.labelsize'] = size
          plt.rcParams['ytick.labelsize'] = size
          plt.rcParams['xtick.labelsize'] = size
      
          plt.rcParams['text.color'] = color
          plt.rcParams['axes.labelcolor'] = color
          plt.rcParams['xtick.color'] = color
          plt.rcParams['ytick.color'] = color
          
          plt.rcParams['axes.grid.axis']='both'
          plt.rcParams['grid.linewidth']=0.1
          plt.rcParams['grid.color']=grid
          #plt.rcParams['axes.edgecolor']="0.2"
          plt.rcParams['axes.linewidth']=0
      
         #plt.rcParams['grid.linewidth']=0
          
          plt.rcParams['figure.facecolor'] = background
          plt.rcParams['axes.facecolor'] = background
          plt.rcParams["savefig.dpi"]=120
          dpi = plt.rcParams["savefig.dpi"]
          width = 700
          height = 1200
          plt.rcParams['figure.figsize'] = height/dpi, width/dpi
          plt.rcParams["savefig.facecolor"] = background
          plt.rcParams["savefig.edgecolor"] = background
          
          plt.rcParams['legend.fontsize'] = SIZE + 2
          plt.rcParams['legend.title_fontsize'] = SIZE + 2
          plt.rcParams['legend.labelspacing'] = 0.25
          plt.rcParams['image.cmap']='tab10'
          
          plt.ioff()
      posted in General Discussion
      Mariano Volpedo
      Mariano Volpedo
    • ALMA: Arnaud Legoux Moving Average

      Another trend indicator: ALMA
      From http://www.financial-hacker.com/trend-delusion-or-reality/

      Appreciate you feedback for bugs or omissions

      Ps: "alma" means soul in spanish

      class ALMA(bt.Indicator):
          lines = ('alma',)
      
          params = dict(
                          period=40,
                          sigma=6,
                          offset=1,
                      )
          def __init__(self):
      
              self.asize = self.p.period - 1
              self.m = self.p.offset * self.asize
              self.s = self.p.period  / self.p.sigma
              self.dss = 2 * self.s * self.s
      
          def next(self):
              try:
                  wtd_sum = 0
                  self.l.alma[0] = 0
                  if len(self) >= self.asize:
                      for i in range(self.p.period):
                          im = i - self.m
                          wtd = np.exp( -(im * im) / self.dss)
                          self.l.alma[0] += self.data[0 - self.p.period + i] * wtd
                          wtd_sum += wtd
                      self.l.alma[0] = self.l.alma[0] / wtd_sum
                      print(self.l.alma[0])
      
              except TypeError:
                  self.l.alma[0] = 0
                  return
      posted in Indicators/Strategies/Analyzers
      Mariano Volpedo
      Mariano Volpedo
    • RE: Custom Indicator Arnaud Legoux Moving Average (Vectorised or Nan-Vec): Help Needed

      @Ender-Kina this my ALMA implementation as backtrader indicator

      class ALMA(bt.Indicator):
          lines = ('alma',)
      
          params = dict(
                          period=40,
                          sigma=6,
                          offset=1,
                      )
          
          '''
          ALMA - Arnaud Legoux Moving Average,
          http://www.financial-hacker.com/trend-delusion-or-reality/
          https://github.com/darwinsys/Trading_Strategies/blob/master/ML/Features.py
            ''' 
          def __init__(self):
      
              self.asize = self.p.period - 1
              self.m = self.p.offset * self.asize
              self.s = self.p.period  / self.p.sigma
              self.dss = 2 * self.s * self.s
      
          def next(self):
              try:
                  wtd_sum = 0
                  self.l.alma[0] = 0
                  if len(self) >= self.asize:
                      for i in range(self.p.period):
                          im = i - self.m
                          wtd = np.exp( -(im * im) / self.dss)
                          self.l.alma[0] += self.data[0 - self.p.period + i] * wtd
                          wtd_sum += wtd
                      self.l.alma[0] = self.l.alma[0] / wtd_sum
                      print(self.l.alma[0])
      
              except TypeError:
                  self.l.alma[0] = 0
                  return
      posted in General Code/Help
      Mariano Volpedo
      Mariano Volpedo
    • MMI: Market Meanness Index

      Hi,

      To develop momentum strategies, its relevant to understand is the trend is strong or a mean reversion is coming. Tipically, Hurst Exponent claims to work, but unfortunally I dont see value on this indicator with my data (latinamerican mutual funds).

      Finally I found the MMI as an alternative with better results to implement in my strategies. You can get the explanation and several backtestings on https://financial-hacker.com/the-market-meanness-index/ (ps: you can read there with 55 is important)

      This is my implementation on backtrader, pls your feedback is welcome

      class MMI(bt.Indicator):
          lines = ('mmi',)
          plotinfo = dict(plothlines=[55])
          params = dict(period=100,)
      
          def __init__(self):
              self.m = Average(self.data.close, period = self.p.period) #replace with median
              
          def next(self):
                  nl = 0
                  nh = 0
      
                  for j in range(self.p.period-1):
                      if j < 1:
                          continue
                      i=j * -1
                      if (self.data.close[i] > self.m[0]) and (self.data.close[i] > self.data.close[i-1]) :
                          nl += 1
                      if (self.data.close[i] < self.m[0]) and (self.data.close[i] < self.data.close[i-1]) :
                          nh += 1
                  self.l.mmi[0] = 100.0 * (nl+nh)/(self.p.period - 1)
      posted in Indicators/Strategies/Analyzers
      Mariano Volpedo
      Mariano Volpedo
    • RE: How to output plots in a dark theme?

      This is my whole dark theme, I´ve tried to emulate TradingView schema.

      plt.style.use('fivethirtyeight')
      
      plt.rcParams["figure.figsize"] = (10, 6)
      plt.rcParams['lines.linewidth'] = 1
      
      SIZE = 7
      plt.rcParams['axes.labelsize'] = SIZE
      plt.rcParams['ytick.labelsize'] = SIZE
      plt.rcParams['xtick.labelsize'] = SIZE
      plt.rcParams["font.size"] = SIZE
      
      COLOR = '1'
      plt.rcParams['text.color'] = COLOR
      plt.rcParams['axes.labelcolor'] = COLOR
      plt.rcParams['xtick.color'] = COLOR
      plt.rcParams['ytick.color'] = COLOR
      
      
      plt.rcParams['grid.linewidth']=0.1
      plt.rcParams['grid.color']="0.2"
      plt.rcParams['lines.color']="0.5"
      plt.rcParams['axes.edgecolor']="0.2"
      plt.rcParams['axes.linewidth']=0.5
      
      plt.rcParams['figure.facecolor']="#101622"
      plt.rcParams['axes.facecolor']="#101622"
      plt.rcParams["savefig.dpi"]=120
      dpi = plt.rcParams["savefig.dpi"]
      width = 700
      height = 1200
      plt.rcParams['figure.figsize'] = height/dpi, width/dpi
      plt.rcParams["savefig.facecolor"] ="#101622"
      plt.rcParams["savefig.edgecolor"]="#101622"
      
      plt.rcParams['legend.fontsize'] = SIZE
      plt.rcParams['legend.title_fontsize'] = SIZE + 1
      plt.rcParams['legend.labelspacing'] =0.25
      plt.rcParams['image.cmap']='tab10'
      
      posted in General Discussion
      Mariano Volpedo
      Mariano Volpedo