<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/financial-time-series-forecasting-an-easy-approach/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://datascienceplus.com/financial-time-series-forecasting-an-easy-approach/"> DataScience+</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Financial time series analysis and their forecasting have an history of remarkable contributions. It is then quite hard for the beginner to get oriented and capitalize from reading such scientific literature as it requires a solid understanding of basic statistics, a detailed study of the ground basis of time series analysis tools and the knowledge of specific statistical models used for financial products. Further, the financial time series ecosystem is not one of the most easiest flavour you may encounter. Trends are typically transitory as driven by underlying random processes, non stationarity, heteroscedasticity, structural breaks and outliers are rather common. All that has driven the adoption of sophisticated models and simulation techniques which require good understanding and expertise to take advantage of.</p>
<p>On the other hand, you may want to get a basic understanding of stock prices time series forecasting by taking advantage of a simple model providing with a sufficient reliability. For such purpose, the Black-Scholes-Merton model as based upon the lognormal distribution hypothesis and largely used in financial analysis can be helpful. The rest of this short dissertation shows how to take advantage of it.</p>
<h2>Model</h2>
<p>As said, I am going to introduce the Black-Scholes-Merton model which assumes that percentage changes in the stock price in a short period of time are normally distributed.</p>
<p>The return of the stock price <strong>S(t)</strong> at time t can be expressed under those hypothesis as:<br>
$$<br>
\begin{equation}<br>
\begin{aligned}<br>
\frac{S(t)-S(t_{0})}{S(t_{0})}\ \sim\ N(u\ \Delta T,\ \sigma^2\Delta T) \ \ \ \ \ (1) \\<br>
\end{aligned}<br>
\end{equation}<br>
$$<br>
where the left term is the (discrete) return on stock price S at time t. By formulating the same equation in terms of first order differentials for price S (dS) and time t (dt), the equation (1) turns out to be expressed in terms of continuously compounded returns, obtaining:<br>
$$<br>
\begin{equation}<br>
\begin{cases}<br>
t = t_{0} + \Delta T \\<br>
ln(\frac{S(t)}{S(t_{0})})\ \sim \ N((u\ -\ \frac{\sigma^2}{2})\ \Delta T,\ \sigma^2\Delta T) \ \ \ \ \ (2) \\<br>
\end{cases}<br>
\end{equation}<br>
$$<br>
Equation (2) states that the log returns follow a normal distribution, where <strong>u</strong> is the stock price drift, <strong>σ</strong> is the stock price standard deviation. From equation (2), it can be stated the following relationship binding stock price S(t) with stock price S(t0):<br>
$$<br>
\begin{equation}<br>
\begin{aligned}<br>
S(t)\ =\ S(t_{0})\ e^{(u\ -\ \frac{\sigma^2}{2})\ +\ \sigma B(t)} \ \ \ \ \ (3) \\<br>
\end{aligned}<br>
\end{equation}<br>
$$<br>
The <strong>B(t)</strong> term represents the Brownian motion.</p>
<p>Furthermore, equation (2) allows to determine the distribution of the stock price as stated by the following equation:<br>
$$<br>
\begin{equation}<br>
\begin{aligned}<br>
\ln(S(t_{0}+\Delta T))\ \sim \ N(ln(S(t_{0})) + (u\ -\ \frac{\sigma^2}{2})\Delta T,\ \sigma^2\Delta T)\ \ \ \ \ (4) \\<br>
\end{aligned}<br>
\end{equation}<br>
$$<br>
The drift <strong>u</strong> and the standard deviation <strong>σ</strong> can be estimated from the stock price time series history.</p>
<p>The time interval <strong>ΔT</strong> represents our future horizon. Please note that both the drift and the standard deviation must refer to the same time scale, in the sense that if <strong>ΔT</strong> is measured in days, we have to use the daily returns and daily standard deviation, if <strong>ΔT</strong> is measured in weeks, we have to use weekly returns and weekly standard deviation, and so on.</p>
<p>Taking the exponential of both terms of equation (4) we obtain:<br>
$$<br>
\begin{equation}<br>
\begin{aligned}<br>
S(t_{0} + \Delta T)\ \sim \ exp(\ N(ln(S(t_{0})) + (u\ -\ \frac{\sigma^2}{2})\ \Delta T,\ \sigma^2 \Delta T)) \\<br>
= exp(\ N(\ \hat u(\Delta T),\ \hat\sigma^2(\Delta T)) \ \ \ \ \ (5) \\<br>
\end{aligned}<br>
\end{equation}<br>
$$<br>
Above equation provides with a family of normal distributions having known parameters and dependent on the time interval <strong>ΔT</strong> = [0, T]. Lower and upper bounds at each instant of time t in ΔT can be modeled as a 95% confidence interval as determined by the 1.96 multiple of the standard deviation at time t in ΔT. As a result, the expected value, lower and upper bounds of the stock price S(t) are so determined:<br>
$$<br>
\begin{equation}<br>
\begin{cases}<br>
E(S(t))\ =\ exp(ln(S(t_{0})) + (u\ -\ \frac{\sigma^2}{2})\ \Delta T) \ \ \ \ \ (6) \\<br>
LB(S(t))\ = exp(ln(S(t_{0})) + (u\ -\ \frac{\sigma^2}{2})\ \Delta T\ -\ 1.96*\sigma \sqrt \Delta T) \\<br>
UB(S(t))\ = exp(ln(S(t_{0})) + (u\ -\ \frac{\sigma^2}{2})\ \Delta T\ +\ 1.96*\sigma \sqrt \Delta T) \\<br>
\end{cases}<br>
\end{equation}<br>
$$</p>
<h2>Implementation</h2>
<p>I will take advantage of the <em>timeSeries</em> package for computing returns (see returns() function) and the <em>quantmod</em> package for financial stock prices availability (see getSymbols() function). Specifically, I will download the Apple share price history.</p>
<pre>
suppressPackageStartupMessages(library(timeSeries))
suppressPackageStartupMessages(library(quantmod))

# downloading stock price
getSymbols(&quot;AAPL&quot;)

head(AAPL)
<em> AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
2007-01-03 86.29 86.58 81.90 83.80 309579900 10.85709
2007-01-04 84.05 85.95 83.82 85.66 211815100 11.09807
2007-01-05 85.77 86.20 84.40 85.05 208685400 11.01904
2007-01-08 85.96 86.53 85.28 85.47 199276700 11.07345
2007-01-09 86.45 92.98 85.15 92.57 837324600 11.99333
2007-01-10 94.75 97.80 93.45 97.00 738220000 12.56728</em></pre>
<pre>
# using adjusted close price
Y &lt;- coredata(AAPL[,&quot;AAPL.Adjusted&quot;])

# history time span
hist_start &lt;- 1
hist_end &lt;- 100
hist &lt;- c(hist_start:hist_end)

# historical prices
Y.hist &lt;- Y[hist]

# historical returns = (Y(t1)-Y(t0))/Y(t0)
Y.hist.ret &lt;- returns(Y.hist)

# standard deviation computed based on history
(sv_hist &lt;- sd(Y.hist.ret, na.rm=T))
<em>[1] 0.01886924</em></pre>
<p>Aboveshown value is the estimate of our standard deviation of our share price daily returns as determined by hystorical observations.</p>
<p>It is a good practice to compute the confidence intervals for estimated parameters in order to understand if we have sufficient precision as implied by the samples set size.</p>
<pre>
# 95% confidence interval
n &lt;- length(hist)
sv_hist_low &lt;- sqrt((n-1)*sv_hist^2/qchisq(.975, df=n-1))
sv_hist_up &lt;- sqrt((n-1)*sv_hist^2/qchisq(.025, df=n-1))
(sv_hist_confint_95 &lt;- c(sv_hist_low, sv_hist, sv_hist_up))
<em>[1] 0.01656732 0.01886924 0.02191993</em></pre>
<p>I am going to show a plot outlining future share price evolution.</p>
<pre># relative future time horizon
t &lt;- 1:20

# martingale hypothesis (the average of future returns is equal to the current value)
u &lt;- 0

# future expected value as based on normal distribution hypothesis
fc &lt;- log(Y.hist[hist_end]) + (u - 0.5*sv_hist^2)*t

# lower bound 95% confidence interval
fc.lb &lt;- fc - 1.96*sv_hist*sqrt(t)

# upper bound 95% confidence interval
fc.ub &lt;- fc + 1.96*sv_hist*sqrt(t)

# collecting lower, expected and upper values
fc_band &lt;- list(lb = exp(fc.lb), m = exp(fc), ub = exp(fc.ub))

# absolute future time horizon
xt &lt;- c(hist_end + t)

# stock price history line plot
plot(Y[hist_start:(hist_end + max(t))], type='l',
     xlim = c(0, hist_end + max(t)),
     ylim = c(5, 20),
     xlab = &quot;Time Index&quot;,
     ylab = &quot;Share Price&quot;,
     panel.first = grid())
# starting point for our forecast
suppressWarnings(points(x = hist_end, y = Y.hist[hist_start+hist_end-1], pch = 21, bg = &quot;green&quot;))
# lower bound stock price forecast
lines(x = xt, y = fc_band$lb, lty = 'dotted', col = 'violet', lwd = 2)
# expected stock price forecast
lines(x = xt, y = fc_band$m, lty = 'dotted', col = 'blue', lwd = 2)
# upper bound stock price forecast
lines(x = xt, y = fc_band$ub, lty = 'dotted', col = 'red', lwd = 2)
</pre>
<p>Gives this plot:<br>
<a title="" data-rel="lightbox-0" target="_blank" rel="nofollow" href="https://i1.wp.com/datascienceplus.com/wp-content/uploads/2017/03/Plot1_100.png?ssl=1"><img sizes="(max-width: 900px) 100vw, 900px" alt="" class="wp-image-5811" src="https://i1.wp.com/datascienceplus.com/wp-content/uploads/2017/03/Plot1_100.png?w=450&ssl=1" data-recalc-dims="1"></a></p>
<p>The plot shows the lower (violet) and upper (red) bounds including the actual future price evolution and the forecasted expected value (blue). In that, I did not account for a drift <strong>u</strong> (u = 0) and as a consequence, there is a flat line representing the future expected value (actually its slope is slightly negative as determined by the -0.5*σ^2 term).</p>
<p>If you like to have future stock price drift more consistent with its recent history, you may compute a return based on the same time scale of the standard deviation.</p>
<p>The lines of code to add are the following:</p>
<pre>
# added line of code
(mu_hist &lt;- mean(Y.hist.ret, na.rm=T))

n &lt;- length(hist)
# 95% confidence interval for the mean
mu_hist_low &lt;- mu_hist - qt(0.975, df=n-1)*sv_hist/sqrt(n)
mu_hist_up &lt;- mu_hist + qt(0.975, df=n-1)*sv_hist/sqrt(n)
(mu_hist_confint_95 &lt;- c(mu_hist_low, mu_hist, mu_hist_up))
<em>[1] -0.0006690514 0.0030750148 0.0068190811</em></pre>
<p>Above the confidence interval for historical daily returns is shown. We have also to change the assigment to the variable u, the drift.</p>
<pre>
# drift computed on historical values
(u &lt;- mu_hist)
<em>[1] 0.0030750148</em></pre>
<p>The resulting plot is:<br>
<a title="" data-rel="lightbox-1" target="_blank" rel="nofollow" href="https://i1.wp.com/datascienceplus.com/wp-content/uploads/2017/03/Plot2_100.png?ssl=1"><img sizes="(max-width: 900px) 100vw, 900px" alt="" class="wp-image-5829" src="https://i1.wp.com/datascienceplus.com/wp-content/uploads/2017/03/Plot2_100.png?w=450&ssl=1" data-recalc-dims="1"></a></p>
<p>Furthermore, the code shown above can be easily enhanced with sliders to specify the stock price history to take into account for parameters estimation and the desired future time horizon. That can be done by taking advantage of the manipulate package or by implementing a Shiny gadget or application, for example.</p>
<p>Using the same model is possible to compute the probability that the future stock price be above or below a predetermined value at time t. That is possible by computing the normal distribution parameters as a function of ΔT = t – t0 and a density distribution basic property. Herein is how.</p>
<p>This is the historical share price daily drift <strong>u</strong>:</p>
<pre>
(u &lt;- mu_hist)
<em>[1] 0.003075015</em></pre>
<p>This is the current share price <strong>S(t0)</strong>:</p>
<pre>
(curr_share_price &lt;- Y.hist[hist_end])
<em>[1] 14.72056</em></pre>
<p>This is the mean <strong>mu_t</strong> of our normal distribution computed with ΔT= 10, ten units of time (days) ahead of the current time:</p>
<pre>
t &lt;- 10
(mu_t &lt;- log(curr_share_price) + u - 0.5*sv_hist^2)*t
<em>[1] 26.92142</em></pre>
<p>This is the standard deviation <strong>sv_t</strong> of our normal distribution computed with ΔT = 10, ten units of time (days) ahead of the current time:</p>
<pre>
(sv_t &lt;- sv_hist*sqrt(t))
<em>[1] 0.05966977</em></pre>
<p>Arbitrarly, I determine a target price 10% higher of the current one and hence equal to:</p>
<pre>
(target_share_price &lt;- 1.10*curr_share_price)
<em>[1] 16.19261</em></pre>
<p>The probability that the share price at time t is equal or greater (please note the lower.tail = FALSE parameter) than the target price is the following:</p>
<pre>
pnorm(q = log(target_share_price),
      mean = mu_t,
      sd = sv_t,
      lower.tail = FALSE)
<em>[1] 0.06072166</em></pre>
<p>Our model states there is a probability of 6% that share price is above or equal to the target price.</p>
<p><strong>The Misbehavior of Markets: criticism to the lognormal hypothesis</strong></p>
<p>In 1963, Mandelbrot published a research highlighting that, contrary to the general assumption that share price movements were normally distributed, they instead followed a Pareto-Levy distribution, which has infinite variance. That implies that values considered with negligible probability determined by normal distribution hypothesis, they actually are not that unlikely to happen in case of Pareto-Levy distribution.</p>
<p>Based on that market booms and crashes are more frequent than we may think. Be aware of this while applying lognormal distribution assumptions.</p>
<h2>Conclusions</h2>
<p>We have outlined an approach that can be easily implemented to compute expected values, lower and upper bounds of future stock prices. That is based on the well known Black-Scholes-Merton model and its normal distribution hypothesis.</p>
<p>The plot showing future share price expected value, lower and upper bounds can be enhanced with interactive inputs to allow users to select history length and future horizon of interest. By using the same model, probabilities associated to future price thresholds can be computed.</p>
<p>A reference for the Black-Scholes-Merton model we talked about can be found in the following book:</p>
<ul>
<li>Options, Futures and Other Derivatives, John C. Hull, Prentice Hall, 8th Ed.</li>
</ul>
<p>A reference for Mandlebrot criticism to share price lognormal distribution hypothesis is the following book:</p>
<ul>
<li>The Misbehavior of Markets: a Fractal View of Finance Turbolence, Benoit Mandelbrot &amp; Richard L. Hudson, Basic Books Ed.</li>
</ul>
<blockquote><p><em>Disclaimer</em><br>
Any securities or databases referred in this post are solely for illustration purposes, and under no regard should the findings presented here be interpreted as investment advice or a promotion of any particular security or source.</p>
</blockquote>
<p>If you have any question, feel free to comment below.</p>
<ul></ul>
<p><strong>
<p>Related Post</p>
<p>
<ol>
<li><a title="Permanent Link toOutlier detection and treatment with R" target="_blank" rel="nofollow" href="https://datascienceplus.com/outlier-detection-and-treatment-with-r/">Outlier detection and treatment with R</a></li>
<li><a title="Permanent Link toImplementing Apriori Algorithm in R" target="_blank" rel="nofollow" href="https://datascienceplus.com/implementing-apriori-algorithm-in-r/">Implementing Apriori Algorithm in R</a></li>
<li><a title="Permanent Link toR for Publication: Lesson 6, Part 2 – Linear Mixed Effects Models" target="_blank" rel="nofollow" href="https://datascienceplus.com/r-for-publication-by-page-piccinini-lesson-6-part-2-linear-mixed-effects-models-lmem/">R for Publication: Lesson 6, Part 2 – Linear Mixed Effects Models</a></li>
<li><a title="Permanent Link toR for Publication: Lesson 6, Part 1 – Linear Mixed Effects Models" target="_blank" rel="nofollow" href="https://datascienceplus.com/r-for-publication-by-page-piccinini-lesson-6-part-1-linear-mixed-effects-models-lmem/">R for Publication: Lesson 6, Part 1 – Linear Mixed Effects Models</a></li>
<li><a title="Permanent Link toCross-Validation: Estimating Prediction Error" target="_blank" rel="nofollow" href="https://datascienceplus.com/cross-validation-estimating-prediction-error/">Cross-Validation: Estimating Prediction Error</a></li>
</ol></strong>
<div>
<a target="_blank" rel="nofollow" href="http://feeds.feedburner.com/~ff/datascienceplus?a=gWRi0Bft644:FTDBXJPwhmQ:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/datascienceplus?i=gWRi0Bft644:FTDBXJPwhmQ:D7DqB2pKExk" border="0"></a> <a target="_blank" rel="nofollow" href="http://feeds.feedburner.com/~ff/datascienceplus?a=gWRi0Bft644:FTDBXJPwhmQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/datascienceplus?d=qj6IDK7rITs" border="0"></a> <a target="_blank" rel="nofollow" href="http://feeds.feedburner.com/~ff/datascienceplus?a=gWRi0Bft644:FTDBXJPwhmQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/datascienceplus?d=yIl2AUoC8zA" border="0"></a>
</div>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://datascienceplus.com/financial-time-series-forecasting-an-easy-approach/"> DataScience+</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/fg2W1ZU1o9I"></a></div>