{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Pricing Basket Options" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Introduction\n", "
\n", "Suppose a basket option with strike price $K$ and two underlying assets whose spot price at maturity $S_T^1$, $S_T^2$ follow given random distributions.\n", "The corresponding payoff function is defined as:\n", "
\n", "
\n", "$$\\max\\{S_T^1 + S_T^2 - K, 0\\}$$\n", "
\n", "In the following, a quantum algorithm based on amplitude estimation is used to estimate the expected payoff, i.e., the fair price before discounting, for the option:\n", "
\n", "
\n", "$$\\mathbb{E}\\left[ \\max\\{S_T^1 + S_T^2 - K, 0\\} \\right].$$\n", "
\n", "The approximation of the objective function and a general introduction to option pricing and risk analysis on quantum computers are given in the following papers:\n", "\n", "- [Quantum Risk Analysis. Woerner, Egger. 2018.](https://arxiv.org/abs/1806.06893)\n", "- [Option Pricing using Quantum Computers. Stamatopoulos et al. 2019.](https://arxiv.org/abs/1905.02666)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2020-07-13T20:39:54.949868Z", "start_time": "2020-07-13T20:39:51.957621Z" } }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "from mpl_toolkits.mplot3d import Axes3D\n", "from scipy.interpolate import griddata\n", "%matplotlib inline\n", "import numpy as np\n", "\n", "from qiskit import Aer, QuantumRegister, QuantumCircuit, execute, AncillaRegister, transpile\n", "from qiskit.utils import QuantumInstance\n", "from qiskit.algorithms import IterativeAmplitudeEstimation, EstimationProblem\n", "from qiskit.circuit.library import WeightedAdder, LinearAmplitudeFunction\n", "from qiskit_finance.circuit.library import LogNormalDistribution" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Uncertainty Model\n", "\n", "We construct a circuit factory to load a multivariate log-normal random distribution into a quantum state on $n$ qubits.\n", "For every dimension $j = 1,\\ldots,d$, the distribution is truncated to a given interval $[\\text{low}_j, \\text{high}_j]$ and discretized using $2^{n_j}$ grid points, where $n_j$ denotes the number of qubits used to represent dimension $j$, i.e., $n_1+\\ldots+n_d = n$.\n", "The unitary operator corresponding to the circuit factory implements the following: \n", "\n", "$$\\big|0\\rangle_{n} \\mapsto \\big|\\psi\\rangle_{n} = \\sum_{i_1,\\ldots,i_d} \\sqrt{p_{i_1\\ldots i_d}}\\big|i_1\\rangle_{n_1}\\ldots\\big|i_d\\rangle_{n_d},$$\n", "\n", "where $p_{i_1\\ldots i_d}$ denote the probabilities corresponding to the truncated and discretized distribution and where $i_j$ is mapped to the right interval using the affine map:\n", "\n", "$$\\{0, \\ldots, 2^{n_j}-1\\} \\ni i_j \\mapsto \\frac{\\text{high}_j - \\text{low}_j}{2^{n_j} - 1} * i_j + \\text{low}_j \\in [\\text{low}_j, \\text{high}_j].$$\n", "\n", "For simplicity, we assume both stock prices are independent and identically distributed.\n", "This assumption just simplifies the parametrization below and can be easily relaxed to more complex and also correlated multivariate distributions.\n", "The only important assumption for the current implementation is that the discretization grid of the different dimensions has the same step size." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2020-07-13T20:39:54.963598Z", "start_time": "2020-07-13T20:39:54.951907Z" } }, "outputs": [], "source": [ "# number of qubits per dimension to represent the uncertainty \n", "num_uncertainty_qubits = 2\n", "\n", "# parameters for considered random distribution\n", "S = 2.0 # initial spot price\n", "vol = 0.4 # volatility of 40%\n", "r = 0.05 # annual interest rate of 4%\n", "T = 40 / 365 # 40 days to maturity\n", "\n", "# resulting parameters for log-normal distribution\n", "mu = ((r - 0.5 * vol**2) * T + np.log(S))\n", "sigma = vol * np.sqrt(T)\n", "mean = np.exp(mu + sigma**2/2)\n", "variance = (np.exp(sigma**2) - 1) * np.exp(2*mu + sigma**2)\n", "stddev = np.sqrt(variance)\n", "\n", "# lowest and highest value considered for the spot price; in between, an equidistant discretization is considered.\n", "low = np.maximum(0, mean - 3*stddev)\n", "high = mean + 3*stddev\n", "\n", "# map to higher dimensional distribution\n", "# for simplicity assuming dimensions are independent and identically distributed)\n", "dimension = 2\n", "num_qubits=[num_uncertainty_qubits]*dimension\n", "low=low*np.ones(dimension)\n", "high=high*np.ones(dimension)\n", "mu=mu*np.ones(dimension)\n", "cov=sigma**2*np.eye(dimension)\n", "\n", "# construct circuit factory\n", "u = LogNormalDistribution(num_qubits=num_qubits, mu=mu, sigma=cov, bounds=list(zip(low, high)))" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2020-07-13T20:39:55.563010Z", "start_time": "2020-07-13T20:39:54.966704Z" }, "tags": [ "nbsphinx-thumbnail" ] }, "outputs": [ { "output_type": "display_data", "data": { "text/plain": "