def testATM(self): put = Option(100, 100, 5/365, 0.05, is_call=False) print(put.getInfo()) print(put.getPrice(0.21)) print(put.getImpliedVol(1)) call = Option(100, 100, 5/365, 0.05, is_call=True) print(call.getInfo()) print(call.getPrice(0.21)) print(call.getImpliedVol(1))
def testOTM(self): put = Option(105, 100, 1/365, 0.05, is_call=False) print(put.getInfo()) print(put.getPrice(0.25)) print(put.getImpliedVol(0)) call = Option(95, 100, 1/365, 0.05, is_call=True) print(call.getInfo()) print(call.getPrice(0.25)) print(call.getImpliedVol(0))
def testITM(self): put = Option(95, 100, 30/365, 0.05, is_call=False) print(put.getInfo()) print(put.getPrice(0.25)) print(put.getImpliedVol(5.6577)) call = Option(105, 100, 30/365, 0.05, is_call=True) print(call.getInfo()) print(call.getPrice(0.25)) print(call.getImpliedVol(6.391))
def testSELLSimpleDynaDeltaCall(self): pf_shares = [] shares_purchased = [] trxn_costs = [] deltas = [] option_price = [] underlying_price = [] vol = 0.20 T = 20 / 365 stk = 50 underlyingP = 49 underlying_price.append(underlyingP) call = Option(underlyingP, stk, T, .05, is_call=True) delta_start = -call.getGreeks(vol)[ 'delta'] #NEGATIVE BECAUSE SOLD OPTION deltas.append(delta_start) opt_cost = -call.getPrice(vol) #NEGATIVE BECAUSE SOLD option_price.append(opt_cost) shares_owned = -delta_start * 100 pf_shares.append(shares_owned) trxn_costs.append(shares_owned * underlyingP) shares_purchased.append(shares_owned) for i in range(20): T = max(T - 1 / 365, 0) if i % 2 == 0: underlyingP = underlyingP + 0.8 underlying_price.append(underlyingP) else: underlyingP = underlyingP - 0.5 underlying_price.append(underlyingP) call.setUnderlyingP(underlyingP) call.setTimetoMaturity(T) opt_prc = -call.getPrice(vol) #NEG BC SOLD option_price.append(opt_prc) delta = -call.getGreeks(vol)[ 'delta'] #NEGATIVE BECAUSE SOLD OPTION deltas.append(delta) purchased_shares = -100 * delta - shares_owned shares_purchased.append(purchased_shares) shares_owned = shares_owned + purchased_shares pf_shares.append(shares_owned) cost_of_shares = purchased_shares * underlyingP trxn_costs.append(cost_of_shares) df = pd.DataFrame([ underlying_price, deltas, pf_shares, shares_purchased, trxn_costs, option_price ]).T df.columns = [ 'underlying_price', 'deltas', 'pf_shares', 'shares_purchased', 'trxn_costs', 'option_price' ] #assume position is closed at mkt close or hedged at mkt close df['cum_trxn_costs'] = df['trxn_costs'].cumsum() df['earlyexit_share_pnl'] = df['pf_shares'].shift( 1) * df['underlying_price'] - df['cum_trxn_costs'].shift(1) df['earlyexit_option_pnl'] = (df['option_price'] - opt_cost) * 100 df['earlyexit_pnl'] = df['earlyexit_share_pnl'] + df[ 'earlyexit_option_pnl'] expiration_pnl = df['earlyexit_pnl'].loc[len(df['earlyexit_pnl']) - 1] df['underlying_price'].plot() plt.axhline(stk, color='red') plt.show() print("PNL on Expiration: {}".format(expiration_pnl)) print("Realized Vol: {}".format( pd.Series(underlying_price).pct_change().std() * np.sqrt(252))) print(df) self.assertEquals(round(expiration_pnl, 5), -18.85561)
def testBUYSimpleDynaDeltaCall(self): pf_shares = [] shares_purchased = [] trxn_costs = [] deltas = [] option_price = [] underlying_price = [] vol = 0.20 T = 20 / 365 stk = 50 underlyingP = 49 underlying_price.append(underlyingP) call = Option(underlyingP, stk, T, .05, is_call=True) delta_start = call.getGreeks(vol)['delta'] deltas.append(delta_start) opt_cost = call.getPrice(vol) option_price.append(opt_cost) shares_owned = -delta_start * 100 pf_shares.append(shares_owned) trxn_costs.append(shares_owned * underlyingP) shares_purchased.append(shares_owned) for i in range(20): T = max(T - 1 / 365, 0) if i % 2 == 0: underlyingP = underlyingP + 0.5 underlying_price.append(underlyingP) else: underlyingP = underlyingP - 0.5 underlying_price.append(underlyingP) call.setUnderlyingP(underlyingP) call.setTimetoMaturity(T) opt_prc = call.getPrice(vol) option_price.append(opt_prc) delta = call.getGreeks(vol)['delta'] deltas.append(delta) purchased_shares = -100 * delta - shares_owned shares_purchased.append(purchased_shares) shares_owned = shares_owned + purchased_shares pf_shares.append(shares_owned) cost_of_shares = purchased_shares * underlyingP trxn_costs.append(cost_of_shares) df = pd.DataFrame([ underlying_price, deltas, pf_shares, shares_purchased, trxn_costs, option_price ]).T df.columns = [ 'underlying_price', 'deltas', 'pf_shares', 'shares_purchased', 'trxn_costs', 'option_price' ] df['pct_chg'] = df['underlying_price'].pct_change() #assume position is closed at mkt close or hedged at mkt close df['cum_trxn_costs'] = df['trxn_costs'].cumsum() df['earlyexit_share_pnl'] = df['pf_shares'].shift( 1) * df['underlying_price'] - df['cum_trxn_costs'].shift(1) df['earlyexit_option_pnl'] = (df['option_price'] - opt_cost) * 100 df['earlyexit_pnl'] = df['earlyexit_share_pnl'] + df[ 'earlyexit_option_pnl'] expiration_pnl = df['earlyexit_pnl'].loc[len(df['earlyexit_pnl']) - 1] self.assertEquals(round(expiration_pnl, 5), 18.85561)
def testMCDynaDelta(self): pf_shares = [] shares_purchased = [] trxn_costs = [] deltas = [] option_price = [] underlying_price = [] chng = [] #Approx historical returns with SPY SPY_df = web.DataReader('GLD', 'yahoo', dt.datetime(2019, 3, 29), dt.datetime.today()).reset_index() SPY = SPY_df[['Date', 'Close']].set_index( 'Date', drop=True).copy() * 10 #to convert to index val rets = SPY['Close'].pct_change().dropna() dist = CurveFitter(rets) #dist.fitGaussian() vol = 0.2157 T = 31 / 365 stk = 2000 timesteps = int(T * 365) underlyingP = 1933 underlying_price.append(underlyingP) call = Option(underlyingP, stk, T, .05, is_call=True) delta_start = call.getGreeks(vol)['delta'] deltas.append(delta_start) opt_cost = call.getPrice(vol) option_price.append(opt_cost) shares_owned = -round(delta_start, 2) * 100 #int(round(b/5.0)*5.0) pf_shares.append(shares_owned) trxn_costs.append(shares_owned * underlyingP) shares_purchased.append(shares_owned) for i in range(timesteps): T = max(T - 1 / 365, 0) if i % 2 == 0: pct_chg = np.random.choice( rets ) #round(dist.sampledist(st.t, 1.8768166491405975, 0.0, 0.01, 1).item(), 8) #dist.samplenorm(1).item() chng.append(pct_chg) underlyingP = underlyingP + underlyingP * pct_chg # + 30 underlying_price.append(underlyingP) else: pct_chg = np.random.choice( rets ) #round(dist.sampledist(st.t, 1.8768166491405975, 0.0, 0.01, 1).item(), 8) #dist.samplenorm(1).item() chng.append(pct_chg) underlyingP = underlyingP + underlyingP * pct_chg # - 30 underlying_price.append(underlyingP) call.setUnderlyingP(underlyingP) call.setTimetoMaturity(T) opt_prc = call.getPrice(vol) option_price.append(opt_prc) delta = call.getGreeks(vol)['delta'] deltas.append(delta) purchased_shares = -100 * round(delta, 2) - shares_owned shares_purchased.append(purchased_shares) shares_owned = shares_owned + purchased_shares pf_shares.append(shares_owned) cost_of_shares = purchased_shares * underlyingP trxn_costs.append(cost_of_shares) df = pd.DataFrame([ underlying_price, chng, deltas, pf_shares, shares_purchased, trxn_costs, option_price ]).T df.columns = [ 'underlying_price', 'pct_chg', 'deltas', 'pf_shares', 'shares_purchased', 'trxn_costs', 'option_price' ] #assume position is closed at mkt close or hedged at mkt close df['cum_trxn_costs'] = df['trxn_costs'].cumsum() df['earlyexit_share_pnl'] = df['pf_shares'].shift( 1) * df['underlying_price'] - df['cum_trxn_costs'].shift(1) df['earlyexit_option_pnl'] = (df['option_price'] - opt_cost) * 100 df['earlyexit_pnl'] = df['earlyexit_share_pnl'] + df[ 'earlyexit_option_pnl'] expiration_pnl = df['earlyexit_pnl'].loc[len(df['earlyexit_pnl']) - 1] df['underlying_price'].plot() plt.axhline(stk, color='red') plt.show() print("PNL on Expiration: {}".format(expiration_pnl)) print("Realized Vol: {}".format( pd.Series(underlying_price).pct_change().std() * np.sqrt(252))) print(df)
def testTheta(self): put = Option(110, 100, 2, 0.05, is_call=False) print(put.getInfo()) print(put.getPrice(0.25)) print(put.getGreeks(.25))
def testVega(self): put = Option(50, 100, 1, 0.05, is_call=False) print(put.getInfo()) print(put.getPrice(0.25)) print(put.getGreeks(.25))
def main(): ticker = 'TGT' SPY_df = web.DataReader(ticker, 'yahoo', dt.datetime(2018, 3, 29), dt.datetime.today()).reset_index() SPY = SPY_df[['Date', 'Close']].set_index( 'Date', drop=True).copy() * 10 # to convert to index val data = SPY['Close'].pct_change().dropna() best_fit_name, best_fit_params = best_fit_distribution(data, 200, ax=None) best_dist = getattr(st, best_fit_name) pdf = make_pdf(best_dist, best_fit_params) plt.figure(figsize=(12, 8)) ax = pdf.plot(lw=2, label='Fitted PDF', legend=True) data.plot(kind='hist', bins=50, density=True, alpha=0.5, label='Raw Data', legend=True, ax=ax) param_names = ( best_dist.shapes + ', loc, scale').split(', ') if best_dist.shapes else ['loc', 'scale'] param_str = ', '.join([ '{}={:0.2f}'.format(k, v) for k, v in zip(param_names, best_fit_params) ]) dist_str = '{}({})'.format(best_fit_name, param_str) ax.set_title(u'{} Returns Best Fit Distribution: \n'.format(ticker) + dist_str) ax.set_xlabel(u'Returns (%)') ax.set_ylabel('Frequency') ax.set_xlim([-.25, .25]) dist = CurveFitter(data) sample_size = 100000 resampled = dist.sampledist(st.nct, best_fit_params[0], best_fit_params[1], best_fit_params[2], best_fit_params[3], sample_size) resampled = pd.Series(resampled) bins = int(sample_size / 100) resampled.plot(kind='hist', bins=bins, density=True, alpha=0.25, label='Resampled Data', legend=True, ax=ax) plt.savefig("BestFit.png") plt.show() pf_shares = [] shares_purchased = [] trxn_costs = [] deltas = [] option_price = [] underlying_price = [] chng = [] vol = 0.30 T = 123 / 365 stk = 170 timesteps = int(T * 365) underlyingP = 149.58 underlying_price.append(underlyingP) call = Option(underlyingP, stk, T, .05, is_call=True) delta_start = call.getGreeks(vol)['delta'] deltas.append(delta_start) opt_cost = call.getPrice(vol) option_price.append(opt_cost) shares_owned = -round(delta_start, 2) * 100 # int(round(b/5.0)*5.0) pf_shares.append(shares_owned) trxn_costs.append(shares_owned * underlyingP) shares_purchased.append(shares_owned) for i in range(timesteps): T = max(T - 1 / 365, 0) if i % 2 == 0: pct_chg = round( dist.sampledist(best_dist, best_fit_params[0], best_fit_params[1], best_fit_params[2], best_fit_params[3], 1).item(), 8) * 2 / 3 #dist.samplenorm(1).item() chng.append(pct_chg) underlyingP = underlyingP + underlyingP * pct_chg # + 30 underlying_price.append(underlyingP) else: pct_chg = round( dist.sampledist(best_dist, best_fit_params[0], best_fit_params[1], best_fit_params[2], best_fit_params[3], 1).item(), 8) #dist.samplenorm(1).item() chng.append(pct_chg) underlyingP = underlyingP + underlyingP * pct_chg # - 30 underlying_price.append(underlyingP) call.setUnderlyingP(underlyingP) call.setTimetoMaturity(T) opt_prc = call.getPrice(vol) option_price.append(opt_prc) delta = call.getGreeks(vol)['delta'] deltas.append(delta) purchased_shares = -100 * round(delta, 2) - shares_owned shares_purchased.append(purchased_shares) shares_owned = shares_owned + purchased_shares pf_shares.append(shares_owned) cost_of_shares = purchased_shares * underlyingP trxn_costs.append(cost_of_shares) df = pd.DataFrame([ underlying_price, chng, deltas, pf_shares, shares_purchased, trxn_costs, option_price ]).T df.columns = [ 'underlying_price', 'pct_chg', 'deltas', 'pf_shares', 'shares_purchased', 'trxn_costs', 'option_price' ] # assume position is closed at mkt close or hedged at mkt close df['cum_trxn_costs'] = df['trxn_costs'].cumsum() df['earlyexit_share_pnl'] = df['pf_shares'].shift( 1) * df['underlying_price'] - df['cum_trxn_costs'].shift(1) df['earlyexit_option_pnl'] = (df['option_price'] - opt_cost) * 100 df['earlyexit_pnl'] = df['earlyexit_share_pnl'] + df['earlyexit_option_pnl'] expiration_pnl = df['earlyexit_pnl'].loc[len(df['earlyexit_pnl']) - 1] df['underlying_price'].plot( color='blue', linewidth=3.0, ) plt.axhline(stk, color='red', linewidth=5.0, linestyle='--') plt.title("Underlying Price Monte Carlo Simulation") plt.ylabel("Price") plt.xlabel("Days") plt.savefig("UnderlyingPrice.png") plt.show() print("PNL on Expiration: {}".format(expiration_pnl)) print("Realized Vol: {}".format( pd.Series(underlying_price).pct_change().std() * np.sqrt(252))) print(df)