Does it make sense to invest into the stock market at all-time highs? Answered with F# on .NET Core
You find the source code here on GitHub.
This post is not an investment advice. It is simply an experiment with historical data.
This is a software engineering blog, but one of my hobbies is stock exchange and investing and these two actually fit together very well. This post follows this theme: I wanted to run some statistics on financial data and I used F# and .NET Core for that.
At the time of writing it is 2017 July and markets reach all-time highs very frequently and this period started a long time ago, so we are in a big bull market.
Many theories say that an “average” investor should not try to time the market; the best way is just to invest into an index (e.g. with an ETF) and stay in it very long and it does not matter where the index is, the investor just should start to invest.
Other theories suggest anti-cyclic investing, meaning an investor (including long-term investors) should invest when the market is down and should sell when the market is up.
I created a small program that basically compares these approaches. “The market is up” in this case is defined as all-time high. The program does not shoot for selling when the “Market is down”, in both cases it just holds the position for the same number of years.
The program solving this problem
I wanted to use F# and .NET Core to get answers to the problem stated above.
In the GitHub repo there is a small F# application with some functions which do the calculation. It basically maps every trading day into one of two lists:
- List of all-time highs*
- List of not all-time highs
After creating the two lists it remembers the price on that day, calculates the gain between that day and the trading day 5 years after the initial day. At the end for both lists it calculates the average gain.
Additionally, I also wanted to visualize the data. Now the problem was that none of the traditional F# charting libraries worked on .NET Core. Plus I used my MacBook with macOS (which I wanted to keep), so there was really no way to use any Windows stuff here. So I decided to write the charting library myself. For this I used SkiaSharp, which is a cross platform graphics library from the Xamarin guys based on Skia. The cool thing about it is that there is a netstandard1.3 based SkiaSharp NuGet package (see here), which is a perfect fit for my .NET Core - F# application. I did not want to code the SkiSharp logic in F#, so the charting itself is done in C#. That library can be found here. It's still in a very early stage! It's basically a prototype, but it does the job to visualize the data. The visualization is stored in .jpeg files.
I ran the tests on these Indexes:
- Dow Jones (^DJI.csv)
- S&P500 (^GSPC.csv)
- NASDAQ (^IXIC.csv)
- DAX (^GDAXI.csv)
The charts show two data sets: The red-green plot is the index itself. The green points are the all-time highs, the red points are not all-time highs. The values can be seen on the left axis.
The black values are the gains: for every trading day it shows how much percent the value changed when you invested on that day and kept the money in the index for 5 years. It is centered on the y axis (date) -so that is 0% change- and the value range can be seen on the right axis.
Processing ^DJI.csv Historical Data Size: 8183 Date Range: 01/29/1985 - 07/14/2017 Number of transactions that were started at all-time high: 1069 Number of transactions that were started at not at all-time high: 5853 All-time high avg Gain: 64.419412817524026636163519599% Not All-time high avg Gain:: 54.537834148644233936464592119%
Processing ^GSPC.csv Historical Data Size: 16998 Date Range: 01/03/1950 - 07/21/2017 Number of transactions that were started at all-time high: 2092 Number of transactions that were started at not at all-time high: 13645 All-time high avg Gain: 54.216484601020712535593668284% Not All-time high avg Gain:: 49.006853908185915798452714764%
Processing ^GDAXI.csv Historical Data Size: 7468 Date Range: 12/30/1987 - 07/21/2017 Number of transactions that were started at all-time high: 601 Number of transactions that were started at not at all-time high: 5593 All-time high avg Gain: 44.500410112352093853479183682% Not All-time high avg Gain:: 63.122345602494611035971993199%
Processing ^IXIC.csv Historical Data Size: 11720 Date Range: 02/05/1971 - 07/21/2017 Number of transactions that were started at all-time high: 1258 Number of transactions that were started at not at all-time high: 9201 All-time high avg Gain: 61.698207737683027462731936261% Not All-time high avg Gain:: 76.237962446772308946927115902%