! Do parametric analysis of Portfolio variance vs. expected return
  for a Markowitz portfolio model in LINGO (PortEfFrontxx.lng).
! Different cases can be run by turning on or off statements
  of the form: !CaseXX;
! Keywords: Parametric Analysis, Markowitz, Graph, Chart, Chartcurve
    Pareto analysis, Efficient frontier, Portfolio;
SETS:
       ASSET: STD, X, STDPP, EXPNS, TAXR, ERET;
       TMAT( ASSET, ASSET) | &1 #GE# &2: CORR;
       GRID: VINP, VOUT;
      ENDSETS
DATA: ! Case based on Vanguard Fund data; ! The initial wealth; !CaseVG WEALTH = 1; ! The investments available(Vanguard funds), and their expected return per year, i.e., expected value next year is (1 + ERET(i)); !CaseVG ASSET = CD___ VG040 VG102 VG058 VG079 VG072 VG533; !CaseVG ERET = .04 .06 .06 .05 .065 .07 .08 ; ! S.D. per period (monthly here) in return for each asset, June 2004 to Dec 2005; !CaseVG STDPP= 0 .02341 .02630 .01067 .02916 .03615 .05002; ! Correlation matrix, based on June 2004 to Dec 2005; !CaseVG CORR = 1 0 1 0 .98209 1 0 -.24279 -.31701 1 0 .75201 .76143 -.34311 1 0 .49386 .49534 -.24055 .68488 1 0 .77011 .76554 -.18415 .84397 .69629 1; ! Number different returns to check; !CaseVG NPERYR = 12; !CaseVG NPOINTS = 17; !CaseVG GRID = 1..NPOINTS; ! Case based on data from Harry Markowitz; ! The initial wealth; !CaseHM WEALTH = 1; ! The investments available, and their expected return per year, i.e., expected value next year is (1 + ERET(i)); !CaseHM ASSET = ATT GMC USX; !CaseHM ERET = 1.0890833 1.213667 1.234583; ! S.D. per period (yearly here) in return for each asset, 1943 to 1954; !CaseHM STDPP= 0.103959 0.241644 0.306964; ! Correlation matrix, based on 1943 to 1954; !CaseHM CORR = 1 0.493895589 1 0.409727718 0.747229121 1 ; !CaseHM NPERYR = 1; ! Number different returns to check; !CaseHM NPOINTS = 17; !CaseHM GRID = 1..NPOINTS; ! Case HM + T bills; ! The initial wealth; !CaseTbill WEALTH = 1; ! The investments available, and their expected return per year, i.e., expected value next year is (1 + ERET(i)); !CaseTbill ASSET = ATT GMC USX TBILL; !CaseTbill ERET = 1.0890833 1.213667 1.234583 1.03; ! S.D. per period (yearly here) in return for each asset, 1943 to 1954; !CaseTbill STDPP= 0.103959 0.241644 0.306964 0; ! Correlation matrix, based on 1943 to 1954; !CaseTbill CORR = 1 0.493895589 1 0.409727718 0.747229121 1 0 0 0 1; !CaseTbill NPERYR = 1; ! Number different returns to check; !CaseTbill NPOINTS = 17; !CaseTbill GRID = 1..NPOINTS; ! Case on some stocks from 1975 to 2017; ! The initial wealth; !Case7517; WEALTH = 1 ! The investments available, and their expected return per year, i.e., expected value next year is (1 + ERET(i)); !!Case7517; ASSET = 3M CHEVRON COCACOLA DUPONT PANDG IBM WEYERHAUS FORD GE ALCOARNC EXXONMOBL DEERE BOEING MERCK CD; !Case7517; ERET = 0.104840 0.110333 0.129940 0.089581 0.099156 0.097740 0.062126 0.148514 0.111147 0.113428 0.102323 0.138958 0.221723 0.117267 0.04; ! S.D. per period (yearly here) in return for each asset; !Case7517; STDPP= 0.179183 0.199911 0.227568 0.204611 0.166706 0.271494 0.216099 0.630138 0.252424 0.331500 0.160082 0.314638 0.388914 0.278148 0; ! Correlation matrix; !Case7517; CORR = 1.000000 0.224103 1.000000 0.471504 0.188059 1.000000 0.569111 0.369613 0.540056 1.000000 0.383458 0.159070 0.605610 0.451472 1.000000 0.177980 0.195755 0.185002 0.218867 0.299420 1.000000 0.536024 0.307412 0.288499 0.492221 0.304817 0.202478 1.000000 0.436319 -0.029829 0.298691 0.421983 0.163719 0.427427 0.495507 1.000000 0.375731 0.335635 0.508517 0.504409 0.558811 0.425427 0.526197 0.282949 1.000000 0.589535 0.288138 0.150212 0.521401 0.316703 0.283604 0.613098 0.340376 0.406583 1.000000 0.137225 0.693282 0.326282 0.335877 0.188402 0.208952 0.264360 -0.098702 0.487905 0.169956 1.000000 0.397611 0.469478 0.204834 0.435663 0.176196 0.117376 0.402432 0.258821 0.188560 0.502105 0.293903 1.000000 0.526127 0.353309 0.320309 0.351982 0.080585 0.107582 0.145074 0.106664 0.192651 0.267838 0.269439 0.354856 1.000000 0.326960 0.195902 0.648996 0.385934 0.279656 0.048635 0.185938 0.084664 0.359242 0.104470 0.461664 0.166394 0.181214 1.000000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1; !Case7517; NPERYR = 1! Number different returns to check; !Case7517; NPOINTS = 17!Case7517; GRID = 1..NPOINTS ENDDATA !--------------------------------------------------------------; SUBMODEL HARRY: ! Min the var in yearly portfolio return; [OBJ] MIN = (@SUM( ASSET( I): STD( I)*STD(I) * X( I)^2) + 2 * @SUM( TMAT( I, J) | I #NE# J: X( I) * X( J)* CORR( I, J) *( STD( I) * STD( J)))) ; ! Budget constraint; [BUDGET] @SUM( ASSET(i): X(i)) = WEALTH; ! Return requirement; [RETURN] @SUM( ASSET(i): ERET(i) * X(i)) >= TARGET * WEALTH; ENDSUBMODEL
CALC: ! Set various performance parameters; @SET( 'TERSEO',2); ! Output level (0:verb, 1:terse, 2:only errors, 3:none); @SET( 'IPTOLR', .02); ! Set ending relative optimality tolerance; @SET( 'TIM2RL', 10); ! Time in seconds to apply optimality tolerance; @SET( 'DUALCO', 1); ! Set dual computations (0:off, 1:On); @SET( 'OROUTE',1); ! Route output immediately to the window line by line; @SET( 'GLOBAL',0); ! 0:Do not use Global solver, 1:Use the Globasolver; @SET( 'TATSLV', 150); ! Solver time limit in seconds (0:no limit) for @SOLVE's; @SET( 'TIMLIM', 5); ! Solver time limit in seconds (0:no limit) for entire session; @SET( 'LINLEN', 85); ! Terminal page width (0:none); @SET( 'USEQPR', 1); ! Use quadratic recognition (1:y, 0:n); ! Compute effective variances and returns; @FOR( ASSET(I): ! Assume variances add over time to compute yearly std. dev.; STD(I) = STDPP(I)*(NPERYR^.5); ); ! Find min and max return; RET_MIN = @MIN( ASSET(I): ERET(I)); RET_MAX = @MAX( ASSET(I): ERET(I)); ! Prepare heading for little report; @WRITE(@NEWLINE(1),' Efficient Frontier Portfolio Calculation',@NEWLINE(1)); @WRITE(' Target Risk(1 sd) Portfolio composition',@NEWLINE(1)); @WRITE(' Return 1-Yr '); @FOR( ASSET(I): @WRITE(@FORMAT(ASSET(i),'10s')); ); @WRITE( @NEWLINE(1)); N1 = NPOINTS-1; K = 0; ! Loop over different target returns, i.e., we change the value of TARGET in each pass through the loop; ! Use integer count to avoid accumulating roundoff; @WHILE( K #LT# NPOINTS: TARGET = RET_MAX*(K/N1) + RET_MIN*((N1-K)/N1); @SOLVE( HARRY); RISK = OBJ; SDP = RISK^0.5; ! Standard deviation of portfolio return; @WRITE( ' ',@FORMAT( TARGET, '#6.5f'),' '); @WRITE( @FORMAT( SDP, '#7.4f'),' '); @FOR( ASSET(I): @IFC( X(i) #GT# .0001: @WRITE( @FORMAT( X(i), '10.4f')); @ELSE @WRITE(' '); ) ); @WRITE( @NEWLINE(1)); K = K + 1; ! Store the input and output variables for graphing; VINP( K) = TARGET; VOUT( K) = SDP; ); ! While end; @WRITE( @NEWLINE(1),' Input Data Used:', @NEWLINE(1)); @WRITE('Expected ret/yr:'); @FOR( ASSET(I): @WRITE( @FORMAT( ERET(i), '10.4f')); ); @WRITE( @NEWLINE(1)); @WRITE('Stdev in ret/yr:'); @FOR( ASSET(I): @WRITE( @FORMAT( STD(i), '10.4f')); ); ! Graph it; @CHARTCURVE( 'Risk vs Return', 'Desired Return', 'Resulting Risk (SD)', 'Standard Deviation', VINP, VOUT); ! Graph it as is done by Finance folks; @CHARTCURVE( 'Return vs Risk', 'Standard Deviation in Return', 'Expected Return', 'Standard Deviation', VOUT, VINP); ENDCALC