For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Re: PyFolio analyzer multiple data sources not working



  • Re: PyFolio analyzer multiple data sources not working.

    I see the above topic was posted back in October 2017 but I'm wondering if this was resolved somewhere else. I'm also finding the exact same thing when using multiple data sources with the pyfolio analyzer. The source code line mentioned in the original post refers to

    ps = [[k] + v[-2:] for k, v in iteritems(pss)]
    

    where v contains the positions for each of the data feeds. [-2:] means that its only using the last two entries (the last symbol and the cash positions). If the line instead is changed to

    ps = [[k] + v for k, v in iteritems(pss)]
    

    Then positions for all datafeeds are saved and pyfolio gives the correct position and full tear sheets. Otherwise pyfolio thinks there was only one symbol in the portfolio.

    A workaround of course is to add your own PositionValues analyzer

    # existing pyfolio analyzer
    cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio',
                            timeframe=bt.TimeFrame.Days)
    pyfoliozer = strat.analyzers.getbyname('pyfolio',)
    returns, positions, transactions, gross_lev = pyfoliozer.get_pf_items() #<--positions only holds data for one symbol here
    
    # Add an extra PositionsValue analyzer to capture positions for all symbols
    from backtrader.utils.py3 import iteritems
    cerebro.addanalyzer(bt.analyzers.PositionsValue, headers=True, cash=True, _name='mypositions')
    p = strat.analyzers.getbyname('mypositions').get_analysis()
    mypositions = [[k] + v for k, v in iteritems(p)] #<-- Now positions will hold data for all symbols
    cols = mypositions.pop(0)  # headers are in the first entry
    mypositions = pd.DataFrame.from_records(mypositions, index=cols[0], columns=cols)
    
    pf.create_full_tear_sheet(
        returns, # from pyfolio analyzer
        positions=mypositions, #<-- from additional PositionsValue analyzer 
        transactions=transactions, # from pyfolio analyzer
        gross_lev=gross_lev, # from pyfolio analyzer
        round_trips=True)