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)
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)
# set the approximation scaling for the payoff function c_approx = 0.25 # setup piecewise linear objective fcuntion breakpoints = [uncertainty_model.low, strike_price_1, strike_price_2] slopes = [0, 1, 0] offsets = [0, 0, strike_price_2 - strike_price_1] f_min = 0 f_max = strike_price_2 - strike_price_1 bull_spread_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 bull_spread = UnivariateProblem(uncertainty_model, bull_spread_objective) # plot exact payoff function (evaluated on the grid of the uncertainty model) x = uncertainty_model.values y = np.minimum(np.maximum(0, x - strike_price_1), strike_price_2 - strike_price_1) plt.plot(x, y, 'ro-') plt.grid() plt.title('Payoff Function', size=15) plt.xlabel('Spot Price', size=15) plt.ylabel('Payoff', size=15) plt.xticks(x, size=15, rotation=90) plt.yticks(size=15) plt.show() # evaluate exact expected value (normalized to the [0, 1] interval)