Navigation

    Backtrader Community

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

    Yang Fu

    @Yang Fu

    2
    Reputation
    13
    Profile views
    7
    Posts
    0
    Followers
    2
    Following
    Joined Last Online

    Yang Fu Unfollow Follow

    Best posts made by Yang Fu

    • RE: Question on making an observer to track individual instrument values

      ok, just figured it out. I can reuse the DataTrades observer. No change needed for the MetaDataTrades class. It will generate multiple lines for the assets. The author sure constructed backtrader to be versatile!

      Here is my code to show pnl in individual asset. Just accumulate daily settled pnl for each asset. Haven't checked the exact numbers yet. Eyeballing it looks alright comparing to the total account pnl.

      class Aseet_monitor(bt.utils.py3.with_metaclass(MetaDataTrades, bt.observer.Observer)):
          _stclock = True
      
          params = (('usenames', True),)
      
          plotinfo = dict(plot=True, subplot=True, plothlines=[0.0],
                          plotymargin=0.10, plotlinelabels=True)
      
          plotlines = dict()
      
          def next(self):
              strat = self._owner
              for inst in strat.datas:
                  pos = strat.broker.positions[inst]
                  cur_line = getattr(self.lines, inst._name)
                  comminfo = strat.broker.getcommissioninfo(inst)
                  if len(self) == 1:
                      cur_line[0] = 0
                  else:
                      if pos.size != 0:
                          cur_pnl = comminfo.profitandloss(pos.size, inst.close[-1],
                                                              inst.close[0])                
                      else:
                          cur_pnl = 0
                  
                      cur_line[0] = cur_line[-1] + cur_pnl
      

      Here is the output. The whole strategy is carried by HG_copper, while CL and ZN are underwater almost the whole time.

      27d7e3a1-67bf-4af6-8bad-4f74d5f11155-image.png

      Comparing to the Value observer.
      83d6a6fd-66c5-489a-b0ab-a1ffd3320da7-image.png

      posted in General Code/Help
      Yang Fu
      Yang Fu

    Latest posts made by Yang Fu

    • RE: Bokeh Integration - Interactive Webbrowser Plotting

      @vbs Sorry for not replying sooner. Got swamped with work.
      Yes, I can see the toolbar on the demo page of github. And it is also correct when I run the demo "blackly_single". I have generated the htmls, but how can I send them to you? I don't see a message/mail function on the forum.

      posted in General Discussion
      Yang Fu
      Yang Fu
    • RE: Bokeh Integration - Interactive Webbrowser Plotting

      @vbs Finally made it work. It appears that I can only get the toolbar to show up with "left/above/below" locations, not "right" location. Don't know why but it works, oh well... Thanks again for the package. It is really nice to have an interactive plotting tool. The zoom and pan feels great!

      Tried different versions of bokeh and its dependencies, python version, also a new PC with Ubuntu/win10, different browser, anaconda or not. They all have the same behavior.

          b = Bokeh(style='bar', tabs='multi', scheme=Tradimo(), filename='test_bt_plot.html',
          toolbar_location='left')
      
      posted in General Discussion
      Yang Fu
      Yang Fu
    • RE: Bokeh Integration - Interactive Webbrowser Plotting

      @vbs Thank you for the quick reply! I did look on the right side of the plot, but no toolbar there. Also it doesn't plot in tabs even if I use the "multi" option. feel like something weird is going on with my setup. I am using windows10 + bokeh 2.0.2 + backtrader_plotting 1.1.0.

      I do see in backtrader_plotting requirements says bokeh ~= 2.0.0. Wondering if anything in 2.0.2 breaks it?

      Requirement already satisfied: bokeh~=2.0.0 in c:\users\yang fu\appdata\roaming\python\python37\site-packages (from backtrader_plotting) (2.0.2)
      
      b = Bokeh(style='bar', plot_mode='multi', scheme=Tradimo())
      cerebro.plot(b)
      
      posted in General Discussion
      Yang Fu
      Yang Fu
    • RE: Bokeh Integration - Interactive Webbrowser Plotting

      Hi @vbs, Excellent work! Really grateful for this nice tool. I do have a question about zoom, how can I do that? I see in the earlier replies you said there will be a toolbar on the left, but I don't see one in my plots.

      I see from Bokeh's help that you can do this, but don't know where to add it to Bokeh in your model.

      from bokeh.models import BoxSelectTool
      
      plot = figure(tools="pan,wheel_zoom,box_zoom,reset")
      plot.add_tools(BoxSelectTool(dimensions="width"))
      

      This is what I see in Chrome. I can pan the plot and see tooltips OK. But no toolbar appearing on the plot.
      df6e071f-64fc-4552-9abd-087e1141c508-image.png

      posted in General Discussion
      Yang Fu
      Yang Fu
    • RE: Question on making an observer to track individual instrument values

      ok, just figured it out. I can reuse the DataTrades observer. No change needed for the MetaDataTrades class. It will generate multiple lines for the assets. The author sure constructed backtrader to be versatile!

      Here is my code to show pnl in individual asset. Just accumulate daily settled pnl for each asset. Haven't checked the exact numbers yet. Eyeballing it looks alright comparing to the total account pnl.

      class Aseet_monitor(bt.utils.py3.with_metaclass(MetaDataTrades, bt.observer.Observer)):
          _stclock = True
      
          params = (('usenames', True),)
      
          plotinfo = dict(plot=True, subplot=True, plothlines=[0.0],
                          plotymargin=0.10, plotlinelabels=True)
      
          plotlines = dict()
      
          def next(self):
              strat = self._owner
              for inst in strat.datas:
                  pos = strat.broker.positions[inst]
                  cur_line = getattr(self.lines, inst._name)
                  comminfo = strat.broker.getcommissioninfo(inst)
                  if len(self) == 1:
                      cur_line[0] = 0
                  else:
                      if pos.size != 0:
                          cur_pnl = comminfo.profitandloss(pos.size, inst.close[-1],
                                                              inst.close[0])                
                      else:
                          cur_pnl = 0
                  
                      cur_line[0] = cur_line[-1] + cur_pnl
      

      Here is the output. The whole strategy is carried by HG_copper, while CL and ZN are underwater almost the whole time.

      27d7e3a1-67bf-4af6-8bad-4f74d5f11155-image.png

      Comparing to the Value observer.
      83d6a6fd-66c5-489a-b0ab-a1ffd3320da7-image.png

      posted in General Code/Help
      Yang Fu
      Yang Fu
    • RE: Question on making an observer to track individual instrument values

      Thank you for the pointer. The PositionsValue analyzer does what I want. May I ask a further question? I know I can plot the result of this analyzer, but is it possible to make it an observer just like the Datatrades observer? This way it can be plotted directly using cerebro.plot() or Bokeh.

      My main issue is how to define class variable "lines" dynamically, since its numbers/names depends on how many instruments in the datas. I see in the datatrades observer, it is produced by the metaclass MetaDataTrades, and the lines are created there dynamically. I want to follow the same pattern. I am trying to single-step into DataTrades and see what's being created at runtime. But somehow even if I set all the breakpoints in DataTrades (using VScode), and added the observer into cerebro, they never get triggered. The observer is generating correct plots, so it is working for sure. The debug mode works fine in other parts of code, like single-step in strategy/indicators. I guess I must be missing something here regarding how the datatrades class is being generated.

      class MetaDataTrades(Observer.__class__):
          def donew(cls, *args, **kwargs):
              _obj, args, kwargs = super(MetaDataTrades, cls).donew(*args, **kwargs)
      
              # Recreate the lines dynamically
              if _obj.params.usenames:
                  lnames = tuple(x._name for x in _obj.datas)
              else:
                  lnames = tuple('data{}'.format(x) for x in range(len(_obj.datas)))
      
              # Generate a new lines class
              linescls = cls.lines._derive(uuid.uuid4().hex, lnames, 0, ())
      
              # Instantiate lines
              _obj.lines = linescls()
      ......
      class DataTrades(with_metaclass(MetaDataTrades, Observer)):
      
      posted in General Code/Help
      Yang Fu
      Yang Fu
    • Question on making an observer to track individual instrument values

      Hello, I am learning backtrader and really like it. I want to make an observer to track the values of individual instrument in the portfolio, say 5 different futures. I am thinking to have one line for each instrument, but how should I define the lines beforehand since the number of instruments could be different?

      I look at the examples especially the trades observer, but it seems like they all have a fixed number of lines defined. The trades observer has pnlplus/pnlminus lines defined, and use different markers to track individual instrument.

      Am I missing something obvious here? Can I initialize the lines tuple with number of instruments as parameter? Sorry for the simple question, I am still new to python. Thank you.

      posted in General Code/Help
      Yang Fu
      Yang Fu