python7c 高等数学 之 BL模型,barra收益回归模型

1. BL

def blacklitterman(returns,tau,P,Q):

mu=returns.mean()

sigma=returns.cov() #协方差

pil=np.expand_dims(mu,axis=0).T #转换维度,axis=0代表扩展列; axis=-1代表扩展最后一个参数

ts=tau*sigma

ts_1=linalg.inv(ts) #np.linalg.inv():矩阵求逆

Omega = np.dot(np.dot(P,ts), P.T)* np.eye(Q.shape[0])#如果a和b都是一维数组,np.dot 向量的内积;如果a和b都是二维数组,那么它返回的是矩阵乘法。# np.eye 对角线为1,其他为0

Omega_1 = linalg.inv(Omega)

er = np.dot(linalg.inv(ts_1 + np.dot(np.dot(P.T,Omega_1),P)),(np.dot(ts_1 ,pil)+np.dot(np.dot(P.T,Omega_1),Q)))

posterirorSigma = linalg.inv(ts_1 + np.dot(np.dot(P.T,Omega_1),P))

return [er, posterirorSigma]

##定义最小化方差的函数,即求解二次规划

def blminVar(blres, goalRet):

covs = np.array(blres[1],dtype=float)

means = np.array(blres[0],dtype=float)

L1 = np.append(np.append(covs.swapaxes(0,1),[means.flatten()],axis=0),[np.ones(len(means))],axis=0).swapaxes(0,1)

## 使用transpose()函数转换各个元素的维度,其括号内如果不加入参数,其含义为:将数组的各个元素,从原默认维度顺序,转换至括号内维度顺序。

##swapaxes类似,是作用在维度上的

# #means.flatten(), 返回一维数组

L2 = list(np.ones(len(means)))

L2.extend([0,0])

##数据拼接

L3 = list(means)

L3.extend([0,0])

L4 = np.array([L2,L3],dtype=float)

L = np.append(L1,L4,axis=0)

results = linalg.solve(L,np.append(np.zeros(len(means)),[1,goalRet]))

## b。a是一个N*N的二维数组,而b是一个长度为N的一维数组,solve函数找到一个长度为N的一维数组x,使得a和x的矩阵乘积正好等于b,数组x就是多元一次方程组的解。

# return pd.DataFrame(results[:-2],columns = ['p_weight'])

#blresult = blminVar(res,0.70/252)

#print(blresult)

对权重进行赋值

def statistics(weights):

weights = np.array(weights)

# returns.mean() = np.array(blres[1],dtype=float)

# returns.cov()= np.array(blres[0],dtype=float)

port_returns = np.sum(returns.mean()*weights)*252

port_variance = np.sqrt(np.dot(weights.T, np.dot(returns.cov()*252,weights)))

sharpe=port_returns/port_variance

return np.array([port_returns, port_variance, sharpe])

#最小化夏普指数的负值,port_returns/port_variance为夏普

def min_sharpe(weights):

return -statistics(weights)[2]

def con(args):

#约束是所有参数(权重)的总和为1。这可以用minimize函数的约定表达如下,type可选'eq'和'ineq',分别是等式=0约束和不等式约束>=0,

x1min,x1max,x2min,x2max,x3min,x3max=args

cons = ({'type':'eq', 'fun':lambda x: np.sum(x)-1},\

{'type': 'ineq', 'fun': lambda x: x[0] - x1min},\

{'type': 'ineq', 'fun': lambda x: -x[0] + x1max},\

{'type': 'ineq', 'fun': lambda x: x[1] - x2min},\

{'type': 'ineq', 'fun': lambda x: -x[1] + x2max},\

{'type': 'ineq', 'fun': lambda x: x[2] - x3min},\

{'type': 'ineq', 'fun': lambda x: -x[2] + x3max})

return cons

args1 = (0.1,0.9,0.1, 0.9,0.1,0.9) #x1min, x1max, x2min, x2max

cons = con(args1)

#设置初始猜测值 ,

x0 = np.asarray((0.5,0.5,0.5))

res = sco.minimize(min_sharpe(weights), x0, method='SLSQP',constraints=cons)

print(res.fun)

print(res.success)

print(res.x)

2. Barra 回归

(1) 需要按昨日和今日计算的部分

(2) 去极值、标准化

(3) WLS 加权回归

barra_returns = pd.DataFrame()

for i in last_day.index: # 这里的last_day 是前一日, this_day 是当日

try: # 谨防barra日期没有及时更新

# 找到回归的x和y,收益率为模拟法下股票收益

# x 为前一日实际barra的因子值

c1, barra_raw1 = _get_temp_combine(c, last_day[i])

factor_c1 = factor_c1.set_index('code')

# factor_market 是 barra在前一日的所有股票因子值

factor_market = barra_raw1.set_index('code')

# pct_thisday 是当日的股票收益矩阵

pct_thisday = stock_pct.loc[this_day[i], :]

pct_thisday.index = [i.split(".")[0] for i in pct_thisday.index]

# mv是股票的市值矩阵

mv_thisday = stock_mv.loc[this_day[i], :]

mv_thisday.index = [i.split(".")[0] for i in mv_thisday.index]

# 去极值

returns_pct_market2 = pct_thisday * 0.01

def extreme_percentile(rawdata, min=0.025, max=0.975):

p = rawdata.quantile([min, max]) # 得到上下限的值

return rawdata.clip(p.loc[min, :], p.loc[max, :], axis=1) # 超出上下限的值,赋值为上下限

factor_market2a = extreme_percentile(factor_market, min=0.1, max=0.9)

# 标准化

factor_market2b = (factor_market2a.T - (factor_market2a.dropna()).mean(axis=1)) / (factor_market2a.dropna()).std(axis=1)

factor_market2 = factor_market2b.T.dropna()

# 直接使用weight进行加权, barra中已验证使用根号市值,进行加权

weight = (np.sqrt(mv_thisday) / (np.sqrt(mv_thisday)).sum())

weight1 = weight[factor_market2.index].replace(np.nan, 0).replace(-np.inf, 0).replace(np.inf, 0)

dataall_market2 =pd.merge(returns_pct_market2 , factor_market2, left_index=True, right_index=True, how='inner') # 将回归的股票数量对齐

dataall_market2 = dataall_market2.replace(np.nan, 0).replace(-np.inf, 0).replace(np.inf, 0)

factor0_market2 = dataall_market2.iloc[:, 1:] # 全市场barra因子,排除国家

returns0_market2 = dataall_market2.iloc[:, 0] # 全市场收益率

x = factor0_market2

y = returns0_market2

model = sm.WLS(y, x, weights=weight1).fit()

z = model.params[:]

barra_returns.loc[:, this_day[i]] = z # 需要按昨日和今日计算的部分

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Barra模型是指由Barra公司开发并广泛应用于股票投资组合管理和风险分析的一种量化模型。它通过对股票的基本面因素进行分析,以预测股票的收益和风险,并用于构建投资组合。 Barra模型的核心是风险因子模型,该模型将投资组合的收益率与各种市场风险因子的变动相关联,从而解释投资组合的风险和收益。这些风险因子包括股票市场风险、行业风险、公司规模风险、财务风险等。通过对这些风险因子的分析,可以了解投资组合在不同市场环境下的表现和风险。 Python是一种广泛应用于数据科学和量化金融领域的编程语言,它具有易学易用的特点,且有丰富的库和工具支持。在Barra模型的应用中,Python可以用于数据获取、数据分析和模型构建等方面。可以使用Python的各种库,如pandas、numpy、scipy等处理和分析大量的股票和市场数据,同时也可以使用matplotlib和seaborn等库进行数据可视化和结果展示。此外,Python还有一些特定于金融领域的库,如zipline和pyfolio,可以用于构建投资策略和评估投资组合的表现。 GitHub是一个代码托管平台,用户可以使用Git版本控制系统来管理和分享代码。在Barra模型的应用中,可以使用GitHub来共享和协作开发Barra模型相关的Python代码和其他的工具。用户可以将自己的代码上传到GitHub上,与其他人分享和交流,也可以从GitHub上下载别人的代码并改进完善。 总结来说,Barra模型是一种用于量化金融领域的模型,通过对股票基本面因素的分析来预测股票的收益和风险。Python是一种广泛应用的编程语言,可以用于数据分析和模型构建。而GitHub则是一个代码托管平台,方便用户共享和协作开发代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值