Main Content

이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.

포트폴리오 최적화를 위한 2차 계획법, 문제 기반

이 예제에서는 문제 기반 접근법을 사용하여 포트폴리오 최적화 문제를 푸는 방법을 보여줍니다. 솔버 기반 접근법은 Quadratic Programming for Portfolio Optimization Problems, Solver-Based 항목을 참조하십시오.

2차 모델

포트폴리오에 $n$개의 다양한 자산이 포함되어 있다고 가정하겠습니다. 자산 $i$의 수익률은 예상 값이 $m_i$인 확률 변수입니다. 이 문제는 지정된 최소 예상 수익률에 따라 위험을 최소화하기 위해 각 자산 $i$에 투자할 비율 $x_i$를 찾는 문제입니다.

$C$가 자산 수익률의 공분산 행렬을 나타내도록 합니다.

기본적인 평균 분산 모델은 포트폴리오의 위험을 최소화하도록 구성되며 다음과 같이 측정됩니다.

$$\frac{1}{2}x^T C x$$

여기에는 제약 조건 세트가 적용됩니다.

예상 수익은 다음과 같이 투자자가 바라는 포트폴리오 최소 수익률 $r$ 이상이어야 하고

$$\sum_{i=1}^n m_i \; x_i \ge r,$$

투자 수익률의 합계 $x_i$는 다음과 같이 1이어야 하며

$$\sum_{i=1}^n x_i = 1,$$

투자 수익률(또는 백분율)은 다음과 같이 0과 1 사이의 숫자여야 합니다.

$$0 \le x_i \le 1, \;\;\; i = 1 \ldots n.$$

포트폴리오 위험을 최소화하기 위한 목적 함수가 2차 함수이고 제약 조건은 선형이므로, 이에 따른 최적화 문제는 2차 계획법(QP)입니다.

225-자산 문제

이제 225개의 자산이 있는 QP를 풀어보겠습니다. 데이터셋은 OR-Library [Chang, T.-J., Meade, N., Beasley, J.E. and Sharaiha, Y.M., "Heuristics for cardinality constrained portfolio optimisation" Computers & Operations Research 27 (2000) 1271-1302]에서 발췌했습니다.

문제 기반 접근법을 위해 데이터셋을 불러온 다음 제약 조건을 설정하겠습니다. 이 데이터셋에서는 수익률 $m_i$의 범위가 -0.008489 ~ 0.003971이며, 이 사이에서 희망 수익률 $r$을 선택하겠습니다(예: 0.002 혹은 0.2%).

MAT 파일에 저장된 데이터셋을 불러옵니다.

load('port5.mat','Correlation','stdDev_return','mean_return')

상관 행렬에서 공분산 행렬을 계산합니다.

Covariance = Correlation .* (stdDev_return * stdDev_return');
nAssets = numel(mean_return); r = 0.002;     % number of assets and desired return

최적화 문제, 목적 함수, 제약 조건 만들기

최소화를 위한 최적화 문제를 만듭니다.

portprob = optimproblem;

요소가 nAssets개인 최적화 벡터 변수 'x'를 만듭니다. 이 변수는 각 자산에 투자된 금액의 비율을 나타내므로 0과 1 사이의 값이어야 합니다.

x = optimvar('x',nAssets,'LowerBound',0,'UpperBound',1);

목적 함수는 1/2*x'*Covariance*x입니다. 이 목적 함수를 문제에 포함시킵니다.

objective = 1/2*x'*Covariance*x;
portprob.Objective = objective;

이들 변수의 합은 1이 되며, 이는 전체 포트폴리오가 투자되었음을 의미합니다. 이를 제약 조건으로 표현하고 문제에 추가합니다.

sumcons = sum(x) == 1;
portprob.Constraints.sumcons = sumcons;

평균 수익률은 r보다 커야 합니다. 이를 제약 조건으로 표현하고 문제에 추가합니다.

averagereturn = dot(mean_return,x) >= r;
portprob.Constraints.averagereturn = averagereturn;

225-자산 문제 풀기

몇 가지 옵션을 설정하고 솔버를 호출합니다.

반복 과정을 표시하도록 옵션을 설정하고 더욱 엄밀한 최적성 종료 허용오차를 설정합니다.

options = optimoptions('quadprog','Display','iter','TolFun',1e-10);

솔버를 호출하고 실제 경과 시간을 측정합니다.

tic
[x1,fval1] = solve(portprob,'Options',options);
toc
 Iter            Fval  Primal Infeas    Dual Infeas  Complementarity  
    0    7.212813e+00   1.227500e+02   1.195948e+00     2.217295e-03  
    1    8.160874e-04   3.615084e-01   3.522160e-03     2.250524e-05  
    2    7.220766e-04   3.592574e-01   3.500229e-03     3.378157e-05  
    3    4.309434e-04   9.991108e-02   9.734292e-04     2.790551e-05  
    4    4.734300e-04   5.551115e-16   7.771561e-16     4.242216e-06  
    5    4.719034e-04   6.661338e-16   3.122502e-16     8.002618e-07  
    6    3.587475e-04   4.440892e-16   3.035766e-18     3.677066e-07  
    7    3.131814e-04   8.881784e-16   3.686287e-18     9.586695e-08  
    8    2.760174e-04   7.771561e-16   1.463673e-18     1.521063e-08  
    9    2.345751e-04   1.110223e-15   1.138412e-18     4.109608e-09  
   10    2.042487e-04   1.221245e-15   1.084202e-18     6.423267e-09  
   11    1.961775e-04   1.110223e-16   9.757820e-19     6.068329e-10  
   12    1.949281e-04   4.440892e-16   9.215718e-19     4.279951e-12  

Minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the value of the constraint tolerance.

Elapsed time is 0.292806 seconds.

결과를 플로팅합니다.

plotPortfDemoStandardModel(x1.x)

그룹 제약 조건이 있는 225-자산 문제

이제 투자자가 투자한 금액의 30%는 자산 1 ~ 75에, 30%는 자산 76 ~ 150에, 30%는 자산 151 ~ 225에 투자해야 하는 제약 조건을 모델 그룹에 추가해 보겠습니다. 이러한 각각의 자산 그룹은 서로 다른 산업일 수 있습니다(예: 기술, 자동차, 제약). 이 새로운 요구 사항을 포착하는 제약 조건은 다음과 같습니다.

$$\sum_{i=1}^{75} x_i \ge 0.3, \qquad$$
$$\sum_{i=76}^{150} x_i \ge 0.3, \qquad$$
$$\sum_{i=151}^{225} x_i \ge 0.3.$$

기존 등식에 그룹 제약 조건을 추가합니다.

grp1 = sum(x(1:75)) >= 0.3;
grp2 = sum(x(76:150)) >= 0.3;
grp3 = sum(x(151:225)) >= 0.3;
portprob.Constraints.grp1 = grp1;
portprob.Constraints.grp2 = grp2;
portprob.Constraints.grp3 = grp3;

솔버를 호출하고 실제 경과 시간을 측정합니다.

tic
[x2,fval2] = solve(portprob,'Options',options);
toc
 Iter            Fval  Primal Infeas    Dual Infeas  Complementarity  
    0    7.212813e+00   1.227500e+02   3.539920e-01     5.253824e-03  
    1    7.004556e-03   2.901399e+00   8.367185e-03     2.207460e-03  
    2    9.181962e-04   4.095630e-01   1.181116e-03     3.749424e-04  
    3    7.515047e-04   3.567918e-01   1.028932e-03     3.486333e-04  
    4    4.238346e-04   9.005778e-02   2.597127e-04     1.607718e-04  
    5    3.695008e-04   1.909891e-04   5.507829e-07     1.341881e-05  
    6    3.691407e-04   6.146337e-07   1.772508e-09     6.817457e-08  
    7    3.010636e-04   7.691892e-08   2.218223e-10     1.837302e-08  
    8    2.669065e-04   1.088252e-08   3.138350e-11     5.474712e-09  
    9    2.195767e-04   8.122574e-10   2.342425e-12     2.814320e-08  
   10    2.102910e-04   2.839773e-10   8.189470e-13     1.037476e-08  
   11    2.060985e-04   6.713696e-11   1.936133e-13     2.876950e-09  
   12    2.015107e-04   0.000000e+00   8.131516e-19     1.522226e-10  
   13    2.009670e-04   4.440892e-16   8.673617e-19     5.264375e-13  

Minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the value of the constraint tolerance.

Elapsed time is 0.162406 seconds.

이전 문제의 결과에 겹쳐서 결과를 플로팅합니다.

plotPortfDemoGroupModel(x1.x,x2.x);

지금까지의 결과 요약

두 번째 막대 플롯을 보면 그룹 제약 조건을 추가한 결과 이 포트폴리오가 첫 번째 포트폴리오보다 3개 자산 그룹에서 더욱 고르게 분산되어 있음을 확인할 수 있습니다. 이렇게 다양성을 적용한 결과 목적 함수에서 측정된 값을 기준으로 보면 위험 또한 약간 증가했습니다. 두 실행에서 반복 과정의 마지막 반복에 "f(x)"로 레이블 지정된 열을 참조하십시오.

임의의 데이터를 사용하는 1,000-자산 문제

규모가 더 큰 문제에서 솔버의 동작 방식을 보여주기 위해, 임의로 생성된 1,000-자산 데이터셋을 사용해 보겠습니다. MATLAB®에서 gallery 함수를 사용하여 랜덤 상관 행렬(대각선상의 1을 포함한 양의 준정부호 대칭 행렬)을 생성합니다.

재현성을 위해 난수 스트림을 재설정합니다.

rng(0,'twister');
nAssets = 1000; % desired number of assets

임의의 데이터 만들기

-0.1 ~ 0.4에서 수익의 평균을 생성합니다.

a = -0.1; b = 0.4;
mean_return = a + (b-a).*rand(nAssets,1);
r = 0.15;                                     % desired return

0.08 ~ 0.6에서 수익의 표준편차를 생성합니다.

a = 0.08; b = 0.6;
stdDev_return = a + (b-a).*rand(nAssets,1);

Correlation = gallery('randcorr',nAssets)를 사용하여 생성된 상관 행렬을 불러옵니다. (이 크기의 상관 행렬을 생성하려면 시간이 걸리므로 미리 생성된 행렬을 대신 불러옵니다.)

load('correlationMatrixDemo.mat','Correlation');

상관 행렬에서 공분산 행렬을 계산합니다.

Covariance = Correlation .* (stdDev_return * stdDev_return');

최적화 문제, 목적 함수, 제약 조건 만들기

최소화를 위한 최적화 문제를 만듭니다.

portprob2 = optimproblem;

nAssets개 요소가 있는 최적화 벡터 변수 'x'를 만듭니다.

x = optimvar('x',nAssets,'LowerBound',0,'UpperBound',1);

목적 함수를 문제에 포함시킵니다.

objective = 1/2*x'*Covariance*x;
portprob2.Objective = objective;

변수의 합이 1이 되고 평균 수익률이 r보다 크다는 제약 조건을 포함시킵니다.

sumcons = sum(x) == 1;
portprob2.Constraints.sumcons = sumcons;
averagereturn = dot(mean_return,x) >= r;
portprob2.Constraints.averagereturn = averagereturn;

1,000-자산 문제 풀기

솔버를 호출하고 실제 경과 시간을 측정합니다.

tic
x3 = solve(portprob2,'Options',options);
toc
 Iter            Fval  Primal Infeas    Dual Infeas  Complementarity  
    0    2.142849e+01   5.490000e+02   3.031839e+00     5.210929e-03  
    1    9.378552e-03   6.439102e+00   3.555978e-02     6.331676e-04  
    2    1.128129e-04   3.705915e-03   2.046582e-05     1.802721e-05  
    3    1.118804e-04   1.852958e-06   1.023291e-08     1.170562e-07  
    4    8.490176e-05   7.650016e-08   4.224702e-10     7.048637e-09  
    5    3.364597e-05   4.440892e-16   3.062871e-18     1.037370e-09  
    6    1.980189e-05   2.220446e-16   8.876905e-19     8.465558e-11  

Minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the value of the optimality tolerance,
and constraints are satisfied to within the value of the constraint tolerance.

Elapsed time is 0.913357 seconds.

요약

이 예제에서는 포트폴리오 최적화 문제에 대해 문제 기반 접근법을 사용하는 방법을 설명하고 다양한 크기의 2차 문제에서의 알고리즘 실행 시간을 보여줍니다.

Financial Toolbox™에서 포트폴리오 최적화를 위해 특별히 설계된 기능을 사용하면 더욱 정교한 분석이 가능합니다.

관련 항목