library(tidyverse)
library(lubridate)
library(scales)
library(ggrepel)
library(tidyquant)
library(jsonlite)
theme_set(theme_minimal())
invisible(Sys.setlocale("LC_TIME", "en_US.UTF-8"))
Immo Funds
library(familyoffice)
sixfunds <- familyoffice::fo_exchange("six.mutual")
immofunds <- sixfunds |>
filter(AssetClassDesc == "Real Estate",
UnderlyingGeographicalDesc == "Switzerland",
TradingBaseCurrency == "CHF", FundCurrency == "CHF") |>
select(FundLongName, ValorSymbol, ValorNumber, ISIN, IssuerNameFull, ManagementFee)
immofunds |>
write_csv("immofunds/immofunds.csv")
immofunds <- read_csv("immofunds/immofunds.csv")
get_swiss_fund_data <- function(id) {
url <- paste0("https://www.swissfunddata.ch/sfdpub/de/funds/excelData/", id)
temp <- tempfile(fileext = ".csv")
# handle error if file not there or some other error when downloading
tryCatch(download.file(url, temp, mode = "wb"), error = function(e) return(NULL))
if (file.exists(temp)) {
data <- read_csv2(temp, skip = 2, col_types = cols(.default = col_character()))
return(data)
} else {
return(NULL)
}
}
immofunds_pricedata <- immofunds |>
mutate(data = map(SwissFundData, get_swiss_fund_data))
library(familyoffice)
immofunds_pricedata_six <- immofunds_pricedata |>
mutate(sixdata = map(ISIN, fo_get)) |>
select(-data)
immofunds_pricedata |>
saveRDS("immofunds/immofunds_pricedata.RDS")
immofunds_pricedata_six |>
saveRDS("immofunds/immofunds_pricedata_six.RDS")
immofunds_pricedata <- readRDS("immofunds/immofunds_pricedata.RDS")
immofunds_pricedata_six <- readRDS("immofunds/immofunds_pricedata_six.RDS")
nav <- immofunds_pricedata |>
unnest(data) |>
transmute(FundLongName, ValorSymbol, ValorNumber, ISIN, IssuerNameFull,
Date = ymd(Date),
`Net Asset Value` = as.numeric(`Net Asset Value`)) |>
filter(!is.na(`Net Asset Value`))
prices <- immofunds_pricedata_six |>
unnest(sixdata) |>
transmute(ValorNumber,
date,
close)
df <- full_join(nav, prices,
by = c("ValorNumber" = "ValorNumber", "Date" = "date")) |>
arrange(FundLongName, ISIN, Date) |>
group_by(FundLongName) |>
mutate(close = na.locf0(close),
`Net Asset Value` = na.locf0(`Net Asset Value`)) |>
mutate(Agio = close/`Net Asset Value` - 1) |>
slice_max(Date)
df |>
filter(!is.na(Agio)) |>
ggplot(aes(x = reorder(FundLongName, Agio), y = Agio)) +
geom_col() +
geom_text_repel(aes(label = scales::percent(Agio, accuracy = 0.01)), nudge_y = 0.01) +
coord_flip() +
labs(title = "Swiss Immo Funds Agio",
x = "Fund",
y = "Agio") +
theme(axis.text.y = element_text(size = 8))

Tax exemption?
url <- "https://www.ictax.admin.ch/extern/de.html#/security/CH0118768057/20231231"
# download page to temp first then read with rvest
temp <- tempfile(fileext = ".html")
# pretend to be a browser
download.file(url, temp, mode = "wb", headers = c("User-Agent" = "Mozilla/5.0"))
page <- read_html(temp)
page |> html_text() |> cat()