1 All Seasons Portfolio Part 1

My second post to connect my readings with my personal passion.

2 Three items coincided to make this idea come to fruition.

  1. Watching Lab 9: Finance with R - Performance Analysis & Portfolio Optimization with tidyquant from Matt Dancho’s Business Science University (https://www.business-science.io/)
DSB Learning Labs Pro

DSB Learning Labs Pro

  1. Reading Tony Robbin’s Master the Game: 7 Simple Steps to Financial Freedom and the concept of the All Season’s fund by Ray Dalio (https://www.iwillteachyoutoberich.com/blog/all-weather-portfolio/)
Master the Game: 7 Simple Steps to Financial Freedom

Master the Game: 7 Simple Steps to Financial Freedom

  1. Reading Reproducible Finance with R: Code Flows and Shiny Apps for Portfolio Analysis by Jonathan K. Regenstein who is Director of Finance Services at RStudio (http://www.reproduciblefinance.com/)
Reproducible Finance with R: Code Flows and Shiny Apps for Portfolio Analysis

Reproducible Finance with R: Code Flows and Shiny Apps for Portfolio Analysis

3 Introduction to my Personal Passion

3.1 Wealth Management Undergraduate Class

During my undergraduate wealth management class, I recall a significant time was spent covering core concepts like diversification, portfolio rebalancing and modern portfolio theory. Despite learning all the theory, one question that I could never answer was how much diversification is enough? Thus, I set an objective to use data science to help me find the optimal way to allocate my portfolio.

Using techniques gleaned from Matt Dancho’s Learning Lab 9 on Finance with R and the tidyquant package, I took on the challenge to create my personal investment portfolio.

Objective and Key Result

  • Objective: Determine an asset allocation for my personal investment portfolio

  • Key Result: Develop a model that consumes 5 securities based on Ray Dalio’s All Weather Fund guidance and then outputs the optimal asset allocation with periodic calibration of asset allocation going forward

3.2 Master the Game: 7 Simple Steps to Financial Freedom - Tony Robbin

“Look for something you love to do and do it well. Go for it. It will give you satisfaction in life. It could mean money, but it may not. It could mean titles, but it may not. But it will bring you satisfaction.” - Tony Robbins

In the world of finance and investing, it is a zero sum game where investors will exploit the advantages they have through skill or technology to make a return (like Flash Boys with HFT in US equity market). Investing in today’s market is similar to playing poker with the best players in the world who play around the clock and have nearly unlimited resources. As an amateur retail investor, timing the market is like playing a losing game. So I began to seek a solution beyond mutual funds and stock picking to satisfy my portfolio requirements.

In Tony Robbin’s book, he interviews multiple iconic investors to understand their asset allocation including David Swensen, Jack Bogle, Warren Buffet and Ray Dalio. In this book, I was first introduced to hedge fund manager Ray Dalio’s ‘All Seasons Portfolio’. In a nutshell, it was in response to a basic question that Ray Dalio was asked. “If I could pass on any information to my next generation who may or may not have as diverse of a financial literacy as Ray and can stand the test of time, what would it be?” For those who don’t know Ray, Ray Dalio is the founder of Bridgewater Associates, the “world’s largest hedge fund firm” and who predicted the 2008 financial crisis.

I sought to understand more about the All Seasons Portfolio by choosing index funds that fit within the portfolio allocation. Please read this article for more information: (https://www.iwillteachyoutoberich.com/blog/all-weather-portfolio/)

To illustrate, I have used the 5 index funds listed in the article mentioned above to start my analysis:

Breakdown of the All Seasons Portfolio

  1. 40% Long Term Bonds (TLT)

  2. 30% Stocks (VTI)

  3. 15% Intermediate Term Bonds (IEF)

  4. 7.5% Gold (GLD)

  5. 7.5% Commodities (DBC)

4 My Workflow

Here’s a breakdown of the workflow I used to create the All Seasons Portfolio:

  1. Import the data of the stock prices using tq_get from tidyquant

  2. Transform stock prices to returns using tq_transmute

  3. Building a portfolio based on the allocation of Ray Dalio’s All Weather Fund using tq_portfolio

  4. Visualize returns and sharpe ratio with ggplot2

  5. Visualize the investment growth of the portfolio based on a $10,000 investment

5 Walk through - Building the All Weather Fund portfolio with tidyquant

5.1 Import Data

Tq_get will grab the 30 years of daily stock prices from Yahoo Finance based on each symbol specified.

#1.0 IMPORT DATA ----
symbols <- c("VTI", "TLT", "IEF", "GLD", "DBC")
end <- "2019-06-30" %>% ymd()
start <- end - years(30) + days(1)

raw_data <- symbols %>% 
    tq_get(get = "stock.prices",
           from = start,
           to = end)

From the table, I understand each fund has a different origination date, which will affect the comparability of my financial return calculations. A closer look into the data, the earliest date with data from all funds is February 6, 2006.

raw_data %>% 
    group_by(symbol) %>% 
    summarise(min_date = min(date), 
              max_date = max(date))

5.2 Transform stock prices to returns

Tq_transmute will transform the retrieved stock prices into monthly returns using the “adjusted” stock prices.

# 2.0 TRANSFORM TO RETURNS ----
# normal returns
returns_reg_tbl <- raw_data %>% 
    select(symbol, date, adjusted) %>% 
    group_by(symbol) %>% 
    tq_transmute(select = adjusted,
                 mutate_fun = periodReturn,
                 period = "monthly") %>% 
    ungroup() %>% 

    #rollback to first day of the month - ETF Issue ----
    mutate(date = lubridate::rollback(date, roll_to_first = TRUE))

From the table, the last day in April 2006 is 28th yet there are 30 days in the month of April (perhaps due to the dividend date on the very last day of the month). This would cause downstream impacts when I attempt to union an individual security or benchmarked funds which can have the last day of April falling outside of April 28th. A quick fix to normalize the dates is the lubridate package. In this case, I have roll-backed the monthly returns to the first day of the month.

raw_data %>% 
    select(symbol, date, adjusted) %>% 
    group_by(symbol) %>% 
    tq_transmute(select = adjusted,
                 mutate_fun = periodReturn,
                 period = "monthly") %>% 
    ungroup() %>% 
    spread(symbol, monthly.returns) %>% 
    na.omit()

5.3 Evaluating each fund

5.3.1 Histogram of Returns

5.3.2 Time Series of Returns

5.3.3 Time Series of Stock Price

5.3.4 Sharpe Ratio

5.4 Building a portfolio based on the allocation of Ray Dalio’s All Weather Fund using tq_portfolio

This is a visual of the asset weighting in the portfolio.

tq_portfolio accepts a tibble with the stocks and asset weights, and aggregates a group of individual assets into a single return based on the weights specified. It will be rebalanced on a yearly basis.

returns_reg_date_tbl <- returns_reg_tbl %>% 
    group_by(symbol) %>% 
    filter(date >= "2006-02-01")

returns_port_tbl <- returns_reg_date_tbl %>% 
    tq_portfolio(assets_col = symbol,
                 returns_col = monthly.returns,
                 weights = wts_tbl,
                 rebalance_on = "years") %>% 
    add_column(symbol = "Portfolio", .before = 1) %>% 
    rename(monthly.returns = portfolio.returns)
end_port_date <- last(returns_port_tbl$date)

returns_port_tbl

5.5 Visualize the portfolio

5.5.1 Time Series of Returns

5.5.2 Comparison of Returns

5.5.3 Sharpe Ratio

5.5.4 Portfolio Growth

5.6 Putting it all together

This is the breakdown of asset allocation for the portfolio and individual securities assuming it was held on their own

w_2 <- c(0.3, 0.4, 0.15, 0.075, 0.075,
         1, 0, 0, 0, 0,
         0, 1, 0, 0, 0,
         0, 0, 1, 0, 0,
         0, 0, 0, 1, 0,
         0, 0, 0, 0, 1)

weights_tbl <- tibble(symbols) %>% 
    tq_repeat_df(n = 6) %>% 
    bind_cols(tibble(w_2)) %>% 
    group_by(portfolio) 

weights_tbl %>% 
    ungroup() %>% 
    mutate(w_2 = paste0(w_2*100, "%")) %>% 
    pivot_wider(names_from = symbols, values_from = w_2) %>% 
    mutate(portfolio = case_when(portfolio == 1 ~ "All Seasons Portfolio",
                                 portfolio == 2 ~ "VTI",
                                 portfolio == 3 ~ "TLT",
                                 portfolio == 4 ~ "IEF",
                                 portfolio == 5 ~ "GLD",
                                 portfolio == 6 ~ "DBC")) 

We apply tq_portfolio iteratively across the 6 portfolios to generate the investment growth returns based on a $10,000 investment.

returns_multi_reg_date_tbl <- returns_reg_date_tbl %>% 
    ungroup() %>% 
    tq_repeat_df(n = 6)

port_returns_investment_tbl <- returns_multi_reg_date_tbl %>% 
    tq_portfolio(assets_col = symbol,
                 returns_col = monthly.returns,
                 weights = weights_tbl,
                 wealth.index = TRUE) %>% 
    mutate(investment.growth = portfolio.wealthindex * 10000)

end_port_returns_investment_tbl <- last(port_returns_investment_tbl$date)

Takeaway: As seen previously, the All Seasons Portfolio has a higher sharpe ratio - for every unit of risk, there is a higher rate of return. If we are pursuing a risk parity portfolio allocation strategy, this would yield an optimal level of return at the targeted risk level.

This chart provides are more compelling illustration as an HTML where you can hover over the different points and see the tooltip change over time.

6 Parting Thoughts

It was really exciting to see the illustrations and analysis I could make from what I have learned so far in. I plan on writing a Part 2 to this post as I dig deeper into this portfolio by solving an optimization problem to determine the perfect asset weights.

If you want to learn more, I am currently in a three part course learning Data Science for Business. I have completed Business Science 101 course and close to completion of the Business Science 201 course and I will be signing up for the 102 Shiny Web Applications course.