{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "50635b8f",
      "metadata": {},
      "source": [
        "# Factor Attribution\n",
        "\n",
        "In this tutorial we are going to show how to run a factor-based attribution (return and risk) using the Reporting API. This API is currently under active development.\n",
        "\n",
        "The steps are as follows:\n",
        "- Uploading a set of portfolios\n",
        "- Organizing the portfolios into a hierarchy\n",
        "- Creating a factor model\n",
        "- Running a factor return attribution report\n",
        "- Pulling out different aggregations and drill-downs\n",
        "- Running a factor risk attribution report"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7c709920",
      "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": "90936ecc",
      "metadata": {},
      "outputs": [],
      "source": [
        "import datetime as dt\n",
        "import polars as pl\n",
        "\n",
        "from bayesline.apiclient import BayeslineApiClient\n",
        "from bayesline.api.equity import (\n",
        "    FactorRiskModelSettings,\n",
        "    UniverseSettings,\n",
        "    ExposureSettings,\n",
        "    ContinuousExposureGroupSettings,\n",
        "    CategoricalExposureGroupSettings,\n",
        "    ModelConstructionSettings,\n",
        "    PortfolioHierarchySettings,\n",
        "    ReturnAttributionReportSettingsV2,\n",
        "    XSRReportSettingsV2,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a4fa0e5d",
      "metadata": {},
      "source": [
        "We will also need to have a Bayesline API client configured."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "d3c3ce1c",
      "metadata": {
        "tags": [
          "skip-execution"
        ]
      },
      "outputs": [],
      "source": [
        "bln = BayeslineApiClient.new_client(\n",
        "    endpoint=\"https://[ENDPOINT]\",\n",
        "    api_key=\"[API-KEY]\",\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d6473290",
      "metadata": {},
      "source": [
        "We will first upload a portfolio and set a hierarchy. The steps followed here are the same as in the [Portfolio Hierarchies Tutorial](https://docs.bayesline.com/0.12.1/notebooks/tutorial_portfolio_hierarchies.html)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "19d6711f",
      "metadata": {},
      "outputs": [],
      "source": [
        "uploader = bln.equity.uploaders.get_data_type(\"portfolios\").create_or_replace_dataset(\"portfolio-attribution-demo\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "27a5ada2",
      "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": 4,
          "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": 5,
      "id": "feb75d1c",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "UploadCommitResult(version=1, committed_names=[])"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "uploader.fast_commit(portfolio_df, mode=\"append\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "265b9020",
      "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: (4, 5)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>fund</th><th>book</th><th>ticker</th><th>portfolio_id</th><th>benchmark_id</th></tr><tr><td>str</td><td>str</td><td>str</td><td>str</td><td>null</td></tr></thead><tbody><tr><td>&quot;some_fund&quot;</td><td>&quot;book_1&quot;</td><td>&quot;AGTHX&quot;</td><td>&quot;AGTHX&quot;</td><td>null</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;book_1&quot;</td><td>&quot;FCNTX&quot;</td><td>&quot;FCNTX&quot;</td><td>null</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;book_2&quot;</td><td>&quot;VADGX&quot;</td><td>&quot;VADGX&quot;</td><td>null</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;book_2&quot;</td><td>&quot;SPX&quot;</td><td>&quot;SPX&quot;</td><td>null</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (4, 5)\n",
              "┌───────────┬────────┬────────┬──────────────┬──────────────┐\n",
              "│ fund      ┆ book   ┆ ticker ┆ portfolio_id ┆ benchmark_id │\n",
              "│ ---       ┆ ---    ┆ ---    ┆ ---          ┆ ---          │\n",
              "│ str       ┆ str    ┆ str    ┆ str          ┆ null         │\n",
              "╞═══════════╪════════╪════════╪══════════════╪══════════════╡\n",
              "│ some_fund ┆ book_1 ┆ AGTHX  ┆ AGTHX        ┆ null         │\n",
              "│ some_fund ┆ book_1 ┆ FCNTX  ┆ FCNTX        ┆ null         │\n",
              "│ some_fund ┆ book_2 ┆ VADGX  ┆ VADGX        ┆ null         │\n",
              "│ some_fund ┆ book_2 ┆ SPX    ┆ SPX          ┆ null         │\n",
              "└───────────┴────────┴────────┴──────────────┴──────────────┘"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "portfolio_hierarchy_df = pl.DataFrame(\n",
        "    {\n",
        "        \"fund\": [\"some_fund\", \"some_fund\", \"some_fund\", \"some_fund\"],\n",
        "        \"book\": [\"book_1\", \"book_1\", \"book_2\", \"book_2\"],\n",
        "        \"ticker\": [\"AGTHX\", \"FCNTX\", \"VADGX\", \"SPX\"],\n",
        "        \"portfolio_id\": [\"AGTHX\", \"FCNTX\", \"VADGX\", \"SPX\"],\n",
        "    }\n",
        ")\n",
        "portfoliohierarchy_settings = PortfolioHierarchySettings.from_polars(\n",
        "    portfolio_hierarchy_df, \n",
        "    portfolio_source=\"portfolio-attribution-demo\", \n",
        "    dataset=\"Bayesline-US-All-1y\",\n",
        ")\n",
        "portfoliohierarchy_settings.to_polars()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4bf4999a",
      "metadata": {},
      "source": [
        "Now that we have the portfolio hiearachy in place, we define a basic factor model."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "349dea55",
      "metadata": {},
      "outputs": [],
      "source": [
        "factorriskmodel_settings = FactorRiskModelSettings(\n",
        "    universe=UniverseSettings(dataset=\"Bayesline-US-All-1y\"),\n",
        "    exposures=ExposureSettings(\n",
        "        exposures=[\n",
        "            ContinuousExposureGroupSettings(hierarchy=\"market\"),\n",
        "            CategoricalExposureGroupSettings(hierarchy=\"trbc\"),\n",
        "            ContinuousExposureGroupSettings(hierarchy=\"style\"),\n",
        "        ]\n",
        "    ),\n",
        "    modelconstruction=ModelConstructionSettings(\n",
        "        estimation_universe=None,\n",
        "        zero_sum_constraints={\"trbc\": \"mcap_weighted\"}\n",
        "    ),\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b37a35a0",
      "metadata": {},
      "source": [
        "We then define and load the report. We have different multi-period aggregation settings available, which we do not go into here."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "a25fd49a",
      "metadata": {},
      "outputs": [],
      "source": [
        "report_settings = ReturnAttributionReportSettingsV2(\n",
        "    portfolio_hierarchy_settings=portfoliohierarchy_settings,\n",
        "    factor_model_settings=factorriskmodel_settings,\n",
        "    normalize_holdings=False, \n",
        "    return_aggregation_type=\"arithmetic\",\n",
        ")\n",
        "report_engine = bln.equity.reports.load(report_settings)\n",
        "report = report_engine.calculate(start_date=\"2026-01-05\", end_date=\"2026-01-30\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d1338c47",
      "metadata": {},
      "source": [
        "Let's first look at the return attribution from all sources at the ticker level (recall that ticker is defined in the portfolio hierarchy). For a specific ticker, we want to know the return attribution to different assets at each date."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "6153f7a6",
      "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: (76, 4)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>ticker</th><th>date</th><th>input_asset_id</th><th>PnL</th></tr><tr><td>str</td><td>date</td><td>str</td><td>f32</td></tr></thead><tbody><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;02079K305&quot;</td><td>0.002221</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;2588173&quot;</td><td>-0.000093</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;67066G10&quot;</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;85371710&quot;</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-06</td><td>&quot;02079K305&quot;</td><td>-0.003514</td></tr><tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-29</td><td>&quot;85371710&quot;</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-30</td><td>&quot;02079K305&quot;</td><td>-0.000399</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-30</td><td>&quot;2588173&quot;</td><td>-0.003319</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-30</td><td>&quot;67066G10&quot;</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-30</td><td>&quot;85371710&quot;</td><td>0.0</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (76, 4)\n",
              "┌────────┬────────────┬────────────────┬───────────┐\n",
              "│ ticker ┆ date       ┆ input_asset_id ┆ PnL       │\n",
              "│ ---    ┆ ---        ┆ ---            ┆ ---       │\n",
              "│ str    ┆ date       ┆ str            ┆ f32       │\n",
              "╞════════╪════════════╪════════════════╪═══════════╡\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ 02079K305      ┆ 0.002221  │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ 2588173        ┆ -0.000093 │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ 67066G10       ┆ 0.0       │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ 85371710       ┆ 0.0       │\n",
              "│ AGTHX  ┆ 2026-01-06 ┆ 02079K305      ┆ -0.003514 │\n",
              "│ …      ┆ …          ┆ …              ┆ …         │\n",
              "│ AGTHX  ┆ 2026-01-29 ┆ 85371710       ┆ 0.0       │\n",
              "│ AGTHX  ┆ 2026-01-30 ┆ 02079K305      ┆ -0.000399 │\n",
              "│ AGTHX  ┆ 2026-01-30 ┆ 2588173        ┆ -0.003319 │\n",
              "│ AGTHX  ┆ 2026-01-30 ┆ 67066G10       ┆ 0.0       │\n",
              "│ AGTHX  ┆ 2026-01-30 ┆ 85371710       ┆ 0.0       │\n",
              "└────────┴────────────┴────────────────┴───────────┘"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# for a specific ticker, the return attribution across dates and assets\n",
        "(\n",
        "    report.accessor.get_data(\n",
        "        [(\"ticker\", \"AGTHX\")],  # filters: [ticker=AGTHX]\n",
        "        expand=(\"date\", \"input_asset_id\",), # combinations define the rows\n",
        "        value_cols=(\"PnL\",),  # exclude benchmark / active\n",
        "    )\n",
        "    .select(\"ticker\", \"date\", \"input_asset_id\", \"PnL\")\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "155d459d",
      "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: (76, 4)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>ticker</th><th>date</th><th>input_asset_id</th><th>PnL</th></tr><tr><td>str</td><td>date</td><td>str</td><td>f32</td></tr></thead><tbody><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;02079K305&quot;</td><td>0.002221</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;2588173&quot;</td><td>-0.000093</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;67066G10&quot;</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;85371710&quot;</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-06</td><td>&quot;02079K305&quot;</td><td>-0.003514</td></tr><tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-29</td><td>&quot;85371710&quot;</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-30</td><td>&quot;02079K305&quot;</td><td>-0.000399</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-30</td><td>&quot;2588173&quot;</td><td>-0.003319</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-30</td><td>&quot;67066G10&quot;</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-30</td><td>&quot;85371710&quot;</td><td>0.0</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (76, 4)\n",
              "┌────────┬────────────┬────────────────┬───────────┐\n",
              "│ ticker ┆ date       ┆ input_asset_id ┆ PnL       │\n",
              "│ ---    ┆ ---        ┆ ---            ┆ ---       │\n",
              "│ str    ┆ date       ┆ str            ┆ f32       │\n",
              "╞════════╪════════════╪════════════════╪═══════════╡\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ 02079K305      ┆ 0.002221  │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ 2588173        ┆ -0.000093 │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ 67066G10       ┆ 0.0       │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ 85371710       ┆ 0.0       │\n",
              "│ AGTHX  ┆ 2026-01-06 ┆ 02079K305      ┆ -0.003514 │\n",
              "│ …      ┆ …          ┆ …              ┆ …         │\n",
              "│ AGTHX  ┆ 2026-01-29 ┆ 85371710       ┆ 0.0       │\n",
              "│ AGTHX  ┆ 2026-01-30 ┆ 02079K305      ┆ -0.000399 │\n",
              "│ AGTHX  ┆ 2026-01-30 ┆ 2588173        ┆ -0.003319 │\n",
              "│ AGTHX  ┆ 2026-01-30 ┆ 67066G10       ┆ 0.0       │\n",
              "│ AGTHX  ┆ 2026-01-30 ┆ 85371710       ┆ 0.0       │\n",
              "└────────┴────────────┴────────────────┴───────────┘"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# for a specific ticker, the return attribution across dates and assets\n",
        "(\n",
        "    report.accessor.get_data(\n",
        "        [(\"ticker\", \"AGTHX\")],  # filters: [ticker=AGTHX]\n",
        "        expand=(\"date\", \"input_asset_id\",), # combinations define the rows\n",
        "        value_cols=(\"PnL\",),  # exclude benchmark / active\n",
        "    )\n",
        "    .select(\"ticker\", \"date\", \"input_asset_id\", \"PnL\")\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8926e0ee",
      "metadata": {},
      "source": [
        "Using different settings, we can split out the returns across all sources (factors and idio) at a different level. Below we show the returns on a specific date, for a specific book, split out by factor."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "e2b0ecca",
      "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: (22, 6)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>date</th><th>book</th><th>type</th><th>factor_group</th><th>factor</th><th>PnL</th></tr><tr><td>date</td><td>str</td><td>str</td><td>str</td><td>str</td><td>f32</td></tr></thead><tbody><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;market&quot;</td><td>&quot;Market&quot;</td><td>0.01711</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Dividend&quot;</td><td>0.001105</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Growth&quot;</td><td>0.001282</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Leverage&quot;</td><td>-0.000288</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Momentum&quot;</td><td>-0.002527</td></tr><tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Institutions, Associations &amp; O…</td><td>0.0</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Real Estate&quot;</td><td>0.0</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Technology&quot;</td><td>-0.004924</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Utilities&quot;</td><td>0.0</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Idiosyncratic&quot;</td><td>&quot;&quot;</td><td>&quot;&quot;</td><td>-0.023967</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (22, 6)\n",
              "┌────────────┬────────┬───────────────┬──────────────┬─────────────────────────────────┬───────────┐\n",
              "│ date       ┆ book   ┆ type          ┆ factor_group ┆ factor                          ┆ PnL       │\n",
              "│ ---        ┆ ---    ┆ ---           ┆ ---          ┆ ---                             ┆ ---       │\n",
              "│ date       ┆ str    ┆ str           ┆ str          ┆ str                             ┆ f32       │\n",
              "╞════════════╪════════╪═══════════════╪══════════════╪═════════════════════════════════╪═══════════╡\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ market       ┆ Market                          ┆ 0.01711   │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ style        ┆ Dividend                        ┆ 0.001105  │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ style        ┆ Growth                          ┆ 0.001282  │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ style        ┆ Leverage                        ┆ -0.000288 │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ style        ┆ Momentum                        ┆ -0.002527 │\n",
              "│ …          ┆ …      ┆ …             ┆ …            ┆ …                               ┆ …         │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ trbc         ┆ Institutions, Associations & O… ┆ 0.0       │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ trbc         ┆ Real Estate                     ┆ 0.0       │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ trbc         ┆ Technology                      ┆ -0.004924 │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ trbc         ┆ Utilities                       ┆ 0.0       │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Idiosyncratic ┆              ┆                                 ┆ -0.023967 │\n",
              "└────────────┴────────┴───────────────┴──────────────┴─────────────────────────────────┴───────────┘"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# for a specific book on a specific date, the factor return attribution across assets\n",
        "(\n",
        "    report.accessor.get_data(\n",
        "        [(\"date\", \"2026-01-05\"), (\"book\", \"book_1\")],  # filters\n",
        "        expand=(\"type\", \"factor_group\", \"factor\",),\n",
        "        value_cols=(\"PnL\",),\n",
        "    )\n",
        "    .select(\"date\", \"book\", \"type\", \"factor_group\", \"factor\", \"PnL\")\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "55682bbc",
      "metadata": {},
      "source": [
        "We can drill down further by including the asset dimension. This decomposes the returns of the assets in a specific book, on a specific date."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "bf5ab534",
      "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: (88, 7)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>date</th><th>book</th><th>type</th><th>factor_group</th><th>factor</th><th>input_asset_id</th><th>PnL</th></tr><tr><td>date</td><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>f32</td></tr></thead><tbody><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;market&quot;</td><td>&quot;Market&quot;</td><td>&quot;02079K305&quot;</td><td>0.004296</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;market&quot;</td><td>&quot;Market&quot;</td><td>&quot;2588173&quot;</td><td>0.004173</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;market&quot;</td><td>&quot;Market&quot;</td><td>&quot;67066G10&quot;</td><td>0.008641</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;market&quot;</td><td>&quot;Market&quot;</td><td>&quot;85371710&quot;</td><td>0.0</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Dividend&quot;</td><td>&quot;02079K305&quot;</td><td>0.000264</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>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Utilities&quot;</td><td>&quot;85371710&quot;</td><td>0.0</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Idiosyncratic&quot;</td><td>&quot;&quot;</td><td>&quot;&quot;</td><td>&quot;02079K305&quot;</td><td>-0.003616</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Idiosyncratic&quot;</td><td>&quot;&quot;</td><td>&quot;&quot;</td><td>&quot;2588173&quot;</td><td>-0.003289</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Idiosyncratic&quot;</td><td>&quot;&quot;</td><td>&quot;&quot;</td><td>&quot;67066G10&quot;</td><td>-0.017061</td></tr><tr><td>2026-01-05</td><td>&quot;book_1&quot;</td><td>&quot;Idiosyncratic&quot;</td><td>&quot;&quot;</td><td>&quot;&quot;</td><td>&quot;85371710&quot;</td><td>0.0</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (88, 7)\n",
              "┌────────────┬────────┬───────────────┬──────────────┬───────────┬────────────────┬───────────┐\n",
              "│ date       ┆ book   ┆ type          ┆ factor_group ┆ factor    ┆ input_asset_id ┆ PnL       │\n",
              "│ ---        ┆ ---    ┆ ---           ┆ ---          ┆ ---       ┆ ---            ┆ ---       │\n",
              "│ date       ┆ str    ┆ str           ┆ str          ┆ str       ┆ str            ┆ f32       │\n",
              "╞════════════╪════════╪═══════════════╪══════════════╪═══════════╪════════════════╪═══════════╡\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ market       ┆ Market    ┆ 02079K305      ┆ 0.004296  │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ market       ┆ Market    ┆ 2588173        ┆ 0.004173  │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ market       ┆ Market    ┆ 67066G10       ┆ 0.008641  │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ market       ┆ Market    ┆ 85371710       ┆ 0.0       │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ style        ┆ Dividend  ┆ 02079K305      ┆ 0.000264  │\n",
              "│ …          ┆ …      ┆ …             ┆ …            ┆ …         ┆ …              ┆ …         │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Factors       ┆ trbc         ┆ Utilities ┆ 85371710       ┆ 0.0       │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Idiosyncratic ┆              ┆           ┆ 02079K305      ┆ -0.003616 │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Idiosyncratic ┆              ┆           ┆ 2588173        ┆ -0.003289 │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Idiosyncratic ┆              ┆           ┆ 67066G10       ┆ -0.017061 │\n",
              "│ 2026-01-05 ┆ book_1 ┆ Idiosyncratic ┆              ┆           ┆ 85371710       ┆ 0.0       │\n",
              "└────────────┴────────┴───────────────┴──────────────┴───────────┴────────────────┴───────────┘"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# for a specific book on a specific date, the factor return attribution by asset\n",
        "(\n",
        "    report.accessor.get_data(\n",
        "        [(\"date\", \"2026-01-05\"), (\"book\", \"book_1\")],  # filters\n",
        "        expand=(\"type\", \"factor_group\", \"factor\", \"input_asset_id\"),\n",
        "        value_cols=(\"PnL\",),\n",
        "    )\n",
        "    .select(\"date\", \"book\", \"type\", \"factor_group\", \"factor\", \"input_asset_id\", \"PnL\")\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9d0ad898",
      "metadata": {},
      "source": [
        "By using the filters, we can also isolate the specific return attribution."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "101e3c80",
      "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: (76, 4)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>fund</th><th>date</th><th>input_asset_id</th><th>PnL</th></tr><tr><td>str</td><td>date</td><td>str</td><td>f32</td></tr></thead><tbody><tr><td>&quot;some_fund&quot;</td><td>2026-01-05</td><td>&quot;02079K305&quot;</td><td>-0.007955</td></tr><tr><td>&quot;some_fund&quot;</td><td>2026-01-05</td><td>&quot;2588173&quot;</td><td>-0.008552</td></tr><tr><td>&quot;some_fund&quot;</td><td>2026-01-05</td><td>&quot;67066G10&quot;</td><td>-0.027298</td></tr><tr><td>&quot;some_fund&quot;</td><td>2026-01-05</td><td>&quot;85371710&quot;</td><td>0.0</td></tr><tr><td>&quot;some_fund&quot;</td><td>2026-01-06</td><td>&quot;02079K305&quot;</td><td>-0.023256</td></tr><tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>&quot;some_fund&quot;</td><td>2026-01-29</td><td>&quot;85371710&quot;</td><td>0.0</td></tr><tr><td>&quot;some_fund&quot;</td><td>2026-01-30</td><td>&quot;02079K305&quot;</td><td>0.025848</td></tr><tr><td>&quot;some_fund&quot;</td><td>2026-01-30</td><td>&quot;2588173&quot;</td><td>-0.004347</td></tr><tr><td>&quot;some_fund&quot;</td><td>2026-01-30</td><td>&quot;67066G10&quot;</td><td>0.022921</td></tr><tr><td>&quot;some_fund&quot;</td><td>2026-01-30</td><td>&quot;85371710&quot;</td><td>0.0</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (76, 4)\n",
              "┌───────────┬────────────┬────────────────┬───────────┐\n",
              "│ fund      ┆ date       ┆ input_asset_id ┆ PnL       │\n",
              "│ ---       ┆ ---        ┆ ---            ┆ ---       │\n",
              "│ str       ┆ date       ┆ str            ┆ f32       │\n",
              "╞═══════════╪════════════╪════════════════╪═══════════╡\n",
              "│ some_fund ┆ 2026-01-05 ┆ 02079K305      ┆ -0.007955 │\n",
              "│ some_fund ┆ 2026-01-05 ┆ 2588173        ┆ -0.008552 │\n",
              "│ some_fund ┆ 2026-01-05 ┆ 67066G10       ┆ -0.027298 │\n",
              "│ some_fund ┆ 2026-01-05 ┆ 85371710       ┆ 0.0       │\n",
              "│ some_fund ┆ 2026-01-06 ┆ 02079K305      ┆ -0.023256 │\n",
              "│ …         ┆ …          ┆ …              ┆ …         │\n",
              "│ some_fund ┆ 2026-01-29 ┆ 85371710       ┆ 0.0       │\n",
              "│ some_fund ┆ 2026-01-30 ┆ 02079K305      ┆ 0.025848  │\n",
              "│ some_fund ┆ 2026-01-30 ┆ 2588173        ┆ -0.004347 │\n",
              "│ some_fund ┆ 2026-01-30 ┆ 67066G10       ┆ 0.022921  │\n",
              "│ some_fund ┆ 2026-01-30 ┆ 85371710       ┆ 0.0       │\n",
              "└───────────┴────────────┴────────────────┴───────────┘"
            ]
          },
          "execution_count": 13,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# the idiosyncratic returns in a specific fund\n",
        "(\n",
        "    report.accessor.get_data(\n",
        "        [(\"fund\", \"some_fund\"), (\"type\", \"Idiosyncratic\")],  # filters\n",
        "        expand=(\"date\", \"input_asset_id\",),\n",
        "        value_cols=(\"PnL\",),\n",
        "    )\n",
        "    .select(\"fund\", \"date\", \"input_asset_id\", \"PnL\")\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7c418fe1",
      "metadata": {},
      "source": [
        "We can now to the same for risk attribution / decomposition"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "5de6e775",
      "metadata": {},
      "outputs": [],
      "source": [
        "report_settings = XSRReportSettingsV2(\n",
        "    portfolio_hierarchy_settings=portfoliohierarchy_settings,\n",
        "    factor_model_settings=factorriskmodel_settings,\n",
        "    normalize_holdings=False,\n",
        ")\n",
        "report_engine = bln.equity.reports.load(report_settings)\n",
        "report = report_engine.calculate(start_date=\"2026-01-05\", end_date=\"2026-01-30\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "4f600683",
      "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: (22, 10)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>ticker</th><th>date</th><th>type</th><th>factor_group</th><th>factor</th><th>Exposure</th><th>Volatility</th><th>Correlation</th><th>Contribution</th><th>Beta</th></tr><tr><td>str</td><td>date</td><td>str</td><td>str</td><td>str</td><td>f32</td><td>f32</td><td>f32</td><td>f32</td><td>f32</td></tr></thead><tbody><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;Factors&quot;</td><td>&quot;market&quot;</td><td>&quot;Market&quot;</td><td>0.99452</td><td>0.139866</td><td>0.586922</td><td>0.081641</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Dividend&quot;</td><td>-0.055837</td><td>0.02517</td><td>-0.047439</td><td>0.000067</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Growth&quot;</td><td>0.903092</td><td>0.016619</td><td>0.151997</td><td>0.002281</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Leverage&quot;</td><td>-0.154088</td><td>0.0235</td><td>-0.271476</td><td>0.000983</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Momentum&quot;</td><td>0.876027</td><td>0.058266</td><td>0.233155</td><td>0.011901</td><td>0.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><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Institutions, Associations &amp; O…</td><td>0.0</td><td>0.175683</td><td>-0.450882</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Real Estate&quot;</td><td>0.0</td><td>0.076858</td><td>-0.256836</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Technology&quot;</td><td>0.99452</td><td>0.050532</td><td>0.345648</td><td>0.01737</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Utilities&quot;</td><td>0.0</td><td>0.111708</td><td>-0.191097</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>2026-01-05</td><td>&quot;Idiosyncratic&quot;</td><td>&quot;&quot;</td><td>&quot;&quot;</td><td>0.99452</td><td>0.147677</td><td>0.640991</td><td>0.094659</td><td>0.0</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (22, 10)\n",
              "┌────────┬────────────┬─────────────┬────────────┬───┬────────────┬────────────┬────────────┬──────┐\n",
              "│ ticker ┆ date       ┆ type        ┆ factor_gro ┆ … ┆ Volatility ┆ Correlatio ┆ Contributi ┆ Beta │\n",
              "│ ---    ┆ ---        ┆ ---         ┆ up         ┆   ┆ ---        ┆ n          ┆ on         ┆ ---  │\n",
              "│ str    ┆ date       ┆ str         ┆ ---        ┆   ┆ f32        ┆ ---        ┆ ---        ┆ f32  │\n",
              "│        ┆            ┆             ┆ str        ┆   ┆            ┆ f32        ┆ f32        ┆      │\n",
              "╞════════╪════════════╪═════════════╪════════════╪═══╪════════════╪════════════╪════════════╪══════╡\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ Factors     ┆ market     ┆ … ┆ 0.139866   ┆ 0.586922   ┆ 0.081641   ┆ 0.0  │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ Factors     ┆ style      ┆ … ┆ 0.02517    ┆ -0.047439  ┆ 0.000067   ┆ 0.0  │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ Factors     ┆ style      ┆ … ┆ 0.016619   ┆ 0.151997   ┆ 0.002281   ┆ 0.0  │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ Factors     ┆ style      ┆ … ┆ 0.0235     ┆ -0.271476  ┆ 0.000983   ┆ 0.0  │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ Factors     ┆ style      ┆ … ┆ 0.058266   ┆ 0.233155   ┆ 0.011901   ┆ 0.0  │\n",
              "│ …      ┆ …          ┆ …           ┆ …          ┆ … ┆ …          ┆ …          ┆ …          ┆ …    │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ Factors     ┆ trbc       ┆ … ┆ 0.175683   ┆ -0.450882  ┆ 0.0        ┆ 0.0  │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ Factors     ┆ trbc       ┆ … ┆ 0.076858   ┆ -0.256836  ┆ 0.0        ┆ 0.0  │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ Factors     ┆ trbc       ┆ … ┆ 0.050532   ┆ 0.345648   ┆ 0.01737    ┆ 0.0  │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ Factors     ┆ trbc       ┆ … ┆ 0.111708   ┆ -0.191097  ┆ 0.0        ┆ 0.0  │\n",
              "│ AGTHX  ┆ 2026-01-05 ┆ Idiosyncrat ┆            ┆ … ┆ 0.147677   ┆ 0.640991   ┆ 0.094659   ┆ 0.0  │\n",
              "│        ┆            ┆ ic          ┆            ┆   ┆            ┆            ┆            ┆      │\n",
              "└────────┴────────────┴─────────────┴────────────┴───┴────────────┴────────────┴────────────┴──────┘"
            ]
          },
          "execution_count": 15,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# for a specific ticker and date, the risk attribution across the factors\n",
        "(\n",
        "    report.accessor.get_data(\n",
        "        [(\"ticker\", \"AGTHX\"), (\"date\", \"2026-01-05\")],  # filters: [ticker=AGTHX]\n",
        "        expand=(\"type\", \"factor_group\", \"factor\",), # combinations define the rows\n",
        "        value_cols=report.accessor.metric_cols,  # Exposure, Stand-alone Volatility, Variance Contribution\n",
        "    )\n",
        "    .select(\"ticker\", \"date\", \"type\", \"factor_group\", \"factor\", *report.accessor.metric_cols)\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "a58a911c",
      "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: (76, 9)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>ticker</th><th>factor</th><th>date</th><th>input_asset_id</th><th>Exposure</th><th>Volatility</th><th>Correlation</th><th>Contribution</th><th>Beta</th></tr><tr><td>str</td><td>str</td><td>date</td><td>str</td><td>f32</td><td>f32</td><td>f32</td><td>f32</td><td>f32</td></tr></thead><tbody><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>2026-01-05</td><td>&quot;02079K305&quot;</td><td>0.05366</td><td>0.128875</td><td>0.583411</td><td>0.004035</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>2026-01-05</td><td>&quot;2588173&quot;</td><td>-0.260326</td><td>0.128875</td><td>0.583411</td><td>-0.019573</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>2026-01-05</td><td>&quot;67066G10&quot;</td><td>0.0</td><td>0.128875</td><td>0.583411</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>2026-01-05</td><td>&quot;85371710&quot;</td><td>0.0</td><td>0.128875</td><td>0.583411</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>2026-01-06</td><td>&quot;02079K305&quot;</td><td>-0.009767</td><td>0.128487</td><td>0.56265</td><td>-0.000706</td><td>0.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><td>&hellip;</td><td>&hellip;</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>2026-01-29</td><td>&quot;85371710&quot;</td><td>0.0</td><td>0.120525</td><td>0.526526</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>2026-01-30</td><td>&quot;02079K305&quot;</td><td>-0.034229</td><td>0.124058</td><td>0.54978</td><td>-0.002335</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>2026-01-30</td><td>&quot;2588173&quot;</td><td>-0.098798</td><td>0.124058</td><td>0.54978</td><td>-0.006739</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>2026-01-30</td><td>&quot;67066G10&quot;</td><td>0.0</td><td>0.124058</td><td>0.54978</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>2026-01-30</td><td>&quot;85371710&quot;</td><td>0.0</td><td>0.124058</td><td>0.54978</td><td>0.0</td><td>0.0</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (76, 9)\n",
              "┌────────┬────────────┬────────────┬─────────────┬───┬────────────┬────────────┬────────────┬──────┐\n",
              "│ ticker ┆ factor     ┆ date       ┆ input_asset ┆ … ┆ Volatility ┆ Correlatio ┆ Contributi ┆ Beta │\n",
              "│ ---    ┆ ---        ┆ ---        ┆ _id         ┆   ┆ ---        ┆ n          ┆ on         ┆ ---  │\n",
              "│ str    ┆ str        ┆ date       ┆ ---         ┆   ┆ f32        ┆ ---        ┆ ---        ┆ f32  │\n",
              "│        ┆            ┆            ┆ str         ┆   ┆            ┆ f32        ┆ f32        ┆      │\n",
              "╞════════╪════════════╪════════════╪═════════════╪═══╪════════════╪════════════╪════════════╪══════╡\n",
              "│ AGTHX  ┆ Volatility ┆ 2026-01-05 ┆ 02079K305   ┆ … ┆ 0.128875   ┆ 0.583411   ┆ 0.004035   ┆ 0.0  │\n",
              "│ AGTHX  ┆ Volatility ┆ 2026-01-05 ┆ 2588173     ┆ … ┆ 0.128875   ┆ 0.583411   ┆ -0.019573  ┆ 0.0  │\n",
              "│ AGTHX  ┆ Volatility ┆ 2026-01-05 ┆ 67066G10    ┆ … ┆ 0.128875   ┆ 0.583411   ┆ 0.0        ┆ 0.0  │\n",
              "│ AGTHX  ┆ Volatility ┆ 2026-01-05 ┆ 85371710    ┆ … ┆ 0.128875   ┆ 0.583411   ┆ 0.0        ┆ 0.0  │\n",
              "│ AGTHX  ┆ Volatility ┆ 2026-01-06 ┆ 02079K305   ┆ … ┆ 0.128487   ┆ 0.56265    ┆ -0.000706  ┆ 0.0  │\n",
              "│ …      ┆ …          ┆ …          ┆ …           ┆ … ┆ …          ┆ …          ┆ …          ┆ …    │\n",
              "│ AGTHX  ┆ Volatility ┆ 2026-01-29 ┆ 85371710    ┆ … ┆ 0.120525   ┆ 0.526526   ┆ 0.0        ┆ 0.0  │\n",
              "│ AGTHX  ┆ Volatility ┆ 2026-01-30 ┆ 02079K305   ┆ … ┆ 0.124058   ┆ 0.54978    ┆ -0.002335  ┆ 0.0  │\n",
              "│ AGTHX  ┆ Volatility ┆ 2026-01-30 ┆ 2588173     ┆ … ┆ 0.124058   ┆ 0.54978    ┆ -0.006739  ┆ 0.0  │\n",
              "│ AGTHX  ┆ Volatility ┆ 2026-01-30 ┆ 67066G10    ┆ … ┆ 0.124058   ┆ 0.54978    ┆ 0.0        ┆ 0.0  │\n",
              "│ AGTHX  ┆ Volatility ┆ 2026-01-30 ┆ 85371710    ┆ … ┆ 0.124058   ┆ 0.54978    ┆ 0.0        ┆ 0.0  │\n",
              "└────────┴────────────┴────────────┴─────────────┴───┴────────────┴────────────┴────────────┴──────┘"
            ]
          },
          "execution_count": 16,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# for a specific ticker and factor, the risk attribution across dates and assets\n",
        "(\n",
        "    report.accessor.get_data(\n",
        "        [(\"ticker\", \"AGTHX\"), (\"factor\", \"Volatility\")],  # filters\n",
        "        expand=(\"date\", \"input_asset_id\",), # combinations define the rows\n",
        "        value_cols=report.accessor.metric_cols,  # Exposure, Stand-alone Volatility, Variance Contribution\n",
        "    )\n",
        "    .select(\"ticker\", \"factor\", \"date\", \"input_asset_id\", *report.accessor.metric_cols)\n",
        ")"
      ]
    }
  ],
  "metadata": {
    "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
}