Skip to content

Learn

Stock Portfolio Research

Calendar or threshold rebalancing for a stock portfolio?

Calendar rebalancing and weight-threshold rebalancing can finish with similar target allocations while taking different paths to get there. Compare their triggers, executions, time spent outside the band and costs under one account model. A threshold that fired but could not trade is an unresolved event, not evidence that the portfolio was automatically restored.

This guide runs two policies on an invented two-stock account. It is an external research extension, not verified scheduling or brokerage functionality in CoTrading. Use one market and currency. Fractional shares, immediate boundary-price execution and the displayed fee are synthetic assumptions, not actual market promises.

Freeze the common account and target

Both policies start with five shares of A and five of B, each priced at 100, no cash and equity 1000. The target is half in each stock. Because this is an existing starting snapshot, initial formation costs are outside both paths rather than charged to one policy only.

Use the same observation schedule, data, prices, cash constraints, fees and terminal marking. A fair policy comparison cannot let the calendar route trade at closing prices while the threshold route receives a more favorable opening price. Preserve the exact execution assumption with every event.

The Investor.gov rebalancing guide describes calendar and allocation-deviation approaches. Our session schedule and thresholds are original toy choices, not recommended frequencies or evidence that either policy is universally superior.

Define triggers before observing the path

The calendar policy checks every session but only triggers at indices three and five. Those synthetic dates illustrate a predetermined schedule; they are not literal monthly market data. The threshold policy also checks each session and triggers when the largest absolute stock-weight deviation from 0.5 is at least 0.05.

The threshold is five percentage points of portfolio weight, not a five-percent relative increase in a position. Record that unit and whether equality triggers. Also freeze the inspection frequency: daily checks can miss intraday breaches, while less frequent checks answer another monitoring question.

Both routes face the same blocked market at session one. The calendar route has no scheduled trigger then; the threshold route can trigger but cannot execute. The availability state must not be changed after seeing which policy benefits from that missed opportunity.

Separate detection, execution and post-action drift

At each observed boundary, value current holdings and cash, calculate pretrade weights, evaluate the policy and record a unique status. If trading is allowed, derive targets, reserve proportional fees and execute the resulting quantity changes. Otherwise retain the actual account unchanged and preserve the reason.

We measure breach duration using weights after the policy’s action or blocked action at each inspection. That differs from counting every pretrade trigger, since a successful rebalance can remove a breach immediately. Keep both columns so the duration number is reproducible rather than inferred from an event count.

Quotes are treated as available executable boundary prices in this fixture. A real closing-weight signal that executes next session needs its actual delay and price. Do not use a known close to claim an earlier fill, or infer real instantaneous execution from this simplified model.

Work through the synthetic prices

A follows [100,130,140,120,100,110]; B stays at 100. With unchanged initial shares, A’s first-session weight is 650/1150, about 0.565217. Its deviation exceeds five percentage points, so the threshold route triggers, but session one is blocked.

At session two A reaches 140. Threshold rebalancing executes there; the calendar route continues holding until its scheduled session three, when A is 120. Later, the threshold route executes at session four, while the calendar route waits for session five.

SessionCalendar statusThreshold status
1no triggerblocked market
2no triggerexecuted
3executedno trigger
4no triggerexecuted
5executedno trigger

Both policies execute two rebalances, but their opportunities and turnover differ. Counting only executions would hide the threshold route’s third trigger and its blocked state. It would also miss how long the calendar route carried the initial deviation.

Fund the rebalance including costs

Charge 0.001 of absolute executed value on both sides. The SEC fees bulletin distinguishes transaction charges from other expenses; our ten-basis-point rate is invented and omits real taxes, minimums and market impact.

For each rebalance, solve for invested wealth after paying the fee on the difference between old and target holdings. Then compute shares and remaining cash. The script uses bisection and checks that cash is nonnegative within the declared tolerance and posttrade equity equals pretrade equity less the fee.

deviation = max(abs(actual_weight[s] - 0.5) for s in basket)
trigger = session in scheduled_sessions if policy == 'calendar' else deviation >= 0.05
if trigger and market_blocked:
    status = 'blocked_market'

The complete file also executes the funded target rather than merely setting displayed weights to 0.5. A real implementation with lots or rejected sells needs those state transitions too. Do not credit the cash from a sale that never happened.

Read the cost and drift results together

Calendar ending equity is 1054.025004, transaction cost 0.145829 and gross traded value divided by initial equity 0.145829. Threshold ending equity is 1079.640030, cost 0.371400 and turnover ratio 0.371400. The matching cost and turnover numerals arise from the chosen 1000 capital and 0.001 fee; their units differ.

The longest post-action breach lasts two inspected sessions for calendar rebalancing and one for threshold rebalancing. The threshold result is better on this particular invented price reversal, but also trades more value and pays more. Another path could reverse that ordering.

Ending within the band does not erase earlier breaches. Retain the full weight and trigger ledger, including session one’s failed threshold action. A final allocation snapshot cannot establish that either policy continuously satisfied its target throughout the holding period.

Test the blocked-trigger counterexample

The script asserts the exact execution dates for both policies and requires the threshold’s first event to remain blocked_market. Treating it as executed would change holdings, later triggers and costs. Treating it as no trigger would conceal the missed action.

It also checks exact ending amounts within 1e-6, cost anchors and the two drift-duration results. These numeric assertions protect the account calculation, not merely the fact that a loop returned. There is no claim that all possible market or order failures have been modeled.

If a real blocked event persists, define whether the policy retries at each inspection, waits for another scheduled date or requires manual review. Freeze that rule before testing. An apparently minor retry choice can materially change the path and should not be selected retrospectively.

Build a reviewable policy comparison

Export target version, inspection keys, trigger reason, pre/post weights, order quantities, execution status, cost, cash and equity. Distinguish a policy trigger from individual fill count. Several fills may belong to one rebalance, and a triggered rebalance may produce no admissible order.

Keep initial holdings and pending orders identical and preserve all failed events. If the basket or target changes during the study, treat it as a separate intervention with its own timing. Do not attribute a target-selection change to the rebalancing schedule alone.

Download the complete example. Use Python 3.12 or later and run python R629.py. Standard-library assertions verify funded state transitions, execution and blocked dates, exact ending/cost values and post-action breach durations on synthetic data.

Accept only a scoped comparison with consistent controls and complete event destinations. Recompute when inspection frequency, target, schedule, band, costs or execution rules change. The result does not establish optimal monthly timing, live execution readiness or an existing automatic CoTrading service.

FAQ

Are two executed rebalances equivalent paths?

No. Their timing, traded values, missed triggers and intervening drift can differ.

Does a threshold trigger guarantee a trade?

No. Preserve blocked or rejected execution and the actual remaining holdings.