def normal_distribution_plot(mu, sigma_sq): t_min = -5. t_max = 5. n = 1000 step = (t_max - t_min) / n x_val = range(n) # values on the x axis y_val = range(n) # y_values - normal distribution y_val_sn = range(n) # y_values - standard normal for k in range(n): x_val[k] = t_min + step * k y_val[k] = dist.normal_pdf(x_val[k], mu, sigma_sq) y_val_sn[k] = dist.standard_normal_pdf(x_val[k]) ####### ### prepare and show plot ### plt.plot(x_val, y_val, 'r-') plt.plot(x_val, y_val_sn, 'g--') plt.axis([t_min, t_max, min(y_val) * .9, max(y_val) * 1.5]) plt.title("Normal PDF") plt.xlabel("x") plt.ylabel("Probability") plt.show()
def plot_bachelier_digital_option(_time, _timestep, _strike): ####### ## call helper function to generate sufficient symmetric binomials ####### size = int(_time / _timestep) sample = random_sample_normal(size, _timestep) sq_t = np.sqrt(_timestep) path_bm = [0] * (size) path_digital_option = [0] * (size) path_digital_option_hedge = [0] * (size) mx = 0 mn = 0 x = [0.0] * (size) for k in range(size): x[k] = _timestep * k #### ## plot the trajectory of the process #### for j in range(size): _t_remain = np.sqrt(_time - x[j]) if (j == 0): path_bm[j] = 0. path_digital_option[j] = 1 - dist.standard_normal_cdf( (_strike - path_bm[j]) / _t_remain) path_digital_option_hedge[j] = path_digital_option[j] else: path_bm[j] = path_bm[j - 1] + sample[j] path_digital_option_hedge[j] = path_digital_option_hedge[ j - 1] + sample[j] * dist.standard_normal_pdf( (_strike - path_bm[j - 1]) / _t_remain) / _t_remain path_digital_option[j] = 1 - dist.standard_normal_cdf( (_strike - path_bm[j]) / _t_remain) mx = max(mx, max(path_digital_option)) mn = min(mn, min(path_digital_option)) ####### ### prepare and show plot ### plt.axis([0, max(x), 1.1 * mn, 1.1 * mx]) plt.title("Paths of Digital Option Value") plt.subplot(2, 1, 1) plt.plot(x, path_digital_option) plt.plot(x, path_digital_option_hedge) plt.ylabel('Option Value') plt.subplot(2, 1, 2) plt.plot(x, path_bm, 'r-') plt.ylabel('Underlying Value') plt.show()
def plot_maximising_goal_probability(_time, _timestep, _initial_capital, _target, _b, _r, _sigma): ####### ## call helper function to generate sufficient symmetric binomials ####### size = int(_time / _timestep) - 1 sample = random_sample_normal(size, _timestep) sq_t = np.sqrt(_timestep) path_underlying = [0] * (size) path_wealth = [0] * (size) path_portfolio = [0] * (size) mx = 0 mn = 0 x = [0.0] * (size) for k in range(size): x[k] = _timestep * k _theta = (_b - _r) / _sigma _y0 = np.sqrt(_time) * dist.standard_normal_inverse_cdf(_initial_capital * np.exp(_r * _time) / _target) #### ## create the various paths for plotting #### bm = 0 for j in range(size): _t_remain = _time - x[j] _t_sq_remain = np.sqrt(_t_remain) if (j == 0): path_underlying[j] = 1. path_wealth[j] = _initial_capital else: path_underlying[j] = path_underlying[j-1] * (1. + _b * _timestep + _sigma * sample[j]) bm = bm + sample[j] + _theta * _timestep path_wealth[j] = _target * np.exp( - _r * _t_remain ) * \ dist.standard_normal_cdf((bm + _y0) / _t_sq_remain) _y = path_wealth[j] * np.exp(_r * _t_remain) / _target path_portfolio[j] = dist.standard_normal_pdf(dist.standard_normal_inverse_cdf(_y)) / (_y * _sigma * _t_sq_remain) mx = max(mx, max(path_wealth)) mn = min(mn, min(path_wealth)) ####### ### prepare and show plot ### plt.axis([0, max(x), 1.1 * mn, 1.1 * mx]) plt.subplot(3, 1, 1) plt.title("Maximising Probability of Reaching a Goal") plt.plot(x, path_underlying) plt.ylabel('Stock Price') plt.subplot(3, 1, 2) plt.plot(x, path_wealth, 'r-') plt.ylabel('Wealth Process') plt.subplot(3, 1, 3) plt.plot(x, path_portfolio, 'r-') plt.ylabel('Portfolio Value') plt.show()
def expected_positive_exposure(_mean, _variance): y = _mean / np.sqrt(_variance) return _mean * dist.standard_normal_cdf(y) + np.sqrt( _variance) * dist.standard_normal_pdf(y)
def binomial_lln_hist(sample_size, repeats, p): ## ## we are sampling from a $B(1,p)$ distribution ## n = sample_size # this is how often we sample each time. lower_bound = 0. upper_bound = 1. plotCLN = True sample_value = range(repeats) for i in sample_value: prev_sum = 0 sum = 0 ## Step 1 - create sample of independent uniform random variables ### This code uses uniform random variables and the quantile transform uni_sample = np.random.uniform(lower_bound, upper_bound, sample_size) sample = range(n) for j in range(n): sample[j] = dist.binomial_inverse_cdf(p, uni_sample[j]) for k in range(n): if (k == 0): sum = sample[k] else: prev_sum = sum sum = sum + sample[k - 1] if plotCLN: sample_value[i] = (sum - sample_size * p) / np.sqrt( sample_size * p * (1 - p)) else: sample_value[i] = sum / (sample_size) ## sample value for CLN ## ## we then turn the outcome into a histogram ## num_bins = 50 # the histogram of the data _n, bins, _hist = plt.hist(sample_value, num_bins, normed=True, facecolor='green', alpha=0.75) plt.xlabel('Outcome') plt.ylabel('Rel. Occurrence') plt.title( "Histogram of Average Sample of Size={1} of B(1,p) with p={0}".format( p, sample_size)) ###### overlay the actual normal distribution if plotCLN: y = range(0, num_bins + 1) for m in range(0, num_bins + 1): y[m] = dist.standard_normal_pdf(bins[m]) plt.plot(bins, y, 'r--') plt.show()