bayesline.api.equity.OptimizationResult#

class bayesline.api.equity.OptimizationResult#

Contains the optimized state of each portfolio in the problem.

Each portfolio is optimized independently against the same objectives and constraints, so every date/portfolio pair carries its own solver status and objective value; one errored or infeasible solve does not affect the others.

__init__()#

Methods

__init__()

get_constraints()

Get the state of every constraint at the optimized holdings.

get_exposures()

Get the prior and optimized factor exposures per date and portfolio.

get_holdings()

Get the prior and optimized holdings per date, portfolio and asset.

get_summary()

Get the solver outcome per date and portfolio.

abstractmethod get_summary() → DataFrame#

Get the solver outcome per date and portfolio.

Solution-carrying rows (optimal, optimal_inaccurate) report the achieved objective value; other rows report a null objective value. message holds a human-readable explanation for rows without a solution; for rows with one it notes held names the problem kept fixed because the risk model has no data for them (missing exposures, volatility forecasts or market caps), and how much of nav is untradable and why, and is null when neither applies.

objective_value is in scaled (gross-nav-relative) units, not dollars or a per-net-nav unit – a multi-term objective would have no single natural unit to convert it to.

Returns#

pl.DataFrame

A dataframe with columns date, portfolio_id, status (an OptimizationStatus value), objective_value, and message, one row per optimized date and portfolio.

abstractmethod get_holdings() → DataFrame#

Get the prior and optimized holdings per date, portfolio and asset.

The frame is the portfolio, so its old and new columns each sum to the portfolio’s nav. Positions the optimizer cannot trade – holdings outside the risk model’s universe, and unmapped nav under the {MISSING} sentinel – are reported at their current value with an untradable_reason and no trade; they still count towards net exposure, gross exposure and turnover. Assets the book neither holds nor names in a position pin or bound contribute no row. Only date/portfolio pairs whose status carries a solution (optimal, optimal_inaccurate) contribute rows.

Returns#

pl.DataFrame

A dataframe with columns date, portfolio_id, asset_id, old, new, and trade, all in nav currency (dollars), and untradable_reason: cash (uploaded cash, which carries no exposure), off_model (a known security the risk model does not cover) or unmapped (nav the upload could not identify), null for positions the optimizer can trade. The latter two carry risk the model does not measure.

abstractmethod get_exposures() → DataFrame#

Get the prior and optimized factor exposures per date and portfolio.

Only date/portfolio pairs whose status carries a solution (optimal, optimal_inaccurate) contribute rows.

Returns#

pl.DataFrame

A dataframe with columns date, portfolio_id, factor, old, and new, both per unit of the portfolio’s whole net nav, including untradable holdings, which contribute no exposure; the reported exposure is therefore a lower bound on the book’s true exposure when untradable nav is not cash. Null for a factor-unconstrained portfolio whose net nav is ~0 (long/short books), where a per-net-nav value is not well-defined.

abstractmethod get_constraints() → DataFrame#

Get the state of every constraint at the optimized holdings.

One row per scalar constraint the problem imposed, including the rows of the defaults block (long_only, position_growth_cap, ownership_cap) and the implicit budget (holds the book’s total holdings fixed), and missing_exposure / missing_idio_vol / missing_market_cap (hold names the risk model has no data for at their current holding). Per-asset rows cover names the book holds before or after the trade. Values are in the unit the constraint was specified in, named by unit. Only date/portfolio pairs whose status carries a solution (optimal, optimal_inaccurate) contribute rows.

Returns#

pl.DataFrame

A dataframe with columns date, portfolio_id, constraint (the constraint kind), name (the bounded item: a factor, asset id, group, or total), side (min, max or eq), value (the achieved value), bound, slack (the room to spare: bound - value for max, value - bound for min, zero for eq), binding (whether the slack is within tolerance of zero; always true for eq), dual (the marginal change of the objective per unit of the bound, non-negative for min/max rows) and unit (net or gross nav, the denominator of value, bound and slack).