bayesline.api.equity.PortfolioSelectionResolution#

pydantic model bayesline.api.equity.PortfolioSelectionResolution#

The outcome of resolving a portfolio selection against the live catalog.

A selection is a portfolio_id -> source mapping. Resolving it runs the same fund-of-funds cascade a report run does: the explicit picks are unioned with the children cascaded in from any fund-of-funds parents among them. The result reports the effective run set, which picks no longer resolve and why, and whether the selection can be run as-is.

Show JSON schema
{
   "title": "PortfolioSelectionResolution",
   "description": "The outcome of resolving a portfolio selection against the live catalog.\n\nA selection is a ``portfolio_id -> source`` mapping. Resolving it runs the\nsame fund-of-funds cascade a report run does: the explicit picks are unioned\nwith the children cascaded in from any fund-of-funds parents among them. The\nresult reports the effective run set, which picks no longer resolve and why,\nand whether the selection can be run as-is.",
   "type": "object",
   "properties": {
      "effective": {
         "additionalProperties": {
            "type": "string"
         },
         "description": "The effective run set as ``portfolio_id -> source``: the still-resolving picks unioned with the fund-of-funds children cascaded in from them. Empty when a collision or cycle prevents cascading.",
         "title": "Effective",
         "type": "object"
      },
      "orphans": {
         "additionalProperties": {
            "enum": [
               "missing_source",
               "missing_portfolio"
            ],
            "type": "string"
         },
         "description": "Portfolio ids in the selection or its fund-of-funds cascade that no longer resolve against the live sources, mapped to the reason. ``missing_source``: the source the selection claimed no longer exists. ``missing_portfolio``: the source still exists but no longer contains this portfolio id (for a cascaded child this means a fund's holdings reference a portfolio with no holdings of its own).",
         "title": "Orphans",
         "type": "object"
      },
      "incomplete_fof_parents": {
         "description": "Selected fund-of-funds parents that transitively hold an orphaned child. When the orphan is an explicit pick these cannot run until it is removed; when it is a cascade-pulled missing constituent they run without it (its NAV share is kept but not decomposed), so aggregates may not fully tie out against the children.",
         "items": {
            "type": "string"
         },
         "title": "Incomplete Fof Parents",
         "type": "array"
      },
      "collision": {
         "anyOf": [
            {
               "$ref": "#/$defs/PortfolioFofCollision"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "A cross-source fund-of-funds collision blocking the cascade, or ``None``. Resolution stops at the first collision, so at most one is reported."
      },
      "cycle": {
         "anyOf": [
            {
               "items": {
                  "type": "string"
               },
               "type": "array"
            },
            {
               "type": "null"
            }
         ],
         "default": null,
         "description": "A fund-of-funds cycle blocking the cascade, as the portfolio-id path that closes the loop, or ``None``. Resolution stops at the first cycle, so at most one is reported.",
         "title": "Cycle"
      },
      "runnable": {
         "description": "True when a report run resolves the selection without error: no explicitly-selected orphans, no collision, and no cycle. An orphan that only cascades in from a fund-of-funds holdings edge (a constituent that was never explicitly selected) does not block: the run keeps a slot for the missing child and preserves its NAV share in the parent, so it is reported in ``orphans`` and ``incomplete_fof_parents`` as a warning only.",
         "title": "Runnable",
         "type": "boolean"
      }
   },
   "$defs": {
      "PortfolioFofCollision": {
         "description": "A fund-of-funds child reachable from two different sources at once.\n\nThe child cascades in from more than one source, so its source is\nambiguous. It is resolved by listing the child explicitly in the selection\nwith the intended source.",
         "properties": {
            "portfolio_id": {
               "description": "The child portfolio id reachable from multiple sources.",
               "title": "Portfolio Id",
               "type": "string"
            },
            "sources": {
               "description": "The conflicting sources the child cascades in from.",
               "items": {
                  "type": "string"
               },
               "title": "Sources",
               "type": "array"
            }
         },
         "required": [
            "portfolio_id",
            "sources"
         ],
         "title": "PortfolioFofCollision",
         "type": "object"
      }
   },
   "required": [
      "effective",
      "runnable"
   ]
}

Fields:
  • collision (bayesline.api._src.equity.portfolio.PortfolioFofCollision | None)

  • cycle (list[str] | None)

  • effective (dict[str, str])

  • incomplete_fof_parents (list[str])

  • orphans (dict[str, Literal['missing_source', 'missing_portfolio']])

  • runnable (bool)

field effective: dict[str, str] [Required]#

The effective run set as portfolio_id -> source: the still-resolving picks unioned with the fund-of-funds children cascaded in from them. Empty when a collision or cycle prevents cascading.

field orphans: dict[str, Literal['missing_source', 'missing_portfolio']] [Optional]#

Portfolio ids in the selection or its fund-of-funds cascade that no longer resolve against the live sources, mapped to the reason. missing_source: the source the selection claimed no longer exists. missing_portfolio: the source still exists but no longer contains this portfolio id (for a cascaded child this means a fund’s holdings reference a portfolio with no holdings of its own).

field incomplete_fof_parents: list[str] [Optional]#

Selected fund-of-funds parents that transitively hold an orphaned child. When the orphan is an explicit pick these cannot run until it is removed; when it is a cascade-pulled missing constituent they run without it (its NAV share is kept but not decomposed), so aggregates may not fully tie out against the children.

field collision: PortfolioFofCollision | None = None#

A cross-source fund-of-funds collision blocking the cascade, or None. Resolution stops at the first collision, so at most one is reported.

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

A fund-of-funds cycle blocking the cascade, as the portfolio-id path that closes the loop, or None. Resolution stops at the first cycle, so at most one is reported.

field runnable: bool [Required]#

True when a report run resolves the selection without error: no explicitly-selected orphans, no collision, and no cycle. An orphan that only cascades in from a fund-of-funds holdings edge (a constituent that was never explicitly selected) does not block: the run keeps a slot for the missing child and preserves its NAV share in the parent, so it is reported in orphans and incomplete_fof_parents as a warning only.