Hello all,
I was interested in reading about any strategies you have in scaling the size of new positions based on the remaining buying power. This can be useful when your alpha opens an unknown number of positions e.g. invest 0.05 in all securities that meet some filtering criteria - if more than 20 securities meet this criteria, buying power is exceeded.
Ideally, the strategies 1) work with any amount of leverage 2) guarantee that buying power won't be exceeded 3) work with any number of new positions.
I have 2 strategies right now, but they each have their issues.
1)
class WeightedConstructionModel(PortfolioConstructionModel):
def CreateTargets(self, algorithm, insights):
targets = []
buying_power = algorithm.Portfolio.MarginRemaining/algorithm.Portfolio.TotalPortfolioValue
for insight in insights:
coeff = 1.00
if buying_power < 0.10:
coeff = np.power(abs(buying_power), 0.90)
algorithm.Debug("{} Scaling positions by factor {}".format(algorithm.Time, coeff))
targets.append(PortfolioTarget.Percent(algorithm, insight.Symbol, coeff * insight.Weight))
buying_power = buying_power - (coeff * insight.Weight)
return targets
Essentially, this strategy does no scaling until buying power is less than 0.10. Then it scales pretty aggressively. Typically, the updated weights are 1/10 of the original weight i.e. and input weight of 0.05 is scaled to 0.005. It also doesn't mathematically guarantee that buying power isn't exceeded. There are other issues too, such as how the buying power is decreased during the loop, which assigns arbitrary weights to insights.
This leads me to my updated strategy for scaling:
2)
class WeightedConstructionModel(PortfolioConstructionModel):
def CreateTargets(self, algorithm, insights):
remaining_bp = (algorithm.Portfolio.MarginRemaining/algorithm.Portfolio.TotalPortfolioValue) - BUFFER_BUYING_POWER
opening_bp = sum(abs(insight.Weight) for insight in insights)
to_open = list(filter(lambda x: x.Weight != 0, insights))
coeff = 1.0
if remaining_bp <= 0:
coeff = 0.0
algorithm.Debug("{} Skipping {} new positions".format(algorithm.Time, len(to_open)))
elif opening_bp != 0 and remaining_bp - opening_bp < 0:
coeff = min(1.0, remaining_bp/opening_bp)
algorithm.Debug("{} Scaling {} new positions by {}".format(algorithm.Time, len(to_open), coeff))
targets = []
for insight in insights:
targets.append(PortfolioTarget.Percent(algorithm, insight.Symbol, coeff * insight.Weight))
return targets
This strategy calculates the remaining buying power and the buying power that will be used, then scales by the excess buying power. For example, if 0.3 is remaining, and new positions will use 0.5, those positions will be scaled by a factor of 0.6 (0.3/0.5). There is some buffer used. This solves some problems with the previous strategy, but I'm interested in reading about anything new or better.
Louis Szeto
Hi AK M
To always allow sufficient buying power, you may take the CustomBuyingPowerModel class from this demo algorithm.
The InsightWeightingPortfolioConstructionModel is already doing scaling when the overall input weight sums up to be > 1. You may take a look at its source code as a reference. Manipulating the below 3 lines, together with the above Buying Power Model, would allow you to use any leverage:
Best
Louis
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
AK M
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!