rebalance_band¶
Defined in fynance.portfolio.rebalance
- rebalance_band(W, X, band=0.05, mode='full')[source]
Rebalance only when the drift leaves a no-trade band around the target.
Each bar the held book is drifted with asset returns and compared to the current target; a trade is triggered only when the largest per-asset deviation exceeds band, \(\max_i |w^{\text{drift}}_{t,i} - W_{t,i}| > band\). When it does:
mode='full'trades all the way back to the targetW[t];mode='edge'trades each asset only to the near band edge, i.e. clips the drifted weight to[W[t] - band, W[t] + band]— the breaching asset lands exactly on the boundary and the book stays inside the band while trading as little as possible.
Bar 0 always establishes the full target book; the band governs bars
>= 1.- Parameters:
- Warray_like
Target weights, shape
(T, N)(1-D promoted to(T, 1), output squeezed back). Long-short books are supported.- Xarray_like
Price/level panel aligned with W, same shape.
- bandfloat, optional
No-trade half-width around each target weight; must be
>= 0. Default 0.05.- mode{‘full’, ‘edge’}, optional
Whether a triggered trade goes to the target (
'full', default) or only to the band edge ('edge').
- Returns:
- np.ndarray
Effective weights actually held, same shape as W.
- Raises:
- ValueError
If W and X do not share the same shape, contain non-finite values,
band < 0, or mode is not'full'/'edge'.
See also
rebalance_calendarrebalance_turnover_cap
Examples
A 20% one-day divergence breaks a 5% band;
'full'snaps back to target while'edge'stops on the band boundary:>>> import numpy as np >>> W = np.array([[0.5, 0.5], [0.5, 0.5]]) >>> X = np.array([[100.0, 100.0], [120.0, 80.0]]) >>> rebalance_band(W, X, band=0.05, mode='full') array([[0.5, 0.5], [0.5, 0.5]]) >>> rebalance_band(W, X, band=0.05, mode='edge') array([[0.5 , 0.5 ], [0.55, 0.45]])