def market_return(self): # 1. Linear Regression: On the estimation_period dr_data = Calculator.returns(self.data) dr_market = Calculator.returns(self.market) c_name = dr_data.columns[0] x = dr_market[c_name][self.start_period:self.end_period] y = dr_data[c_name][self.start_period:self.end_period] slope, intercept, r_value, p_value, std_error = stats.linregress(x, y) er = lambda x: x * slope + intercept # 2. Analysis on the event window # Expexted Return: self.er = dr_market[self.start_window:self.end_window].apply( er)[c_name] self.er.name = 'Expected return' # Abnormal return: Return of the data - expected return self.ar = dr_data[c_name][self.start_window:self.end_window] - self.er self.ar.name = 'Abnormal return' # Cumulative abnormal return self.car = self.ar.cumsum() self.car.name = 'Cum abnormal return' # t-test t_test_calc = lambda x: x / std_error self.t_test = self.ar.apply(t_test_calc) self.t_test.name = 't-test' self.prob = self.t_test.apply(stats.norm.cdf) self.prob.name = 'Probability'
def test_tvm(self): ''' Tests ----- 1. FV w/ PV, R, n, m and ret_list=False 2. PV w/ PV, R, n, m and ret_list=False 3. R w/ PV, FV, n, m 4. n w/ PV, FV, R, m 5. ear w/ R, m ''' self_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) tests = ['Calculator_TVM_1.csv', 'Calculator_TVM_2.csv', 'Calculator_TVM_3.csv'] tests = [os.path.join(self_dir, 'docs',test) for test in tests] for test_file in tests: # Set up solution = pd.read_csv(test_file) for idx, row in solution.iterrows(): # Test 1 FV = Calculator.FV(PV=row['PV'], R=row['R'], n=row['n'], m=row['m']) self.assertAlmostEquals(FV, row['FV'], 4) # Test 2 PV = Calculator.PV(FV=row['FV'], R=row['R'], n=row['n'], m=row['m']) self.assertAlmostEquals(PV, row['PV'], 4) # Test 3 R = Calculator.R(PV=row['PV'], FV=row['FV'], n=row['n'], m=row['m']) self.assertAlmostEquals(R, row['R'], 4) # Test 4 n = Calculator.n(PV=row['PV'], FV=row['FV'], R=row['R'], m=row['m']) self.assertAlmostEquals(n, row['n'], 4) # Test 5 ear = Calculator.eff_ret(R=row['R'], m=row['m']) self.assertAlmostEquals(ear, row['EAR'], 4, "R(%s),m(%s)" % (row['R'], row['m']))
def market_return(self): # 1. Linear Regression: On the estimation_period dr_data = Calculator.returns(self.data) dr_market = Calculator.returns(self.market) c_name = dr_data.columns[0] x = dr_market[c_name][self.start_period:self.end_period] y = dr_data[c_name][self.start_period:self.end_period] slope, intercept, r_value, p_value, std_error = stats.linregress(x, y) er = lambda x: x * slope + intercept # 2. Analysis on the event window # Expexted Return: self.er = dr_market[self.start_window:self.end_window].apply(er)[c_name] self.er.name = 'Expected return' # Abnormal return: Return of the data - expected return self.ar = dr_data[c_name][self.start_window:self.end_window] - self.er self.ar.name = 'Abnormal return' # Cumulative abnormal return self.car = self.ar.cumsum() self.car.name = 'Cum abnormal return' # t-test t_test_calc = lambda x: x / std_error self.t_test = self.ar.apply(t_test_calc) self.t_test.name = 't-test' self.prob = self.t_test.apply(stats.norm.cdf) self.prob.name = 'Probability'
def test_tvm(self): ''' Tests ----- 1. FV w/ PV, R, n, m and ret_list=False 2. PV w/ PV, R, n, m and ret_list=False 3. R w/ PV, FV, n, m 4. n w/ PV, FV, R, m 5. ear w/ R, m ''' self_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) tests = ['Calculator_TVM_1.csv', 'Calculator_TVM_2.csv', 'Calculator_TVM_3.csv'] tests = [os.path.join(self_dir, 'docs',test) for test in tests] for test_file in tests: # Set up solution = pd.read_csv(test_file) for idx, row in solution.iterrows(): # Test 1 FV = Calculator.FV(PV=row['PV'], R=row['R'], n=row['n'], m=row['m']) self.assertAlmostEqual(FV, row['FV'], 4) # Test 2 PV = Calculator.PV(FV=row['FV'], R=row['R'], n=row['n'], m=row['m']) self.assertAlmostEqual(PV, row['PV'], 4) # Test 3 R = Calculator.R(PV=row['PV'], FV=row['FV'], n=row['n'], m=row['m']) self.assertAlmostEqual(R, row['R'], 4) # Test 4 n = Calculator.n(PV=row['PV'], FV=row['FV'], R=row['R'], m=row['m']) self.assertAlmostEqual(n, row['n'], 4) # Test 5 ear = Calculator.eff_ret(R=row['R'], m=row['m']) self.assertAlmostEqual(ear, row['EAR'], 4, "R(%s),m(%s)" % (row['R'], row['m']))
def test_assets(self): ''' Tests ----- 1. Calculator.returns w/ basedOn=1 cc=False 2. Calculator.returns w/ basedOn=1 cc=True 3. Calculator.returns w/ basedOn=2 cc=False 4. Calculator.returns w/ basedOn=2 cc=True 5. Calculator.FV w/ R=list ret_list=True 6. Calculator.PV w/ R=list ret_list=True ''' # Load Data self_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) tests = ['Calculator_Assets_1.csv'] tests = [os.path.join(self_dir, 'docs', test) for test in tests] for test_file in tests: # Set up solution = pd.read_csv(test_file).set_index('Date').fillna(value=0) data = solution['Adj. Close'] # Test 1 simple_returns = Calculator.returns(data) self.assertEqual(solution['Adj. Close returns'], simple_returns) # Test 2 cc_returns = Calculator.returns(data, cc=True) self.assertEqual(solution['Adj. Close CC returns'], cc_returns) # Test 3 simple_returns_2 = Calculator.returns(data, basedOn=2) self.assertEqual(solution['Adj. Close returns (2)'], simple_returns_2) # Test 4 cc_returns_2 = Calculator.returns(data, basedOn=2, cc=True) self.assertEqual(solution['Adj. Close CC returns (2)'], cc_returns_2) # Test 5 fv = Calculator.FV(PV=1, R=simple_returns, ret_list=True) self.assertEqual(solution['Future value'], fv) # Test 6 pv = Calculator.PV(FV=fv[-1], R=simple_returns, ret_list=True) pv_sol = solution['Future value'] pv_sol.name = 'Present value' self.assertEqual(solution['Future value'], pv)
def test_sharpe_ratio(self): array = np.array([1, 1.5, 3, 4, 4.3]) array_2 = np.array([5, 4.3, 3, 3.5, 1]) matrix = np.array([array, array_2]).T series = pd.Series(array) time_series = pd.Series(array_2) df = pd.DataFrame(matrix, columns=['c1', 'c2']) # Input is np.array of 1 dimmension => float ans = Calculator.sharpe_ratio(array) self.assertFloat(ans) self.assertAlmostEquals(ans, 2.38842, 5) # Input is np.array of 2 dimmensions => array ans = Calculator.sharpe_ratio(matrix) self.assertArray(ans) sol = np.array([2.38842482, -1.4708528]) self.assertEqual(ans, sol, 5) # Input is pandas.Series => float ans = Calculator.sharpe_ratio(series) self.assertFloat(ans) self.assertAlmostEquals(ans, 2.38842, 5) # Input is pandas.TimeSeries => float ans = Calculator.sharpe_ratio(time_series) self.assertFloat(ans) self.assertAlmostEquals(ans, -1.4708528, 5) # Input is pandas.DataFrame with col parameter => float ans = Calculator.sharpe_ratio(df, col='c1') self.assertFloat(ans) self.assertAlmostEquals(ans, 2.38842, 5) # -- ans = Calculator.sharpe_ratio(df, col='c2') self.assertFloat(ans) self.assertAlmostEqual(ans, -1.4708528, 5) # Input is pandas.DataFrame without col parameter => pd.Series ans = Calculator.sharpe_ratio(df) self.assertSeries(ans) sol = pd.Series([2.38842482, -1.4708528], index=['c1', 'c2'], name='Sharpe Ratios') self.assertEqual(ans, sol)
def test_ret(self): # Variables array = np.array([1, 2, 3, 4, 5]) array_2 = np.array([5, 4, 3, 2, 1]) matrix = np.array([array, array_2]).T series = pd.Series(array, index=[5, 7, 8, 10, 11]) time_series = pd.Series(array) df = pd.DataFrame(matrix, columns=['c1', 'c2'], index=[5, 7, 8, 10, 11]) # Input is numpy.ndarray of 1 dimmension => float ans = Calculator.ret(array) self.assertFloat(ans) self.assertEqual(ans, 4) # Input is numpy.ndarray of 2 dimmensions => np.ndarray ans = Calculator.ret(matrix) self.assertArray(ans) self.assertEqual(ans, np.array([4, -0.8])) # Input is pandas.Series => float ans = Calculator.ret(series) self.assertFloat(ans) self.assertEqual(ans, 4) # Input is pandas.TimeSeries => float ans = Calculator.ret(time_series) self.assertFloat(ans) self.assertEqual(ans, 4) # Input is pandas.DataFrame with col parameter => float ans = Calculator.ret(df, col='c1') self.assertFloat(ans) self.assertEqual(ans, 4) # -- ans = Calculator.ret(df, col='c2') self.assertFloat(ans) self.assertEqual(ans, -0.8) # Input is pandas.DataFrame without col parameter => Return pd.Series ans = Calculator.ret(df) self.assertSeries(ans) sol = pd.Series([4, -0.8], index=['c1', 'c2'], name='Total Returns') self.assertEqual(ans, sol)
def test_sharpe_ratio(self): array = np.array([1,1.5,3,4,4.3]) array_2 = np.array([5,4.3,3,3.5,1]) matrix = np.array([array, array_2]).T series = pd.Series(array) time_series = pd.Series(array_2) df = pd.DataFrame(matrix, columns=['c1', 'c2']) # Input is np.array of 1 dimmension => float ans = Calculator.sharpe_ratio(array) self.assertFloat(ans) self.assertAlmostEquals(ans, 2.38842, 5) # Input is np.array of 2 dimmensions => array ans = Calculator.sharpe_ratio(matrix) self.assertArray(ans) sol = np.array([2.38842482, -1.4708528]) self.assertEqual(ans, sol, 5) # Input is pandas.Series => float ans = Calculator.sharpe_ratio(series) self.assertFloat(ans) self.assertAlmostEquals(ans, 2.38842, 5) # Input is pandas.TimeSeries => float ans = Calculator.sharpe_ratio(time_series) self.assertFloat(ans) self.assertAlmostEquals(ans, -1.4708528, 5) # Input is pandas.DataFrame with col parameter => float ans = Calculator.sharpe_ratio(df, col='c1') self.assertFloat(ans) self.assertAlmostEquals(ans, 2.38842, 5) # -- ans = Calculator.sharpe_ratio(df, col='c2') self.assertFloat(ans) self.assertAlmostEqual(ans, -1.4708528, 5) # Input is pandas.DataFrame without col parameter => pd.Series ans = Calculator.sharpe_ratio(df) self.assertSeries(ans) sol = pd.Series([2.38842482, -1.4708528], index=['c1', 'c2'], name='Sharpe Ratios') self.assertEqual(ans, sol)
def test_ret(self): # Variables array = np.array([1,2,3,4,5]) array_2 = np.array([5,4,3,2,1]) matrix = np.array([array, array_2]).T series = pd.Series(array, index=[5,7,8,10,11]) time_series = pd.Series(array) df = pd.DataFrame(matrix, columns=['c1', 'c2'], index=[5,7,8,10,11]) # Input is numpy.ndarray of 1 dimmension => float ans = Calculator.ret(array) self.assertFloat(ans) self.assertEqual(ans, 4) # Input is numpy.ndarray of 2 dimmensions => np.ndarray ans = Calculator.ret(matrix) self.assertArray(ans) self.assertEqual(ans, np.array([4, -0.8])) # Input is pandas.Series => float ans = Calculator.ret(series) self.assertFloat(ans) self.assertEqual(ans, 4) # Input is pandas.TimeSeries => float ans = Calculator.ret(time_series) self.assertFloat(ans) self.assertEqual(ans, 4) # Input is pandas.DataFrame with col parameter => float ans = Calculator.ret(df, col='c1') self.assertFloat(ans) self.assertEqual(ans, 4) # -- ans = Calculator.ret(df, col='c2') self.assertFloat(ans) self.assertEqual(ans, -0.8) # Input is pandas.DataFrame without col parameter => Return pd.Series ans = Calculator.ret(df) self.assertSeries(ans) sol = pd.Series([4, -0.8], index=['c1', 'c2'], name='Total Returns') self.assertEqual(ans, sol)
def test_returns(self): # Variables array_1 = np.array([1, 1.5, 3, 4, 4.3]) array_2 = np.array([5, 4.3, 3, 3.5, 1]) matrix = np.array([array_1, array_2]).T ser = pd.Series(array_1, name='TEST') df = pd.DataFrame(matrix, columns=['c1', 'c2']) sol_array_1 = np.array([0, 0.5, 1, 0.33333333, 0.075]) sol_array_2 = np.array( [0., -0.14, -0.30232558, 0.16666667, -0.71428571]) sol_matrix = np.array([sol_array_1, sol_array_2]).T # Input is numpy.array of 1 dimmension => np.ndarray ans = Calculator.returns(array_1) self.assertArray(ans) self.assertEqual(ans, sol_array_1, 5) # Input is numpy.ndarray of 2 dimmension 2 => np.ndarray ans = Calculator.returns(matrix) self.assertArray(ans) self.assertEqual(ans, sol_matrix, 5) # Input is pandas.Series => pd.Series ans = Calculator.returns(ser) self.assertSeries(ans) sol = pd.Series(sol_array_1, index=ser.index, name='TEST returns') self.assertEqual(ans, sol) # Input is pandas.DataFrame with col parameter => pd.Series ans = Calculator.returns(df, col='c1') self.assertSeries(ans) sol = pd.Series(sol_array_1, index=df.index, name='c1 returns') self.assertEqual(ans, sol) # -- ans = Calculator.returns(df, col='c2') self.assertSeries(ans) sol = pd.Series(sol_array_2, index=df.index, name='c2 returns') self.assertEqual(ans, sol) # Test: Input is pandas.DataFrame without col parameter => pd.DataFrame ans = Calculator.returns(df) sol = pd.DataFrame(sol_matrix, index=df.index, columns=df.columns) self.assertEqual(ans, sol)
def test_returns(self): # Variables array_1 = np.array([1,1.5,3,4,4.3]) array_2 = np.array([5,4.3,3,3.5,1]) matrix = np.array([array_1, array_2]).T ser = pd.Series(array_1, name='TEST') df = pd.DataFrame(matrix, columns=['c1', 'c2']) sol_array_1 = np.array([0, 0.5, 1, 0.33333333, 0.075]) sol_array_2 = np.array([ 0., -0.14, -0.30232558, 0.16666667, -0.71428571]) sol_matrix = np.array([sol_array_1, sol_array_2]).T # Input is numpy.array of 1 dimmension => np.ndarray ans = Calculator.returns(array_1) self.assertArray(ans) self.assertEqual(ans, sol_array_1, 5) # Input is numpy.ndarray of 2 dimmension 2 => np.ndarray ans = Calculator.returns(matrix) self.assertArray(ans) self.assertEqual(ans, sol_matrix, 5) # Input is pandas.Series => pd.Series ans = Calculator.returns(ser) self.assertSeries(ans) sol = pd.Series(sol_array_1, index=ser.index, name='TEST returns') self.assertEqual(ans, sol) # Input is pandas.DataFrame with col parameter => pd.Series ans = Calculator.returns(df, col='c1') self.assertSeries(ans) sol = pd.Series(sol_array_1, index=df.index, name='c1 returns') self.assertEqual(ans, sol) # -- ans = Calculator.returns(df, col='c2') self.assertSeries(ans) sol = pd.Series(sol_array_2, index=df.index, name='c2 returns') self.assertEqual(ans, sol) # Test: Input is pandas.DataFrame without col parameter => pd.DataFrame ans = Calculator.returns(df) sol = pd.DataFrame(sol_matrix, index=df.index, columns=df.columns) self.assertEqual(ans, sol)
plt.show() # Question 9 W0 = 100000 R = stats.norm(loc=0.04, scale=0.09) print(9, W0 * R.ppf(0.01), W0 * R.ppf(0.05)) # Question 10 W0 = 100000 r = stats.norm(loc=0.04, scale=0.09) r_1, r_5 = r.ppf(0.01), r.ppf(0.05) R_1, R_5 = math.exp(r_1) - 1, math.exp(r_5) - 1 print(10, W0 * R_1, W0 * R_5) # Question 11 q11_amzn = Calculator.ret([38.23, 41.29]) # q11_amzn = Calculator.R(PV=38.23, FV=41.29) # Other option q11_cost = Calculator.ret([41.11, 41.74]) print(11, q11_amzn, q11_cost) # Question 12 q12_amzn = Calculator.ret([38.23, 41.29], cc=True) q12_cost = Calculator.ret([41.11, 41.74], cc=True) print(12, q12_amzn, q12_cost) # Question 13 q13_amzn = Calculator.ret([38.23, 41.29], dividends=[0, 0.1]) print(13, q13_amzn, 0.1/41.29) print(13, (41.29 + 0.1)/38.23 - 1, 0.1/41.29) # Question 14
da = DataAccess() # Question 1 symbols = ['SBUX'] start_date = datetime(1993, 3, 31) end_date = datetime(2008, 3, 31) fields = "Adj Close" data = da.get_data(symbols, start_date, end_date, fields) monthly = data.asfreq('M', method='ffill') monthly.plot() plt.title('Montly Data') plt.draw() # Question 2 and 3 total_return = Calculator.ret(data) q2 = Calculator.FV(PV=10000, R=total_return) print(2, q2) # Question 3 q3 = Calculator.ann_ret(R=total_return, m=1 / 15) print(3, q3) # Question 4 monthly_ln = monthly.apply(np.log) monthly_ln.plot() plt.title('Montly Natural Logarithm') plt.draw() # Question 5 monthly_returns = Calculator.returns(monthly)
# Create the data data = [['December, 2004', 31.18], ['January, 2005', 27.00],['February, 2005', 25.91], ['March, 2005', 25.83],['April, 2005', 24.76],['May, 2005', 27.40], ['June, 2005', 25.83],['July, 2005', 26.27],['August, 2005', 24.51], ['September, 2005', 25.05],['October, 2005', 28.28],['November, 2005', 30.45], ['December, 2005', 30.51]] starbucks = pd.DataFrame(data, columns=['Date', 'Value']).set_index('Date')['Value'] ''' Question 1: Using the data in the table, what is the simple monthly return between the end of December 2004 and the end of January 2005? Ans: -13.40% ''' q1 = Calculator.ret(starbucks, pos=1) # q1 = Calculator.R(PV=data[0][1], FV=data[1][1]) # Other option print(1, q1) ''' Question 2: If you invested $10,000 in Starbucks at the end of December 2004, how much would the investment be worth at the end of January 2005? Ans: $8659.39 ''' q2 = Calculator.FV(PV=10000, R=q1) print(2, q2) ''' Question 3: Using the data in the table, what is the continuously compounded monthly return between December 2004 and January 2005? Ans: -14.39% '''
da = DataAccess() # Question 1 symbols = ['SBUX'] start_date = datetime(1993, 3, 31) end_date = datetime(2008, 3, 31) fields = 'adjusted_close' data = da.get_data(symbols, start_date, end_date, fields) monthly = data.asfreq('M', method='ffill') monthly.plot() plt.title('Montly Data') plt.draw() # Question 2 and 3 total_return = Calculator.ret(data) q2 = Calculator.FV(PV=10000, R=total_return) print(2, q2) # Question 3 q3 = Calculator.ann_ret(R=total_return, m=1/15) print(3, q3) # Question 4 monthly_ln = monthly.apply(np.log) monthly_ln.plot() plt.title('Montly Natural Logarithm') plt.draw() # Question 5 monthly_returns = Calculator.returns(monthly)
def run(self): ''' Assess the events |-----100-----|-------20-------|-|--------20--------| estimation lookback event lookforward Prerequisites ------------- self.matrix self.market = 'SPY' self.lookback_days = 20 self.lookforward_days = 20 self.estimation_period = 200 self.field = 'Adj Close' ''' # 0. Get the dates and Download/Import the data symbols = list(set(self.list)) start_date = self.list.index[0] end_date = self.list.index[-1] nyse_dates = DateUtils.nyse_dates( start=start_date, end=end_date, lookbackDays=self.lookback_days + self.estimation_period + 1, lookforwardDays=self.lookforward_days) data = self.data_access.get_data(symbols, nyse_dates[0], nyse_dates[-1], self.field) market = self.data_access.get_data(self.market, nyse_dates[0], nyse_dates[-1], self.field) if len(data.columns) == 1: data.columns = symbols if len(data) > len(market): market = market.reindex(data.index) market.columns = [self.field] data = data.fillna(method='ffill').fillna(method='bfill') market = market.fillna(method='ffill').fillna(method='bfill') # 1. Create DataFrames with the data of each event windows_indexes = range(-self.lookback_days, self.lookforward_days + 1) estimation_indexes = range( -self.estimation_period - self.lookback_days, -self.lookback_days) self.equities_window = pd.DataFrame(index=windows_indexes) self.equities_estimation = pd.DataFrame(index=estimation_indexes) self.market_window = pd.DataFrame(index=windows_indexes) self.market_estimation = pd.DataFrame(index=estimation_indexes) dr_data = Calculator.returns(data) dr_market = Calculator.returns(market) self.dr_equities_window = pd.DataFrame(index=windows_indexes) self.dr_equities_estimation = pd.DataFrame(index=estimation_indexes) self.dr_market_window = pd.DataFrame(index=windows_indexes) self.dr_market_estimation = pd.DataFrame(index=estimation_indexes) # 2. Iterate over the list of events and fill the DataFrames for i in range(len(self.list)): symbol = self.list[i] evt_date = self.list.index[i].to_pydatetime() col_name = symbol + ' ' + evt_date.strftime('%Y-%m-%d') evt_idx = DateUtils.search_closer_date(evt_date, data[symbol].index, exact=True) # 1.1 Data on the estimation period: self.equities_estimation start_idx = evt_idx - self.lookback_days - self.estimation_period # estimation start idx on self.data end_idx = evt_idx - self.lookback_days # estimation end idx on self.data new_equities_estimation = data[symbol][start_idx:end_idx] new_equities_estimation.index = self.equities_estimation.index self.equities_estimation[col_name] = new_equities_estimation # Daily return of the equities on the estimation period new_dr_equities_estimation = dr_data[symbol][start_idx:end_idx] new_dr_equities_estimation.index = self.dr_equities_estimation.index self.dr_equities_estimation[col_name] = new_dr_equities_estimation # 1.4 Market on the estimation period: self.market_estimation new_market_estimation = market[self.field][start_idx:end_idx] new_market_estimation.index = self.market_estimation.index self.market_estimation[col_name] = new_market_estimation # Daily return of the market on the estimation period new_dr_market_estimation = dr_market[start_idx:end_idx] new_dr_market_estimation.index = self.dr_market_estimation.index self.dr_market_estimation[col_name] = new_dr_market_estimation # 1.3 Equities on the event window: self.equities_window start_idx = evt_idx - self.lookback_days # window start idx on self.data end_idx = evt_idx + self.lookforward_days + 1 # window end idx on self.data new_equities_window = data[symbol][start_idx:end_idx] new_equities_window.index = self.equities_window.index self.equities_window[col_name] = new_equities_window # Daily return of the equities on the event window new_dr_equities_window = dr_data[symbol][start_idx:end_idx] new_dr_equities_window.index = self.dr_equities_window.index self.dr_equities_window[col_name] = new_dr_equities_window # 1.4 Market on the event window: self.market_window new_market_window = market[self.field][start_idx:end_idx] new_market_window.index = self.market_window.index self.market_window[col_name] = new_market_window # Daily return of the market on the event window new_dr_market_window = dr_market[start_idx:end_idx] new_dr_market_window.index = self.dr_market_window.index self.dr_market_window[col_name] = new_dr_market_window # 3. Calculate the linear regression -> expected return self.reg_estimation = pd.DataFrame( index=self.dr_market_estimation.columns, columns=['Intercept', 'Slope', 'Std Error']) self.er = pd.DataFrame(index=self.dr_market_window.index, columns=self.dr_market_window.columns) # For each column (event) on the estimation period for col in self.dr_market_estimation.columns: # 3.1 Calculate the regression x = self.dr_market_estimation[col] y = self.dr_equities_estimation[col] slope, intercept, r_value, p_value, slope_std_error = stats.linregress( x, y) self.reg_estimation['Slope'][col] = slope self.reg_estimation['Intercept'][col] = intercept self.reg_estimation['Std Error'][col] = slope_std_error # 3.2 Calculate the expected return of each date using the regression self.er[col] = intercept + self.dr_market_window[col] * slope # 4. Final results self.er.columns.name = 'Expected return' self.mean_er = self.er.mean(axis=1) self.mean_er.name = 'Mean ER' self.std_er = self.er.std(axis=1) self.std_er.name = 'Std ER' self.ar = self.dr_equities_window - self.er self.ar.columns.name = 'Abnormal return' self.mean_ar = self.ar.mean(axis=1) self.mean_ar.name = 'Mean AR' self.std_ar = self.ar.std(axis=1) self.std_ar.name = 'Std AR' self.car = self.ar.apply(np.cumsum) self.car.columns.name = 'Cum Abnormal Return' self.mean_car = self.car.mean(axis=1) self.mean_car.name = 'Mean CAR' self.std_car = self.car.std(axis=1) self.mean_car.name = 'Mean CAR'
def run(self): """ Assess the events |-----100-----|-------20-------|-|--------20--------| estimation lookback event lookforward Prerequisites ------------- self.matrix self.market = 'SPY' self.lookback_days = 20 self.lookforward_days = 20 self.estimation_period = 200 self.field = 'Adj Close' """ # 0. Get the dates and Download/Import the data symbols = list(set(self.list)) start_date = self.list.index[0] end_date = self.list.index[-1] nyse_dates = DateUtils.nyse_dates( start=start_date, end=end_date, lookbackDays=self.lookback_days + self.estimation_period + 1, lookforwardDays=self.lookforward_days, ) data = self.data_access.get_data(symbols, nyse_dates[0], nyse_dates[-1], self.field) market = self.data_access.get_data(self.market, nyse_dates[0], nyse_dates[-1], self.field) if len(data.columns) == 1: data.columns = symbols if len(data) > len(market): market = market.reindex(data.index) market.columns = [self.field] data = data.fillna(method="ffill").fillna(method="bfill") market = market.fillna(method="ffill").fillna(method="bfill") # 1. Create DataFrames with the data of each event windows_indexes = range(-self.lookback_days, self.lookforward_days + 1) estimation_indexes = range(-self.estimation_period - self.lookback_days, -self.lookback_days) self.equities_window = pd.DataFrame(index=windows_indexes) self.equities_estimation = pd.DataFrame(index=estimation_indexes) self.market_window = pd.DataFrame(index=windows_indexes) self.market_estimation = pd.DataFrame(index=estimation_indexes) dr_data = Calculator.returns(data) dr_market = Calculator.returns(market) self.dr_equities_window = pd.DataFrame(index=windows_indexes) self.dr_equities_estimation = pd.DataFrame(index=estimation_indexes) self.dr_market_window = pd.DataFrame(index=windows_indexes) self.dr_market_estimation = pd.DataFrame(index=estimation_indexes) # 2. Iterate over the list of events and fill the DataFrames for i in range(len(self.list)): symbol = self.list[i] evt_date = self.list.index[i].to_pydatetime() col_name = symbol + " " + evt_date.strftime("%Y-%m-%d") evt_idx = DateUtils.search_closer_date(evt_date, data[symbol].index, exact=True) # 1.1 Data on the estimation period: self.equities_estimation start_idx = evt_idx - self.lookback_days - self.estimation_period # estimation start idx on self.data end_idx = evt_idx - self.lookback_days # estimation end idx on self.data new_equities_estimation = data[symbol][start_idx:end_idx] new_equities_estimation.index = self.equities_estimation.index self.equities_estimation[col_name] = new_equities_estimation # Daily return of the equities on the estimation period new_dr_equities_estimation = dr_data[symbol][start_idx:end_idx] new_dr_equities_estimation.index = self.dr_equities_estimation.index self.dr_equities_estimation[col_name] = new_dr_equities_estimation # 1.4 Market on the estimation period: self.market_estimation new_market_estimation = market[self.field][start_idx:end_idx] new_market_estimation.index = self.market_estimation.index self.market_estimation[col_name] = new_market_estimation # Daily return of the market on the estimation period new_dr_market_estimation = dr_market[start_idx:end_idx] new_dr_market_estimation.index = self.dr_market_estimation.index self.dr_market_estimation[col_name] = new_dr_market_estimation # 1.3 Equities on the event window: self.equities_window start_idx = evt_idx - self.lookback_days # window start idx on self.data end_idx = evt_idx + self.lookforward_days + 1 # window end idx on self.data new_equities_window = data[symbol][start_idx:end_idx] new_equities_window.index = self.equities_window.index self.equities_window[col_name] = new_equities_window # Daily return of the equities on the event window new_dr_equities_window = dr_data[symbol][start_idx:end_idx] new_dr_equities_window.index = self.dr_equities_window.index self.dr_equities_window[col_name] = new_dr_equities_window # 1.4 Market on the event window: self.market_window new_market_window = market[self.field][start_idx:end_idx] new_market_window.index = self.market_window.index self.market_window[col_name] = new_market_window # Daily return of the market on the event window new_dr_market_window = dr_market[start_idx:end_idx] new_dr_market_window.index = self.dr_market_window.index self.dr_market_window[col_name] = new_dr_market_window # 3. Calculate the linear regression -> expected return self.reg_estimation = pd.DataFrame( index=self.dr_market_estimation.columns, columns=["Intercept", "Slope", "Std Error"] ) self.er = pd.DataFrame(index=self.dr_market_window.index, columns=self.dr_market_window.columns) # For each column (event) on the estimation period for col in self.dr_market_estimation.columns: # 3.1 Calculate the regression x = self.dr_market_estimation[col] y = self.dr_equities_estimation[col] slope, intercept, r_value, p_value, slope_std_error = stats.linregress(x, y) self.reg_estimation["Slope"][col] = slope self.reg_estimation["Intercept"][col] = intercept self.reg_estimation["Std Error"][col] = slope_std_error # 3.2 Calculate the expected return of each date using the regression self.er[col] = intercept + self.dr_market_window[col] * slope # 4. Final results self.er.columns.name = "Expected return" self.mean_er = self.er.mean(axis=1) self.mean_er.name = "Mean ER" self.std_er = self.er.std(axis=1) self.std_er.name = "Std ER" self.ar = self.dr_equities_window - self.er self.ar.columns.name = "Abnormal return" self.mean_ar = self.ar.mean(axis=1) self.mean_ar.name = "Mean AR" self.std_ar = self.ar.std(axis=1) self.std_ar.name = "Std AR" self.car = self.ar.apply(np.cumsum) self.car.columns.name = "Cum Abnormal Return" self.mean_car = self.car.mean(axis=1) self.mean_car.name = "Mean CAR" self.std_car = self.car.std(axis=1) self.mean_car.name = "Mean CAR"
plt.show() # Question 9 W0 = 100000 R = stats.norm(loc=0.04, scale=0.09) print(9, W0 * R.ppf(0.01), W0 * R.ppf(0.05)) # Question 10 W0 = 100000 r = stats.norm(loc=0.04, scale=0.09) r_1, r_5 = r.ppf(0.01), r.ppf(0.05) R_1, R_5 = math.exp(r_1) - 1, math.exp(r_5) - 1 print(10, W0 * R_1, W0 * R_5) # Question 11 q11_amzn = Calculator.ret([38.23, 41.29]) # q11_amzn = Calculator.R(PV=38.23, FV=41.29) # Other option q11_cost = Calculator.ret([41.11, 41.74]) print(11, q11_amzn, q11_cost) # Question 12 q12_amzn = Calculator.ret([38.23, 41.29], cc=True) q12_cost = Calculator.ret([41.11, 41.74], cc=True) print(12, q12_amzn, q12_cost) # Question 13 q13_amzn = Calculator.ret([38.23, 41.29], dividends=[0, 0.1]) print(13, q13_amzn, 0.1 / 41.29) print(13, (41.29 + 0.1) / 38.23 - 1, 0.1 / 41.29) # Question 14
from datetime import datetime import matplotlib.pyplot as plt from finance.utils import Calculator from finance.sim import MarketSimulator # from finance.utils import DataAccess # DataAccess.path = 'data' sim = MarketSimulator() sim.initial_cash = 1000000 sim.load_trades("MarketSimulator_orders.csv") sim.simulate() print(sim.portfolio[0:10]) print('Total Return:', Calculator.ret(sim.portfolio)) print(Calculator.sharpe_ratio(sim.portfolio)) sim.portfolio.plot() # plt.grid(True) plt.show()
data = [['December, 2004', 31.18], ['January, 2005', 27.00], ['February, 2005', 25.91], ['March, 2005', 25.83], ['April, 2005', 24.76], ['May, 2005', 27.40], ['June, 2005', 25.83], ['July, 2005', 26.27], ['August, 2005', 24.51], ['September, 2005', 25.05], ['October, 2005', 28.28], ['November, 2005', 30.45], ['December, 2005', 30.51]] starbucks = pd.DataFrame(data, columns=['Date', 'Value']).set_index('Date')['Value'] ''' Question 1: Using the data in the table, what is the simple monthly return between the end of December 2004 and the end of January 2005? Ans: -13.40% ''' q1 = Calculator.ret(starbucks, pos=1) # q1 = Calculator.R(PV=data[0][1], FV=data[1][1]) # Other option print(1, q1) ''' Question 2: If you invested $10,000 in Starbucks at the end of December 2004, how much would the investment be worth at the end of January 2005? Ans: $8659.39 ''' q2 = Calculator.FV(PV=10000, R=q1) print(2, q2) ''' Question 3: Using the data in the table, what is the continuously compounded monthly return between December 2004 and January 2005? Ans: -14.39% ''' q3 = Calculator.ret(starbucks, pos=1, cc=True)