Today, we're announcing the stable release of the Optimize API. A number of classes and API methods have changed since its first experimental release, and this post details the changes.
Optimize is the recommended method for placing orders on Quantopian. It uses advanced optimization techniques to move your portfolio from its current state to your desired state, managing constraints and objectives that you can pass in. There are several reasons why it's better to use Optimize than order_target_percent or other manual ordering methods:
- Optimize allows you to easily specify constraints when ordering, to manage your algorithm's leverage, position concentration, and exposures to risk factors.
- Optimize accounts for open market orders when determining target positions, unlike the order_target family of methods which only account for filled orders.
- Because Optimize is a declarative API, there's less manual order management to take care of, and the focus can instead be on alpha discovery and portfolio construction. You simply specify what you'd like your desired portfolio to be, either in the form of portfolio weights or alpha vectors, and Optimize handles placing the orders.
- With the
MaximizeAlphaobjective, you now have the option of specifying alpha vectors as your ordering objectives, unlike the previous ordering methods which all needed a quantity of a specifically named stock.
Algorithms need to use the Optimize API in order to receive an allocation. We require this because having an objective and constraints allows us to more effectively respect an algorithm's desires if we're unable to hold the algorithm's exact optimal portfolio (e.g., because an asset is halted intraday or restricted by our prime broker). This post contains a lot more detail.
If you're new to Optimize and want to get started, the best place is the help docs.
If you'd like to see fully worked examples, go here to see Optimize in a notebook, or clone the attached backtest to see Optimize in an algorithm.
If you've already been using Optimize during the experimental release, here's what's new:
New Features
- The error messages resulting from
InfeasibleConstraintserrors are now much more detailed. You'll see details about the constraints violated by the current portfolio, the empty portfolio - and when using theTargetWeightsobjective, the target portfolio as well. - A new method called
run_optimizationhas been added.run_optimizationis similar tocalculate_optimal_portfolio, but returns an OptimizationResult - an object containing diagnostic information about the attempted portfolio optimization.run_optimizationis primarily useful as a debugging tool. - Docs! Full documentation is now available for Optimize.
- Objectives can now be rendered as LaTeX in research notebooks via their
.mathattribute. For example:
Parameter Changes
The
universeparameter toorder_optimal_portfoliois deprecated. Calls toorder_optimal_portfoliowill ignore theuniverseparameter, if it's passed in. In the original release of the API,order_optimal_portfoliorequired the user to pass provide a list of assets to act as the "optimization universe". The universe was used by the optimizer to define the assets that could be considered as potential candidates for orders and/or positions. After working with the Optimize API, however, we found that in practice the only reasonable choice for universe was the union of three sets of assets:- Assets referenced by the algorithm's objective.
- Assets held in the algorithm's portfolio.
- Assets with unfilled open orders.
We also found that Optimize API users often passed a much larger list of assets than was desirable. A particularly common mistakes was to pass the entire index of a pipeline result, which might contain thousands of assets, even though the user only had intentions of trading a small percentage of those assets. Passing very large universes slowed down optimizations and caused problems where the optimizer would sometimes take a large number of tiny (e.g. 1-share) hedging positions to avoid violating users' constraints.
order_optimal_portfolionow always uses the union of the three sets of assets listed above as the optimization universe.- Assets referenced by the algorithm's objective.
The
current_portfolioparameter tocalculate_optimal_portfoliois now optional. If it is not provided,calculate_optimal_portfoliowill default to the current portfolio in an algorithm, and the empty portfolio in a notebook.Several constraints that previously took only a single asset, now accept multiple.
Frozen,ReduceOnly,LongOnly,ShortOnly, andCannotHoldwill now either take an Asset or an iterable (for example, a list) of Assets.The
Basketconstraint (formerlyNeutralBasket) now takes in a single list of assets instead of two lists for longs and shorts respectively.
Name Changes
A number of modules and classes have been renamed. While the old names will continue to work, using them will bring up a deprecation warning.
- The
quantopian.experimental.optimizemodule has been renamed toquantopian.optimize. Algorithms that used to doimport quantopian.experimental.optimize as optshould now doimport quantopian.optimize as opt. - The
TargetPortfolioWeightsobjective has been renamed toTargetWeights. - The
NetLeverageconstraint has been renamed toNetExposure. - Likewise,
MaxGrossLeveragehas been renamed toMaxGrossExposure. - The
NetPartitionExposureconstraint (often used to constrain sector and industry exposure) has been renamed toNetGroupExposure. - The
WeightedExposureconstraint has been renamed toFactorExposure. - The
NeutralBasketconstraint has been reworked substantially, as detailed in the 'Parameter Changes' section. It has also been renamed toBasket.