{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "7b51ae77-8333-41c8-b6e1-90f2155a7cb7",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Quantum Portfolio Optimizer – Eine Qiskit-Funktion von Global Data Quantum\"\n",
        "description: \"Eine Qiskit-Funktion zur Lösung dynamischer Probleme mit dem „ Portfolio Optimization ” unter Verwendung einer fein abgestimmten Implementierung des VQE.\"\n",
        "---\n",
        "\n",
        "<span id=\"quantum-portfolio-optimizer-a-qiskit-function-by-global-data-quantum\" />\n",
        "\n",
        "# Quantum Portfolio Optimizer: Eine Qiskit-Funktion von Global Data Quantum\n",
        "\n",
        "{/* cspell:ignore rebalance, GBPJPY, TMBMKDE  */}\n",
        "\n",
        "*Siehe [API-Referenz](/docs/api/functions/global-data-quantum-optimizer)*\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a95af5a5-933c-4f11-a841-65483946a528",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0466d79d-52b1-4ae4-bdbe-94357784cf7f",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  Qiskit-Funktionen sind eine experimentelle Funktion, die nur für Benutzer des IBM Quantum® Premium Plan, Flex Plan und On-Prem (über IBM Quantum Platform API) Plan verfügbar ist. Sie befinden sich im Status einer Vorabversion und können sich noch ändern.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f350e597-000e-4c64-8e5d-c5b95851d26c",
      "metadata": {},
      "source": [
        "<span id=\"overview\" />\n",
        "\n",
        "## Übersicht\n",
        "\n",
        "Der Quantum Portfolio Optimizer ist eine Qiskit-Funktion, die sich mit dem Problem der dynamischen Portfolio-Optimierung befasst, einem Standardproblem im Finanzwesen, das darauf abzielt, periodische Investitionen in einer Reihe von Vermögenswerten neu zu verteilen, um die Erträge zu maximieren und die Risiken zu minimieren. Durch den Einsatz modernster Quantenoptimierungstechniken vereinfacht diese Funktion den Prozess, so dass auch Nutzer ohne Fachkenntnisse im Quantencomputing von den Vorteilen dieser Funktion bei der Suche nach optimalen Investitionspfaden profitieren können. Dieses Tool ist ideal für Portfoliomanager, Forscher im Bereich der quantitativen Finanzen und Privatanleger und ermöglicht das Backtesting von Handelsstrategien zur Portfoliooptimierung.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "977a893a-9bbe-47f9-b4be-d9f6b8d27a72",
      "metadata": {},
      "source": [
        "<span id=\"function-description\" />\n",
        "\n",
        "## Funktionsbeschreibung\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9038f89a-7452-45bf-a96c-8a5ba8b061d0",
      "metadata": {},
      "source": [
        "Die Funktion Quantum Portfolio Optimizer verwendet den Algorithmus Variational Quantum Eigensolver (VQE) zur Lösung eines quadratischen, uneingeschränkten binären Optimierungsproblems (QUBO), das sich mit dynamischen Portfolio-Optimierungsproblemen befasst. Die Benutzer müssen lediglich die Preisdaten für die Vermögenswerte angeben und die Investitionsbeschränkung definieren, woraufhin die Funktion den Quantenoptimierungsprozess durchführt, der eine Reihe optimierter Investitionstrajektorien liefert.\n",
        "\n",
        "Der Prozess besteht aus vier Hauptphasen. Zunächst werden die Eingabedaten auf ein quantenkompatibles Problem abgebildet, wobei das QUBO des dynamischen Portfoliooptimierungsproblems konstruiert und in einen Quantenoperator (Ising-Hamiltonian) umgewandelt wird. Anschließend werden das Eingabeproblem und der VQE-Algorithmus so angepasst, dass sie auf der Quantenhardware ausgeführt werden können. Anschließend wird der VQE-Algorithmus auf der Quantenhardware ausgeführt, und schließlich werden die Ergebnisse nachbearbeitet, um die optimalen Investitionsverläufe zu ermitteln. Das System umfasst zudem eine rauschbewusste ( [SQD](/docs/addons/qiskit-addon-sqd) -basierte) Nachbearbeitung, um die Qualität des Ergebnisses zu optimieren.\n",
        "\n",
        "Diese Qiskit-Funktion basiert auf dem [veröffentlichten Manuskript](https://arxiv.org/abs/2412.19150) von Global Data Quantum.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3667fa72-ebef-476a-94a1-553389889623",
      "metadata": {},
      "source": [
        "![Visualisierung des Arbeitsablaufs der Funktion](https://quantum.cloud.ibm.com/docs/images/guides/global-data-quantum-optimizer/function_workflow.svg)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "32a1bfa7-0e6d-4e64-9169-3b285597cfe1",
      "metadata": {},
      "source": [
        "<span id=\"get-started\" />\n",
        "\n",
        "# Erste Schritte\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8c2eeb5b-14c5-4c49-a02b-612ebcd64960",
      "metadata": {},
      "source": [
        "Authentifizieren Sie sich mit Ihrem [API-Schlüssel](/) und wählen Sie die Qiskit-Funktion wie folgt aus. (In diesem Codeausschnitt wird davon ausgegangen, dass Sie [Ihr Konto](/docs/guides/functions-get-started#install-qiskit-functions-catalog-client) bereits in Ihrer lokalen Umgebung gespeichert haben.)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "d62b10b4-432b-4885-b4a1-c4266d675386",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "[QiskitFunction(qunova/hivqe-chemistry),\n",
              " QiskitFunction(global-data-quantum/quantum-portfolio-optimizer),\n",
              " QiskitFunction(algorithmiq/tem),\n",
              " QiskitFunction(qedma/qesem),\n",
              " QiskitFunction(multiverse/singularity),\n",
              " QiskitFunction(ibm/circuit-function),\n",
              " QiskitFunction(q-ctrl/optimization-solver),\n",
              " QiskitFunction(colibritd/quick-pde),\n",
              " QiskitFunction(q-ctrl/performance-management),\n",
              " QiskitFunction(kipu-quantum/iskay-quantum-optimizer)]"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit_ibm_catalog import QiskitFunctionsCatalog\n",
        "\n",
        "catalog = QiskitFunctionsCatalog(channel=\"ibm_quantum_platform\")\n",
        "\n",
        "# Verify that you have access to the function\n",
        "catalog.list()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "b0a820cb-a3e1-4156-a156-0da2e9db9640",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Access function\n",
        "dpo_solver = catalog.load(\"global-data-quantum/quantum-portfolio-optimizer\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0503669b-15e6-4533-b4ef-7f6c9e7d9f4f",
      "metadata": {},
      "source": [
        "<span id=\"example-dynamic-portfolio-optimization-with-seven-assets\" />\n",
        "\n",
        "## Beispiel: Dynamische Portfoliooptimierung mit sieben Vermögenswerten\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "298a6e60-52cd-491c-8777-cdd3038ab490",
      "metadata": {},
      "source": [
        "In diesem Beispiel wird gezeigt, wie Sie die dynamische Portfoliooptimierung (DPO) ausführen und ihre Einstellungen für eine optimale Leistung anpassen. Er enthält detaillierte Schritte zur Feinabstimmung der Parameter, um die gewünschten Ergebnisse zu erzielen.\n",
        "\n",
        "In diesem Fall sind sieben Aktiva, vier Zeitschritte und vier Auflösungs-Qubits erforderlich, was einen Gesamtbedarf von 112 Qubits ergibt.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "736b0557-f4bf-43ad-a8e3-f1b871f67398",
      "metadata": {},
      "source": [
        "<span id=\"1-read-the-assets-included-in-the-portfolio\" />\n",
        "\n",
        "### 1. Sehen Sie sich die im Portfolio enthaltenen Vermögenswerte an\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "276c3f55-f75b-4320-807b-007a3881bdaa",
      "metadata": {},
      "source": [
        "Wenn alle Assets des Portfolios in einem Ordner unter einem bestimmten Pfad gespeichert sind, können Sie sie mit der folgenden Funktion in ein `pandas.DataFrame` laden und in ein Objekt im Format `dict` konvertieren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "c961d730-8a65-4a2b-b312-1006af8565ca",
      "metadata": {},
      "outputs": [],
      "source": [
        "import os\n",
        "import glob\n",
        "import pandas as pd\n",
        "\n",
        "\n",
        "def read_and_join_csv(file_pattern):\n",
        "    \"\"\"\n",
        "    Reads multiple CSV files matching the file pattern and combines them\n",
        "    into a single DataFrame.\n",
        "\n",
        "    Parameters:\n",
        "    file_pattern (str): The pattern to match CSV files.\n",
        "\n",
        "    Returns:\n",
        "    pd.DataFrame: Combined DataFrame with data from all CSV files.\n",
        "    \"\"\"\n",
        "    # Find all files matching the pattern\n",
        "    csv_files = glob.glob(file_pattern)\n",
        "    # Get the base file names without the .csv extension\n",
        "    file_names = [os.path.basename(f).replace(\".csv\", \"\") for f in csv_files]\n",
        "    # Read each CSV file into a DataFrame and set the first column as the index\n",
        "    df_list = [pd.read_csv(f).set_index(\"Unnamed: 0\") for f in csv_files]\n",
        "\n",
        "    # Rename columns in each DataFrame to the base file names\n",
        "    for df, name in zip(df_list, file_names):\n",
        "        df.columns = [name]\n",
        "\n",
        "    # Combine all DataFrames into one by merging them side by side\n",
        "    combined_df = pd.concat(df_list, axis=1)\n",
        "    return combined_df\n",
        "\n",
        "\n",
        "file_pattern = \"route/to/folder/with/assets/data/*.csv\"\n",
        "assets = read_and_join_csv(file_pattern).to_dict()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "29b4f417-c61d-4c6f-9779-15e052b90076",
      "metadata": {},
      "source": [
        "Für dieses Beispiel haben wir die Assets [8801.T](https://finance.yahoo.com/quote/8801.T), [CLF](https://finance.yahoo.com/quote/CLF), [GBPJPY](https://finance.yahoo.com/quote/GBPJPY), [ITX.MC](https://finance.yahoo.com/quote/ITX.MC), [META](https://finance.yahoo.com/quote/META), [TMBMKDE-10Y](https://finance.yahoo.com/quote/TMBMKDE-10Y), und [XS2239553048](https://finance.yahoo.com/quote/XS2239553048). Die folgende Abbildung veranschaulicht die in diesem Beispiel verwendeten Daten und zeigt die tägliche Schlusskursentwicklung der Vermögenswerte vom 1. Januar bis zum 1. September 2023.\n",
        "\n",
        "In diesem Beispiel haben wir, um die Einheitlichkeit der Daten zu gewährleisten, nicht gehandelte Tage mit dem Schlusskurs des letzten verfügbaren Datums gefüllt. Wir wenden diesen Schritt an, weil die ausgewählten Vermögenswerte von verschiedenen Märkten mit unterschiedlichen Handelstagen stammen, so dass eine Standardisierung des Datensatzes aus Konsistenzgründen unerlässlich ist.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fb8b3592-5c1c-4dde-b635-a8b46e66f500",
      "metadata": {},
      "source": [
        "![Visualisierung der historischen Daten der Assets](https://quantum.cloud.ibm.com/docs/images/guides/global-data-quantum-optimizer/assets.avif)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "708bf084-29bb-4201-a904-acefb2c85af8",
      "metadata": {},
      "source": [
        "<span id=\"2-define-the-problem\" />\n",
        "\n",
        "### 2. Das Problem definieren\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d6f9c0f2-48be-48a4-bef4-b98f5f85b8b1",
      "metadata": {},
      "source": [
        "Definieren Sie die Spezifikationen des Problems, indem Sie die Parameter im Wörterbuch `qubo_settings` konfigurieren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "b92835c1-eb14-429e-ba22-846ee849764c",
      "metadata": {},
      "outputs": [],
      "source": [
        "qubo_settings = {\n",
        "    \"nt\": 4,\n",
        "    \"nq\": 4,\n",
        "    \"dt\": 30,\n",
        "    \"max_investment\": 25,\n",
        "    \"risk_aversion\": 1000.0,\n",
        "    \"transaction_fee\": 0.01,\n",
        "    \"restriction_coeff\": 1.0,\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "98da8a80-2f9b-4b62-abfe-364a1dc712f4",
      "metadata": {},
      "source": [
        "<span id=\"3-define-the-optimizer-and-ansatz-settings-optional\" />\n",
        "\n",
        "### 3. Legen Sie die Einstellungen für den Optimierer und den Ansatz fest (optional)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "526df9d9-d52c-4a81-89ca-ff047eda5eb5",
      "metadata": {},
      "source": [
        "Definieren Sie optional spezifische Anforderungen für den Optimierungsprozess, einschließlich der Auswahl des Optimierers und seiner Parameter sowie der Spezifikation des Primitivs und seiner Konfigurationen.\n",
        "\n",
        "Für den Tailored Ansatz wurde die Populationsgröße auf der Grundlage früherer Experimente gewählt, die gezeigt haben, dass dieser Wert eine stabile und effiziente Optimierung ermöglicht.\n",
        "\n",
        "Im Falle des Ansatzes der reellen Amplituden kann man eine lineare Beziehung zwischen `population_size` und der Anzahl der Qubits in der Schaltung verfolgen. Als ungefähre Faustregel wird empfohlen, ein **Minimum von** `population_size ~ 0.8 * n_qubits` für den Ansatz `real_amplitudes` zu verwenden.\n",
        "\n",
        "Es wird erwartet, dass die Optimierten Realen Amplituden eine bessere Optimierungsleistung aufweisen als der Ansatz der Realen Amplituden. Allerdings steigt die Anzahl der zu optimierenden Variablen in diesem Ansatz viel schneller als im Fall der reellen Amplituden (siehe [Manuskript](https://arxiv.org/pdf/2412.19150) ). Bei großen Problemen erfordert die Optimierte Reale Amplitude daher mehr Schaltkreisausführungen. Die optimierten realen Amplituden sind wahrscheinlich nützlich für Probleme, die bis zu 100 Qubits erfordern, aber es wird empfohlen, bei der Einstellung der `population_size` Parameter vorsichtig zu sein. Als Beispiel für diese Skalierung in `population_size` zeigt die vorherige Tabelle, dass für ein 84-Qubit-Problem die Optimize Real Amplitudes 120 `population_size` benötigt, während für ein 56-Qubit-Problem eine `population_size` von 40 ausreicht.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "1ad03fde-4c78-4ec3-a027-cf0e2599d857",
      "metadata": {},
      "outputs": [],
      "source": [
        "optimizer_settings = {\n",
        "    \"de_optimizer_settings\": {\n",
        "        \"num_generations\": 20,\n",
        "        \"population_size\": 90,\n",
        "        \"recombination\": 0.4,\n",
        "        \"max_parallel_jobs\": 5,\n",
        "        \"max_batchsize\": 4,\n",
        "        \"mutation_range\": [0.0, 0.25],\n",
        "    },\n",
        "    \"optimizer\": \"differential_evolution\",\n",
        "    \"primitive_settings\": {\n",
        "        \"estimator_shots\": 25_000,\n",
        "        \"estimator_precision\": None,\n",
        "        \"sampler_shots\": 100_000,\n",
        "    },\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "253955cb-87cd-4e39-a0fa-21c457db0106",
      "metadata": {},
      "source": [
        "Es ist auch möglich, einen bestimmten Ansatz zu wählen. Im Folgenden wird der Ansatz `'Tailored'` verwendet.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "9fa3c8be-c755-49e7-8c3e-322e5da7c802",
      "metadata": {},
      "outputs": [],
      "source": [
        "ansatz_settings = {\n",
        "    \"ansatz\": \"tailored\",\n",
        "    \"multiple_passmanager\": False,\n",
        "}"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6e7b6809-aca0-4d04-bb99-c258e758a0b4",
      "metadata": {},
      "source": [
        "<span id=\"4-run-the-problem\" />\n",
        "\n",
        "### 4. Führen Sie das Programm aus\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "09553772-82e9-4d42-bc8f-f75f20c7d355",
      "metadata": {},
      "outputs": [],
      "source": [
        "dpo_job = dpo_solver.run(\n",
        "    assets=assets,\n",
        "    qubo_settings=qubo_settings,\n",
        "    optimizer_settings=optimizer_settings,\n",
        "    ansatz_settings=ansatz_settings,\n",
        "    backend_name=\"<backend name>\",\n",
        "    previous_session_id=[],\n",
        "    apply_postprocess=True,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f6890c97-0c0e-4750-bc31-114e7dc830e0",
      "metadata": {},
      "source": [
        "<span id=\"5-retrieve-results\" />\n",
        "\n",
        "### 5. Ergebnisse abrufen\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fe8cfc2e-3305-4a33-89cc-a73fb64ada69",
      "metadata": {},
      "source": [
        "Die Funktion gibt ein Wörterbuch zurück, in dem die Investitionsverläufe nach ihrem Zielfunktionswert von niedrig nach hoch sortiert sind (siehe Abschnitt [„Ausgabe“](/docs/api/functions/global-data-quantum-optimizer#output) in der API-Referenz). Anhand dieser Ergebnisse lassen sich die kostengünstigste Vorgehensweise und die entsprechenden Investitionsbewertungen ermitteln. Darüber hinaus ermöglicht es die Analyse verschiedener Entwicklungswege und erleichtert so die Auswahl derjenigen, die den spezifischen Bedürfnissen oder Zielen am besten entsprechen. Diese Flexibilität gewährleistet, dass die Auswahlmöglichkeiten auf eine Vielzahl von Vorlieben oder Szenarien zugeschnitten werden können.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "eb7eeefd-935c-4c7e-8ea0-f2ef07498641",
      "metadata": {},
      "source": [
        "Beginnen Sie mit der Darstellung der Strategie, die zu den niedrigsten objektiven Kosten geführt hat, die während des Prozesses gefunden wurden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "c1bc72c1-d5a1-4834-9737-f573b8f0f4d6",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "{'time_step_0': {'8801.T': 0.11764705882352941,\n",
              "  'ITX.MC': 0.20588235294117646,\n",
              "  'META': 0.38235294117647056,\n",
              "  'GBPJPY=X': 0.058823529411764705,\n",
              "  'TMBMKDE-10Y': 0.0,\n",
              "  'CLF': 0.058823529411764705,\n",
              "  'XS2239553048': 0.17647058823529413},\n",
              " 'time_step_1': {'8801.T': 0.11428571428571428,\n",
              "  'ITX.MC': 0.14285714285714285,\n",
              "  'META': 0.2,\n",
              "  'GBPJPY=X': 0.02857142857142857,\n",
              "  'TMBMKDE-10Y': 0.42857142857142855,\n",
              "  'CLF': 0.0,\n",
              "  'XS2239553048': 0.08571428571428572},\n",
              " 'time_step_2': {'8801.T': 0.0,\n",
              "  'ITX.MC': 0.09375,\n",
              "  'META': 0.3125,\n",
              "  'GBPJPY=X': 0.34375,\n",
              "  'TMBMKDE-10Y': 0.0,\n",
              "  'CLF': 0.0,\n",
              "  'XS2239553048': 0.25},\n",
              " 'time_step_3': {'8801.T': 0.3939393939393939,\n",
              "  'ITX.MC': 0.09090909090909091,\n",
              "  'META': 0.12121212121212122,\n",
              "  'GBPJPY=X': 0.18181818181818182,\n",
              "  'TMBMKDE-10Y': 0.0,\n",
              "  'CLF': 0.0,\n",
              "  'XS2239553048': 0.21212121212121213}}"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Get the results of the job\n",
        "dpo_result = dpo_job.result()\n",
        "\n",
        "# Show the solution strategy\n",
        "dpo_result[\"result\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "043ab9f6-c50c-4387-9de1-fe4de3491980",
      "metadata": {},
      "source": [
        "Anschließend können Sie über die Metadaten auf die Ergebnisse aller Strategien der Stichprobe zugreifen. Auf diese Weise können Sie die vom Optimierer zurückgegebenen alternativen Trajektorien weiter analysieren. Lesen Sie dazu das in `dpo_result['metadata']['all_samples_metrics']` gespeicherte Wörterbuch, das nicht nur zusätzliche Informationen über die optimale Strategie, sondern auch Einzelheiten über die anderen während der Optimierung bewerteten Kandidatenstrategien enthält.\n",
        "\n",
        "Das folgende Beispiel zeigt, wie diese Informationen mit Hilfe von `pandas` gelesen werden können, um die mit der optimalen Strategie verbundenen Schlüsselkennzahlen zu extrahieren. Dazu gehören Restriktionsabweichung, Sharpe Ratio und die entsprechende Anlagerendite.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "6d79bf57-3f68-4981-aa66-7a0cf17c4155",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Minimum Objective Cost Found: -3.78\n",
            "Best Solution:\n",
            "  - Restriction Deviation: 40.0\n",
            "  - Sharpe Ratio: 24.82\n",
            "  - Return: 0.46\n"
          ]
        }
      ],
      "source": [
        "# Convert metadata to a DataFrame\n",
        "df = pd.DataFrame(dpo_result[\"metadata\"][\"all_samples_metrics\"])\n",
        "\n",
        "# Find the minimum objective cost\n",
        "min_cost = df[\"objective_costs\"].min()\n",
        "print(f\"Minimum Objective Cost Found: {min_cost:.2f}\")\n",
        "\n",
        "# Extract the row with the lowest cost\n",
        "best_row = df[df[\"objective_costs\"] == min_cost].iloc[0]\n",
        "\n",
        "# Display the results associated with the best solution\n",
        "print(\"Best Solution:\")\n",
        "print(f\"  - Restriction Deviation: {best_row['rest_breaches']}%\")\n",
        "print(f\"  - Sharpe Ratio: {best_row['sharpe_ratios']:.2f}\")\n",
        "print(f\"  - Return: {best_row['returns']}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "51797701-c647-4b1a-b863-be743d359ffe",
      "metadata": {},
      "source": [
        "<span id=\"6-performance-analysis\" />\n",
        "\n",
        "### 6. Leistungsanalyse\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f595acfc-e26b-44fd-8c1c-8b1bc81611aa",
      "metadata": {},
      "source": [
        "Analysieren Sie schließlich die Leistung Ihrer Optimierungsanwendung. Vergleichen Sie insbesondere Ihre Ergebnisse aus dem vorherigen Beispiel mit einer zufälligen Basislinie, um die Wirksamkeit unseres Ansatzes zu bewerten. Wenn der Quantenalgorithmus nachweislich und durchgängig Ergebnisse mit niedrigeren Kostenwerten liefert, deutet dies auf einen effektiven Optimierungsprozess hin.\n",
        "\n",
        "Die Abbildung zeigt die Wahrscheinlichkeitsverteilungen der objektiven Kosten. Um diese Verteilungen zu erstellen, nehmen Sie die Liste der objektiven Kosten aus dem Funktionsergebnis und zählen Sie die Häufigkeit der einzelnen Kostenwerte (Werte auf die zweite Dezimalstelle gerundet). Aktualisieren Sie dann die Zählspalte entsprechend, indem Sie die Zählungen identischer gerundeter Werte verbinden. Um einen besseren visuellen Vergleich zu ermöglichen, wurde die Anzahl der Vorkommen normalisiert, so dass jede Verteilung zwischen 0 und 1 angezeigt wird.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "560912e7-6722-4f06-87b1-83fd4ac2073f",
      "metadata": {},
      "source": [
        "![Visualisierung der Lösung der Optimierungsaufgabe](https://quantum.cloud.ibm.com/docs/images/guides/global-data-quantum-optimizer/cost_distribution.avif)\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0bd0704d-83a0-4b29-b3aa-cb1eddef412d",
      "metadata": {},
      "source": [
        "Wie in der Abbildung (blaue durchgezogene Linie) zu sehen ist, konzentriert sich die Kostenverteilung für unseren Ansatz des Variational Quantum Eigensolver (nachbearbeitet mit SQD) stark auf die niedrigeren Zielkostenwerte, was auf eine gute Optimierungsleistung hinweist. Im Gegensatz dazu weist die verrauschte Basislinie eine breitere Verteilung auf, die sich auf höhere Kostenwerte konzentriert. Die graue, gestrichelte vertikale Linie stellt den Mittelwert der Zufallsverteilung dar, was die Konsistenz der Funktion bei der Ermittlung optimierter Anlagestrategien weiter verdeutlicht. Die schwarze gestrichelte Linie in der Abbildung entspricht der Lösung, die mit dem Gurobi-Optimierer (kostenlose Version) erzielt wurde, um einen zusätzlichen Vergleich zu ermöglichen. Alle diese Ergebnisse werden in den nachstehenden Benchmarks für das Beispiel \"Gemischte Vermögenswerte\", das mit dem \"maßgeschneiderten\" Ansatz bewertet wurde, näher untersucht.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "de293919-a802-4ebe-95e3-173083268741",
      "metadata": {},
      "source": [
        "<span id=\"benchmarks\" />\n",
        "\n",
        "# Benchmarks\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bb44f36c-de99-44ed-921b-003ec3030e86",
      "metadata": {},
      "source": [
        "Diese Funktion wurde unter verschiedenen Konfigurationen von Auflösungsqubits, Ansatzschaltungen und Gruppierungen von Vermögenswerten aus verschiedenen Sektoren getestet: eine Mischung verschiedener Vermögenswerte (Set 1), Ölderivate (Set 2) und IBEX35 (Set 3). Weitere Einzelheiten finden Sie in der folgenden Tabelle.\n",
        "\n",
        "| Festlegen    | Datum      | Anlagen                                                         |\n",
        "| ------------ | ---------- | --------------------------------------------------------------- |\n",
        "| **Gruppe 1** | 01/01/2023 | 8801.T, CL=F, GBPJPY=X, ITX.MC, META, TMBMKDE-10Y, XS2239553048 |\n",
        "| **Gruppe 2** | 01/06/2023 | CL=F, BZ=F, HO=F, NG=F, XOM, RB=F, 2222.SR                      |\n",
        "| **Satz 3**   | 01/11/2022 | ACS.MC, ITX.MC, FER.MC, ELE.MC, SCYR.MC, AENA.MC, AMS.MC        |\n",
        "\n",
        "Zur Bewertung der Lösungsqualität wurden zwei Schlüsselkennzahlen herangezogen.\n",
        "\n",
        "1. Die objektiven Kosten, die die Effizienz der Optimierung messen, indem der Wert der Kostenfunktion jedes Experiments mit den Ergebnissen von Gurobi (kostenlose Version) verglichen wird.\n",
        "2. Die Sharpe-Ratio, die die risikobereinigte Rendite jedes Portfolios erfasst und einen Einblick in die finanzielle Leistung der Lösungen bietet.\n",
        "\n",
        "Mit diesen Kennzahlen werden sowohl die rechnerischen als auch die finanziellen Aspekte der durch Quanten generierten Portfolios bewertet.\n",
        "\n",
        "| Beispiel                                                          | Qubits | Ansatz                      | Tiefe | Laufzeitverbrauch (s) | Gesamtverbrauch (s) | Objektive Kosten | Sharpe | Gurobi objektive Kosten | Gurobi Sharpe |\n",
        "| ----------------------------------------------------------------- | ------ | --------------------------- | ----- | --------------------- | ------------------- | ---------------- | ------ | ----------------------- | ------------- |\n",
        "| Gemischte Anlagen (Satz 1, 4 Zeitschritte, 4-Bit)                 | 112    | Gerader Rock                | 83    | 12735                 | 13095               | -3.78            | 24.82  | -4.25                   | 24.71         |\n",
        "| Gemischte Anlagen (Satz 1, 4 Zeitschritte, 4 Zeitschritte, 4 Bit) | 112    | Reale Amplituden            | 359   | 11739                 | 11903               | -3.39            | 23.64  | -4.25                   | 24.71         |\n",
        "| Ölderivate (Satz 2, 4 Zeitschritte, 3-Bit)                        | 84     | Optimierte reale Amplituden | 78    | 6180                  | 6350                | -3.73            | 19.13  | -4.19                   | 21.71         |\n",
        "| IBEX35 (Satz 3, 4 Zeitschritte, 2-Bit)                            | 56     | Optimierte reale Amplituden | 96    | 3314                  | 3523                | -3.67            | 14.48  | -4.11                   | 16.44         |\n",
        "\n",
        "Die Ergebnisse zeigen, dass der Quantenoptimierer mit problemspezifischen Ansätzen effektiv effiziente Anlagestrategien für verschiedene Portfoliotypen identifiziert.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2db3bd86-393e-4e88-851c-fd496f956aed",
      "metadata": {},
      "source": [
        "Im Folgenden werden sowohl die Größe der Population als auch die Anzahl der Generationen, die im Wörterbuch `optimizer_options` angegeben sind, näher erläutert. Alle anderen Parameter wurden auf ihre Standardwerte gesetzt.\n",
        "\n",
        "| **Beispiel**                        | `population_size` | `num_generations` |\n",
        "| ----------------------------------- | ----------------- | ----------------- |\n",
        "| Portfolio gemischter Vermögenswerte | 90                | 20 Jahre          |\n",
        "| Portfolio gemischter Vermögenswerte | 92                | 20 Jahre          |\n",
        "| Portfolio von Ölderivaten           | 120               | 20 Jahre          |\n",
        "| IBEX35 Portfolio                    | 40                | 20 Jahre          |\n",
        "\n",
        "Die Anzahl der Generationen wurde auf 20 festgelegt, da sich dieser Wert als ausreichend erwiesen hat, um Konvergenz zu erreichen. Darüber hinaus wurden die Standardwerte für die internen Parameter des Optimierers unverändert belassen, da sie durchweg gute Leistungen erbrachten und in der Literatur und in den Implementierungsrichtlinien allgemein empfohlen werden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "021187a8-c6f9-4f31-89f8-32dbb85ec5f6",
      "metadata": {},
      "source": [
        "<span id=\"get-support\" />\n",
        "\n",
        "# Unterstützung anfordern\n",
        "\n",
        "Wenn Sie Hilfe benötigen, können Sie eine E-Mail [globaldataquantum.com qpo.support](mailto:qpo.support@globaldataquantum.com) senden. Geben Sie in Ihrer Nachricht die Job-ID der Funktion an.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0a6148bb-1b04-4ad8-bbaf-3cba2b41b037",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"note\" title=\"Empfehlungen\">\n",
        "  * Lesen Sie [das zugehörige Forschungspapier](https://arxiv.org/pdf/2412.19150).\n",
        "  * * Rufen Sie die [API-Referenz](/docs/api/functions/global-data-quantum-optimizer) für diese Qiskit-Funktion auf.\n",
        "  * Beantragen Sie den Zugriff auf die Funktion, indem Sie [dieses Formular](https://globaldatum.io/qiskit-function/#form) ausfüllen.\n",
        "  * Probieren Sie die Anleitung [Dynamic Portfolio Optimization](/docs/tutorials/global-data-quantum-optimizer) aus.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "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"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}