Pivot Point and Cross Plotting - plotting doesn't work



  • Hi,
    I tried the example 'ppsample.py' described here:
    https://www.backtrader.com/blog/posts/2016-04-28-pivot-point-cross-plotting/pivotpoint-crossplotting.html
    but when I run:

    ./ppsample --plot --plot-on-daily
    

    I am getting this error:

    ...
    ...
    ...
    0507,0507,0023,2006-12-20,4019.19
    0508,0508,0023,2006-12-21,4019.19
    0509,0509,0023,2006-12-22,4019.19
    0510,0510,0023,2006-12-27,4019.19
    0511,0511,0023,2006-12-28,4019.19
    0512,0512,0023,2006-12-29,4019.19
    0513,0512,0024,2006-12-29,4060.59
    Traceback (most recent call last):
      File "./ppsample.py", line 95, in <module>
        runstrat()
      File "./ppsample.py", line 70, in runstrat
        cerebro.plot(style='bar')
      File "D:\Anaconda3\envs\python3.4.5\lib\site-packages\backtrader\cerebro.py",
    line 659, in plot
        useplotly=useplotly)
      File "D:\Anaconda3\envs\python3.4.5\lib\site-packages\backtrader\plot\plot.py"
    , line 196, in plot
        self.plotdata(data, self.dplotsover[data])
      File "D:\Anaconda3\envs\python3.4.5\lib\site-packages\backtrader\plot\plot.py"
    , line 659, in plotdata
        self.plotind(data, ind, subinds=self.dplotsover[ind], masterax=ax)
      File "D:\Anaconda3\envs\python3.4.5\lib\site-packages\backtrader\plot\plot.py"
    , line 410, in plotind
        plottedline = pltmethod(self.pinf.xdata, lplot, **plotkwargs)
      File "D:\Anaconda3\envs\python3.4.5\lib\site-packages\matplotlib\__init__.py",
     line 1818, in inner
        return func(ax, *args, **kwargs)
      File "D:\Anaconda3\envs\python3.4.5\lib\site-packages\matplotlib\axes\_axes.py
    ", line 1382, in plot
        for line in self._get_lines(*args, **kwargs):
      File "D:\Anaconda3\envs\python3.4.5\lib\site-packages\matplotlib\axes\_base.py
    ", line 381, in _grab_next_args
        for seg in self._plot_args(remaining, kwargs):
      File "D:\Anaconda3\envs\python3.4.5\lib\site-packages\matplotlib\axes\_base.py
    ", line 359, in _plot_args
        x, y = self._xy_from_xy(x, y)
      File "D:\Anaconda3\envs\python3.4.5\lib\site-packages\matplotlib\axes\_base.py
    ", line 219, in _xy_from_xy
        raise ValueError("x and y must have same first dimension")
    ValueError: x and y must have same first dimension
    

    I am using Python 3.4.5, matplotlib 1.5.3, backtrader 1.9.17.105.

    Please help. I would like to plot pivots on base chart (Daily in this case). Thanks


  • administrators

    The PivotPoint family of indicators fail unfortunately to plot under the new synchronization mechanism released with 1.9.x, because under the old scheme they used the surrounding Strategy instance to auto-synchronize the LinesCoupler object.

    Extra logic has been added and pushed into the development branch to find the right synchronization source. The blog post will have to be updated, because the indicators can now auto-couple themselves.

    You may check out the development branch and see the updated ppsample.py (easier)



  • This seems to be a bug or I don't understand something :(
    I created an indicator similar to PivotPoint which uses the values from previous bar for the calculation.
    My original data are daily data but I also resample to weekly and monthly.
    When I plot my indicators on daily chart everything is fine for the indicator that works on daily data.
    For the indicators that use resampled data (weekly&monthly), values seem not to be ok. For example, for weekly indicator, its value is changed each Tuesday, not Monday. Similar for monthly indicator, it changes its value not on the first trading day in the month but on the day after.
    I am using last version of Backtrader.


  • administrators

    The easiest way to see if you are doing something wrong or if the platform doesn't deliver would be to make a simple use case.

    Your indicator is your intellectual property, but you may craft one that follows the same delivery principles, but returns nonsensical values. Bottom line: grasp what you'd like to see in comparison with what you actually see.



  • Ok, I put here what I got and what I think I should get. This example uses simple indicator which calculates high and low of the previous bar. Each bar on chart represents one trading day and the indicator is calculated for weekly data and plot on daily chart.
    Weekly indicator should have the same value for the week November 7-11 but instead of that the same value is from November 8-14. I hope I managed to explain where is the problem.

    0_1485368085338_GSPC_Daily_BT.png

    0_1485368105181_GSPC_Daily_BT_expected.png


  • administrators

    Your description was clear, but charts don't help when having a look at what you may be experiencing. Hence the suggestion to simplify your code down to something that replicates what you do, but without sharing the details of your indicator.



  • It can't be simpler :) Just calculate Low of the previous bar in an indicator for weekly or monthly data and show the indicator on daily data. That it what I showed for SP500, Low and High (blue and red line).



  • The code is not perfect but you can reproduce the issue with it:

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    
    from datetime import datetime
    import os.path 
    import sys 
    
    import backtrader as bt
    
    class TestIndicator(bt.Indicator):
     
        lines = ('h', 'l')
        plotinfo = dict(subplot=False)
        
        params = (
            ('is_bars_aggregated', True),
            ('_autoplot', False),  # attempt to plot on real target data
        )
        
        
        def _plotinit(self):
            # Try to plot to the actual timeframe master
            if self.p._autoplot:
                if hasattr(self.data, 'data'):
                    self.plotinfo.plotmaster = self.data.data
    
        def __init__(self):
            
                  
            if self.p.is_bars_aggregated:
                high = self.data.high
                low = self.data.low
            else:
                high = self.data.high(-1)
                low = self.data.low(-1)            
            
            self.lines.h=high                
            self.lines.l=low
                    
            if self.p._autoplot:
                self.plotinfo.plot = False  # disable own plotting
                self()  # Coupler to follow real object
    
    
            
    class TestStrategy(bt.Strategy):
        
            
        def __init__(self):
            
            self.TIDaily = TestIndicator(self.data0, is_bars_aggregated=False, plot=False)
            self.TIWeekly = TestIndicator(self.data1, is_bars_aggregated=True, _autoplot=True, plot=False)
            self.TIMonthly = TestIndicator(self.data2, is_bars_aggregated=True, _autoplot=False, plot=False)
            
             
    
        def notify_order(self, order):
            pass
            
    
        def notify_trade(self, trade):
            pass
    
        def next(self):
            pass
            
      
    
    if __name__ == '__main__':      
            
         
        # Create a cerebro entity
        cerebro = bt.Cerebro()
    
        # Add a strategy
        cerebro.addstrategy(TestStrategy)   
    
        data = bt.feeds.YahooFinanceData(dataname='^GSPC', fromdate=datetime(2016, 11, 1), todate=datetime(2016, 11, 30))
        
        data2=data.clone()
        data2.plotinfo.plot=False
        data3=data.clone()
        data3.plotinfo.plot=False
        
        cerebro.adddata(data)
        cerebro.resampledata(data2, timeframe=bt.TimeFrame.Weeks)    
        cerebro.resampledata(data3, timeframe=bt.TimeFrame.Months)
      
        cerebro.broker.setcash(10000.0)
    
        # Add a FixedSize sizer according to the stake
        cerebro.addsizer(bt.sizers.FixedSize, stake=1)
        # Set the commission        
        cerebro.broker.setcommission(commission=0.000)
        #cerebro.broker.setcommission(commission=7.0, margin=1000.0, mult=10.0)
    
        # Print out the starting conditions
        print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
        # Run over everything
        cerebro.run()
    
        # Print out the final result
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
        # Plot the result
        cerebro.plot(style='candle')
    


  • Actually, weekly indicator value is correct but the presentation on the graph is wrong.


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.