<jupyter_start><jupyter_text>1.1 False Mean-Variance is to optimize risk under certain return, thus it does not mean to long highest sharpe-ratio assets and short the lowest. It depends on the correlation of them.1.2True. LETF combines a series of stocks and it is more convenient to trade as it has a higher liquity.1.3We should have an intercept. It depends on whether we want to replicate the in-sample mean. BITO has bitcoin contracts which can not be explained by SPY and IEF. Meanwhile, the time is short so we should have an intercept.1.4It is effective at tracking in-sample.1.5The value of alpha depends on the benchmark, so maybe they use different benchmark and it will have different outcomes which means perhaps alpha is really just some missing beta from the mode. Sometimes, high alpha will lead to the question of whether theperformance is good, or whether we used a bad model.<jupyter_code>import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns

import statsmodels.api as sm
from sklearn.linear_model import LinearRegression
from arch import arch_model
import scipy.stats
from arch.univariate import GARCH, EWMAVariance
df = pd.read_excel("C:\\Users\\linji\\Desktop\\class\\proshares_analysis_data.xlsx", sheet_name='merrill_factors')
df.set_index("date",inplace=True)
df
columns = list(df.columns)
columns.remove("USGG3M Index")
for i in columns:
    df[i+"_e"] = df[i]-df["USGG3M Index"]
df
columns = [i+"_e" for i in columns]
df1 = df[columns]
df1
mu = df1.mean()*12
vol = df1.std()*np.sqrt(12)
#2.1
def TanZeroPort(covm, mu, scale = 12, ilabels = np.array(df1.columns)):
    scalar1 = np.dot(np.ones(len(covm)),np.linalg.inv(covm)) #compute part of the denominator of the wt formula
    scalar1 = np.dot(scalar1, np.array(mu)) #compute the denominator of the wt formula
    scalar2 = np.dot(np.linalg.inv(covm), np.array(mu)) #compute the second multiplier
    wt = (1/scalar1)*scalar2 #formula from lecture 1 slide 50
    pmean = wt @ mu #compute mean 
    pvol = np.sqrt(wt @ covm @ wt)*np.sqrt(scale) #compute volatility 
    pSharpe = pmean/pvol #compute sharpe ratio
    
    dic = {'Mean': pmean, 'Volatility': pvol, 'Sharpe': pSharpe}
    df = pd.DataFrame(data = wt, index = ilabels, columns = ['WeightsT'])
    
    return df, dic
covm = df1.cov().to_numpy()
muv = np.array(mu)
[wtf, dic] = TanZeroPort(covm, muv, 12)

wtf
#2.2
def MVPortER(targetreturn, covm, mu, scale = 1, ilabels = np.array(df1.columns)):
    scalar1 = np.dot(np.ones(len(covm)),np.linalg.inv(covm)) #compute part of the denominator of the wt formula
    scalar1 = np.dot(scalar1, np.array(mu)) #compute the denominator of the wt formula
    scalar2 = np.dot(np.linalg.inv(covm), np.array(mu)) #compute the second multiplier
    scalar3 = np.dot(np.transpose(mu),np.linalg.inv(covm)) #compute part of the denominator of the delta formula
    scalar3 = np.dot(scalar3, np.array(mu)) #compute the denominator of the delta formula
    
    wt = (1/scalar1)*scalar2 #formula from lecture 1 slide 50
    delta = (scalar1/scalar3)*targetreturn*12 #here annualize target return 
    wp = delta*wt
    
    pmean = wp @ mu #compute mean
    pvol = np.sqrt(wp @ covm @ wp)*np.sqrt(scale) #compute volatility 
    pSharpe = pmean/pvol #compute sharpe ratio

    dic = {'Mean': pmean, 'Volatility': pvol, 'Sharpe': pSharpe}
    df = pd.DataFrame(data = wp, index = ilabels, columns = ['WeightsMVER'])
    
    return df, dic, delta
[wp, dicp,delta] = MVPortER(0.02, covm, muv, 12)
delta
wp
1-delta
#They shor risk-free rate
#2.3
dic
#2.4
df2 = df1[(df1.index>"2018") & (df1.index<"2019")]
df2
mu = df2.mean()*12
covm = df2.cov().to_numpy()
muv = np.array(mu)
[wp, dicp, delta] = MVPortER(0.02, covm, muv, 12)
wp
df3 = df1[df.index>"2019"]
covmos = df3.cov().to_numpy() # get the outsample covariance matrix 
muout = np.array(df3.mean()*12) # get the outsample mean 
wpisx = np.transpose(np.array(wp.to_numpy())) # use wpis from part a

outpmean = wpisx @ muout # compute the new mean
outpvol = np.sqrt(wpisx @ covmos @ np.transpose(wpisx))*np.sqrt(12) # compute the volatility
pSharpe = outpmean/outpvol # compute the Sharpe ratio

print('Mean        :', float(outpmean))
print('Volatility  :', float(outpvol))
print('Sharpe Ratio:', float(pSharpe))
#2.5<jupyter_output><empty_output><jupyter_text>Optimization should be based on expectation of returns goingforward.MV Optimization is sensitive to mean returns, which are not estimated precisely from historic data. While oil,coffee, cocoa, lumber, cattle, and gold also flactuate a lot.Also, MV Optimization is extremely sensitive to the covariance matrix, which changes over time.In this time, oil, coffee, cocoa, lumber, cattle, and gold might perform better. Therefore, oil, coffee, cocoa, lumber, cattle, and gold might perform better.<jupyter_code>#3.1
lhs = df['EEM US Equity']
rhs = df['SPY US Equity']
reg = sm.OLS(lhs, rhs, missing='drop').fit()
beta = reg.params["SPY US Equity"]<jupyter_output><empty_output><jupyter_text>For every dollar invested in EEM, we should short 0.924093 unit of SPY to hedge<jupyter_code>#3.2
eem_new = df['EEM US Equity'] - beta*df['SPY US Equity']
mu = eem_new.mean()*12
std = eem_new.std()*np.sqrt(12)
Sharpe = (eem_new.mean()*12) / (eem_new.std()*np.sqrt(12))
print("mean:%f"%mu)
print("volatility:%f"%std)
print("sharpe:%f"%Sharpe)
#3.3
df['EEM US Equity'].mean()*12<jupyter_output><empty_output><jupyter_text>Therefore, it does not have the same mean.<jupyter_code>#3.4
df[['EEM US Equity',"SPY US Equity","IWM US Equity"]].corr()<jupyter_output><empty_output><jupyter_text>From the correlation matrix, we can see that they are highly correlated.<jupyter_code>#4.1
df_log = np.log(df+1)
mu_s =  df_log["SPY US Equity"].mean()*12
vol_s =  df_log["SPY US Equity"].std()*np.sqrt(12)
mu_e =  df_log["EFA US Equity"].mean()*12
vol_e =  df_log["EFA US Equity"].std()*np.sqrt(12)
def prob_calc(mu, bar_r, sigma, years=10):
    x = np.sqrt(years) * (mu - bar_r)/sigma
    val = scipy.stats.norm.cdf(x)
    return val
prob_calc(mu_s,mu_e,vol_s)
mu_s
mu_e
index=df.index 
dic1={}
for i in range(0,len(index)-59):
    temp = df[(df.index>=index[i])&(df.index<=index[i+59])]
    dic1[index[i+59]]=temp["EFA US Equity"].std()*np.sqrt(12)
    mu1 = temp.mean()*12
pd.DataFrame(list(dic1.items()), columns=["date",'vol'])
x = temp-mu1/temp["EFA US Equity"].std()*np.sqrt(12)
val = scipy.stats.norm.cdf(x)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13394381499301566, 'fraction_numerical': 0.02498835945987894, 'mean_word_length': 4.702654867256637, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 24, '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': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '155751', 'license': 'MIT', 'n_tokens_mistral': 2464, 'n_tokens_neox': 2332, 'n_words': 689, 'path': 'solutions/mid1/submissions/linjin_167549_6241554_midterm.ipynb', 'repo_name': 'tulyu96/finm-portfolio-2021', 'size': '6443'}