简体   繁体   English

再平衡投资组合创建奇异矩阵

[英]Rebalancing portfolio creates a Singular Matrix

I am trying to create a minimum variance portfolio based on 1 year of data.我正在尝试根据 1 年的数据创建最小方差投资组合。 I then want to rebalance the portfolio every month recomputing thus the covariance matrix.然后我想每月重新平衡投资组合,从而重新计算协方差矩阵。 (my dataset starts in 1992 and finishes in 2017). (我的数据集从 1992 年开始,到 2017 年结束)。

I did the following code which works when it is not in a loop.我做了以下代码,当它不在循环中时它可以工作。 But when put in the loop the inverse of the covariance matrix is Singular.但是当放入循环时,协方差矩阵的逆矩阵是奇异的。 I don't understand why this problem arises since I reset every variable at the end of the loop.我不明白为什么会出现这个问题,因为我在循环结束时重置了每个变量。

### Importing the necessary libraries ###
import pandas as pd
import numpy as np
from numpy.linalg import inv

### Importing the dataset ###
df = pd.read_csv("UK_Returns.csv", sep = ";")
df.set_index('Date', inplace = True)

### Define varibales ###
stocks = df.shape[1]
returns = []
vol = []
weights_p =[]

### for loop to compute portfolio and rebalance every 30 days ###
for i in range (0,288):
  a = i*30
  b = i*30 + 252
  portfolio = df[a:b]
  mean_ret = ((1+portfolio.mean())**252)-1
  var_cov = portfolio.cov()*252
  inv_var_cov = inv(var_cov)
  doit = 0
  weights = np.dot(np.ones((1,stocks)),inv_var_cov)/(np.dot(np.ones((1,stocks)),np.dot(inv_var_cov,np.ones((stocks,1)))))
  ret = np.dot(weights, mean_ret)
  std = np.sqrt(np.dot(weights, np.dot(var_cov, weights.T)))
  returns.append(ret)
  vol.append(std)
  weights_p.append(weights)
  weights = []
  var_cov = np.zeros((stocks,stocks))
  inv_var_cov = np.zeros((stocks,stocks))
  i+=1

Does anyone has an idea to solve this issue?有没有人有解决这个问题的想法?

The error it yields is the following:它产生的错误如下:

---------------------------------------------------------------------------
LinAlgError                               Traceback (most recent call last)
<ipython-input-17-979efdd1f5b2> in <module>()
     21   mean_ret = ((1+portfolio.mean())**252)-1
     22   var_cov = portfolio.cov()*252
---> 23   inv_var_cov = inv(var_cov)
     24   doit = 0
     25   weights = np.dot(np.ones((1,stocks)),inv_var_cov)/(np.dot(np.ones((1,stocks)),np.dot(inv_var_cov,np.ones((stocks,1)))))

<__array_function__ internals> in inv(*args, **kwargs)

1 frames
/usr/local/lib/python3.6/dist-packages/numpy/linalg/linalg.py in _raise_linalgerror_singular(err, flag)
     95 
     96 def _raise_linalgerror_singular(err, flag):
---> 97     raise LinAlgError("Singular matrix")
     98 
     99 def _raise_linalgerror_nonposdef(err, flag):

LinAlgError: Singular matrix

Thank you so much for any help you can provide me with!非常感谢您为我提供的任何帮助!

The data is shared in the following google drive: https://drive.google.com/file/d/1-Bw7cowZKCNU4JgNCitmblHVw73ORFKR/view?usp=sharing数据在以下谷歌驱动器中共享: https://drive.google.com/file/d/1-Bw7cowZKCNU4JgNCitmblHVw73ORFKR/view?usp=sharing

It would be better to identify what is causing the singularity of the matrix but there are means of living with singular matrices.最好确定是什么导致了矩阵的奇异性,但是有办法使用奇异矩阵。

Try to use pseudoinverse by np.linalg.pinv() .尝试通过np.linalg.pinv()使用伪逆。 It is guaranteed to always exist.它保证永远存在。 See pinvpinv

Other way around it is avoid computing inverse matrix at all.其他方法是完全避免计算逆矩阵。 Just find Least Squares solution of the system.只需找到系统的最小二乘解。 See lstsqlstsq

Just replace np.dot(X,inv_var_cov) with只需将np.dot(X,inv_var_cov)替换为

np.linalg.lstsq(var_conv, X, rcond=None)[0]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM