discretizeΒΆ

Defined in fynance.portfolio.rebalance

discretize(W, prices, capital=1e6, lot=1.0, min_notional=0.0)[source]

Round a target weight book to whole lots on a fixed capital base.

Turns continuous target weights into the book an integer-lot execution would actually hold. At each bar the target notional W[t, i] * capital is converted to shares at prices[t, i], rounded to the nearest multiple of lot, and converted back to a weight shares * price / capital. A rebalancing trade whose notional |shares_new - shares_prev| * price falls below min_notional is suppressed (the previous share count is kept), which removes the churn of tiny odd-lot adjustments. The scan carries the held share count across bars, so the output depends on trade history, not only on the current target.

Parameters:
Warray_like

Target weights, shape (T, N) (1-D promoted to (T, 1), output squeezed back). Long-short books are supported (negative weights round to negative share counts).

pricesarray_like

Strictly positive price levels aligned with W, same shape.

capitalfloat, optional

Reference capital defining the notional base; must be > 0. Default 1e6.

lotfloat, optional

Tradeable lot size in shares (e.g. 100 for round lots); must be > 0. Default 1.0.

min_notionalfloat, optional

Trades whose notional value is strictly below this threshold are skipped, keeping the previous position; must be >= 0. Default 0.0 (never skip).

Returns:
np.ndarray

Effective weights implied by the rounded share book, same shape as W.

Raises:
ValueError

If W and prices do not share the same shape, contain non-finite values, or if capital <= 0, lot <= 0 or min_notional < 0.

Examples

With capital=1000 and unit lots, a 50% target on a $300 asset buys round(500 / 300) = 2 shares, i.e. an effective 60% weight; the $50 asset lands exactly on 50%:

>>> import numpy as np
>>> W = np.array([[0.5, 0.5]])
>>> prices = np.array([[300.0, 50.0]])
>>> discretize(W, prices, capital=1000.0, lot=1.0)
array([[0.6, 0.5]])