qis.plot_overlay_allocation_frontier¶
- qis.plot_overlay_allocation_frontier(portfolio_stats, frontier_stats=None, groups=None, benchmark=None, group_styles=None, highlights=None, annotations=None, label_offsets=None, x_column='bear_sharpe', y_column='sharpe', frontier_label='Optimal stacked portfolios', frontier_color='#009E73', xlabel='Bear Sharpe contribution of the stacked portfolio', ylabel='Arithmetic excess Sharpe ratio of the stacked portfolio', title=None, legend_loc='upper center', figsize=(8.6, 5.2), ax=None, bbox_to_anchor=(0.5, -0.14), ncols=2)[source]¶
Stacked portfolios by group and an optional solved coverage-floor frontier.
Every point is a portfolio, not a standalone overlay: the benchmark itself, or the benchmark at weight one plus an overlay at the chosen budget, the stacked portfolio of Sepp and Kastenholz (2026, Definition 3). Build the stacked returns
r_B + w r_ifirst and pass them, with the benchmark, throughqis.regimes.compute_regime_premium_table, whosebear_sharpeandsharpecolumns are the default coordinates. Compute the frontier rows the same way from the solved allocations. Weights and optimiser objects are not needed, and the function does not fit, sort, round or recompute coordinates.- Parameters:
portfolio_stats (DataFrame) – statistics of the benchmark and the stacked portfolios, indexed by unique portfolio names
frontier_stats (DataFrame | None) – statistics of the solved portfolios in the order of the floor; None draws only the points. Repeated coordinate pairs are kept, as where the floor is slack
groups (Series | None) – group label by portfolio name, covering every point of
portfolio_stats; None puts the points in one group and the benchmark in its ownbenchmark (str | None) – name of the benchmark row, whose x coordinate sets the dashed vertical line
group_styles (Mapping[str, Mapping[str, Any]] | None) – matplotlib scatter options by group, such as color, marker, s and label; groups without options use the matplotlib colour cycle
highlights (Mapping[str, Mapping[str, Any]] | None) – scatter options by portfolio name for selected allocations, drawn once apart from their groups and named in the legend
annotations (Sequence[str] | None) – names of the points to label; None labels every point that is not highlighted, and an empty sequence none
label_offsets (Mapping[str, Tuple[float, float]] | None) – label offsets in points by portfolio name
x_column (str) – column of the x coordinate in both tables, the Bear contribution by default
y_column (str) – column of the y coordinate in both tables, the Sharpe ratio by default
frontier_label (str) – legend label of the frontier
frontier_color (str) – colour of the frontier line
xlabel (str) – x-axis label; state the Sharpe convention when it matters
ylabel (str) – y-axis label
title (str | None) – optional title
legend_loc (str | None) – legend location; None draws no legend. The default puts the legend’s upper centre below the axes, in two columns without a frame
ax (Axes | None) – axis to draw on; None creates a figure
bbox_to_anchor (Tuple[float, float] | None) – legend anchor in axes coordinates; None uses
legend_localonencols (int) – number of legend columns
- Returns:
the new figure, or None when
axis given- Raises:
ValueError – if the coordinates, the row labels, the groups or a selected name are invalid
- Return type:
Figure | None