robertmartin8 / PyPortfolioOpt

Financial portfolio optimisation in python, including classical efficient frontier, Black-Litterman, Hierarchical Risk Parity
https://pyportfolioopt.readthedocs.io/
MIT License
4.3k stars 930 forks source link

Version update - zipline integration. #12

Closed andrewcz closed 5 years ago

andrewcz commented 5 years ago

@robertmartin8 hey! Was wondering if zipline was being added to the library. Looks very promising :)!! I wanted to try it out with some backtests. Best, Andrew

robertmartin8 commented 5 years ago

Hi Andrew,

This is definitely something that I had always been meaning to build (though possibly with backtrader rather than Zipline). In fact, when I was working on portfolio optimisation professionally, I did actually have a go at doing a zipline/backtrader backtest, but in the end our team came to the conclusion that event-driven backtesting frameworks are not really suitable for backtesting portfolio optimisation methods, or at least they are certainly not worth the development effort. Here are a couple of interesting discussions on the topic (quantstart, quantopian): I am inclined to believe that a simple for-loop backtest is superior in our case.

Unfortunately, university commitments mean that I will not be able to tackle this. However, I may considering uploading my for-loop backtesting script instead, but I will need to make heavy modifications before it is ready for distribution.

Best, Robert

andrewcz commented 5 years ago

Champion! Interesting thoughts. Would you be able to include fees and slippage? I was looking at a couple of basic for loop backtests but I would question the reality of the modeling? Best, Andrew

robertmartin8 commented 5 years ago

Event-driven backtests are suited to more active strategies, which need to rebalance and adjust position sizes almost every trading day. For a long term buy-and-hold approach, for-loop backtests are arguably equally-valid models of reality.

With regard to fees and slippage, it is indeed possible to model them, but it is rather difficult to optimise for them as you have to find a suitable cost function (one that can be solved by the convex optimiser). If my memory serves, I did implement such a cost function before realising that it was not producing interesting results: it basically acted as a control knob to compromise the active portfolio with the benchmark – i.e if you aggressively optimise for transaction costs, you end up with a portfolio that resembles the benchmark very closely.

I would suggest that you begin with a for-loop and only move to an event-driven backtest if there are concrete areas in which you think the for-loop is inadequate. This is most likely to be the case if you are looking for a daily rebalancing strategy.