A few weeks ago, I posted a notebook presenting a new Optimize API. Today we're announcing that the Optimize API is available for use in algorithms, and we've added new features to make the API easier to use in the context of a running algorithm.
The basic idea of the Optimize API is that it relieves authors from the burden of having to manually size orders and positions. Instead of calculating individual share counts and placing orders directly, authors can now specify the desired state of their portfolio in terms of high-level objectives and constraints.
Since the original announcement, we've made a few tweaks to the built-in Objective and Constraint classes, but the biggest change to the API is the addition of a new top-level entrypoint, order_optimal_portfolio
, which is available only in algorithms. order_optimal_portfolio accepts three parameters, all of which are required:
objective
, an Objective that the new portfolio should maximize or minimize.constraints
, a list of Constraints that the new portfolio should adhere to.universe
, an iterable of Equity objects to consider in the optimization. In idiomatic usage, this will usually be the index of a Pipeline result.
When called, order_optimal_portfolio calculates the set of portfolio weights that optimizes objective
while still respecting constraints
. It then subtracts the target portfolio weights from the current portfolio weights and places orders to move from the current portfolio state to the new optimal state.
Examples
Backtest
The backtest attached to this post provides a complete example of how the Optimize API can be used in a realistic trading algorithm. The outline of the algorithm is as follows:
- Once a month, choose a universe of 500 liquid assets.
- Every day, build an alpha vector for our 500 assets. The alpha model we use is very simple: we rank assets by z-score of free cash flow yield and earning yield, both of which are fundamental value measures.
- Once a week, calculate the portfolio that maximizes the alpha-weighted sum of our position sizes, subject to the following constraints:
- Our portfolio must have a maintain a gross leverage ratio of 1.0 or less.
- Our portfolio can have no more than 1.5% in any single name.
- Our portfolio must be equally exposed to long and short positions.
- Within each market sector, our portfolio must be equally-exposed to long and short positions.
- Our portfolio must have a maintain a gross leverage ratio of 1.0 or less.
Notebook
In the first comment below this post I've included an updated version of my original optimization notebook. It provides a more theoretical introduction to the idea of portfolio optimization, and it includes a reference for the built-in objectives and constraints.
Next Steps
Now is a great time to try out the Optimize API and provide design feedback or ideas for improvements. The API is still marked as experimental, which means breaking changes are possible, but based on feedback from the previous announcement, I think it's unlikely that there will be major backwards-incompatible changes. Examples of ideas for improvements might include new objectives/constraints, a first-class notion of "penalties", or options for avoiding orders if the new portfolio isn't a significant improvement over the old one.
If you want to get a feel for the new API but don't know where to start, I'd recommend cloning the attached algorithm and tweaking some of the parameters. Many of the constants listed above can be easily changed by editing a line or two. How does increasing the leverage cap affect performance? How about the position size constraint? For a bit more of a challenge, try adding a new constraint. The algorithm currently places a few orders that don't fill by the end of the day. Would the algo improve if we constrained our position sizes to a fixed percentage of trailing volume?
If you're looking to dig deeper into the details of the Optimize API, I'd recommend opening up the notebook reading through the examples. If you have a specific idea you want to try, you can build your constraints and objectives interactively in research and copy them over to an algorithm when you're happy with them.