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

Leverage analysis with Pyfolio



  • Hello, Backtraders!

    A few days ago I'm started to play with leverage in backtrader in order to use it in Interactive Brokers (IB). In particular to trade stocks.

    In my understanding, leverage in IB, it is a little different from other platforms (based on some blogs reading). What I mean by this, in simple words, is that you can consider that you are using leverage if you buy more than the cash you have (I know that some conditions need to be met, like initial margin, maintenance margin among others). When you do that, you cash will be negative, because you have "debt".
    In other platforms, and it seems the case of backtrader, when you buy with leverage, you will never have negative cash.

    Until now, that behavior of backtrader was not a problem, the returns of the strategy seem to be ok. It was until I processed the results with Pyfolio that I realized that it leads to confusion in the Pyfolio analysis.

    Here is a screenshot of the first position a strategy took with leverage of 4x:

    Screenshot from 2020-06-05 13-44-31.png

    In some operations with pyfolio, it considers the sum of each row as the portfolio value. And that it is incorrect here.

    Although it could be a desition design, another output from backtrader is also incorrect. The gross leverage is erroneous:

    Screenshot from 2020-06-05 13-51-58.png

    It never reports a value greater than 1.

    It could be a bug or a decision design or that pyfolio has changed since the last commit about pyfolio analyzer of backtrader. But I ask this community to provide any help on how to fix it. Any insight is welcome :)

    --
    Regards,
    Javier



  • Numbers you posted for sure make sense for you, but you may want to elaborate more if you really want some help. Leverage is a word used in different context differently by different traders. What is ADSK? What is gross_lev? You made some calcs, but didn't reveal them.

    Just make simple thing: open one position, post prices and size, cash before and aft in bt and in ib, post what you expect.



  • Thanks for your response. I apologize for not provide enough info.

    ADSK is the Autodesk stock symbol and I'm testing trading with the other two stocks: FB (Facebook) and AAPL (Apple). gross_lev is one of the outputs of the PyFolio Analyzer and it is a series with the amount of leverage that your strategy use.

    Following your suggestion, this is the result:

    • In bt using 4x leverage:
      • With a long position:
        long.png
      • With a short position:
        short.png
        and this is the code in the next() :
    def next(self):
       self.log('val:${:.2f}, cash:${:.2f}'.format(self.broker.getvalue(), self.broker.getcash())
    
       if self.send_order_flag:
           # self.buy(data=self.datas[1], size=200)
           self.sell(data=self.datas[1], size=200)
           self.send_order_flag = False
    
    • In ib:
      • Before open any position (buying power of ~4x):
        IB_none.png
      • With a long position:
        IB_long.png
      • With a short position:
        IB_short.png

    In the short scenario, bt behave as I expected. But in the long case, I expected, that as I buy more than the cash I had, the cash should be negative as a representation of the debt. As it is the behavior in ib.

    The "calcs" I made before comes from reading the PyFolio analyzer results in a jupyter notebook. Here are the jupyters for:

    • Long position:
      long_jupyter.png
    • Short position:
      short_jupyter.png

    This is how I saved the PyFolio analyzer results in backtrader

    results = cerebro.run()
    strat = results[0]
    pyfoliozer = strat.analyzers.getbyname('pyfolio')
    returns, positions, transactions, gross_lev = pyfoliozer.get_pf_items()
    
    if not os.path.exists('out/'):
        os.makedirs('out/')
    
    filepath = 'out/BTesting_results.pkl'
    file = open(filepath, 'wb')
    pikle_dict = {
        'returns': returns,
        'positions': positions,
        'transactions': transactions,
        'gross_lev': gross_lev,
    }
    dump(pikle_dict, file)
    


  • @ab_trader Please, if any further info is needed, don't hesitate to ask. Thanks again.



  • Check out the following discussion. @backtrader explained how the leverage was incorporated.

    https://community.backtrader.com/topic/118/leverage-discussion



  • @ab_trader Ok. Thank you. Let me read it.



});