Homework Week 3

Author

Lara

For February 16th 2023

library(tidyverse) 
── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
✔ ggplot2 3.4.0     ✔ purrr   1.0.1
✔ tibble  3.1.8     ✔ dplyr   1.1.0
✔ tidyr   1.3.0     ✔ stringr 1.5.0
✔ readr   2.1.3     ✔ forcats 1.0.0
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
# assign the url to `github_raw_csv_url`
github_raw_csv_url <- "https://raw.githubusercontent.com/t-emery/sais-susfin_data/main/datasets/blackrock_etf_screener_2022-08-30.csv"

blackrock_etf_data <- read_csv(github_raw_csv_url)
Rows: 393 Columns: 22
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (14): ticker, name, incept_date, net_assets_as_of, asset_class, sub_asse...
dbl  (8): gross_expense_ratio_percent, net_expense_ratio_percent, net_assets...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
blackrock_etf_data <- blackrock_etf_data |> 
   mutate(across(contains("date"), lubridate::mdy)) |>
   mutate(net_assets_usd_bn = net_assets_usd_mn/10^3) |>
   select(-net_assets_as_of)


blackrock_etf_data |> 
  summarize(across(where(is.character), n_distinct)) |>
    rename(msci_esg_rating = sustainability_characteristics_msci_esg_fund_ratings_msci_esg_fund_rating_aaa_ccc) |>
  pivot_longer(cols = everything()) |>
  arrange(value |> desc())
# A tibble: 12 × 2
   name                       value
   <chr>                      <int>
 1 ticker                       393
 2 name                         393
 3 name_wo_ishares_etf          393
 4 location                      41
 5 sub_asset_class               18
 6 region                         7
 7 msci_esg_rating                7
 8 asset_class                    5
 9 sustainable_classification     5
10 market                         3
11 investment_style               2
12 is_esg                         2
blackrock_etf_data |>
  select(market) |> 
  distinct()
# A tibble: 3 × 1
  market   
  <chr>    
1 Developed
2 Emerging 
3 Frontier 
It might be interesting to check whether the share of actively managed funds is bigger among ESG or regular funds to get an overview of the size of this industry.
net_assets_by_investment_style <- blackrock_etf_data |>
  group_by(is_esg, investment_style) |>
  summarise(total_assets_bn = sum(net_assets_usd_bn))
`summarise()` has grouped output by 'is_esg'. You can override using the
`.groups` argument.
ggplot(net_assets_by_investment_style, aes(x = investment_style, y=total_assets_bn)) + geom_col() +  facet_wrap(~is_esg, scales = "free_y") + labs(title = "Actively managed funds are slightly more common in the ESG world",
       x = "",
       y = "Net Assets in Billion", 
       caption = "Source: Blackrock Calculations by Lara") +
  theme_minimal()

Even though the share of actively managed funds is larger in the ESG sector, the net worth of regular funds that are actively managed is bigger in absolute terms.

  actively_managed_net_assets <- blackrock_etf_data |>
  filter(investment_style == "Active") |> 
  group_by(is_esg) |>
  summarise(total_assets_bn = sum(net_assets_usd_bn))


ggplot(actively_managed_net_assets, aes(x = is_esg, y=total_assets_bn)) + geom_col() +
  labs(title = "Active regular funds still lead in total assets managed",
       x = "",
       y = "Net Assets in Billion",
       caption = "Source: Blackrock | Calculations by Lara"
       ) +
 theme_minimal()

The following graphs explore two questions regarding the environmental, social, and governance (ESG) ratings and carbon intensity of funds across different markets. First, they examine which markets have the funds with the highest average ESG rating. Second, they compare the ESG rating and carbon intensity of ESG funds to non-ESG funds to assess their respective sustainability performances.
blackrock_etf_data <- blackrock_etf_data |>
rename(co2_intensity = msci_weighted_average_carbon_intensity_tons_co2e_m_sales, msci_esg_rating = sustainability_characteristics_msci_esg_fund_ratings_msci_esg_fund_rating_aaa_ccc)


drop_na_CO2_intensity <- blackrock_etf_data |>
  drop_na(co2_intensity)


ggplot(drop_na_CO2_intensity, aes(x = co2_intensity, y=net_assets_usd_bn, color = market)) + geom_point() +  facet_wrap(~is_esg) +
  labs(title = "Balckrocks' ESG Fund Portfolio", subtitle = str_wrap("Developed Markets, Low-Carbon Footprints, Small in AUM", width = 70),
       x = "CO2 intensity",
       y = "Net Assets in Billion",
       caption = "Source: Blackrock | Calculations by Lara"
       ) +
 theme_minimal()

Now create the same graph for the msci_esg_quality score
ggplot(blackrock_etf_data, aes(x = msci_esg_quality_score_0_10, y=net_assets_usd_bn, color = market)) + geom_point() +  facet_wrap(~is_esg) +
  labs(title = "Blackrock's ESG Portfolio",
       x = "MSCI ESG Quality Score",
       y = "Net Assets in Billion",
       caption = "Source: Blackrock | Calculations by Lara"
       ) +
 theme_minimal()
Warning: Removed 38 rows containing missing values (`geom_point()`).

There is an outlier in terms of asset size among the regular funds. To get a better idea of the distribution, I will exclude the outlier and look at the graphs without it.
blackrock_etf_data |>
  arrange(desc(net_assets_usd_bn))
# A tibble: 393 × 22
   ticker name  incept_d…¹ gross…² net_e…³ net_a…⁴ asset…⁵ sub_a…⁶ region market
   <chr>  <chr> <date>       <dbl>   <dbl>   <dbl> <chr>   <chr>   <chr>  <chr> 
 1 IVV    iSha… 2000-05-15    0.03    0.03 297663. Equity  Large … North… Devel…
 2 IEFA   iSha… 2012-10-18    0.07    0.07  84222. Equity  All Cap Global Devel…
 3 AGG    iSha… 2003-09-22    0.04    0.03  82344. Fixed … Multi … North… Devel…
 4 IJR    iSha… 2000-05-22    0.06    0.06  66533. Equity  Small … North… Devel…
 5 IEMG   iSha… 2012-10-18    0.09    0.09  64920. Equity  All Cap Global Emerg…
 6 IWF    iSha… 2000-05-22    0.18    0.18  61831. Equity  Large/… North… Devel…
 7 IJH    iSha… 2000-05-22    0.05    0.05  61424. Equity  Mid Cap North… Devel…
 8 IWM    iSha… 2000-05-22    0.19    0.19  53048. Equity  Small … North… Devel…
 9 IWD    iSha… 2000-05-22    0.18    0.18  51913. Equity  Large/… North… Devel…
10 EFA    iSha… 2001-08-14    0.32    0.32  44144. Equity  Large/… Global Devel…
# … with 383 more rows, 12 more variables: location <chr>,
#   investment_style <chr>, msci_esg_rating <chr>,
#   msci_esg_quality_score_0_10 <dbl>, co2_intensity <dbl>,
#   msci_esg_percent_coverage <dbl>, sustainable_classification <chr>,
#   name_wo_ishares_etf <chr>, is_esg <chr>, years_from_inception <dbl>,
#   year_launched <dbl>, net_assets_usd_bn <dbl>, and abbreviated variable
#   names ¹​incept_date, ²​gross_expense_ratio_percent, …
#outlier identified as iShares Core S&P 500 ETF, ticker IVV

blackrock_data_without_SP500ETF <- blackrock_etf_data |>
  filter(ticker != "IVV")

blackrock_data_without_SP500ETF
# A tibble: 392 × 22
   ticker name  incept_d…¹ gross…² net_e…³ net_a…⁴ asset…⁵ sub_a…⁶ region market
   <chr>  <chr> <date>       <dbl>   <dbl>   <dbl> <chr>   <chr>   <chr>  <chr> 
 1 IEFA   iSha… 2012-10-18    0.07    0.07  84222. Equity  All Cap Global Devel…
 2 AGG    iSha… 2003-09-22    0.04    0.03  82344. Fixed … Multi … North… Devel…
 3 IJR    iSha… 2000-05-22    0.06    0.06  66533. Equity  Small … North… Devel…
 4 IEMG   iSha… 2012-10-18    0.09    0.09  64920. Equity  All Cap Global Emerg…
 5 IWF    iSha… 2000-05-22    0.18    0.18  61831. Equity  Large/… North… Devel…
 6 IJH    iSha… 2000-05-22    0.05    0.05  61424. Equity  Mid Cap North… Devel…
 7 IWM    iSha… 2000-05-22    0.19    0.19  53048. Equity  Small … North… Devel…
 8 IWD    iSha… 2000-05-22    0.18    0.18  51913. Equity  Large/… North… Devel…
 9 EFA    iSha… 2001-08-14    0.32    0.32  44144. Equity  Large/… Global Devel…
10 ITOT   iSha… 2004-01-20    0.03    0.03  41075. Equity  All Cap North… Devel…
# … with 382 more rows, 12 more variables: location <chr>,
#   investment_style <chr>, msci_esg_rating <chr>,
#   msci_esg_quality_score_0_10 <dbl>, co2_intensity <dbl>,
#   msci_esg_percent_coverage <dbl>, sustainable_classification <chr>,
#   name_wo_ishares_etf <chr>, is_esg <chr>, years_from_inception <dbl>,
#   year_launched <dbl>, net_assets_usd_bn <dbl>, and abbreviated variable
#   names ¹​incept_date, ²​gross_expense_ratio_percent, …
# repeat the same two visualisations 

drop_na_CO2_intensity_without_SP500ETF <- blackrock_data_without_SP500ETF |>
  drop_na(co2_intensity)


ggplot(drop_na_CO2_intensity_without_SP500ETF, aes(x = co2_intensity, y=net_assets_usd_bn, color = market)) + geom_point() +  facet_wrap(~is_esg) +
  labs(title = "Balckrock's ESG Fund Portfolio", subtitle = str_wrap("Developed Markets, Low-Carbon Footprints, Small in AUM", width = 70),
       x = "CO2 intensity",
       y = "Net Assets in Billion",
       caption = "Source: Blackrock | Calculations by Lara"
       ) +
 theme_minimal()

ggplot(blackrock_data_without_SP500ETF, aes(x = msci_esg_quality_score_0_10, y=net_assets_usd_bn, color = market)) + geom_point() +  facet_wrap(~is_esg) +
  labs(title = "Blackrock's ESG Portfolio",
       x = "MSCI ESG Quality Score",
       y = "Net Assets in Billion",
       caption = "Source: Blackrock | Calculations by Lara"
       ) +
 theme_minimal()
Warning: Removed 38 rows containing missing values (`geom_point()`).

Based on the analysis of high-level indicators, the four preceding graphs indicate that Blackrock’s ESG funds could simply represent a subset of conventional funds with a focus on developed markets. There appears to be considerable overlap between funds that invest in developed countries and ESG funds.

Part 2: ETF comparison between the holdings of the largest ESG Funds and the largest Regular Fund

etf_comparison_data_github_url <- "https://raw.githubusercontent.com/t-emery/sais-susfin_data/main/datasets/etf_comparison-2022-10-03.csv"

etf_comparison <- read_csv(etf_comparison_data_github_url)
Rows: 537 Columns: 14
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (4): ticker, company_name, sector, esg_uw_ow
dbl (7): esg_etf, standard_etf, esg_tilt, esg_tilt_z_score, esg_tilt_rank, e...
lgl (3): in_esg_only, in_standard_only, in_on_index_only

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
I would first want to know how similar these ETF’s are in terms of ESG criteria. Since both represent the US - a developed economy - chances are high that ESG values are relatively good.
#how similar are they in terms of general holdings? 

esg_holdings <- etf_comparison |>
  filter(esg_etf > 0)

holdings_list_esg <- esg_holdings |>
  pull(ticker) |>
  as.list()

regular_holdings <-etf_comparison |>
  filter(standard_etf > 0)

holdings_list_regular <- regular_holdings |>
  pull(ticker) |>
  as.list()

library(ggvenn)
Lade nötiges Paket: grid
a <- list(`esg` = holdings_list_esg,
          `regular` = holdings_list_regular)

ggvenn(a, c("esg", "regular"))

okay, so this is clearly not a good graph to illustrate this. But the figures show that the regular ETF comprises almost all of the ESG holdings. Only 35 holdings are in the ESG Fund but not in the regular fund. Let’s make a ranking of the esg and regular holdings by sector to make this more clear:
#ranking of highest weigted esg companies 
top_10_esg_holdings <- esg_holdings |> 
slice_max(order_by = esg_etf, n = 10) 

top_10_esg_holdings |> 
  ggplot(aes(x = esg_etf, y = fct_reorder(.f = company_name, .x = esg_etf),
             fill = sector)) +
  geom_bar(stat = "identity") + 
  labs(title = "Top 10 companies in ESG ETF",
       x = "weight",
       y = "", )

 #do the same for the regular ETF 
 
 top_10_regular_holdings <- regular_holdings |> 
slice_max(order_by = standard_etf, n = 10) 

top_10_regular_holdings |> 
  ggplot(aes(x = standard_etf, y = fct_reorder(.f = company_name, .x = standard_etf),
             fill = sector)) +
  geom_bar(stat = "identity") + 
  labs(title = "Top 10 companies in regular ETF",
       x = "weight",
       y = "", )