tno.quantum.problems.portfolio-optimization


Nametno.quantum.problems.portfolio-optimization JSON
Version 1.0.0 PyPI version JSON
download
home_pagehttps://tno.nl
SummaryQuantum Computing based Portfolio Optimization
upload_time2024-05-01 15:38:34
maintainerTNO Quantum
docs_urlNone
authorTNO Quantum
requires_pythonNone
licenseApache License, Version 2.0
keywords tno quantum portfolio optimization quantum annealing
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Portfolio optimization

Real-world investment decisions involve multiple, often conflicting, objectives that needs to be balanced.
Primary goals typically revolve around maximizing returns while minimizing risks.
At the same time, one might want to require additional constraints such as demanding a minimum carbon footprint reduction. 
Finding a portfolio that balances these objectives is a challenging task and can be solved using multi-objective portfolio optimization. 

This repository provides Python code that converts the multi-objective portfolio optimization problem
into a [QUBO](https://en.wikipedia.org/wiki/Quadratic_unconstrained_binary_optimization) problem. The transformed problem can then be solved using quantum annealing techniques.

The following objectives can be considered

- `return on capital`, indicated by `ROC`,
- `diversification`, indicated by the [Herfindahl-Hirschman Index](https://en.wikipedia.org/wiki/Herfindahl%E2%80%93Hirschman_inde) `HHI`.

Additionally, we allow for a capital growth factor and arbitrary emission reduction constraints to be considered.

The `Pareto front`, the set of solutions where one objective can't be improved without worsening the other objective,
can be computed for the objectives return on capital and diversification. 

The codebase is based on the following paper:

- [Aguilera et al., - Multi-objective Portfolio Optimisation Using the Quantum Annealer (2024)](https://www.mdpi.com/2227-7390/12/9/1291)

**Funding:** This research was funded by Rabobank and Stichting TKI High Tech Systems
and Materials, under a program by Brightland's Techruption.

*Limitations in (end-)use: the content of this software package may solely be used for applications that comply with international export control laws.*

## Documentation

Documentation of the `tno.quantum.problems.portfolio_optimization` package can be found [here](https://tno-quantum.github.io/problems.portfolio_optimization/).

## Install

Easily install the `tno.quantum.problems.portfolio_optimization` package using pip:

```console
$ python -m pip install tno.quantum.problems.portfolio_optimization
```

If you wish to use D-Wave quantum hardware:
```console
$ python -m pip install 'tno.quantum.problems.portfolio_optimization[quantum]'
```

If you wish to run the tests you can use:
```console
$ python -m pip install 'tno.quantum.problems.portfolio_optimization[tests]'
```

## Usage

<details>
  <summary>Solve portfolio optimization problem.</summary>

Here's an example of how the `PortfolioOptimizer` class can be used to define an portfolio optimization problem,
and subsequently, how the Pareto front can be computed using the simulated annealing sampler from D-Wave. 

```python
import numpy as np
from dwave.samplers import SimulatedAnnealingSampler

from tno.quantum.problems.portfolio_optimization import PortfolioOptimizer

# Choose sampler for solving qubo
sampler = SimulatedAnnealingSampler()
sampler_kwargs = {"num_reads": 20, "num_sweeps": 200}

# Set up penalty coefficients for the constraints
lambdas1 = np.logspace(-16, 1, 25, endpoint=False, base=10.0)
lambdas2 = np.logspace(-16, 1, 25, endpoint=False, base=10.0)
lambdas3 = np.array([1])

# Create portfolio optimization problem
portfolio_optimizer = PortfolioOptimizer("benchmark_dataset")
portfolio_optimizer.add_minimize_hhi(weights=lambdas1)
portfolio_optimizer.add_maximize_roc(formulation=1, weights_roc=lambdas2)
portfolio_optimizer.add_emission_constraint(
   weights=lambdas3,
   emission_now="emis_intens_now",
   emission_future="emis_intens_future",
   name="emission"
)

# Solve the portfolio optimization problem
results = portfolio_optimizer.run(sampler, sampler_kwargs)
```
</details>

<details>
  <summary>Visualize results.</summary>

The results can be inspected in more detail by looking at the Pandas results DataFrame
`results.results_df`.

Alternatively, the results can be plotted in a `(Diversification, ROC)`-graph. The
following example first slices the results in data points that do and do not satisfy the
constraints using the method `slice_results`. 

Note that:

- Individual data points can subsequently be plotted using the `plot_points` function.
- The Pareto front can be plotted using the `plot_front` function.

```python
import matplotlib.pyplot as plt

from tno.quantum.problems.portfolio_optimization import plot_front, plot_points

(x1, y1), (x2, y2) = results.slice_results()
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 5))

# Plot data points
plot_points(x2, y2, color="orange", label="QUBO constraint not met", ax=ax1)
plot_points(x1, y1, color="green", label="QUBO constraint met", ax=ax1)
ax1.set_title("Points")

# Plot Pareto front
plot_front(x2, y2, color="orange", label="QUBO constraint not met", ax=ax2)
plot_front(x1, y1, color="green", label="QUBO constraint met", ax=ax2)
ax2.set_title("Pareto Front")
fig.tight_layout()
plt.show()
```

</details>

![(Diversification, ROC)-Graph](https://github.com/TNO-Quantum/problems.portfolio_optimization/raw/main/images_for_docs/example.png)


More elaborate examples can be found in our [examples repository](https://github.com/TNO-Quantum/examples ).

Data input
----------

The data used for the portfolio optimization can be imported via an excel file, csv file,
json file or as a Pandas DataFrame.
The data needs to contain at least the following columns:

- `asset`: The name of the asset.
- `outstanding_now`: Current outstanding amount per asset.
- `min_outstanding_future`: Lower bound outstanding amount in the future per asset.
- `max_outstanding_future`: Upper bound outstanding amount in the future per asset.
- `income_now`: Current income per asset, corresponds to return multiplied by the current outstanding amount.
- `regcap_now`: Current regulatory capital per asset.


If the input datafile contains all the correct information, but has different column
names, it is possible to rename the columns without altering the input file.
Details and examples can be found in the [documentation]((https://tno-quantum.github.io/problems.portfolio_optimization/)).

The data that was used for the publication can be found in the `tno/quantum/problems/portfolio_optimization/datasets/` folder.


Using Quantum Annealing Solvers
-------------------------------

By default, the portfolio optimization QUBO is solved using simulated annealing.
Any D-Wave ``Sampler`` is however supported and can be provided to the `PortfolioOptimizer.run` method.
 

Below is an example how to initialise a quantum annealing sampler that uses `100` micro seconds annealing time per sample.
The example assumes a proper [configuration setup](https://docs.ocean.dwavesys.com/en/stable/overview/sapi.html) to the D-Wave's Solver API.

```python
from dwave.system import DWaveSampler, LazyFixedEmbeddingComposite

# Define QPU D-Wave Sampler
qpu = DWaveSampler()
sampler = LazyFixedEmbeddingComposite(qpu)
sampler_kwargs = {"annealing_time": 100}
```

We refer to the [D-Wave Sampler documentation](https://docs.ocean.dwavesys.com/projects/system/en/stable/reference/samplers.html) for information on usage of different samplers and their sampler arguments.

            

Raw data

            {
    "_id": null,
    "home_page": "https://tno.nl",
    "name": "tno.quantum.problems.portfolio-optimization",
    "maintainer": "TNO Quantum",
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": "tnoquantum@tno.nl",
    "keywords": "TNO, Quantum, Portfolio Optimization, Quantum Annealing",
    "author": "TNO Quantum",
    "author_email": "tnoquantum@tno.nl",
    "download_url": "https://files.pythonhosted.org/packages/97/e3/7e6584a4b8e50c53180e2b0965434924018f9435a2ff7fe749e29216082f/tno_quantum_problems_portfolio_optimization-1.0.0.tar.gz",
    "platform": "any",
    "description": "# Portfolio optimization\r\n\r\nReal-world investment decisions involve multiple, often conflicting, objectives that needs to be balanced.\r\nPrimary goals typically revolve around maximizing returns while minimizing risks.\r\nAt the same time, one might want to require additional constraints such as demanding a minimum carbon footprint reduction. \r\nFinding a portfolio that balances these objectives is a challenging task and can be solved using multi-objective portfolio optimization. \r\n\r\nThis repository provides Python code that converts the multi-objective portfolio optimization problem\r\ninto a [QUBO](https://en.wikipedia.org/wiki/Quadratic_unconstrained_binary_optimization) problem. The transformed problem can then be solved using quantum annealing techniques.\r\n\r\nThe following objectives can be considered\r\n\r\n- `return on capital`, indicated by `ROC`,\r\n- `diversification`, indicated by the [Herfindahl-Hirschman Index](https://en.wikipedia.org/wiki/Herfindahl%E2%80%93Hirschman_inde) `HHI`.\r\n\r\nAdditionally, we allow for a capital growth factor and arbitrary emission reduction constraints to be considered.\r\n\r\nThe `Pareto front`, the set of solutions where one objective can't be improved without worsening the other objective,\r\ncan be computed for the objectives return on capital and diversification. \r\n\r\nThe codebase is based on the following paper:\r\n\r\n- [Aguilera et al., - Multi-objective Portfolio Optimisation Using the Quantum Annealer (2024)](https://www.mdpi.com/2227-7390/12/9/1291)\r\n\r\n**Funding:** This research was funded by Rabobank and Stichting TKI High Tech Systems\r\nand Materials, under a program by Brightland's Techruption.\r\n\r\n*Limitations in (end-)use: the content of this software package may solely be used for applications that comply with international export control laws.*\r\n\r\n## Documentation\r\n\r\nDocumentation of the `tno.quantum.problems.portfolio_optimization` package can be found [here](https://tno-quantum.github.io/problems.portfolio_optimization/).\r\n\r\n## Install\r\n\r\nEasily install the `tno.quantum.problems.portfolio_optimization` package using pip:\r\n\r\n```console\r\n$ python -m pip install tno.quantum.problems.portfolio_optimization\r\n```\r\n\r\nIf you wish to use D-Wave quantum hardware:\r\n```console\r\n$ python -m pip install 'tno.quantum.problems.portfolio_optimization[quantum]'\r\n```\r\n\r\nIf you wish to run the tests you can use:\r\n```console\r\n$ python -m pip install 'tno.quantum.problems.portfolio_optimization[tests]'\r\n```\r\n\r\n## Usage\r\n\r\n<details>\r\n  <summary>Solve portfolio optimization problem.</summary>\r\n\r\nHere's an example of how the `PortfolioOptimizer` class can be used to define an portfolio optimization problem,\r\nand subsequently, how the Pareto front can be computed using the simulated annealing sampler from D-Wave. \r\n\r\n```python\r\nimport numpy as np\r\nfrom dwave.samplers import SimulatedAnnealingSampler\r\n\r\nfrom tno.quantum.problems.portfolio_optimization import PortfolioOptimizer\r\n\r\n# Choose sampler for solving qubo\r\nsampler = SimulatedAnnealingSampler()\r\nsampler_kwargs = {\"num_reads\": 20, \"num_sweeps\": 200}\r\n\r\n# Set up penalty coefficients for the constraints\r\nlambdas1 = np.logspace(-16, 1, 25, endpoint=False, base=10.0)\r\nlambdas2 = np.logspace(-16, 1, 25, endpoint=False, base=10.0)\r\nlambdas3 = np.array([1])\r\n\r\n# Create portfolio optimization problem\r\nportfolio_optimizer = PortfolioOptimizer(\"benchmark_dataset\")\r\nportfolio_optimizer.add_minimize_hhi(weights=lambdas1)\r\nportfolio_optimizer.add_maximize_roc(formulation=1, weights_roc=lambdas2)\r\nportfolio_optimizer.add_emission_constraint(\r\n   weights=lambdas3,\r\n   emission_now=\"emis_intens_now\",\r\n   emission_future=\"emis_intens_future\",\r\n   name=\"emission\"\r\n)\r\n\r\n# Solve the portfolio optimization problem\r\nresults = portfolio_optimizer.run(sampler, sampler_kwargs)\r\n```\r\n</details>\r\n\r\n<details>\r\n  <summary>Visualize results.</summary>\r\n\r\nThe results can be inspected in more detail by looking at the Pandas results DataFrame\r\n`results.results_df`.\r\n\r\nAlternatively, the results can be plotted in a `(Diversification, ROC)`-graph. The\r\nfollowing example first slices the results in data points that do and do not satisfy the\r\nconstraints using the method `slice_results`. \r\n\r\nNote that:\r\n\r\n- Individual data points can subsequently be plotted using the `plot_points` function.\r\n- The Pareto front can be plotted using the `plot_front` function.\r\n\r\n```python\r\nimport matplotlib.pyplot as plt\r\n\r\nfrom tno.quantum.problems.portfolio_optimization import plot_front, plot_points\r\n\r\n(x1, y1), (x2, y2) = results.slice_results()\r\nfig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 5))\r\n\r\n# Plot data points\r\nplot_points(x2, y2, color=\"orange\", label=\"QUBO constraint not met\", ax=ax1)\r\nplot_points(x1, y1, color=\"green\", label=\"QUBO constraint met\", ax=ax1)\r\nax1.set_title(\"Points\")\r\n\r\n# Plot Pareto front\r\nplot_front(x2, y2, color=\"orange\", label=\"QUBO constraint not met\", ax=ax2)\r\nplot_front(x1, y1, color=\"green\", label=\"QUBO constraint met\", ax=ax2)\r\nax2.set_title(\"Pareto Front\")\r\nfig.tight_layout()\r\nplt.show()\r\n```\r\n\r\n</details>\r\n\r\n![(Diversification, ROC)-Graph](https://github.com/TNO-Quantum/problems.portfolio_optimization/raw/main/images_for_docs/example.png)\r\n\r\n\r\nMore elaborate examples can be found in our [examples repository](https://github.com/TNO-Quantum/examples ).\r\n\r\nData input\r\n----------\r\n\r\nThe data used for the portfolio optimization can be imported via an excel file, csv file,\r\njson file or as a Pandas DataFrame.\r\nThe data needs to contain at least the following columns:\r\n\r\n- `asset`: The name of the asset.\r\n- `outstanding_now`: Current outstanding amount per asset.\r\n- `min_outstanding_future`: Lower bound outstanding amount in the future per asset.\r\n- `max_outstanding_future`: Upper bound outstanding amount in the future per asset.\r\n- `income_now`: Current income per asset, corresponds to return multiplied by the current outstanding amount.\r\n- `regcap_now`: Current regulatory capital per asset.\r\n\r\n\r\nIf the input datafile contains all the correct information, but has different column\r\nnames, it is possible to rename the columns without altering the input file.\r\nDetails and examples can be found in the [documentation]((https://tno-quantum.github.io/problems.portfolio_optimization/)).\r\n\r\nThe data that was used for the publication can be found in the `tno/quantum/problems/portfolio_optimization/datasets/` folder.\r\n\r\n\r\nUsing Quantum Annealing Solvers\r\n-------------------------------\r\n\r\nBy default, the portfolio optimization QUBO is solved using simulated annealing.\r\nAny D-Wave ``Sampler`` is however supported and can be provided to the `PortfolioOptimizer.run` method.\r\n \r\n\r\nBelow is an example how to initialise a quantum annealing sampler that uses `100` micro seconds annealing time per sample.\r\nThe example assumes a proper [configuration setup](https://docs.ocean.dwavesys.com/en/stable/overview/sapi.html) to the D-Wave's Solver API.\r\n\r\n```python\r\nfrom dwave.system import DWaveSampler, LazyFixedEmbeddingComposite\r\n\r\n# Define QPU D-Wave Sampler\r\nqpu = DWaveSampler()\r\nsampler = LazyFixedEmbeddingComposite(qpu)\r\nsampler_kwargs = {\"annealing_time\": 100}\r\n```\r\n\r\nWe refer to the [D-Wave Sampler documentation](https://docs.ocean.dwavesys.com/projects/system/en/stable/reference/samplers.html) for information on usage of different samplers and their sampler arguments.\r\n",
    "bugtrack_url": null,
    "license": "Apache License, Version 2.0",
    "summary": "Quantum Computing based Portfolio Optimization",
    "version": "1.0.0",
    "project_urls": {
        "Documentation": "https://tno-quantum.github.io/problems.portfolio_optimization/",
        "Download": "https://pypi.org/project/tno.quantum.problems.portfolio_optimization/#files",
        "Homepage": "https://tno.nl",
        "Source Code": "https://github.com/TNO-Quantum/problems.portfolio_optimization"
    },
    "split_keywords": [
        "tno",
        " quantum",
        " portfolio optimization",
        " quantum annealing"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2d1e78f0e9d18d8366aa5ce3a988208f18e4d9241ecfa5632265270d04b5f4ce",
                "md5": "8c5982e6e54445a4102f1059e26f739c",
                "sha256": "d049b94b1599131459ecaa07f1444e2d8820cb8c2e50a9476c66c7cc2284d3a3"
            },
            "downloads": -1,
            "filename": "tno.quantum.problems.portfolio_optimization-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8c5982e6e54445a4102f1059e26f739c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 50348,
            "upload_time": "2024-05-01T15:38:32",
            "upload_time_iso_8601": "2024-05-01T15:38:32.830458Z",
            "url": "https://files.pythonhosted.org/packages/2d/1e/78f0e9d18d8366aa5ce3a988208f18e4d9241ecfa5632265270d04b5f4ce/tno.quantum.problems.portfolio_optimization-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "97e37e6584a4b8e50c53180e2b0965434924018f9435a2ff7fe749e29216082f",
                "md5": "9c2af8f84207da7722129ba7bc67aa95",
                "sha256": "83154fed4696fac35fa9ba2c2a35bf7b9f4e3787c3e1ca0f50c0118d45bb27c0"
            },
            "downloads": -1,
            "filename": "tno_quantum_problems_portfolio_optimization-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "9c2af8f84207da7722129ba7bc67aa95",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 47195,
            "upload_time": "2024-05-01T15:38:34",
            "upload_time_iso_8601": "2024-05-01T15:38:34.549143Z",
            "url": "https://files.pythonhosted.org/packages/97/e3/7e6584a4b8e50c53180e2b0965434924018f9435a2ff7fe749e29216082f/tno_quantum_problems_portfolio_optimization-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-01 15:38:34",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "TNO-Quantum",
    "github_project": "problems.portfolio_optimization",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "tno.quantum.problems.portfolio-optimization"
}
        
Elapsed time: 0.31136s