<jupyter_start><jupyter_text>Load Data<jupyter_code>df = pd.read_excel('hedge_data.xls', sheet_name = [0,1,2], index_col = 0)
df = pd.concat(df.values(), axis=1).loc[:'1998-06',]
df.head()<jupyter_output><empty_output><jupyter_text>Q1 Allocation 1(a) Summary Statistics<jupyter_code>funds_name = df.columns[2:-1]
funds = df[funds_name]
mean_ret_funds = funds.mean() * 12
vol_funds = funds.std() * np.sqrt(12)
SR_funds = mean_ret_funds / vol_funds
pd.DataFrame({'mean return': mean_ret_funds, 'volatility': vol_funds, 'Sharpe ratio':SR_funds})<jupyter_output><empty_output><jupyter_text>1(b)Event Driven has the best sharpe ratio, while Dedicated Short Bias has the worst sharpe ratio  1(c)Even if an asset has a bad Sharpe Ratio individually, it may have low correlation to the other securities such that it diversifies the overall risk. So while it may not have a great return-to-risk tradeoff individually, it can have a good return-to-risk tradeoff with respect to the marginal impact on the portfolio.   1(d)<jupyter_code>funds.quantile(0.05)<jupyter_output><empty_output><jupyter_text>2(a)<jupyter_code>def compute_mv(data, diag=False):
    mu_tilde = data.mean()
    covariance = data.cov()
    if diag:
        covariance = np.diag(np.diag(covariance))
    N = covariance.shape[0]
    cov_inv = np.linalg.inv(covariance)
    omega_tan = cov_inv @ mu_tilde /(np.ones(N) @ cov_inv @ mu_tilde)
    return pd.Series(omega_tan,index=data.columns)

omega_tan = compute_mv(funds)
omega_tan<jupyter_output><empty_output><jupyter_text>3(a)<jupyter_code>omega_tan_diag = compute_mv(funds, True)
omega_tan_diag<jupyter_output><empty_output><jupyter_text>3(b)Based on HW1 and class discussion, we expect the diagonalized version to do better out-of-sample. Though it is a biased estimate (we are purposely using the wrong covariance matrix!) this is worth higher statistical precision. If we use the full covariance matrix in the tangency formula, it is an input to the formula which is very imprecisely estimated, then inverted to make it even more imprecise, then we get extremely imprecise outputs.   3(c)Different objective function (care about quantiles not variance?) different constraints (limits to long-short holdings), etc. Also fine if they talk about non-normality of returns or non iid returns.  Q2 Performance 1(a)  see df  2(a)<jupyter_code>y = df['net']
X = sm.add_constant(df['Total Index'])
res = sm.OLS(y,X,missing='drop').fit()
alpha, beta = res.params
rsquared = res.rsquared
print(f'alpha is {alpha:.4f}, beta is {beta:.4f}, and R^2 is {rsquared:.4f}')<jupyter_output>alpha is 0.0135, beta is 0.0497, and R^2 is 0.0014<jupyter_text>2(b) No. The intercept significantly above 0, indicating existence of other factors.  2(c)No. The $R^2$ is very small, and only 0.14% of the variation is explained by the Total Index  2(d)If the Total Index goes up by 1%, we would expect return of LTCM goes uo by 0.0497% that month  3(a)<jupyter_code>resid_vol = res.resid.std()
IR = alpha / resid_vol
print(f'IR is {IR:.4f}')<jupyter_output>IR is 0.4144
{'fraction_non_alphanumeric': 0.10805500982318271, 'fraction_numerical': 0.02455795677799607, 'mean_word_length': 5.541755888650964, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '637841', 'license': 'MIT', 'n_tokens_mistral': 1123, 'n_tokens_neox': 1053, 'n_words': 325, 'path': 'practice_midterms/Midterm #1 Solution.ipynb', 'repo_name': 'MarkHendricks/finm-quant-2021', 'size': '3054'}