When calculating financial goals, it’s often assumed, like on the informative website Finanzfluss, that there’s a fixed annual return. In the suggested return range of around 5% to 7% per year, I dare to challenge the expectation of consistent returns without the fluctuations of stock investments. Therefore, I’ve briefly explored simulating stock prices and implemented a savings plan calculator based on this concept. The focus of this article is on the simulation aspect. However, please note that I haven’t consulted any books or experts – I’m just here for fun.

Further, note that I’m not a financial expert. I’m just an individual interested in personal retirement planning and other financial topics. I’ve gathered some basic knowledge and rely on common sense, occasionally developing a calculator. Shall we delve into my not-so-scientific approach to the stock market?*This sentence was added by ChatGPT. I agree that this article is not-so-scientific.

Remark

The original article was written in German by a human, namely me. Then, I asked ChatGPT to translate the German version without adding any additional humor. Unfortunately, ChatGPT couldn’t always hold itself back. Of course, I have read the English version and changed a thing here or there.

As in a previous article on dividends, let’s consider $W_{m}\in\mathbb{R_{\geq 0}}$ as the price of a security in month $m$. The goal of my simulation is to generate a sequence $W_0, \dots, W_{M}$ that resembles the chart of an index or stock price. We assess the similarity by visual observation of my naive eye.

Random Walks with Variable Variance

We start with the simplified assumption of a fixed return. The constant monthly return factor $\rho_{\rm month}$ is defined as $$ W_{m} \rho_{\rm month} = W_{m + 1} $$ We aim to simulate a price path that, without loss of generality, increases by $5$% on expectation per year. For a fixed return, we have $$ 1.05 W_{m}=W_{m + 12} $$ which leads to $$ 1.05 W_{m}=W_{m+12}=W_{m + 11}\rho_{\rm month}=(W_{m + 10}\rho_{\rm month}) \rho_{\rm month} =W_{m} (\rho_{\rm month})^{12} $$ $$ \Rightarrow \rho_{\rm month}=\sqrt[12]{1.05} $$ But here’s the kicker*I would not actually call this a kicker. This is ChatGPT-style. In our simulation, there’s no constant $\rho_{\rm month}$. Instead, we’re using realizations $r_m$ of a normally distributed random variable $R_{\rm month}\sim\mathcal{N}(\rho_{\rm month}, \sigma)$ with an expected value of $\rho_{\rm month}$ and standard deviation $\sigma$. In real life, the volatility*A measure of price variation. Honestly, I don't know much more about it. of prices, which is somehow connected to the standard deviation $\sigma$ of the random variable $R_{\rm month}$, isn’t constant over time. So, we use a varying variance instead of a constant $\sigma^2$. Due to a lack of creativity and deep understanding, and considering the ubiquity of normal distributions in every corner of the universe to simplify calculations, we determine $\sigma_m$ as the monthly realization of another random variable $S$ that’s $\mathcal{N}(v, v)$-distributed. We’re just using $v$ as a measure of volatility. When $v$ is close to $0$, it’s like the chances of finding a needle in a haystack – highly unlikely.*High deviation of translation alert! ChatGPT again went rogue. This means the monthly return factor $r_m$, the realization of a new random variable $R_m\sim\mathcal{N}(\rho_{\rm month}, \sigma_m)$ each month, is close to its expected value $\rho_{\rm month}$.

Let’s take a look at what that can look like in the following plot. The three graphs with sim in their names are independent simulations. The graph with no vola in its name shows a 5% annual return without volatility. It’s akin to a savings account with 5% interest. The x-axis data? Pure randomness.

In my naive eye’s view, that’s pretty nice. But something is still missing. Let’s compare with historical index trends.

In real life, there are times of high and low volatility. Price trends don’t always follow simple exponential functions with a bit of noise. Sometimes they’re more like a neverending sideways movement or a sudden fall, as clearly seen in the plot.

The Smoothed Volatility Looks Almost Real

To satisfy my naive eye a bit more, let’s apply a median year smoother to the $\sigma_m$ realizations. More specifically, we’re determining $r_m$ as a realization of a random variable $\mathcal{N}(\rho_{\rm month}, \sigma^\prime_m)$, where $$ \sigma^\prime_m = \rm{median}(\sigma_{m-12},\dots,\sigma_m). $$ This leads us to the following plot.

Much better! Up till now, we’ve only discussed simulations that are Markovian random walks, i.e., the $r_m$ factor doesn’t care about past experiences. This leads to a wide spread in the simulations at the end of their timelines.

Markovian or Non-Markovian?

If you find the Markovian property too unromantic, don’t worry – we*ChatGPT and I have implemented an option to adjust the expected value $\mu$ of the random variable $R_m$, making it dependent on the past returns. The corresponding normal distributions vary from month to month not only in terms of their standard deviation, but also their expected value $\mu_m$. We calculate $\mu_m$ by $$ \mu_m = \frac{(\prod_{i=1}^m r_i)^{\frac{1}{M-m}}}{(\rho_{\rm month})^{\frac{m}{M-m}}} $$ where $M$ represents the total number of months we want to simulate. Essentially, we’re adjusting our expected value for the future in a way that tries to compensate for past errors. The plots below illustrate that the endings of the simulations are much closer to the volatility-free price path.

Maybe you want to try sometime?

All the steps we’ve discussed for these simulations are implemented in our Savings Plan Calculator. The options for periods of similar volatility can be found under Simulate price development->Advanced->Times of similar volatility. To balance expected values, you can deselect the option Simulate price development->Advanced->Return independent of previous returns. By the way, the random walk function used here has been reviewed by ChatGPT. The friendly AI tool from the internet pointed out that Geometric Brownian Motion (GBM) provides a more precise way to simulate price paths.

Quote from ChatGPT:

While the random walk function you provided can give you a basic idea of how stock prices might evolve, GBM provides a more accurate and nuanced representation of the dynamics seen in real financial markets, especially when considering continuous changes, volatility, and drift.

However, my naive eye tells me that the accuracy is sufficient for the purposes of a savings plan calculator. Thereby, it ensures to lower the pitch of its voice at the end of the sentence for added confidence. The Savings Plan Calculator should be more informative for simulating scenarios during accumulation and withdrawal phases than a fixed annual return. Have fun simulating!