1、对冲基金绩效评估
(a)年化算术平均收益
(b)年化几何平均收益
(c)超额收益年化波动率
(d)年化夏普比率
(e)市场beta
(f )年化市场阿尔法
(g)年度信息比率
(h)最大回撤
(i)每月超额收益的偏度
(j)每月超额收益的超额峰度
a)
import pandas as pd
import numpy as np
import statsmodels.api as sm
file = "PS_2_Performance_Measurement.xlsx"
# 读取数据
factors = pd.read_excel(file, sheet_name="factors", parse_dates=["date"], index_col="date")
factors.head()
rets = pd.read_excel(file, sheet_name="total_returns", parse_dates=["date"], index_col="date")
rets.head()
# 计算超额收益
xrets = rets.sub(factors.loc[:,"RF"], axis=0) # axis = 0 row wise
# 年化算术平均回报
avg_rets = rets.mean() * 12
avg_rets.map("{:.2%}".format)
b)
# 年化几何平均收益
T = len(rets) / 12 # number of years
geo_avg_rets = (1 + rets).prod().pow(1 / T) - 1
geo_avg_rets.map("{:.2%}".format)
c)
# 超额收益年化波动率
vol = xrets.std()
vol.map("{:.2%}".format)
d)
# 年化 Sharpe Ratio
sr = (xrets.mean() * 12) / vol
round(sr, 2)
e) f) g)
index_names = xrets.columns # 不同的基金策略的名字
# 建立空的 dictionaries 储存线性回归结果
alpha = {}
beta = {}
ssr = {}
for index in index_names:
# 每个基金的超额收益
y = xrets.loc[:,index]
# 市场收益
x = factors.loc[:,"Mkt-RF"]
# 回归
reg = sm.OLS(y, sm.add_constant(x)).fit()
# 更新参数
alpha.update({index: reg.params.loc["const"] * 12})
beta.update({index: reg.params.loc["Mkt-RF"]})
ssr.update({index: reg.ssr})
# transform dictionaries to pandas Series
alpha = pd.Series(alpha)
beta = pd.Series(beta)
ssr = pd.Series(ssr)
round(beta, 2)
alpha.map("{:.2%}".format)
ir = alpha / np.sqrt(ssr / len(xrets) * 12)
round(ir, 2)
h)
cum_rets = (1 + rets).cumprod()
#找到t之前的最大值 最高水位线
hwm = cum_rets.expanding().max()
#回撤
dd = (hwm - cum_rets) / hwm
max_dd = dd.max()
max_dd.map("{:.2%}".format)
i)
# 偏度
skewness = xrets.skew()
round(skewness, 2)
j)
# 峰度
excess_kurtosis = xrets.kurt()
round(excess_kurtosis, 2)
# 收集所有统计数据
names = ["Ann. arith. ave. ret", "Ann. geo. ave. ret", "Ann. volatility",
"Ann. Sharpe ratio", "Market beta", "Ann. alpha to MKT", "Ann. IR",
"Max drawdown", "Skewness", "Excess kurtosis"]
# a list of pandas Series
stats = [avg_rets, geo_avg_rets, vol, sr, beta,
alpha, ir, max_dd, skewness, excess_kurtosis]
# create a pandas DataFrame
stats = pd.DataFrame(stats,index=names)#不能换顺序
for col in [0, 1, 2, 5, 7]: stats.iloc[col] = stats.iloc[col].map("{:.2%}".format)
for col in [3, 4, 6, 8, 9]: stats.iloc[col] = stats.iloc[col].map("{:.2f}".format)
stats
2.画图
在一张图里画出累计收益,最高水位线和回撤
import matplotlib.pyplot as plt
fund_name = "Global Mac Hedge Fund USD"
fig, ax1 = plt.subplots(figsize=(8,4), dpi=100)
# ax1 画累计收益和最高水位线
ax1.plot(cum_rets.loc[:,fund_name], color="blue", label="Cumulative return")
ax1.plot(cum_rets.loc[:,fund_name].expanding().max(), color="grey", ls="--", label="High water mark")
# ax2 画回撤
ax2 = ax1.twinx()
ax2.plot(dd.loc[:,fund_name], color="green", label="Drawdown")
# y轴标签
ax1.set_ylabel("Cumulative return")
ax2.set_ylabel("Drawdown")
ax1.legend(loc="upper left", frameon=False)
ax2.legend(loc="upper center", frameon=False)
plt.title(fund_name)
plt.show()
3. 因子模型
对于Equity Long/Short,运行两个回归:
(i)对冲基金指数的超额收益对市场超额收益的单变量回归;
(ii)市场,规模,价值和momentum因素的多元回归。
i)单因子模型
fund_name = "Ln/Sh Eq Hedge Fund USD"
y = xrets.loc[:,fund_name]
x = factors.loc[:,"Mkt-RF"]
uv_regression = sm.OLS(y, sm.add_constant(x)).fit()
uv_alpha = uv_regression.params.loc["const"] * 12 * 100
uv_alpha = round(uv_alpha, 2)
ii)多因子模型
x = factors.loc[:,["Mkt-RF", "SMB", "HML", "UMD"]]
mv_regression = sm.OLS(y, sm.add_constant(x)).fit()
mv_alpha = mv_regression.params.loc["const"] * 12 * 100
round(mv_alpha, 2)
展示回归结果
from stargazer.stargazer import Stargazer
table = Stargazer([uv_regression, mv_regression])# include reg results
table.add_line("Annualized Alpha (in %)", [uv_alpha, mv_alpha])
table.covariate_order(["const", "Mkt-RF", "SMB", "HML", "UMD"])
table