PROGRAM Portfolios IMPLICIT NONE INTEGER, PARAMETER :: NMAT=10 REAL*8 :: MAT(NMAT,NMAT),XVEC(NMAT),BVEC(NMAT), Risk = 0.0, Returns(NMAT) REAL*8 :: KRISK, X, Returnss = 0.0, Dummy = 0.0 INTEGER :: I, Now(8), J, L1, L2, ErrorStat, StockNum(NMAT), Count = 1, Used(NMAT) = 0 CHARACTER*4, DIMENSION(NMAT) :: StockName OPEN (UNIT = 10, FILE = "Portfolios.txt", STATUS = "UNKNOWN") OPEN (UNIT = 20, FILE = "Weights.txt", STATUS = "UNKNOWN") OPEN (UNIT = 30, FILE = "Qin.txt", STATUS = "OLD") OPEN (UNIT = 40, FILE = "RetIn.txt", STATUS = "OLD") !OPEN (UNIT = 45, FILE = "StockNames.txt", STATUS = "OLD") StockName(1) = "AAPL" StockName(2) = "B " StockName(3) = "MSFT" StockName(4) = "EBAT" StockName(5) = "CAT " StockName(6) = "LMT " StockName(7) = "QSII" StockName(8) = "DIS " StockName(9) = "TWX " StockName(10) = "XOM " DO I = 1, NMAT DO J = 1, NMAT READ(30, '(1X, ES12.5)', ADVANCE = 'NO', IOSTAT = ErrorStat) Dummy IF (ErrorStat /= 0) THEN PRINT *, "*** ERROR IN READING INPUT ***" ! PRINT *, I, J STOP END IF MAT(I,J) = Dummy Dummy = 0.0 !PRINT *, I, J, MAT(I,J) END DO READ(30, '(T1)', ADVANCE = 'YES') END DO DO I = 1, NMAT READ(40,'(1X, ES12.5)', ADVANCE = 'YES', IOSTAT = ErrorStat) Dummy IF (ErrorStat /= 0) THEN PRINT *, "*** ERROR IN READING INPUT ***" ! PRINT *, I STOP END IF ! PRINT *, Dummy BVec(I) = Dummy Dummy = 0.0 END DO ! covariance matrix for the 10 stocks ! MAT(1,1)=1.217E-03 ! MAT(1,2)=6.779E-05 ! MAT(1,3)=7.264E-05 ! MAT(2,1)=6.779E-05 ! MAT(2,2)=2.971E-04 ! MAT(2,3)=8.169E-05 ! MAT(3,1)=7.264E-05 ! MAT(3,2)=8.169E-05 ! MAT(3,3)=3.866E-04 ! risk vector ! BVEC(1) = 1.01601E-03 ! BVEC(2) = 6.77637E-04 ! BVEC(3) = -2.70803E-04 ! BVEC(4) = 2.40569E-04 ! BVEC(5) = 4.79332E-04 ! BVEC(6) = 9.77431E-04 ! BVEC(7) = 1.35795E-03 ! BVEC(8) = 2.64866E-04 ! BVEC(9) = -4.55110E-04 ! BVEC(10) = 2.95342E-04 CALL date_and_time(values=now) CALL random_seed(put=now(5:8)) DO J = 1, 10000 CALL GetStock(StockNum(1)) CALL random_number(X) XVec(StockNum(1)) = X ! PRINT *, "1" ! PRINT *, XVec(StockNum(1)) CALL GetStock(StockNum(2)) DO CALl Random_Number(X) IF (X < (1.0 - XVec(StockNum(1)))) THEN XVec(StockNum(2)) = X EXIT ELSE CYCLE END IF END DO ! PRINT *, "2" CALL GetStock(StockNum(3)) DO CALl Random_Number(X) IF (X < (1.0 - XVec(StockNum(1)) - XVec(StockNum(2)))) THEN XVec(StockNum(3)) = X EXIT ELSE CYCLE END IF END DO ! PRINT *, "3" CALL GetStock(StockNum(4)) DO CALl Random_Number(X) IF (X < (1.0 - XVec(StockNum(1)) - XVec(StockNum(2)) - Xvec(StockNum(3)))) THEN XVec(StockNum(4)) = X Exit ELSE CYCLE ! PRINT *, X, ",", 1.0 - XVec(StockNum(1))- XVec(StockNum(2)) - Xvec(StockNum(3)) END IF END DO ! PRINT *, "4" CALL GetStock(StockNum(5)) DO CALl Random_Number(X) IF (X < (1.0 - XVec(StockNum(1)) - XVec(StockNum(2)) - XVec(StockNum(3)) - XVec(StockNum(4)))) THEN XVec(StockNum(5)) = X Exit ELSE CYCLE ! PRINT *, X, ",", 1.0 - XVec(StockNum(1))- XVec(StockNum(2)) - Xvec(StockNum(3)) - Xvec(StockNum(4)) END IF END DO ! PRINT *, "5" CALL GetStock(StockNum(6)) DO CALl Random_Number(X) IF (X < (1.0 - XVec(StockNum(1)) - XVec(StockNum(2)) - Xvec(StockNum(3)) - Xvec(StockNum(4))- XVec(StockNum(5)))) THEN XVec(StockNum(6)) = X Exit ELSE ! PRINT *, X, ",", 1.0-XVec(StockNum(1))-XVec(StockNum(2))-Xvec(StockNum(3))-Xvec(StockNum(4))- XVec(StockNum(5)) CYCLE END IF END DO ! PRINT *, "6" CALL GetStock(StockNum(7)) DO CALl Random_Number(X) IF (X < (1.0 - XVec(StockNum(1))- XVec(StockNum(2)) - Xvec(StockNum(3)) - Xvec(StockNum(4))- XVec(StockNum(5))& &- XVec(StockNum(6)))) THEN XVec(StockNum(7)) = X Exit ELSE CYCLE END IF END DO ! PRINT *, "7" CALL GetStock(StockNum(8)) DO CALl Random_Number(X) IF (X < (1.0 - XVec(StockNum(1))- XVec(StockNum(2)) - Xvec(StockNum(3)) - Xvec(StockNum(4))- XVec(StockNum(5))& &- XVec(StockNum(6)) - XVec(StockNum(7)))) THEN XVec(StockNum(8)) = X Exit ELSE CYCLE END IF END DO ! PRINT *, "8" CALL GetStock(StockNum(9)) DO CALl Random_Number(X) IF (X < (1.0 - XVec(StockNum(1))- XVec(StockNum(2)) - Xvec(StockNum(3)) - Xvec(StockNum(4))- XVec(StockNum(5))& &- XVec(StockNum(6)) - XVec(StockNum(7)) - XVec(StockNum(8)))) THEN XVec(StockNum(9)) = X Exit ELSE CYCLE END IF END DO ! PRINT *, "9" CALL GetStock(StockNum(10)) XVec(StockNum(10)) = 1.0 - XVec(StockNum(1)) - XVec(StockNum(2)) - XVec(StockNum(3)) - XVec(StockNum(4)) - XVec(StockNum(5))& &- XVec(StockNum(6)) - XVec(StockNum(7)) - XVec(StockNum(8)) - XVec(StockNum(9)) ! PRINT *, "10" DO I = 1, NMAT Returns(I) = XVec(I) * BVec(I) Returnss = Returnss + Returns(I) END DO DO L1=1,NMAT DO L2=1,NMAT Risk = Risk + MAT(L1,L2) * XVEC(L1) * XVEC(L2) END DO ! PRINT *, L1, Risk END DO ! PRINT *, Risk, SQRT(ABS(Risk)) ! Risk = MAT(1,1) * BVEC(1) ** 2 + BVEC(1) * ((MAT(1,2) + MAT(2,1)) * BVEC(2) + (MAT(1,3) + MAT(3,1)) * BVEC(3))& ! &+ MAT(2,2) * BVEC(2) ** 2 + (MAT(2,3) + MAT(3,2)) * BVEC(2) * BVEC(3) + MAT(3,3) * BVEC(3) ** 2 WRITE(10, *) J, Returnss, SQRT(ABS(Risk)) WRITE(20,*) J, XVec(1), XVec(2), XVec(3), XVec(4), XVec(5), XVec(6), Xvec(7), XVec(8), XVec(9), XVec(10), SQRT(ABS(Risk)) IF (MOD(J,500) == 0) PRINT *, J ! PRINT *, "J: ", J CALL Reset() END DO !------------------------------------------------------------------------------------------------------------------ CONTAINS !------------------------------------------------------------------------------------------------------------------ SUBROUTINE Reset INTEGER :: L DO L = 1, NMAT XVec(L) = 0.0 Returns(L) = 0.0 Used = 0 END DO Returnss = 0.0 Risk = 0.0 Count = 0 END SUBROUTINE !------------------------------------------------------------------------------------------------------------------ SUBROUTINE GetStock(Stock) INTEGER :: NX = 0, Stock REAL*8 :: X = 0.0d0 DO CALL Random_Number(X) X = X * 10.0d0 ! PRINT *, X, NINT(X) NX = NINT(X) IF(NX == 0) THEN CYCLE END IF IF (Used(NX) == 0) THEN Used(NX) = 1 Stock = NX Count = Count + 1 ! PRINT *, NX, Count ! PRINT *, X, NX IF (Count == 10) THEN WRITE(45, '(1X, A)', ADVANCE = 'YES') TRIM(StockName(NX)) EXIT ELSE WRITE(45, '(1X, A, ",")', ADVANCE = 'NO') TRIM(StockName(NX)) EXIT END IF ELSE CYCLE END IF END DO END SUBROUTINE END PROGRAM