0

尝试在这里优化投资组合权重分配,以最大限度地降低经典 Markowitz 投资组合的风险。假设我有一个表示像的因子暴露约束数据框

In [138]: exp_sub = pd.DataFrame(data=[[-10, 20],[-10, 20],[-10, 20],[-10, 20],[-10, 20]], columns=['lower','upper'])

In [131]: exp_sub
In [132]:    lower  upper
0    -10     20
1    -10     20
2    -10     20
3    -10     20
4    -10     20

我尝试在我的代码中添加此约束,但即使 sol 的状态为最佳,解决方案也不正确。有人可以帮忙吗?谢谢你。

我的代码如下:

# -*- coding: utf-8 -*-
### Portfolio Optiimization
# Finds an optimal allocation of stocks in a portfolio,
# satisfying a minimum expected return.
# The problem is posed as a Quadratic Program, and solved
# using the cvxopt library.
# Uses actual past stock data, obtained using the stocks module.

import sys
import itertools
from cvxopt import matrix, solvers, spmatrix, sparse
from cvxopt.blas import dot
import pandas as pd
import numpy as np
from datetime import datetime

solvers.options['show_progress'] = False

import logging
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)


# solves the QP, where x is the allocation of the portfolio:
# minimize   x'Px + q'x
# subject to Gx <= h
#            Ax == b
#
# Input:  n       - # of assets
#         avg_ret - nx1 matrix of average returns
#         covs    - nxn matrix of return covariance
#         r_min   - the minimum expected return that you'd
#                   like to achieve
# Output: sol - cvxopt solution object

dates = pd.date_range('2000-01-01', periods=6)
industry = ['industry', 'industry', 'utility', 'utility', 'consumer']
symbols = ['A', 'B', 'C', 'D', 'E']
zipped = list(zip(industry, symbols))
index = pd.MultiIndex.from_tuples(zipped)

noa = len(symbols)

data = np.array([[10, 11, 12, 13, 14, 10],
                 [10, 11, 10, 13, 14, 9],
                 [10, 10, 12, 13, 9, 11],
                 [10, 11, 12, 13, 14, 8],
                 [10, 9, 12, 13, 14, 9]])

market_to_market_price = pd.DataFrame(data.T, index=dates, columns=index)
rets = market_to_market_price / market_to_market_price.shift(1) - 1.0
rets = rets.dropna(axis=0, how='all')

# covariance of asset returns
covs    = matrix(rets.cov().values)

# average yearly return for each stock
rets_mean = rets.mean()
avg_ret = matrix(rets_mean.values)
n = len(symbols)

factor_exposure = pd.DataFrame(np.ones((5,5)),
                               columns=list('ABCDE'))


P = covs
q = matrix(np.zeros((n, 1)), tc='d')
asset_sub = matrix(np.eye(n), tc='d')
asset_sub = matrix(sparse([asset_sub, -asset_sub]))
exp_sub = matrix(factor_exposure.values)
exp_sub = matrix(sparse([exp_sub, -exp_sub]))
# set boundary vector for h
df_asset_weight = pd.DataFrame({'lower': [0.0], 'upper': [1.0]},
                               index=list("ABCDE"))
df_asset_bnd_matrix = matrix(np.concatenate(((df_asset_weight.upper,
                                              df_asset_weight.lower)), 0))


df_factor_exposure_bound = pd.DataFrame(data=[[-10, 20],[-10, 20],[-10, 20],[-10, 20],[-10, 20]], columns=['lower','upper'])


df_factor_exposure_bnd_matrix = matrix(np.concatenate(((df_factor_exposure_bound.upper,
                                                        df_factor_exposure_bound.lower)), 0))


G = matrix(sparse([asset_sub, exp_sub]))
h = matrix(sparse([df_asset_bnd_matrix, df_factor_exposure_bnd_matrix]))

# equality constraint Ax = b; captures the constraint sum(x) == 1
A = matrix(1.0, (1, n))
b = matrix(1.0)
sol = solvers.qp(P, q, G, h, A, b)
4

1 回答 1

0

这个库 cvxportfolio 很容易解决因子暴露约束问题。简历

于 2017-08-08T09:18:21.100 回答