PROGRAM BackProp ! Copyright 2007 Matthew Norton ! ! This program is free software; you can redistribute it and/or modify ! it under the terms of the GNU General Public License as published by ! the Free Software Foundation; either version 2 of the License, or ! (at your option) any later version. ! ! This program is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! GNU General Public License for more details. ! ! You should have received a copy of the GNU General Public License ! along with this program; if not, write to the Free Software ! Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ! ! NOTE: This is in FORTRAN 90 and you will need a FORTRAN 90 complier to run this code !--------------------------------------------------------------------------- ! This program uses backpropagation to train an artificial neural network ! to predict future values of the Dow Jones Industrial Average. ! ! Programmed by: ! Matthew Norton ! !---------------------------------------------------------------------------- IMPLICIT NONE INTEGER :: I, J, M = 501, N = 0, Count = 0, X, K, ECount = 1, B, Num = 0 REAL*8 :: Alpha, G, FPrimeGk, Error = 0.0 REAL*8, DIMENSION(:), ALLOCATABLE :: DJIA REAL*8, DIMENSION(10) :: Zj = 0.0, Hj = 0.0 REAL*8 :: EpsilonK = 0.0, Gk = 0.0, Yk = 0.0, RError REAL*8, DIMENSION(0:10,6) :: Weights, DWeights REAL*8, DIMENSION(0:6) :: VWeights, DVWeights, DeltaJ REAL*8, DIMENSION(6) :: FPRimeZj REAL*8, DIMENSION(10) :: Train = 0.0 CALL SetupDJIA() CALL Setup() !DO J = 200, 210 DO X = 1, 10 N = X + M ! Increment counter for DJIA Train(X) = DJIA(N) ! Train(J,I) = DJIA(I+M) END DO ! END DO Epoch: DO DO J = 1, 6 Zj(J) = Weights(0,J) + (Weights(1,J) * Train(1)) +& &(Weights(2,J) * Train(2)) + (Weights(3,J) * Train(3)) +& &(Weights(4,J) * Train(4)) + (Weights(5,J) * Train(5)) +& &(Weights(6,J) * Train(6)) + (Weights(7,J) * Train(7)) +& &(Weights(8,J) * Train(8)) + (Weights(9,J) * Train(9)) +& &(Weights(10,J) * Train(10)) Hj(J) = (( 1.0 + DTANH(Zj(J))) / 2.0) END DO Gk = VWeights(0) DO J = 1, 6 Gk = Gk + (VWeights(J) * Hj(J)) END DO Yk = (( 1.0 + DTANH(Gk)) / 2.0) IF ((501 + Num) == 525) EXIT Epoch Num = Num + 1 CALL Shift() !ECount = Ecount + 1 ! IF (RError > 0.05) THEN ! CALL Reset ! CYCLE Epoch ! END IF ! EXIT Epoch END DO Epoch 200 FORMAT(1X, I5, 4(1X, F15.13)) 300 FORMAT(1X, F15.13) ! ------------------------------------------------------------------------------ CONTAINS ! ------------------------------------------------------------------------------ SUBROUTINE SetupDJIA INTEGER :: I = 1, ErrorStat REAL :: Dummy ! Dummy variable used for reading in array OPEN(UNIT = 10, FILE = "DJI.txt", STATUS = "OLD", IOSTAT = ErrorStat) !input file IF (ErrorStat /= 0) STOP "*** ERROR IN OPENING DJI.txt ***" ! If error, stop FindSize: DO ! Find file length READ (10,200) Dummy ! read in line READ (10,200, IOSTAT = ErrorStat, ADVANCE = "NO") Dummy ! see if next line is there IF (ErrorStat /= 0) THEN ! If end of file, exit loop EXIT FindSize END IF Count = Count + 1 ! Increment count END DO FindSize REWIND(10) ! go back to begining of file ALLOCATE(DJIA(Count)) ! Allocate space for DJIA array DO I = 1, Count ! Do from I to end of file READ(10,200) DJIA(I) ! read in values for DJIA from file END DO 200 FORMAT(T2, F8.7) END SUBROUTINE SUBROUTINE Setup REAL*8 :: Dummy INTEGER :: Sign = 1, I, J, ErrorStat = 0 OPEN(UNIT = 20, File = "BackOut.txt", Status = "UNKNOWN") OPEN(UNIT = 30, File = "Weights.txt", Status = "OLD") OPEN(UNIT = 40, FILE = "VWeights.txt", STATUS = "OLD") OPEN(UNIT = 50, FILE = "Dweights.txt", STATUS = "UNKNOWN") OPEN(UNIT = 60, FILE = "DVWeights.txt", STATUS = "UNKNOWN") Alpha = 0.05 DO I = 0, 10 DO J = 1, 6 READ(30, 300, ADVANCE = "NO", IOSTAT = ErrorStat) Dummy IF (ErrorStat /= 0) STOP "*** ERROR IN READING INPUT ***" Weights(I,J) = Dummy Dummy = 0.0 END DO END DO DO J = 0, 6 READ(40,300, ADVANCE = "NO", IOSTAT = ErrorStat) Dummy IF (ErrorStat /= 0) STOP "*** ERROR IN READING INPUT ***" VWeights(J) = Dummy Dummy = 0.0 END DO 300 FORMAT(1X, F15.12) END SUBROUTINE ! ------------------------------------------------------------------------------ SUBROUTINE Shift INTEGER :: N, I DO I = 1, 9 Train(I) = Train(I + 1) END DO Train(10) = Yk CALL Compare(Yk) END SUBROUTINE ! ------------------------------------------------------------------------------ SUBROUTINE Reset ECount = 1 Error = 0.0 Zj = 0.0 Hj = 0.0 EpsilonK = 0.0 Gk = 0.0 Yk = 0.0 END SUBROUTINE ! ------------------------------------------------------------------------------ SUBROUTINE Compare(Predict) REAL*8, INTENT(IN) :: Predict REAL*8 :: RError INTEGER :: N = 220 OPEN(UNIT = 99, FILE = "Predict.txt") RError = ABS(Predict - DJIA(N + Num)) / DJIA(N + Num) PRINT *, N+Num, Predict, DJIA(N + NUM), RError WRITE(99,*) N+Num, Predict, DJIA(N + NUM), RError END SUBROUTINE ! ------------------------------------------------------------------------------ END PROGRAM