Portfolio Construction ======================= How you build and manage the portfolio is just as important as the entry signals. This page covers position sizing, rebalancing, and risk management at the portfolio level. ---- .. contents:: On this page :local: :depth: 1 ---- Slots and position sizing -------------------------- Quantlens uses a **fixed slots** model. You set a maximum number of simultaneous positions in the :ref:`config` block, and each position receives an equal share of the portfolio. .. code-block:: text Portfolio Value: $100,000 Slots: 10 Position Size: $10,000 per stock (10%) When fewer stocks than available slots qualify, the remaining capital sits in cash: .. code-block:: text Slots: 10 (maximum capacity) Selected: 6 (only 6 passed the filter today) In cash: 4 slots worth of idle capital **Why equal weighting?** Equal weighting is the simplest and most robust approach: - No single stock can dominate the portfolio. - Less sensitive to forecasting errors (you don't need to predict *how much* better one stock is). - Performs well over the long run compared to market-cap weighting for smaller universes. **How many slots?** .. list-table:: :header-rows: 1 :widths: 15 25 60 * - Slots - Position size - Characteristics * - 5 - 20% each - Concentrated. High individual stock impact. Greater volatility. * - 10 - 10% each - Balanced. The most common starting point. * - 20 - 5% each - Diversified. Smoother equity curve. Lower peak returns. * - 50 - 2% each - Highly diversified. Behaves more like an index. Suitable for large universes. .. tip:: Start with **10 slots**. Once your strategy logic is solid, experiment with 5 and 20 to see how concentration affects the Sharpe Ratio and Max Drawdown. ---- Stop-loss and take-profit -------------------------- These are set globally in the :ref:`config` block and apply to every position. **Stop-loss** closes a position when it falls N% from the entry price: .. code-block:: text Entry price: $100.00 Stop-loss: 0.07 (7%) Exit triggers: $100.00 × (1 − 0.07) = $93.00 **Take-profit** closes a position when it rises N% from entry: .. code-block:: text Entry price: $100.00 Take-profit: 0.15 (15%) Exit triggers: $100.00 × (1 + 0.15) = $115.00 **Trade-offs:** .. list-table:: :header-rows: 1 :widths: 30 35 35 * - Setting - Tighter (smaller %) - Wider (larger %) * - **Stop-Loss** - More exits, smaller losses, more trades, higher commission cost - Fewer exits, larger losses, trend-following friendly * - **Take-Profit** - Locks gains early, cuts momentum trades short - Lets winners run longer, but risks giving back profits For **mean-reversion** strategies: tighter stops, moderate take-profits (e.g. SL 5%, TP 10%). For **momentum** strategies: wider stops, no take-profit or wide take-profit (e.g. SL 7–10%, TP disabled or 30%+). ---- Rebalancing frequency ---------------------- The Primary Interval sets how often the portfolio is reviewed and rotated. .. list-table:: :header-rows: 1 :widths: 20 20 60 * - Interval - Trades/year - Best suited for * - ``1d`` (daily) - 200–500+ - Short-term mean reversion; high-frequency rotation. High commission cost. * - ``1w`` (weekly) - 50–150 - Momentum with weekly signals; lower costs than daily. * - ``2w`` (bi-weekly) - 25–75 - Classic momentum rotation. Best balance of signal freshness and costs. * - ``1m`` (monthly) - 10–30 - Long-term trend following. Very low costs. Slow to react. **The commission drag effect:** Frequent rebalancing compounds commission costs rapidly. With 0.1% commission and 300 trades/year, you lose 30% of gains to commissions alone. .. code-block:: text 0.1% commission × 2 (round-trip buy + sell) × 300 trades = 60% drag per year Always include realistic commission in your backtest settings before evaluating a daily strategy. ---- Market filter -------------- A market filter is a condition that prevents entering *any* new positions when the broad market is in a downtrend. It is one of the simplest and most effective risk-reduction techniques. **Classic filter:** .. code-block:: text Condition: Index Value > SMA(200) When the NASDAQ index closes below its 200-day SMA, the filter turns off new entries. Existing positions are still managed (stop-losses still trigger). **Why it works:** In bear markets, even fundamentally strong stocks fall — they are dragged down by the broader selloff. A market filter keeps you in cash during the worst drawdown periods. **Example impact:** .. list-table:: :header-rows: 1 :widths: 40 30 30 * - Strategy version - Max Drawdown - Sharpe Ratio * - Without market filter - -42% - 0.85 * - With Index > SMA(200) filter - -22% - 1.20 The filter typically *reduces* total return slightly (you miss some recovery rallies) but significantly improves the risk-adjusted return (Sharpe) and reduces Max Drawdown. ---- Cooldown filter ---------------- After a stock hits its stop-loss, it is placed in a "cooldown" for N days. During that period it cannot be re-entered, even if it passes all other filters. **Why use it:** Without a cooldown, a stock stopped out on Monday could re-enter on Wednesday at a lower price, get stopped again on Friday, re-enter the following Monday — burning commission on each cycle. The :ref:`stock_cooldown_filter` breaks this loop. **Typical setting:** 20 trading days (one calendar month). Shorter cooldowns (5–10 days) let you re-enter quickly if the stock recovers. Longer cooldowns (40–60 days) more aggressively filter out damaged stocks. ---- Combining filters ------------------ A robust portfolio strategy typically layers several filters: .. code-block:: text Entry conditions (all must be true): 1. Market filter: Index > SMA(200) 2. Momentum rank: Top 10 by 189-day momentum 3. Cooldown: Not stopped in last 20 days 4. (Optional) RSI: RSI(14) > 30 ← not deeply oversold Each layer removes some candidates, raising the average quality of selected positions. The trade-off: fewer qualifying stocks, more cash held on some rebalance dates. .. warning:: Over-filtering can leave the portfolio nearly empty most of the time. Monitor the average number of open positions in your results. If it's consistently below half your slot count, your filters may be too restrictive. ---- Cash drag ---------- When fewer stocks than slots pass all filters, the unallocated capital sits in cash. Cash earns nothing (in the backtest model) — this is called **cash drag**. Cash drag is not always bad: - In bear markets, high cash levels protect capital. - In choppy markets, avoiding bad trades by holding cash is better than forced entry. It becomes a problem only if your filters are so strict that you're almost never invested. **Check:** After running a backtest, look at the average number of open positions. For a 10-slot strategy, aim for 6–10 positions open on most rebalance dates.