def objective(chain, x): T = chain.Time_to_exp / 252 Rf = chain.Rf c_total = len(chain.Call_Strike) p_total = len(chain.Put_Strike) w = x[0] F1 = x[1] sigma1 = x[2] F2 = x[3] sigma2 = x[4] c_market = (chain.Call_Ask + chain.Call_Bid) / 2 p_market = (chain.Put_Ask + chain.Put_Bid) / 2 S1 = F1 * math.exp(-1 * Rf * T) S2 = F2 * math.exp(-1 * Rf * T) c_the =np.array([w*(american_option('c',S1,chain.Call_Dummy_Strike[i],T,Rf,sigma1)[0])\ + (1-w)*(american_option('c',S2,chain.Call_Dummy_Strike[i],T,Rf,sigma2)[0])\ for i in range(c_total)]) p_the = np.array([w*(american_option('p',S1,chain.Put_Dummy_Strike[i],T,Rf,sigma1)[0])\ + (1-w)*(american_option('p',S2,chain.Put_Dummy_Strike[i],T,Rf,sigma2)[0])\ for i in range(p_total)]) c_sse = np.sum((c_market - c_the)**2) p_sse = np.sum((p_market - p_the)**2) return c_sse + p_sse
def __init__(self, asset, final_dataset): self.Name = asset self.lot_size = 100 setattr(self, "Time_to_exp", days_to_expiry) asset_df = final_dataset[final_dataset['Group'] == asset] asset_df["Dummy_Strike"] = asset_df.loc[:, "Strike"] filtered = asset_df.groupby('Strike')['Strike'].filter( lambda x: len(x) == 2) not_common = asset_df[~asset_df['Strike'].isin(filtered)] records = not_common.to_dict('records') to_add = list() for record in records: new = record.copy() if record["Option_type"] == "CALL": for keys, value in new.items(): if type(value) == str: if keys in ["Symbol", "Description"]: new[keys] = "Dummy" if keys == "Option_type": new[keys] = "PUT" else: if keys in ["Bid", "Ask"]: option_type = 'p' fs = new['stock_Last'] x = new['Strike'] t = self.Time_to_exp / 252 r = rf_value v = new['Impl Vol'] new[keys] = american_option( option_type, fs, x, t, r, v)[0] if keys[:5] != "stock" and (keys not in [ "Strike", "Dummy_Strike", "Ask", "Bid", "Impl Vol" ]): new[keys] = 0 new["Strike"] = -1000000 else: for keys, value in new.items(): if type(value) == str: if keys in ["Symbol", "Description"]: new[keys] = "Dummy" if keys == "Option_type": new[keys] = "CALL" else: if keys in ["Bid", "Ask"]: option_type = 'p' fs = new['stock_Last'] x = new['Strike'] t = self.Time_to_exp / 252 r = rf_value v = new['Impl Vol'] new[keys] = american_option( option_type, fs, x, t, r, v)[0] if keys[:5] != "stock" and (keys not in [ "Strike", "Dummy_Strike", "Ask", "Bid", "Impl Vol" ]): new[keys] = 0 new["Strike"] = 1000000 to_add.append(new) df_dummy_options = pd.DataFrame(to_add) asset_df = asset_df.append(df_dummy_options) asset_df = asset_df.sort_values(by=['Option_type', 'Dummy_Strike']) greeks = ["Delta", "Gamma", "Theta", "Vega", "Rho"] for greek in greeks: setattr(self, "Var_" + greek, np.std(asset_df[greek].values)) self.call_df = asset_df[asset_df['Option_type'] == "CALL"] self.put_df = asset_df[asset_df['Option_type'] == "PUT"] cols = [ "Bid", "Ask", "Last", "Delta", "Gamma", "Theta", "Vega", "Rho", "Impl Vol", "Strike", "Dummy_Strike" ] for col in cols: setattr(self, "Call_" + col, self.call_df[col].values) setattr(self, "Put_" + col, self.put_df[col].values) setattr(self, "Call_total", len(self.Call_Strike)) setattr(self, "Put_total", len(self.Put_Strike)) setattr(self, "Stock_Last", asset_df["stock_Last"].iloc[0]) setattr(self, "Description", asset_df["stock_Description"].iloc[0]) setattr(self, "Stock_Volt", asset_df["stock_Impl_Vol"].iloc[0]) std = self.Stock_Last * (self.Stock_Volt * ((self.Time_to_exp / 252)**0.5)) self.sigma = std self.Rf = rf_value vol_day = (self.Stock_Volt) * math.sqrt(1 / 252) ln_S_0 = math.log(self.Stock_Last) rt = self.Rf * (self.Time_to_exp / 252) s_term = -0.5 * (vol_day**2) * (self.Time_to_exp) mu_n = ln_S_0 + rt + s_term sigma_n = vol_day * math.sqrt(self.Time_to_exp) s = sigma_n scale = math.exp(mu_n) self.lognormal_s = s self.lognormal_scale = scale S = self.Stock_Last #self.S_space = np.linspace(self.Stock_Last - 4*self.sigma, self.Stock_Last + 4*self.sigma, 20) self.S_space = np.arange(S - 0.5 * S, S + 0.5 * S, 0.1) self.S_density = stats.lognorm.pdf(self.S_space, s, loc=0, scale=scale) ## for optimization variables = [ "Ask", "Bid", "Strike", "Delta", "Gamma", "Theta", "Vega", "Rho" ] for variable in variables: cal_cont = getattr(self, "Call_" + variable) put_cont = getattr(self, "Put_" + variable) array = np.hstack((cal_cont[:, np.newaxis], put_cont[:, np.newaxis])) setattr(self, variable + "_List", [[array[i, j] for j in range(array.shape[1])] for i in range(array.shape[0])])
from american_option_pricing import american_option option_type = 'c' fs = 98.95 x = 104 t = 9 / 252 r = 0.103 / 100 b = 0 v = 0.2793 ans = american_option(option_type, fs, x, t, r, v) #actual = 5.75 #print(actual) print((0.62 + 0.35) / 2) print(ans[0])