Monte Carlo simulated stock price time series and random number generator
Given a starting price and desired volatility, this calculator generates a series of simulated daily stock prices using a
choice of calculation methods.
The purpose of doing this would be to generate a series of stock prices that is realistic1 but unpredictable and isn't drawn from a price history that you or
a trading system you are testing might already be familiar with, such as prices from the past year.
Ways to use these numbers:
For a real stock, enter its current price and volatility to create hypothetical continuations of its daily prices into the
future.
As the basis for calculating the value of options on the stock. Calculate a new
option
value for each new stock price.
View how the theoretical value of the option changes in response to stock price changes. This can give you a sense of what option trading
feels like, without risking any real money.
Doing this many times for the same stock and option, and recording and averaging the outcomes, is the basis of the
Monte
Carlo option pricing method, which is one way to study the behavior
of American-style options.
Test yourself or a trading system on a series of stock prices that you and the system could not have encountered
previously and learned to recognize.
In a stock market trading game.
Create fake stock charts. Mix them up with real stock charts, give the set to your friends, and see if they can tell
which are real and which are fake.
Create a stock chart that contains sections of data from a real stock mixed in with sections of data that you calculated here.
See if your friends can determine which sections are real and which are fake.
Try to write a computer program that can tell the difference between the fake charts and the real ones. The most realistic
model would be the one that the program has the most difficulty identifying as fake.
Inputs
Instructions
To calculate by the most common method, simply enter Starting Price and
Volatility, and click Calculate.
Output Prices
Starting Price:
This will be the starting point from which successive values
are calculated, but the start value will not be in the output list. Thus, if you want to extend an existing time series,
you can enter its last value as the start value here.
Volatility (%):
%
The same volatility figure required for Black-Scholes option valuation.
Enter as a percent, not a decimal. Ex: 62, not 0.62. If you have a set of daily prices for a real stock but don't know its volatility, you can use the
volatility calculator. Historical
price data is available at
Yahoo! Finance.
Price calculation method:
Arithmetic: Up/down percentage point moves are equally likely even though up and down are not symmetrical. For
example, a stock that loses 50% must gain 100% to regain the lost ground.
Logarithmic: Up and down moves are
symmetrical; the probabilities of the stock doubling or halving are equal. Although it is nonintuitive, the most common model
used in economics and finance is Logarithmic
+ Normal (below) = "lognormal".
None: Uses the calculator as a random number generator. The raw random numbers are not turned into simulated daily
prices.
Probability distribution:
Normal (aka
gaussian): Mean=0, StdDev=Volatility / 100.
Levy: Mean=0, Beta
(skewness)=0, Alpha (kurtosis) is used as entered below. c (variability, "StdDev") = (Volatility / 100) / Vol.adj.factor.
Uniform:
Mean=0. For raw random numbers, > -Volatility / 100 and < Volatility / 100. For simulated prices, equally distributed between ±1.733421 *
Volatility / 100, which forces calculated volatility into desired range9.
For Levy only:
Alpha:
Vol. adj. factor:
Alpha must be > 0 and <= 2. Default value of 1.7 is probably too low. Alpha = 1 is a
Cauchy distribution. Alpha = 2 is a Gaussian
normal distribution.
Volatility adjustment (aka fudge) factor is any number that brings the calculated volatility (in Verify:, below) closer
to the requested value. With Alpha = 1.7, an adjustment factor of 2 seems to work ok.
# of days:
The number of values to calculate. Default = 252 = 1 trading year.
Click Calculate.
(Reverse)
The output default sort order is from oldest date at the top to most recent at the bottom. To reverse, click the
Reverse button before copying the data.
Copy
and
Paste
Click anywhere in the output box. Type Ctrl+A (Select All), then Ctrl+C (Copy to
clipboard). Paste the numbers in the application where you want to use them (Ctrl+V).
Verify: at left is the actual calculated annualized volatility of the generated numbers. It won't exactly match the
requested value because the output prices are random numbers.
Notes
1) How well any of these models simulate real price behavior is debatable.
2) General method of calculation:
Convert the input Volatility (a percent) to decimal: true annual Volatility = Volatility / 100
Convert annual Volatility to daily: Volatilitydaily = Volatilityannual *
SQRT(1/252)
252 is the number of trading days in a year. The calculator generates 252 random daily prices for each year. If the 252-based
daily volatility is used 252 times, the volatility for the entire year will approximate the requested annual volatility. Note
that if we used a 365-based daily volatility (a smaller number) and only use it in 252 predictions (because no stock or option
trades 365 days in a year), the annualized volatility won't approximate the requested value. It will be less.
For each daily data point: generate a random number from the specified probability distribution (Normal, Levy, or Uniform); use the random number and
yesterday's price in the appropriate equation (arithmetic or logarithmic) to calculate a new price for today; lastly, today's price becomes yesterday, and repeat.
3) Equations for some of the combinations (the others are in the JavaScript source code):
The Mean (average) of 0 makes it equally likely that today's price will be above/below yesterday's. Volatilitydaily
is used as the standard deviation. As an example, if it is .01 and Yesterday was $100, then there is a 68% probability
that Today will be somewhere between
($100 * (1 + (-.01))) = $99 and ($100 * (1 + (.01))) = $101.
The lognormal model of price fluctuations is commonly used. It is the model assumed by Black-Scholes. Using
the random number in the exponent causes the price changes in the output series to have a lognormal distribution. This means
that the price changes themselves do not fall into a normal distribution, but the natural logarithms of the price
changes do.
The equation is the same as for Arithmetic Normal, but the random number is from a Levy distribution. Levy (Lévy)
distributions have wider variance than the Gaussian normal distribution and can produce large price jumps that
almost
never occur with a normal distribution. The reason some people advocate using a Levy distribution is specifically because price swings that the Gaussian distribution says are nearly impossible do occur in real trading.
The Alpha parameter of a Levy determines its kurtosis (inversely). A Gaussian normal curve actually is a Levy curve with alpha=2. As
alpha drops below 2, the kurtosis increases: the curve becomes more pointy in the middle, and the tails rise farther
above the baseline so there is more area in them. What this means in practical terms is that even though most values still
tend to be near the center point of 0, deviations that are very far away from it become more and more probable as alpha goes
lower.
Levy distributions have a skewness parameter called beta. In these calculations, beta = 0.
A peculiar characteristic of a Levy distribution is that it has no defined standard deviation. This becomes a problem when
we want to generate random numbers with a particular standard deviation.
Instead, a Levy has a scale (or dispersion) parameter, known as "c", that is analogous to StdDev in that it describes in a
sense how wide the distribution is but isn't the same as StdDev.
This calculator uses the Volatility as the value for c. However, because the Levy distribution doesn't "respect" the
standard deviation the way the Gaussian does, the numbers generated are not so strictly limited by this c value as they would
be for a real standard deviation. Thus, due to the greater likelihood of extreme values in the generated numbers, their calculated volatility
(in the "Verify:" box of the calculator) can vary wildly from the requested volatility
value and can vary wildly from one run to the next.
In testing, I found that although there is great variability in the calculated volatility, it's not totally random, and
it's possible to bring the calculated values more or less into the desired range, but it requires applying a fudge factor to c
(the Volatility) to do it, and that is where AdjustFactor in the above equation comes in. It's a practical necessity. Since,
in the Levy case, the Volatility is not a real standard deviation anyway, fudging it hardly seems a violation from any
theoretical perspective. The ultimate goal is to get output numbers whose actual volatility, when calculated the usual
way, is in the requested range.
Nonetheless, I'm open to alternatives, especially ones that make more theoretical sense. One alternative that might
make more sense is to use an AdjustmentFactor of 1 and adjust Alpha instead, to values between 1.7 and 2.0.
This method is like the lognormal, except it uses the Levy random number in the exponent and therefore produces lognormally
distributed stock prices. I suspect that if the Levy distribution ever replaces the Gaussian normal for stock price models, it
would be with this log-Levy model.
However, the Levy distribution's ability to produce almost arbitrarily large numbers can be especially weird when the value
is used as an exponent. In one test, a stock price went from $9 to $29,000 in one day, which can hardly be said to be
realistic.
4) The Levy methods in the calculator are experimental. I don't know if they are correct.
6) The Gaussian and Levy random number generator functions are in my
JavaScript
library.
7) How to graph the simulated price series in Excel:
Copy the output prices and paste them into Column A of a blank worksheet.
Click Insert > Chart (or the Chart Wizard button).
Type=Line. Next...
Data Range: Click the top of Column A so the entire column is selected. Equivalent is $A:$A.
Click Finish. You can drag the chart handles to resize it.
8) How to make a frequency histogram in Excel:
The type of graph that reveals the bell shape of a bell-shaped distribution (or the shape of any probability distribution) from
raw data is
called a histogram. It plots each number (on the X axis) against the number of times it occurred (on the Y axis). (As a practical
matter, since any one number is unlikely to recur, the numbers are usually grouped into intervals first.)
Click Tools > Data Analysis > Histogram
Input Range = the column where
you pasted the source
numbers, such as $A:$A
Bin Range = (blank). Let Excel automatically determine how the numbers are grouped.
Labels = checked if the top cell is a textual label
New Worksheet Ply = checked
Pareto and
Cumulative = unchecked
Chart Output = checked
Click OK. Drag chart handles to resize it.
As an example: next to Column A of raw prices (for which a histogram isn't much use), make Column B for the "daily returns"
(today's price / yesterday's price), and next to that, Column C for the logarithm (LN() function) of the daily returns. Make
(separate) histograms for Columns B and C. If your prices were created using a lognormal distribution, the graph of Column B looks like a
bell-shaped curve except that the right side has a slightly longer and taller tail than the squished-looking left side. (It is
skewed.) However, the histogram of Column C (the logarithms) should be a symmetrical normal curve.
9) I found through testing that using (Volatility * 1.733421) for uniformly distributed random numbers used for
generating time series brought their calculated volatility into the same range as a normally distributed random number with
StdDev=Volatility. It wasn't the factor I expected to use, so where it comes from is a mystery to me. It is approximately SQRT(3),
which might or might not be a coincidence.
10) Questions, comments, feedback, suggestions are welcome in the
discussion forum. It was a
forum question that inspired
the addition of Lévy distribution methods.