def get_distribution(self, *args, **kwargs): distribution_df = copy.deepcopy(self.event_input_distribution_df) distribution_df.loc[:, 'Pct_Move'] *= self.mult * self.idio_mult distribution_df.loc[:, 'Relative_Price'] = distribution_df.loc[:, 'Pct_Move'] + 1 return Distribution(distribution_df)
def get_distribution(self, expiry: 'dt.date', *args, **kwargs): ref_date = dt.date.today() time_to_expiry = get_time_to_expiry(expiry) prob_takeout_by_expiry = time_to_expiry * self.takeout_prob prob_no_takeout_by_expiry = 1 - prob_takeout_by_expiry relative_price_takeout = (1 + self.takeout_premium) relative_price_no_takeout = 1-(prob_takeout_by_expiry*self.takeout_premium) / (prob_no_takeout_by_expiry) distribution_df = pd.DataFrame({'States': ['Takeout', 'No Takeout'], 'Prob': [prob_takeout_by_expiry, prob_no_takeout_by_expiry], 'Relative_Price': [relative_price_takeout, relative_price_no_takeout], 'Pct_Move': [self.takeout_premium, relative_price_no_takeout-1] }) distribution_df.set_index('States', inplace=True) distribution_df = distribution_df.loc[:, ['Prob', 'Pct_Move', 'Relative_Price']] distribution_df = Distribution(distribution_df) return distribution_df
def mc_simulation(expiry=None, mc_iterations=10**5): # Define Events event1 = TakeoutEvent('CLVS', 1) event2 = SysEvt_PresElection('CLVS', .015) event3 = Event('CLVS', Distribution(pd.read_csv('CLVS.csv')), 'Ph3_Data') event4 = Event('CLVS', .025, 'Investor_Day') event5 = Event('CLVS', .15, 'FDA_Approval') event6 = Event('CLVS', .15, 'Q1_Earnings') event7 = Event('CLVS', .05, 'Q2_Earnings') events1 = [event6] events2 = [event6, event7] events3 = [event5, event6, event7] events4 = [event1, event5, event6, event7] events5 = [event1, event3, event5, event6, event7] event_groupings = [events1, events2, events3, events4, events5] @my_time_decorator def get_total_mc_distribution(events, expiry=None, symbol=None, mc_iterations=10**4): """Add together the MC Distributions of individual events. Return the Total MC Distribution.""" total_mc_distribution = np.zeros(mc_iterations) for event in events: distribution = event.get_distribution(expiry) total_mc_distribution += distribution.mc_simulation(mc_iterations) return total_mc_distribution @my_time_decorator def get_option_prices_from_mc_distribution(mc_distribution, strikes=None): if strikes is None: strikes = np.arange(.5, 1.55, .05) option_prices = [] implied_vols = [] for strike in strikes: if strike >= 1.0: option_type = 'Call' else: option_type = 'Put' option = Option(option_type, strike, expiry) option_price = OptionPriceMC(option, mc_distribution) option_prices.append(option_price) implied_vol = get_implied_volatility(option, 1.0, option_price) implied_vols.append(implied_vol) prices_info = { 'Strikes': strikes, 'Prices': option_prices, 'IVs': implied_vols } prices_df = pd.DataFrame(prices_info).round(3) prices_df.set_index('Strikes', inplace=True) return prices_df @my_time_decorator def event_groupings_df(event_groupings): i = 0 for grouping in event_groupings: mc_distribution = get_total_mc_distribution(grouping, expiry=expiry) prices = get_option_prices_from_mc_distribution( mc_distribution, strikes=np.arange(.5, 1.55, .05)).loc[:, ['Prices', 'IVs']] if event_groupings.index(grouping) == 0: prices_df = prices else: prices_df = pd.merge(prices_df, prices, left_index=True, right_index=True) get_mc_histogram(mc_distribution) i += 1 return prices_df event_df = event_groupings_df(event_groupings) print(event_df)
def mc_simulation(expiry=None, timing_descriptor=None, mc_iterations=10**5): timing_descriptor = 'Q2_2018' # Define Events event1 = SysEvt_PresElection('CLVS', .02, timing_descriptor) event2 = Event('CLVS', .05, 'Q2_2018', 'Q2_Earnings') event3 = Event('CLVS', .05, 'Q3_2018', 'Q3_Earnings') event4 = Event('CLVS', .075, 'Q3_2018', 'Investor_Day') event5 = Event('CLVS', .1, '2H_2018', 'FDA_Approval') event6 = TakeoutEvent('CLVS', 1) event7 = Event('CLVS', Distribution(pd.read_csv('CLVS.csv')), 'Q2_2018', 'Ph3_Data') events1 = [event1] events2 = [event1, event2] events3 = [event1, event2, event3] events4 = [event1, event2, event3, event4] events5 = [event1, event2, event3, event4, event5] events6 = [event1, event2, event3, event4, event5, event6] events7 = [event1, event2, event3, event4, event5, event6, event7] event_groupings = [ events1, events2, events3, events4, events5, events6, events7 ] @my_time_decorator def get_total_mc_distribution(events, expiry=None, symbol=None, mc_iterations=10**4): """Add the simulation results of individual events to return the total simulated distribution.""" distributions = map(lambda evt: evt.get_distribution(expiry), events) mc_distributions = map(lambda dist: dist.mc_simulation(mc_iterations), distributions) return sum(mc_distributions) @my_time_decorator def get_option_sheet_from_mc_distribution(mc_distribution, expiry=None, strikes=None): if strikes is None: strikes = np.arange(.5, 1.55, .05) call_options = [Option('Call', strike, expiry) for strike in strikes] call_prices = list( map(lambda option: OptionPriceMC(option, mc_distribution), call_options)) call_IVs = list( map( lambda option, option_price: get_implied_volatility( option, option_price), call_options, call_prices)) put_options = [Option('Put', strike, expiry) for strike in strikes] put_prices = list( map(lambda option: OptionPriceMC(option, mc_distribution), put_options)) put_IVs = list( map( lambda option, option_price: get_implied_volatility( option, option_price), put_options, put_prices)) option_sheet_info = { 'Strike': strikes, 'Price': call_prices, 'IV': call_IVs } option_sheet = pd.DataFrame(option_sheet_info).round(2) option_sheet.set_index('Strike', inplace=True) option_sheet = option_sheet.loc[:, ['Price', 'IV']] print(option_sheet) #iterables = [['Price', 'IV'], ['Group 1']] #index = pd.MultiIndex.from_product(iterables, names=['Option Info', 'Event Grouping']) #option_sheet.rename(columns=index) #print(index) return option_sheet @my_time_decorator def get_option_sheet_by_event_groupings(event_groupings, expiry): # i = 0 # for grouping in event_groupings: # mc_distribution = get_total_mc_distribution(grouping, expiry = expiry) # prices = get_option_sheet_from_mc_distribution(mc_distribution, strikes = np.arange(.5, 1.55, .05)).loc[:, ['Price','IV']] # # if event_groupings.index(grouping) == 0: # prices_df = prices # else: # prices_df = pd.merge(prices_df, prices, left_index=True, right_index=True) # # get_mc_histogram(mc_distribution) # # i += 1 # return prices_df mc_distributions = list( map( lambda event_grouping: get_total_mc_distribution( event_grouping, expiry), event_groupings)) [ get_mc_histogram(mc_distribution) for mc_distribution in mc_distributions ] option_sheets = list( map( lambda dist: get_option_sheet_from_mc_distribution( dist, expiry).loc[:, ['IV']], mc_distributions)) return reduce( lambda x, y: pd.merge(x, y, left_index=True, right_index=True), option_sheets) event_df = get_option_sheet_by_event_groupings(event_groupings, expiry) print(event_df)