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 Integration Method for the rainbow option presented in [1].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, though 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=NUM_QUBITS) 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>" ) )
The comparator collects the probabilities g(r) of ∣r⟩ state until ∣r⟩ register is lower than ∣x⟩:=r=0∑2R−1g(r)∣x⟩∣r⟩∣r≤x⟩∣x⟩⊗r=0∑xg(r)∣r⟩∣1⟩+r=x∑2R−1g(r)∣r⟩∣0⟩Collecting the probability to have r≤x, define the function:h~(x)=r=0∑xg(r)Evaluating the probability to get a ∣1⟩ results in ∑x=02R−1h~(x).
To obtain a given function h~, choose a proper function g(r).The g(r) for r=0 value must therefore be:
g(0)={~h}(0)
and for all the other r:g(r)=h~(r)−h~(r−1)
@qfuncdef integrator(x: Const[QNum], ref: QNum, res: QBit) -> None: exp_rate = (1 / (2**x.fraction_digits)) * a prepare_exponential_state(-exp_rate, ref) res ^= x >= ref
from classiq.qmod.symbolic import asin, exp, sqrtdef get_strike_price_theta_integration(x: QNum): exp_rate = (1 / (2**x.fraction_digits)) * a B = (exp((2**x.size) * exp_rate) - 1) / exp(exp_rate) A = 1 / exp(exp_rate) C = S0[0] * exp((MU[0] + MIN_X * CHOLESKY[0].sum())) return 2 * asin(sqrt((K - (C * A)) / (C * B)))# this is not a qfunc, just a utility functiondef is_geq_strike_price( x: Const[QNum],) -> None: a = STEP_X / SCALING_FACTOR b = np.log(S0[0]) + MU[0] + MIN_X * CHOLESKY[0].sum() COMP_VALUE = (np.log(K) - b) / a return x > floor_factor(COMP_VALUE)@qfuncdef integration_payoff(max_reg: Const[QNum], integrator_reg: QNum, ind_reg: QBit): control( is_geq_strike_price(max_reg), lambda: integrator(max_reg, integrator_reg, ind_reg), lambda: RY(get_strike_price_theta_integration(max_reg), ind_reg), )
Add a term to the post-processing function:E[max(ea(xmax+1)−1ea(x+1)−1c+ea1,Ke−b′)]eb′−K=E[max(ea(xmax+1)−1ea(x+1)−1,cKe−b′−ce−a)]ceb′+eb′e−a−K
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}"