Site icon R-bloggers

Invest everyday, biweekly, or monthly?

[This article was first published on r on Everyday Is A School Day, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Biweekly did great overall, Better at TIPS, short-term bond, real estate, international; Monthly is second best with 3 out of 8. Good at small, mid, large caps

If you want to automate your investment on index funds with a fixed amount every month, is there a better way to divide the investment? Such as once a month, everyday, or biweekly? I’m very curious about this.

Disclaimer: < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

I am not a financial adviser. Everything that I shared here were purely out of curiosity and to spark questions for experts to explore the idea further. Also, to utilize our data science skills to explore available data to inform one own’s decision. Please take in any information at your own discretion. If you believe that the methodology is erroneous, please feel free to contact and educate me. I’m more than happy to learn from you!

Thought Process:

Let’s Look at FXAIX < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

from <- "2018-01-01"
to <- "2022-10-1"


tq_get("FXAIX", from = from, to = to) %>%
  select(date,close) %>%
  ggplot(.,aes(x=date,y=close)) +
  geom_point(alpha = 0.5) +
  # geom_line(color = "blue") +
  theme_bw() +
  ggtitle("Fidelity S&P 500 closing prices")

The visual does give us an idea that past performance is not indicative of future results. Look at the peaks and troughs, it sure looks like it has a life of its own.

It’s Playtime ! < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

Let’s play with old data < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

Assuming that we want to automatically invest $200 per month, how would the return of investment look like with dividend reinvestment in daily, biweekly, and monthly strategy, if we had invested from 2018-01-01 to 2022-10-1.

One strategy that most financial advisors would provide is to diverse one’s portfolio. Lets diverse our portfolio to include bonds (short term, TIPS etc), small/mid/large caps, real estate, international indices, all through Fidelity. To make things simple, we are going to simulate contribution of the same amount, which is $200 for each index fund.

Hence, we have selected the following index funds:

Tips/Disclaimers:

You could potentially rewrite/change existing code to simulate DAvid Swenson’s Asset allocation portfolio. To read more about David Swenson Yale Endowment Portfolio. Click here

Also please note that I use Fidelity as an example for simplicity purposes. You could use other brokers such as Vanguard, iShares, etc,

Spend some time assessing all of their expense ratio too

x <- "FXAIX"
ticker(x)  
df <- df %>% 
  add_row(tibble(from=from,to=to,ticker=x,daily=daily_ri,biweekly=biweekly_ri,monthly=monthly_ri,daily_gain=percent_gain_daily_ri,biweekly_gain=percent_gain_biweeekly_ri,monthly_gain=percent_gain_monthly_ri)) 

holdings <- c("FXAIX","FIPDX", "FNSOX", "FREL","FSMDX","FSSNX","FTIHX","FUAMX")


for (i in holdings) {
  ticker(i)  
  df <- df %>% 
  add_row(tibble(from=from,to=to,ticker=i,daily=daily_ri,biweekly=biweekly_ri,monthly=monthly_ri,daily_gain=percent_gain_daily_ri,biweekly_gain=percent_gain_biweeekly_ri,monthly_gain=percent_gain_monthly_ri)) 
}

my next blog will describe how to write the above function!

Wow, this is pretty cool. It does look like biweekly investment is better than daily or month. In terms of gain, there is a slightly higher percentage than the rest. And also if there is a lost, it loses less as well (less negative). But is this real? Let’s dive in

For clarity daily_gain, biweekly_gain, and monthly_gain units are in percentage.

Data dive with Monte Carlo: < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

Let’s randomly pick 50 end dates after 1-1-2019 and see how well did biweekly investment do. Do you think there is a difference? I would imagine 50 random dates will give us some idea of the distribution of which has higher percentage gain. It will also, hopefully, captures some of the peaks and troughs. I estimated that each run of the ticker() function takes about 36 seconds to pull information. Fifty is a good number that will take about 25-26 minutes to finish accumulating data.

First 48 rows of Data < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

df %>%
  print(n = 48)


May the Best Strategy Win! < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

df <- df %>%
  mutate(strategy = case_when(
    daily_gain > biweekly_gain & daily_gain > monthly_gain ~ "daily",
    biweekly_gain > daily_gain & biweekly_gain > monthly_gain ~ "biweekly",
    monthly_gain > daily_gain & monthly_gain > biweekly_gain ~ "monthly",
    TRUE ~ "dunno"
  )) 

Basically creating a new column with conditions that tells me which of the 3 investment strategy has the highest yield.

Sneak peek

df %>%
  kbl() %>%
  kable_classic()


Visualize our Winner < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

df %>%
  ggplot(.,aes(x=strategy,fill=strategy)) +
  geom_histogram(stat = "count", col = "black", alpha = 0.8) +
  theme_bw() 

Interesting! Biweekly seems to be ahead. Is it the same for all tickers?


Is our winner a true winner? < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

df %>%
  mutate(strategy = as.factor(strategy)) %>%
  group_by(ticker,strategy) %>%
  summarize(count = n()) %>%
  ggplot(.,aes(x=strategy,y=count, fill=strategy)) +
  geom_col(col = "black", alpha = 0.8) +
  theme_bw() +
  scale_x_discrete(drop=FALSE) +
  facet_wrap(.~ticker,scales = "free") 

Not bad!

If we were to explore further, being a winner does not mean you make $$$. For some funds it just means you have less losses, let’s find out more.


Bird’s Eye View < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

df %>%
  # mutate(to = lubridate::ymd(to)) %>%
  select(-daily,-biweekly,-monthly,-strategy) %>%
  pivot_longer(cols = c("daily_gain","biweekly_gain","monthly_gain"), names_to = "strategy", values_to = "percent_gain") %>%
  ggplot(.,aes(x=to,y=percent_gain,fill=strategy)) +
  geom_col(alpha=0.9,position = "dodge") +
  # geom_line() +
  theme_bw() +
  facet_wrap(.~ticker,scales="free") +
  theme(axis.text.x = element_text(size = 4,angle = 45, hjust = 1)) 

click here for bigger view

Wow, very busy faceted graphs! What I’ve observed is that biweekly seems to have slightly higher percentage gain and less percentage losses when evaluated during a bear market. This is very helpful because if the plan is to have a fixed income at retirement, preparing for a bear market is probably a better strategy in my opinion.


Zoom in on FXAIX < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">

Limitations/Oppurtunities for improvement < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">


Conclusion/Lessons Learnt < svg class="anchor-symbol" aria-hidden="true" height="26" width="26" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> < path d="M0 0h24v24H0z" fill="currentColor"> < path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76.0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71.0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71.0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76.0 5-2.24 5-5s-2.24-5-5-5z">


If you like this article:

To leave a comment for the author, please follow the link and comment on their blog: r on Everyday Is A School Day.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.