qmeanvag.gms : 병렬 솔루션을 사용한 포트폴리오 메가 슬롯링

설명

이 메가 슬롯은 순차 QMEANVAR의 병렬 구현입니다.
메가 슬롯. 최소 및 최대 무역 제한 사항이 표준에 추가되었습니다.
평균-분산 메가 슬롯. 이 범위 내에서 거래하는 것이 수익성이 없는 경우
범위에서는 거래가 이루어져서는 안됩니다. 회전율 제약이 추가됩니다.
데이터의 작은 변화에 대한 솔루션의 안정성을 향상시킵니다. 는
결과 메가 슬롯은 이제 MIQCP로 표현되며 프론티어는 다음과 같습니다.
계산되었습니다.

Dahl, H, Meeraus, A 및 Zenios, S A, 일부 재무 최적화
메가 슬롯: 위험 관리. Zenios, S A, Ed, 재무 최적화.
캠브리지 대학 출판부, 뉴욕, 뉴욕, 1993.

소형 메가 슬롯 유형 :MIQCP


카테고리 : 메가 슬롯 모델 라이브러리


메인 파일 : qmeanvag.gms

$title 병렬 솔루션을 사용한 포트폴리오 모델링(QMEANVAG,SEQ=327)

$onText
이 모델은 순차 QMEANVAR의 병렬 구현입니다.
모델. 최소 및 최대 무역 제한 사항이 표준에 추가되었습니다.
평균-분산 모델. 이 범위 내에서 거래하는 것이 수익성이 없는 경우
범위에서는 거래가 이루어져서는 안됩니다. 회전율 제약이 추가됩니다.
데이터의 작은 변화에 대한 솔루션의 안정성을 향상시킵니다. 는
결과 모델은 이제 MIQCP로 표현되며 프론티어는 다음과 같습니다.
계산되었습니다.

Dahl, H, Meeraus, A 및 Zenios, S A, 일부 재무 최적화
모델: 위험 관리. Zenios, S A, Ed, 재무 최적화.
캠브리지 대학 출판부, 뉴욕, 뉴욕, 1993.

두 개의 이중 대시 옵션을 사용하여 편리하게 숫자를 변경할 수 있습니다.
포인트를 설정하고 시간 제한을 설정하세요.

키워드: 혼합 정수 2차 제약 조건 프로그래밍, 포트폴리오 최적화,
          금융, 리스크 관리
$offText

$eolCom //
$ifE %system.gamsversion%<231 $abort 버전이 너무 오래되었습니다! 231 이상이 필요합니다.

$setDDList 포인트 ETIME_LIMIT
$설정 포인트가 아닌 경우 $설정 포인트 4
$ifThen ETIME_LIMIT가 설정되지 않았습니다.
* jobTrace는 slvtest가 이 모델을 호출하는 지표로 사용됩니다.
$ "%메가 슬롯jobTrace%"가 아닌 경우 $set ETIME_LIMIT 120
$ if "%메가 슬롯jobTrace%" $set ETIME_LIMIT 9e9
$endIf
$if errorfree $abort 잘못된 이중 대시 매개변수: --points=n --ETIME_LIMIT=secs

스칼라 etimeLim / %ETIME_LIMIT% /;

i '증권' 설정 / cn, fr, gr, jp, sw, uk, us /;

별칭(i,j);

매개변수 mu(i) '예상되는 증권 반환'
                / cn 0.1287, fr 0.1096, gr 0.0501, jp 0.1524, sw 0.0763, uk 0.1854, us 0.0620 /;

테이블 q(i,j) '공분산 행렬'
           cn fr gr jp sw 영국 우리
   CN 42.18
   fr 20.18 70.89
   gr 10.88 21.58 25.51
   일본 5.30 15.41 9.60 22.33
   남 12.32 23.24 22.63 10.32 30.01
   영국 23.84 23.80 13.22 10.46 16.36 42.23
   미국 17.41 12.62 4.70 1.00 7.20 9.90 16.42;

* 우리는 계속해서 q-행렬의 아래쪽 삼각형만 사용할 것입니다.
* 올바른 결과를 얻으려면 대각선 항목을 조정하십시오.

q(i,j) = 2*q(j,i);
q(i,i) = q(i,i)/2;

스칼라 타우 '현재 보유 자산 회전율에 대한 경계 매개변수' / 0.3 /;

pd '포트폴리오 데이터 라벨' 설정
       / 이전 '포트폴리오의 현재 보유 비율'
         umin '증권 보유분의 최소 증가 i'
         umax '증권 i의 보유 지분 최대 증가'
         lmin '증권 i의 보유 지분의 최소 감소'
         lmax '증권 i의 보유 지분 최대 감소' /;

테이블 bdata(i,pd) '포트폴리오 데이터 및 거래 제한'
* - 증가 - - 감소 -
        오래된 umin umax lmin lmax
   CN 0.2 0.03 0.11 0.02 0.30
   프르 0.2 0.04 0.10 0.02 0.15
   gr 0.0 0.04 0.07 0.04 0.10
   일본 0.0 0.03 0.11 0.04 0.10
   남서 0.2 0.03 0.20 0.04 0.10
   영국 0.2 0.03 0.10 0.04 0.15
   미국 0.2 0.03 0.10 0.04 0.30;

bdata(i,'lmax') = min(bdata(i,'old'),bdata(i,'lmax')); // 경계를 강화하다

abort$(abs(sum(i, bdata(i,'old')) - 1) >= 1e5) 'bdata에 오류가 있습니다', bdata;

변수
   var '포트폴리오의 변화'
   '포트폴리오 반환'을 ret
   x(i) 'i의 현재 보유 포트폴리오 중 일부'
   xi(i) '포트폴리오 증가 비율'
   xd(i) '포트폴리오 감소 비율'
   y(i) 'i의 전류 보유량을 증가시키기 위한 이진 스위치'
   z(i) 'i의 전류 유지를 감소시키기 위한 이진 스위치';

이진변수 y, z;
양수 변수 x, xi, xd;

방정식
   예산 '예산 제약'
   회전율 '포트폴리오의 최대 회전율 제한'
   maxinc(i) 'i 부분의 최대 로트 증가 한계'
   minnc(i) 'i 부분의 최소 로트 증가 한계'
   maxdec(i) 'i 부분의 최대 로트 감소 한계'
   Mindec(i) 'i 부분의 최소 로트 감소 한계'
   binsum(i) '이진 변수 사용을 제한합니다'
   xdef(i) '최종 포트폴리오 정의'
   retdef '반환 정의'
   vardef '분산 정의';

예산.. sum(i, x(i)) =e= 1;

xdef(i).. x(i) =e= bdata(i,'old') - xd(i) + xi(i);

maxinc(i)..xi(i) =l= bdata(i,'umax')*y(i);

mininc(i)..xi(i) =g= bdata(i,'umin')*y(i);

maxdec(i).. xd(i) =l= bdata(i,'lmax')*z(i);

mindec(i).. xd(i) =g= bdata(i,'lmin')*z(i);

binsum(i)..y(i) + z(i) =l= 1;

매출액.. sum(i, xi(i)) =l= tau;

retdef..ret =e= sum(i, mu(i)*x(i));

vardef.. var =e= sum((i,j), x(i)*q(i,j)*x(j));

모델
   maxret / 예산, xdef, 매출액, maxinc, minnc, maxdec, mindec, binsum, retdef /
   minvar / 예산, xdef, 매출액, maxinc, minnc, maxdec, mindec, binsum, retdef, vardef /;

세트
   p '효율적인 프런티어 포인트' / minvar, p1*p%points%, maxret /
   pp(p) '효율적인 경계점' / p1*p%points% /;

스칼라
   rmin '최소 분산'
   rmax '최대 분산';

매개변수
   Report(p,i,*) '다른 지점의 포트폴리오 세부정보'
   xres(*,p) '다른 지점의 요약 보고서';

옵션 limCol = 0, limRow = 0, solPrint = off, optCr = 0,solveLink = %solveLink.callModule%, reslim = %ETIME_LIMIT%;

loop(p('maxret'),
   mip를 사용하여 maxret max ret을 해결합니다.
   rmax = ret.l;
   xres(i,p) = x.l(i);
   보고서(p,i,'inc') = xi.l(i);
   보고서(p,i,'dec') = xd.l(i);
);

루프(p('minvar'),
   miqcp를 사용하여 minvar min var를 해결합니다.
   rmin = ret.l;
   xres(i,p) = x.l(i);
   보고서(p,i,'inc') = xi.l(i);
   보고서(p,i,'dec') = xd.l(i);
);

매개변수 h(p) '해 처리';

minvar.solPrint = %solPrint.quiet%;
minvar.solveLink = %solveLink.asyncGrid%;

abort.noError$(timeelapsed > etimeLim - 5) "초기 해결에 너무 많은 시간이 소요됨";
minvar.resLim = etimeLim - 경과 시간 - 4;

루프(pp,
   ret.fx = rmin + (rmax - rmin)/(카드(pp) + 1)*ord(pp);
   miqcp를 사용하여 minvar min var를 해결합니다.
   h(pp) = minvar.handle;
);

반복하다
   루프(pp$handlecollect(h(pp))),
      if(minvar.solveStat = %solveStat.normalCompletion%,
         xres(i,pp) = x.l(i);
         보고서(pp,i,'inc') = xi.l(i);
         보고서(pp,i,'dec') = xd.l(i);
      );
      display$handledelete(h(pp)) '핸들 삭제 문제';
      h(pp) = 0;
   );
   display$sleep(card(h)*0.1) '잠깐만 자세요';
카드(h) = 0 또는 timeelapsed > etimeLim까지;
abort.noError$[card(h)>0] '수집 루프가 너무 느림', etimeLim, h;

xres(i,pp)$h(pp) = na;

xres('평균',p) = sum(i, mu(i)*xres(i,p));
xres('var' ,p) = sum((i,j), xres(i,p)*q(i,j)*xres(j,p));

디스플레이$(카드(p) < 10) xres, 보고서;

* IDE 차트 작성을 위한 gdx 데이터 준비
Execute_unload "qmeanvarg.gdx";