def get_pdf(qu, S0, sig, r, T):
    """
    Function to extract probability distribution functions
    :param qu: Number of qubits
    :param S0: Initial price
    :param sig: Volatility
    :param r: Interest rate
    :param T: Maturity date
    :return: uncertainty models, (values, pdf), (mu, mean, variance)
    """
    mu = ((r - 0.5 * sig**2) * T + np.log(S0)
          )  # parameters for the log_normal distribution
    sigma = sig * np.sqrt(T)
    mean = np.exp(mu + sigma**2 / 2)
    variance = (np.exp(sigma**2) - 1) * np.exp(2 * mu + sigma**2)
    stddev = np.sqrt(variance)

    # lowest and highest value considered for the spot price; in between, an equidistant discretization is considered.
    low = np.maximum(0, mean - 3 * stddev)
    high = mean + 3 * stddev
    # S = np.linspace(low, high, samples)

    # construct circuit factory for uncertainty model
    uncertainty_model = LogNormalDistribution(min(16, qu),
                                              mu=mu,
                                              sigma=sigma,
                                              low=low,
                                              high=high)

    values = uncertainty_model.values
    pdf = uncertainty_model.probabilities

    return uncertainty_model, (values, pdf), (mu, mean, variance)
def load_payoff_quantum_sim(qu, S0, sig, r, T, K, error=0.05):
    """
    Function to create quantum circuit to return an approximate probability distribution.
        This function is thought to be the prelude of run_payoff_quantum_sim
    :param qu: Number of qubits
    :param S0: Initial price
    :param sig: Volatility
    :param r: Interest rate
    :param T: Maturity date
    :param K: strike
    :return: quantum circuit, backend, prices
    """

    mu = ((r - 0.5 * sig**2) * T + np.log(S0)
          )  # parameters for the log_normal distribution
    sigma = sig * np.sqrt(T)
    mean = np.exp(mu + sigma**2 / 2)
    variance = (np.exp(sigma**2) - 1) * np.exp(2 * mu + sigma**2)
    stddev = np.sqrt(variance)

    # lowest and highest value considered for the spot price; in between, an equidistant discretization is considered.
    low = np.maximum(0, mean - 3 * stddev)
    high = mean + 3 * stddev
    # S = np.linspace(low, high, samples)

    # construct circuit factory for uncertainty model
    uncertainty_model = LogNormalDistribution(qu,
                                              mu=mu,
                                              sigma=sigma,
                                              low=low,
                                              high=high)

    # values = uncertainty_model.values
    # pdf = uncertainty_model.probabilities

    qr = QuantumRegister(2 * qu + 2)
    cr = ClassicalRegister(1)
    qc = QuantumCircuit(qr, cr)
    uncertainty_model.build(qc, qr)

    k, c = payoff_circuit(qc, qu, K, high, low, error=error)

    return c, k, high, low, qc
Exemple #3
0
    def test_expected_value(self, simulator):

        # number of qubits to represent the uncertainty
        num_uncertainty_qubits = 3

        # parameters for considered random distribution
        S = 2.0  # initial spot price
        vol = 0.4  # volatility of 40%
        r = 0.05  # annual interest rate of 4%
        T = 40 / 365  # 40 days to maturity

        # resulting parameters for log-normal distribution
        mu = ((r - 0.5 * vol**2) * T + np.log(S))
        sigma = vol * np.sqrt(T)
        mean = np.exp(mu + sigma**2 / 2)
        variance = (np.exp(sigma**2) - 1) * np.exp(2 * mu + sigma**2)
        stddev = np.sqrt(variance)

        # lowest and highest value considered for the spot price; in between, an equidistant discretization is considered.
        low = np.maximum(0, mean - 3 * stddev)
        high = mean + 3 * stddev

        # construct circuit factory for uncertainty model
        uncertainty_model = LogNormalDistribution(num_uncertainty_qubits,
                                                  mu=mu,
                                                  sigma=sigma,
                                                  low=low,
                                                  high=high)

        # set the strike price (should be within the low and the high value of the uncertainty)
        strike_price = 2

        # set the approximation scaling for the payoff function
        c_approx = 0.5

        # construct circuit factory for payoff function
        european_call = EuropeanCallExpectedValue(uncertainty_model,
                                                  strike_price=strike_price,
                                                  c_approx=c_approx)

        # set number of evaluation qubits (samples)
        m = 3

        # construct amplitude estimation
        ae = AmplitudeEstimation(m, european_call)

        # run simulation
        quantum_instance = QuantumInstance(BasicAer.get_backend(simulator),
                                           circuit_caching=False)
        result = ae.run(quantum_instance=quantum_instance)

        # compare to precomputed solution
        self.assertEqual(
            0.0, np.round(result['estimation'] - 0.045705353233, decimals=4))
def load_Q_operator(qu, depth, S0, sig, r, T, K, error=0.05):
    """
    Function to create quantum circuit for the unary representation to return an approximate probability distribution.
        This function is thought to be the prelude of run_payoff_quantum_sim
    :param qu: Number of qubits
    :param S0: Initial price
    :param depth: Number of implementations of Q
    :param sig: Volatility
    :param r: Interest rate
    :param T: Maturity date
    :param K: strike
    :return: quantum circuit, backend, prices
    """
    depth = int(depth)

    mu = ((r - 0.5 * sig**2) * T + np.log(S0)
          )  # parameters for the log_normal distribution
    sigma = sig * np.sqrt(T)
    mean = np.exp(mu + sigma**2 / 2)
    variance = (np.exp(sigma**2) - 1) * np.exp(2 * mu + sigma**2)
    stddev = np.sqrt(variance)

    # lowest and highest value considered for the spot price; in between, an equidistant discretization is considered.
    low = np.maximum(0, mean - 3 * stddev)
    high = mean + 3 * stddev
    #S = np.linspace(low, high, samples)

    # construct circuit factory for uncertainty model
    uncertainty_model = LogNormalDistribution(qu,
                                              mu=mu,
                                              sigma=sigma,
                                              low=low,
                                              high=high)

    qr = QuantumRegister(2 * qu + 2)
    cr = ClassicalRegister(1)
    qc = QuantumCircuit(qr, cr)

    uncertainty_model.build(qc, qr)
    (k, c) = payoff_circuit(qc, qu, K, high, low, error=error, measure=False)

    for i in range(depth):
        oracle_operator(qc, qu)
        payoff_circuit_inv(qc, qu, K, high, low, error=error, measure=False)
        uncertainty_model.build_inverse(qc, qr)
        diffusion_operator(qc, qu)
        uncertainty_model.build(qc, qr)
        payoff_circuit(qc, qu, K, high, low, error=error, measure=False)

    qc.measure([2 * qu + 1], [0])
    return qc, (k, c, high, low)
def load_quantum_sim(qu, S0, sig, r, T):
    """
    Function to create quantum circuit for the binary representation to return an approximate probability distribution.
        This function is thought to be the prelude of run_quantum_sim
    :param qu: Number of qubits
    :param S0: Initial price
    :param sig: Volatility
    :param r: Interest rate
    :param T: Maturity date
    :return: quantum circuit, backend, (values of prices, prob. distri. function), (mu, mean, variance)
    """
    mu = ((r - 0.5 * sig**2) * T + np.log(S0)
          )  # parameters for the log_normal distribution
    sigma = sig * np.sqrt(T)
    mean = np.exp(mu + sigma**2 / 2)
    variance = (np.exp(sigma**2) - 1) * np.exp(2 * mu + sigma**2)
    stddev = np.sqrt(variance)

    # lowest and highest value considered for the spot price; in between, an equidistant discretization is considered.
    low = np.maximum(0, mean - 3 * stddev)
    high = mean + 3 * stddev
    # S = np.linspace(low, high, samples)

    # construct circuit factory for uncertainty model
    uncertainty_model = LogNormalDistribution(qu,
                                              mu=mu,
                                              sigma=sigma,
                                              low=low,
                                              high=high)

    values = uncertainty_model.values
    pdf = uncertainty_model.probabilities

    qr = QuantumRegister(qu)
    cr = ClassicalRegister(qu)
    qc = QuantumCircuit(qr, cr)
    uncertainty_model.build(qc, qr)
    qc.measure(np.arange(0, qu), np.arange(0, qu))

    return qc, (values, pdf), (mu, mean, variance)
Exemple #6
0
    def setUp(self):
        super().setUp()

        # number of qubits to represent the uncertainty
        num_uncertainty_qubits = 3

        # parameters for considered random distribution
        s_p = 2.0  # initial spot price
        vol = 0.4  # volatility of 40%
        r = 0.05  # annual interest rate of 4%
        t_m = 40 / 365  # 40 days to maturity

        # resulting parameters for log-normal distribution
        m_u = ((r - 0.5 * vol**2) * t_m + np.log(s_p))
        sigma = vol * np.sqrt(t_m)
        mean = np.exp(m_u + sigma**2 / 2)
        variance = (np.exp(sigma**2) - 1) * np.exp(2 * m_u + sigma**2)
        stddev = np.sqrt(variance)

        # lowest and highest value considered for the spot price;
        # in between, an equidistant discretization is considered.
        low = np.maximum(0, mean - 3 * stddev)
        high = mean + 3 * stddev

        # construct circuit factory for uncertainty model
        uncertainty_model = LogNormalDistribution(num_uncertainty_qubits,
                                                  mu=m_u,
                                                  sigma=sigma,
                                                  low=low,
                                                  high=high)

        # set the strike price (should be within the low and the high value of the uncertainty)
        strike_price = 1.896

        # set the approximation scaling for the payoff function
        c_approx = 0.1

        # setup piecewise linear objective function
        breakpoints = [uncertainty_model.low, strike_price]
        slopes = [0, 1]
        offsets = [0, 0]
        f_min = 0
        f_max = uncertainty_model.high - strike_price
        european_call_objective = PwlObjective(
            uncertainty_model.num_target_qubits, uncertainty_model.low,
            uncertainty_model.high, breakpoints, slopes, offsets, f_min, f_max,
            c_approx)

        # construct circuit factory for payoff function
        self.european_call = UnivariateProblem(uncertainty_model,
                                               european_call_objective)

        # construct circuit factory for payoff function
        self.european_call_delta = EuropeanCallDelta(
            uncertainty_model,
            strike_price=strike_price,
        )

        self._statevector = QuantumInstance(
            backend=BasicAer.get_backend('statevector_simulator'),
            seed_simulator=2,
            seed_transpiler=2)
        self._qasm = QuantumInstance(
            backend=BasicAer.get_backend('qasm_simulator'),
            shots=100,
            seed_simulator=2,
            seed_transpiler=2)
    def __init__(self, value, spot_price, volatility, int_rate, days,
                 strike_price):
        self.value = value
        # Number of qubits to represent the uncertainty
        num_uncertainty_qubits = 3

        # Parameters
        try:
            S = float(spot_price)
            vol = float(volatility)
            r = float(int_rate)
            T = int(days) / 365
            strike_price = float(strike_price)
        except ValueError:
            print("Some parameters wrong !!! ")

        mu = ((r - 0.5 * vol**2) * T + np.log(S))
        sigma = vol * np.sqrt(T)
        mean = np.exp(mu + sigma**2 / 2)
        variance = (np.exp(sigma**2) - 1) * np.exp(2 * mu + sigma**2)
        stddev = np.sqrt(variance)

        low = np.maximum(0, mean - 3 * stddev)
        high = mean + 3 * stddev

        # Circuit factory for uncertainty model
        self.uncertainty_model = LogNormalDistribution(num_uncertainty_qubits,
                                                       mu=mu,
                                                       sigma=sigma,
                                                       low=low,
                                                       high=high)

        try:
            self.strike_price = float(strike_price)
        except ValueError:
            print("Some parameters wrong !!! ")

        # The approximation scaling for the payoff function
        c_approx_payoff = 0.25  #abs(S-self.strike_price)
        print(c_approx_payoff)

        breakpoints = [self.uncertainty_model.low, self.strike_price]

        if self.value == str("call"):
            slopes_payoff = [0, 1]
        else:
            slopes_payoff = [-1, 0]

        if self.value == str("call"):
            offsets_payoff = [0, 0]
        else:
            offsets_payoff = [
                self.strike_price - self.uncertainty_model.low, 0
            ]

        f_min_payoff = 0

        if self.value == str("call"):
            f_max_payoff = self.uncertainty_model.high - self.strike_price
        else:
            f_max_payoff = self.strike_price - self.uncertainty_model.low

        european_objective = PwlObjective(
            self.uncertainty_model.num_target_qubits,
            self.uncertainty_model.low, self.uncertainty_model.high,
            breakpoints, slopes_payoff, offsets_payoff, f_min_payoff,
            f_max_payoff, c_approx_payoff)

        # Circuit factory for payoff function
        self.european_payoff = UnivariateProblem(self.uncertainty_model,
                                                 european_objective)

        slopes_delta = [0, 0]

        if self.value == str("call"):
            offsets_delta = [0, 1]
        else:
            offsets_delta = [1, 0]

        f_min_delta = 0

        f_max_delta = 1

        c_approx_delta = 1

        european_delta_objective = PwlObjective(
            self.uncertainty_model.num_target_qubits,
            self.uncertainty_model.low, self.uncertainty_model.high,
            breakpoints, slopes_delta, offsets_delta, f_min_delta, f_max_delta,
            c_approx_delta)

        self.european_delta = UnivariateProblem(self.uncertainty_model,
                                                european_delta_objective)
for i in sortedkeys:
    for j in counts:
        if (i == j):
            sortedcounts.append(counts.get(j))

plt.suptitle('Uniform Distribution')
plt.plot(sortedcounts)
plt.show()

print("\n Log-Normal Distribution")
print("-----------------")

circuit = QuantumCircuit(q, c)
lognorm = LogNormalDistribution(num_target_qubits=5,
                                mu=0,
                                sigma=1,
                                low=0,
                                high=1)
lognorm.build(circuit, q)
circuit.measure(q, c)

circuit.draw(output='mpl', filename='log.png')

job = execute(circuit, backend, shots=8192)
job_monitor(job)
counts = job.result().get_counts()

print(counts)

sortedcounts = []
sortedkeys = sorted(counts)
Exemple #9
0
# resulting parameters for log-normal distribution
mu = ((r - 0.5 * vol**2) * T + np.log(S))
sigma = vol * np.sqrt(T)
mean = np.exp(mu + sigma**2 / 2)
variance = (np.exp(sigma**2) - 1) * np.exp(2 * mu + sigma**2)
stddev = np.sqrt(variance)

# lowest and highest value considered for the spot price; in between, an equidistant discretization is considered.
low = np.maximum(0, mean - 3 * stddev)
high = mean + 3 * stddev

# construct circuit factory for uncertainty model
uncertainty_model = LogNormalDistribution(num_uncertainty_qubits,
                                          mu=mu,
                                          sigma=sigma,
                                          low=low,
                                          high=high)

# plot probability distribution
x = uncertainty_model.values
y = uncertainty_model.probabilities
plt.bar(x, y, width=0.2)
plt.xticks(x, size=15, rotation=90)
plt.yticks(size=15)
plt.grid()
plt.xlabel('Spot Price at Maturity $S_T$ (\$)', size=15)
plt.ylabel('Probability ($\%$)', size=15)
# should show graph
plt.show()