Discrete Allocation

Discrete allocation helpers transforming continuous weights into share counts.

class pyvallocation.discrete_allocation.DiscreteAllocationInput(weights, latest_prices, total_value, lot_sizes=None)[source]

Bases: object

Container for validated discrete allocation inputs.

Key fields:

weights: Continuous target weights. latest_prices: Latest asset prices. total_value: Total portfolio value. lot_sizes: Optional lot sizes per asset.

Parameters:
  • weights (pandas.Series | Mapping[str, float])

  • latest_prices (pandas.Series | Mapping[str, float])

  • total_value (float)

  • lot_sizes (pandas.Series | Mapping[str, int] | None)

property asset_names: Sequence[str]

Tuple of asset names inferred from the weights index.

Returns:

Sequence[str] – Asset labels.

latest_prices: pandas.Series | Mapping[str, float]
lot_sizes: pandas.Series | Mapping[str, int] | None = None
total_value: float
class pyvallocation.discrete_allocation.DiscreteAllocationResult(shares, leftover_cash, achieved_weights, tracking_error)[source]

Bases: object

Discrete allocation output bundle.

Key fields:

shares: Non-zero share counts by asset. leftover_cash: Uninvested cash amount. achieved_weights: Realized weights from share allocation (relative to total portfolio value). tracking_error: L1 weight deviation (sum of absolute differences between target and achieved weights).

Parameters:
  • shares (Dict[str, int])

  • leftover_cash (float)

  • achieved_weights (pandas.Series)

  • tracking_error (float)

achieved_weights: pandas.Series
as_series()[source]

Return the allocated share counts as a pandas Series.

Returns:

pd.Series – Share counts indexed by asset.

Return type:

pandas.Series

leftover_cash: float
shares: Dict[str, int]
tracking_error: float
pyvallocation.discrete_allocation.allocate_greedy(inputs, max_iterations=None, *, fallback_mode='auto', fallback_kwargs=None)[source]

Greedy rounding of weights into integer share counts.

The allocator performs an initial floor pass followed by a deficit-driven topping up routine. If the greedy loop cannot make progress (e.g. due to a tight iteration cap), fallback_mode controls whether the MILP allocator should be tried as a secondary attempt.

Parameters:
  • inputs (DiscreteAllocationInput)

  • max_iterations (int | None)

  • fallback_mode (str)

  • fallback_kwargs (Dict[str, Any] | None)

Return type:

DiscreteAllocationResult

pyvallocation.discrete_allocation.allocate_mip(inputs, cash_penalty=1.0, max_cash=None, solver_options=None)[source]

Mixed-integer allocation minimizing L1 tracking error and leftover cash.

Parameters:
  • inputs – Validated allocation inputs.

  • cash_penalty – Penalty on leftover cash in the objective.

  • max_cash – Optional upper bound on leftover cash.

  • solver_options – Optional SciPy MILP solver options.

Returns:

DiscreteAllocationResult – Allocation result with share counts.

Parameters:
  • inputs (DiscreteAllocationInput)

  • cash_penalty (float)

  • max_cash (float | None)

  • solver_options (Dict[str, int | float] | None)

Return type:

DiscreteAllocationResult

pyvallocation.discrete_allocation.discretize_weights(weights, latest_prices, total_value, *, method='greedy', lot_sizes=None, **kwargs)[source]

Routes to the requested discrete allocation algorithm.

Parameters:
  • weights – Target weights.

  • latest_prices – Latest asset prices.

  • total_value – Total portfolio value.

  • method"greedy" or "milp".

  • lot_sizes – Optional lot sizes per asset.

  • **kwargs – Extra keyword arguments forwarded to the allocator.

Returns:

DiscreteAllocationResult – Allocation result with share counts.

Parameters:
  • weights (pandas.Series | Mapping[str, float])

  • latest_prices (pandas.Series | Mapping[str, float])

  • total_value (float)

  • method (str)

  • lot_sizes (pandas.Series | Mapping[str, int] | None)

Return type:

DiscreteAllocationResult