Quant Trading for Programmers 19: Generate Rebalance Plans From Target Weights
· 12 min read · Views --
Last updated on

Quant Trading for Programmers 19: Generate Rebalance Plans From Target Weights

Author: Alex Xiang


Quant Trading for Programmers 19: Generate Rebalance Plans From Target Weights

One easy mistake in paper trading is treating a “strategy target” as an “account execution.”

Article 19 deliberately adds one layer between them: the rebalance plan. It only gives buy and sell suggestions. It does not directly modify account state.

A ZiCode engineer planning paper-trading rebalancing

Inputs To A Rebalance Plan

Chapter 19 adds app/rebalance_plan.py.

Inputs include:

  • Current paper-trading account.
  • Latest prices.
  • Target weights.
  • Minimum rebalance value.

Target weights can come from many places: equal-weight portfolios, factor-score rankings, risk budgets, manually specified whitelists, or more complex portfolio optimization later. No matter where they come from, they should become a rebalance plan before reaching the account layer. The strategy layer expresses “how much weight I want”; the account layer handles prices, board lots, minimum trade value, and risk controls.

Output Buy And Sell Suggestions

The output object is RebalancePlan, which contains a set of RebalanceOrderPlan entries:

@dataclass(frozen=True)
class RebalanceOrderPlan:
    symbol: str
    side: str
    shares: int
    price: float
    target_weight: float
    current_weight: float
    delta_value: float

It keeps current weight, target weight, and delta value so later explanations can show why a buy or sell is suggested.

Why Not Place Orders Directly

A rebalance plan is not an executor.

It does not deduct cash, change positions, or pretend an order was filled. In a real system, the plan still needs risk checks, manual confirmation, tradability checks, and execution matching. Even in paper trading, separating plan from execution reduces a lot of debugging cost.

A-Share Board-Lot Constraint

The plan function rounds shares down to board lots of 100:

def _lot_shares(raw_shares: float) -> int:
    lots = int(abs(raw_shares) // 100)
    return lots * 100

This stays consistent with the trading rules from article 4. If odd-lot selling or finer trading rules need to be supported later, this layer can be extended.

Current Mainline Integrated Run

After risk controls find excessive single-stock concentration, paper-flow continues by generating a rebalance plan from target weights:

uv run python -m scripts.chapter_examples paper-flow

Real output:

Real rebalance-plan output for article 19

The current position weight is 80.74%, and the target weight is 45.00%, so the plan suggests selling 2800 shares. This is still only a plan. It does not directly modify the account. A later execution layer must still check available position, price, fees, and risk status.

Chapter Update And Repository

This chapter adds:

  • app/rebalance_plan.py.
  • Rebalance plans based on current weights and target weights.
  • Minimum rebalance value filtering, missing-price skips, and A-share board-lot constraints.
  • tests/test_rebalance_plan.py, covering buy/sell suggestions and small-change skips.
  • A real current-mainline screenshot for the rebalance-plan integrated example.
  • Context on target-weight sources and the responsibility boundary between strategy and account layers.

Repository:

https://github.com/ax2/zi-quant-platform

Code for this chapter:

git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-19
uv sync --extra dev
uv run pytest tests/test_rebalance_plan.py

Chapter 19 is commit b655c37, tagged as chapter-19.

Summary

Strategy targets should not be treated as account actions directly.

Article 19 converts target weights into explainable, testable, not-yet-executed rebalance plans. The next article combines account snapshots, risk reports, and rebalance plans into one paper-trading daily report.