{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "992223c7",
      "metadata": {},
      "source": [
        "# Portfolio Aligned Universes\n",
        "\n",
        "In this notebook we'll demonstrate how to define universes based on existing portfolio data. \n",
        "\n",
        "For this purpose we will first upload some sample portfolio holdings and subsequently use them to define a universe filter."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "112d39e5",
      "metadata": {},
      "outputs": [],
      "source": [
        "import io\n",
        "\n",
        "import polars as pl\n",
        "\n",
        "from bayesline.api.equity import (\n",
        "    PortfolioOrganizerSettings,\n",
        "    UniverseSettings,\n",
        ")\n",
        "from bayesline.apiclient import BayeslineApiClient"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "7fc19806",
      "metadata": {
        "tags": [
          "skip-execution"
        ]
      },
      "outputs": [],
      "source": [
        "bln = BayeslineApiClient.new_client(\n",
        "    endpoint=\"https://[ENDPOINT]\",\n",
        "    api_key=\"[API-KEY]\",\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d43df41f",
      "metadata": {},
      "source": [
        "## Uploading Portfolios\n",
        "\n",
        "We'll upload two portfolios `PORT_1` and `PORT_2` which contain assets *Apple* (`IC83A1B819`), *Microsoft* (`ICF982536B`) and *Alphabet* (`ICA17F00B9`)."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "42971f80",
      "metadata": {},
      "outputs": [],
      "source": [
        "portfolio_uploaders = bln.equity.uploaders.get_data_type(\"portfolios\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "fa9144b9",
      "metadata": {},
      "outputs": [],
      "source": [
        "portfolio_uploader = portfolio_uploaders.create_or_replace_dataset(\"US-Portfolios\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "564efafe",
      "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>date</th><th>portfolio_id</th><th>IC83A1B819</th><th>ICA17F00B9</th><th>ICF982536B</th></tr><tr><td>date</td><td>str</td><td>f64</td><td>f64</td><td>f64</td></tr></thead><tbody><tr><td>2025-01-01</td><td>&quot;PORT_1&quot;</td><td>0.3</td><td>0.7</td><td>0.0</td></tr><tr><td>2025-01-01</td><td>&quot;PORT_2&quot;</td><td>0.4</td><td>0.0</td><td>0.6</td></tr><tr><td>2025-02-01</td><td>&quot;PORT_1&quot;</td><td>1.0</td><td>0.0</td><td>0.0</td></tr><tr><td>2025-02-01</td><td>&quot;PORT_2&quot;</td><td>0.0</td><td>0.0</td><td>1.0</td></tr></tbody></table></div>"
            ],
            "text/plain": [
              "shape: (4, 5)\n",
              "┌────────────┬──────────────┬────────────┬────────────┬────────────┐\n",
              "│ date       ┆ portfolio_id ┆ IC83A1B819 ┆ ICA17F00B9 ┆ ICF982536B │\n",
              "│ ---        ┆ ---          ┆ ---        ┆ ---        ┆ ---        │\n",
              "│ date       ┆ str          ┆ f64        ┆ f64        ┆ f64        │\n",
              "╞════════════╪══════════════╪════════════╪════════════╪════════════╡\n",
              "│ 2025-01-01 ┆ PORT_1       ┆ 0.3        ┆ 0.7        ┆ 0.0        │\n",
              "│ 2025-01-01 ┆ PORT_2       ┆ 0.4        ┆ 0.0        ┆ 0.6        │\n",
              "│ 2025-02-01 ┆ PORT_1       ┆ 1.0        ┆ 0.0        ┆ 0.0        │\n",
              "│ 2025-02-01 ┆ PORT_2       ┆ 0.0        ┆ 0.0        ┆ 1.0        │\n",
              "└────────────┴──────────────┴────────────┴────────────┴────────────┘"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "data_csv = \"\"\"\n",
        "portfolio_id\tdate\tasset_id\tasset_id_type\tvalue\n",
        "PORT_1\t2025-01-01\tIC83A1B819\tbayesid\t.3\n",
        "PORT_1\t2025-01-01\tICA17F00B9\tbayesid\t.7\n",
        "PORT_2\t2025-01-01\tIC83A1B819\tbayesid\t.4\n",
        "PORT_2\t2025-01-01\tICF982536B\tbayesid\t.6\n",
        "PORT_1\t2025-02-01\tIC83A1B819\tbayesid\t1\n",
        "PORT_2\t2025-02-01\tICF982536B\tbayesid\t1\n",
        "\"\"\"\n",
        "\n",
        "portfolios_df = pl.read_csv(io.StringIO(data_csv.strip()), separator=\"\\t\", try_parse_dates=True)\n",
        "\n",
        "portfolios_df.pivot(index=[\"date\", \"portfolio_id\"], on=\"asset_id\", values=\"value\").fill_null(0)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "b80b8359",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "UploadCommitResult(version=1, committed_names=[])"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "portfolio_uploader.fast_commit(portfolios_df, mode=\"append\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7d5dfb26",
      "metadata": {},
      "source": [
        "## Creating the Universe\n",
        "\n",
        "Note that below we could still use other filters in addition to the portfolio filter. This way we could for instance express *the energy sector within the Russell 3000*."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "3b83a604",
      "metadata": {},
      "outputs": [],
      "source": [
        "universe_settings = UniverseSettings(\n",
        "    dataset=\"Bayesline-US-All-1y\",\n",
        "    portfolio_filter=PortfolioOrganizerSettings(\n",
        "        # filters against the point in time superset \n",
        "        # of all portfolios contained in `US-Portfolios`\n",
        "        enabled_portfolios=\"US-Portfolios\"\n",
        "    ),\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "73b8a7ae",
      "metadata": {},
      "outputs": [],
      "source": [
        "universe_api = bln.equity.universes.load(universe_settings)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b6c628a4",
      "metadata": {},
      "source": [
        "When obtaining the universe data note how even though we only specified holdings for `2025-01-01` and `2025-02-01` (which could be rebalance dates) the resulting universe contains entries for each day. Underneath the holdings are forward filled and delisted assets are dropped."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "3074fb96",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead tr th {\n",
              "        text-align: left;\n",
              "    }\n",
              "\n",
              "    .dataframe thead tr:last-of-type th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr>\n",
              "      <th></th>\n",
              "      <th colspan=\"3\" halign=\"left\">value</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>bayesid</th>\n",
              "      <th>IC83A1B819</th>\n",
              "      <th>ICA17F00B9</th>\n",
              "      <th>ICF982536B</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>date</th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>2025-01-01</th>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2025-01-02</th>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2025-01-03</th>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2025-01-04</th>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2025-01-05</th>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>...</th>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2025-08-21</th>\n",
              "      <td>1.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2025-08-22</th>\n",
              "      <td>1.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2025-08-23</th>\n",
              "      <td>1.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2025-08-24</th>\n",
              "      <td>1.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2025-08-25</th>\n",
              "      <td>1.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>237 rows × 3 columns</p>\n",
              "</div>"
            ],
            "text/plain": [
              "                value                      \n",
              "bayesid    IC83A1B819 ICA17F00B9 ICF982536B\n",
              "date                                       \n",
              "2025-01-01        1.0        1.0        1.0\n",
              "2025-01-02        1.0        1.0        1.0\n",
              "2025-01-03        1.0        1.0        1.0\n",
              "2025-01-04        1.0        1.0        1.0\n",
              "2025-01-05        1.0        1.0        1.0\n",
              "...               ...        ...        ...\n",
              "2025-08-21        1.0        NaN        1.0\n",
              "2025-08-22        1.0        NaN        1.0\n",
              "2025-08-23        1.0        NaN        1.0\n",
              "2025-08-24        1.0        NaN        1.0\n",
              "2025-08-25        1.0        NaN        1.0\n",
              "\n",
              "[237 rows x 3 columns]"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "universe_api.get().to_pandas().assign(value=1.).set_index([\"date\", \"bayesid\"]).unstack()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "2a87149e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Axes: xlabel='date'>"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "image/png": "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FUY2btyo2267TS1atFCrVq10991368svvww8fujQIblcLr3zzjsaMmSIrrrqKt14443asWOHhVXXXXR0tNq2bRt0i4qK0rp163TzzTeradOmuvbaazVr1iydPXs2qO2RI0f0s5/9TDExMbr22mu1evVqi47iym6++WYlJyfrnXfeCWx755131KFDB910002BbTX9OVi5cqUGDRqkpk2bavny5Q16LHVx8uRJrVy5Uo8//rhGjRqlrKyswGN5eXlyuVxav369evXqpaZNm6pfv34qKCgI7JOVlaUWLVro3XffVffu3RUdHa2ioiILjqTm6uuzHzp0qNLT04Oe+7vvvlOTJk20ZcuW8B9IGHTq1Enz5s0L2ta7d28999xzgfsul0uLFy/WPffco6uuuko/+clP9O677zZsoWFUk/fABJf73ff/Xl9s7dq1crlcQdtefPFFJSYmKjY2VhMnTtRTTz2l3r17h7/4MLNVGCkrK9O0adO0e/dubdmyRW63W/fcc0+V/+ubPn26nnjiCe3du1c33HCDxo4dW+WPtNP9+c9/VlpamiZPnqzPP/9cv//975WVlaXZs2cH7ffMM8/o3nvv1b59+/TQQw/pX//1X3XgwAGLqr6yRx55REuXLg3cf+ONN/SLX/wiaJ+a/hw89dRTmjx5sg4cOKCRI0c2SP314b//+7/VtWtXdenSRT//+c/1xhtvVFnR8sknn9TcuXO1a9cutW7dWqNHjw7q/Tl16pRefvllLV68WPv371diYmJDH0bI6uOznzhxorKzs1VeXh5os2zZMrVr105Dhw5tmAOxyKxZs/Qv//Iv+vTTT3XXXXfpoYce0vfff291WQhBTX73L2f58uWaPXu2Xn75Ze3Zs0cdOnTQ/Pnzw1hxA/JZbNy4cb4xY8Zc8rHvvvvOJ8n32Wef+Xw+n++rr77ySfItXrw4sM/+/ft9knwHDhxoiHLr3bhx43xRUVG+Zs2aBW733Xef74477vC99NJLQfu+9dZbvqSkpMB9Sb7HHnssaJ9bb73V9/jjjzdI7aHwf87ffvutLzo62nfo0CHfoUOHfE2bNvV99913vjFjxvjGjRt3ybbV/RzMmzevAY+g/vTv3z9Qe0VFhe/qq6/2bdu2zefz+Xzbtm3zSfLl5OQE9j927JgvJibGt3LlSp/P5/MtXbrUJ8m3d+/eBq+9Nurzs//xxx99LVu2DLwXPp/P16tXL99zzz3XEIdSby7+3uvYsaPvtddeC3r8xhtv9M2cOTNwX5JvxowZgfsnT570SfL98Y9/bIBqw6M278GaNWsarL5wuNzv/tKlS33x8fFB+69Zs8Z38Z/pW2+91efxeIL2GTBggO/GG28MZ9kNwlY9I//zP/+jsWPH6tprr1VcXJw6deokSVW6oHv16hX4d1JSkiTp22+/bbA669uQIUO0d+/ewO23v/2t9u3bp+eff17NmzcP3H75y1/qyJEjOnXqVKBtSkpK0HOlpKTYumekdevWge7JpUuXatSoUbr66quD9qnpz0GfPn0aqux6U1hYqI8//lhjx46VJDVq1EgPPPCAlixZErTfxZ9rQkKCunTpEvS5NmnSJOj3wAnq47Nv2rSpHn74Yb3xxhuSpE8++UQFBQURMQD24s+7WbNmiouLc/T3XqSp6e/+lZ7jpz/9adC2f7zvVLZatXf06NHq2LGjFi1apGuuuUZer1c9evTQmTNngvZr3Lhx4N/+82l2H8B3Oc2aNdP1118ftO3kyZOaNWuW/vmf/7nK/k2bNm2o0sLikUceCZz3/6//+q8qj9f056BZs2YNUm99WrJkic6ePatrrrkmsM3n8yk6Olr/+Z//WePniYmJqXIu2Qnq47OfOHGievfurb///e9aunSphg4dqo4dOzbYMdQ3t9tdpav+UgOyL/7ek85/9zn5e+9iNX0PnOxKv/uR8B5cjm3CyLFjx1RYWKhFixbp9ttvlyS9//77FldlnZtvvlmFhYVVQso/2rlzp9LS0oLuXzwg0I7uvPNOnTlzRi6Xq8pYD5N/Ds6ePas333xTc+fO1YgRI4IeS01N1YoVK9S1a1dJ5z9H/1Umx48f1xdffKFu3bo1eM31rT4++549e6pPnz5atGiRsrOzQwpxdtS6dWsdOXIkcL+0tFRfffWVhRU1PNPfg5r87nfs2FEnTpxQWVlZ4H+09u7dG7Rvly5dtGvXrqDv/F27doW9/oZgmzDSsmVLtWrVSgsXLlRSUpKKior01FNPWV2WZZ599lndfffd6tChg+677z653W7t27dPBQUFevHFFwP7rVq1Sn369NFtt92m5cuX6+OPPw6p288KUVFRgVMOUVFRQY+Z/HOQm5ur48ePa8KECYqPjw967N5779WSJUv0yiuvSJKef/55tWrVSm3atNH06dN19dVXGzEnQ3199hMnTlR6erqaNWume+65J+x1h9PQoUOVlZWl0aNHq0WLFnr22WervDemM/09qMnv/qZNm3TVVVfp6aef1r/927/po48+CrraRpImTZqkX/7yl+rTp4/69++vlStX6tNPP9W1117bgEcTHpaPGfF6vWrUqJHcbrdycnK0Z88e9ejRQ1OnTg18MUeikSNHKjc3V++995769u2rfv366bXXXqvSHT1r1izl5OSoV69eevPNN7VixQp1797doqprLi4u7pLLSZv8c7BkyRINGzasypeRdP4Laffu3fr0008lSXPmzNHkyZN1yy23qLi4WH/4wx/UpEmThi45LOrjsx87dqwaNWqksWPHOvK0pf97T5IyMjI0aNAg3X333Ro1apRSU1N13XXXWVxh+EXSe1CT3/2///3vWrZsmTZs2KCePXtqxYoVVS5tfuihh5SRkaEnnnhCN998s7766iuNHz/ekb8D/8jyVXvvvPNOXX/99Y7vagXqQ15enoYMGaLjx49XmXMAlQ4dOqTrrrtOu3bt0s0332x1OSHje4/3oL4MHz5cbdu21VtvvWV1KXVi2Wma48eP64MPPlBeXt4lp4kGgH9UUVGhY8eOacaMGerXr5/jggjfe7wHdXHq1CktWLBAI0eOVFRUlFasWKE//elP2rx5s9Wl1ZllYeSRRx7Rrl279Ktf/UpjxoyxqgwADvLBBx9oyJAhuuGGG2w923B1+N7jPagLl8ulDRs2aPbs2Tp9+rS6dOmit99+W8OGDbO6tDqz/DQNAACIbJYPYAUAAJGNMAIAACxFGAEAAJZqkDCSmZmpvn37KjY2VomJiUpNTVVhYWHQPqdPn5bH41GrVq3UvHlz3XvvvTp69Gjg8X379mns2LFKTk5WTEyMunXrptdffz3oOfzLr//jrbi4uCEOEwAA1EKDhJH8/Hx5PB7t3LlTmzdvVkVFhUaMGKGysrLAPlOnTtUf/vAHrVq1Svn5+frmm2+C1mXZs2ePEhMTtWzZMu3fv1/Tp09XRkbGJa9RLyws1JEjRwI3JyyvDgBApLLkaprvvvtOiYmJys/P18CBA1VSUqLWrVsrOztb9913nyTpr3/9q7p166YdO3aoX79+l3wej8ejAwcOaOvWrZKYMAoAACeyZMxISUmJpPNLo0vnez0qKiqCrpXu2rWrOnTooB07dlz2efzPcbHevXsrKSlJw4cP1wcffFDP1QMAgPrU4JOeeb1eTZkyRQMGDFCPHj0kScXFxWrSpEmV3ow2bdpUO97jww8/1MqVK7V+/frAtqSkJC1YsEB9+vRReXm5Fi9erMGDB+ujjz5y3EyNAABEigYPIx6PRwUFBXVaFr6goEBjxozRzJkzg5Zj7tKli7p06RK4379/f3355Zd67bXXHD9vPwAApmrQ0zTp6enKzc3Vtm3b1L59+8D2tm3b6syZM/rhhx+C9j969Kjatm0btO3zzz/XHXfcoUcffVQzZsy44mv+9Kc/1cGDB+ulfgAAUP8aJIz4fD6lp6drzZo12rp1qzp37hz0+C233KLGjRtry5YtgW2FhYUqKipSSkpKYNv+/fs1ZMgQjRs3TrNnz67Ra+/du1dJSUn1cyAAAKDeNchpGo/Ho+zsbK1bt06xsbGBcSDx8fGKiYlRfHy8JkyYoGnTpikhIUFxcXGaNGmSUlJSAlfSFBQUaOjQoRo5cqSmTZsWeI6oqCi1bt1akjRv3jx17txZ//RP/6TTp09r8eLF2rp1q957772GOEwAAFALDXJpr8vluuT2pUuXavz48ZLOT3r2q1/9SitWrFB5eblGjhyp3/3ud4HTNM8995xmzZpV5Tk6duyoQ4cOSZJ+85vfaOHChfr666911VVXqVevXnr22Wc1ZMiQsBwXAACoO1btBQAAlmJtGgAAYCnCCAAAsBRhBAAAWIowAgAALEUYAQAAliKMAAAASxFGAACApQgjAMJq8ODBmjJlitVlALAxwggA28jLy5PL5aqyaCYAsxFGAACApQgjAOpNWVmZ0tLS1Lx5cyUlJWnu3LlBj7/11lvq06ePYmNj1bZtWz344IP69ttvJUmHDh0KrCPVsmVLuVyuwNpVXq9XmZmZ6ty5s2JiYnTjjTdq9erVDXpsAMKHMAKg3jz55JPKz8/XunXr9N577ykvL0+ffPJJ4PGKigq98MIL2rdvn9auXatDhw4FAkdycrLefvttSVJhYaGOHDmi119/XZKUmZmpN998UwsWLND+/fs1depU/fznP1d+fn6DHyOA+sdCeQDqxcmTJ9WqVSstW7ZM999/vyTp+++/V/v27fXoo49q3rx5Vdrs3r1bffv21YkTJ9S8eXPl5eVpyJAhOn78uFq0aCFJKi8vV0JCgv70pz8pJSUl0HbixIk6deqUsrOzG+LwAIRRI6sLAGCGL7/8UmfOnNGtt94a2JaQkKAuXboE7u/Zs0fPPfec9u3bp+PHj8vr9UqSioqK1L1790s+78GDB3Xq1CkNHz48aPuZM2d00003heFIADQ0wgiABlFWVqaRI0dq5MiRWr58uVq3bq2ioiKNHDlSZ86cqbbdyZMnJUnr169Xu3btgh6Ljo4Oa80AGgZhBEC9uO6669S4cWN99NFH6tChgyTp+PHj+uKLLzRo0CD99a9/1bFjxzRnzhwlJydLOn+a5mJNmjSRJJ07dy6wrXv37oqOjlZRUZEGDRrUQEcDoCERRgDUi+bNm2vChAl68skn1apVKyUmJmr69Olyu8+Pk+/QoYOaNGmi//iP/9Bjjz2mgoICvfDCC0HP0bFjR7lcLuXm5uquu+5STEyMYmNj9cQTT2jq1Knyer267bbbVFJSog8++EBxcXEaN26cFYcLoB5xNQ2AevPKK6/o9ttv1+jRozVs2DDddtttuuWWWyRJrVu3VlZWllatWqXu3btrzpw5evXVV4Pat2vXTrNmzdJTTz2lNm3aKD09XZL0wgsv6JlnnlFmZqa6deumO++8U+vXr1fnzp0b/BgB1D+upgEAAJaiZwQAAFiKMAIAACxFGAEAAJYijAAAAEsRRgAAgKUIIwAAwFKEEQAAYCnCCAAAsBRhBAAAWIowAgAALEUYAQAAliKMAAAAS/0/fnztvz/mlOoAAAAASUVORK5CYII=",
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# asset counts over\n",
        "universe_api.counts().to_pandas().set_index(\"date\")[\"count\"].sort_index().plot()"
      ]
    }
  ],
  "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
}