Portfolio optimization stands as one of the oldest and useful challenges in quantitative finance. While traditional computing methods have served us well, quantum computing offers a novel approach to tackle this complex problem. In this blog post, we'll explore how quantum computing can aid in portfolio optimization using Qiskit, IBM's quantum computing framework.
Understanding the Problem
Portfolio optimization essentially boils down to finding the optimal distribution of investments across different assets while balancing expected returns against risk. The classical Markowitz model formulates this as a quadratic programming problem, considering:
- Expected returns of assets
- Covariance matrix (representing risk)
- Investment constraints (like budget constraints)
Implementation Overview
Let's break down our quantum approach to portfolio optimization:
1. Setting Up the Environment
from qiskit.circuit.library import TwoLocal
from qiskit_finance.applications.optimization import PortfolioOptimization
from qiskit_finance.data_providers import RandomDataProvider
import datetime
We're using Qiskit's finance module, which provides specialized tools for financial applications. The code initializes a problem with 20 assets, using randomly generated data to simulate real market conditions:
num_assets = 20
stocks = [("TICKER%s" % i) for i in range(num_assets)]
data = RandomDataProvider(
tickers=stocks,
start=datetime.datetime(2016, 1, 1),
end=datetime.datetime(2016, 1, 30),
seed=seed,
)
2. Problem Formulation
The portfolio optimization problem is configured with three key parameters:
- Risk factor (q = 0.5): Balances the trade-off between risk and return
- Budget (num_assets // 2): Constrains the number of assets we can invest in
- Penalty term: Ensures the budget constraint is properly enforced
portfolio = PortfolioOptimization(
expected_returns=mu,
covariances=sigma,
risk_factor=q,
budget=budget
)
3. Implementation
This implementation uses two different approaches:
a. Exact Solver
exact_mes = NumPyMinimumEigensolver()
exact_eigensolver = MinimumEigenOptimizer(exact_mes)
result = exact_eigensolver.solve(qp)
This provides a baseline solution using direct solution with numpy. As the number of assets grow so does the complexity of calculating the exact solution. For huge number of assets, approximate methods are used instead.
b. Using Variational Quantum Eigensolver
ry = TwoLocal(num_assets, "ry", "crx", reps=3, entanglement="full")
svqe_mes = SamplingVQE(sampler=Sampler(), ansatz=ry, optimizer=cobyla)
svqe = MinimumEigenOptimizer(svqe_mes)
result = svqe.solve(qp)
TwoLocal creates an ansatz for initial state preparation. COBYLA is the optimizer.
Key Features and Benefits
1. The quantum approach can potentially provide better solution in complex combination of assets
2. Another approach can leverage the strengths of both classical and quantum computing where both of them provide advantage than their counterpart.
Results
For better visualisation of the results
def print_result(result):
selection = result.x
value = result.fval
print("Optimal: selection {}, value {:.4f}".format(selection, value))
eigenstate = result.min_eigen_solver_result.eigenstate
probabilities = (
eigenstate.binary_probabilities()
if isinstance(eigenstate, QuasiDistribution)
else {k: np.abs(v) ** 2 for k, v in eigenstate.to_dict().items()}
)
print("\n----------------- Full result ---------------------")
print("selection\tvalue\t\tprobability")
print("---------------------------------------------------")
probabilities = sorted(probabilities.items(), key=lambda x: x[1], reverse=True)
for k, v in probabilities:
x = np.array([int(i) for i in list(reversed(k))])
value = portfolio.to_quadratic_program().objective.evaluate(x)
print("%10s\t%.4f\t\t%.4f" % (x, value, v))
Conclusion
Quantum computing offers a new approach to portfolio optimization. While these implementations will not outperform classical methods in terms of time complexity they provide a pathway to achieve a better solution for large number of assets.
Comments