{
  "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",
        "    ReportSettings,\n",
        "    FactorAttributionDrilldownReportSettings,\n",
        "    FactorAttributionDrilldownMeasureSettings,\n",
        "    XSRDrillDownReportSettings,\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.9.2/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, 5)</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>value</th></tr><tr><td>str</td><td>str</td><td>str</td><td>date</td><td>f64</td></tr></thead><tbody><tr><td>&quot;AGTHX&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;cusip9&quot;</td><td>2025-01-01</td><td>0.5</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;02079K305&quot;</td><td>&quot;cusip9&quot;</td><td>2025-01-31</td><td>0.55</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2588173&quot;</td><td>&quot;sedol7&quot;</td><td>2025-01-01</td><td>0.5</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2588173&quot;</td><td>&quot;sedol7&quot;</td><td>2025-01-31</td><td>0.45</td></tr><tr><td>&quot;FCNTX&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;cusip8&quot;</td><td>2025-01-01</td><td>1.0</td></tr><tr><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>2025-01-31</td><td>0.2</td></tr><tr><td>&quot;SPX&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;cusip8&quot;</td><td>2025-01-01</td><td>0.3</td></tr><tr><td>&quot;SPX&quot;</td><td>&quot;67066G10&quot;</td><td>&quot;cusip8&quot;</td><td>2025-01-31</td><td>0.25</td></tr><tr><td>&quot;SPX&quot;</td><td>&quot;85371710&quot;</td><td>&quot;cusip8&quot;</td><td>2025-01-01</td><td>0.3</td></tr><tr><td>&quot;SPX&quot;</td><td>&quot;85371710&quot;</td><td>&quot;cusip8&quot;</td><td>2025-01-31</td><td>0.25</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (20, 5)\n",
              "┌──────────────┬───────────┬───────────────┬────────────┬───────┐\n",
              "│ portfolio_id ┆ asset_id  ┆ asset_id_type ┆ date       ┆ value │\n",
              "│ ---          ┆ ---       ┆ ---           ┆ ---        ┆ ---   │\n",
              "│ str          ┆ str       ┆ str           ┆ date       ┆ f64   │\n",
              "╞══════════════╪═══════════╪═══════════════╪════════════╪═══════╡\n",
              "│ AGTHX        ┆ 02079K305 ┆ cusip9        ┆ 2025-01-01 ┆ 0.5   │\n",
              "│ AGTHX        ┆ 02079K305 ┆ cusip9        ┆ 2025-01-31 ┆ 0.55  │\n",
              "│ AGTHX        ┆ 2588173   ┆ sedol7        ┆ 2025-01-01 ┆ 0.5   │\n",
              "│ AGTHX        ┆ 2588173   ┆ sedol7        ┆ 2025-01-31 ┆ 0.45  │\n",
              "│ FCNTX        ┆ 67066G10  ┆ cusip8        ┆ 2025-01-01 ┆ 1.0   │\n",
              "│ …            ┆ …         ┆ …             ┆ …          ┆ …     │\n",
              "│ SPX          ┆ 2588173   ┆ sedol7        ┆ 2025-01-31 ┆ 0.2   │\n",
              "│ SPX          ┆ 67066G10  ┆ cusip8        ┆ 2025-01-01 ┆ 0.3   │\n",
              "│ SPX          ┆ 67066G10  ┆ cusip8        ┆ 2025-01-31 ┆ 0.25  │\n",
              "│ SPX          ┆ 85371710  ┆ cusip8        ┆ 2025-01-01 ┆ 0.3   │\n",
              "│ SPX          ┆ 85371710  ┆ cusip8        ┆ 2025-01-31 ┆ 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(2025, 1, 1), dt.date(2025, 1, 31), \n",
        "        dt.date(2025, 1, 1), dt.date(2025, 1, 31),\n",
        "\n",
        "        # FCNTX\n",
        "        dt.date(2025, 1, 1), dt.date(2025, 1, 31),\n",
        "\n",
        "        # VADGX\n",
        "        dt.date(2025, 1, 1), dt.date(2025, 1, 31), \n",
        "        dt.date(2025, 1, 1), dt.date(2025, 1, 31), \n",
        "        dt.date(2025, 1, 1), dt.date(2025, 1, 31), \n",
        "        \n",
        "        # SPX\n",
        "        dt.date(2025, 1, 1), dt.date(2025, 1, 31), \n",
        "        dt.date(2025, 1, 1), dt.date(2025, 1, 31), \n",
        "        dt.date(2025, 1, 1), dt.date(2025, 1, 31), \n",
        "        dt.date(2025, 1, 1), dt.date(2025, 1, 31), \n",
        "    ],\n",
        "    \"value\": [\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",
        "})\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, portfolio_source=\"portfolio-attribution-demo\"\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": "78da2620",
      "metadata": {},
      "outputs": [],
      "source": [
        "# construct the report\n",
        "report_settings = ReportSettings(\n",
        "    report=FactorAttributionDrilldownReportSettings(\n",
        "        measures=[\n",
        "            FactorAttributionDrilldownMeasureSettings(  # return attribution\n",
        "                normalize_holdings=True,\n",
        "                return_aggregation_type=\"geometric\",\n",
        "            ),\n",
        "            FactorAttributionDrilldownMeasureSettings(  # PnL attribution\n",
        "                normalize_holdings=False,\n",
        "                return_aggregation_type=\"arithmetic\",\n",
        "            ),\n",
        "        ],\n",
        "    ),\n",
        "    risk_model=factorriskmodel_settings,\n",
        ")\n",
        "report_engine = bln.equity.portfolioreport.load(\n",
        "    report_settings,\n",
        "    hierarchy_ref_or_settings=portfoliohierarchy_settings,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5c73fe88",
      "metadata": {},
      "source": [
        "The order defines the axes over which we can aggregate. For example by putting fund, book and ticker in our portfolio axis, we can filter and aggregate along this dimension at a later stage. The concepts of fund, book, and ticker were defined through the PortfolioHierarchySettings above."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "3135f018",
      "metadata": {},
      "outputs": [],
      "source": [
        "order = {\n",
        "    \"date\": [\"date\"],\n",
        "    \"portfolio\": [\"fund\", \"book\", \"ticker\"],\n",
        "    \"factor_and_idio\": [\"type\", \"factor\", \"factor_group\"],\n",
        "    \"asset\": [\"input_asset_id\"],\n",
        "}\n",
        "report_accessor = report_engine.get_report(\n",
        "    order,\n",
        "    date_start=\"2025-01-03\",\n",
        "    date_end=\"2025-01-31\",\n",
        "    subtotals=[\"date\", \"portfolio\", \"factor_and_idio\", \"asset\"],\n",
        ")"
      ]
    },
    {
      "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": 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: (57, 5)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>ticker</th><th>date</th><th>input_asset_id</th><th>Return</th><th>PnL</th></tr><tr><td>str</td><td>str</td><td>str</td><td>f32</td><td>f32</td></tr></thead><tbody><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;02079K305&quot;</td><td>0.006253</td><td>0.006234</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;2588173&quot;</td><td>0.005676</td><td>0.005658</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;67066G10&quot;</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-06&quot;</td><td>&quot;02079K305&quot;</td><td>0.013301</td><td>0.013418</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-06&quot;</td><td>&quot;2588173&quot;</td><td>0.005292</td><td>0.005338</td></tr><tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-30&quot;</td><td>&quot;2588173&quot;</td><td>-0.031159</td><td>-0.032432</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-30&quot;</td><td>&quot;67066G10&quot;</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-31&quot;</td><td>&quot;02079K305&quot;</td><td>0.008134</td><td>0.00832</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-31&quot;</td><td>&quot;2588173&quot;</td><td>0.000081</td><td>0.000083</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-31&quot;</td><td>&quot;67066G10&quot;</td><td>0.0</td><td>0.0</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (57, 5)\n",
              "┌────────┬────────────┬────────────────┬───────────┬───────────┐\n",
              "│ ticker ┆ date       ┆ input_asset_id ┆ Return    ┆ PnL       │\n",
              "│ ---    ┆ ---        ┆ ---            ┆ ---       ┆ ---       │\n",
              "│ str    ┆ str        ┆ str            ┆ f32       ┆ f32       │\n",
              "╞════════╪════════════╪════════════════╪═══════════╪═══════════╡\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ 02079K305      ┆ 0.006253  ┆ 0.006234  │\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ 2588173        ┆ 0.005676  ┆ 0.005658  │\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ 67066G10       ┆ 0.0       ┆ 0.0       │\n",
              "│ AGTHX  ┆ 2025-01-06 ┆ 02079K305      ┆ 0.013301  ┆ 0.013418  │\n",
              "│ AGTHX  ┆ 2025-01-06 ┆ 2588173        ┆ 0.005292  ┆ 0.005338  │\n",
              "│ …      ┆ …          ┆ …              ┆ …         ┆ …         │\n",
              "│ AGTHX  ┆ 2025-01-30 ┆ 2588173        ┆ -0.031159 ┆ -0.032432 │\n",
              "│ AGTHX  ┆ 2025-01-30 ┆ 67066G10       ┆ 0.0       ┆ 0.0       │\n",
              "│ AGTHX  ┆ 2025-01-31 ┆ 02079K305      ┆ 0.008134  ┆ 0.00832   │\n",
              "│ AGTHX  ┆ 2025-01-31 ┆ 2588173        ┆ 0.000081  ┆ 0.000083  │\n",
              "│ AGTHX  ┆ 2025-01-31 ┆ 67066G10       ┆ 0.0       ┆ 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=(\"Return\", \"PnL\"),  # exclude benchmark / active\n",
        "    )\n",
        "    .select(\"ticker\", \"date\", \"input_asset_id\", \"Return\", \"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, 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>Return</th><th>PnL</th></tr><tr><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>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;market&quot;</td><td>&quot;Market&quot;</td><td>0.013663</td><td>0.027693</td></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Energy&quot;</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Basic Materials&quot;</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Industrials&quot;</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Consumer Cyclicals&quot;</td><td>0.0</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></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Volatility&quot;</td><td>-0.000889</td><td>-0.001802</td></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Momentum&quot;</td><td>0.002296</td><td>0.004653</td></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Dividend&quot;</td><td>0.000091</td><td>0.000185</td></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Leverage&quot;</td><td>0.000591</td><td>0.001198</td></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Idiosyncratic&quot;</td><td>&quot;&quot;</td><td>&quot;&quot;</td><td>0.006521</td><td>0.013217</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (22, 7)\n",
              "┌────────────┬────────┬───────────────┬──────────────┬────────────────────┬───────────┬───────────┐\n",
              "│ date       ┆ book   ┆ type          ┆ factor_group ┆ factor             ┆ Return    ┆ PnL       │\n",
              "│ ---        ┆ ---    ┆ ---           ┆ ---          ┆ ---                ┆ ---       ┆ ---       │\n",
              "│ str        ┆ str    ┆ str           ┆ str          ┆ str                ┆ f32       ┆ f32       │\n",
              "╞════════════╪════════╪═══════════════╪══════════════╪════════════════════╪═══════════╪═══════════╡\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors       ┆ market       ┆ Market             ┆ 0.013663  ┆ 0.027693  │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors       ┆ trbc         ┆ Energy             ┆ 0.0       ┆ 0.0       │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors       ┆ trbc         ┆ Basic Materials    ┆ 0.0       ┆ 0.0       │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors       ┆ trbc         ┆ Industrials        ┆ 0.0       ┆ 0.0       │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors       ┆ trbc         ┆ Consumer Cyclicals ┆ 0.0       ┆ 0.0       │\n",
              "│ …          ┆ …      ┆ …             ┆ …            ┆ …                  ┆ …         ┆ …         │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors       ┆ style        ┆ Volatility         ┆ -0.000889 ┆ -0.001802 │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors       ┆ style        ┆ Momentum           ┆ 0.002296  ┆ 0.004653  │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors       ┆ style        ┆ Dividend           ┆ 0.000091  ┆ 0.000185  │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors       ┆ style        ┆ Leverage           ┆ 0.000591  ┆ 0.001198  │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Idiosyncratic ┆              ┆                    ┆ 0.006521  ┆ 0.013217  │\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\", \"2025-01-03\"), (\"book\", \"book_1\")],  # filters\n",
        "        expand=(\"type\", \"factor_group\", \"factor\",),\n",
        "        value_cols=(\"Return\", \"PnL\"),\n",
        "    )\n",
        "    .select(\"date\", \"book\", \"type\", \"factor_group\", \"factor\", \"Return\", \"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: (66, 8)</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>Return</th><th>PnL</th></tr><tr><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>&quot;2025-01-03&quot;</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.003373</td><td>0.006836</td></tr><tr><td>&quot;2025-01-03&quot;</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.003347</td><td>0.006784</td></tr><tr><td>&quot;2025-01-03&quot;</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.006943</td><td>0.014072</td></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Energy&quot;</td><td>&quot;02079K305&quot;</td><td>0.0</td><td>0.0</td></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Energy&quot;</td><td>&quot;2588173&quot;</td><td>0.0</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></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Leverage&quot;</td><td>&quot;2588173&quot;</td><td>-0.000065</td><td>-0.000131</td></tr><tr><td>&quot;2025-01-03&quot;</td><td>&quot;book_1&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Leverage&quot;</td><td>&quot;67066G10&quot;</td><td>0.000221</td><td>0.000449</td></tr><tr><td>&quot;2025-01-03&quot;</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.001356</td><td>-0.002748</td></tr><tr><td>&quot;2025-01-03&quot;</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.000086</td><td>-0.000175</td></tr><tr><td>&quot;2025-01-03&quot;</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.007963</td><td>0.016139</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (66, 8)\n",
              "┌────────────┬────────┬─────────────┬─────────────┬──────────┬─────────────┬───────────┬───────────┐\n",
              "│ date       ┆ book   ┆ type        ┆ factor_grou ┆ factor   ┆ input_asset ┆ Return    ┆ PnL       │\n",
              "│ ---        ┆ ---    ┆ ---         ┆ p           ┆ ---      ┆ _id         ┆ ---       ┆ ---       │\n",
              "│ str        ┆ str    ┆ str         ┆ ---         ┆ str      ┆ ---         ┆ f32       ┆ f32       │\n",
              "│            ┆        ┆             ┆ str         ┆          ┆ str         ┆           ┆           │\n",
              "╞════════════╪════════╪═════════════╪═════════════╪══════════╪═════════════╪═══════════╪═══════════╡\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors     ┆ market      ┆ Market   ┆ 02079K305   ┆ 0.003373  ┆ 0.006836  │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors     ┆ market      ┆ Market   ┆ 2588173     ┆ 0.003347  ┆ 0.006784  │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors     ┆ market      ┆ Market   ┆ 67066G10    ┆ 0.006943  ┆ 0.014072  │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors     ┆ trbc        ┆ Energy   ┆ 02079K305   ┆ 0.0       ┆ 0.0       │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors     ┆ trbc        ┆ Energy   ┆ 2588173     ┆ 0.0       ┆ 0.0       │\n",
              "│ …          ┆ …      ┆ …           ┆ …           ┆ …        ┆ …           ┆ …         ┆ …         │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors     ┆ style       ┆ Leverage ┆ 2588173     ┆ -0.000065 ┆ -0.000131 │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Factors     ┆ style       ┆ Leverage ┆ 67066G10    ┆ 0.000221  ┆ 0.000449  │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Idiosyncrat ┆             ┆          ┆ 02079K305   ┆ -0.001356 ┆ -0.002748 │\n",
              "│            ┆        ┆ ic          ┆             ┆          ┆             ┆           ┆           │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Idiosyncrat ┆             ┆          ┆ 2588173     ┆ -0.000086 ┆ -0.000175 │\n",
              "│            ┆        ┆ ic          ┆             ┆          ┆             ┆           ┆           │\n",
              "│ 2025-01-03 ┆ book_1 ┆ Idiosyncrat ┆             ┆          ┆ 67066G10    ┆ 0.007963  ┆ 0.016139  │\n",
              "│            ┆        ┆ ic          ┆             ┆          ┆             ┆           ┆           │\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\", \"2025-01-03\"), (\"book\", \"book_1\")],  # filters\n",
        "        expand=(\"type\", \"factor_group\", \"factor\", \"input_asset_id\"),\n",
        "        value_cols=(\"Return\", \"PnL\"),\n",
        "    )\n",
        "    .select(\"date\", \"book\", \"type\", \"factor_group\", \"factor\", \"input_asset_id\", \"Return\", \"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: (57, 5)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>fund</th><th>date</th><th>input_asset_id</th><th>Return</th><th>PnL</th></tr><tr><td>str</td><td>str</td><td>str</td><td>f32</td><td>f32</td></tr></thead><tbody><tr><td>&quot;some_fund&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;02079K305&quot;</td><td>-0.001496</td><td>-0.006045</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;2588173&quot;</td><td>-0.000112</td><td>-0.000454</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;67066G10&quot;</td><td>0.006392</td><td>0.025823</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;2025-01-06&quot;</td><td>&quot;02079K305&quot;</td><td>0.004032</td><td>0.016697</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;2025-01-06&quot;</td><td>&quot;2588173&quot;</td><td>0.000716</td><td>0.002964</td></tr><tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;2025-01-30&quot;</td><td>&quot;2588173&quot;</td><td>-0.023051</td><td>-0.091597</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;2025-01-30&quot;</td><td>&quot;67066G10&quot;</td><td>-0.001804</td><td>-0.00717</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;2025-01-31&quot;</td><td>&quot;02079K305&quot;</td><td>0.005031</td><td>0.019784</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;2025-01-31&quot;</td><td>&quot;2588173&quot;</td><td>0.000653</td><td>0.002569</td></tr><tr><td>&quot;some_fund&quot;</td><td>&quot;2025-01-31&quot;</td><td>&quot;67066G10&quot;</td><td>-0.013499</td><td>-0.053083</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (57, 5)\n",
              "┌───────────┬────────────┬────────────────┬───────────┬───────────┐\n",
              "│ fund      ┆ date       ┆ input_asset_id ┆ Return    ┆ PnL       │\n",
              "│ ---       ┆ ---        ┆ ---            ┆ ---       ┆ ---       │\n",
              "│ str       ┆ str        ┆ str            ┆ f32       ┆ f32       │\n",
              "╞═══════════╪════════════╪════════════════╪═══════════╪═══════════╡\n",
              "│ some_fund ┆ 2025-01-03 ┆ 02079K305      ┆ -0.001496 ┆ -0.006045 │\n",
              "│ some_fund ┆ 2025-01-03 ┆ 2588173        ┆ -0.000112 ┆ -0.000454 │\n",
              "│ some_fund ┆ 2025-01-03 ┆ 67066G10       ┆ 0.006392  ┆ 0.025823  │\n",
              "│ some_fund ┆ 2025-01-06 ┆ 02079K305      ┆ 0.004032  ┆ 0.016697  │\n",
              "│ some_fund ┆ 2025-01-06 ┆ 2588173        ┆ 0.000716  ┆ 0.002964  │\n",
              "│ …         ┆ …          ┆ …              ┆ …         ┆ …         │\n",
              "│ some_fund ┆ 2025-01-30 ┆ 2588173        ┆ -0.023051 ┆ -0.091597 │\n",
              "│ some_fund ┆ 2025-01-30 ┆ 67066G10       ┆ -0.001804 ┆ -0.00717  │\n",
              "│ some_fund ┆ 2025-01-31 ┆ 02079K305      ┆ 0.005031  ┆ 0.019784  │\n",
              "│ some_fund ┆ 2025-01-31 ┆ 2588173        ┆ 0.000653  ┆ 0.002569  │\n",
              "│ some_fund ┆ 2025-01-31 ┆ 67066G10       ┆ -0.013499 ┆ -0.053083 │\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=(\"Return\", \"PnL\"),\n",
        "    )\n",
        "    .select(\"fund\", \"date\", \"input_asset_id\", \"Return\", \"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": "7b46e364",
      "metadata": {},
      "outputs": [],
      "source": [
        "# construct the report\n",
        "report_settings = ReportSettings(\n",
        "    report=XSRDrillDownReportSettings(),  # uses default measures & forecasting settings\n",
        "    risk_model=factorriskmodel_settings,\n",
        ")\n",
        "report_engine = bln.equity.portfolioreport.load(\n",
        "    report_settings,\n",
        "    hierarchy_ref_or_settings=portfoliohierarchy_settings,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "61bd00e3",
      "metadata": {},
      "source": [
        "Orders work the same as for attribution"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "3b7d6da3",
      "metadata": {},
      "outputs": [],
      "source": [
        "order = {\n",
        "    \"date\": [\"date\"],\n",
        "    \"portfolio\": [\"fund\", \"book\", \"ticker\"],\n",
        "    \"factor_and_idio\": [\"type\", \"factor\", \"factor_group\"],\n",
        "    \"asset\": [\"input_asset_id\"],\n",
        "}\n",
        "report_accessor = report_engine.get_report(\n",
        "    order,\n",
        "    date_start=\"2025-01-03\",\n",
        "    date_end=\"2025-01-31\",\n",
        "    subtotals=[\"date\", \"portfolio\", \"factor_and_idio\", \"asset\"],\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "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, 9)</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 (X)</th><th>Volatility (σ)</th><th>Correlation (ρ)</th><th>Contribution (Xσρ)</th></tr><tr><td>str</td><td>str</td><td>str</td><td>str</td><td>str</td><td>f32</td><td>f32</td><td>f32</td><td>f32</td></tr></thead><tbody><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;Factors&quot;</td><td>&quot;market&quot;</td><td>&quot;Market&quot;</td><td>1.0</td><td>0.145571</td><td>0.581724</td><td>0.084682</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Energy&quot;</td><td>1.0000e-16</td><td>0.161093</td><td>-0.195762</td><td>-3.1536e-18</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Basic Materials&quot;</td><td>1.0000e-16</td><td>0.084038</td><td>-0.158261</td><td>-1.3300e-18</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Industrials&quot;</td><td>1.0000e-16</td><td>0.051383</td><td>-0.013657</td><td>-7.0171e-20</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;Factors&quot;</td><td>&quot;trbc&quot;</td><td>&quot;Consumer Cyclicals&quot;</td><td>1.0000e-16</td><td>0.058483</td><td>-0.278516</td><td>-1.6288e-18</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;2025-01-03&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Volatility&quot;</td><td>-0.615608</td><td>0.094433</td><td>0.593388</td><td>-0.034496</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Momentum&quot;</td><td>0.671758</td><td>0.048824</td><td>0.274103</td><td>0.00899</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Dividend&quot;</td><td>-0.08854</td><td>0.024852</td><td>-0.316676</td><td>0.000697</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;Factors&quot;</td><td>&quot;style&quot;</td><td>&quot;Leverage&quot;</td><td>-0.22636</td><td>0.021849</td><td>-0.365077</td><td>0.001806</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;Idiosyncratic&quot;</td><td>&quot;&quot;</td><td>&quot;&quot;</td><td>1.0</td><td>0.143307</td><td>0.663646</td><td>0.095105</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (22, 9)\n",
              "┌────────┬────────────┬────────────┬───────────┬───┬───────────┬───────────┬───────────┬───────────┐\n",
              "│ ticker ┆ date       ┆ type       ┆ factor_gr ┆ … ┆ Exposure  ┆ Volatilit ┆ Correlati ┆ Contribut │\n",
              "│ ---    ┆ ---        ┆ ---        ┆ oup       ┆   ┆ (X)       ┆ y (σ)     ┆ on (ρ)    ┆ ion (Xσρ) │\n",
              "│ str    ┆ str        ┆ str        ┆ ---       ┆   ┆ ---       ┆ ---       ┆ ---       ┆ ---       │\n",
              "│        ┆            ┆            ┆ str       ┆   ┆ f32       ┆ f32       ┆ f32       ┆ f32       │\n",
              "╞════════╪════════════╪════════════╪═══════════╪═══╪═══════════╪═══════════╪═══════════╪═══════════╡\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ Factors    ┆ market    ┆ … ┆ 1.0       ┆ 0.145571  ┆ 0.581724  ┆ 0.084682  │\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ Factors    ┆ trbc      ┆ … ┆ 1.0000e-1 ┆ 0.161093  ┆ -0.195762 ┆ -3.1536e- │\n",
              "│        ┆            ┆            ┆           ┆   ┆ 6         ┆           ┆           ┆ 18        │\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ Factors    ┆ trbc      ┆ … ┆ 1.0000e-1 ┆ 0.084038  ┆ -0.158261 ┆ -1.3300e- │\n",
              "│        ┆            ┆            ┆           ┆   ┆ 6         ┆           ┆           ┆ 18        │\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ Factors    ┆ trbc      ┆ … ┆ 1.0000e-1 ┆ 0.051383  ┆ -0.013657 ┆ -7.0171e- │\n",
              "│        ┆            ┆            ┆           ┆   ┆ 6         ┆           ┆           ┆ 20        │\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ Factors    ┆ trbc      ┆ … ┆ 1.0000e-1 ┆ 0.058483  ┆ -0.278516 ┆ -1.6288e- │\n",
              "│        ┆            ┆            ┆           ┆   ┆ 6         ┆           ┆           ┆ 18        │\n",
              "│ …      ┆ …          ┆ …          ┆ …         ┆ … ┆ …         ┆ …         ┆ …         ┆ …         │\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ Factors    ┆ style     ┆ … ┆ -0.615608 ┆ 0.094433  ┆ 0.593388  ┆ -0.034496 │\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ Factors    ┆ style     ┆ … ┆ 0.671758  ┆ 0.048824  ┆ 0.274103  ┆ 0.00899   │\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ Factors    ┆ style     ┆ … ┆ -0.08854  ┆ 0.024852  ┆ -0.316676 ┆ 0.000697  │\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ Factors    ┆ style     ┆ … ┆ -0.22636  ┆ 0.021849  ┆ -0.365077 ┆ 0.001806  │\n",
              "│ AGTHX  ┆ 2025-01-03 ┆ Idiosyncra ┆           ┆ … ┆ 1.0       ┆ 0.143307  ┆ 0.663646  ┆ 0.095105  │\n",
              "│        ┆            ┆ tic        ┆           ┆   ┆           ┆           ┆           ┆           │\n",
              "└────────┴────────────┴────────────┴───────────┴───┴───────────┴───────────┴───────────┴───────────┘"
            ]
          },
          "execution_count": 16,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# for a specific ticker and date, the return attribution across the factors\n",
        "(\n",
        "    report_accessor.get_data(\n",
        "        [(\"ticker\", \"AGTHX\"), (\"date\", \"2025-01-03\")],  # filters: [ticker=AGTHX]\n",
        "        expand=(\"type\", \"factor_group\", \"factor\",), # combinations define the rows\n",
        "        value_cols=report_accessor.metric_cols,  # X-Sigma-Rho and Contribution\n",
        "    )\n",
        "    .select(\"ticker\", \"date\", \"type\", \"factor_group\", \"factor\", *report_accessor.metric_cols)\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "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: (57, 8)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>ticker</th><th>factor</th><th>date</th><th>input_asset_id</th><th>Exposure (X)</th><th>Volatility (σ)</th><th>Correlation (ρ)</th><th>Contribution (Xσρ)</th></tr><tr><td>str</td><td>str</td><td>str</td><td>str</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>&quot;2025-01-03&quot;</td><td>&quot;02079K305&quot;</td><td>-0.211609</td><td>0.094433</td><td>0.593388</td><td>-0.011858</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;2588173&quot;</td><td>-0.403999</td><td>0.094433</td><td>0.593388</td><td>-0.022638</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>&quot;2025-01-03&quot;</td><td>&quot;67066G10&quot;</td><td>1.0000e-16</td><td>0.094433</td><td>0.593388</td><td>5.6035e-18</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>&quot;2025-01-06&quot;</td><td>&quot;02079K305&quot;</td><td>-0.213743</td><td>0.094154</td><td>0.577862</td><td>-0.011629</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>&quot;2025-01-06&quot;</td><td>&quot;2588173&quot;</td><td>-0.41507</td><td>0.094154</td><td>0.577862</td><td>-0.022583</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></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>&quot;2025-01-30&quot;</td><td>&quot;2588173&quot;</td><td>-0.261793</td><td>0.09853</td><td>0.587572</td><td>-0.015156</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>&quot;2025-01-30&quot;</td><td>&quot;67066G10&quot;</td><td>1.0000e-16</td><td>0.09853</td><td>0.587572</td><td>5.7893e-18</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>&quot;2025-01-31&quot;</td><td>&quot;02079K305&quot;</td><td>-0.146631</td><td>0.09758</td><td>0.599562</td><td>-0.008579</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>&quot;2025-01-31&quot;</td><td>&quot;2588173&quot;</td><td>-0.242358</td><td>0.09758</td><td>0.599562</td><td>-0.014179</td></tr><tr><td>&quot;AGTHX&quot;</td><td>&quot;Volatility&quot;</td><td>&quot;2025-01-31&quot;</td><td>&quot;67066G10&quot;</td><td>1.0000e-16</td><td>0.09758</td><td>0.599562</td><td>5.8505e-18</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (57, 8)\n",
              "┌────────┬────────────┬────────────┬────────────┬────────────┬────────────┬────────────┬───────────┐\n",
              "│ ticker ┆ factor     ┆ date       ┆ input_asse ┆ Exposure   ┆ Volatility ┆ Correlatio ┆ Contribut │\n",
              "│ ---    ┆ ---        ┆ ---        ┆ t_id       ┆ (X)        ┆ (σ)        ┆ n (ρ)      ┆ ion (Xσρ) │\n",
              "│ str    ┆ str        ┆ str        ┆ ---        ┆ ---        ┆ ---        ┆ ---        ┆ ---       │\n",
              "│        ┆            ┆            ┆ str        ┆ f32        ┆ f32        ┆ f32        ┆ f32       │\n",
              "╞════════╪════════════╪════════════╪════════════╪════════════╪════════════╪════════════╪═══════════╡\n",
              "│ AGTHX  ┆ Volatility ┆ 2025-01-03 ┆ 02079K305  ┆ -0.211609  ┆ 0.094433   ┆ 0.593388   ┆ -0.011858 │\n",
              "│ AGTHX  ┆ Volatility ┆ 2025-01-03 ┆ 2588173    ┆ -0.403999  ┆ 0.094433   ┆ 0.593388   ┆ -0.022638 │\n",
              "│ AGTHX  ┆ Volatility ┆ 2025-01-03 ┆ 67066G10   ┆ 1.0000e-16 ┆ 0.094433   ┆ 0.593388   ┆ 5.6035e-1 │\n",
              "│        ┆            ┆            ┆            ┆            ┆            ┆            ┆ 8         │\n",
              "│ AGTHX  ┆ Volatility ┆ 2025-01-06 ┆ 02079K305  ┆ -0.213743  ┆ 0.094154   ┆ 0.577862   ┆ -0.011629 │\n",
              "│ AGTHX  ┆ Volatility ┆ 2025-01-06 ┆ 2588173    ┆ -0.41507   ┆ 0.094154   ┆ 0.577862   ┆ -0.022583 │\n",
              "│ …      ┆ …          ┆ …          ┆ …          ┆ …          ┆ …          ┆ …          ┆ …         │\n",
              "│ AGTHX  ┆ Volatility ┆ 2025-01-30 ┆ 2588173    ┆ -0.261793  ┆ 0.09853    ┆ 0.587572   ┆ -0.015156 │\n",
              "│ AGTHX  ┆ Volatility ┆ 2025-01-30 ┆ 67066G10   ┆ 1.0000e-16 ┆ 0.09853    ┆ 0.587572   ┆ 5.7893e-1 │\n",
              "│        ┆            ┆            ┆            ┆            ┆            ┆            ┆ 8         │\n",
              "│ AGTHX  ┆ Volatility ┆ 2025-01-31 ┆ 02079K305  ┆ -0.146631  ┆ 0.09758    ┆ 0.599562   ┆ -0.008579 │\n",
              "│ AGTHX  ┆ Volatility ┆ 2025-01-31 ┆ 2588173    ┆ -0.242358  ┆ 0.09758    ┆ 0.599562   ┆ -0.014179 │\n",
              "│ AGTHX  ┆ Volatility ┆ 2025-01-31 ┆ 67066G10   ┆ 1.0000e-16 ┆ 0.09758    ┆ 0.599562   ┆ 5.8505e-1 │\n",
              "│        ┆            ┆            ┆            ┆            ┆            ┆            ┆ 8         │\n",
              "└────────┴────────────┴────────────┴────────────┴────────────┴────────────┴────────────┴───────────┘"
            ]
          },
          "execution_count": 17,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# for a specific ticker and factor, the return 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,  # X-Sigma-Rho and 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.14"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}