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
MaximizeAlpha
objective, 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
InfeasibleConstraints
errors are now much more detailed. You'll see details about the constraints violated by the current portfolio, the empty portfolio - and when using theTargetWeights
objective, the target portfolio as well. - A new method called
run_optimization
has been added.run_optimization
is similar tocalculate_optimal_portfolio
, but returns an OptimizationResult - an object containing diagnostic information about the attempted portfolio optimization.run_optimization
is 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
.math
attribute. For example:
Parameter Changes
The
universe
parameter toorder_optimal_portfolio
is deprecated. Calls toorder_optimal_portfolio
will ignore theuniverse
parameter, if it's passed in. In the original release of the API,order_optimal_portfolio
required 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_portfolio
now 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_portfolio
parameter tocalculate_optimal_portfolio
is now optional. If it is not provided,calculate_optimal_portfolio
will 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
, andCannotHold
will now either take an Asset or an iterable (for example, a list) of Assets.The
Basket
constraint (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.optimize
module has been renamed toquantopian.optimize
. Algorithms that used to doimport quantopian.experimental.optimize as opt
should now doimport quantopian.optimize as opt
. - The
TargetPortfolioWeights
objective has been renamed toTargetWeights
. - The
NetLeverage
constraint has been renamed toNetExposure
. - Likewise,
MaxGrossLeverage
has been renamed toMaxGrossExposure
. - The
NetPartitionExposure
constraint (often used to constrain sector and industry exposure) has been renamed toNetGroupExposure
. - The
WeightedExposure
constraint has been renamed toFactorExposure
. - The
NeutralBasket
constraint has been reworked substantially, as detailed in the 'Parameter Changes' section. It has also been renamed toBasket
.