# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

Visualize and examine changes in the underlying trend in the performance of your portfolio in terms of Sharpe Ratio.

Choose your stocks.

from 2012-12-31 to present

1 Import stock prices

symbols <- c("JPM", "MS", "DNB.OL", "NDA-FI.HE")

prices <- tq_get(x    = symbols, 
                 get  = "stock.prices", 
                 from = "2017-01-01", 
                 to   = "2023-12-31") %>%
          filter(!is.na(close)) 

2 Convert prices to returns (monthly)

asset_returns_tbl <-prices %>%
    
    group_by(symbol) %>%
    
    tq_transmute(select     = adjusted, 
                 mutate_fun = periodReturn, 
                 period     = "quarterly",
                 type = "log") %>%
    ungroup() %>%
    
    set_names(c("asset", "date", "returns"))
asset_returns_tbl
## # A tibble: 112 × 3
##    asset date       returns
##    <chr> <date>       <dbl>
##  1 JPM   2017-03-31  0.0125
##  2 JPM   2017-06-30  0.0455
##  3 JPM   2017-09-29  0.0495
##  4 JPM   2017-12-29  0.119 
##  5 JPM   2018-03-29  0.0331
##  6 JPM   2018-06-29 -0.0488
##  7 JPM   2018-09-28  0.0851
##  8 JPM   2018-12-31 -0.138 
##  9 JPM   2019-03-29  0.0444
## 10 JPM   2019-06-28  0.107 
## # ℹ 102 more rows

3 Assign a weight to each asset (change the weigting scheme)

symbols <- asset_returns_tbl %>% distinct(asset) %>% pull()
symbols
## [1] "JPM"       "MS"        "DNB.OL"    "NDA-FI.HE"
#weights 
weights <- c(0.25, 0.25, 0.25, 0.25)
weights
## [1] 0.25 0.25 0.25 0.25
w_tbl <- tibble(symbols, weights)
w_tbl
## # A tibble: 4 × 2
##   symbols   weights
##   <chr>       <dbl>
## 1 JPM          0.25
## 2 MS           0.25
## 3 DNB.OL       0.25
## 4 NDA-FI.HE    0.25

4 Build a portfolio

portfolio_returns_tbl <- asset_returns_tbl %>%
    
    tq_portfolio(assets_col   = asset, 
                 returns_col  = returns,
                 weights      = w_tbl, 
                 rebalance_on = "months")

portfolio_returns_tbl
## # A tibble: 33 × 2
##    date       portfolio.returns
##    <date>                 <dbl>
##  1 2017-03-31         0.0324   
##  2 2017-06-30         0.0531   
##  3 2017-09-29         0.0704   
##  4 2017-12-29         0.00773  
##  5 2018-03-28         0.0000821
##  6 2018-03-29        -0.00540  
##  7 2018-06-29        -0.0306   
##  8 2018-09-28         0.0706   
##  9 2018-12-28        -0.119    
## 10 2018-12-31        -0.0829   
## # ℹ 23 more rows

5 Compute Sharpe Ratio

# Risk free rate
rfr <- 0.0003

portfolio_sharpe_tbl <- portfolio_returns_tbl %>%

    tq_performance(Ra = portfolio.returns,
                   Rf = rfr,
                   performance_fun = SharpeRatio,
                   FUN = "StdDev") 

portfolio_sharpe_tbl
## # A tibble: 1 × 1
##   `StdDevSharpe(Rf=0%,p=95%)`
##                         <dbl>
## 1                       0.227

6 Plot: Rolling Sharpe Ratio

calculate_rolling_sharpeRatio <- function(df) {

    SharpeRatio(df,
                Rf = rfr,
                FUN = "StdDev")

}

window <- 24

# Calculate rolling sharpe ratios
rolling_sharpe_tbl <- portfolio_returns_tbl %>%

    tq_mutate(select = portfolio.returns,
              mutate_fun = rollapply,
              width = window,
              align = "right",
              FUN = calculate_rolling_sharpeRatio,
              col_rename = "sharpeRatio") %>%
    na.omit()

rolling_sharpe_tbl
## # A tibble: 10 × 3
##    date       portfolio.returns sharpeRatio
##    <date>                 <dbl>       <dbl>
##  1 2021-12-30           0.0202       0.242 
##  2 2021-12-31          -0.00283      0.229 
##  3 2022-03-31          -0.0827       0.174 
##  4 2022-06-30          -0.124        0.0996
##  5 2022-09-30           0.00184      0.0974
##  6 2022-12-30           0.147        0.146 
##  7 2023-03-31           0.0108       0.152 
##  8 2023-06-30           0.0622       0.185 
##  9 2023-09-29           0.0210       0.168 
## 10 2023-12-29           0.0980       0.251
# Figure 7.5 Rolling Sharpe ggplot ----

rolling_sharpe_tbl %>%

    ggplot(aes(date, sharpeRatio)) +
    geom_line(color = "cornflowerblue") +

    labs(title = paste0("Rolling ", window, "-Month Sharpe Ratio"),
         y = "rolling Sharpe Ratio",
         x = NULL) +
    theme(plot.title = element_text(hjust = 0.5)) +

    annotate(geom = "text",
             x = as.Date("2022-06-01"), y = 0.4,
             label = "This portfolio has shown notable\nfluctuation since 2022",
             size = 5, color = "red")

How has your portfolio performed over time? Provide dates of the structural breaks, if any. The Code Along Assignment 9 had one structural break in November 2016. What do you think the reason is?

Based on the rolling Sharpe Ratio chart, my portfolio’s performance has shown notable fluctuations over time. A key structural break appears around mid-2022, where the Sharpe Ratio declines sharply, indicating a period of reduced risk-adjusted returns. Another structural break is visible in early 2023, as the Sharpe Ratio begins a steady upward trend that continues through to early 2024.

The decline in mid-2022 could be partially attributed to the lingering effects of the COVID-19 pandemic. Global economic disruptions, market volatility, and heightened uncertainty likely impacted returns during this period. Additionally, factors like interest rate hikes and inflation concerns may have added to the volatility without compensating returnsThe recovery beginning in early 2023 aligns with a general market rebound, as the economy adjusted post-pandemic.