There currently aren't any known 'bugs' in the TargetWeights
objective. A fix was made in May 2019 which addressed the issue Jamie McCorriston alluded to in the post above. See this post for the update. The TargetWeights
objective now closes out all zero weight, or non-weighted, positions.
One can use either TargetWeights
or MaximizeAlpha
as objectives. Both work fine. The choice depends upon what your algorithm is trying to accomplish. The TargetWeights
objective tries to find an array of portfolio weights that minimizes the distance from the target weights (as measured by Euclidean Distance). The MaximizeAlpha
objective tries to find an array of portfolio weights that maximizes the sum of each asset's weight times the target alpha value. Under the hood, the optimize methods rely upon cvxpy. The Quantopian methods are simply wrappers to make it a bit easier to use. There is a bit of background in this post and of course the documentation.
With all that said, optimization can sometimes lead to some non-intuitive results. Consider the following case
# Create target weights of 50% for two securities
weights = pd.Series(data=.5, index=symbols(['AAPL', 'IBM']))
target_portfolio = opt.TargetPortfolioWeights(weights)
# Constrain portfolio to be 'Dollar Neutral' (ie equal long and short)
dollar_neutral = opt.DollarNeutral()
optimized_portfolio = opt.order_optimal_portfolio(
objective=target_portfolio,
constraints=[dollar_neutral])
The above code will end up not ordering anything. We wanted a portfolio with AAPL and IBM but ended up with no orders. How can that be? Very simple. Optimize essentially starts with the target weights of .5 and moves them a little bit until the DollarNeutral constraint is met. The first solution it finds is a weight of 0 for each security. This isn't what we expected but it's technically true. The sum of the longs and shorts is 0. Constraints often lead to unexpected results.
The complete advice that Thomas Wiecki gave in the post referenced above is
Code-wise, you should not use MaximizeAlpha and instead TargetWeights.
This is a good place to start:
order_optimal_portfolio(opt.TargetWeights(weights), constraints=[])
The emphasis is meant to be on not using constraints as a starting point (note constraints=[]). It wasn't meant to say don't use MaximizeAlpha
. The advice is to start by programmatically defining target weights in one's algo and then using the order_optimal_portfolio
to simply execute the orders. By using the TargetWeights
objective without any constraints, the weighting logic is moved out of the optimize method and into one's logic. It's generally better to explicitly define one's weighting rules than relying on optimize to implicitly, and sometimes unexpectedly, implement them.
Hope that clears up any confusion. The requirement to use order_optimal_portfolio
shouldn't be a reason not to join the contest or the platform.
Good luck!