🚀 AI One-Click Generation of quantconnect Strategy Code

How to Allocate a Fixed Percentage of Your Portfolio with PortfolioTarget.Percent

quantconnect | Published on: 2025/12/3
The following content is generated by EasyQuant .

Problem Description

How do I create an order that targets 5% of my portfolio's value?

Solution

To create an order that targets a specific percentage of your portfolio (e.g., 5%), the most efficient method in QuantConnect is using the set_holdings method. This helper method automatically calculates the number of shares required based on the current price and your total portfolio value (Cash + Equity) and places a market order to adjust your position to the desired target.

Below are the two primary ways to achieve this: using set_holdings (recommended for market orders) and using calculate_order_quantity (recommended if you need Limit or Stop orders).

Method 1: Using set_holdings (Recommended)

This method automatically handles the math. If you already hold 2% and ask for 5%, it buys 3%. If you hold 10% and ask for 5%, it sells 5%.

class PortfolioTargetingAlgorithm(QCAlgorithm):
    def initialize(self):
        self.set_start_date(2023, 1, 1)
        self.set_end_date(2023, 6, 1)
        self.set_cash(100000)
        
        # Add an asset
        self.spy = self.add_equity("SPY", Resolution.MINUTE).symbol

    def on_data(self, data):
        # Check if we have data for the symbol to avoid errors
        if not data.contains_key(self.spy):
            return

        # Example: If we are not invested, buy 5% of Portfolio Value
        if not self.portfolio.invested:
            # 0.05 represents 5%
            # liquidate_existing_holdings=False means it won't sell other assets to fund this
            self.set_holdings(self.spy, 0.05)
            
            # To Short 5%, use negative value:
            # self.set_holdings(self.spy, -0.05)

Method 2: Manual Calculation (For Limit/Stop Orders)

If you need to place a Limit Order or Stop Market Order targeting 5% of the portfolio, set_holdings cannot be used because it forces a Market Order. Instead, use calculate_order_quantity to get the share count, then place the specific order type.

class ManualCalculationAlgorithm(QCAlgorithm):
    def initialize(self):
        self.set_start_date(2023, 1, 1)
        self.set_end_date(2023, 6, 1)
        self.set_cash(100000)
        
        self.spy = self.add_equity("SPY", Resolution.MINUTE).symbol

    def on_data(self, data):
        if not data.contains_key(self.spy):
            return

        if not self.portfolio.invested:
            # 1. Calculate the number of shares that represent 5% of the portfolio
            # This returns a signed integer (positive for long, negative for short)
            quantity = self.calculate_order_quantity(self.spy, 0.05)
            
            # 2. Place a Limit Order at 1% below current price
            limit_price = data[self.spy].price * 0.99
            
            self.limit_order(self.spy, quantity, limit_price)
            
            # Or place a standard market order manually
            # self.market_order(self.spy, quantity)

Key Considerations

  1. Buying Power: Both methods respect the margin model. If you request 5% but only have enough margin for 2%, the order may be rejected or reduced depending on the BuyingPowerModel settings.
  2. Total Portfolio Value: The calculation is based on self.portfolio.total_portfolio_value (Cash + Unrealized Profit/Loss + Equity), not just available cash.
  3. Fractional Shares: By default, these methods calculate integer share counts. If your brokerage model supports fractional shares, the quantity might be a float.

Q&A

Q: Does set_holdings liquidate other positions?
A: By default, set_holdings only adjusts the specific symbol you pass to it. However, if you set the optional parameter liquidate_existing_holdings=True, it will liquidate all other positions in your portfolio before buying the target asset.

Q: How do I target 5% leverage (using margin)?
A: The percentage parameter represents the target leverage. If you want to use 2x leverage (200% of portfolio value), you would pass 2.0. For 5% of portfolio value (no leverage, small position), you pass 0.05.

Q: Why did set_holdings result in slightly less than 5%?
A: This usually happens due to two factors:

  1. Rounding: The algorithm usually rounds down to the nearest whole share to ensure you don't exceed available cash.
  2. Fees: The system estimates transaction fees and subtracts them from the buying power to prevent a negative cash balance.