Skip to content

Finance

Classiq financial package provides a rich interface to automatically generate and execute quantum circuits for various financial problems, such as options pricing and risk analysis. The financial problems model is divided into two parts: the first is the financial model, and the second is the function that acts on this model.

Introduction and background

Complex models and simulations, borrowed from the world of physics, are very common in Finance. Many of these models are stochastic in nature, hence, numerical methods have to be employed for solving them. The most popular model is Monte Carlo [1] due to its flexibility and ability to generically handle stochastic parameters. Classical Monte Carlo methods however generally require extensive computational resources to provide an accurate estimation. By leveraging the laws of quantum mechanics a quantum computer may provide novel ways to solve such computationally intensive financial problems. Relevant Financial applications include risk management, portfolio optimization, and option pricing. The core of several of these applications is the Amplitude Estimation algorithm [2] which can estimate a parameter with a convergence rate of 1/M, where M is the number of Grover iterations, representing a theoretical quadratic speed-up over classical Monte Carlo methods.

Example 1

Quantum Risk analysis

Risk analysis aims to evaluate the potential for loss in an investment. Specifically, an investor needs to quantify how large a loss on investment could be, given a certain level of confidence, over a period of time. This quantity is known as the Value at risk (VaR). The value at risk is based on the statistical characteristics of the investment, and the shape of its distribution curve. It is evaluated using intensive computations of the aggregated value for M different realizations of portfolio assets model. The width of the confidence interval scales like \(O(M^{-1/2})\). To calculate the value at risk of some assets portfolio on a quantum computer we define the VaR such that [3] :

\[ VaR = argmin_{x_0}{(P(x > x_0) <= \alpha)} \]

where \(x \in {0,...N-1}\) and \(\alpha\) is the confidence level, i.e. the percentage that a loss will be larger than the VaR. The VaR is the smallest value of x with a confidence level of \(\alpha\).

To create a quantum circuit that can solve this kind of problem, one needs to:

  • Create a distribution function that represents the assets portfolio
  • Construct the VaR operator
  • Extract the Value at Risk using amplitude estimation.

This can be done using classiq financial package in two phases:

  • Financial model which contains the distribution function and
  • Financial function \(f_x(i)\) that is implemented by the model.

Financial model:

{
    "logic_flow": [
        {
            "function": "Finance",
            "function_params": {
                "model": {
                    "name": "gaussian",
                    "params": {
                        "num_qubits":2,
                        "normal_max_value":2,
                        "default_probabilities":[0.15, 0.25],
                        "rhos":[0.1, 0.05],
                        "loss":[1, 2],
                        "min_loss":0
                    }
                },
                "finance_function": {
                    "f": "var",
                    "condition": {
                        "threshold":2,
                        "larger": true}
                }
            }
        }
    ]
}
from classiq import Model
from classiq.builtin_functions import Finance
from classiq.applications.finance import (
    model_input,
    function_input,
    gaussian_model_input
)

model = Model()
gaussian_input = gaussian_model_input.GaussianModelInput(
    num_qubits=2,
    normal_max_value=2,
    default_probabilities=[0.15, 0.25],
    rhos=[0.1, 0.05],
    loss=[1, 2],
    min_loss=0
)
finance_model = model_input.FinanceModelInput(name="gaussian", params=gaussian_input)

condition = function_input.FunctionCondition(threshold=2, larger=True)
finance_function = function_input.FinanceFunctionInput(
    f="var",
    condition=condition,
)
model.Finance(Finance(model=finance_model, finance_function=finance_function))

circuit = model.synthesize()

In the example above the model is a gaussian model (called Conditioned Gaussian) of a two assets portfolio. The parameters that define this model are:

  • num qubits (int): Number of qubits that describes the accuracy of the Gaussian
  • normal max value (float): The discrete number where the Gaussian is truncated,
  • default probabilities (List[float]): The loss probability of each asset
  • rhos (List[float]): The width of the Gaussian
  • loss (List[int]): The loss of each asset
  • min loss (int): The minimum loss of the entire distribution

Financial Function

On the same financial model, one can generate several quantum circuits with different financial functions. In the current example we generate the VaR function:

{
  "logic_flow": [
    {
      "function": "Finance",
      "function_params": {
        "model": {
          "name": "gaussian",
          "params": {
            "num_qubits": 2,
            "normal_max_value": 2,
            "default_probabilities": [
              0.15,
              0.25
            ],
            "rhos": [
              0.1,
              0.05
            ],
            "loss": [
              1,
              2
            ],
            "min_loss": 0
          }
        },
        "finance_function": {
          "f": "var",
          "condition": {
            "threshold": 2,
            "larger": true
          }
        }
      }
    }
  ]
}
from classiq import Model
from classiq.builtin_functions import Finance
from classiq.applications.finance import (
    model_input,
    function_input,
    gaussian_model_input
)

model = Model()
gaussian_input = gaussian_model_input.GaussianModelInput(
    num_qubits=2,
    normal_max_value=2,
    default_probabilities=[0.15, 0.25],
    rhos=[0.1, 0.05],
    loss=[1, 2],
    min_loss=0
)
finance_model = model_input.FinanceModelInput(name="gaussian", params=gaussian_input)

condition = function_input.FunctionCondition(threshold=2, larger=True)
finance_function = function_input.FinanceFunctionInput(
    f="var",
    condition=condition,
)
model.Finance(Finance(model=finance_model, finance_function=finance_function))

circuit = model.synthesize()

The output circuit, with some (but not all) of its blocks expanded, will be: alt text

This circuit can be executed on a quantum computer.

Synthesizing a financial model in the IDE

The screenshot below shows the IDE when the Finance option is selected form the application suite.

finance-ide

An additional section is added below Preferences with editable model parameters, corresponding to the model input parameters described on this documentation page. This side panel simplifies manual tweaking of model parameters. Pressing the Synthesize button will generate the model and show its graphical representation.

Execute quantum circuit

The generated circuit can be executed from the execution section of the IDE ( see execution) using Amplitude Estimation or from the SDK.

For execution from within the IDE, select the execution from the side pane.

execution_button

You can then select the execution resource using the drop-down filters for vendor and device type.

execution_button

Finally, enter the required preferences for performing amplitude estimation into the appropriate group of fields. The image below shows an example of such parameters.

execution_button

An example of execution from the SDK is shown in the snippet below.

from classiq import Model, Executor
from classiq.builtin_functions import Finance
from classiq.execution import AmplitudeEstimation
from classiq.applications.finance import (
    model_input,
    function_input,
    gaussian_model_input,
)

model = Model()
gaussian_input = gaussian_model_input.GaussianModelInput(
    num_qubits=2,
    normal_max_value=2,
    default_probabilities=[0.15, 0.25],
    rhos=[0.1, 0.05],
    loss=[1, 2],
    min_loss=0,
)
finance_model = model_input.FinanceModelInput(name="gaussian", params=gaussian_input)

condition = function_input.FunctionCondition(threshold=2, larger=True)
finance_function = function_input.FinanceFunctionInput(
    f="var",
    condition=condition,
)
model.Finance(Finance(model=finance_model, finance_function=finance_function))

circuit = model.synthesize()

res = Executor(
    amplitude_estimation=AmplitudeEstimation(
        alpha=0.5, epsilon=0.5, binary_search_threshold=0.05
    )
).execute(circuit)

In this example, we are running amplitude estimation, which is the quantum analog to Monte Carlo simulation generally used for this kind of problems. To find the value at risk we use binary search. The value at risk is the loss value that corresponds to the percentile we have inserted at the binary search threshold.

Example 2

Option pricing

An option is the possibility to buy (call) or sell (put) an item (or share) at a known price - the strike price (K) The option has a maturity price (S). The payoff function to describe for example an european call option will be:

\[ \Bigg\{\begin{array}{lr} 0, & \text{when } K\geq S\\ S - K, & \text{when } K < S\end{array} \]

The maturity price is unknown therefore it is expressed by a price distribution function, which may be any type of distribution function. For example a log-normal distribution: \(X=e^{\mu+\sigma Z}\), where \(\mu,\sigma\) are the mean and std respectively and Z is the standard normal distribution.

To estimate the option price using a quantum computer, one needs to:

  • Load the wanted distribution, that is, discretize the distribution using \(2^n\) points (n is the number of qubits) and truncate it,
  • Implement the payoff function that is equal to zero if \(S\leq{K}\) and increases linearly. The linear part is approximated in order to be loaded properly using \(R_y\) rotations [3] .
  • Evaluate the expected payoff using amplitude estimation

This can be implemented as follows:

{
    "logic_flow": [
        {
            "function": "Finance",
            "function_params": {
                "model": {
                    "name": "log normal",
                    "params": {
                        "num_qubits":3,
                        "mu":0.68986,
                        "sigma":0.132417
                    }
                },
                "finance_function": {
                    "f": "european call option",
                    "condition": {
                        "threshold":1.896,
                        "larger": true
                    }
                }
            }
        }
    ]
}
from classiq import Model
from classiq.builtin_functions import Finance
from classiq.applications.finance import (
    model_input,
    function_input,
    log_normal_model_input,
)

model = Model()

log_normal_input = log_normal_model_input.LogNormalModelInput(
    num_qubits=3, mu=0.68986, sigma=0.132417
)
finance_model = model_input.FinanceModelInput(
    name="log normal", params=log_normal_input
)
condition = function_input.FunctionCondition(threshold=1.896, larger=True)
finance_function = function_input.FinanceFunctionInput(
    f="european call option",
    condition=condition,
)

model.Finance(Finance(model=finance_model, finance_function=finance_function))
circuit = model.synthesize()

This circuit can be executed via the IDE ( see execution), or using the SDK as demonstrated below:

from classiq import Model, Executor
from classiq.builtin_functions import Finance
from classiq.applications.finance import (
    model_input,
    function_input,
    log_normal_model_input,
)
from classiq.execution import AmplitudeEstimation

model = Model()

log_normal_input = log_normal_model_input.LogNormalModelInput(
    num_qubits=3, mu=0.68986, sigma=0.132417
)
finance_model = model_input.FinanceModelInput(name="log normal", params=log_normal_input)
condition = function_input.FunctionCondition(threshold=1.896, larger=True)
finance_function = function_input.FinanceFunctionInput(
    f="european call option",
    condition=condition,
)

model.Finance(Finance(model=finance_model, finance_function=finance_function))

circuit = model.synthesize()
res = Executor(
    amplitude_estimation=AmplitudeEstimation(
        alpha=0.5, epsilon=0.5, binary_search_threshold=None
    )
).execute(circuit)

Available models

The available models on the Classiq platform:

  • "gaussian", abbreviation for 'Gaussian conditional independence model'
  • "log normal"

Available functions

The available functions are:

  • "var"
  • "expected shortfall"
  • "european call option"
  • "x**2"

Example 3

The Classiq finance package allows the generation of any function using Chebyshev polynomial approximations. In the following example, the polynomial degree is the approximation degree.

{
  "logic_flow": [
    {
      "function": "Finance",
      "function_params": {
        "model": {
          "name": "gaussian",
          "params": {
            "num_qubits": 2,
            "normal_max_value": 2,
            "default_probabilities": [
              0.15,
              0.25
            ],
            "rhos": [
              0.1,
              0.05
            ],
            "loss": [
              1,
              2
            ],
            "min_loss": 0
          }
        },
        "finance_function": {
          "f": "european call option",
          "condition": {
            "threshold": 1.896,
            "larger": true
          },
          "polynomial_degree": 1,
          "use_chebyshev_polynomial_approximation": true
        }
      }
    }
  ]
}
from classiq.applications.finance import (
    function_input,
    log_normal_model_input,
)

condition = function_input.FunctionCondition(threshold=1.896, larger=True)
finance_function = function_input.FinanceFunctionInput(
    f="european call option",
    condition=condition,
    polynomial_degree=1,
    use_chebyshev_polynomial_approximation=True,
)

References

[1] Paul Glasserman, Monte Carlo Methods in Financial Engineering. Springer-Verlag New York, 2003, p. 596.

[2] Gilles Brassard, Peter Hoyer, Michele Mosca, and Alain Tapp, Quantum Amplitude Amplification and Estimation. Contemporary Mathematics 305 (2002)

[3] Woerner, S., Egger, D.J. Quantum risk analysis. npj Quantum Inf 5, 15 (2019).