Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    1. Home
    2. weibudda
    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 1
    • Followers 0
    • Topics 14
    • Posts 23
    • Best 1
    • Groups 0

    weibudda

    @weibudda

    1
    Reputation
    20
    Profile views
    23
    Posts
    0
    Followers
    1
    Following
    Joined Last Online

    weibudda Unfollow Follow

    Best posts made by weibudda

    • Problem in parallel

      Following the documention sample code, "Strategy Selection Revisited", https://www.backtrader.com/blog/posts/2017-05-16-stsel-revisited/stsel-revisited/

      when --maxcpus 1, everything is OK, but when --maxcpus 2, or anything else but 1, it reports :

      multiprocessing.pool.MaybeEncodingError: Error sending result: '[<backtrader.cerebro.OptReturn object at 0x0000000015921988>]'. Reason: 'PicklingError("Can't pickle <class
      'mp_main.St0'>: it's not the same object as mp_main.St0")'

      what's the problem?

      the related details:

      (backtrader37) D:\Python\Jupyter\BackTrader\Test>python ./stselection-revisited.py --optreturn --maxcpus 2
      Traceback (most recent call last):
      File "./stselection-revisited.py", line 89, in <module>
      runstrat()
      File "./stselection-revisited.py", line 59, in runstrat
      results = cerebro.run(maxcpus=args.maxcpus, optreturn=args.optreturn)
      File "C:\Users\WEI.conda\envs\backtrader37\lib\site-packages\backtrader\cerebro.py", line 1143, in run
      for r in pool.imap(self, iterstrats):
      File "C:\Users\WEI.conda\envs\backtrader37\lib\multiprocessing\pool.py", line 748, in next
      raise value
      multiprocessing.pool.MaybeEncodingError: Error sending result: '[<backtrader.cerebro.OptReturn object at 0x0000000015921988>]'. Reason: 'PicklingError("Can't pickle <class
      'mp_main.St0'>: it's not the same object as mp_main.St0")'

      from future import (absolute_import, division, print_function,
      unicode_literals)

      import argparse

      import backtrader as bt
      from backtrader.utils.py3 import range

      class StFetcher(object):
      _STRATS = []

      @classmethod
      def register(cls, target):
          cls._STRATS.append(target)
      
      @classmethod
      def COUNT(cls):
          return range(len(cls._STRATS))
      
      def __new__(cls, *args, **kwargs):
          idx = kwargs.pop('idx')
      
          obj = cls._STRATS[idx](*args, **kwargs)
          return obj
      

      @StFetcher.register
      class St0(bt.SignalStrategy):
      def init(self):
      sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30)
      crossover = bt.ind.CrossOver(sma1, sma2)
      self.signal_add(bt.SIGNAL_LONG, crossover)

      @StFetcher.register
      class St1(bt.SignalStrategy):
      def init(self):
      sma1 = bt.ind.SMA(period=10)
      crossover = bt.ind.CrossOver(self.data.close, sma1)
      self.signal_add(bt.SIGNAL_LONG, crossover)

      def runstrat(pargs=None):
      args = parse_args(pargs)

      cerebro = bt.Cerebro()
      data = bt.feeds.BacktraderCSVData(dataname=args.data)
      cerebro.adddata(data)
      
      cerebro.addanalyzer(bt.analyzers.Returns)
      cerebro.optstrategy(StFetcher, idx=StFetcher.COUNT())
      results = cerebro.run(maxcpus=args.maxcpus, optreturn=args.optreturn)
      
      strats = [x[0] for x in results]  # flatten the result
      for i, strat in enumerate(strats):
          rets = strat.analyzers.returns.get_analysis()
          print('Strat {} Name {}:\n  - analyzer: {}\n'.format(
              i, strat.__class__.__name__, rets))
      

      def parse_args(pargs=None):

      parser = argparse.ArgumentParser(
          formatter_class=argparse.ArgumentDefaultsHelpFormatter,
          description='Sample for strategy selection')
      
      parser.add_argument('--data', required=False,
                          default='../../datas/2005-2006-day-001.txt',
                          help='Data to be read in')
      
      parser.add_argument('--maxcpus', required=False, action='store',
                          default=None, type=int,
                          help='Limit the numer of CPUs to use')
      
      parser.add_argument('--optreturn', required=False, action='store_true',
                          help='Return reduced/mocked strategy object')
      
      return parser.parse_args(pargs)
      

      if name == 'main':
      runstrat()

      posted in General Code/Help
      weibudda
      weibudda

    Latest posts made by weibudda

    • RE: How to skip the plot of some datas in a mutidata strategy

      @run-out said in How to skip the plot of some datas in a mutidata strategy:

      data_0.plotinfo.plot = False

      Problem has been solved, thanks very much!

      posted in General Code/Help
      weibudda
      weibudda
    • How to skip the plot of some datas in a mutidata strategy

      In an indicator development, simply adding a _plotskip=True command, can skip the plot of a specific line. But how to skip the plot of some datas in a mutidata strategy?
      I have tried the following, but it does not work? data_0 and data_1 are still plotted. Any suggestions?

      data_0 = bt.feeds.PandasData(dataname=data_index, tz=tz_cn)
          data_0.plotinfo._plotskip = True
          cerebro.adddata(data_0)
          data_1 = cerebro.replaydata(data_0, timeframe=getattr(bt.TimeFrame, 'Weeks'))
          data_1.plotinfo._plotskip = True
      
      posted in General Code/Help
      weibudda
      weibudda
    • RE: MultiCursor horizontal and vertical lines invisible

      Problem solved. Simply modify block=True in plot.py:

       def show(self):
              self.mpyplot.show(block=True)
      
      posted in General Code/Help
      weibudda
      weibudda
    • MultiCursor horizontal and vertical lines invisible

      In the matplotlib's multicursor example:

      import numpy as np
      import matplotlib.pyplot as plt
      from matplotlib.widgets import MultiCursor
      
      t = np.arange(0.0, 2.0, 0.01)
      s1 = np.sin(2*np.pi*t)
      s2 = np.sin(4*np.pi*t)
      
      fig, (ax1, ax2) = plt.subplots(2, sharex=True)
      ax1.plot(t, s1)
      ax2.plot(t, s2)
      
      multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1)
      plt.show()
      

      The horizontal and vertical lines is visible. Why in the backtrader situation, the are disappeared?

      I checked the MultiCursor source code in backtrader,

      class MultiCursor(Widget):
          """
          Provide a vertical (default) and/or horizontal line cursor shared between
          multiple axes.
      
          For the cursor to remain responsive you much keep a reference to
          it.
      
          Example usage::
      
              from matplotlib.widgets import MultiCursor
              from pylab import figure, show, np
      
              t = np.arange(0.0, 2.0, 0.01)
              s1 = np.sin(2*np.pi*t)
              s2 = np.sin(4*np.pi*t)
              fig = figure()
              ax1 = fig.add_subplot(211)
              ax1.plot(t, s1)
      
      
              ax2 = fig.add_subplot(212, sharex=ax1)
              ax2.plot(t, s2)
      
              multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1,
                                  horizOn=False, vertOn=True)
              show()
      
          """
          def __init__(self, canvas, axes, useblit=True,
                       horizOn=False, vertOn=True,
                       horizMulti=False, vertMulti=True,
                       horizShared=True, vertShared=False,
                       **lineprops):
      
              self.canvas = canvas
              self.axes = axes
              self.horizOn = horizOn
              self.vertOn = vertOn
              self.horizMulti = horizMulti
              self.vertMulti = vertMulti
      
              self.visible = True
              self.useblit = useblit and self.canvas.supports_blit
              self.background = None
              self.needclear = False
      
              if self.useblit:
                  lineprops['animated'] = True
      
              self.vlines = []
              if vertOn:
                  xmin, xmax = axes[-1].get_xlim()
                  xmid = 0.5 * (xmin + xmax)
      
                  for ax in axes:
                      if not horizShared:
                          xmin, xmax = ax.get_xlim()
                          xmid = 0.5 * (xmin + xmax)
      
                      vline = ax.axvline(xmid, visible=False, **lineprops)
                      self.vlines.append(vline)
      
              self.hlines = []
              if horizOn:
                  ymin, ymax = axes[-1].get_ylim()
                  ymid = 0.5 * (ymin + ymax)
      
                  for ax in axes:
                      if not vertShared:
                          ymin, ymax = ax.get_ylim()
                          ymid = 0.5 * (ymin + ymax)
      
                      hline = ax.axhline(ymid, visible=False, **lineprops)
                      self.hlines.append(hline)
      
              self.connect()
      
          def connect(self):
              """connect events"""
              self._cidmotion = self.canvas.mpl_connect('motion_notify_event',
                                                        self.onmove)
              self._ciddraw = self.canvas.mpl_connect('draw_event', self.clear)
      
          def disconnect(self):
              """disconnect events"""
              self.canvas.mpl_disconnect(self._cidmotion)
              self.canvas.mpl_disconnect(self._ciddraw)
      
          def clear(self, event):
              """clear the cursor"""
              if self.ignore(event):
                  return
              if self.useblit:
                  self.background = (
                      self.canvas.copy_from_bbox(self.canvas.figure.bbox))
              for line in self.vlines + self.hlines:
                  line.set_visible(False)
      
          def onmove(self, event):
              if self.ignore(event):
                  return
              if event.inaxes is None:
                  return
              if not self.canvas.widgetlock.available(self):
                  return
              self.needclear = True
              if not self.visible:
                  return
              if self.vertOn:
                  for line in self.vlines:
                      visible = self.visible
                      if not self.vertMulti:
                          visible = visible and line.axes == event.inaxes
      
                      if visible:
                          line.set_xdata((event.xdata, event.xdata))
                          line.set_visible(visible)
              if self.horizOn:
                  for line in self.hlines:
                      visible = self.visible
                      if not self.horizMulti:
                          visible = visible and line.axes == event.inaxes
                      if visible:
                          line.set_ydata((event.ydata, event.ydata))
                          line.set_visible(self.visible)
              self._update(event)
      
          def _update(self, event):
              if self.useblit:
                  if self.background is not None:
                      self.canvas.restore_region(self.background)
                  if self.vertOn:
                      for ax, line in zip(self.axes, self.vlines):
                          if self.vertMulti or event.inaxes == line.axes:
                              ax.draw_artist(line)
      
                  if self.horizOn:
                      for ax, line in zip(self.axes, self.hlines):
                          if self.horizMulti or event.inaxes == line.axes:
                              ax.draw_artist(line)
                  self.canvas.blit(self.canvas.figure.bbox)
              else:
                  self.canvas.draw_idle()
      

      and compared it to the one in matplotlib:

      class MultiCursor(Widget):
          """
          Provide a vertical (default) and/or horizontal line cursor shared between
          multiple axes.
      
          For the cursor to remain responsive you must keep a reference to
          it.
      
          Example usage::
      
              from matplotlib.widgets import MultiCursor
              import matplotlib.pyplot as plt
              import numpy as np
      
              fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)
              t = np.arange(0.0, 2.0, 0.01)
              ax1.plot(t, np.sin(2*np.pi*t))
              ax2.plot(t, np.sin(4*np.pi*t))
      
              multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1,
                                  horizOn=False, vertOn=True)
              plt.show()
      
          """
         def __init__(self, canvas, axes, useblit=True, horizOn=False, vertOn=True,
                       **lineprops):
      
              self.canvas = canvas
              self.axes = axes
              self.horizOn = horizOn
              self.vertOn = vertOn
      
              xmin, xmax = axes[-1].get_xlim()
              ymin, ymax = axes[-1].get_ylim()
              xmid = 0.5 * (xmin + xmax)
              ymid = 0.5 * (ymin + ymax)
      
              self.visible = True
              self.useblit = useblit and self.canvas.supports_blit
              self.background = None
              self.needclear = False
      
              if self.useblit:
                  lineprops['animated'] = True
      
              if vertOn:
                  self.vlines = [ax.axvline(xmid, visible=False, **lineprops)
                                 for ax in axes]
              else:
                  self.vlines = []
      
              if horizOn:
                  self.hlines = [ax.axhline(ymid, visible=False, **lineprops)
                                 for ax in axes]
              else:
                  self.hlines = []
      
              self.connect()
      
        def connect(self):
              """connect events"""
              self._cidmotion = self.canvas.mpl_connect('motion_notify_event',
                                                        self.onmove)
              self._ciddraw = self.canvas.mpl_connect('draw_event', self.clear)
      
      
          def disconnect(self):
              """disconnect events"""
              self.canvas.mpl_disconnect(self._cidmotion)
              self.canvas.mpl_disconnect(self._ciddraw)
      
         def clear(self, event):
              """clear the cursor"""
              if self.ignore(event):
                  return
              if self.useblit:
                  self.background = (
                      self.canvas.copy_from_bbox(self.canvas.figure.bbox))
              for line in self.vlines + self.hlines:
                  line.set_visible(False)
      
          def onmove(self, event):
              if self.ignore(event):
                  return
              if event.inaxes is None:
                  return
              if not self.canvas.widgetlock.available(self):
                  return
              self.needclear = True
              if not self.visible:
                  return
              if self.vertOn:
                  for line in self.vlines:
                      line.set_xdata((event.xdata, event.xdata))
                      line.set_visible(self.visible)
              if self.horizOn:
                  for line in self.hlines:
                      line.set_ydata((event.ydata, event.ydata))
                      line.set_visible(self.visible)
              self._update()
      
      
          def _update(self):
              if self.useblit:
                  if self.background is not None:
                      self.canvas.restore_region(self.background)
                  if self.vertOn:
                      for ax, line in zip(self.axes, self.vlines):
                          ax.draw_artist(line)
                  if self.horizOn:
                      for ax, line in zip(self.axes, self.hlines):
                          ax.draw_artist(line)
                  self.canvas.blit(self.canvas.figure.bbox)
              else:
                  self.canvas.draw_idle()
      

      Nothing is wrong. What's the problem? Any suggestions?

      posted in General Code/Help
      weibudda
      weibudda
    • How to use backtrader built-in indicator like a 'normal' indicator?

      When I use backtrader built-in indicator out-of backtrader environment,

      a = bt.indicators.EMA(datas.close, period=13)
      

      it returns a <backtrader.indicators.ema.EMA at 0x1af69d08> object, with data lengtn of 0
      How to get a normal data array like datas.close, instead of an empty object?

      posted in General Code/Help
      weibudda
      weibudda
    • Problem with data clone

      When I use data1 = data.clone() method, it reports the following error:

      ...
              data = bt.feeds.PandasData(dataname=datas.loc[code], tz=tz_cn)
              data._name = code[0:6]
              data1 = data.clone()
              cerebro.adddata(data1)
      ...
      
        File "D:/Python/Jupyter/BackTrader/Test/Record/Order_History_C1.py", line 436, in runstrat
          cerebro.run()
        File "C:\Users\WEI\.conda\envs\backtrader37\lib\site-packages\backtrader\cerebro.py", line 1127, in run
          runstrat = self.runstrategies(iterstrat)
        File "C:\Users\WEI\.conda\envs\backtrader37\lib\site-packages\backtrader\cerebro.py", line 1210, in runstrategies
          data._start()
        File "C:\Users\WEI\.conda\envs\backtrader37\lib\site-packages\backtrader\feed.py", line 756, in _start
          self._tz = self.data._tz
        File "C:\Users\WEI\.conda\envs\backtrader37\lib\site-packages\backtrader\lineseries.py", line 461, in __getattr__
          return getattr(self.lines, name)
      AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute '_tz'
      
      

      Any suggestions?

      posted in General Code/Help
      weibudda
      weibudda
    • Is it possible to bulid a data filter using backtrader's built-in indicators?

      I want to bulid a data filter using backtrader's built in indicators, as the following codes:

      class ImpulseSystem(object):
          def __init__(self, data):
              self.ema = bt.indicators.EMA(data.close, period=13)
              macd, signal, self.macd_hist = bt.indicators.MACDHisto(data.close, period_me1=12, period_me2=26,
                                                                     period_signal=9)
              data.impulse = np.zeros_like(data.close)
      
          def __call__(self, data):
              if len(data) > 1:
                  if (self.ema[0] > self.ema[-1]) and (self.macd_hist[0] > self.macd_hist[-1]):
                      data.impulse[0] = 1
                  elif (self.ema[0] < self.ema[-1]) and (self.macd_hist[0] < self.macd_hist[-1]):
                      data.impulse[0] = -1
              return False  # length of data stream is unaltered
      
      
      ....
      
              data = bt.feeds.PandasData(dataname=datas.loc[code], tz=tz_cn)
              data._name = code[0:6]
              data1 = data.clone()
              data1.addfilter(ImpulseSystem)
              cerebro.adddata(data1)
      

      This code will atempt to and a signal line 'impulse' to the data feed,
      but it reports the following error,

      File "D:/Python/Jupyter/BackTrader/Test/Record/Order_History_C1.py", line 397, in runstrat
          data1.addfilter(ImpulseSystem)
        File "C:\Users\WEI\.conda\envs\backtrader37\lib\site-packages\backtrader\feed.py", line 332, in addfilter
          pobj = p(self, *args, **kwargs)
        File "D:/Python/Jupyter/BackTrader/Test/Record/Order_History_C1.py", line 89, in __init__
          self.ema = bt.indicators.EMA(data.close, period=13)
        File "C:\Users\WEI\.conda\envs\backtrader37\lib\site-packages\backtrader\indicator.py", line 53, in __call__
          return super(MetaIndicator, cls).__call__(*args, **kwargs)
        File "C:\Users\WEI\.conda\envs\backtrader37\lib\site-packages\backtrader\metabase.py", line 89, in __call__
          _obj, args, kwargs = cls.dopostinit(_obj, *args, **kwargs)
        File "C:\Users\WEI\.conda\envs\backtrader37\lib\site-packages\backtrader\lineiterator.py", line 143, in dopostinit
          _obj._owner.addindicator(_obj)
        File "C:\Users\WEI\.conda\envs\backtrader37\lib\site-packages\backtrader\lineseries.py", line 461, in __getattr__
          return getattr(self.lines, name)
      AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'addindicator'
      

      What's the matter?

      posted in Indicators/Strategies/Analyzers
      weibudda
      weibudda
    • RE: How to control the color of the Histogram in MACDHisto?

      A method has been found, not very genious.

      A few lines can be added to the plotind function of plot.py in the source code:

                  if plotkwargs['color'] == 'bar':
                      colord = {True: 'red', False: 'green'}
                      colors = [colord[lplot_value > 0] for lplot_value in lplotarray]
                      plotkwargs['color'] = colors
      
                  plottedline = pltmethod(xdata, lplotarray, **plotkwargs)
      

      And when defining a new indicator:

      simply add:

      plotlines = dict(histo=dict(_method='bar', alpha=0.50, width=1.0, color='bar'))
      
      posted in General Code/Help
      weibudda
      weibudda
    • RE: How to control the color of the Histogram in MACDHisto?

      I tried the following:

      class MACDHisto2(bt.indicators.MACDHisto):
          alias = ('MACDHistogram',)
      
          lines = ('histo',)
      
          # colors = ['r','g']
          plotlines = dict(histo=dict(_method='bar', alpha=0.50, width=1.0))
      
          def __init__(self):
              colord = {True: 'red', False: 'green'}
              colors = [colord[histo_0 < 0] for histo_0 in self.lines.histo]
      
              self.plotlines['histo'].update(color=colors)
              super(MACDHisto2, self).__init__()
      

      it reports:

      File "D:/Python/C1.py", line 82, in __init__
          self.plotlines['histo'].update(color=colors)
      TypeError: 'AutoInfoClass_pl_LineSeries_pl_LineIterator_pl_DataAccessor_pl_IndicatorBase_pl_Indicator_pl_MACD_pl_MACDHisto_pl_MACDHisto2' object is not subscriptable
      

      Still did not Work...

      posted in General Code/Help
      weibudda
      weibudda
    • How to control the color of the Histogram in MACDHisto?

      In many stock charts, we can find MACD Histogram bar plots with different colors for positive and negtive ones. But in backtrader, they have the same color in default. How to implement different color for positive and negtive bars?

      I have tried to append a 'color=[]' parameter as follows,

      class MACDHisto2(bt.indicators.MACDHisto):
      
          alias = ('MACDHistogram',)
      
          lines = ('histo',)
      
          colors = ['r','g']
      
          # colord = {True: 'red', False: 'green'}
          # colors = [colord[histo_0 < 0] for histo_0 in lines.histo]
      
          plotlines = dict(histo=dict(_method='bar', alpha=0.50, width=1.0, color=colors))
      
          def __init__(self):
              super(MACDHisto2, self).__init__()
      

      it works, the bar plots becomes alternating red and green bars
      But how to construct a list, correspongding to the correct color of each bars?
      I have tried the following, but it doesn't works? any suggestions?

      class MACDHisto2(bt.indicators.MACDHisto):
      
          alias = ('MACDHistogram',)
      
          lines = ('histo',)
      
          # colors = ['r','g']
      
          colord = {True: 'red', False: 'green'}
          colors = [colord[histo_0 < 0] for histo_0 in lines.histo]
      
          plotlines = dict(histo=dict(_method='bar', alpha=0.50, width=1.0, color=colors))
      
          def __init__(self):
              super(MACDHisto2, self).__init__()
      
      ERROR:
      
      File "D:/Python/Jupyter/BackTrader/Test/Record/Order_History_C1.py", line 79, in MACDHisto2
          colors = [colord[histo_0 < 0] for histo_0 in lines.histo]
      AttributeError: 'tuple' object has no attribute 'histo'
      
      

      or

      class MACDHisto2(bt.indicators.MACDHisto):
          alias = ('MACDHistogram',)
      
          lines = ('histo',)
      
          # colors = ['r','g']
          plotlines = {}
      
          def __init__(self):
              colord = {True: 'red', False: 'green'}
              colors = [colord[histo_0 < 0] for histo_0 in self.lines.histo]
      
              self.plotlines = dict(histo=dict(_method='bar', alpha=0.50, width=1.0, color=colors))
              super(MACDHisto2, self).__init__()
      
      

      No error reports, but the histogram bar is missing! Checking the varialbles, find the plotlines passed to the bar plot is still [].

      posted in General Code/Help
      weibudda
      weibudda