bayesline.api.equity.PortfolioHierarchySettings#

pydantic model bayesline.api.equity.PortfolioHierarchySettings#

Specifies portfolio hierarchies with arbitrary groupings (e.g. manager, etc.).

Show JSON schema
{
   "title": "PortfolioHierarchySettings",
   "description": "Specifies portfolio hierarchies with arbitrary groupings (e.g. manager, etc.).",
   "type": "object",
   "properties": {
      "portfolio_schema": {
         "anyOf": [
            {
               "type": "string"
            },
            {
               "type": "integer"
            },
            {
               "$ref": "#/$defs/PortfolioOrganizerSettings"
            }
         ],
         "description": "The portfolio organizer settings to use as an underlying schema of portfolios. The 'Default' schema is used by default.",
         "title": "Portfolio Schema"
      },
      "groupings": {
         "additionalProperties": {
            "items": {
               "type": "string"
            },
            "type": "array"
         },
         "title": "Groupings",
         "type": "object"
      },
      "portfolio_ids": {
         "items": {
            "type": "string"
         },
         "title": "Portfolio Ids",
         "type": "array"
      },
      "benchmark_ids": {
         "items": {
            "anyOf": [
               {
                  "type": "string"
               },
               {
                  "type": "null"
               }
            ]
         },
         "title": "Benchmark Ids",
         "type": "array"
      },
      "auto_decompose_levels": {
         "anyOf": [
            {
               "items": {
                  "type": "string"
               },
               "maxItems": 100,
               "type": "array"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "When provided, each ``portfolio_id`` that is a FoF parent is automatically expanded at load time into one entry per descendant path (``parent:child:...:leaf``) plus a ``parent_path:{REST}`` entry at each non-leaf level capturing what wasn't decomposed there. Path-typed inputs (containing ``:``) are left unchanged for idempotence. Only ``len(auto_decompose_levels)`` is meaningful \u2014 it sets the maximum recursion depth; the cascade emits exactly that many system grouping columns named ``bayesline/level_N``, and the element values themselves are not consumed. Deeper branches stop expanding and are emitted as bare leaves (no ``:{REST}`` sibling is added below a truncated node for its own un-emitted children); NAV is still conserved because the lookthrough math at query time descends through the full subtree. So ``auto_decompose_levels=['fund', 'strategy']`` decomposes up to two levels and emits ``bayesline/level_1`` and ``bayesline/level_2`` columns in ``groupings`` carrying the parent ids at each level. Compatible with hand-rolled ``groupings``: the cascade merges them via path-walk inheritance under their bare names (see ``auto_decompose_hierarchy`` in ``portfolio_cascade``). ``None`` disables auto-decompose; an empty list is rejected. Capped at 100 to keep recursion well below Python's default limit; real FoF hierarchies rarely exceed a handful of levels.",
         "title": "Auto Decompose Levels"
      }
   },
   "$defs": {
      "PortfolioOrganizerSettings": {
         "additionalProperties": false,
         "description": "Definition of where to source portfolio data from.\n\nSpecifies which portfolios to enable (from different sources).\nDifferent sources (e.g. uploaded portfolios) can provide the same portfolio\nidentifiers. These settings allow to specify which portfolios to enable from\nwhich sources.",
         "properties": {
            "enabled_portfolios": {
               "anyOf": [
                  {
                     "type": "string"
                  },
                  {
                     "additionalProperties": {
                        "type": "string"
                     },
                     "type": "object"
                  }
               ],
               "description": "The enabled portfolios from different sources. The key is the portfolio ID, and the value is the source (name of the underlying portfolio service). Pass a str to reference an entire portfolio source (e.g. all portfolios from an upload).",
               "title": "Enabled Portfolios"
            },
            "auxiliary_portfolios": {
               "additionalProperties": {
                  "type": "string"
               },
               "description": "Portfolios pulled in by fund-of-funds (FoF) cascade. Informational: always recomputed from ``enabled_portfolios`` plus the FoF graph at load time. Persisted as-is on save; any stale values are overwritten on the next normalize. The loader's effective enabled set is the union of ``enabled_portfolios`` and ``auxiliary_portfolios`` with user-explicit entries winning on key collision.",
               "title": "Auxiliary Portfolios",
               "type": "object"
            }
         },
         "required": [
            "enabled_portfolios"
         ],
         "title": "PortfolioOrganizerSettings",
         "type": "object"
      }
   },
   "additionalProperties": false,
   "required": [
      "portfolio_schema",
      "portfolio_ids",
      "benchmark_ids"
   ]
}

Config:
  • frozen: bool = True

  • extra: str = forbid

Fields:
  • auto_decompose_levels (list[str] | None)

  • benchmark_ids (list[str | None])

  • groupings (dict[str, list[str]])

  • portfolio_ids (list[str])

  • portfolio_schema (str | int | bayesline.api._src.equity.portfolio_settings.PortfolioOrganizerSettings)

Validators:
  • _fill_benchmark_ids » all fields

  • _validate_auto_decompose » all fields

  • _validate_benchmark_ids » portfolio_ids

  • _validate_dimensions » all fields

  • _validate_groupings » groupings

  • _validate_groupings_namespace » all fields

  • _validate_ids_with_rest » all fields

  • _validate_portfolio_ids » portfolio_ids

  • _validate_portfolio_schema » portfolio_schema

field portfolio_schema: str | int | PortfolioOrganizerSettings [Required]#

The portfolio organizer settings to use as an underlying schema of portfolios. The ‘Default’ schema is used by default.

Validated by:
  • _fill_benchmark_ids

  • _strip_unknown_on_load

  • _validate_auto_decompose

  • _validate_dimensions

  • _validate_groupings_namespace

  • _validate_ids_with_rest

  • _validate_portfolio_schema

field groupings: dict[str, list[str]] [Optional]#
Validated by:
  • _fill_benchmark_ids

  • _strip_unknown_on_load

  • _validate_auto_decompose

  • _validate_dimensions

  • _validate_groupings

  • _validate_groupings_namespace

  • _validate_ids_with_rest

field portfolio_ids: list[str] [Required]#
Validated by:
  • _fill_benchmark_ids

  • _strip_unknown_on_load

  • _validate_auto_decompose

  • _validate_benchmark_ids

  • _validate_dimensions

  • _validate_groupings_namespace

  • _validate_ids_with_rest

  • _validate_portfolio_ids

field benchmark_ids: list[str | None] [Required]#
Validated by:
  • _fill_benchmark_ids

  • _strip_unknown_on_load

  • _validate_auto_decompose

  • _validate_dimensions

  • _validate_groupings_namespace

  • _validate_ids_with_rest

field auto_decompose_levels: list[str] | None = None#

When provided, each portfolio_id that is a FoF parent is automatically expanded at load time into one entry per descendant path (parent:child:...:leaf) plus a parent_path:{REST} entry at each non-leaf level capturing what wasn’t decomposed there. Path-typed inputs (containing :) are left unchanged for idempotence. Only len(auto_decompose_levels) is meaningful — it sets the maximum recursion depth; the cascade emits exactly that many system grouping columns named bayesline/level_N, and the element values themselves are not consumed. Deeper branches stop expanding and are emitted as bare leaves (no :{REST} sibling is added below a truncated node for its own un-emitted children); NAV is still conserved because the lookthrough math at query time descends through the full subtree. So auto_decompose_levels=['fund', 'strategy'] decomposes up to two levels and emits bayesline/level_1 and bayesline/level_2 columns in groupings carrying the parent ids at each level. Compatible with hand-rolled groupings: the cascade merges them via path-walk inheritance under their bare names (see auto_decompose_hierarchy in portfolio_cascade). None disables auto-decompose; an empty list is rejected. Capped at 100 to keep recursion well below Python’s default limit; real FoF hierarchies rarely exceed a handful of levels.

Constraints:
  • max_length = 100

Validated by:
  • _fill_benchmark_ids

  • _strip_unknown_on_load

  • _validate_auto_decompose

  • _validate_dimensions

  • _validate_groupings_namespace

  • _validate_ids_with_rest

property menu_type: type[PortfolioHierarchySettingsMenu]#

Get the menu type for this settings object.

Returns#

type[M]

The menu type for this settings object.

classmethod from_source(source: str, portfolio_ids: list[str], benchmark_ids: list[str | None] | None = None, groupings: dict[str, list[str]] | None = None, *, auto_decompose_levels: list[str] | None = None) PortfolioHierarchySettings#

Create portfolio hierarchy settings from a source.

Parameters#

sourcestr

The name of an upload from the portfolio uploader.

portfolio_idslist[str]

The list of portfolio IDs.

benchmark_idslist[str | None] | None, default=None

The list of benchmark IDs, defaults to None for each portfolio.

groupingsdict[str, list[str]] | None, default=None

The groupings dictionary, defaults to empty dict.

auto_decompose_levelslist[str] | None, default=None

See PortfolioHierarchySettings.auto_decompose_levels.

Returns#

PortfolioHierarchySettings

The created portfolio hierarchy settings.

classmethod from_polars(df: DataFrame, portfolio_schema: str | int | PortfolioOrganizerSettings = 'Default', portfolio_source: str | None = None, *, auto_decompose_levels: list[str] | None = None) PortfolioHierarchySettings#

Create a portfolio hierarchy from a dataframe.

Must contain a column portfolio_id and optionally benchmark_id. Every other column is interpreted as a grouping. 0 groupings are allowed. Index is ignored.

Parameters#

dfpl.DataFrame

The dataframe to create the hierarchy from.

portfolio_schemastr | int | PortfolioOrganizerSettings, default=”Default”

The underlying portfolio schema to use.

portfolio_sourcestr | None, default=None

The source to use for the portfolio schema. If not provided then the portfolio schema is used. If provided then it will override the portfolio schema.

auto_decompose_levelslist[str] | None, default=None

See PortfolioHierarchySettings.auto_decompose_levels.

Returns#

PortfolioHierarchySettings

The created portfolio hierarchy settings.

Raises#

ValueError

If the portfolio_id column is not found in the dataframe.

to_polars() DataFrame#

Convert the hierarchy to a polars dataframe.

The last two columns are the portfolio and benchmark IDs. Every column before that is a grouping. 0 groupings are possible.

Returns#

pl.DataFrame

The dataframe representation of the hierarchy, sorted by portfolio ID.

get_references() Sequence[str | int]#

Get references for this settings object.

Returns#

Sequence[str | int]

A sequence of references (strings or integers) for this settings object.

describe(menu: PortfolioHierarchySettingsMenu) str#

Describe the portfolio hierarchy settings.

Parameters#

menuPortfolioHierarchySettingsMenu

The menu to get context information from.

Returns#

str

The description of the portfolio hierarchy settings.