如何使用cvxopt.qp为二次规划设置因子暴露约束?

时间:2017-07-26 15:34:31

标签: python optimization constraints quadratic cvxopt

尝试优化投资组合权重分配,以最大限度地降低经典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)

1 个答案:

答案 0 :(得分:0)

此库cvxportfolio易于解决因子暴露约束问题。cvxpy