🚀 AI One-Click Generation of quantconnect Strategy Code

Building a Custom Portfolio Sizing Model in Python (Fixed Fraction Example)

quantconnect | Published on: 2025/11/27
The following content is generated by EasyQuant .

Problem Description

How can I create a rule to always invest a fixed 5% of my portfolio into any new trade signal?

Solution

To implement a rule that always invests a fixed percentage (e.g., 5%) of your portfolio into every new trade signal, the most robust method within the QuantConnect LEAN framework is to define a custom Portfolio Construction Model (PCM).

This approach separates your signal logic (Alpha) from your sizing logic (Portfolio), ensuring that every Insight emitted by your algorithm is automatically converted into a PortfolioTarget of the specific size you desire.

Implementation

Here is the complete code for a custom FixedAllocationPortfolioConstructionModel and how to integrate it into your algorithm.

1. Define the Custom Portfolio Construction Model

from AlgorithmImports import *

class FixedAllocationPortfolioConstructionModel(PortfolioConstructionModel):
    """
    Allocates a fixed percentage of the total portfolio value to every active insight.
    """
    def __init__(self, percent: float = 0.05):
        """
        Args:
            percent: The fixed percentage to allocate (0.05 = 5%)
        """
        super().__init__()
        self.percent = percent

    def CreateTargets(self, algorithm, insights):
        targets = []
        
        for insight in insights:
            # If the signal is Flat, we likely want to liquidate (0% allocation)
            if insight.Direction == InsightDirection.Flat:
                targets.append(PortfolioTarget.Percent(algorithm, insight.Symbol, 0.0))
                continue

            # Determine direction multiplier (1 for Long, -1 for Short)
            direction = 1 if insight.Direction == InsightDirection.Up else -1
            
            # Calculate the target weight
            # Example: Short (-1) * 0.05 = -0.05 (Sell 5% of portfolio)
            weight = direction * self.percent
            
            # Create the target
            targets.append(PortfolioTarget.Percent(algorithm, insight.Symbol, weight))
            
        return targets

2. Integrate into Your Algorithm

In your main algorithm class, you must set this model during the Initialize method.

class FixedPercentAllocationAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2020, 1, 1)
        self.set_cash(100000)
        
        # Add assets
        self.add_equity("SPY", Resolution.DAILY)
        self.add_equity("AAPL", Resolution.DAILY)
        
        # 1. Set the Alpha Model (Logic that generates signals/insights)
        # Using a standard RsiAlphaModel as an example
        self.set_alpha(RsiAlphaModel())

        # 2. Set the Custom Portfolio Construction Model
        # This enforces the 5% rule for every signal generated by the Alpha model
        self.set_portfolio_construction(FixedAllocationPortfolioConstructionModel(percent=0.05))

        # 3. Set Execution Model (How to execute the orders)
        self.set_execution(ImmediateExecutionModel())

Key Details

  • PortfolioTarget.Percent: This helper function automatically calculates the number of shares required to reach the target weight based on the current TotalPortfolioValue.
  • Direction Handling: The code checks InsightDirection. If the signal is Up, it allocates +5%. If Down, it allocates -5% (short). If Flat, it allocates 0% (liquidates the position).
  • Independence: This model does not check if you have enough cash. If you generate 25 signals at 5% each, you will be 125% invested (using margin). If you want to prevent leverage, you would need to add logic to check algorithm.Portfolio.MarginRemaining.

Q&A

Q: Does this work if I manually place orders using self.SetHoldings?
A: No. This model works specifically with the Algorithm Framework (using EmitInsights or Alpha Models). If you are manually placing trades in OnData using self.SetHoldings, you should simply pass the percentage there: self.SetHoldings("SPY", 0.05).

Q: What happens if the price moves and my 5% allocation becomes 6%?
A: The CreateTargets method runs every time new insights are generated or at the rebalance frequency defined in the PCM. If the insight is still active, this model will recalculate the target. If the value has drifted significantly, the Execution model will generate a small rebalancing order to bring it back to 5%.

Q: Can I change the percentage dynamically?
A: Yes. You can modify the self.percent attribute of your model instance, or create logic inside CreateTargets to adjust the weight based on volatility or other factors available in the algorithm object.