how is this different from setting the style exposure to close to 0 using the Risk API
Interesting point by Joakim above. I have to say, the whole apparatus of the risk model, its implementation in
risk_model_exposure = opt.experimental.RiskModelExposure(
has been a matter of faith for me, mostly. By some magic, it does seem to work, but I don't understand it well enough, given its importance in shifting money from Q to my wallet.
It seems that the Optimize API should be sufficient, no? I'm wondering if one could achieve the same end result by calling the Optimize API with
calculate_optimal_portfolio, and returning the resulting portfolio weight vector? In other words, can the Optimize API be re-purposed to better align individual alpha factors with the desired risk profile, prior to their combination? Alternatively, one could write a custom implementation using CVXPY.
For example, on a given alpha factor, if we run the Optimize API on it, and constrain only
short_term_reversal we should be left with a residual that contains everything except the 14-day RSI (to within a specified tolerance), right?
Another observation is that all of this relies on the past being predictive of the future. For example, I've found that depending on the stock universe, the effectiveness of
SimpleBeta and the Optimize API vary. Using a trailing 260-day computation of beta isn't sufficient; for example, I need to bias the beta exposure, to achieve beta ~ 0:
MIN_BETA_EXPOSURE = -0.2
MAX_BETA_EXPOSURE = -0.2
My hypothesis is that the trailing beta doesn't persist into the future. I suspect that a similar problem is at play in the application of the risk model; it only works ideally under the assumption that the future equals the past.
One thing to try is to include the z-scored style risk factors in the alpha combination, but instead of adding them with the alpha factors, subtract them. I tried this once with the RSI style risk factor, and it seemed to work well.