Use this file to discover all available pages before exploring further.
View on GitHub
Open this notebook in GitHub to run it yourself
This notebook covers the implementation of the rainbow option using Qmod.The role of the notebook is to verify the result of a different methodology on a small scale problem, as it grows exponentially in the gate count.In finance, a crucial aspect of asset pricing pertains to derivatives.Derivatives are contracts whose value is contingent upon another source, known as the underlying.The pricing of options—a specific derivative instrument—involves determining the fair market value (discounted payoff) of contracts that afford their holders the right, although not the obligation, to buy (call) or sell (put) one or more underlying assets at a predefined strike price by a specified future expiration date (maturity date).This process relies on mathematical models, considering variables such as current asset prices, time to expiration, volatility, and interest rates.
Encode the probability distribution of a discrete multivariate random variable W taking values in {w0,..,wN−1} describing the asset prices at the maturity date.The number of discretized values, denoted as N, depends on the precision of the state preparation module and is consequently connected to the number of qubits (n=) according to the formula N=2n:i=0∑N−1p(wi)∣wi⟩
To avoid meaningless results, the process must stop if the strike price K is greater than the maximum value reacheable by the assets during the simulation. In this case, the payoff is 0, so there is no need to simulate:
from IPython.display import Markdownif K >= max(S0 * np.exp(np.dot(CHOLESKY, [grid_points[-1]] * 2) + MU)): display( Markdown( "<font color='red'> K always greater than the maximum asset values.Stop the run, the payoff is 0</font>" ) )
Considering the time delta between the starting date (t0) and the maturity date (t), express the return value Ri for the i-th asset as Ri=μi+yi whereμi=(t−t0)μ~i, being μ~i the expected daily log-return value. It can be estimated by considering the historical time series of log returns for the i-th asset.yi is obtained through the dot product between the matrix L and the standard multivariate Gaussian sample:yi=Δx⋅k∑likdk+xmin⋅k∑likΔx is the Gaussian discretization step, xmin is the lower Gaussian truncation value, and dk∈[0,2m−1] is the sample taken from the k-th standard Gaussian.
lik is the i,k entry of the matrix L, defined as L=C(t−t0), where C is the lower triangular matrix obtained by applying the Cholesky decomposition to the historical daily log-return correlation matrix:
This type of amplitude loading has an exponential scale, and is therefore used as a “sanity check” method for validating the result from the direct method and integration method that are part of the paper [1].
/var/folders/h1/cd4f05zs1bv9k8xcn5y2x17m0000gn/T/ipykernel_11657/1054662268.py:31: ClassiqDeprecationWarning: The '*=' operator is deprecated and will no longer be supported starting on 2025-12-03 at the earliest.Use the 'assign_amplitude_table' function instead ind_reg *= get_payoff_expression_normalized(
Output:
Quantum program link: https://platform.classiq.io/circuit/35601S9I1x9ngoD5kSqo49d60eV
/var/folders/h1/cd4f05zs1bv9k8xcn5y2x17m0000gn/T/ipykernel_11657/1054662268.py:31: ClassiqDeprecationWarning: The '*=' operator is deprecated and will no longer be supported starting on 2025-12-03 at the earliest.Use the 'assign_amplitude_table' function instead ind_reg *= get_payoff_expression_normalized(
Output:
Starting synthesis Quantum program link: https://platform.classiq.io/circuit/3560IQUU8u8M4IzsByiJOeDmb6N Starting execution
parsed_result, conf_interval = parse_result_bruteforce(result)print( f"raw iqae results: {result.estimation} with confidence interval {result.confidence_interval}")print( f"option estimated value: {parsed_result} with confidence interval {conf_interval}")
Output:
raw iqae results: 0.5048828125 with confidence interval [0.4732664268687129, 0.5364991981312871] option estimated value: 23.326296635630996 with confidence interval [ 9.96754032 36.68505295]
expected_payoff = 23.0238ALPHA_ASSERTION = 1e-5measured_confidence = conf_interval[1] - conf_interval[0]confidence_scale_by_alpha = np.sqrt( np.log(ALPHA / ALPHA_ASSERTION)) # based on e^2=(1/2N)*log(2T/alpha) from "Iterative Quantum Amplitude Estimation" since our alpha is low, we want to check within a bigger confidence intervalassert ( np.abs(parsed_result - expected_payoff) <= 0.5 * measured_confidence * confidence_scale_by_alpha), f"Payoff result is out of the {ALPHA_ASSERTION*100}% confidence interval: |{parsed_result} - {expected_payoff}| > {0.5*measured_confidence * confidence_scale_by_alpha}"