Created
March 18, 2020 14:32
-
-
Save Beliavsky/c81919cae66bbe77d1c32360a7a992a3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
! RESULTS: | |
! #paths initial ann_drift ann_vol min max <terminal> terminal terminal-max sd(terminal) %bottom | |
! 100000 100.00 0.15 0.40 77.99 145.60 116.18 115.95 -29.65 48.21 4.52 | |
! 100000 100.00 0.15 0.40 77.97 145.67 116.18 116.04 -29.63 48.30 4.39 | |
! 100000 100.00 0.15 0.40 77.92 145.58 116.18 115.88 -29.70 48.25 4.33 | |
! 100000 100.00 0.15 0.40 78.02 145.96 116.18 116.27 -29.69 48.64 4.41 | |
! 100000 100.00 0.15 0.40 78.02 145.53 116.18 115.93 -29.60 47.89 4.37 | |
module statistics_mod | |
implicit none | |
public :: dp,mean,sd,random_normal | |
integer, parameter :: dp = kind(1.0d0) | |
contains | |
pure function mean(xx) result(xmean) | |
! compute the mean of xx(:) | |
real(kind=dp), intent(in) :: xx(:) | |
real(kind=dp) :: xmean | |
integer :: n | |
n = size(xx) | |
if (n > 0) then | |
xmean = sum(xx)/n | |
else | |
xmean = 0.0_dp | |
end if | |
end function mean | |
! | |
pure function sd(xx) result(xsd) | |
! compute the standard deviation of xx(:) | |
real(kind=dp), intent(in) :: xx(:) | |
real(kind=dp) :: xsd | |
real(kind=dp) :: xmean | |
integer :: n | |
n = size(xx) | |
if (n > 1) then | |
xmean = sum(xx)/n | |
xsd = sqrt(sum((xx-xmean)**2)/(n-1)) | |
else | |
xsd = -1.0 | |
end if | |
end function sd | |
! | |
function random_normal() result(fn_val) | |
! Generate a random normal deviate using the polar method. | |
! Reference: Marsaglia,G. & Bray,T.A. 'A convenient method for generating | |
! normal variables',Siam Rev.,vol.6,260-264,1964. | |
real(kind=dp) :: fn_val | |
! Local variables | |
real(kind=dp) :: u,sum | |
real(kind=dp),save :: v,sln | |
logical,save :: second = .false. | |
real(kind=dp),parameter :: one = 1.0d0,vsmall = tiny(one) | |
if (second) then | |
! If second,use the second random number generated on last call | |
second = .false. | |
fn_val = v*sln | |
else | |
! First call; generate a pair of random normals | |
second = .true. | |
do | |
call random_number(u) | |
call random_number(v) | |
u = scale(u,1) - one | |
v = scale(v,1) - one | |
sum = u*u + v*v + vsmall ! vsmall added to prevent log(zero) / zero | |
if(sum < one) exit | |
end do | |
sln = sqrt(- scale(log(sum),1) / sum) | |
fn_val = u*sln | |
end if | |
end function random_normal | |
end module statistics_mod | |
! | |
program xxreturns_drawdown | |
! 03/18/2020 10:16 AM branched from xreturns_drawdown.f90 to xxreturns_drawdown.f90 | |
! 03/18/2020 09:50 AM simulate the maximum cumulative loss given expected return and volatility | |
use statistics_mod , only: dp,mean,sd,random_normal | |
integer, parameter :: tdy = 252 ! trading days per year | |
integer, parameter :: nfwd = 252 | |
integer, parameter :: niter = 100000, nsim = 5 | |
real(kind=dp) :: ann_drift,ann_vol,daily_drift,daily_vol,x0,xx(0:nfwd),xmin(niter),xmax(niter),xlast(niter) | |
integer :: i,iter,isim | |
call random_seed() | |
ann_drift = 0.15_dp ! annualized simple daily return | |
ann_vol = 0.40_dp ! annualized daily volatility | |
daily_drift = ann_drift/tdy | |
daily_vol = ann_vol/sqrt(dble(tdy)) | |
x0 = 100.0_dp ! initial stock price | |
write (*,"(100a13)") "#paths","initial","ann_drift","ann_vol","min","max","<terminal>", & | |
"terminal","terminal-max","sd(terminal)","%bottom" | |
do_sim: do isim=1,nsim | |
do iter=1,niter | |
do i=0,nfwd | |
if (i > 0) then | |
xx(i) = xx(i-1)*(1 + daily_drift + daily_vol*random_normal()) | |
else | |
xx(i) = x0 | |
end if | |
end do | |
xmin(iter) = minval(xx) | |
xmax(iter) = maxval(xx) | |
xlast(iter) = xx(nfwd) | |
end do | |
write (*,"(i13,100f13.2)") niter,x0,ann_drift,ann_vol,mean(xmin),mean(xmax),x0*(1+daily_drift)**nfwd, & | |
mean(xlast),mean(xlast-xmax),sd(xlast),100.0_dp*count(xmin >= x0)/niter | |
end do do_sim | |
end program xxreturns_drawdown |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment