def test_prices(self): while self.tdi.has_next(): row = self.tdi.next_row() S, K, t, r, sigma = row['S'], row['K'], row['t'], row['R'], row[ 'v'] self.assertTrue( almost_equal(black_scholes('c', S, K, t, r, sigma), row['bs_call'], epsilon=.000001)) self.assertTrue( almost_equal(black_scholes('p', S, K, t, r, sigma), row['bs_put'], epsilon=.000001))
def test_implied_volatility(self): while self.tdi.has_next(): row = self.tdi.next_row() S,K,t,r,sigma = row['S'],row['K'],row['t'],row['R'],row['v'] C,P = black_scholes('c', S, K, t, r, sigma), black_scholes('p', S, K, t, r, sigma) try: iv = implied_volatility(C, S, K, t, r, 'c') self.assertTrue(almost_equal(sigma, iv, epsilon = .0001)) except: print 'could not calculate iv for ', C, S, K, t, r, 'c' iv = implied_volatility(P, S, K, t, r, 'p') self.assertTrue(almost_equal(sigma, iv, epsilon = .001) or (iv ==0.0))
def test_prices(self): while self.tdi.has_next(): row = self.tdi.next_row() S,K,t,r,sigma = row['S'],row['K'],row['t'],row['R'],row['v'] self.assertTrue( almost_equal( black_scholes('c', S, K, t, r, sigma), row['bs_call'], epsilon=.000001 ) ) self.assertTrue( almost_equal( black_scholes('p', S, K, t, r, sigma), row['bs_put'], epsilon=.000001 ) )
def plot_numerical_vs_analytical(greek, flag): """Displays a plot comparing analytically and numerically computed values of a given greek and option type. :param flag: 'd','g','t','r', or 'v' :type flag: str :param flag: 'c' or 'p' for call or put. :type flag: str """ f_analytical, f_numerical = { 'd':(delta,ndelta), 'g':(gamma,ngamma), 't':(theta,ntheta), 'v':(vega,nvega), 'r':(rho, nrho), }[greek] S_vals = numpy.linspace(10,250,2000) K=100 t =.5 q =.05 sigma = 0.2 r = .01 price, analytical, numerical = [],[],[] for S in S_vals: analytical.append(f_analytical(flag, S, K, t, r, sigma)) numerical.append(f_numerical(flag, S, K, t, r, sigma)) price.append(black_scholes(flag, S, K, t, r, sigma)) plt.figure(1) plt.subplot(211) plt.plot(S_vals,analytical,label = 'Analytical') plt.plot(S_vals,numerical, label = 'Numerical') min_a, max_a = min(analytical), max(analytical) h = max_a-min_a plt.ylim(min_a - h*.05, max_a + h*.05) plt.grid() plt.legend(loc = 'best') plt.subplot(212) plt.plot(S_vals,price, label = 'Price') plt.ylim(min(min(price),-10), max(max(price),10)) plt.grid() plt.legend(loc = 'best') plt.show() #plot_numerical_vs_analytical('t','c')
def recalc(self,Scenario): global r S=self.underlying*(1+Scenario.fut/100.0) t=(self.expiry-(self.valdate+dt.timedelta(days=Scenario.expiry_delta))).total_seconds()/(365.0*24*60*60) sigma=self.vol+Scenario.vol/100.0 self.scenario_price=black_scholes(self.flag, S, self.strike, t, r, sigma) self.PnL=100*(self.scenario_price-self.price)/self.price return PnL(S,sigma,self.PnL)
def test_implied_volatility(self): while self.tdi.has_next(): row = self.tdi.next_row() S, K, t, r, sigma = row['S'], row['K'], row['t'], row['R'], row[ 'v'] C, P = black_scholes('c', S, K, t, r, sigma), black_scholes('p', S, K, t, r, sigma) try: iv = implied_volatility(C, S, K, t, r, 'c') self.assertTrue(almost_equal(sigma, iv, epsilon=.0001)) except: print('could not calculate iv for ', C, S, K, t, r, 'c') iv = implied_volatility(P, S, K, t, r, 'p') self.assertTrue( almost_equal(sigma, iv, epsilon=.001) or (iv == 0.0))
def test_prices(self): S = 100.0 for flag in ['c','p']: for K in numpy.linspace(20,200,10): for r in numpy.linspace(0,0.2,10): for sigma in numpy.linspace(0.1,0.5,10): for t in numpy.linspace(0.01,2,10): for i in range(5): val1 = black_scholes(flag, S, K, t, r, sigma) val2 = python_black_scholes(flag, S, K, t, r, sigma) results_match = abs(val1-val2)<epsilon if not results_match: print 'price mismatch:', flag, val1, val2 self.assertTrue(results_match)
def theoreticalPricer(algo_client): calls = [] puts = [] given_strikes = [233500, 234000, 234500, 235000, 235500] strikes = [ "C2335", "P2335", "C2340", "P2340", "C2345", "P2345", "C2350", "P2350", "C2355", "P2355" ] interest = .01 time_to_expiry = float(60 / 252) greeks = Greeks(algo_client, "ESM7", given_strikes, .01, .24) iv = greeks.return_implied_vol() for x in xrange(1, 3): calls.append(iv[given_strikes[x - 1]][0]) puts.append(iv[given_strikes[x - 1]][1]) theoreticalPrice = {} x = 0 while x < 5: theoreticalPrice[strikes[x]] = b_s.black_scholes( 'c', 9830, given_strikes[x / 2], .24, .01, calls[x / 2]) theoreticalPrice[strikes[x + 1]] = b_s.black_scholes( 'p', 9830.5, given_strikes[x / 2], .24, .01, puts[x / 2]) x += 2 return theoreticalPrice
def plot(self, x_vector, date, r, iv): ''' Creates a risk graph for the calendar spread inputs: x_vector -> vector of underlying prices where Black-Scholes must be calculated date -> date to be plotted r -> interest rate on a 3-month U.S. Treasury bill or similar iv -> implied volatility of the underlying returns: y -> Black-Scholes solution to given x_vector and parameters ''' y = np.zeros(len(x_vector)) # Create the discrete values of P/L to plot against xrange for opt in self.options_list: t = (opt.expiration - date).days / 365. y += np.array([opt.multiplier * opt.amount * (bs.black_scholes( opt.right, x, opt.strike, t, r, iv) - opt.get_debit()) for x in x_vector]) return y
def corp1(ss, k1, k2, r, T, vol, callput): return k1-bls.black_scholes(callput, ss, k2, T, r, vol)
def vol_lib(x_vector, K, r, t, iv): return [vol_bs.black_scholes('c', x, K, t, r, iv) for x in x_vector]
def bs_price(cp_flag,S,K,T,v,r,q=0.0): price = black_scholes(cp_flag, S, K, T, r, v) return price
def function_to_minimize(sigma): return price - black_scholes(flag, S, K, t, r, sigma)
def optPrice(curVol, price, S0, T): return (price-bls.black_scholes('c', S0, K, T, r, curVol))
def plot_risk_graph(options_list, t_list, risk_free_rate, iv, show_plot=False, save_png=False): ''' Creates a risk graph for the combination of options provided in the input list of options for the different times to expiration provided inputs: options_list -> list of options composing the strategy. It is important to provide this list ordered by near-term expiries first t_list -> dates to be plotted (in datetime) risk_free_rate -> interest rate on a 3-month U.S. Treasury bill or similar iv -> implied volatility of underlying show_plot -> determines if the plot is shown in a window (default False) save_png -> determines if the plot is saved as a PNG file (default False) returns: list of tuples (x, (datetime, y)) ''' # First get the graph bounds, 10% apart from the min and max # strikes min_strike = None max_strike = None for opt in options_list: if (min_strike is None) or (opt.strike < min_strike): min_strike = opt.strike if (max_strike is None) or (opt.strike > max_strike): max_strike = opt.strike # Prices x_vector = np.linspace(min_strike * 0.7, max_strike * 1.3, 500) # Now plot the risk graph for the different time values provided return_values = [] y = [] for t in t_list: y.append(np.zeros(len(x_vector))) # Create the discrete values of P/L to plot against xrange for opt in options_list: t_exp = (opt.expiration - t).days / 365. y[-1] += np.array([ opt.multiplier * opt.amount * (bs.black_scholes(opt.right, x, opt.strike, t_exp, risk_free_rate, iv / 100.) - opt.get_debit()) for x in x_vector ]) # Get the number of days to expiration from today for plot's legend days_to_expire = (options_list[0].expiration - t).days plt.plot(x_vector, y[-1], label='t: ' + str(days_to_expire)) return_values.append((t, y[-1])) plt.legend() plt.xlabel('Price') plt.ylabel('P/L') # Save the plot as a PNG if required, or show plot in a window if save_png: plt.savefig(datetime.today().strftime('%d%b%y ') + '.png') else: # Show the plot plt.show() # Return the values calculated TODO for what? to calculate breakevens? return (x_vector, return_values)