# ============================================================
# EQUINOX: DAILY EXCEL -> CLEAN QUARTERLY TOTAL-RETURN SERIES
# Output:
# eqnx_q with columns:
# date_q, year, qtr, eqnx_close, dy_eqnx_ann, dy_eqnx_q,
# r_eqnx_price_log, r_eqnx_total_log, idx_eqnx_tr
# ============================================================
library(readxl)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr)
## Warning: package 'tidyr' was built under R version 4.4.3
library(lubridate)
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
library(stringr)
library(scales)
# ------------------------------------------------------------
# 1) FILE PATHS
# ------------------------------------------------------------
eqnx_price_file <- "/Users/lukavrtac/Faks - EF/IMB/Master thesis/Data/Stocks/EQNX daily return.xlsx"
eqnx_div_file <- "/Users/lukavrtac/Faks - EF/IMB/Master thesis/Data/Stocks/EQNX dividend yield.xlsx"
# If sheet names are not the first sheet, set them here
eqnx_price_sheet <- 1
eqnx_div_sheet <- 1
# ------------------------------------------------------------
# 2) IMPORT DAILY EQUINOX PRICE DATA
# Expected columns from Excel:
# Koda | Datum | Tečaj | Premik | Indeks | Količina | tisoč EUR
# ------------------------------------------------------------
eqnx_daily_raw <- read_excel(eqnx_price_file, sheet = eqnx_price_sheet)
# Inspect imported names if needed
print(names(eqnx_daily_raw))
## [1] "Koda" "Datum" "Tečaj" "Premik" "Indeks" "Količina"
## [7] "tisoč EUR"
# ------------------------------------------------------------
# 3) CLEAN DAILY DATA
# ------------------------------------------------------------
eqnx_daily <- eqnx_daily_raw %>%
rename_with(~ str_trim(.x)) %>%
rename(
code_raw = matches("^Koda$|^Code$", ignore.case = TRUE),
date_raw = matches("^Datum$|^Date$", ignore.case = TRUE),
price_raw = matches("^Tečaj$|^Tecaj$|^Price$|^Close$", ignore.case = TRUE)
) %>%
mutate(
date = suppressWarnings(as.Date(date_raw, format = "%d.%m.%y")),
date = if_else(is.na(date), as.Date(date_raw), date),
# SAFE numeric conversion:
# - if already numeric, keep it
# - if text with decimal comma, convert comma -> dot
eqnx_close_daily = case_when(
is.numeric(price_raw) ~ as.numeric(price_raw),
TRUE ~ as.numeric(str_replace_all(as.character(price_raw), ",", "."))
)
) %>%
filter(!is.na(date), !is.na(eqnx_close_daily)) %>%
arrange(date) %>%
distinct(date, .keep_all = TRUE) %>%
transmute(
code = as.character(code_raw),
date,
eqnx_close_daily
)
# ------------------------------------------------------------
# 4) COLLAPSE TO QUARTER-END CLOSES
# Keep the LAST available trading day in each quarter
# ------------------------------------------------------------
eqnx_q_price <- eqnx_daily %>%
mutate(
year = year(date),
qtr = quarter(date),
q_id = paste0(year, "Q", qtr)
) %>%
group_by(year, qtr, q_id) %>%
slice_tail(n = 1) %>%
ungroup() %>%
mutate(
date_q = ceiling_date(date, unit = "quarter") - days(1)
) %>%
select(q_id, date_q, year, qtr, eqnx_close = eqnx_close_daily)
# Quick check
eqnx_q_price
## # A tibble: 12 × 5
## q_id date_q year qtr eqnx_close
## <chr> <date> <dbl> <int> <dbl>
## 1 2022Q1 2022-03-31 2022 1 40.7
## 2 2022Q2 2022-06-30 2022 2 48
## 3 2022Q3 2022-09-30 2022 3 49.6
## 4 2022Q4 2022-12-31 2022 4 50
## 5 2023Q1 2023-03-31 2023 1 48.2
## 6 2023Q2 2023-06-30 2023 2 48.8
## 7 2023Q3 2023-09-30 2023 3 53
## 8 2023Q4 2023-12-31 2023 4 52.5
## 9 2024Q1 2024-03-31 2024 1 52.5
## 10 2024Q2 2024-06-30 2024 2 56.5
## 11 2024Q3 2024-09-30 2024 3 59
## 12 2024Q4 2024-12-31 2024 4 56.5
# ------------------------------------------------------------
# 5) IMPORT DIVIDEND YIELD DATA
# Expected columns:
# Year | DividendYield
# ------------------------------------------------------------
eqnx_div_raw <- read_excel(eqnx_div_file, sheet = eqnx_div_sheet)
print(names(eqnx_div_raw))
## [1] "Year" "Dividend Yield"
eqnx_div <- eqnx_div_raw %>%
rename_with(~ str_trim(.x)) %>%
rename(
year_raw = matches("^Year$|^Leto$", ignore.case = TRUE),
dy_raw = matches("^DividendYield$|^Dividend Yield$|^Dividenda$|^Dividendni donos$", ignore.case = TRUE)
) %>%
mutate(
year = as.integer(year_raw),
dy_chr = as.character(dy_raw),
dy_chr = str_replace_all(dy_chr, "\\.", ""),
dy_chr = str_replace_all(dy_chr, ",", "."),
dy_chr = str_replace_all(dy_chr, "%", ""),
dy_eqnx_ann = as.numeric(dy_chr) / 10000
) %>%
select(year, dy_eqnx_ann) %>%
filter(!is.na(year), !is.na(dy_eqnx_ann))
eqnx_div
## # A tibble: 3 × 2
## year dy_eqnx_ann
## <int> <dbl>
## 1 2022 0.0322
## 2 2023 0.0275
## 3 2024 0.0296
# ------------------------------------------------------------
# 6) MERGE QUARTER-END PRICES WITH ANNUAL DIVIDEND YIELD
# Quarterly DY = annual DY / 4
# ------------------------------------------------------------
eqnx_q <- eqnx_q_price %>%
left_join(eqnx_div, by = "year") %>%
mutate(
dy_eqnx_q = dy_eqnx_ann / 4
) %>%
arrange(date_q)
# ------------------------------------------------------------
# 7) COMPUTE QUARTERLY PRICE RETURN AND TOTAL RETURN
# Same convention as SBITOP in your thesis:
# total log return = log(P_t / P_{t-1}) + DY_ann/4
# ------------------------------------------------------------
eqnx_q <- eqnx_q %>%
mutate(
r_eqnx_price_log = log(eqnx_close / lag(eqnx_close)),
r_eqnx_total_log = r_eqnx_price_log + dy_eqnx_q
)
# ------------------------------------------------------------
# 8) BUILD REBASED TOTAL-RETURN INDEX (START = 100)
# ------------------------------------------------------------
eqnx_q <- eqnx_q %>%
mutate(
idx_eqnx_tr = 100 * exp(cumsum(replace_na(r_eqnx_total_log, 0)))
)
# ------------------------------------------------------------
# 9) FINAL OUTPUT
# ------------------------------------------------------------
eqnx_q
## # A tibble: 12 × 10
## q_id date_q year qtr eqnx_close dy_eqnx_ann dy_eqnx_q
## <chr> <date> <dbl> <int> <dbl> <dbl> <dbl>
## 1 2022Q1 2022-03-31 2022 1 40.7 0.0322 0.00805
## 2 2022Q2 2022-06-30 2022 2 48 0.0322 0.00805
## 3 2022Q3 2022-09-30 2022 3 49.6 0.0322 0.00805
## 4 2022Q4 2022-12-31 2022 4 50 0.0322 0.00805
## 5 2023Q1 2023-03-31 2023 1 48.2 0.0275 0.00688
## 6 2023Q2 2023-06-30 2023 2 48.8 0.0275 0.00688
## 7 2023Q3 2023-09-30 2023 3 53 0.0275 0.00688
## 8 2023Q4 2023-12-31 2023 4 52.5 0.0275 0.00688
## 9 2024Q1 2024-03-31 2024 1 52.5 0.0296 0.0074
## 10 2024Q2 2024-06-30 2024 2 56.5 0.0296 0.0074
## 11 2024Q3 2024-09-30 2024 3 59 0.0296 0.0074
## 12 2024Q4 2024-12-31 2024 4 56.5 0.0296 0.0074
## # ℹ 3 more variables: r_eqnx_price_log <dbl>, r_eqnx_total_log <dbl>,
## # idx_eqnx_tr <dbl>
# ============================================================
# 1) Load packages
# ============================================================
library(dplyr)
library(tidyr)
library(lubridate)
library(readr)
## Warning: package 'readr' was built under R version 4.4.3
##
## Attaching package: 'readr'
## The following object is masked from 'package:scales':
##
## col_factor
# ============================================================
# 2) Define path to your RDS folder
# Adjust only this path if needed
# ============================================================
rds_dir <- "/Users/lukavrtac/Faks - EF/IMB/Master thesis/Data/R ready/rds"
# ============================================================
# 3) Import master file and optional supporting files
# ============================================================
master <- readRDS(file.path(rds_dir, "master_q_levels.rds"))
# Optional, only if you will need them later in the Equinox case
costs_base <- readRDS(file.path(rds_dir, "costs_base.rds"))
eq_cgt <- readRDS(file.path(rds_dir, "eq_cgt_schedule.rds"))
# ============================================================
# 4) Basic checks
# ============================================================
glimpse(master)
## Rows: 60
## Columns: 15
## $ q_id <chr> "2010Q1", "2010Q2", "2010Q3", "2010Q4", "2011Q1"…
## $ date_q <date> 2010-03-31, 2010-06-30, 2010-09-30, 2010-12-31,…
## $ year <int> 2010, 2010, 2010, 2010, 2011, 2011, 2011, 2011, …
## $ qtr <int> 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, …
## $ hpi_si_eurostat <dbl> 117.41, 118.08, 116.53, 116.80, 122.24, 121.89, …
## $ hpi_si_surs_used <dbl> 118.15, 117.64, 117.23, 116.10, 119.29, 119.94, …
## $ hpi_lj_surs_used <dbl> 119.75, 119.41, 118.80, 122.17, 124.68, 125.93, …
## $ hpi_si_exlj_surs_used <dbl> 116.78, 116.17, 115.88, 112.38, 116.03, 116.29, …
## $ hicp_rent <dbl> 102.48, 101.58, 102.28, 101.72, 101.92, 101.56, …
## $ hicp_all <dbl> 93.18, 94.78, 93.93, 94.48, 95.38, 96.25, 96.05,…
## $ sbitop_close <dbl> 965.95, 880.02, 830.94, 850.35, 832.37, 742.29, …
## $ dy_eq_ann <dbl> 0.02579782, 0.02579782, 0.02579782, 0.02579782, …
## $ rf_log_q <dbl> 8.604179e-04, 8.856720e-04, 1.158545e-03, 1.5262…
## $ rf_simple_q <dbl> 8.607882e-04, 8.860644e-04, 1.159216e-03, 1.5274…
## $ rf_rate_ann_qavg_pct <dbl> 0.34410000, 0.35050000, 0.45343333, 0.59733333, …
names(master)
## [1] "q_id" "date_q" "year"
## [4] "qtr" "hpi_si_eurostat" "hpi_si_surs_used"
## [7] "hpi_lj_surs_used" "hpi_si_exlj_surs_used" "hicp_rent"
## [10] "hicp_all" "sbitop_close" "dy_eq_ann"
## [13] "rf_log_q" "rf_simple_q" "rf_rate_ann_qavg_pct"
master %>%
select(q_id, date_q, year, qtr, sbitop_close, dy_eq_ann, rf_log_q) %>%
print(n = 10)
## # A tibble: 60 × 7
## q_id date_q year qtr sbitop_close dy_eq_ann rf_log_q
## <chr> <date> <int> <int> <dbl> <dbl> <dbl>
## 1 2010Q1 2010-03-31 2010 1 966. 0.0258 0.000860
## 2 2010Q2 2010-06-30 2010 2 880. 0.0258 0.000886
## 3 2010Q3 2010-09-30 2010 3 831. 0.0258 0.00116
## 4 2010Q4 2010-12-31 2010 4 850. 0.0258 0.00153
## 5 2011Q1 2011-03-31 2011 1 832. 0.0323 0.00168
## 6 2011Q2 2011-06-30 2011 2 742. 0.0323 0.00263
## 7 2011Q3 2011-09-30 2011 3 619. 0.0323 0.00249
## 8 2011Q4 2011-12-31 2011 4 590. 0.0323 0.00202
## 9 2012Q1 2012-03-31 2012 1 599. 0.0360 0.000929
## 10 2012Q2 2012-06-30 2012 2 520. 0.0360 0.000854
## # ℹ 50 more rows
# ============================================================
# 5) Merge quarterly Equinox data onto master
# Assumes your Equinox quarterly object is called eqnx_q
# ============================================================
master_eqnx <- master %>%
left_join(
eqnx_q %>%
select(date_q, eqnx_close, dy_eqnx_ann, dy_eqnx_q, r_eqnx_price_log),
by = "date_q"
)
# Check merge result
master_eqnx %>%
select(q_id, date_q, eqnx_close, dy_eqnx_ann, dy_eqnx_q, r_eqnx_price_log) %>%
filter(!is.na(eqnx_close)) %>%
print(n = Inf)
## # A tibble: 12 × 6
## q_id date_q eqnx_close dy_eqnx_ann dy_eqnx_q r_eqnx_price_log
## <chr> <date> <dbl> <dbl> <dbl> <dbl>
## 1 2022Q1 2022-03-31 40.7 0.0322 0.00805 NA
## 2 2022Q2 2022-06-30 48 0.0322 0.00805 0.165
## 3 2022Q3 2022-09-30 49.6 0.0322 0.00805 0.0328
## 4 2022Q4 2022-12-31 50 0.0322 0.00805 0.00803
## 5 2023Q1 2023-03-31 48.2 0.0275 0.00688 -0.0367
## 6 2023Q2 2023-06-30 48.8 0.0275 0.00688 0.0124
## 7 2023Q3 2023-09-30 53 0.0275 0.00688 0.0826
## 8 2023Q4 2023-12-31 52.5 0.0275 0.00688 -0.00948
## 9 2024Q1 2024-03-31 52.5 0.0296 0.0074 0
## 10 2024Q2 2024-06-30 56.5 0.0296 0.0074 0.0734
## 11 2024Q3 2024-09-30 59 0.0296 0.0074 0.0433
## 12 2024Q4 2024-12-31 56.5 0.0296 0.0074 -0.0433
# ============================================================
# MERGE MASTER + EQUINOX, THEN RESTRICT TO RELEVANT SAMPLE
# Final Equinox analysis window: 2022Q2–2024Q4
# ============================================================
library(dplyr)
library(lubridate)
# 1) Clean master
master_clean <- master %>%
mutate(
date_q = as.Date(date_q),
q_id = paste0(year(date_q), "Q", quarter(date_q))
)
# 2) Clean Equinox quarterly data
# IMPORTANT:
# - keep dy_eqnx_ann in DECIMAL form
# - if your current dy_eqnx_ann is still 3.22, 2.75, 2.96, divide by 100
eqnx_q_clean <- eqnx_q %>%
mutate(
date_q = as.Date(date_q),
q_id = paste0(year(date_q), "Q", quarter(date_q)),
dy_eqnx_ann = ifelse(dy_eqnx_ann > 1, dy_eqnx_ann / 100, dy_eqnx_ann),
dy_eqnx_q = dy_eqnx_ann / 4
) %>%
select(q_id, date_q, eqnx_close, dy_eqnx_ann, dy_eqnx_q, r_eqnx_price_log)
# 3) Merge onto full master
master_eqnx_full <- master_clean %>%
left_join(
eqnx_q_clean %>%
select(q_id, eqnx_close, dy_eqnx_ann, dy_eqnx_q, r_eqnx_price_log),
by = "q_id"
) %>%
arrange(date_q)
# 4) Build Equinox total return log series
master_eqnx_full <- master_eqnx_full %>%
mutate(
r_eqnx_total_log = r_eqnx_price_log + dy_eqnx_q
)
# 5) Restrict to Equinox-relevant analysis sample only
# Start at 2022Q2 because 2022Q1 has no valid price return yet
master_eqnx <- master_eqnx_full %>%
filter(date_q >= as.Date("2022-06-30"),
date_q <= as.Date("2024-12-31")) %>%
arrange(date_q)
# 6) Check result
master_eqnx %>%
select(q_id, date_q, eqnx_close, dy_eqnx_ann, dy_eqnx_q,
r_eqnx_price_log, r_eqnx_total_log) %>%
print(n = Inf)
## # A tibble: 11 × 7
## q_id date_q eqnx_close dy_eqnx_ann dy_eqnx_q r_eqnx_price_log
## <chr> <date> <dbl> <dbl> <dbl> <dbl>
## 1 2022Q2 2022-06-30 48 0.0322 0.00805 0.165
## 2 2022Q3 2022-09-30 49.6 0.0322 0.00805 0.0328
## 3 2022Q4 2022-12-31 50 0.0322 0.00805 0.00803
## 4 2023Q1 2023-03-31 48.2 0.0275 0.00688 -0.0367
## 5 2023Q2 2023-06-30 48.8 0.0275 0.00688 0.0124
## 6 2023Q3 2023-09-30 53 0.0275 0.00688 0.0826
## 7 2023Q4 2023-12-31 52.5 0.0275 0.00688 -0.00948
## 8 2024Q1 2024-03-31 52.5 0.0296 0.0074 0
## 9 2024Q2 2024-06-30 56.5 0.0296 0.0074 0.0734
## 10 2024Q3 2024-09-30 59 0.0296 0.0074 0.0433
## 11 2024Q4 2024-12-31 56.5 0.0296 0.0074 -0.0433
## # ℹ 1 more variable: r_eqnx_total_log <dbl>
# ============================================================
# FIGURE 22: Equinox case
# Panel 1: Common-sample total return wealth indices (base = 100)
# Panel 2: Common-sample drawdowns from peak
# - Common sample: 2022Q2 to 2024Q4
# - Years only on x-axis
# - Same thesis style as previous figures
# ============================================================
library(dplyr)
library(tidyr)
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
library(scales)
library(patchwork)
library(zoo)
## Warning: package 'zoo' was built under R version 4.4.3
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
# ------------------------------------------------------------
# 0) Thesis theme (reuse your existing one if already defined)
# ------------------------------------------------------------
theme_thesis <- function() {
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 10.5, color = "grey30"),
legend.position = "bottom",
legend.title = element_blank(),
legend.text = element_text(size = 9.5),
legend.key.width = unit(14, "pt"),
legend.spacing.x = unit(6, "pt"),
legend.box.margin = margin(t = 8),
plot.margin = margin(t = 10, r = 10, b = 10, l = 10),
panel.grid.minor = element_blank()
)
}
# ------------------------------------------------------------
# 1) Safety checks
# master_eqnx must already contain:
# date_q, eqnx_close, dy_eqnx_q
# and either:
# r_eq_total_log, r_re_eu_total_log
# or the raw ingredients to construct them
# ------------------------------------------------------------
req_cols_direct <- c("date_q", "eqnx_close", "dy_eqnx_q", "r_eq_total_log", "r_re_eu_total_log")
has_direct <- all(req_cols_direct %in% names(master_eqnx))
req_cols_raw <- c("date_q", "eqnx_close", "dy_eqnx_q", "sbitop_close", "dy_eq_ann", "hpi_si_eurostat", "hicp_rent")
has_raw <- all(req_cols_raw %in% names(master_eqnx))
if (!has_direct && !has_raw) {
stop("master_eqnx must contain either direct return columns (r_eq_total_log, r_re_eu_total_log) or the raw inputs needed to construct them.")
}
# ------------------------------------------------------------
# 2) Build working dataset
# ------------------------------------------------------------
if (has_direct) {
work <- master_eqnx %>%
arrange(date_q) %>%
mutate(
r_eqnx_price_log = log(eqnx_close / lag(eqnx_close)),
r_eqnx_total_log = r_eqnx_price_log + dy_eqnx_q
) %>%
select(date_q, r_eq_total_log, r_re_eu_total_log, r_eqnx_total_log)
} else {
# Construct equity and RE returns from raw inputs
y0_ann <- 0.04
base_anchor <- master_eqnx %>%
arrange(date_q) %>%
filter(!is.na(hicp_rent), !is.na(hpi_si_eurostat)) %>%
slice(1)
R0 <- base_anchor$hicp_rent
He0 <- base_anchor$hpi_si_eurostat
work <- master_eqnx %>%
arrange(date_q) %>%
mutate(
# SBITOP total return
dy_eq_q = dy_eq_ann / 4,
r_eq_price_log = log(sbitop_close / lag(sbitop_close)),
r_eq_total_log = r_eq_price_log + dy_eq_q,
# Eurostat RE total return
r_re_eu_price_log = log(hpi_si_eurostat / lag(hpi_si_eurostat)),
y_eu_t = y0_ann * ((hicp_rent / R0) / (hpi_si_eurostat / He0)),
r_re_eu_income_q = lag(y_eu_t) / 4,
r_re_eu_total_log = r_re_eu_price_log + r_re_eu_income_q,
# Equinox total return
r_eqnx_price_log = log(eqnx_close / lag(eqnx_close)),
r_eqnx_total_log = r_eqnx_price_log + dy_eqnx_q
) %>%
select(date_q, r_eq_total_log, r_re_eu_total_log, r_eqnx_total_log)
}
# ------------------------------------------------------------
# 3) Restrict to common sample and complete cases
# ------------------------------------------------------------
plot_df <- work %>%
filter(date_q >= as.Date("2022-06-30"),
date_q <= as.Date("2024-12-31")) %>%
filter(
!is.na(r_eq_total_log),
!is.na(r_re_eu_total_log),
!is.na(r_eqnx_total_log)
) %>%
arrange(date_q)
if (nrow(plot_df) < 4) {
stop("Too few complete quarterly observations in the common sample.")
}
# ------------------------------------------------------------
# 4) Build wealth indices
# ------------------------------------------------------------
to_wealth <- function(r_log) {
100 * exp(cumsum(replace_na(r_log, 0)))
}
wealth_df <- plot_df %>%
mutate(
w_eqnx = to_wealth(r_eqnx_total_log),
w_eq = to_wealth(r_eq_total_log),
w_re = to_wealth(r_re_eu_total_log)
) %>%
select(date_q, w_eqnx, w_eq, w_re) %>%
pivot_longer(-date_q, names_to = "series", values_to = "wealth") %>%
mutate(
series = recode(series,
w_eqnx = "Equinox",
w_eq = "Equities: SBITOP",
w_re = "Real estate: Slovenia (Eurostat)"
),
series = factor(series, levels = c("Equinox", "Equities: SBITOP", "Real estate: Slovenia (Eurostat)"))
)
# ------------------------------------------------------------
# 5) Build drawdowns
# ------------------------------------------------------------
to_drawdown <- function(w) {
w / cummax(w) - 1
}
drawdown_df <- plot_df %>%
mutate(
w_eqnx = to_wealth(r_eqnx_total_log),
w_eq = to_wealth(r_eq_total_log),
w_re = to_wealth(r_re_eu_total_log),
dd_eqnx = to_drawdown(w_eqnx),
dd_eq = to_drawdown(w_eq),
dd_re = to_drawdown(w_re)
) %>%
select(date_q, dd_eqnx, dd_eq, dd_re) %>%
pivot_longer(-date_q, names_to = "series", values_to = "drawdown") %>%
mutate(
series = recode(series,
dd_eqnx = "Equinox",
dd_eq = "Equities: SBITOP",
dd_re = "Real estate: Slovenia (Eurostat)"
),
series = factor(series, levels = c("Equinox", "Equities: SBITOP", "Real estate: Slovenia (Eurostat)"))
)
# ------------------------------------------------------------
# 6) Styling
# ------------------------------------------------------------
COL_EQNX <- c(
"Equinox" = "#222222",
"Equities: SBITOP" = "#F8766D",
"Real estate: Slovenia (Eurostat)" = "#B79F00"
)
LT_EQNX <- c(
"Equinox" = "solid",
"Equities: SBITOP" = "solid",
"Real estate: Slovenia (Eurostat)" = "dashed"
)
# ------------------------------------------------------------
# 7) Panel A: Wealth indices
# ------------------------------------------------------------
p6_1a <- ggplot(wealth_df, aes(x = date_q, y = wealth, color = series, linetype = series)) +
geom_line(linewidth = 1.05) +
scale_color_manual(values = COL_EQNX) +
scale_linetype_manual(values = LT_EQNX) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
scale_y_continuous(labels = label_number(accuracy = 1)) +
labs(
subtitle = "Panel 1: Common-sample total return wealth indices (base = 100)",
x = NULL,
y = "Wealth index"
) +
theme_thesis() +
guides(
color = guide_legend(nrow = 1, byrow = TRUE),
linetype = "none"
)
# ------------------------------------------------------------
# 8) Panel B: Drawdowns
# ------------------------------------------------------------
p6_1b <- ggplot(drawdown_df, aes(x = date_q, y = drawdown, color = series, linetype = series)) +
geom_hline(yintercept = 0, linewidth = 0.4, color = "grey60") +
geom_line(linewidth = 1.05) +
scale_color_manual(values = COL_EQNX) +
scale_linetype_manual(values = LT_EQNX) +
scale_x_date(date_breaks = "1 year", date_labels = "%Y") +
scale_y_continuous(labels = percent_format(accuracy = 1)) +
labs(
subtitle = "Panel 2: Common-sample drawdowns from peak",
x = NULL,
y = "Drawdown from peak"
) +
theme_thesis() +
guides(
color = guide_legend(nrow = 1, byrow = TRUE),
linetype = "none"
)
# ------------------------------------------------------------
# 9) Combine
# ------------------------------------------------------------
p6_1 <- p6_1a / p6_1b +
plot_layout(heights = c(2, 1))
p6_1

ggsave(
filename = "Figure_6_1_Equinox_case_two_panel.png",
plot = p6_1,
width = 12,
height = 8.8,
dpi = 300,
limitsize = FALSE
)