Stock Price Simulation in R
Stock Price Simulation in R
EA Valdez
Simulation results
page 1
Modeling stock prices In nance, we are always interested in the return on stocks. The Normal distribution is a typical distribution model for return on the stock; indeed equivalent to modeling the value of the stock as a lognormal distribution. Assume that the return on the stock is normally distributed with annual mean and annual standard deviation . Denote by St the value of the asset at time t and St +t denoting the the value t periods later. Thus, the percentage change (or return) of the value of the stock between times t and t + t is approximated by log St log St +t = log St St +t = log (1 + rt ) rt ,
Another way to write the stock price at time t + t is St +t = St exp t + Z t , where Z is standard normal N(0, 1). If you know diffusion processes, this is the discrete analogue of the geometric diffusion: dS = dt + dB , S where dB is a Brownian motion (or Weiner) process with dB = Z dt .
page 3
Illustrative example
Consider a stock paying no dividends with a volatility = 0.05 per annum and with an expected return of = 0.10 per annum with continuous compounding. The stock price process can be written as dS = 0.10dt + 0.20dB or (in the discrete sense) with S small interval of time S = 0.15t + 0.20Z t . S The gures in the following page demonstrate this price process (by simulation) for different time intervals: year (t = 1), month (t = 1/12), week (t = 1/52), and day (t = 1/365). Here we assume the initial stock price is 100.
page 4
R code to generate the stock price process The following is a routine in R to generate the stock price process. Function is called simstock.R.
# function to generate (discrete) stock price process simstock <- function(mu,sigma,dt,n.yr){ n.gen <- (1/dt)*n.yr S.vector <- rep(0,n.gen+1) S0 <- 100 S.vector[1] <- S0 for(i in 2:(n.gen+1)) { zrandom <- rnorm(1) ds <- S.vector[i-1]*(mu*dt + sigma*zrandom*sqrt(dt)) S.vector[i] <- S.vector[i-1] + ds } # output S.vector }
> st.mo <- simstock(0.1,0.2,1/12,20) > month <- 0:(12*20) > plot(st.mo~month,type="l",ylab="stock price") > st.wk <- simstock(0.1,0.2,1/52,20) > week <- 0:(52*20) > plot(st.wk~week,type="l",ylab="stock price") > st.dy <- simstock(0.1,0.2,1/365,20) > day <- 0:(365*20) > plot(st.dy~day,type="l",ylab="stock price")
Simulation results
page 5
700
600
400
500
stock price
stock price
300
400
R code to generate the stock price process Pictorial illustration Lognormal property
200
300
200
100
100
10 year
15
20
50
100 month
150
200
800
Simulation
stock price
stock price
300
400
600
200
200
100
200
400 week
600
800
1000
page 6
Lognormal property of stock prices In the geometric Brownian motion, the change in the log S between time 0 and T has a Normal distribution with
log ST log S0 N ( 2 /2)T , 2 T , where S0 is the initial stock price while ST is the stock price T periods later. This is equivalent to ST having a lognormal distribution: log ST N log S0 + ( 2 /2)T , 2 T . It is straightforward to show that the mean is given by E(ST ) = S0 eT , and the variance is
2 2T Var(ST ) = S0 e e
2
The lognormal distribution Illustrative example R code to generate the stock price process Pictorial illustration Lognormal property Illustration of generating distribution of stock price Distribution graph Generating distribution of a portfolio of assets
1 .
page 7
R code to illustrate simulating the stock price at time T The following is a routine in R to generate the stock price at time T . Function is called simstprice.R.
# function to generate stock price/value at time T simstprice <- function(n.gen,S0,mu,sigma,T){ zrandom <- rnorm(n.gen) l.mu <- log(S0) + (mu - 0.5*sigma^2)*T l.sigma <- sigma*sqrt(T) nrandom <- l.mu + l.sigma*zrandom S.vector <- exp(nrandom) # output S.vector }
page 8
Illustrative example R code to generate the stock price process Pictorial illustration
0.05
Lognormal property Illustration of generating distribution of stock price Distribution graph Generating distribution of a portfolio of assets
0.04
0.03
0.02
0.01
0.00
20
30
40
60
70
80
Simulation results
page 9
R code to illustrate simulating a portfolio of assets The following is a routine in R to generate the value of a portfolio of stocks at time T . Function is called simportfolio.R.
# # # # function to generate a portfolio of securities at time T the variables required: n.gen (number to simulate), S0.vector (vector of initial values of the stocks), mu.vector/sigma.vector (self-explanatory), n.holdings (the number of holdings for each corresponding stock), T (valuation date)
simportfolio <- function(n.gen,S0.vector,mu.vector,sigma.vector,n.holdings,T){ n.port <- length(S0.vector) S.matrix <- matrix(0,nrow=n.gen,ncol=n.port) for (i in 1:n.port){ zrandom <- rnorm(n.gen) l.mu <- log(S0.vector[i]) + (mu.vector[i] - 0.5*sigma.vector[i]^2)*T l.sigma <- sigma.vector[i]*sqrt(T) nrandom <- l.mu + l.sigma*zrandom S.matrix[,i] <- exp(nrandom) } # multiply with the holdings S.matrix <- t(n.holdings*t(S.matrix)) # output # this actually sums the rows with each column referring to one particular stock rowSums(S.matrix) }
page 10
R code to generate the stock price process Pictorial illustration Lognormal property Illustration of generating distribution of stock price Distribution graph Generating distribution of a portfolio of assets
portfolio value
50000
100000
150000
200000
250000
page 11
> source("C:\\...\\Math276-Spring2008\\Rcodes-2008\\Week67\\Data.SummStats.R") > Data.SummStats(out1) Value Number 1.000e+03 Mean 1.181e+05 5th Q 9.157e+04 25th Q 1.042e+05 Median 1.167e+05 75th Q 1.279e+05 95th Q 1.530e+05 Variance 3.533e+08 StdDev 1.880e+04 Minimum 7.529e+04 Maximum 2.382e+05 Skewness 9.300e-01 Kurtosis 2.080e+00 >
R code to generate the stock price process Pictorial illustration Lognormal property Illustration of generating distribution of stock price Distribution graph Generating distribution of a portfolio of assets
page 12
The distribution of the total claim amount In general (property/casualty) insurance, we often study the distribution of the aggregate claim amount dened by S = X1 + X2 + + XN , where Xi is the amount of the i -th claim and N refers to the number of claims. Here we are referring to the total claims only for a xed period, e.g. one year, though this can be a stochastic process (over time). The standard assumptions in the model are:
1
the claim amounts Xi are i.i.d. (independent and identically distributed) random variables; and the claim amounts X1 , X2 , . . . and the claim count N are all independent.
The aggregate sum S has what we call a compound distribution, and in many instances, it is not possible to derive explicit form of its distribution.
Simulation results
page 13
The lognormal distribution Illustrative example R code to generate the stock price process
, for x > 0.
Pictorial illustration Lognormal property Illustration of generating distribution of stock price Distribution graph
Note that to simulate from the Pareto, it can be shown that, using the inverse transform method, the following generates a Pareto(, ) random variable: X = (1 U )1/ 1 .
page 14
Case illustration
Consider a portfolio of 10,000 automobile insurance policies with the following assumptions:
The period is exactly one year where each policy pays an annual premium of = $500. Expenses include an overhead (or xed) expense of $500,000 and a per policy expense of $2.50. The aggregate claims distribution assume that claim size has a Pareto with = 625 and = 1.5 and claim count has a Poisson with = 900.
The Prot/Loss (P/L) for this insurance portfolio is clearly Premiums - (Claims + Expenses) where:
Premiums: 10, 000 = 10, 000(500) = 5, 000, 000 Claims: S = X1 + X2 + + XN Expenses: 500, 000 + 2.5 10, 000 = 525, 000
Simulation
page 15
R code to illustrate simulating the aggregate claims The following is a routine in R to generate the aggregate claim amount for a portfolio of auto insurance policies. Function is called simillustrate.R.
# function to simulate the aggregate claims using the illustration simillustrate <- function(n.gen,ptheta,palpha,nlambda){ n.claims <- rpois(n.gen,nlambda) S.vector <- rep(0,n.gen) for (i in 1:n.gen) { urandom <- runif(n.claims[i]) claims <- ptheta * ((1-urandom)^(-1/palpha)-1) S.vector[i] <- sum(claims) } # output S.vector }
page 16
1.0
2.5
0.8
2.0
frequency
frequency
1.5
0.6
Simulation
0.4
1.0
0.2
0.5
0.0
10
15 in millions
20
25
0.0
Simulation results
13
14
15 in logarithm
16
17
page 17
Prot/loss analysis
> pl <- 5000000 - (out1 + 525000) > Data.SummStats(pl) Value Number 1.000e+04 Mean 3.345e+06 5th Q 2.943e+06 25th Q 3.302e+06 Median 3.427e+06 75th Q 3.518e+06 95th Q 3.620e+06 Variance 3.618e+11 StdDev 6.015e+05 Minimum -2.040e+07 Maximum 3.804e+06 Skewness -2.076e+01 Kurtosis 6.096e+02
Profit/Loss Distribution
1.2
1.0
frequency
0.4
0.6
0.8
0.0
0.2
Simulation results
20
15
10
5
page 18
in millions
Introduction - life insurance models The actuarial equivalence principle has one main drawback: it simply looks at the mean/average of the loss-at-issue distribution. Alternative is to also examine the variability of this loss, but this does not give the complete picture of the loss distribution. A much better alternative is to examine the loss distribution itself. In many cases, it is impossible to derive explicit form of the loss distribution. Simulating the loss distribution is one method to do it main drawback is it may require computer-intensive calculations. We demonstrate this only for a whole life insurance policy issued to a single person - in practice, you would be doing this for a portfolio of insurance contracts.
page 19
Assume that mortality follows the Gompertz with force of mortality x = Bc x , where B and c are constants satisfying B > 0 and c > 1. It is easy to show that for an issue age x , its future lifetime Tx follows the survival pattern Bc x STx (t ) = P (Tx > t ) = exp ct 1 log(c ) for t 0. ,
The lognormal distribution Illustrative example R code to generate the stock price process Pictorial illustration Lognormal property Illustration of generating distribution of stock price Distribution graph Generating distribution of a portfolio of assets
page 20
We can use the inverse transform method to simulate from Gompertz. Begin with a random number U , generate a Gompertz lifetime, say T , from the following equation: exp Bc cT 1 log(c )
x
= U,
Running this procedure m (number of simulations) times, we can then have a simulated distribution of the Gompertz lifetime.
page 21
With a simulated value of T , we can then simulate a value of the present value of the loss-at-issue. For example, in a (fully continuous) whole life insurance contract, we have , L0 = bT v T a T where v = 1/(1 + i ) = e is the discount factor, is the annual premium assumed to be payable continuously throughout the year, and bT is the amount of insurance payable at death. Again, run this procedure for m number of times to get a simulated distribution of the loss-at-issue.
page 22
Simulating the loss after k years When computing reserves, we need to evaluate the loss at that point. Suppose we are interested in the loss after k years, then it can be shown that the simulated lifetime for the person who is then aged x + k is T = log(c ) log(U ) 1 log 1 , log(c ) Bc x +k
where U is U (0, 1) generated value. For the same (fully continuous) whole life insurance contract, we would have the loss after k years evaluated as , Lk = bT v T a T where T is the future lifetime of the person x who is now aged x + k .
page 23
Parameter assumptions
To illustrate, we assume the following Gompertz parameter values: B = 0.0000429 and c = 1.1070839. In addition, benet amount is $100, premium is $0.0095 per $1 of insurance, and i = 5%. Number of simulations: 50,000. Apart from calculating the losses at issue, we also calculate reserves (or losses) at the end of 10 years. The R routine is called Gompertz.SimulationT.R - too long to print in these slides; but is available on the website.
page 24
> source("C:\\...\\Math276-Spring2008\\Rcodes-2008\\Week67\\Gompertz.SimulationT.R") Value Number 50000.00 Mean 41.19 5th Q 18.90 25th Q 34.41 Median 42.97 75th Q 49.71 95th Q 57.16 Variance 136.32 StdDev 11.68 Minimum 0.00 Maximum 71.08 Skewness -0.74 Kurtosis 0.40 Value Number 50000.00 Mean -0.18 5th Q -12.12 25th Q -8.90 Median -4.79 75th Q 2.82 95th Q 28.04 Variance 212.20 StdDev 14.57 Minimum -15.75 Maximum 99.99 Skewness 2.79 Kurtosis 10.19
page 25
- continued
Value Number 50000.00 Mean 31.74 5th Q 10.85 25th Q 24.90 Median 33.18 75th Q 39.83 95th Q 47.26 Variance 119.26 StdDev 10.92 Minimum 0.01 Maximum 59.04 Skewness -0.54 Kurtosis -0.14 Value Number 50000.00 Mean 10.16 5th Q -7.56 25th Q -2.36 Median 4.20 75th Q 15.98 95th Q 50.89 Variance 353.57 StdDev 18.80 Minimum -12.77 Maximum 99.95 Skewness 1.93 Kurtosis 4.21
page 26
frequency
0.00
10
30 t.30
50
70
frequency
0.02
20
20
40 loss.30
60
80
Distribution of T(40)
0.04
0.04
Simulation
frequency
frequency
0.02
0.02
0.00
0.00
10
20
30 t.40
40
50
60
20
40
60
80
100
loss.40
page 27
Density
0.00
20
40
60
Density
0.02
20
20
40
60
80
N = 50000
Bandwidth = 1.182
N = 50000
Bandwidth = 0.9113
T(40)
0.04
Simulation
Density
Density
0.02
0.02
0.00
0.00
10
20
30
40
50
60
20
20
40
60
80
N = 50000
Bandwidth = 1.124
N = 50000
Bandwidth = 1.397
page 28