{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "4473a1c7",
      "metadata": {},
      "source": [
        "# Portfolio Hierarchies\n",
        "\n",
        "**Prerequisites**\n",
        "* *Portfolios API* Tutorial\n",
        "* *Uploaders API* Tutorial\n",
        "\n",
        "In this tutorial we are going to demonstrate the usage of the Bayesline Portfolio Hierarchies API. The Portfolio Hierarchies API builds on the Portfolios API (see tutorial for an in depth walk through). It allows to combine portfolios with benchmarks and other groupings and by default applies forward filling and drift correction. This forms the foundation for portfolio analytics, where we can simply link a *Portfolio Hierarchy* and obtain analytics (e.g. a return attribution report) for different portfolios with optional benchmarks and other groupings.\n",
        "\n",
        "Specifically, we will introduce and explore:\n",
        "* *Portfolio Hierarchies*\n",
        "* Creating a new *Portfolio Hierarchy*\n",
        "    * Only portfolios\n",
        "    * With benchmarks\n",
        "    * Additional Groupings \n",
        "* Obtaining data\n",
        "* Housekeeping "
      ]
    },
    {
      "cell_type": "markdown",
      "id": "66d1b33f",
      "metadata": {},
      "source": [
        "## Imports & Setup\n",
        "\n",
        "For this tutorial notebook, you will need to import the following packages."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "fca4e97c",
      "metadata": {},
      "outputs": [],
      "source": [
        "import datetime as dt\n",
        "\n",
        "import polars as pl\n",
        "\n",
        "from bayesline.apiclient import BayeslineApiClient\n",
        "\n",
        "from bayesline.api.equity import (\n",
        "    PortfolioHierarchySettings,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "08cbea4b",
      "metadata": {},
      "source": [
        "We will also need to have a Bayesline API client configured."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "124b3afd",
      "metadata": {
        "tags": [
          "skip-execution"
        ]
      },
      "outputs": [],
      "source": [
        "bln = BayeslineApiClient.new_client(\n",
        "    endpoint=\"https://[ENDPOINT]\",\n",
        "    api_key=\"[API-KEY]\",\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "67b72bd7",
      "metadata": {},
      "source": [
        "The main entrypoint for the Portfolios API sits on `bln.equity.portfoliohierarchies`. All portfolio hierarchies functionality can be reached from here on out.\n",
        "\n",
        "See here for relevant docs:\n",
        "* [Portfolio Hierarchies](https://docs.bayesline.com/0.21.0/_autosummary/bayesline.api.equity.AsyncPortfolioHierarchyApi.html)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "8eaa4d1f",
      "metadata": {},
      "outputs": [],
      "source": [
        "ph_loader = bln.equity.portfoliohierarchies"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f3ef5ca6",
      "metadata": {},
      "source": [
        "## Portfolio Hierarchies\n",
        "\n",
        "In its most plain form a *PortfolioHierarchy* solely consists of a list of portfolio ids and a source or schema that describes where to obtain the data from.\n",
        "\n",
        "Below we create some demo portfolio data and upload it to the system such that it can be used for this demo. See the *Uploaders API* tutorial for an in depth walk through on how to bring data into the Bayesline ecosystem. \n",
        "\n",
        "In this toy example we create four portfolios with 2 holdings prints, 2025-01-01 and 2025-01-31:\n",
        "1. `AGTHX` with two holdings\n",
        "2. `FCNTX` with one holding\n",
        "3. `VADGX` with three holdings\n",
        "3. `SPX` with four holdings"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "d1427178",
      "metadata": {},
      "outputs": [],
      "source": [
        "uploader = bln.equity.uploaders.get_data_type(\"portfolios\").get_or_create_dataset(\"portfolio-hierarchies-demo\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "07ac4530",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div><style>\n",
              ".dataframe > thead > tr,\n",
              ".dataframe > tbody > tr {\n",
              "  text-align: right;\n",
              "  white-space: pre-wrap;\n",
              "}\n",
              "</style>\n",
              "<small>shape: (20, 7)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>portfolio_id</th><th>asset_id</th><th>asset_id_type</th><th>date</th><th>currency</th><th>share_qty</th><th>nav</th></tr><tr><td>str</td><td>str</td><td>str</td><td>date</td><td>str</td><td>f64</td><td>f64</td></tr></thead><tbody><tr><td>&quot;AGTHX&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;cusip9&quot;</td><td>2026-01-01</td><td>null</td><td>null</td><td>0.5</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;cusip9&quot;</td><td>2026-01-31</td><td>null</td><td>null</td><td>0.55</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2588173&quot;</td><td>&quot;sedol7&quot;</td><td>2026-01-01</td><td>null</td><td>null</td><td>0.5</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2588173&quot;</td><td>&quot;sedol7&quot;</td><td>2026-01-31</td><td>null</td><td>null</td><td>0.45</td></tr><tr><td>&quot;FCNTX&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;cusip8&quot;</td><td>2026-01-01</td><td>null</td><td>null</td><td>1.0</td></tr><tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>&quot;SPX&quot;</td><td>&quot;2588173&quot;</td><td>&quot;sedol7&quot;</td><td>2026-01-31</td><td>null</td><td>null</td><td>0.2</td></tr><tr><td>&quot;SPX&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;cusip8&quot;</td><td>2026-01-01</td><td>null</td><td>null</td><td>0.3</td></tr><tr><td>&quot;SPX&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;cusip8&quot;</td><td>2026-01-31</td><td>null</td><td>null</td><td>0.25</td></tr><tr><td>&quot;SPX&quot;</td><td>&quot;85371710&quot;</td><td>&quot;cusip8&quot;</td><td>2026-01-01</td><td>null</td><td>null</td><td>0.3</td></tr><tr><td>&quot;SPX&quot;</td><td>&quot;85371710&quot;</td><td>&quot;cusip8&quot;</td><td>2026-01-31</td><td>null</td><td>null</td><td>0.25</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (20, 7)\n",
              "┌──────────────┬───────────┬───────────────┬────────────┬──────────┬───────────┬──────┐\n",
              "│ portfolio_id ┆ asset_id  ┆ asset_id_type ┆ date       ┆ currency ┆ share_qty ┆ nav  │\n",
              "│ ---          ┆ ---       ┆ ---           ┆ ---        ┆ ---      ┆ ---       ┆ ---  │\n",
              "│ str          ┆ str       ┆ str           ┆ date       ┆ str      ┆ f64       ┆ f64  │\n",
              "╞══════════════╪═══════════╪═══════════════╪════════════╪══════════╪═══════════╪══════╡\n",
              "│ AGTHX        ┆ 02079K305 ┆ cusip9        ┆ 2026-01-01 ┆ null     ┆ null      ┆ 0.5  │\n",
              "│ AGTHX        ┆ 02079K305 ┆ cusip9        ┆ 2026-01-31 ┆ null     ┆ null      ┆ 0.55 │\n",
              "│ AGTHX        ┆ 2588173   ┆ sedol7        ┆ 2026-01-01 ┆ null     ┆ null      ┆ 0.5  │\n",
              "│ AGTHX        ┆ 2588173   ┆ sedol7        ┆ 2026-01-31 ┆ null     ┆ null      ┆ 0.45 │\n",
              "│ FCNTX        ┆ 67066G10  ┆ cusip8        ┆ 2026-01-01 ┆ null     ┆ null      ┆ 1.0  │\n",
              "│ …            ┆ …         ┆ …             ┆ …          ┆ …        ┆ …         ┆ …    │\n",
              "│ SPX          ┆ 2588173   ┆ sedol7        ┆ 2026-01-31 ┆ null     ┆ null      ┆ 0.2  │\n",
              "│ SPX          ┆ 67066G10  ┆ cusip8        ┆ 2026-01-01 ┆ null     ┆ null      ┆ 0.3  │\n",
              "│ SPX          ┆ 67066G10  ┆ cusip8        ┆ 2026-01-31 ┆ null     ┆ null      ┆ 0.25 │\n",
              "│ SPX          ┆ 85371710  ┆ cusip8        ┆ 2026-01-01 ┆ null     ┆ null      ┆ 0.3  │\n",
              "│ SPX          ┆ 85371710  ┆ cusip8        ┆ 2026-01-31 ┆ null     ┆ null      ┆ 0.25 │\n",
              "└──────────────┴───────────┴───────────────┴────────────┴──────────┴───────────┴──────┘"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "portfolio_df = pl.DataFrame({\n",
        "    \"portfolio_id\": [\n",
        "        \"AGTHX\", \"AGTHX\", \"AGTHX\", \"AGTHX\",\n",
        "        \"FCNTX\", \"FCNTX\",\n",
        "        \"VADGX\", \"VADGX\", \"VADGX\", \"VADGX\", \"VADGX\", \"VADGX\",\n",
        "        \"SPX\", \"SPX\", \"SPX\", \"SPX\", \"SPX\", \"SPX\", \"SPX\", \"SPX\",\n",
        "    ],\n",
        "    \"asset_id\": [\n",
        "        # AGTHX\n",
        "        \"02079K305\", \"02079K305\", \n",
        "        \"2588173\", \"2588173\",\n",
        "\n",
        "        # FCNTX\n",
        "        \"67066G10\", \"67066G10\",\n",
        "\n",
        "        # VADGX\n",
        "        \"02079K305\", \"02079K305\", \n",
        "        \"2588173\", \"2588173\", \n",
        "        \"67066G10\", \"67066G10\",\n",
        "\n",
        "        # SPX\n",
        "        \"02079K305\", \"02079K305\", \n",
        "        \"2588173\", \"2588173\",\n",
        "        \"67066G10\", \"67066G10\",\n",
        "        \"85371710\", \"85371710\",\n",
        "\n",
        "    ],  \n",
        "    \"asset_id_type\": [\n",
        "        # AGTHX\n",
        "        \"cusip9\", \"cusip9\", \"sedol7\", \"sedol7\",\n",
        "\n",
        "        # FCNTX\n",
        "        \"cusip8\", \"cusip8\",\n",
        "\n",
        "        # VADGX\n",
        "        \"cusip9\", \"cusip9\", \"sedol7\", \"sedol7\", \"cusip8\", \"cusip8\",\n",
        "\n",
        "        # SPX\n",
        "        \"cusip9\", \"cusip9\", \"sedol7\", \"sedol7\", \"cusip8\", \"cusip8\", \"cusip8\", \"cusip8\",\n",
        "        \n",
        "    ],\n",
        "    \"date\": [\n",
        "        # AGTHX\n",
        "        dt.date(2026, 1, 1), dt.date(2026, 1, 31), \n",
        "        dt.date(2026, 1, 1), dt.date(2026, 1, 31),\n",
        "\n",
        "        # FCNTX\n",
        "        dt.date(2026, 1, 1), dt.date(2026, 1, 31),\n",
        "\n",
        "        # VADGX\n",
        "        dt.date(2026, 1, 1), dt.date(2026, 1, 31), \n",
        "        dt.date(2026, 1, 1), dt.date(2026, 1, 31), \n",
        "        dt.date(2026, 1, 1), dt.date(2026, 1, 31), \n",
        "        \n",
        "        # SPX\n",
        "        dt.date(2026, 1, 1), dt.date(2026, 1, 31), \n",
        "        dt.date(2026, 1, 1), dt.date(2026, 1, 31), \n",
        "        dt.date(2026, 1, 1), dt.date(2026, 1, 31), \n",
        "        dt.date(2026, 1, 1), dt.date(2026, 1, 31), \n",
        "    ],\n",
        "    \"currency\": [None] * 20,\n",
        "    \"share_qty\": [None] * 20,\n",
        "    \"nav\": [\n",
        "        # AGTHX\n",
        "        0.5, 0.55, \n",
        "        0.5, 0.45,\n",
        "\n",
        "        # FCNTX\n",
        "        1.0, 1.0,\n",
        "\n",
        "        # VADGX\n",
        "        0.3, 0.5, \n",
        "        0.4, 0.2,\n",
        "        0.3, 0.25,\n",
        "\n",
        "        # SPX\n",
        "        0.3, 0.3, \n",
        "        0.4, 0.2,\n",
        "        0.3, 0.25,\n",
        "        0.3, 0.25,\n",
        "    ],\n",
        "}).with_columns(pl.col(\"currency\").cast(pl.String), pl.col(\"share_qty\").cast(pl.Float64))\n",
        "\n",
        "portfolio_df"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "6d9c52b2",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "UploadCommitResult(version=1, committed_names=[])"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "uploader.fast_commit(portfolio_df, mode=\"append\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bf0f9d81",
      "metadata": {},
      "source": [
        "### Hierarchy with only Portfolios \n",
        "\n",
        "Next up we create a portfolio hierarchy with only two of the portfolios we created. This is the first use case of the hierarchy, to subset a larger source of portfolios to only those that are relevant for a specific analysis.\n",
        "\n",
        "Note that the `portfolio_ids` must be unique for a hierarchy to be valid."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "becec711",
      "metadata": {},
      "outputs": [],
      "source": [
        "ph_settings = PortfolioHierarchySettings.from_source(\n",
        "    source=\"portfolio-hierarchies-demo\",\n",
        "    portfolio_ids=[\"AGTHX\", \"SPX\"],\n",
        ")\n",
        "\n",
        "ph_api = ph_loader.load(ph_settings.with_dataset(\"bayesline/Bayesline-US-All-1y\"))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "69474038",
      "metadata": {},
      "source": [
        "Below we obtain holdings data for our setup and we find that:\n",
        "\n",
        "1. Only our two specified portfolios are present\n",
        "2. The values have been forward filled and drift corrected\n",
        "3. The benchmark is unset (as specified)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "7e8b4fc4",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div><style>\n",
              ".dataframe > thead > tr,\n",
              ".dataframe > tbody > tr {\n",
              "  text-align: right;\n",
              "  white-space: pre-wrap;\n",
              "}\n",
              "</style>\n",
              "<small>shape: (100, 10)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>date</th><th>portfolio_group</th><th>portfolio_id</th><th>input_asset_id_type</th><th>input_asset_id</th><th>asset_id_type</th><th>asset_id</th><th>currency</th><th>nav</th><th>nav_bench</th></tr><tr><td>date</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>f32</td><td>f32</td></tr></thead><tbody><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.503434</td><td>null</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.488958</td><td>null</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.302061</td><td>null</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.391166</td><td>null</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;cusip8&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;IC46D464E0&quot;</td><td>&quot;USD&quot;</td><td>0.30378</td><td>null</td></tr><tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.539936</td><td>null</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.444864</td><td>null</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.323962</td><td>null</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.355891</td><td>null</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;cusip8&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;IC46D464E0&quot;</td><td>&quot;USD&quot;</td><td>0.307448</td><td>null</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (100, 10)\n",
              "┌────────────┬───────────┬───────────┬───────────┬───┬───────────┬──────────┬──────────┬───────────┐\n",
              "│ date       ┆ portfolio ┆ portfolio ┆ input_ass ┆ … ┆ asset_id  ┆ currency ┆ nav      ┆ nav_bench │\n",
              "│ ---        ┆ _group    ┆ _id       ┆ et_id_typ ┆   ┆ ---       ┆ ---      ┆ ---      ┆ ---       │\n",
              "│ date       ┆ ---       ┆ ---       ┆ e         ┆   ┆ str       ┆ str      ┆ f32      ┆ f32       │\n",
              "│            ┆ str       ┆ str       ┆ ---       ┆   ┆           ┆          ┆          ┆           │\n",
              "│            ┆           ┆           ┆ str       ┆   ┆           ┆          ┆          ┆           │\n",
              "╞════════════╪═══════════╪═══════════╪═══════════╪═══╪═══════════╪══════════╪══════════╪═══════════╡\n",
              "│ 2026-01-02 ┆ portfolio ┆ AGTHX     ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.503434 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ AGTHX     ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.488958 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ SPX       ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.302061 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ SPX       ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.391166 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ SPX       ┆ cusip8    ┆ … ┆ IC46D464E ┆ USD      ┆ 0.30378  ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 0         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ …          ┆ …         ┆ …         ┆ …         ┆ … ┆ …         ┆ …        ┆ …        ┆ …         │\n",
              "│ 2026-01-30 ┆ portfolio ┆ AGTHX     ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.539936 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ AGTHX     ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.444864 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ SPX       ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.323962 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ SPX       ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.355891 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ SPX       ┆ cusip8    ┆ … ┆ IC46D464E ┆ USD      ┆ 0.307448 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 0         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "└────────────┴───────────┴───────────┴───────────┴───┴───────────┴──────────┴──────────┴───────────┘"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ph_api.get(start_date=dt.date(2026, 1, 1), end_date=dt.date(2026, 1, 31))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7ac4d078",
      "metadata": {},
      "source": [
        "### Adding Benchmarks\n",
        "\n",
        "We can add a benchmark to our hierarchy which will populate the benchmark column. Note that we can selectively specify a benchmark, for instance we could benchmark `AGTHX` against `SPX` but leave `SPX` itself unbenchmarked."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "9a0b6f01",
      "metadata": {},
      "outputs": [],
      "source": [
        "ph_settings = PortfolioHierarchySettings.from_source(\n",
        "    source=\"portfolio-hierarchies-demo\",\n",
        "    portfolio_ids=[\"AGTHX\", \"SPX\"],\n",
        "    benchmark_ids=[\"SPX\", None],\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "b718c43b",
      "metadata": {},
      "outputs": [],
      "source": [
        "ph_api = ph_loader.load(ph_settings.with_dataset(\"bayesline/Bayesline-US-All-1y\"))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f3cbd5e1",
      "metadata": {},
      "source": [
        "Note that the `null` observations are cases where either portfolio or benchmark as a holding but the other does not (in its respective id space)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "55a49e13",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div><style>\n",
              ".dataframe > thead > tr,\n",
              ".dataframe > tbody > tr {\n",
              "  text-align: right;\n",
              "  white-space: pre-wrap;\n",
              "}\n",
              "</style>\n",
              "<small>shape: (120, 10)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>date</th><th>portfolio_group</th><th>portfolio_id</th><th>input_asset_id_type</th><th>input_asset_id</th><th>asset_id_type</th><th>asset_id</th><th>currency</th><th>nav</th><th>nav_bench</th></tr><tr><td>date</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>f32</td><td>f32</td></tr></thead><tbody><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.503434</td><td>0.302061</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.488958</td><td>0.391166</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;cusip8&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;IC46D464E0&quot;</td><td>&quot;USD&quot;</td><td>0.0</td><td>0.30378</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.302061</td><td>null</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.391166</td><td>null</td></tr><tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.444864</td><td>0.355891</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;cusip8&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;IC46D464E0&quot;</td><td>&quot;USD&quot;</td><td>0.0</td><td>0.307448</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.323962</td><td>null</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.355891</td><td>null</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;cusip8&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;IC46D464E0&quot;</td><td>&quot;USD&quot;</td><td>0.307448</td><td>null</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (120, 10)\n",
              "┌────────────┬───────────┬───────────┬───────────┬───┬───────────┬──────────┬──────────┬───────────┐\n",
              "│ date       ┆ portfolio ┆ portfolio ┆ input_ass ┆ … ┆ asset_id  ┆ currency ┆ nav      ┆ nav_bench │\n",
              "│ ---        ┆ _group    ┆ _id       ┆ et_id_typ ┆   ┆ ---       ┆ ---      ┆ ---      ┆ ---       │\n",
              "│ date       ┆ ---       ┆ ---       ┆ e         ┆   ┆ str       ┆ str      ┆ f32      ┆ f32       │\n",
              "│            ┆ str       ┆ str       ┆ ---       ┆   ┆           ┆          ┆          ┆           │\n",
              "│            ┆           ┆           ┆ str       ┆   ┆           ┆          ┆          ┆           │\n",
              "╞════════════╪═══════════╪═══════════╪═══════════╪═══╪═══════════╪══════════╪══════════╪═══════════╡\n",
              "│ 2026-01-02 ┆ portfolio ┆ AGTHX     ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.503434 ┆ 0.302061  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ AGTHX     ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.488958 ┆ 0.391166  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ AGTHX     ┆ cusip8    ┆ … ┆ IC46D464E ┆ USD      ┆ 0.0      ┆ 0.30378   │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 0         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ SPX       ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.302061 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ SPX       ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.391166 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ …          ┆ …         ┆ …         ┆ …         ┆ … ┆ …         ┆ …        ┆ …        ┆ …         │\n",
              "│ 2026-01-30 ┆ portfolio ┆ AGTHX     ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.444864 ┆ 0.355891  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ AGTHX     ┆ cusip8    ┆ … ┆ IC46D464E ┆ USD      ┆ 0.0      ┆ 0.307448  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 0         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ SPX       ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.323962 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ SPX       ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.355891 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ SPX       ┆ cusip8    ┆ … ┆ IC46D464E ┆ USD      ┆ 0.307448 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 0         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "└────────────┴───────────┴───────────┴───────────┴───┴───────────┴──────────┴──────────┴───────────┘"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ph_api.get(start_date=dt.date(2026, 1, 1), end_date=dt.date(2026, 1, 31))"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9ae4e6bc",
      "metadata": {},
      "source": [
        "We can pass one of the supported output id types to map ids on the fly."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "7d853b46",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{'AGTHX': ['bayesid'], 'SPX': ['bayesid']}"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ph_api.get_id_types()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "19690c33",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div><style>\n",
              ".dataframe > thead > tr,\n",
              ".dataframe > tbody > tr {\n",
              "  text-align: right;\n",
              "  white-space: pre-wrap;\n",
              "}\n",
              "</style>\n",
              "<small>shape: (120, 10)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>date</th><th>portfolio_group</th><th>portfolio_id</th><th>input_asset_id_type</th><th>input_asset_id</th><th>asset_id_type</th><th>asset_id</th><th>currency</th><th>nav</th><th>nav_bench</th></tr><tr><td>date</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>f32</td><td>f32</td></tr></thead><tbody><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.503434</td><td>0.302061</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.488958</td><td>0.391166</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;cusip8&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;IC46D464E0&quot;</td><td>&quot;USD&quot;</td><td>0.0</td><td>0.30378</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.302061</td><td>null</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.391166</td><td>null</td></tr><tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.444864</td><td>0.355891</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;cusip8&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;IC46D464E0&quot;</td><td>&quot;USD&quot;</td><td>0.0</td><td>0.307448</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.323962</td><td>null</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.355891</td><td>null</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;SPX&quot;</td><td>&quot;cusip8&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;IC46D464E0&quot;</td><td>&quot;USD&quot;</td><td>0.307448</td><td>null</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (120, 10)\n",
              "┌────────────┬───────────┬───────────┬───────────┬───┬───────────┬──────────┬──────────┬───────────┐\n",
              "│ date       ┆ portfolio ┆ portfolio ┆ input_ass ┆ … ┆ asset_id  ┆ currency ┆ nav      ┆ nav_bench │\n",
              "│ ---        ┆ _group    ┆ _id       ┆ et_id_typ ┆   ┆ ---       ┆ ---      ┆ ---      ┆ ---       │\n",
              "│ date       ┆ ---       ┆ ---       ┆ e         ┆   ┆ str       ┆ str      ┆ f32      ┆ f32       │\n",
              "│            ┆ str       ┆ str       ┆ ---       ┆   ┆           ┆          ┆          ┆           │\n",
              "│            ┆           ┆           ┆ str       ┆   ┆           ┆          ┆          ┆           │\n",
              "╞════════════╪═══════════╪═══════════╪═══════════╪═══╪═══════════╪══════════╪══════════╪═══════════╡\n",
              "│ 2026-01-02 ┆ portfolio ┆ AGTHX     ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.503434 ┆ 0.302061  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ AGTHX     ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.488958 ┆ 0.391166  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ AGTHX     ┆ cusip8    ┆ … ┆ IC46D464E ┆ USD      ┆ 0.0      ┆ 0.30378   │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 0         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ SPX       ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.302061 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ SPX       ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.391166 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ …          ┆ …         ┆ …         ┆ …         ┆ … ┆ …         ┆ …        ┆ …        ┆ …         │\n",
              "│ 2026-01-30 ┆ portfolio ┆ AGTHX     ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.444864 ┆ 0.355891  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ AGTHX     ┆ cusip8    ┆ … ┆ IC46D464E ┆ USD      ┆ 0.0      ┆ 0.307448  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 0         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ SPX       ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.323962 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ SPX       ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.355891 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ SPX       ┆ cusip8    ┆ … ┆ IC46D464E ┆ USD      ┆ 0.307448 ┆ null      │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 0         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "└────────────┴───────────┴───────────┴───────────┴───┴───────────┴──────────┴──────────┴───────────┘"
            ]
          },
          "execution_count": 13,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ph_api.get(start_date=dt.date(2026, 1, 1), end_date=dt.date(2026, 1, 31), id_type=\"bayesid\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a3c627be",
      "metadata": {},
      "source": [
        "### Adding Additional Groupings\n",
        "\n",
        "We can add additional groupings that downstream can be used to provide additional aggregations for these groupings. For instance we might assign portfolios to managers or a specific investment style.\n",
        "\n",
        "Below we're assigning hypothetical managers *Alex* and *Joanna*. Note that these groupings have no effect on the output of the `ph_loader.get` method but they are picked up downstream by the *Reports API*."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "0c284c4c",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div><style>\n",
              ".dataframe > thead > tr,\n",
              ".dataframe > tbody > tr {\n",
              "  text-align: right;\n",
              "  white-space: pre-wrap;\n",
              "}\n",
              "</style>\n",
              "<small>shape: (3, 3)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>Manager</th><th>portfolio_id</th><th>benchmark_id</th></tr><tr><td>str</td><td>str</td><td>str</td></tr></thead><tbody><tr><td>&quot;Alice&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;SPX&quot;</td></tr><tr><td>&quot;Bob&quot;</td><td>&quot;FCNTX&quot;</td><td>&quot;SPX&quot;</td></tr><tr><td>&quot;Charlie&quot;</td><td>&quot;VADGX&quot;</td><td>&quot;VADGX&quot;</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (3, 3)\n",
              "┌─────────┬──────────────┬──────────────┐\n",
              "│ Manager ┆ portfolio_id ┆ benchmark_id │\n",
              "│ ---     ┆ ---          ┆ ---          │\n",
              "│ str     ┆ str          ┆ str          │\n",
              "╞═════════╪══════════════╪══════════════╡\n",
              "│ Alice   ┆ AGTHX        ┆ SPX          │\n",
              "│ Bob     ┆ FCNTX        ┆ SPX          │\n",
              "│ Charlie ┆ VADGX        ┆ VADGX        │\n",
              "└─────────┴──────────────┴──────────────┘"
            ]
          },
          "execution_count": 14,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ph_settings = PortfolioHierarchySettings.from_source(\n",
        "    source=\"portfolio-hierarchies-demo\",\n",
        "    portfolio_ids=[\"AGTHX\", \"FCNTX\", \"VADGX\"],\n",
        "    benchmark_ids=[\"SPX\", \"SPX\", \"VADGX\"],\n",
        "    groupings={\"Manager\": [\"Alice\", \"Bob\", \"Charlie\"]},\n",
        ")\n",
        "\n",
        "\n",
        "ph_settings.to_polars()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "263a0087",
      "metadata": {},
      "source": [
        "### Creating from Polars\n",
        "\n",
        "As a shorthand it might be more convenient to create a hierarchy from a data frame instead of manually specifying the Pydantic object."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "677ddb9f",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div><style>\n",
              ".dataframe > thead > tr,\n",
              ".dataframe > tbody > tr {\n",
              "  text-align: right;\n",
              "  white-space: pre-wrap;\n",
              "}\n",
              "</style>\n",
              "<small>shape: (3, 3)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>Manager</th><th>portfolio_id</th><th>benchmark_id</th></tr><tr><td>str</td><td>str</td><td>str</td></tr></thead><tbody><tr><td>&quot;Alice&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;SPX&quot;</td></tr><tr><td>&quot;Bob&quot;</td><td>&quot;FCNTX&quot;</td><td>&quot;SPX&quot;</td></tr><tr><td>&quot;Charlie&quot;</td><td>&quot;VADGX&quot;</td><td>&quot;VADGX&quot;</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (3, 3)\n",
              "┌─────────┬──────────────┬──────────────┐\n",
              "│ Manager ┆ portfolio_id ┆ benchmark_id │\n",
              "│ ---     ┆ ---          ┆ ---          │\n",
              "│ str     ┆ str          ┆ str          │\n",
              "╞═════════╪══════════════╪══════════════╡\n",
              "│ Alice   ┆ AGTHX        ┆ SPX          │\n",
              "│ Bob     ┆ FCNTX        ┆ SPX          │\n",
              "│ Charlie ┆ VADGX        ┆ VADGX        │\n",
              "└─────────┴──────────────┴──────────────┘"
            ]
          },
          "execution_count": 15,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ph_settings_df = ph_settings.to_polars()\n",
        "\n",
        "ph_settings_df"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "253f7758",
      "metadata": {},
      "outputs": [],
      "source": [
        "ph_settings = PortfolioHierarchySettings.from_polars(\n",
        "    ph_settings_df, \n",
        "    portfolio_source=\"portfolio-hierarchies-demo\",\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "00e76272",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div><style>\n",
              ".dataframe > thead > tr,\n",
              ".dataframe > tbody > tr {\n",
              "  text-align: right;\n",
              "  white-space: pre-wrap;\n",
              "}\n",
              "</style>\n",
              "<small>shape: (180, 10)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>date</th><th>portfolio_group</th><th>portfolio_id</th><th>input_asset_id_type</th><th>input_asset_id</th><th>asset_id_type</th><th>asset_id</th><th>currency</th><th>nav</th><th>nav_bench</th></tr><tr><td>date</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>f32</td><td>f32</td></tr></thead><tbody><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.503434</td><td>0.302061</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.488958</td><td>0.391166</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;cusip8&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;IC46D464E0&quot;</td><td>&quot;USD&quot;</td><td>0.0</td><td>0.30378</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;FCNTX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.0</td><td>0.302061</td></tr><tr><td>2026-01-02</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;FCNTX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.0</td><td>0.391166</td></tr><tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;FCNTX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.0</td><td>0.355891</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;FCNTX&quot;</td><td>&quot;cusip8&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;IC46D464E0&quot;</td><td>&quot;USD&quot;</td><td>1.024826</td><td>0.307448</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;VADGX&quot;</td><td>&quot;cusip9&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICA17F00B9&quot;</td><td>&quot;USD&quot;</td><td>0.323962</td><td>0.323962</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;VADGX&quot;</td><td>&quot;sedol7&quot;</td><td>&quot;2588173&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;ICF982536B&quot;</td><td>&quot;USD&quot;</td><td>0.355891</td><td>0.355891</td></tr><tr><td>2026-01-30</td><td>&quot;portfolio-hierarchies-demo&quot;</td><td>&quot;VADGX&quot;</td><td>&quot;cusip8&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;bayesid&quot;</td><td>&quot;IC46D464E0&quot;</td><td>&quot;USD&quot;</td><td>0.307448</td><td>0.307448</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (180, 10)\n",
              "┌────────────┬───────────┬───────────┬───────────┬───┬───────────┬──────────┬──────────┬───────────┐\n",
              "│ date       ┆ portfolio ┆ portfolio ┆ input_ass ┆ … ┆ asset_id  ┆ currency ┆ nav      ┆ nav_bench │\n",
              "│ ---        ┆ _group    ┆ _id       ┆ et_id_typ ┆   ┆ ---       ┆ ---      ┆ ---      ┆ ---       │\n",
              "│ date       ┆ ---       ┆ ---       ┆ e         ┆   ┆ str       ┆ str      ┆ f32      ┆ f32       │\n",
              "│            ┆ str       ┆ str       ┆ ---       ┆   ┆           ┆          ┆          ┆           │\n",
              "│            ┆           ┆           ┆ str       ┆   ┆           ┆          ┆          ┆           │\n",
              "╞════════════╪═══════════╪═══════════╪═══════════╪═══╪═══════════╪══════════╪══════════╪═══════════╡\n",
              "│ 2026-01-02 ┆ portfolio ┆ AGTHX     ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.503434 ┆ 0.302061  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ AGTHX     ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.488958 ┆ 0.391166  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ AGTHX     ┆ cusip8    ┆ … ┆ IC46D464E ┆ USD      ┆ 0.0      ┆ 0.30378   │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 0         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ FCNTX     ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.0      ┆ 0.302061  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-02 ┆ portfolio ┆ FCNTX     ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.0      ┆ 0.391166  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ …          ┆ …         ┆ …         ┆ …         ┆ … ┆ …         ┆ …        ┆ …        ┆ …         │\n",
              "│ 2026-01-30 ┆ portfolio ┆ FCNTX     ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.0      ┆ 0.355891  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ FCNTX     ┆ cusip8    ┆ … ┆ IC46D464E ┆ USD      ┆ 1.024826 ┆ 0.307448  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 0         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ VADGX     ┆ cusip9    ┆ … ┆ ICA17F00B ┆ USD      ┆ 0.323962 ┆ 0.323962  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 9         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ VADGX     ┆ sedol7    ┆ … ┆ ICF982536 ┆ USD      ┆ 0.355891 ┆ 0.355891  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ B         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "│ 2026-01-30 ┆ portfolio ┆ VADGX     ┆ cusip8    ┆ … ┆ IC46D464E ┆ USD      ┆ 0.307448 ┆ 0.307448  │\n",
              "│            ┆ -hierarch ┆           ┆           ┆   ┆ 0         ┆          ┆          ┆           │\n",
              "│            ┆ ies-demo  ┆           ┆           ┆   ┆           ┆          ┆          ┆           │\n",
              "└────────────┴───────────┴───────────┴───────────┴───┴───────────┴──────────┴──────────┴───────────┘"
            ]
          },
          "execution_count": 17,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ph_api = ph_loader.load(ph_settings.with_dataset(\"bayesline/Bayesline-US-All-1y\"))\n",
        "\n",
        "ph_api.get(start_date=dt.date(2026, 1, 1), end_date=dt.date(2026, 1, 31))"
      ]
    }
  ],
  "metadata": {
    "jupytext": {
      "text_representation": {
        "extension": ".py",
        "format_name": "percent",
        "format_version": "1.3",
        "jupytext_version": "1.19.3"
      }
    },
    "kernelspec": {
      "display_name": ".venv",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.15"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}