Benefits of patience in investing - maximize returns while reducing risk over long term

I recently read the book Coffee can investing by CIO of Marcellus. I highly recommend this book if you want a simple formula on how to identify and invest in stocks which give consistent 20% CAGR. But in my opinion and my personal experience identifying and buying the stock is just half the battle, sticking with it through thick and thin is much more difficult and I must admit I’m still learning on this front. Patience in investing pays off.

Let us see if we can back our hypothesis with data.

(Even the book talks about patience, there is a separate chapter for it. Below analysis is inspired by that chapter)

Code

from datetime import date, datetime
import calendar
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns; sns.set_theme()
import jugaad_data.nse as nse

Download NIFTY historical data using jugaad-data.

nifty = nse.index_df(symbol="NIFTY 50", from_date=date(1990, 8,1), to_date=datetime.now().date())

As you can see the data received is newest first, we need to sort oldest first and reset the indices.

nifty.sort_values('HistoricalDate', inplace=True)
nifty.reset_index(drop=True, inplace=True)
print(nifty.head())
      Index Name INDEX_NAME HistoricalDate  OPEN  HIGH  LOW   CLOSE
    0   Nifty 50   Nifty 50     1990-08-03   NaN   NaN  NaN  337.29
    1   Nifty 50   Nifty 50     1990-08-07   NaN   NaN  NaN  331.45
    2   Nifty 50   Nifty 50     1990-08-08   NaN   NaN  NaN  322.11
    3   Nifty 50   Nifty 50     1990-08-09   NaN   NaN  NaN  325.69
    4   Nifty 50   Nifty 50     1990-08-10   NaN   NaN  NaN  333.35
nifty.set_index('HistoricalDate', inplace=True)

Note on how we calculate returns to keep things simple

We will calculate returns on weekly rolling basis

We will use 1527 one year periods from Aug 1990 till today. eg. 5 Aug 1990 to 4 Aug 1991, 12 Aug 1990 to 11 Aug 1991 so on and so forth

An year consists of 52 trading weeks

An year will have approximately 52 weeks, This will create some gaps over longer period of times but it does not matter for our purpose.

We will also calcuate CAGR and not the absolute returns

t is the holding period here

# Sampling NIFTY on every first day of the week
nifty_sampled = nifty.resample("W").first()
holding_period = [1, 5, 10, 15]
for i in holding_period:
    nifty_sampled['{}Y CAGR'.format(i)] = (np.power(nifty_sampled['CLOSE']/nifty_sampled['CLOSE'].shift(52*i), 1/i) - 1)*100

Now let’s look at the returns over various holding periods

Mean CAGR over various holding periods

nifty_returns = nifty_sampled[['{}Y CAGR'.format(i) for i in holding_period]]
nifty_returns.mean().plot(grid=True, title="Mean CAGR for different holding periods")
print(nifty_returns.mean())
    1Y CAGR     16.250648
    5Y CAGR     11.146642
    10Y CAGR    11.377821
    15Y CAGR    12.665201
    dtype: float64

Mean CAGR values in isolation are misleading

Box plot analysis of the returns over holding periods

ax = nifty_returns.boxplot(grid=True)
fig = ax.get_figure()
fig.suptitle("Boxplot for CARG over different holdig periods")
Text(0.5, 0.98, 'Boxplot for CARG over different holdig periods')

Range of returns over 1 year period is wild

  1. As described in the book, one year investment hoizon can be an intense roller coaster ride for the investor. It varies from over 200% returns during 1991-1992 from Harshad Meheta’s era to as low as more than -50% during 2008 crash. Depending on when you invest returns could range anywhere from -50% to 200% (historically)
  2. Range narrows considerably over 5 year period. 2002-2007 saw high returns of over 40% and 1994-1999 troughs less than -5% returns.
  3. The range narrows further over 10 year with CAGR of 20% and lowest CAGR of -1%
  4. Over 15 year period there are no negative returns with max CAGR of 17%

(Minimum and maximum returns might change slightly from the book over longer periods because of our simple approach of taking 52 weeks returns)

Standard deviation

std_data = nifty_returns.std()
std_data.plot.bar(title="Standard deviation of CAGR over different holding periods")
print(std_data)
    1Y CAGR     33.204075
    5Y CAGR      9.481012
    10Y CAGR     4.858627
    15Y CAGR     2.231804
    dtype: float64

In world of investment standard deviation of returns is the key indicator of risk. As you can see the standard deviation reduces drastically with holding period.

Conlcusion