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

Rebalancing portfolio creates a Singular Matrix

我正在尝试根据 1 年的数据创建最小方差投资组合。然后我想每个月重新平衡投资组合,从而重新计算协方差矩阵。 (我的数据集从 1992 年开始,到 2017 年结束)。

我做了以下代码,它在不在循环中时有效。但是当放在循环中时,协方差矩阵的逆是奇异的。我不明白为什么会出现这个问题,因为我在循环结束时重置了每个变量。

### 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

有没有人有解决这个问题的想法?

它产生的错误如下:

---------------------------------------------------------------------------
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

非常感谢您能为我提供的任何帮助!

数据在以下 google 驱动器中共享:https://drive.google.com/file/d/1-Bw7cowZKCNU4JgNCitmblHVw73ORFKR/view?usp=sharing

最好确定是什么导致了矩阵的奇点 但是有奇异矩阵的方法。

尝试使用 np.linalg.pinv() 的伪逆。它保证永远存在。 参见 pinv

另一种解决方法是完全避免计算逆矩阵。 只需找到系统的最小二乘解即可。参见 lstsq

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

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