library(tidyquant)         
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
## ── Attaching core tidyquant packages ─────────────────────── tidyquant 1.0.11 ──
## ✔ PerformanceAnalytics 2.0.8      ✔ TTR                  0.24.4
## ✔ quantmod             0.4.27     ✔ xts                  0.14.1
## ── Conflicts ────────────────────────────────────────── tidyquant_conflicts() ──
## ✖ zoo::as.Date()                 masks base::as.Date()
## ✖ zoo::as.Date.numeric()         masks base::as.Date.numeric()
## ✖ PerformanceAnalytics::legend() masks graphics::legend()
## ✖ quantmod::summary()            masks base::summary()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(timetk)            
## 
## Attaching package: 'timetk'
## 
## The following object is masked from 'package:tidyquant':
## 
##     FANG
library(tidyverse)         
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::first()  masks xts::first()
## ✖ dplyr::lag()    masks stats::lag()
## ✖ dplyr::last()   masks xts::last()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(PerformanceAnalytics) 
library(quadprog)
library(tseries) 
library(zoo)     
library(xts)     
library(quantmod)
library(ggplot2) 
library(reshape2)
## 
## Attaching package: 'reshape2'
## 
## The following object is masked from 'package:tidyr':
## 
##     smiths
library(corrplot)
## corrplot 0.95 loaded

Getting data - 20 stocks from 4 industries: Technology, Automotive, Financial, Helathcare + 1 commodity (gold), 1 crypto (Bitcoin), 1 ESG ETF (ESGU) and S&P 500 index ETF (SPY)

library(tidyquant)

tickers <- c("AAPL", "MSFT", "GOOGL", "AMZN", "NVDA",       # Tech
             "TSLA", "F", "GM", "APTV", "BWA",              # Automotive
             "JPM", "BAC", "WFC", "GS", "MS",               # Financials
             "JNJ", "PFE", "MRK", "ABBV", "UNH",            # Healthcare
             "GLD", "BTC-USD", "ESGU", "SPY")               # Commodity, Crypto, ESG, Market Index

prices <- tq_get(
  tickers,
  from = "2020-01-01",
  to = "2025-01-01",
  get = "stock.prices",
  periodicity = "weekly"
)
library(tidyr)
library(dplyr)

prices_wide <- prices %>%
  select(date, symbol, adjusted) %>%
  pivot_wider(names_from = symbol, values_from = adjusted) %>%
  arrange(date)

Getting Risk free rate data

library(quantmod)

# Getting 1-month T-Bill from FRED
getSymbols("DGS1MO", src = "FRED")
## [1] "DGS1MO"
rf_weekly <- mean(DGS1MO, na.rm = TRUE) / 100 / 52  # decimal, weeklyized
rf_annual <- mean(DGS1MO, na.rm = TRUE) / 100  # Convert to decimal and annualize
library(knitr)

rf_table <- data.frame(
  Frequency = c("Weekly", "Annual"),
  Risk_Free_Rate = c(rf_weekly, rf_annual)
)

kable(rf_table, digits = 6, caption = "Risk-Free Rate (Weekly vs. Annual)")
Risk-Free Rate (Weekly vs. Annual)
Frequency Risk_Free_Rate
Weekly 0.000307
Annual 0.015962

Calculate weekly log returns and annualized returns

library(dplyr)
library(lubridate)
library(knitr)

# Compute weekly log returns
weekly_returns <- prices_wide %>%
  mutate(date = as.Date(date)) %>%
  arrange(date) %>%
  mutate(across(-date, ~ log(. / lag(.)))) %>%
  mutate(year = year(date)) %>%
  na.omit()

# Compute annual log returns by summing weekly returns
annual_log_returns <- weekly_returns %>%
  group_by(year) %>%
  summarize(across(where(is.numeric), sum, .names = "{.col}")) %>%
  ungroup()

# Show table
kable(annual_log_returns, caption = "Annual Log Returns", digits = 4)
Annual Log Returns
year AAPL MSFT GOOGL AMZN NVDA TSLA F GM APTV BWA JPM BAC WFC GS MS JNJ PFE MRK ABBV UNH GLD BTC-USD ESGU SPY
2020 0.5718 0.3346 0.2209 0.5235 0.8058 2.0587 -0.0502 0.1820 0.3829 -0.0662 -0.0426 -0.1081 -0.5057 0.1640 0.3406 0.1150 0.0515 -0.0639 0.2346 0.1901 0.2118 1.4264 0.1932 0.1588
2021 0.3222 0.4204 0.5066 0.0402 0.7825 0.4471 1.0384 0.4562 0.2554 0.2221 0.3143 0.4802 0.5604 0.4255 0.4293 0.1023 0.4211 0.0308 0.2852 0.3672 -0.0755 0.3003 0.2477 0.2648
2022 -0.3566 -0.3079 -0.4826 -0.6689 -0.7150 -1.2655 -0.7009 -0.6602 -0.6167 -0.1573 -0.1857 -0.3361 -0.2097 -0.1369 -0.1612 0.0667 -0.0299 0.3985 0.2217 0.0677 0.0087 -1.0122 -0.2334 -0.2102
2023 0.4005 0.4458 0.4385 0.5579 1.2138 0.8321 0.1401 0.0745 -0.0304 0.0267 0.2712 0.0422 0.1967 0.1459 0.1292 -0.0780 -0.5004 0.0463 0.0237 0.0541 0.1088 0.9915 0.2263 0.2311
2024 0.3042 0.1354 0.3185 0.3807 1.0256 0.4859 -0.1380 0.4008 -0.3994 -0.1096 0.3551 0.2848 0.3795 0.4124 0.3276 -0.0697 -0.0545 -0.1026 0.1420 -0.0486 0.2387 0.7315 0.2245 0.2278
kable(weekly_returns, caption = "Weekly Log Returns", digits = 4)
Weekly Log Returns
date AAPL MSFT GOOGL AMZN NVDA TSLA F GM APTV BWA JPM BAC WFC GS MS JNJ PFE MRK ABBV UNH GLD BTC-USD ESGU SPY year
2020-01-08 0.0468 0.0285 0.0251 -0.0198 0.0302 0.1370 0.0043 0.0000 -0.0242 -0.0169 0.0277 0.0200 -0.0659 0.0423 0.0374 0.0106 0.0335 0.0082 -0.0078 -0.0054 -0.0155 0.0782 0.0168 0.0145 2020
2020-01-15 0.0124 0.0266 0.0355 0.0120 0.0027 0.0171 -0.0086 -0.0046 0.0221 -0.0299 -0.0142 -0.0305 -0.0073 0.0002 0.0563 0.0186 0.0067 0.0004 0.0110 0.0418 0.0072 -0.0093 0.0124 0.0117 2020
2020-01-22 0.0035 -0.0063 -0.0217 -0.0207 0.0001 0.0354 -0.0264 -0.0393 -0.0151 -0.1337 -0.0178 -0.0302 -0.0326 -0.0128 -0.0346 0.0015 -0.0561 -0.0422 -0.0491 -0.0500 0.0063 0.0677 -0.0117 -0.0134 2020
2020-01-29 0.0036 0.0849 -0.0035 0.1007 -0.0034 0.4477 0.0231 0.0215 0.0097 -0.0286 0.0064 0.0114 -0.0023 -0.0026 0.0000 0.0139 -0.0119 0.0242 0.0070 -0.0178 -0.0084 -0.0192 0.0101 0.0066 2020
2020-02-05 0.0024 0.0237 0.0438 0.0482 0.0807 -0.1358 -0.1083 0.0184 0.0055 -0.0093 0.0198 0.0336 0.0153 -0.0229 0.0386 0.0026 0.0207 -0.0358 0.1293 0.0348 0.0084 0.1061 0.0170 0.0187 2020
2020-02-12 0.0005 0.0150 0.0062 0.0023 0.1017 0.1030 -0.0050 -0.0173 -0.0309 0.0067 -0.0172 -0.0145 -0.0104 -0.0138 -0.0047 -0.0189 -0.0476 -0.0333 -0.0252 0.0383 0.0218 -0.0065 0.0048 0.0044 2020
2020-02-19 -0.1020 -0.1080 -0.0917 -0.0887 -0.1237 -0.0706 -0.1087 -0.0805 -0.0818 -0.1098 -0.0717 -0.0977 -0.0406 -0.0692 -0.1449 -0.0306 -0.0681 -0.0269 -0.0485 -0.1373 0.0157 -0.0822 -0.0735 -0.0742 2020
2020-02-26 0.0043 -0.0187 -0.0357 -0.0328 0.0145 -0.0704 -0.0366 -0.0395 -0.0067 0.0152 -0.0765 -0.1133 -0.1073 -0.0674 -0.0786 -0.0583 0.0108 -0.0143 -0.0182 -0.0076 0.0038 -0.0611 -0.0401 -0.0405 2020
2020-03-04 -0.0139 -0.0221 -0.0479 -0.0090 -0.0177 -0.1443 -0.1074 -0.1181 -0.1009 -0.1115 -0.1497 -0.1616 -0.1444 -0.0924 -0.1169 0.0437 0.0084 0.0359 -0.0005 0.0687 0.0038 -0.1053 -0.0424 -0.0402 2020
2020-03-11 -0.1208 -0.0934 -0.1315 -0.0454 -0.1837 -0.4055 -0.2227 -0.2765 -0.4106 -0.2205 -0.0714 -0.0652 -0.1688 -0.1500 -0.1561 -0.0363 -0.0728 -0.0964 -0.1812 -0.1367 -0.0733 -0.4145 -0.1246 -0.1318 2020
2020-03-18 -0.0239 0.0120 0.0106 0.0706 0.1370 0.1603 -0.0120 0.0381 0.0247 0.0222 -0.0585 -0.0442 -0.0243 -0.0325 -0.0170 -0.1363 -0.0796 -0.0675 -0.0788 -0.1010 0.0663 0.2537 -0.0354 -0.0389 2020
2020-03-25 0.0296 0.0613 0.0279 0.0049 0.0563 0.0369 -0.0245 -0.0158 -0.0057 0.0670 0.0179 0.0095 -0.0076 0.0064 0.0232 0.0956 0.0944 0.1082 0.1213 0.1263 -0.0355 -0.0450 0.0475 0.0642 2020
2020-04-01 0.0200 0.0360 0.0176 0.0312 -0.0175 0.0401 -0.0252 0.0247 0.0830 0.0122 0.0068 0.0420 0.0024 0.0713 0.0829 0.0473 0.0293 0.0208 -0.0106 -0.0054 0.0526 0.1085 0.0369 0.0282 2020
2020-04-08 0.1012 0.0606 0.0676 0.1267 0.0919 0.2635 0.1161 0.0759 0.1606 0.0973 0.0626 0.0694 0.0478 0.0710 0.0761 0.0603 0.0808 0.0530 0.0856 0.0867 0.0417 -0.0477 0.0696 0.0680 2020
2020-04-15 -0.0673 -0.0344 -0.0429 0.0194 -0.0522 -0.0332 -0.1035 -0.0787 -0.0738 -0.0638 -0.0699 -0.0922 -0.1173 -0.0251 -0.0758 0.0247 -0.0228 -0.0530 -0.0070 0.0135 -0.0253 0.0055 -0.0412 -0.0386 2020
2020-04-22 0.0373 0.0118 0.0167 -0.0060 0.0780 0.1133 0.1203 0.0433 0.1334 0.1126 0.0677 0.0989 0.0729 0.0732 0.0826 0.0114 0.0623 0.0328 0.0294 0.0504 0.0140 0.1264 0.0472 0.0454 2020
2020-04-29 0.0659 0.0625 0.0903 0.0016 0.0081 -0.0012 -0.0793 -0.0424 -0.0157 -0.0573 -0.0351 -0.0529 -0.0925 -0.0477 -0.0551 -0.0126 0.0157 -0.0398 0.0310 0.0161 0.0011 0.1425 0.0031 0.0016 2020
2020-05-06 0.0455 0.0096 0.0192 0.0167 0.0606 0.0522 0.0020 0.0594 -0.0175 0.0457 -0.0555 -0.0355 -0.0906 -0.0061 0.0203 -0.0159 -0.0303 -0.0106 0.0579 -0.0184 -0.0061 -0.0223 0.0053 0.0017 2020
2020-05-13 0.0082 0.0061 -0.0006 0.0384 0.1209 -0.0017 0.0623 0.0902 0.0818 0.0235 0.0187 0.0154 0.0164 0.0035 0.0234 0.0127 0.0184 0.0047 0.0081 0.0047 0.0260 0.0999 0.0175 0.0183 2020
2020-05-20 0.0114 -0.0113 0.0336 -0.0113 -0.0100 0.0134 0.0970 0.1041 0.0780 0.0871 0.0775 0.0891 0.0921 0.0976 0.1051 -0.0304 -0.0051 -0.0037 -0.0054 0.0200 -0.0207 -0.0964 0.0252 0.0241 2020
2020-05-27 0.0207 0.0210 0.0146 0.0207 0.0123 0.0738 0.0102 0.0004 0.0513 0.0740 0.0319 0.0228 0.0425 0.0404 0.0424 0.0321 -0.0361 0.0453 0.0036 0.0380 0.0106 0.0757 0.0304 0.0296 2020
2020-06-03 0.0619 0.0261 0.0068 0.0506 0.0247 0.0649 0.2047 0.0856 -0.0482 0.0821 0.1110 0.1276 0.1747 0.0724 0.1005 -0.0156 0.0014 0.0174 0.0548 0.0094 -0.0083 0.0275 0.0391 0.0404 2020
2020-06-10 0.0232 0.0197 -0.0039 0.0055 0.0029 0.0431 -0.1002 -0.0722 0.0032 -0.0869 -0.0798 -0.0827 -0.1346 -0.0398 -0.0372 -0.0103 -0.0808 -0.0665 -0.0011 -0.0538 0.0061 -0.0267 -0.0279 -0.0247 2020
2020-06-17 0.0402 0.0422 0.0120 0.0555 0.0412 0.0198 -0.0630 -0.0567 0.0337 0.0528 -0.0413 -0.0399 -0.0463 -0.0232 -0.0139 -0.0111 -0.0190 0.0099 0.0129 0.0156 0.0257 0.0096 0.0080 -0.0029 2020
2020-06-24 -0.0047 0.0079 -0.0319 -0.0020 0.0050 0.0750 -0.0114 -0.0369 -0.0107 -0.0034 -0.0403 -0.0429 -0.0617 -0.0356 0.0085 -0.0157 -0.0021 0.0027 0.0089 -0.0046 0.0053 -0.0524 -0.0080 -0.0075 2020
2020-07-01 0.0214 0.0230 0.0494 0.0838 0.0386 0.2524 0.0066 -0.0067 -0.0104 -0.0074 -0.0187 -0.0317 -0.0456 0.0088 -0.0169 0.0157 0.0399 0.0178 0.0118 0.0057 0.0099 0.0124 0.0174 0.0174 2020
2020-07-08 0.0409 0.0005 0.0206 0.0276 0.0499 0.0874 0.0385 0.0201 0.0139 0.0348 0.0715 0.0479 -0.0086 0.0709 0.0615 0.0349 0.0347 -0.0060 -0.0048 0.0392 0.0068 -0.0010 0.0162 0.0162 2020
2020-07-15 -0.0006 0.0019 0.0228 0.0175 -0.0047 0.0334 0.0491 0.0197 0.0460 0.0384 0.0121 0.0115 0.0773 -0.0093 0.0366 0.0122 0.0406 0.0081 -0.0028 -0.0111 0.0164 0.0141 0.0187 0.0189 2020
2020-07-22 -0.0394 -0.0328 -0.0342 -0.0450 -0.0110 -0.0604 0.0482 0.0069 0.0037 0.0210 -0.0212 -0.0025 -0.0259 -0.0503 -0.0413 -0.0196 0.0616 0.0101 -0.0071 -0.0171 0.0603 0.1519 -0.0127 -0.0119 2020
2020-07-29 0.1621 0.0543 -0.0204 0.0451 0.0945 0.0071 -0.0216 -0.0203 -0.0141 -0.0354 -0.0184 0.0263 -0.0527 0.0001 -0.0201 0.0027 -0.0163 0.0245 -0.0253 0.0151 0.0313 0.0265 0.0294 0.0273 2020
2020-08-05 -0.0026 -0.0476 0.0049 -0.0187 -0.0342 -0.0788 0.0525 0.1002 0.0921 0.1162 0.0830 0.0736 0.0444 0.0457 0.0568 -0.0017 -0.0060 -0.0093 -0.0173 0.0356 -0.0522 0.0181 0.0055 0.0083 2020
2020-08-12 0.0568 0.0391 0.0496 0.0726 0.1222 0.3170 -0.0482 0.0452 -0.0182 -0.0128 -0.0544 -0.0530 -0.0478 -0.0473 -0.0167 0.0210 0.0150 0.0441 0.0317 0.0040 0.0448 0.0496 0.0214 0.0174 2020
2020-08-19 0.0771 0.0233 0.0317 0.0102 0.0391 0.0697 0.0072 -0.0050 -0.0218 -0.0051 0.0219 0.0182 0.0234 0.0230 0.0219 0.0130 0.0013 0.0132 -0.0168 -0.0146 -0.0377 -0.0535 0.0165 0.0161 2020
2020-08-26 0.0723 0.0511 0.0302 0.0446 0.0807 0.1604 -0.0160 0.0034 0.0196 0.0140 -0.0036 -0.0112 -0.0230 -0.0026 0.0101 0.0031 -0.0406 -0.0147 -0.0195 0.0020 0.0209 0.0518 0.0267 0.0243 2020
2020-09-02 -0.1734 -0.1146 -0.0828 -0.1052 -0.1483 -0.3637 0.0289 0.0834 -0.0278 0.0048 -0.0022 -0.0090 -0.0033 -0.0086 -0.0469 -0.0285 -0.0261 -0.0131 -0.0221 -0.0180 -0.0205 -0.1668 -0.0626 -0.0566 2020
2020-09-09 0.0238 0.0298 0.0075 0.0020 0.0866 0.3090 0.0014 -0.0250 0.0158 0.0157 -0.0064 -0.0009 0.0373 -0.0224 0.0044 0.0110 0.0283 0.0105 0.0076 -0.0001 0.0118 0.0636 0.0232 0.0207 2020
2020-09-16 -0.0328 -0.0065 -0.0503 -0.0086 -0.0276 -0.0584 -0.0376 -0.0702 -0.0176 -0.1221 -0.0518 -0.0545 -0.0507 -0.0328 -0.0563 -0.0319 -0.0194 -0.0079 -0.0257 -0.0390 -0.0265 -0.0242 -0.0240 -0.0294 2020
2020-09-23 0.0202 -0.0008 0.0042 0.0051 0.0455 -0.0122 -0.0269 -0.0241 0.0840 0.0164 0.0114 -0.0071 -0.0166 0.0266 -0.0082 0.0196 -0.0022 -0.0126 -0.0195 0.0331 -0.0026 0.0286 0.0024 0.0102 2020
2020-09-30 -0.0082 -0.0065 -0.0103 -0.0144 0.0379 -0.0122 0.0560 0.0562 0.0275 0.0490 0.0276 0.0249 0.0388 0.0216 0.0105 -0.0055 0.0000 -0.0281 -0.0116 0.0333 -0.0050 -0.0224 0.0130 0.0077 2020
2020-10-07 0.0678 0.0791 0.0769 0.1051 0.0366 0.0760 0.1059 0.0472 0.0167 -0.0251 0.0370 0.0235 0.0229 0.0472 0.0550 0.0143 0.0200 0.0135 0.0223 0.0526 0.0024 0.0746 0.0452 0.0444 2020
2020-10-14 -0.0301 -0.0375 -0.0103 -0.0681 -0.0432 -0.0569 -0.0026 0.1107 0.0420 0.0087 -0.0041 -0.0330 -0.0812 -0.0133 0.0202 -0.0260 0.0159 -0.0307 -0.0416 -0.0245 0.0086 0.0420 -0.0191 -0.0195 2020
2020-10-21 -0.0078 -0.0065 0.0304 0.0213 -0.0184 0.0065 0.0230 -0.0201 -0.0397 -0.0456 -0.0104 -0.0121 -0.0444 -0.0612 -0.0576 -0.0097 -0.0016 -0.0036 -0.0049 -0.0090 -0.0013 0.1361 -0.0148 -0.0151 2020
2020-10-28 -0.0543 -0.0325 0.0288 -0.0752 -0.0286 -0.0018 -0.0051 0.0131 0.0555 -0.0325 0.0403 0.0346 0.0123 0.0114 0.0519 -0.0330 -0.0337 -0.0138 0.0615 0.0026 -0.0006 0.0215 -0.0078 -0.0065 2020
2020-11-04 0.0489 0.0219 0.0544 -0.0044 -0.0193 -0.0325 0.0615 0.1502 0.0670 0.0655 0.1194 0.1136 0.0908 0.0941 0.0929 0.0682 0.0665 0.0530 0.1169 0.0959 -0.0184 0.0918 0.0514 0.0522 2020
2020-11-11 0.0308 0.0162 0.0137 0.0326 0.0498 0.0734 0.0432 0.0217 0.0502 -0.0208 -0.0035 -0.0040 0.0391 0.0325 0.0534 0.0072 -0.0079 0.0048 0.0034 -0.0045 0.0048 0.1432 0.0200 0.0184 2020
2020-11-18 -0.0360 -0.0028 0.0013 -0.0056 -0.0352 0.2292 0.0770 0.1014 0.0612 0.0630 0.0602 0.0506 0.1333 0.0556 0.0783 -0.0374 0.0154 -0.0168 0.0468 -0.0468 -0.0399 0.0796 0.0110 0.0072 2020
2020-11-25 0.0635 0.0135 0.0177 0.0322 0.0328 0.0515 -0.0225 -0.0391 0.0045 -0.0445 -0.0295 -0.0101 -0.0194 -0.0231 -0.0050 0.0315 0.0740 0.0174 0.0008 0.0153 0.0035 -0.0161 0.0091 0.0077 2020
2020-12-02 0.0134 -0.0009 0.0089 -0.0134 -0.0030 0.1056 0.0011 -0.0199 0.0070 0.0207 0.0187 0.0083 0.0309 0.0341 0.0099 0.0274 0.0769 0.0198 0.0345 0.0194 0.0308 -0.0260 0.0130 0.0113 2020
2020-12-09 0.0278 -0.0087 -0.0281 -0.0038 0.0011 -0.0259 -0.0109 -0.0501 -0.0037 -0.0428 -0.0139 -0.0039 0.0269 0.0149 0.0006 -0.0065 -0.0948 -0.0330 -0.0463 -0.0202 -0.0089 0.0581 -0.0051 -0.0016 2020
2020-12-16 0.0308 0.0448 -0.0235 0.0130 -0.0062 0.0111 -0.0401 -0.0184 0.0196 0.0367 0.0112 0.0197 -0.0262 0.0311 0.0412 0.0142 -0.0522 -0.0054 -0.0002 -0.0138 0.0032 0.2028 0.0057 -0.0064 2020
2020-12-23 0.0224 0.0009 0.0216 0.0354 -0.0256 0.0393 0.0034 0.0162 0.0239 -0.0144 0.0271 0.0270 0.0279 0.0312 0.0159 0.0093 0.0084 0.0249 0.0183 0.0362 0.0106 0.1402 0.0080 0.0157 2020
2020-12-30 -0.0290 -0.0283 -0.0101 -0.0316 0.0350 0.0987 -0.0195 0.0022 0.0407 0.0106 0.0051 0.0083 0.0249 0.0489 0.0259 0.0269 0.0038 -0.0039 0.0170 -0.0074 0.0363 0.2170 -0.0004 -0.0004 2020
2021-01-06 -0.0170 -0.0137 -0.0015 -0.0308 0.0060 0.1446 0.1228 0.1379 0.1246 0.0552 0.1169 0.1065 0.1059 0.1093 0.0869 -0.0013 -0.0003 0.0242 0.0303 0.0358 -0.0490 -0.0020 0.0221 0.0198 2021
2021-01-13 -0.0076 0.0070 0.0267 0.0000 -0.0347 -0.0058 0.0242 0.1370 -0.0580 -0.0465 -0.0157 -0.0268 -0.0394 -0.0269 -0.0107 0.0290 -0.0122 0.0012 0.0216 -0.0146 -0.0089 0.0614 -0.0001 -0.0003 2021
2021-01-20 0.1133 0.0708 0.0669 0.0637 0.0310 0.0446 0.1104 -0.0524 -0.0494 0.1121 -0.0479 -0.0575 -0.0391 -0.0432 -0.0517 0.0462 0.0157 -0.0360 -0.0190 -0.0261 0.0060 -0.1021 0.0139 0.0135 2021
2021-01-27 -0.0588 0.0304 0.0058 0.0161 0.0090 -0.0117 -0.0299 0.0130 0.0402 -0.0614 0.0153 0.0029 -0.0203 0.0183 -0.0037 -0.0557 -0.0642 -0.0314 -0.0502 -0.0129 -0.0087 0.0864 -0.0044 -0.0059 2021
2021-02-03 0.0075 0.0176 0.0783 -0.0224 0.0508 -0.0271 0.0940 0.0614 0.0485 0.0373 0.0437 0.0600 0.0785 0.0459 0.0505 0.0307 0.0102 -0.0357 0.0185 -0.0272 -0.0002 0.2692 0.0233 0.0225 2021
2021-02-10 -0.0195 -0.0003 0.0169 -0.0110 0.0721 -0.0647 -0.0332 -0.0475 0.0449 0.0201 0.0357 0.0393 0.0481 0.0376 0.0241 -0.0072 -0.0080 -0.0106 -0.0115 -0.0153 -0.0226 0.0568 0.0063 0.0052 2021
2021-02-17 -0.0566 -0.0437 -0.0243 -0.0230 -0.0807 -0.1305 0.0069 -0.0450 -0.0224 0.0248 0.0404 0.0358 0.0654 0.0230 0.0189 -0.0284 -0.0227 0.0039 0.0197 0.0150 0.0052 -0.0077 -0.0155 -0.0123 2021
2021-02-24 -0.0059 0.0049 0.0021 -0.0318 -0.0534 -0.0179 0.0770 0.0570 0.0167 0.0294 -0.0040 0.0003 0.0000 0.0361 0.0416 -0.0027 -0.0119 -0.0229 0.0148 0.0154 -0.0405 -0.0092 -0.0043 -0.0025 2021
2021-03-03 -0.0327 -0.0004 -0.0118 -0.0103 -0.0684 -0.0189 0.0016 0.0099 -0.0720 0.0603 0.0121 0.0220 0.0263 0.0029 0.0007 -0.0083 0.0277 0.0176 -0.0099 0.0505 -0.0097 0.1251 -0.0019 0.0016 2021
2021-03-10 0.0363 0.0167 0.0211 0.0094 0.0601 0.0049 -0.0064 0.0442 0.0265 -0.0029 0.0110 0.0407 0.0315 0.0331 0.0207 0.0230 0.0393 0.0354 0.0372 0.0074 0.0093 0.0355 0.0229 0.0223 2021
2021-03-17 -0.0244 -0.0005 -0.0206 0.0147 -0.0167 -0.0220 -0.0227 -0.0169 -0.0549 -0.0961 -0.0267 -0.0199 -0.0286 -0.0295 -0.0423 -0.0063 -0.0132 0.0017 -0.0557 0.0420 -0.0033 -0.0370 -0.0132 -0.0163 2021
2021-03-24 -0.0218 -0.0244 0.0025 -0.0266 -0.0153 -0.0409 0.0203 0.0410 -0.0158 0.0491 0.0330 0.0551 0.0296 0.0007 -0.0004 0.0286 0.0210 0.0090 0.0184 0.0136 -0.0266 0.0736 0.0073 0.0166 2021
2021-03-31 0.0513 0.0668 0.0765 0.0537 0.0741 0.0844 0.0363 0.0570 0.0497 0.0030 -0.0126 0.0178 0.0116 -0.0150 0.0000 -0.0099 -0.0017 -0.0153 -0.0133 -0.0249 0.0352 -0.0124 0.0328 0.0284 2021
2021-04-07 0.0631 0.0420 0.0202 0.0532 0.1232 0.0973 -0.0573 -0.0573 -0.0216 0.0109 0.0160 -0.0094 -0.0015 0.0019 0.0055 -0.0242 0.0303 0.0084 0.0266 0.0274 0.0013 0.0873 0.0179 0.0165 2021
2021-04-14 -0.0099 -0.0009 0.0108 -0.0194 -0.0330 -0.0585 -0.0634 -0.0476 -0.0446 0.0158 -0.0318 -0.0320 0.0668 0.0127 -0.0286 0.0430 0.0491 0.0276 0.0075 0.0572 0.0185 -0.1173 -0.0024 -0.0017 2021
2021-04-21 0.0096 0.0143 0.0052 0.0245 0.0138 -0.0200 0.0869 0.0558 0.0829 0.0445 0.0132 0.0462 0.0582 0.0435 0.0587 -0.0200 -0.0150 -0.0155 0.0339 -0.0051 -0.0004 -0.0258 0.0126 0.0129 2021
2021-04-28 -0.0499 -0.0556 0.0069 -0.0314 -0.0693 -0.0452 -0.0904 -0.0635 -0.0487 -0.0327 0.0276 0.0277 0.0143 0.0092 0.0083 0.0277 0.0383 -0.0179 0.0218 0.0418 0.0010 -0.0314 -0.0074 -0.0046 2021
2021-05-05 -0.0153 -0.0063 -0.0161 -0.0269 -0.0031 -0.0874 0.0148 0.0070 0.0063 0.0629 0.0195 0.0138 -0.0004 0.0284 0.0315 0.0066 -0.0151 0.0192 0.0087 0.0009 0.0328 0.0613 -0.0041 -0.0034 2021
2021-05-12 -0.0068 -0.0129 -0.0033 0.0026 -0.0205 -0.0658 0.0472 0.0029 -0.0237 -0.0101 0.0237 0.0141 0.0268 0.0128 0.0239 0.0093 0.0274 0.0245 0.0200 -0.0032 0.0167 -0.2788 -0.0070 -0.0055 2021
2021-05-19 0.0163 0.0349 0.0434 0.0082 0.1101 0.0454 0.0537 0.0154 0.0325 -0.0264 -0.0031 -0.0036 -0.0166 -0.0001 0.0215 -0.0022 -0.0181 -0.0240 -0.0229 0.0065 0.0165 -0.1110 0.0171 0.0152 2021
2021-05-26 -0.0209 -0.0150 0.0077 -0.0125 0.0387 0.0313 0.1451 0.0497 0.0880 0.0615 0.0256 0.0214 0.0251 0.0480 0.0359 -0.0209 -0.0213 -0.0304 -0.0207 -0.0154 -0.0003 -0.0457 0.0035 0.0034 2021
2021-06-02 0.0196 0.0207 0.0072 0.0140 0.0708 -0.0331 0.0539 0.0691 0.0278 0.0151 -0.0063 -0.0009 -0.0138 0.0093 0.0074 -0.0130 0.0091 0.0092 0.0012 -0.0123 -0.0033 -0.0916 0.0081 0.0062 2021
2021-06-09 0.0226 0.0227 0.0124 0.0358 0.0188 -0.0070 -0.0411 -0.0499 -0.0144 -0.0284 -0.0614 -0.0312 -0.0250 -0.0355 -0.0228 0.0067 0.0189 0.0446 0.0306 -0.0036 -0.0186 0.1883 0.0032 0.0052 2021
2021-06-16 0.0329 0.0273 0.0075 0.0355 0.0601 0.0398 -0.0060 -0.0262 -0.0347 -0.0716 -0.0326 -0.0349 -0.0432 -0.0378 -0.0567 -0.0053 0.0005 0.0150 -0.0098 -0.0040 -0.0458 -0.2176 0.0029 -0.0032 2021
2021-06-23 0.0174 0.0219 -0.0005 -0.0165 0.0586 0.0875 0.0067 -0.0069 0.0430 -0.0027 0.0258 0.0228 0.0283 0.0413 0.0560 0.0025 -0.0130 0.0133 -0.0211 0.0022 -0.0086 0.0984 0.0131 0.0141 2021
2021-06-30 0.0409 0.0228 0.0315 0.0639 0.0330 -0.0316 -0.0346 -0.0236 -0.0044 -0.0112 -0.0047 -0.0203 -0.0295 -0.0074 -0.0048 0.0237 0.0048 0.0116 0.0301 0.0301 0.0198 -0.0466 0.0107 0.0122 2021
2021-07-07 0.0252 0.0119 0.0091 0.0004 -0.0219 0.0135 -0.0055 0.0219 -0.0004 -0.0055 0.0202 -0.0053 -0.0060 0.0164 0.0327 0.0077 0.0091 -0.0064 0.0187 0.0200 0.0065 -0.0458 0.0057 0.0061 2021
2021-07-14 0.0035 -0.0059 -0.0089 -0.0287 -0.0843 -0.0121 -0.0360 -0.0449 -0.0282 -0.0112 -0.0389 -0.0560 0.0366 -0.0303 -0.0096 -0.0049 0.0347 -0.0187 -0.0159 -0.0134 0.0010 -0.0927 -0.0094 -0.0105 2021
2021-07-21 0.0042 0.0255 0.0441 0.0148 0.0315 -0.0241 -0.0087 -0.0207 0.0369 0.0072 0.0116 0.0077 0.0067 0.0273 0.0441 0.0247 0.0253 0.0218 0.0274 0.0051 -0.0056 0.2792 0.0178 0.0183 2021
2021-07-28 0.0040 0.0020 0.0279 -0.0744 0.0311 0.0960 0.0165 0.0510 0.0625 0.0412 0.0095 0.0149 0.0368 0.0146 0.0012 0.0100 0.0816 -0.0187 -0.0146 0.0162 0.0062 -0.0323 0.0039 0.0049 2021
2021-08-04 -0.0120 -0.0024 0.0086 -0.0136 0.0061 0.0004 -0.0144 -0.0646 0.0037 -0.0735 0.0408 0.0720 0.0581 0.0701 0.0621 -0.0036 0.0625 -0.0161 -0.0124 -0.0243 -0.0466 0.1780 0.0028 0.0035 2021
2021-08-11 0.0325 0.0229 -0.0011 -0.0240 -0.0243 -0.0644 -0.0619 -0.0724 -0.0702 -0.0258 -0.0142 -0.0082 -0.0144 -0.0074 0.0081 0.0323 0.0452 0.0473 0.0413 0.0240 0.0316 -0.0197 0.0023 0.0031 2021
2021-08-18 -0.0038 0.0320 0.0331 0.0195 0.1133 0.0623 0.0069 -0.0180 -0.0039 -0.0295 0.0042 0.0094 -0.0072 0.0088 0.0021 -0.0230 -0.0413 -0.0142 0.0002 0.0039 0.0100 0.0652 0.0101 0.0088 2021
2021-08-25 0.0147 -0.0005 0.0240 0.0487 0.0268 0.0377 -0.0038 -0.0114 -0.0352 -0.0165 0.0144 0.0065 -0.0566 0.0120 0.0129 -0.0070 -0.0489 -0.0186 0.0091 -0.0170 0.0061 -0.0114 0.0086 0.0080 2021
2021-09-01 0.0315 -0.0056 -0.0029 0.0110 0.0125 0.0231 -0.0062 -0.0059 -0.0104 0.0128 -0.0046 -0.0104 -0.0309 -0.0029 -0.0024 -0.0047 0.0147 -0.0041 -0.1023 0.0119 -0.0117 -0.0076 -0.0001 -0.0002 2021
2021-09-08 -0.0562 -0.0013 -0.0121 -0.0170 -0.0187 -0.0113 -0.0070 0.0406 -0.0052 -0.0026 -0.0135 -0.0314 0.0385 -0.0163 -0.0220 -0.0446 -0.0446 -0.0523 -0.0237 -0.0209 0.0066 0.0060 -0.0166 -0.0163 2021
2021-09-15 -0.0322 -0.0168 -0.0249 -0.0313 -0.0458 -0.0069 -0.0070 -0.0274 -0.0516 -0.0329 -0.0264 -0.0180 -0.0044 -0.0715 -0.0361 -0.0016 -0.0178 0.0070 0.0063 0.0030 -0.0166 -0.1460 -0.0205 -0.0240 2021
2021-09-22 -0.0107 -0.0390 -0.0233 -0.0083 -0.0261 0.0503 0.1139 0.0681 0.0804 0.0735 0.0822 0.0980 0.0015 0.0357 0.0373 -0.0105 -0.0202 0.0186 0.0018 -0.0338 -0.0243 0.0083 -0.0046 0.0034 2021
2021-09-29 -0.0057 0.0183 0.0014 -0.0291 -0.0121 0.0039 -0.0014 0.0278 0.0249 0.0133 0.0154 0.0243 0.0435 -0.0095 -0.0282 -0.0200 -0.0169 0.1070 0.0200 -0.0131 0.0156 0.2275 0.0008 -0.0014 2021
2021-10-06 0.0028 0.0142 0.0031 0.0081 0.0107 0.0317 0.0903 0.0816 0.0306 0.0430 -0.0138 -0.0155 -0.0277 0.0019 -0.0144 -0.0119 -0.0112 -0.0249 -0.0086 0.0246 0.0004 0.0842 0.0027 0.0012 2021
2021-10-13 0.0500 0.0511 0.0485 0.0588 0.0754 0.0701 -0.0142 -0.0364 0.0216 -0.0322 0.0192 0.0653 0.0761 0.0642 0.0398 0.0384 0.0057 -0.0013 -0.0104 0.0511 0.0048 0.1369 0.0399 0.0385 2021
2021-10-20 0.0038 0.0061 -0.0278 -0.0200 0.1034 0.1641 0.0332 0.0091 0.0155 -0.0396 0.0166 0.0313 0.0057 0.0131 0.0168 0.0114 0.0343 0.0341 0.0309 0.0689 0.0134 -0.0626 0.0105 0.0117 2021
2021-10-27 0.0047 0.0716 0.0430 -0.0189 0.0659 0.1404 0.1221 -0.0315 0.0316 0.0661 -0.0054 -0.0017 0.0131 0.0148 0.0114 -0.0010 0.0425 0.0791 0.0623 -0.0057 -0.0031 0.0463 0.0123 0.0129 2021
2021-11-03 0.0053 0.0084 0.0237 0.0765 0.1495 -0.1355 0.1108 0.0531 -0.0123 -0.0118 -0.0159 -0.0211 -0.0279 -0.0446 -0.0416 -0.0188 0.0399 -0.0734 -0.0079 0.0269 0.0244 0.0576 0.0115 0.0118 2021
2021-11-10 0.0027 0.0105 -0.0070 -0.0100 -0.0149 0.0301 -0.0165 0.0658 0.0124 0.0400 -0.0145 0.0043 0.0134 -0.0056 0.0098 0.0010 0.0562 0.0167 0.0070 -0.0322 0.0095 -0.1072 0.0039 0.0041 2021
2021-11-17 0.0667 -0.0054 -0.0143 0.0110 0.0498 0.0502 0.0205 0.0070 -0.0251 -0.0137 0.0175 0.0089 0.0202 0.0080 0.0116 -0.0122 0.0294 -0.0157 0.0209 -0.0056 -0.0332 -0.0440 -0.0064 -0.0023 2021
2021-11-24 0.0238 -0.0194 -0.0270 -0.0206 0.0289 0.0317 -0.0463 -0.0857 -0.0602 -0.0981 -0.0578 -0.0659 -0.0730 -0.0644 -0.0716 -0.0235 0.0506 -0.1001 -0.0308 -0.0065 -0.0107 -0.0098 -0.0265 -0.0273 2021
2021-12-01 0.0350 0.0130 0.0372 0.0046 -0.0076 -0.0847 0.0393 0.0613 0.0443 0.0549 0.0233 0.0054 0.0504 0.0490 0.0779 0.0465 -0.0381 -0.0357 0.0526 0.0451 0.0079 -0.1172 0.0250 0.0275 2021
2021-12-08 0.0182 -0.0198 -0.0231 -0.0410 -0.1347 -0.0928 0.0045 -0.0522 -0.0414 -0.0211 -0.0214 -0.0083 -0.0274 -0.0234 -0.0366 0.0415 0.0713 0.0197 0.0465 0.0345 -0.0082 -0.0841 -0.0172 -0.0106 2021
2021-12-15 -0.0077 -0.0032 -0.0030 0.0078 0.0257 -0.0211 -0.0222 -0.0638 -0.0176 -0.0396 -0.0193 0.0014 -0.0223 -0.0221 -0.0107 -0.0183 0.0596 0.0338 0.0207 0.0160 0.0095 0.0487 0.0065 -0.0006 2021
2021-12-22 0.0358 0.0418 0.0222 0.0014 0.0420 0.1482 0.0570 0.0415 0.0288 0.0465 0.0162 0.0115 0.0127 0.0190 0.0223 0.0186 -0.0161 0.0167 0.0336 0.0318 0.0097 -0.0279 0.0285 0.0329 2021
2021-12-29 0.0023 -0.0365 -0.0157 -0.0186 -0.0346 0.0546 0.1579 0.1407 0.0572 0.0651 0.0563 0.0710 0.0857 0.0500 0.0420 0.0043 -0.0619 0.0026 0.0057 -0.0242 0.0055 -0.0362 -0.0007 0.0014 2021
2022-01-05 -0.0260 -0.0436 -0.0328 -0.0130 -0.0516 -0.0770 0.0016 -0.0673 -0.0754 0.0135 -0.0020 0.0251 0.0609 -0.0109 0.0158 0.0010 0.0388 0.0588 0.0133 -0.0456 0.0042 -0.0714 -0.0180 -0.0165 2022
2022-01-12 -0.0306 -0.0399 -0.0271 -0.0398 -0.0713 -0.0324 0.0012 -0.0444 -0.0656 0.0078 -0.0959 -0.0618 0.0112 -0.1286 -0.1193 -0.0245 -0.0466 -0.0016 -0.0014 -0.0172 -0.0053 -0.0085 -0.0322 -0.0286 2022
2022-01-19 -0.0608 -0.0479 -0.0690 -0.1268 -0.1487 -0.1152 -0.1990 -0.1247 -0.0956 -0.1032 -0.0318 -0.0181 -0.0562 -0.0369 0.0521 0.0032 -0.0294 -0.0258 -0.0170 -0.0090 0.0187 -0.1369 -0.0502 -0.0494 2022
2022-01-26 0.0888 0.0679 0.0810 0.0770 0.0986 0.0139 0.0335 0.0410 0.0294 0.0124 0.0310 0.0327 0.0368 0.0638 0.0484 0.0192 0.0100 0.0305 0.0290 0.0250 -0.0255 0.0473 0.0422 0.0417 2022
2022-02-02 0.0013 -0.0137 0.0127 0.0654 0.0189 -0.0100 -0.1484 -0.0891 -0.0419 -0.0047 0.0313 0.0507 0.0551 0.0165 0.0298 0.0037 -0.0186 -0.0631 0.0464 0.0520 0.0142 0.1299 -0.0069 -0.0044 2022
2022-02-09 -0.0105 -0.0135 -0.0202 -0.0308 0.0538 0.0005 0.0201 0.0042 0.0675 0.0174 -0.0079 -0.0327 -0.0018 -0.0168 -0.0278 -0.0248 -0.0376 0.0116 0.0087 -0.0312 0.0143 0.0103 -0.0101 -0.0108 2022
2022-02-16 -0.0503 -0.0434 -0.0510 -0.0412 -0.1246 -0.1158 -0.0447 -0.0602 -0.0433 -0.0662 -0.0186 -0.0478 -0.0546 -0.0556 -0.0877 -0.0376 -0.0465 -0.0242 0.0055 -0.0334 0.0252 -0.1521 -0.0410 -0.0378 2022
2022-02-23 -0.0068 0.0269 0.0322 0.0063 0.0037 0.0508 -0.0347 -0.0493 -0.1527 -0.0875 -0.1071 -0.0702 -0.0946 -0.0478 -0.0781 0.0240 -0.0382 0.0051 0.0145 0.0293 0.0230 0.1471 0.0035 0.0010 2022
2022-03-02 -0.0359 -0.0669 -0.0533 -0.1055 -0.0873 -0.0473 -0.0409 -0.1021 -0.1645 -0.0683 -0.0616 -0.0958 -0.0792 -0.0152 -0.0506 0.0284 0.0363 0.0080 -0.0037 -0.0059 0.0530 -0.1354 -0.0355 -0.0325 2022
2022-03-09 -0.0150 0.0401 0.0163 0.0802 0.0658 -0.0277 0.0019 0.0469 0.0762 0.0110 0.0321 0.0776 0.0756 0.0240 0.0356 0.0430 0.0958 0.0217 0.0576 0.0504 -0.0682 0.0154 0.0195 0.0236 2022
2022-03-16 0.0848 0.0572 0.0794 0.1123 0.1437 0.2147 0.0622 0.0561 0.0904 0.0515 0.0738 0.0626 0.0634 0.0412 0.0875 -0.0065 0.0158 0.0172 0.0261 0.0177 0.0026 0.0740 0.0610 0.0535 2022
2022-03-23 0.0583 0.0366 0.0187 0.0265 0.0773 0.1010 0.0379 0.0374 0.0642 0.0415 -0.0101 -0.0169 -0.0341 -0.0098 -0.0256 0.0155 -0.0057 0.0282 0.0135 0.0106 -0.0012 0.1138 0.0239 0.0294 2022
2022-03-30 -0.0220 -0.0145 -0.0135 -0.0316 -0.0999 -0.0076 -0.1151 -0.1105 -0.1120 -0.0778 -0.0571 -0.0790 -0.0698 -0.0473 -0.0741 -0.0007 -0.0289 0.0260 0.0077 0.0137 0.0006 -0.0411 -0.0206 -0.0231 2022
2022-04-06 -0.0432 -0.0973 -0.0961 -0.0843 -0.1872 -0.1005 -0.0295 -0.0339 -0.0172 -0.0005 -0.0062 -0.0245 0.0062 -0.0130 -0.0160 0.0128 0.0358 0.0226 0.0235 0.0303 0.0250 -0.1269 -0.0325 -0.0287 2022
2022-04-13 -0.0016 0.0114 0.0178 0.0475 0.0318 0.0409 0.0502 0.0497 -0.0035 0.0363 -0.0032 0.0102 -0.0123 0.0493 0.0576 0.0175 -0.0567 0.0019 -0.0678 0.0074 -0.0107 0.0337 0.0156 0.0153 2022
2022-04-20 -0.0654 -0.0543 -0.0914 -0.1260 -0.1668 -0.1597 -0.0934 -0.1009 -0.0748 -0.0673 -0.0638 -0.0821 -0.0704 -0.0704 -0.0764 0.0087 -0.0232 -0.0154 0.0074 -0.0455 -0.0251 -0.0851 -0.0682 -0.0672 2022
2022-04-27 0.0169 0.0419 -0.0112 -0.1150 0.0424 0.0368 -0.0036 0.0487 0.0486 0.0597 0.0001 0.0185 -0.0095 0.0049 0.0166 -0.0352 0.0053 0.0305 -0.0430 -0.0279 -0.0184 -0.0097 0.0019 0.0007 2022
2022-05-04 -0.0317 -0.0446 -0.0254 -0.1323 -0.1080 -0.1280 -0.0868 -0.0315 -0.1152 -0.0494 -0.0342 -0.0376 -0.0248 -0.0310 -0.0340 -0.0068 0.0040 0.0081 0.0165 -0.0235 -0.0155 -0.1963 -0.0477 -0.0424 2022
2022-05-11 -0.0332 -0.0100 0.0180 0.0581 0.0325 -0.0492 0.0134 -0.0156 0.0335 0.0835 0.0273 0.0064 0.0200 0.0256 0.0327 0.0097 0.0367 0.0574 0.0175 0.0092 -0.0123 -0.0194 0.0246 0.0229 2022
2022-05-18 -0.0613 -0.0274 -0.0945 -0.1028 -0.1180 -0.1926 -0.0856 -0.0789 -0.0852 -0.0523 0.0336 -0.0095 -0.0097 0.0031 -0.0118 0.0143 0.0476 0.0175 -0.0373 0.0102 0.0280 -0.0256 -0.0377 -0.0360 2022
2022-05-25 0.0587 0.0484 0.0710 0.1439 0.1449 0.1882 0.0966 0.0940 0.1541 0.0738 0.0454 0.0426 0.0557 0.0403 0.0497 -0.0040 -0.0070 -0.0280 -0.0117 -0.0016 -0.0173 0.0696 0.0480 0.0472 2022
2022-06-01 -0.0009 0.0023 0.0293 0.0229 0.0135 -0.0564 0.0044 -0.0080 0.0317 -0.0079 -0.0165 -0.0231 -0.0066 -0.0104 -0.0094 -0.0067 0.0172 -0.0170 0.0119 0.0006 0.0105 -0.0202 0.0087 0.0068 2022
2022-06-08 -0.1135 -0.1085 -0.0933 -0.1842 -0.1783 -0.0783 -0.1189 -0.1447 -0.1444 -0.1276 -0.1313 -0.1387 -0.1946 -0.1292 -0.1296 -0.0586 -0.1187 -0.0684 -0.0804 -0.0738 -0.0256 -0.3386 -0.1126 -0.1062 2022
2022-06-15 0.0232 0.0371 0.0443 0.0604 0.0453 0.0706 -0.0626 -0.0170 -0.0456 0.0097 0.0154 0.0432 0.0408 0.0080 -0.0044 0.0283 0.0040 0.0491 0.0416 0.0394 0.0121 -0.0698 0.0102 0.0032 2022
2022-06-22 0.0115 0.0107 0.0041 -0.0118 -0.0359 -0.0186 0.0301 0.0405 0.0528 0.0182 -0.0001 -0.0181 0.0301 0.0503 0.0462 0.0225 0.0516 0.0429 0.0610 0.0605 -0.0059 -0.0210 0.0163 0.0191 2022
2022-06-29 0.0295 0.0245 0.0111 0.0552 -0.0658 0.0017 -0.0530 -0.0488 -0.0535 -0.0668 -0.0280 -0.0321 -0.0020 -0.0077 -0.0266 0.0068 0.0192 0.0081 0.0094 -0.0063 -0.0291 -0.0045 0.0029 0.0034 2022
2022-07-06 0.0299 -0.0355 0.0067 -0.0384 0.0079 0.0000 0.0316 -0.0263 -0.0080 0.0232 0.0119 0.0038 -0.0125 -0.0158 -0.0022 -0.0129 0.0077 0.0103 -0.0096 0.0180 -0.0241 -0.0438 -0.0032 -0.0030 2022
2022-07-13 0.0346 0.0228 -0.0018 0.0791 0.1192 0.0521 0.0854 0.0871 0.0770 0.0350 0.0140 0.0615 0.0800 0.0836 0.0725 -0.0239 -0.0130 -0.0133 -0.0180 0.0363 -0.0081 0.1909 0.0300 0.0296 2022
2022-07-20 0.0040 -0.0298 -0.0804 -0.0292 -0.0274 0.0529 -0.0040 -0.0313 -0.0090 0.0199 -0.0100 -0.0090 0.0000 0.0016 -0.0106 0.0115 0.0179 -0.0117 0.0168 -0.0035 0.0031 -0.0964 -0.0032 -0.0035 2022
2022-07-27 0.0540 0.0871 0.0919 0.1558 0.1138 0.1494 0.1897 0.0804 0.1194 0.0560 -0.0088 -0.0003 -0.0005 0.0289 0.0334 -0.0044 -0.0512 -0.0411 -0.0720 0.0073 0.0247 0.0787 0.0445 0.0430 2022
2022-08-03 0.0302 0.0269 0.0129 0.0270 -0.0809 -0.0591 0.0020 0.0135 -0.0867 -0.0131 0.0259 0.0263 0.0121 0.0263 0.0428 -0.0160 0.0095 0.0216 -0.0010 0.0034 0.0190 0.0081 0.0089 0.0080 2022
2022-08-10 0.0494 0.0362 0.0426 0.0492 0.0998 0.0788 0.0785 0.0627 0.0833 0.0434 0.0691 0.0771 0.0663 0.0531 0.0613 -0.0155 0.0016 0.0119 0.0163 0.0164 -0.0107 0.0306 0.0437 0.0436 2022
2022-08-17 -0.0341 -0.0572 -0.0666 -0.0802 -0.0942 -0.0335 -0.0600 -0.0111 -0.1181 -0.0679 -0.0678 -0.0628 -0.0374 -0.0426 -0.0391 -0.0086 -0.0378 -0.0043 -0.0251 -0.0191 -0.0161 -0.1038 -0.0420 -0.0412 2022
2022-08-24 -0.0510 -0.0478 -0.0442 -0.0373 -0.1050 -0.0653 0.0084 0.0147 -0.0180 0.0297 -0.0097 -0.0093 -0.0052 -0.0194 -0.0448 -0.0158 -0.0460 -0.0375 -0.0253 -0.0245 -0.0140 -0.0838 -0.0354 -0.0349 2022
2022-08-31 -0.0279 -0.0377 -0.0197 -0.0206 -0.1387 -0.0119 -0.0276 -0.0085 -0.0591 -0.0487 -0.0059 -0.0307 -0.0290 -0.0216 0.0083 0.0046 -0.0020 -0.0053 0.0149 -0.0099 -0.0137 -0.0497 -0.0206 -0.0189 2022
2022-09-07 -0.0045 -0.0050 -0.0236 0.0056 -0.0251 0.0625 -0.0195 0.0459 0.0874 0.0448 0.0230 0.0346 0.0079 0.0133 0.0223 -0.0114 0.0094 -0.0016 0.0068 -0.0072 0.0013 0.0746 0.0066 0.0060 2022
2022-09-14 0.0197 -0.0386 -0.0310 -0.0372 0.0037 0.0553 -0.1187 -0.0369 -0.0421 -0.0409 -0.0048 0.0050 0.0044 -0.0157 0.0016 0.0223 -0.0312 -0.0033 0.0231 0.0202 -0.0221 -0.0718 -0.0208 -0.0232 2022
2022-09-21 -0.0333 -0.0252 -0.0367 -0.0658 -0.0597 -0.0872 -0.0945 -0.1181 -0.1141 -0.0902 -0.0901 -0.1113 -0.0811 -0.1038 -0.0926 -0.0002 -0.0153 0.0062 -0.0004 -0.0280 -0.0230 0.0116 -0.0612 -0.0513 2022
2022-09-28 -0.0380 0.0514 0.0416 0.0567 0.0590 -0.1260 0.0371 0.0309 0.0600 0.0311 0.0633 0.0575 0.0841 0.0775 0.0550 0.0041 0.0084 0.0293 0.0019 0.0287 0.0587 0.0622 0.0455 0.0394 2022
2022-10-05 -0.0500 -0.0990 -0.0449 -0.0762 -0.1279 -0.1416 -0.0669 -0.1094 -0.0731 -0.0416 -0.1008 -0.0840 -0.0791 -0.0679 -0.0867 -0.0176 -0.0588 0.0296 -0.0034 -0.0457 -0.0351 -0.0653 -0.0569 -0.0550 2022
2022-10-12 0.0337 0.0564 0.0363 0.0363 0.0324 0.0169 0.0399 0.0651 0.0734 0.0352 0.1621 0.1584 0.1047 0.0646 0.0312 0.0200 0.0505 0.0384 0.0216 0.0438 -0.0091 0.0147 0.0371 0.0367 2022
2022-10-19 0.0580 0.0497 0.0362 0.0358 0.1027 0.0101 0.0644 0.0775 0.0240 0.0639 0.0320 0.0145 0.0155 0.0574 0.0134 0.0279 0.0335 0.0322 0.0456 0.0339 0.0016 0.0386 0.0366 0.0365 2022
2022-10-26 -0.0112 -0.0940 -0.1440 -0.2199 0.0210 0.0240 0.0435 0.0613 0.0142 0.0258 0.0435 0.0226 0.0342 0.0475 0.0391 0.0138 0.0517 0.0208 -0.0196 0.0130 -0.0035 0.0192 -0.0006 -0.0010 2022
2022-11-02 -0.0769 0.0031 -0.0175 -0.0730 0.0753 -0.1747 0.0236 -0.0077 0.0991 0.0404 0.0254 0.0248 0.0049 0.0433 0.0281 0.0043 -0.0138 0.0173 0.0110 0.0104 0.0383 -0.0997 -0.0073 -0.0066 2022
2022-11-09 0.0745 0.0557 0.1019 0.0949 0.1322 0.0162 0.0414 0.0300 0.0945 0.0966 0.0113 0.0158 -0.0036 0.0505 0.0594 -0.0084 0.0340 -0.0189 0.0299 -0.0948 0.0372 -0.0936 0.0441 0.0423 2022
2022-11-16 0.0009 0.0126 -0.0142 -0.0598 -0.0384 -0.1348 -0.0058 -0.0067 -0.0374 -0.0073 0.0157 -0.0056 0.0085 0.0026 -0.0092 0.0254 0.0104 0.0707 0.0432 0.0391 -0.0209 -0.0420 0.0019 0.0035 2022
2022-11-23 -0.0619 -0.0166 -0.0194 -0.0084 -0.0252 0.0623 -0.0230 -0.0055 -0.0497 -0.0130 0.0112 -0.0132 0.0097 -0.0004 0.0156 0.0023 0.0083 0.0180 -0.0100 0.0093 0.0041 0.0156 -0.0119 -0.0117 2022
2022-11-30 0.0123 0.0197 0.0186 -0.0462 0.0220 -0.0056 -0.0348 -0.0445 -0.0215 -0.0224 -0.0371 -0.1144 -0.0917 -0.0557 -0.0400 0.0001 0.0044 0.0008 0.0343 0.0212 0.0129 0.0384 -0.0045 -0.0035 2022
2022-12-07 0.0178 0.0470 -0.0140 0.0469 0.1228 -0.1109 0.0216 0.0218 -0.0216 0.0070 0.0187 -0.0018 -0.0181 0.0223 0.0577 0.0175 0.0654 0.0180 0.0065 0.0010 0.0220 0.0397 0.0180 0.0205 2022
2022-12-14 -0.0949 -0.0607 -0.0716 -0.0822 -0.1165 -0.1553 -0.1681 -0.0966 -0.0406 -0.0162 -0.0256 -0.0172 -0.0392 -0.0679 -0.0849 -0.0200 -0.0335 -0.0109 -0.0259 -0.0340 0.0034 -0.0505 -0.0481 -0.0548 2022
2022-12-21 -0.0173 -0.0202 -0.0185 -0.0256 -0.1302 -0.2335 -0.0238 -0.0549 -0.0238 -0.0077 0.0080 0.0105 0.0015 -0.0073 -0.0012 0.0100 -0.0037 0.0283 0.0149 0.0224 -0.0024 -0.0113 0.0009 0.0068 2022
2022-12-28 -0.0389 0.0110 0.0196 0.0329 0.0136 -0.0092 0.0420 0.0149 0.0157 0.0030 0.0253 0.0297 0.0181 0.0124 0.0077 0.0043 0.0025 -0.0088 -0.0037 -0.0254 0.0141 -0.0022 -0.0008 -0.0015 2022
2023-01-04 0.0443 -0.0458 -0.0079 0.0461 0.1056 0.0948 0.0947 0.0928 0.0695 0.0672 0.0254 0.0180 0.0135 0.0317 0.0367 -0.0172 -0.0737 -0.0030 -0.0170 -0.0650 0.0213 0.0449 0.0253 0.0253 2023
2023-01-11 0.0391 0.0490 0.0319 0.0665 0.1068 0.1011 -0.0133 -0.0136 0.0288 0.0270 0.0231 0.0117 0.0407 -0.0210 0.0878 -0.0161 -0.0329 -0.0033 -0.0436 -0.0019 0.0162 0.1931 0.0197 0.0182 2023
2023-01-18 0.0473 0.0070 0.0679 0.0028 0.0846 0.0901 0.0055 -0.0113 0.0333 0.0061 -0.0168 0.0014 0.0075 -0.0046 -0.0163 -0.0238 -0.0302 -0.0176 -0.0247 0.0134 0.0150 0.0674 0.0050 0.0061 2023
2023-01-25 0.0123 0.0236 0.0116 0.0683 0.0140 0.1855 0.0587 0.0827 0.0646 0.0601 0.0108 0.0260 0.0530 0.0490 0.0189 -0.0295 -0.0124 -0.0103 0.0004 0.0153 -0.0048 0.0220 0.0165 0.0156 2023
2023-02-01 0.0693 0.0767 0.0853 -0.0099 0.1266 0.1277 -0.0045 0.0515 0.0246 0.0006 0.0260 0.0357 0.0265 0.0232 0.0273 -0.0001 -0.0039 -0.0162 -0.0178 -0.0457 -0.0307 0.0054 0.0204 0.0212 2023
2023-02-08 -0.0094 0.0171 -0.1283 -0.0239 0.0354 0.0613 -0.0363 0.0246 0.0438 0.0491 -0.0031 -0.0318 0.0140 -0.0070 0.0134 -0.0084 0.0030 0.0285 0.0501 0.0329 -0.0079 -0.0459 -0.0064 -0.0062 2023
2023-02-15 -0.0298 -0.0743 -0.0310 -0.0527 -0.1063 -0.0584 -0.0001 -0.0311 -0.0404 -0.0073 -0.0252 -0.0314 -0.0477 -0.0291 -0.0297 -0.0252 -0.0236 0.0030 -0.0039 -0.0031 -0.0116 0.0950 -0.0340 -0.0334 2023
2023-02-22 -0.0072 -0.0104 -0.0190 -0.0037 0.1169 0.0414 -0.0107 -0.0599 -0.0002 0.0191 0.0263 -0.0064 0.0114 -0.0266 -0.0115 -0.0233 -0.0512 -0.0263 0.0124 -0.0318 -0.0049 -0.0542 -0.0066 -0.0071 2023
2023-03-01 0.0280 0.0188 0.0413 -0.0072 0.0031 -0.0916 0.0611 0.0255 0.0026 -0.0026 -0.0336 -0.0386 -0.0509 -0.0160 -0.0046 0.0054 -0.0057 0.0463 -0.0063 -0.0043 -0.0069 -0.0409 0.0043 0.0051 2023
2023-03-08 0.0065 0.0258 0.0012 0.0141 0.0329 -0.0240 -0.0727 -0.1077 -0.0312 -0.0486 -0.0293 -0.1311 -0.1012 -0.0645 -0.0655 -0.0011 -0.0110 -0.0394 0.0060 -0.0198 0.0475 0.1077 -0.0186 -0.0166 2023
2023-03-15 0.0429 0.0486 0.1102 0.0586 0.0850 0.0752 -0.0178 -0.0141 -0.0180 -0.0084 -0.0307 -0.0059 -0.0430 -0.0152 -0.0135 -0.0002 0.0189 -0.0065 0.0188 0.0364 0.0198 0.1298 0.0224 0.0182 2023
2023-03-22 -0.0103 0.0053 -0.0378 -0.0341 0.0080 -0.0434 -0.0103 -0.0254 -0.0274 0.0097 -0.0129 -0.0166 -0.0344 0.0036 -0.0447 -0.0135 -0.0166 -0.0001 0.0094 -0.0158 0.0169 -0.0327 -0.0147 -0.0045 2023
2023-03-29 0.0494 0.0425 0.0359 0.0667 0.0387 0.0178 0.0922 0.0435 -0.0071 -0.0050 -0.0036 -0.0050 -0.0100 0.0131 -0.0007 0.0430 0.0225 0.0308 0.0096 0.0428 0.0244 0.0325 0.0375 0.0325 2023
2023-04-05 -0.0296 -0.0153 0.0060 -0.0395 -0.0104 -0.0305 0.0117 -0.0093 -0.0212 0.0057 0.0008 0.0258 0.0672 0.0145 0.0032 0.0358 0.0215 0.0331 0.0100 0.0547 -0.0091 0.0708 0.0013 0.0026 2023
2023-04-12 0.0347 0.0194 -0.0081 0.0235 0.0182 -0.0134 -0.0109 -0.0023 0.0239 0.0162 0.1033 0.0624 0.0616 0.0198 0.0544 -0.0200 -0.0301 0.0206 -0.0112 -0.0322 -0.0002 0.0054 0.0108 0.0109 2023
2023-04-19 -0.0164 -0.0459 -0.0062 0.0026 -0.0529 -0.1373 -0.0784 -0.0710 -0.0495 -0.0027 -0.0267 -0.0579 -0.0320 0.0165 -0.0201 0.0256 -0.0305 0.0147 0.0419 -0.0252 -0.0027 -0.0712 -0.0213 -0.0198 2023
2023-04-26 0.0287 0.1034 0.0141 0.0103 0.0724 -0.0022 0.0150 0.0052 -0.0107 -0.0220 0.0090 -0.0239 -0.0431 -0.0182 -0.0203 -0.0009 -0.0069 0.0116 -0.0840 0.0030 0.0095 0.0131 0.0125 0.0117 2023
2023-05-03 0.0190 0.0052 0.0191 0.0284 0.0127 0.0537 0.0051 0.0060 -0.0808 -0.0608 -0.0182 -0.0179 -0.0078 -0.0261 -0.0139 -0.0244 -0.0150 -0.0039 -0.0321 -0.0061 0.0080 -0.0363 0.0002 0.0002 2023
2023-05-10 0.0017 0.0153 0.1073 0.0617 0.0222 -0.0157 -0.0528 -0.0537 -0.0268 -0.0204 -0.0154 -0.0109 0.0039 -0.0123 -0.0302 -0.0107 -0.0390 -0.0116 -0.0244 -0.0220 -0.0222 -0.0227 -0.0028 -0.0017 2023
2023-05-17 -0.0016 0.0112 0.0252 0.0139 0.0493 0.1094 0.0418 0.0579 0.0172 0.0691 0.0168 0.0436 0.0709 0.0086 0.0095 -0.0160 0.0794 -0.0245 -0.0054 -0.0006 -0.0078 0.0070 0.0100 0.0093 2023
2023-05-24 0.0329 0.0515 0.0090 0.0564 0.2678 0.0796 0.0708 -0.0018 -0.0136 -0.0004 0.0063 -0.0113 -0.0056 0.0222 0.0094 -0.0082 -0.0687 -0.0369 -0.0436 0.0009 -0.0076 0.0174 0.0144 0.0146 2023
2023-05-31 0.0107 0.0074 0.0290 0.0399 -0.0370 0.0955 0.0266 0.0548 0.0452 0.0056 0.0136 0.0337 0.0068 -0.0123 0.0288 0.0244 0.0361 0.0077 -0.0074 0.0160 0.0016 -0.0169 0.0202 0.0185 2023
2023-06-07 0.0226 0.0018 -0.0277 0.0004 0.0595 0.1561 0.0888 0.0689 0.0580 -0.0025 0.0191 0.0137 0.0331 0.0545 0.0278 0.0161 0.0486 -0.0002 0.0210 0.0076 -0.0099 -0.0497 0.0160 0.0200 2023
2023-06-14 0.0092 0.0112 -0.0059 -0.0070 0.0658 0.0591 0.0063 -0.0088 -0.0098 -0.0062 0.0036 -0.0182 -0.0180 -0.0350 -0.0177 0.0209 -0.0236 0.0022 -0.0035 -0.0456 -0.0044 0.0889 0.0073 0.0012 2023
2023-06-21 0.0164 -0.0103 -0.0395 0.0267 -0.0451 -0.0925 0.0133 0.0043 0.0038 -0.0009 -0.0236 -0.0221 -0.0237 -0.0536 -0.0269 -0.0051 -0.0771 0.0343 -0.0386 0.0318 -0.0115 0.0800 -0.0033 0.0014 2023
2023-06-28 0.0231 0.0102 0.0132 0.0080 0.0127 0.1118 0.0560 0.0387 0.0245 0.0742 0.0519 0.0334 0.0591 0.0411 0.0232 0.0004 0.0063 0.0089 0.0180 -0.0097 0.0044 0.0029 0.0177 0.0173 2023
2023-07-05 -0.0230 -0.0165 -0.0233 -0.0111 -0.0002 -0.0365 -0.0007 0.0256 0.0689 0.0363 0.0055 -0.0062 -0.0153 -0.0177 -0.0169 -0.0293 -0.0173 -0.0505 0.0041 -0.0319 0.0055 -0.0051 -0.0022 -0.0030 2023
2023-07-12 0.0296 0.0781 0.0550 0.0310 0.1133 0.0837 -0.0721 -0.0212 -0.0131 0.0018 0.0483 0.0563 0.0648 0.0498 0.0790 0.0027 0.0061 -0.0256 0.0074 0.0771 0.0231 -0.0253 0.0274 0.0262 2023
2023-07-19 -0.0006 -0.0240 -0.0126 -0.0283 -0.0390 -0.1005 -0.0425 -0.0314 0.0088 0.0076 0.0204 0.0461 -0.0026 0.0504 0.0266 0.0805 0.0224 0.0148 0.0473 0.0216 -0.0067 -0.0213 0.0029 0.0027 2023
2023-07-26 0.0102 -0.0426 0.0736 0.0196 0.0180 -0.0160 -0.0010 0.0053 -0.0037 0.0102 0.0023 -0.0166 0.0050 0.0085 -0.0376 -0.0205 -0.0399 -0.0211 0.0476 -0.0122 -0.0107 0.0152 0.0016 0.0023 2023
2023-08-02 -0.0843 -0.0311 -0.0011 0.0608 -0.0404 -0.0445 -0.0411 -0.0342 -0.0294 -0.1033 -0.0083 -0.0111 -0.0273 -0.0268 -0.0183 0.0251 0.0119 0.0107 0.0072 0.0022 -0.0101 0.0030 -0.0185 -0.0171 2023
2023-08-09 -0.0132 -0.0129 -0.0124 -0.0164 -0.0163 -0.0694 -0.0724 -0.1010 -0.0887 -0.0278 -0.0329 -0.0435 -0.0323 -0.0472 -0.0265 -0.0014 -0.0070 0.0209 0.0166 0.0016 -0.0115 -0.0202 -0.0126 -0.0131 2023
2023-08-16 0.0001 0.0019 -0.0054 -0.0252 0.0386 0.0010 -0.0092 -0.0112 -0.0121 -0.0329 -0.0299 -0.0514 -0.0292 -0.0412 -0.0376 -0.0408 0.0402 -0.0132 -0.0258 -0.0287 -0.0028 -0.1138 -0.0120 -0.0108 2023
2023-08-23 0.0381 0.0204 0.0417 0.0049 0.0660 0.0979 0.0151 0.0160 0.0476 0.0324 0.0161 0.0253 0.0120 0.0423 0.0305 -0.0104 -0.0189 0.0254 -0.0044 0.0010 0.0212 0.0631 0.0262 0.0248 2023
2023-08-30 0.0299 0.0155 0.0089 0.0173 -0.0048 -0.0027 0.0033 -0.0054 0.0229 -0.0047 -0.0242 -0.0180 -0.0110 -0.0268 -0.0083 -0.0151 -0.0215 -0.0228 -0.0101 -0.0247 -0.0069 -0.0728 0.0010 0.0002 2023
2023-09-06 -0.0733 -0.0054 -0.0032 0.0284 -0.0788 0.0420 0.0293 0.0084 -0.0048 0.0220 0.0078 0.0194 0.0238 0.0301 0.0083 0.0179 -0.0354 0.0139 0.0215 -0.0019 -0.0065 0.0021 -0.0084 -0.0073 2023
2023-09-13 0.0156 -0.0094 0.0198 -0.0258 -0.0305 -0.0037 0.0088 0.0145 -0.0010 -0.0027 0.0175 -0.0111 0.0159 0.0327 0.0340 -0.0085 -0.0047 -0.0153 0.0279 0.0055 0.0097 0.0520 -0.0057 -0.0074 2023
2023-09-20 -0.0405 -0.0515 -0.0711 -0.0884 -0.0377 -0.0877 -0.0104 -0.0514 -0.0615 -0.0338 -0.0272 -0.0530 -0.0613 -0.0543 -0.0743 -0.0198 -0.0479 -0.0117 0.0027 0.0503 -0.0165 -0.0372 -0.0433 -0.0352 2023
2023-09-27 0.0026 0.0040 0.0296 -0.0101 0.0376 0.0098 -0.0294 -0.0277 -0.0197 -0.0252 -0.0154 -0.0475 -0.0499 -0.0562 -0.0518 -0.0234 0.0453 -0.0350 -0.0430 0.0079 -0.0412 0.0452 -0.0062 -0.0101 2023
2023-10-04 0.0342 0.0468 0.0416 0.0375 0.0511 0.0670 0.0107 0.0032 0.0369 0.0226 0.0204 0.0416 0.0293 0.0279 0.0267 0.0193 -0.0218 0.0179 0.0099 0.0286 0.0197 -0.0014 0.0309 0.0303 2023
2023-10-11 -0.0070 0.0111 0.0120 0.0153 -0.0415 -0.0338 -0.0132 -0.0372 -0.0158 -0.0073 0.0202 0.0223 0.0528 -0.0173 0.0025 -0.0144 -0.0127 0.0054 0.0019 0.0234 0.0328 0.0367 0.0032 0.0034 2023
2023-10-18 -0.0212 -0.0046 -0.0065 -0.0224 -0.0063 -0.1630 -0.0555 -0.0601 -0.0618 -0.0275 -0.0441 -0.0810 -0.0665 -0.0335 -0.1156 -0.0316 -0.0735 -0.0110 -0.0095 -0.0219 0.0258 0.1765 -0.0311 -0.0288 2023
2023-10-25 -0.0155 0.0227 -0.1122 0.0346 -0.0683 -0.0752 -0.1555 -0.0127 -0.0403 -0.0398 -0.0151 0.0336 0.0124 0.0147 -0.0104 -0.0193 0.0043 -0.0032 -0.0357 0.0199 0.0062 0.0224 -0.0123 -0.0129 2023
2023-11-01 0.0627 0.0642 0.0540 0.0698 0.1195 0.1010 0.0576 0.0074 -0.1412 -0.1230 0.0350 0.0668 0.0314 0.0648 0.0763 0.0171 0.0223 0.0126 0.0069 0.0042 -0.0082 0.0221 0.0447 0.0438 2023
2023-11-08 0.0304 0.0267 0.0200 0.0214 0.0775 0.0663 0.0224 -0.0074 0.0476 0.0269 0.0303 0.0370 0.0339 0.0446 0.0364 -0.0217 -0.0658 -0.0178 -0.0293 0.0049 -0.0026 0.0027 0.0279 0.0266 2023
2023-11-15 0.0182 0.0075 0.0248 -0.0131 0.0058 0.0158 -0.0204 -0.0107 0.0177 0.0148 0.0301 0.0149 0.0123 -0.0111 0.0020 0.0232 0.0483 0.0004 0.0048 -0.0016 0.0176 0.0077 0.0107 0.0101 2023
2023-11-22 -0.0013 0.0275 0.0017 0.0215 -0.0434 0.0226 0.0175 0.0349 0.0138 -0.0100 0.0037 -0.0044 0.0179 0.0080 -0.0205 0.0113 -0.0203 -0.0201 -0.0047 0.0017 0.0209 0.0548 0.0044 0.0037 2023
2023-11-29 0.0157 -0.0270 -0.0463 -0.0010 -0.0266 -0.0330 0.0219 0.1233 -0.0135 -0.0210 0.0284 0.0349 0.0255 0.0121 0.0419 0.0446 -0.0204 0.0586 0.0459 0.0178 -0.0112 0.1529 0.0054 0.0037 2023
2023-12-06 0.0066 0.0050 0.0116 0.0041 0.0232 -0.0072 0.0515 0.0252 -0.0051 0.0020 0.0160 0.0132 0.0435 0.0395 0.0419 -0.0222 -0.0177 -0.0178 0.0582 -0.0049 -0.0198 -0.0615 0.0166 0.0163 2023
2023-12-13 0.0114 -0.0030 0.0307 0.0419 0.0400 0.0818 0.0742 0.0707 0.0993 0.0709 0.0482 0.0863 0.0750 0.0812 0.0949 0.0089 -0.0148 0.0202 0.0023 -0.0405 0.0303 0.0196 0.0273 0.0229 2023
2023-12-20 -0.0199 0.0037 0.0350 -0.0025 -0.0066 -0.0024 0.0351 0.0072 0.0067 0.0179 -0.0004 0.0104 -0.0090 -0.0022 0.0100 -0.0020 0.0088 0.0179 0.0066 -0.0077 0.0136 0.0059 -0.0010 0.0058 2023
2023-12-27 -0.0391 -0.0102 -0.0240 -0.0229 -0.0228 -0.0324 -0.0236 -0.0022 0.0081 -0.0017 0.0217 0.0012 -0.0063 0.0174 0.0114 0.0242 0.0454 0.0508 0.0331 0.0365 -0.0052 0.0557 -0.0045 -0.0063 2023
2024-01-03 -0.0027 0.0132 0.0199 0.0096 0.0982 -0.0557 -0.0267 0.0135 -0.0918 -0.0564 -0.0083 -0.0080 -0.0008 -0.0118 -0.0198 0.0103 -0.0112 0.0448 0.0155 -0.0018 -0.0147 0.0259 0.0017 0.0026 2024
2024-01-10 -0.0082 0.0378 0.0109 0.0118 0.0592 -0.0662 -0.0326 -0.0320 -0.0180 -0.0256 -0.0096 -0.0459 -0.0514 -0.0086 -0.0684 -0.0069 -0.0374 0.0005 -0.0051 -0.0364 -0.0001 -0.0669 0.0029 0.0022 2024
2024-01-17 0.0610 0.0219 0.0314 0.0185 0.0601 -0.0502 -0.0079 -0.0045 0.0105 0.0102 0.0059 0.0200 0.0480 0.0008 0.0089 -0.0044 0.0039 0.0113 0.0461 -0.0070 0.0002 -0.0798 0.0203 0.0207 2024
2024-01-24 -0.0373 0.0240 0.0296 0.0189 0.0473 -0.0876 0.0354 0.0796 0.0604 0.0286 0.0422 0.0598 0.0413 0.0159 0.0101 -0.0065 -0.0509 0.0151 -0.0155 -0.0234 0.0034 0.0751 0.0115 0.0124 2024
2024-01-31 0.0067 -0.0076 -0.0498 0.0619 0.0832 -0.0345 0.0243 -0.0032 -0.0296 -0.0102 -0.0067 -0.0516 -0.0583 -0.0049 -0.0078 -0.0045 0.0325 0.0420 0.0495 0.0139 -0.0002 0.0031 0.0059 0.0063 2024
2024-02-07 -0.0228 0.0020 0.0072 -0.0030 0.0557 -0.0059 0.0493 0.0073 -0.0625 -0.0928 -0.0048 -0.0088 0.0060 -0.0163 -0.0250 -0.0101 -0.0195 -0.0115 0.0000 0.0120 -0.0216 0.1437 0.0004 0.0002 2024
2024-02-14 -0.0177 -0.0087 -0.0281 -0.0093 -0.0378 0.0516 -0.0345 0.0181 -0.0170 -0.0291 0.0309 0.0363 0.0706 0.0151 0.0163 0.0088 0.0227 0.0153 0.0141 0.0081 0.0158 0.0498 0.0046 0.0054 2024
2024-02-21 0.0059 0.0134 -0.0160 0.0379 0.1250 0.0303 0.0060 0.0296 0.0137 0.0171 0.0205 0.0094 0.0571 0.0162 0.0016 0.0271 -0.0257 0.0129 0.0183 -0.0148 0.0028 0.0878 0.0197 0.0203 2024
2024-02-28 -0.0710 -0.0119 -0.0457 0.0033 0.0883 -0.0999 0.0472 0.0116 0.0076 0.0206 0.0274 0.0319 0.0321 0.0003 0.0417 -0.0063 -0.0306 -0.0492 0.0009 -0.0817 0.0477 0.1112 0.0005 0.0005 2024
2024-03-06 0.0181 0.0309 0.0430 0.0073 0.0670 -0.0179 -0.0381 -0.0331 -0.0091 0.0418 0.0068 0.0230 0.0177 0.0001 -0.0236 0.0172 0.0714 -0.0014 0.0098 0.0337 0.0131 0.1137 0.0186 0.0188 2024
2024-03-13 0.0163 0.0147 0.0598 0.0029 -0.0277 -0.0357 0.0156 0.0570 -0.0101 -0.0236 0.0206 0.0019 -0.0105 0.0012 0.0156 -0.0410 -0.0137 -0.0038 -0.0070 0.0120 0.0001 -0.1437 0.0010 -0.0021 2024
2024-03-20 -0.0368 0.0006 0.0245 0.0136 0.0348 0.0364 0.0113 0.0583 -0.0172 0.0572 0.0100 0.0290 -0.0058 0.0441 0.0318 -0.0028 -0.0014 0.0331 -0.0026 -0.0020 0.0092 0.1226 0.0030 0.0091 2024
2024-03-27 -0.0051 -0.0005 0.0255 0.0133 -0.0342 -0.0642 0.0653 0.0200 0.0074 0.0319 0.0159 0.0056 0.0118 0.0097 0.0155 0.0125 -0.0015 0.0378 0.0083 -0.0719 0.0449 -0.0671 0.0032 0.0001 2024
2024-04-03 0.0049 0.0114 0.0131 0.0272 -0.0469 0.0597 0.0194 -0.0036 0.0227 0.0247 -0.0086 0.0115 0.0040 0.0014 0.0147 -0.0351 -0.0283 -0.0283 -0.0602 0.0034 0.0316 0.0549 0.0018 0.0009 2024
2024-04-10 -0.0017 -0.0278 -0.0141 -0.0127 0.0239 -0.1185 -0.1133 -0.0474 -0.0927 -0.0932 -0.0808 -0.0843 -0.0205 -0.0343 -0.0539 -0.0529 -0.0416 -0.0131 -0.0457 0.0198 0.0162 -0.0802 -0.0332 -0.0309 2024
2024-04-17 -0.0148 -0.0171 0.0247 -0.0208 -0.0588 -0.0824 0.0679 0.0556 -0.0238 0.0274 0.0608 0.1011 0.0772 0.0661 0.0505 0.0348 0.0242 0.0144 0.0515 0.0362 -0.0283 0.0399 0.0044 0.0042 2024
2024-04-24 0.0203 -0.0458 0.0282 -0.0256 0.0471 0.2365 -0.0630 -0.0127 0.0106 -0.0172 -0.0021 -0.0361 -0.0269 0.0064 -0.0316 -0.0338 -0.0270 0.0183 -0.0415 -0.0051 -0.0149 -0.0909 -0.0061 -0.0073 2024
2024-05-01 0.0685 0.0501 0.0507 0.0757 0.0469 -0.0303 0.0016 0.0167 0.1562 0.1160 0.0001 0.0222 0.0157 0.0393 0.0623 0.0282 0.0806 0.0089 -0.0006 0.0351 0.0110 0.0276 0.0307 0.0298 2024
2024-05-08 0.0272 0.0175 -0.0053 -0.0090 0.0088 -0.0015 0.0340 -0.0055 -0.0019 0.0212 0.0496 0.0170 0.0267 0.0325 0.0368 0.0177 0.0217 -0.0133 -0.0059 0.0255 0.0180 -0.0126 0.0132 0.0118 2024
2024-05-15 0.0273 0.0295 0.0431 -0.0212 0.0432 0.0497 -0.0236 -0.0024 -0.0064 -0.0294 -0.0099 0.0297 -0.0012 0.0257 0.0214 -0.0009 0.0213 0.0162 0.0083 0.0186 0.0278 0.1305 0.0136 0.0153 2024
2024-05-22 -0.0123 0.0048 -0.0082 -0.0055 0.1774 -0.0542 -0.0395 -0.0416 0.0099 -0.0155 -0.0001 -0.0084 -0.0327 -0.0228 -0.0286 -0.0384 -0.0091 -0.0364 -0.0477 -0.0387 -0.0273 -0.0266 -0.0038 -0.0029 2024
2024-05-29 0.0227 -0.0337 -0.0149 -0.0155 0.0220 -0.0113 0.0295 0.0491 0.0079 -0.0345 -0.0017 0.0091 -0.0132 -0.0099 -0.0214 0.0234 0.0412 0.0206 0.0428 0.0036 -0.0135 0.0327 -0.0057 -0.0027 2024
2024-06-05 0.0638 0.0391 0.0162 0.0431 0.0377 -0.0238 0.0066 0.0631 -0.0939 -0.0261 -0.0244 -0.0209 -0.0271 -0.0185 -0.0120 -0.0071 -0.0508 0.0240 0.0337 -0.0185 -0.0052 -0.0469 0.0136 0.0161 2024
2024-06-12 0.0339 0.0311 -0.0076 -0.0239 0.1146 0.0799 -0.0276 -0.0135 -0.0771 -0.0213 0.0135 0.0347 0.0331 0.0292 0.0222 -0.0076 -0.0224 -0.0296 0.0216 -0.0310 0.0061 -0.0331 0.0239 0.0213 2024
2024-06-19 -0.0247 0.0103 0.0498 0.0191 -0.0726 0.0134 0.0260 -0.0220 0.0381 -0.0043 0.0054 -0.0154 -0.0318 -0.0001 0.0024 0.0105 0.0209 0.0438 -0.0036 0.0114 -0.0042 -0.0526 -0.0038 -0.0067 2024
2024-06-26 0.0522 0.0183 0.0066 0.0707 -0.0275 0.2106 0.0625 0.0116 -0.0549 -0.0344 0.0529 0.0386 0.0638 0.0178 0.0187 -0.0079 -0.0057 -0.0399 -0.0285 0.0280 0.0046 0.0036 0.0081 0.0109 2024
2024-07-03 0.0375 0.0006 0.0200 -0.0033 0.0686 0.1261 0.0023 -0.0148 -0.0052 -0.0032 -0.0058 0.0119 -0.0180 0.0154 0.0293 0.0070 -0.0040 -0.0132 0.0125 -0.0124 0.0138 -0.0670 0.0130 0.0123 2024
2024-07-10 0.0265 -0.0220 -0.0271 -0.0322 -0.0390 -0.0222 0.1093 0.0731 0.0608 0.0862 0.0340 0.0634 0.0060 0.0619 0.0346 0.0266 0.0622 -0.0048 0.0068 0.1092 0.0436 0.1153 0.0175 0.0161 2024
2024-07-17 -0.0427 -0.0104 -0.0116 -0.0348 -0.0303 -0.0405 -0.0397 -0.0705 -0.0679 -0.0585 -0.0155 -0.0398 -0.0095 -0.0218 -0.0259 0.0088 0.0000 -0.0085 0.0322 0.0106 -0.0253 0.0127 -0.0213 -0.0198 2024
2024-07-24 -0.0280 -0.0506 -0.0653 -0.0255 -0.1671 -0.1014 -0.2436 -0.0475 -0.0141 -0.0031 0.0228 -0.0270 0.0057 0.0271 0.0025 0.0573 0.0621 -0.0762 0.0758 0.0383 -0.0003 0.0041 -0.0201 -0.0215 2024
2024-07-31 -0.0543 -0.0567 -0.0731 -0.1152 0.0050 -0.1040 -0.1029 -0.0854 0.0208 -0.0183 -0.0715 -0.1116 -0.1364 -0.0727 -0.1098 -0.0147 -0.0542 -0.0362 -0.0057 -0.0139 -0.0082 -0.1667 -0.0378 -0.0373 2024
2024-08-07 0.0656 0.0354 0.0364 0.0500 0.1080 0.0352 0.0361 0.0646 -0.0158 0.0003 0.0372 0.0409 0.0097 0.0452 0.0484 -0.0037 -0.0162 0.0287 0.0293 0.0103 0.0328 0.0785 0.0377 0.0374 2024
2024-08-14 0.0246 0.0257 0.0182 0.0496 0.0914 0.0619 0.0673 0.0596 0.0273 0.0199 0.0312 0.0060 0.0678 0.0109 0.0412 0.0111 0.0017 0.0065 0.0254 0.0111 0.0191 -0.0267 0.0298 0.0303 2024
2024-08-21 0.0067 -0.0243 -0.0151 -0.0327 0.0082 -0.0553 0.0422 0.0687 0.0139 0.0345 0.0260 0.0250 0.0020 0.0197 0.0128 0.0173 -0.0028 0.0117 -0.0012 0.0115 0.0040 0.0083 0.0051 0.0051 2024
2024-08-28 -0.0233 -0.0107 -0.0455 0.0179 -0.1722 0.0066 -0.0145 -0.0172 -0.0102 -0.0168 0.0005 0.0256 0.0368 -0.0398 -0.0279 0.0331 -0.0182 0.0007 0.0090 0.0191 -0.0134 -0.0355 -0.0161 -0.0170 2024
2024-09-04 -0.0120 0.0116 -0.0569 0.0186 0.0009 0.0713 -0.0620 -0.0771 -0.0698 -0.0441 -0.0693 -0.0355 -0.0787 -0.0367 -0.0271 0.0013 0.0496 -0.0108 0.0084 0.0006 0.0101 0.0038 -0.0064 -0.0060 2024
2024-09-11 -0.0152 0.0493 0.0706 0.0400 0.0670 0.0075 0.0547 0.0610 0.0714 0.0416 0.0178 0.0133 0.0103 0.0383 0.0328 -0.0019 0.0030 0.0253 -0.0300 -0.0358 0.0201 0.0451 0.0280 0.0257 2024
2024-09-18 0.0476 -0.0138 0.0185 0.0372 0.0448 0.1096 -0.0028 0.0115 0.0266 0.0647 0.0111 -0.0025 -0.0064 0.0257 0.0271 -0.0260 -0.0111 -0.0219 0.0003 -0.0013 0.0361 0.0641 0.0167 0.0145 2024
2024-09-25 -0.0051 -0.0200 0.0285 -0.0466 -0.0325 0.0146 -0.0111 -0.0687 -0.0223 0.0110 -0.0217 -0.0058 0.0225 -0.0159 0.0178 -0.0049 -0.0285 -0.0019 0.0177 0.0140 -0.0019 -0.0554 -0.0084 -0.0016 2024
2024-10-02 -0.0019 -0.0143 -0.0158 -0.0131 0.1273 -0.0538 -0.0245 0.0249 -0.0131 -0.0231 0.0178 0.0179 0.0339 0.0130 0.0290 -0.0143 0.0176 -0.0557 -0.0203 -0.0030 -0.0133 0.0211 0.0117 0.0080 2024
2024-10-09 0.0352 0.0097 0.0065 0.0268 -0.0098 -0.1075 0.0328 0.0392 0.0057 0.0086 0.0599 0.0539 0.0953 0.0507 0.0431 0.0272 0.0089 0.0274 -0.0060 -0.0445 0.0145 0.0760 0.0115 0.0115 2024
2024-10-16 0.0086 0.0207 -0.0019 0.0107 0.0872 -0.0073 0.0246 0.1159 -0.0046 -0.0228 0.0077 0.0038 0.0278 -0.0078 0.0529 -0.0040 -0.0206 -0.0448 -0.0083 0.0241 0.0321 0.0048 0.0031 0.0061 2024
2024-10-23 -0.0093 0.0103 0.0271 0.0059 -0.0164 0.1745 -0.0651 -0.0416 -0.0076 0.0009 -0.0055 0.0054 0.0075 0.0115 0.0082 -0.0208 -0.0133 -0.0277 0.0036 -0.0137 0.0085 0.0766 -0.0019 -0.0027 2024
2024-10-30 -0.0447 -0.0486 0.0004 0.0444 -0.0095 -0.0316 0.0181 0.0411 -0.2246 -0.0059 -0.0063 -0.0154 -0.0190 0.0051 -0.0126 -0.0109 -0.0167 -0.0203 0.0626 0.0087 -0.0106 -0.0473 -0.0071 -0.0088 2024
2024-11-06 0.0035 0.0277 0.0676 0.0461 0.0582 0.2673 0.0461 0.0668 0.0204 0.0324 0.0784 0.0908 0.1250 0.1174 0.1239 -0.0367 -0.0665 -0.0307 -0.1645 0.0807 -0.0541 0.2375 0.0365 0.0344 2024
2024-11-13 0.0190 -0.0125 -0.0195 -0.0208 -0.0087 0.0519 0.0090 -0.0409 -0.0788 -0.0589 0.0146 0.0119 0.0171 -0.0191 -0.0005 0.0024 -0.0271 -0.0209 -0.0268 -0.0632 0.0132 0.0487 -0.0118 -0.0111 2024
2024-11-20 0.0293 0.0241 -0.0518 0.0158 -0.0711 -0.0227 0.0045 -0.0058 0.0591 0.0309 0.0279 0.0285 0.0520 0.0406 -0.0073 0.0099 0.0263 0.0513 0.0839 0.0503 -0.0012 -0.0039 0.0189 0.0174 2024
2024-11-27 0.0318 0.0095 0.0130 0.0265 0.0241 0.0383 -0.0255 -0.0208 0.0077 -0.0094 -0.0208 -0.0197 -0.0424 -0.0057 -0.0064 -0.0061 -0.0082 0.0023 0.0020 -0.0026 0.0040 0.0427 0.0050 0.0054 2024
2024-12-04 0.0209 0.0277 0.0776 0.0529 -0.0377 0.1320 -0.0243 -0.0173 0.0475 0.0254 -0.0080 -0.0231 -0.0286 -0.0238 -0.0284 -0.0208 0.0004 -0.0084 -0.0326 -0.0684 0.0189 0.0070 -0.0021 -0.0018 2024
2024-12-11 0.0228 0.0248 0.0550 0.0268 -0.0352 0.1796 -0.0575 -0.0284 -0.0096 -0.0404 -0.0187 -0.0099 -0.0174 -0.0178 0.0075 -0.0191 0.0331 -0.0094 -0.0017 -0.1481 -0.0189 0.0934 -0.0016 0.0025 2024
2024-12-18 0.0184 -0.0339 0.0035 -0.0091 0.0727 -0.0373 0.0050 0.0451 0.0355 -0.0324 0.0164 -0.0150 0.0110 0.0140 -0.0053 -0.0038 0.0117 0.0019 0.0260 0.0415 -0.0103 -0.0729 0.0004 -0.0050 2024
2024-12-25 -0.0306 -0.0414 -0.0353 -0.0431 -0.0432 -0.1352 -0.0120 -0.0045 0.0088 -0.0122 -0.0108 -0.0097 -0.0190 -0.0176 -0.0106 -0.0085 -0.0079 0.0003 -0.0129 -0.0005 0.0029 -0.0546 -0.0258 -0.0223 2024

a) Efficient frontier

library(quadprog)
library(dplyr)
library(ggplot2)

compute_efficient_frontier <- function(returns_data, n_points = 150, buffer = 0.1) {
  R <- as.matrix(returns_data[, -1])
  mu <- colMeans(R)
  cov_matrix <- cov(R)

  
  mu_annual <- mu * 52
  min_ret <- min(mu_annual) * (1 - buffer)
  max_ret <- max(mu_annual) * (1 + buffer)
  target_returns <- seq(min_ret / 52, max_ret / 52, length.out = n_points)

  eff_data <- data.frame(Return = numeric(n_points), Risk = numeric(n_points))

  for (i in seq_along(target_returns)) {
    Dmat <- 2 * cov_matrix
    dvec <- rep(0, ncol(R))
    Amat <- cbind(rep(1, ncol(R)), mu)
    bvec <- c(1, target_returns[i])

    result <- tryCatch(
      solve.QP(Dmat, dvec, Amat, bvec, meq = 2),
      error = function(e) return(NULL)
    )

    if (!is.null(result)) {
      w <- result$solution
      port_return <- sum(w * mu) * 52
      port_sd <- sqrt(t(w) %*% cov_matrix %*% w) * sqrt(52)
      eff_data[i, ] <- c(port_return, port_sd)
    } else {
      eff_data[i, ] <- c(NA, NA)
    }
  }

  return(na.omit(eff_data))
}
stock_tickers <- c("AAPL", "MSFT", "GOOGL", "AMZN", "NVDA", "TSLA", "F", "GM", "APTV", "BWA",
                   "JPM", "BAC", "WFC", "GS", "MS", "JNJ", "PFE", "MRK", "UNH", "ABBV")
gold_ticker <- "GLD"
crypto_ticker <- "BTC-USD"
esg_ticker <- "ESGU"

# Subsets
returns_20 <- weekly_returns %>% select(date, all_of(stock_tickers))
returns_gold <- weekly_returns %>% select(date, all_of(c(stock_tickers, gold_ticker)))
returns_crypto <- weekly_returns %>% select(date, all_of(c(stock_tickers, gold_ticker, crypto_ticker)))
returns_full <- weekly_returns %>% select(date, all_of(c(stock_tickers, gold_ticker, crypto_ticker, esg_ticker)))
clean_efficient_curve <- function(data) {
  data <- data[order(data$Risk), ]  # sort by risk (x-axis)
  data_clean <- data[1, , drop = FALSE]

  for (i in 2:nrow(data)) {
    if (data$Return[i] >= tail(data_clean$Return, 1)) {
      data_clean <- rbind(data_clean, data[i, ])
    }
  }

  return(data_clean)
}
eff_20 <- compute_efficient_frontier(returns_20)
eff_20$Group <- "20 Stocks"

eff_gold <- compute_efficient_frontier(returns_gold)
eff_gold$Group <- "20 Stocks + Gold"

eff_crypto <- compute_efficient_frontier(returns_crypto)
eff_crypto$Group <- "Stocks + Gold + Crypto"

eff_full <- compute_efficient_frontier(returns_full)
eff_full$Group <- "Stocks + Gold + Crypto + ESG"

# Combine
all_eff <- bind_rows(eff_20, eff_gold, eff_crypto, eff_full)
eff_20_clean <- clean_efficient_curve(eff_20)
eff_20_clean$Group <- "20 Stocks"

eff_gold_clean <- clean_efficient_curve(eff_gold)
eff_gold_clean$Group <- "20 Stocks + Gold"

eff_crypto_clean <- clean_efficient_curve(eff_crypto)
eff_crypto_clean$Group <- "Stocks + Gold + Crypto"

eff_full_clean <- clean_efficient_curve(eff_full)
eff_full_clean$Group <- "Stocks + Gold + Crypto + ESG"

all_eff_clean <- bind_rows(eff_20_clean, eff_gold_clean, eff_crypto_clean, eff_full_clean)
ggplot(all_eff_clean, aes(x = Risk, y = Return, color = Group)) +
  geom_line(size = 1.4) +
  labs(title = "Efficient Frontier",
       x = "Annualized Risk (σ)",
       y = "Annualized Return") +
  theme_minimal() +
  scale_color_manual(values = c(
    "20 Stocks" = "blue",
    "20 Stocks + Gold" = "orange",
    "Stocks + Gold + Crypto" = "green",
    "Stocks + Gold + Crypto + ESG" = "red"
  ))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

plot_frontier <- function(data, title) {
  ggplot(data, aes(x = Risk, y = Return)) +
    geom_line(color = "steelblue", size = 1.2) +
    labs(title = title, x = "Annualized Risk", y = "Annualized Return") +
    theme_minimal()
}

plot_frontier(eff_20_clean, "Efficient Frontier: 20 Stocks")

plot_frontier(eff_gold_clean, "Efficient Frontier: Stocks + Gold")

plot_frontier(eff_crypto_clean, "Efficient Frontier: Stocks + Gold + Crypto")

plot_frontier(eff_full_clean, "Efficient Frontier: Stocks + Gold + Crypto + ESG")

# Annualized table with Sharpe ratios
create_annual_frontier_table <- function(frontier_data, rf_rate) {
  frontier_data %>%
    mutate(Portfolio = row_number(),
           Sharpe = (Return - rf_rate) / Risk) %>%
    select(Portfolio, Return, Risk, Sharpe)
}
eff_20_table <- create_annual_frontier_table(eff_20_clean, rf_annual)
eff_gold_table <- create_annual_frontier_table(eff_gold_clean, rf_annual)
eff_crypto_table <- create_annual_frontier_table(eff_crypto_clean, rf_annual)
eff_full_table <- create_annual_frontier_table(eff_full_clean, rf_annual)
kable(eff_20_table, caption = "Efficient Frontier: 20 Stocks (Annualized)", digits = 4, row.names = "False")
Efficient Frontier: 20 Stocks (Annualized)
Portfolio Return Risk Sharpe
1 0.0945 0.1420 0.5529
2 0.0996 0.1420 0.5887
3 0.1047 0.1421 0.6242
4 0.1097 0.1422 0.6595
5 0.1148 0.1424 0.6945
6 0.1199 0.1426 0.7292
7 0.1250 0.1428 0.7636
8 0.1301 0.1431 0.7976
9 0.1352 0.1434 0.8312
10 0.1403 0.1438 0.8644
11 0.1454 0.1443 0.8971
12 0.1505 0.1447 0.9293
13 0.1555 0.1452 0.9611
14 0.1606 0.1458 0.9923
15 0.1657 0.1464 1.0230
16 0.1708 0.1470 1.0532
17 0.1759 0.1477 1.0828
18 0.1810 0.1484 1.1118
19 0.1861 0.1492 1.1402
20 0.1912 0.1500 1.1680
21 0.1963 0.1508 1.1952
22 0.2013 0.1517 1.2218
23 0.2064 0.1526 1.2478
24 0.2115 0.1536 1.2732
25 0.2166 0.1546 1.2979
26 0.2217 0.1556 1.3220
27 0.2268 0.1567 1.3456
28 0.2319 0.1578 1.3685
29 0.2370 0.1589 1.3908
30 0.2421 0.1601 1.4124
31 0.2471 0.1613 1.4335
32 0.2522 0.1625 1.4540
33 0.2573 0.1638 1.4739
34 0.2624 0.1650 1.4933
35 0.2675 0.1664 1.5121
36 0.2726 0.1677 1.5303
37 0.2777 0.1691 1.5480
38 0.2828 0.1705 1.5651
39 0.2879 0.1719 1.5817
40 0.2929 0.1734 1.5978
41 0.2980 0.1748 1.6134
42 0.3031 0.1763 1.6285
43 0.3082 0.1779 1.6432
44 0.3133 0.1794 1.6573
45 0.3184 0.1810 1.6711
46 0.3235 0.1826 1.6843
47 0.3286 0.1842 1.6972
48 0.3337 0.1858 1.7096
49 0.3387 0.1875 1.7216
50 0.3438 0.1892 1.7333
51 0.3489 0.1909 1.7445
52 0.3540 0.1926 1.7554
53 0.3591 0.1943 1.7659
54 0.3642 0.1961 1.7761
55 0.3693 0.1978 1.7859
56 0.3744 0.1996 1.7954
57 0.3795 0.2014 1.8046
58 0.3845 0.2032 1.8135
59 0.3896 0.2051 1.8221
60 0.3947 0.2069 1.8303
61 0.3998 0.2088 1.8384
62 0.4049 0.2107 1.8461
63 0.4100 0.2126 1.8536
64 0.4151 0.2145 1.8608
65 0.4202 0.2164 1.8678
66 0.4253 0.2183 1.8746
67 0.4304 0.2203 1.8811
68 0.4354 0.2222 1.8874
69 0.4405 0.2242 1.8935
70 0.4456 0.2262 1.8994
71 0.4507 0.2282 1.9051
72 0.4558 0.2302 1.9107
73 0.4609 0.2322 1.9160
74 0.4660 0.2342 1.9211
75 0.4711 0.2363 1.9261
76 0.4762 0.2383 1.9309
77 0.4812 0.2404 1.9356
78 0.4863 0.2424 1.9401
79 0.4914 0.2445 1.9444
80 0.4965 0.2466 1.9486
81 0.5016 0.2487 1.9527
82 0.5067 0.2508 1.9566
83 0.5118 0.2529 1.9604
84 0.5169 0.2550 1.9641
85 0.5220 0.2572 1.9676
86 0.5270 0.2593 1.9711
87 0.5321 0.2614 1.9744
88 0.5372 0.2636 1.9776
89 0.5423 0.2657 1.9807
90 0.5474 0.2679 1.9837
91 0.5525 0.2701 1.9866
92 0.5576 0.2722 1.9894
93 0.5627 0.2744 1.9921
94 0.5678 0.2766 1.9948
95 0.5728 0.2788 1.9973
96 0.5779 0.2810 1.9998
97 0.5830 0.2832 2.0022
98 0.5881 0.2854 2.0045
99 0.5932 0.2877 2.0067
100 0.5983 0.2899 2.0088
101 0.6034 0.2921 2.0109
102 0.6085 0.2943 2.0129
103 0.6136 0.2966 2.0149
104 0.6186 0.2988 2.0168
105 0.6237 0.3011 2.0186
106 0.6288 0.3033 2.0204
107 0.6339 0.3056 2.0221
108 0.6390 0.3079 2.0238
109 0.6441 0.3101 2.0254
110 0.6492 0.3124 2.0269
111 0.6543 0.3147 2.0284
112 0.6594 0.3170 2.0299
113 0.6644 0.3193 2.0313
114 0.6695 0.3215 2.0326
115 0.6746 0.3238 2.0339
116 0.6797 0.3261 2.0352
117 0.6848 0.3284 2.0364
kable(eff_gold_table, caption = "Efficient Frontier: 20 Stocks + Gold (Annualized)", digits = 4, row.names = "False")
Efficient Frontier: 20 Stocks + Gold (Annualized)
Portfolio Return Risk Sharpe
1 0.0945 0.1062 0.7390
2 0.0996 0.1063 0.7866
3 0.1047 0.1064 0.8338
4 0.1097 0.1065 0.8803
5 0.1148 0.1068 0.9262
6 0.1199 0.1070 0.9713
7 0.1250 0.1074 1.0156
8 0.1301 0.1078 1.0591
9 0.1352 0.1082 1.1017
10 0.1403 0.1087 1.1432
11 0.1454 0.1093 1.1838
12 0.1505 0.1099 1.2233
13 0.1555 0.1106 1.2617
14 0.1606 0.1114 1.2991
15 0.1657 0.1122 1.3353
16 0.1708 0.1130 1.3703
17 0.1759 0.1139 1.4042
18 0.1810 0.1148 1.4370
19 0.1861 0.1158 1.4686
20 0.1912 0.1169 1.4990
21 0.1963 0.1180 1.5283
22 0.2013 0.1191 1.5565
23 0.2064 0.1203 1.5836
24 0.2115 0.1215 1.6096
25 0.2166 0.1228 1.6346
26 0.2217 0.1241 1.6585
27 0.2268 0.1254 1.6814
28 0.2319 0.1268 1.7033
29 0.2370 0.1282 1.7242
30 0.2421 0.1296 1.7442
31 0.2471 0.1311 1.7634
32 0.2522 0.1326 1.7816
33 0.2573 0.1342 1.7990
34 0.2624 0.1357 1.8157
35 0.2675 0.1373 1.8315
36 0.2726 0.1390 1.8466
37 0.2777 0.1406 1.8610
38 0.2828 0.1423 1.8747
39 0.2879 0.1440 1.8877
40 0.2929 0.1458 1.9001
41 0.2980 0.1475 1.9119
42 0.3031 0.1493 1.9232
43 0.3082 0.1511 1.9339
44 0.3133 0.1530 1.9440
45 0.3184 0.1548 1.9537
46 0.3235 0.1567 1.9629
47 0.3286 0.1586 1.9716
48 0.3337 0.1605 1.9799
49 0.3387 0.1624 1.9878
50 0.3438 0.1643 1.9953
51 0.3489 0.1663 2.0024
52 0.3540 0.1683 2.0092
53 0.3591 0.1702 2.0156
54 0.3642 0.1722 2.0217
55 0.3693 0.1743 2.0275
56 0.3744 0.1763 2.0330
57 0.3795 0.1783 2.0382
58 0.3845 0.1804 2.0432
59 0.3896 0.1825 2.0479
60 0.3947 0.1846 2.0523
61 0.3998 0.1866 2.0566
62 0.4049 0.1888 2.0606
63 0.4100 0.1909 2.0644
64 0.4151 0.1930 2.0680
65 0.4202 0.1951 2.0714
66 0.4253 0.1973 2.0747
67 0.4304 0.1994 2.0777
68 0.4354 0.2016 2.0806
69 0.4405 0.2038 2.0834
70 0.4456 0.2060 2.0860
71 0.4507 0.2082 2.0885
72 0.4558 0.2104 2.0908
73 0.4609 0.2126 2.0930
74 0.4660 0.2148 2.0951
75 0.4711 0.2170 2.0971
76 0.4762 0.2192 2.0990
77 0.4812 0.2215 2.1007
78 0.4863 0.2237 2.1024
79 0.4914 0.2260 2.1040
80 0.4965 0.2282 2.1055
81 0.5016 0.2305 2.1069
82 0.5067 0.2328 2.1082
83 0.5118 0.2350 2.1094
84 0.5169 0.2373 2.1106
85 0.5220 0.2396 2.1117
86 0.5270 0.2419 2.1127
87 0.5321 0.2442 2.1136
88 0.5372 0.2465 2.1145
89 0.5423 0.2488 2.1154
90 0.5474 0.2511 2.1162
91 0.5525 0.2534 2.1169
92 0.5576 0.2558 2.1176
93 0.5627 0.2581 2.1182
94 0.5678 0.2604 2.1188
95 0.5728 0.2628 2.1193
96 0.5779 0.2651 2.1198
97 0.5830 0.2674 2.1203
98 0.5881 0.2698 2.1207
99 0.5932 0.2721 2.1211
100 0.5983 0.2745 2.1215
101 0.6034 0.2768 2.1218
102 0.6085 0.2792 2.1221
103 0.6136 0.2816 2.1223
104 0.6186 0.2839 2.1225
105 0.6237 0.2863 2.1227
106 0.6288 0.2887 2.1229
107 0.6339 0.2911 2.1231
108 0.6390 0.2934 2.1232
109 0.6441 0.2958 2.1233
110 0.6492 0.2982 2.1234
111 0.6543 0.3006 2.1234
112 0.6594 0.3030 2.1235
113 0.6644 0.3054 2.1235
114 0.6695 0.3078 2.1235
115 0.6746 0.3102 2.1235
116 0.6797 0.3126 2.1234
117 0.6848 0.3150 2.1234
kable(eff_crypto_table, caption = "Efficient Frontier: Stocks + Gold + Crypto (Annualized)", digits = 4, row.names = "False")
Efficient Frontier: Stocks + Gold + Crypto (Annualized)
Portfolio Return Risk Sharpe
1 0.0894 0.1057 0.6949
2 0.0945 0.1057 0.7428
3 0.0996 0.1058 0.7902
4 0.1047 0.1060 0.8371
5 0.1097 0.1062 0.8834
6 0.1148 0.1064 0.9290
7 0.1199 0.1068 0.9739
8 0.1250 0.1071 1.0179
9 0.1301 0.1076 1.0611
10 0.1352 0.1081 1.1033
11 0.1403 0.1086 1.1446
12 0.1454 0.1092 1.1849
13 0.1505 0.1099 1.2242
14 0.1555 0.1106 1.2624
15 0.1606 0.1113 1.2996
16 0.1657 0.1121 1.3356
17 0.1708 0.1130 1.3705
18 0.1759 0.1139 1.4043
19 0.1810 0.1148 1.4370
20 0.1861 0.1158 1.4686
21 0.1912 0.1169 1.4990
22 0.1963 0.1180 1.5284
23 0.2013 0.1191 1.5567
24 0.2064 0.1203 1.5839
25 0.2115 0.1215 1.6101
26 0.2166 0.1227 1.6352
27 0.2217 0.1240 1.6594
28 0.2268 0.1253 1.6825
29 0.2319 0.1267 1.7047
30 0.2370 0.1280 1.7260
31 0.2421 0.1295 1.7464
32 0.2471 0.1309 1.7659
33 0.2522 0.1324 1.7845
34 0.2573 0.1339 1.8024
35 0.2624 0.1355 1.8194
36 0.2675 0.1370 1.8357
37 0.2726 0.1386 1.8513
38 0.2777 0.1402 1.8662
39 0.2828 0.1419 1.8804
40 0.2879 0.1436 1.8939
41 0.2929 0.1453 1.9069
42 0.2980 0.1470 1.9192
43 0.3031 0.1487 1.9310
44 0.3082 0.1505 1.9423
45 0.3133 0.1523 1.9530
46 0.3184 0.1541 1.9632
47 0.3235 0.1559 1.9729
48 0.3286 0.1577 1.9822
49 0.3337 0.1596 1.9911
50 0.3387 0.1614 1.9995
51 0.3438 0.1633 2.0076
52 0.3489 0.1652 2.0153
53 0.3540 0.1671 2.0226
54 0.3591 0.1691 2.0296
55 0.3642 0.1710 2.0362
56 0.3693 0.1730 2.0425
57 0.3744 0.1750 2.0486
58 0.3795 0.1769 2.0543
59 0.3845 0.1789 2.0598
60 0.3896 0.1810 2.0650
61 0.3947 0.1830 2.0700
62 0.3998 0.1850 2.0747
63 0.4049 0.1871 2.0792
64 0.4100 0.1891 2.0835
65 0.4151 0.1912 2.0876
66 0.4202 0.1933 2.0915
67 0.4253 0.1953 2.0952
68 0.4304 0.1974 2.0988
69 0.4354 0.1995 2.1021
70 0.4405 0.2017 2.1053
71 0.4456 0.2038 2.1084
72 0.4507 0.2059 2.1113
73 0.4558 0.2081 2.1141
74 0.4609 0.2102 2.1167
75 0.4660 0.2123 2.1192
76 0.4711 0.2145 2.1216
77 0.4762 0.2167 2.1239
78 0.4812 0.2188 2.1260
79 0.4863 0.2210 2.1281
80 0.4914 0.2232 2.1300
81 0.4965 0.2254 2.1319
82 0.5016 0.2276 2.1336
83 0.5067 0.2298 2.1353
84 0.5118 0.2320 2.1369
85 0.5169 0.2342 2.1384
86 0.5220 0.2365 2.1398
87 0.5270 0.2387 2.1412
88 0.5321 0.2409 2.1425
89 0.5372 0.2432 2.1437
90 0.5423 0.2454 2.1449
91 0.5474 0.2476 2.1460
92 0.5525 0.2499 2.1470
93 0.5576 0.2521 2.1480
94 0.5627 0.2544 2.1489
95 0.5678 0.2567 2.1498
96 0.5728 0.2589 2.1506
97 0.5779 0.2612 2.1514
98 0.5830 0.2635 2.1521
99 0.5881 0.2658 2.1528
100 0.5932 0.2680 2.1535
101 0.5983 0.2703 2.1541
102 0.6034 0.2726 2.1547
103 0.6085 0.2749 2.1552
104 0.6136 0.2772 2.1557
105 0.6186 0.2795 2.1562
106 0.6237 0.2818 2.1566
107 0.6288 0.2841 2.1570
108 0.6339 0.2864 2.1574
109 0.6390 0.2887 2.1577
110 0.6441 0.2911 2.1580
111 0.6492 0.2934 2.1583
112 0.6543 0.2957 2.1586
113 0.6594 0.2980 2.1589
114 0.6644 0.3003 2.1591
115 0.6695 0.3027 2.1593
116 0.6746 0.3050 2.1595
117 0.6797 0.3073 2.1596
118 0.6848 0.3097 2.1598
kable(eff_full_table, caption = "Efficient Frontier: Stocks + Gold + Crypto + ESG (Annualized)", digits = 4, row.names = "False")
Efficient Frontier: Stocks + Gold + Crypto + ESG (Annualized)
Portfolio Return Risk Sharpe
1 0.0741 0.1044 0.5569
2 0.0792 0.1044 0.6056
3 0.0843 0.1045 0.6539
4 0.0894 0.1046 0.7019
5 0.0945 0.1048 0.7493
6 0.0996 0.1050 0.7963
7 0.1047 0.1053 0.8427
8 0.1097 0.1056 0.8884
9 0.1148 0.1059 0.9334
10 0.1199 0.1063 0.9776
11 0.1250 0.1068 1.0211
12 0.1301 0.1073 1.0637
13 0.1352 0.1079 1.1054
14 0.1403 0.1085 1.1462
15 0.1454 0.1091 1.1861
16 0.1505 0.1098 1.2250
17 0.1555 0.1105 1.2629
18 0.1606 0.1113 1.2998
19 0.1657 0.1121 1.3356
20 0.1708 0.1130 1.3705
21 0.1759 0.1139 1.4043
22 0.1810 0.1148 1.4372
23 0.1861 0.1158 1.4689
24 0.1912 0.1168 1.4997
25 0.1963 0.1179 1.5295
26 0.2013 0.1190 1.5583
27 0.2064 0.1201 1.5861
28 0.2115 0.1212 1.6129
29 0.2166 0.1224 1.6388
30 0.2217 0.1237 1.6638
31 0.2268 0.1249 1.6879
32 0.2319 0.1262 1.7111
33 0.2370 0.1275 1.7334
34 0.2421 0.1288 1.7549
35 0.2471 0.1302 1.7755
36 0.2522 0.1316 1.7954
37 0.2573 0.1330 1.8146
38 0.2624 0.1345 1.8329
39 0.2675 0.1359 1.8506
40 0.2726 0.1374 1.8676
41 0.2777 0.1389 1.8839
42 0.2828 0.1405 1.8995
43 0.2879 0.1420 1.9146
44 0.2929 0.1436 1.9290
45 0.2980 0.1452 1.9429
46 0.3031 0.1468 1.9562
47 0.3082 0.1484 1.9690
48 0.3133 0.1501 1.9812
49 0.3184 0.1517 1.9930
50 0.3235 0.1534 2.0043
51 0.3286 0.1551 2.0152
52 0.3337 0.1568 2.0256
53 0.3387 0.1586 2.0356
54 0.3438 0.1603 2.0451
55 0.3489 0.1621 2.0543
56 0.3540 0.1639 2.0632
57 0.3591 0.1656 2.0717
58 0.3642 0.1674 2.0798
59 0.3693 0.1692 2.0876
60 0.3744 0.1711 2.0951
61 0.3795 0.1729 2.1023
62 0.3845 0.1748 2.1092
63 0.3896 0.1766 2.1159
64 0.3947 0.1785 2.1222
65 0.3998 0.1804 2.1283
66 0.4049 0.1822 2.1342
67 0.4100 0.1841 2.1399
68 0.4151 0.1860 2.1453
69 0.4202 0.1880 2.1505
70 0.4253 0.1899 2.1555
71 0.4304 0.1918 2.1603
72 0.4354 0.1938 2.1649
73 0.4405 0.1957 2.1694
74 0.4456 0.1977 2.1737
75 0.4507 0.1996 2.1778
76 0.4558 0.2016 2.1817
77 0.4609 0.2036 2.1855
78 0.4660 0.2056 2.1891
79 0.4711 0.2076 2.1926
80 0.4762 0.2096 2.1960
81 0.4812 0.2116 2.1992
82 0.4863 0.2136 2.2024
83 0.4914 0.2156 2.2054
84 0.4965 0.2176 2.2082
85 0.5016 0.2196 2.2110
86 0.5067 0.2217 2.2137
87 0.5118 0.2237 2.2162
88 0.5169 0.2258 2.2187
89 0.5220 0.2278 2.2211
90 0.5270 0.2299 2.2234
91 0.5321 0.2319 2.2256
92 0.5372 0.2340 2.2277
93 0.5423 0.2361 2.2297
94 0.5474 0.2381 2.2317
95 0.5525 0.2402 2.2336
96 0.5576 0.2423 2.2354
97 0.5627 0.2444 2.2371
98 0.5678 0.2465 2.2388
99 0.5728 0.2486 2.2404
100 0.5779 0.2507 2.2420
101 0.5830 0.2528 2.2435
102 0.5881 0.2549 2.2449
103 0.5932 0.2570 2.2463
104 0.5983 0.2591 2.2476
105 0.6034 0.2612 2.2489
106 0.6085 0.2633 2.2501
107 0.6136 0.2654 2.2513
108 0.6186 0.2676 2.2525
109 0.6237 0.2697 2.2536
110 0.6288 0.2718 2.2546
111 0.6339 0.2740 2.2556
112 0.6390 0.2761 2.2566
113 0.6441 0.2782 2.2576
114 0.6492 0.2804 2.2585
115 0.6543 0.2825 2.2593
116 0.6594 0.2847 2.2602
117 0.6644 0.2868 2.2610
118 0.6695 0.2890 2.2618
119 0.6746 0.2911 2.2625
120 0.6797 0.2933 2.2632
121 0.6848 0.2954 2.2639

b) Minimum variance porfolio

compute_mvp <- function(returns_data) {
  R <- as.matrix(returns_data[,-1])
  cov_matrix <- cov(R)
  n_assets <- ncol(R)

  Dmat <- 2 * cov_matrix
  dvec <- rep(0, n_assets)
  Amat <- matrix(1, nrow = n_assets)
  bvec <- 1

  sol <- solve.QP(Dmat, dvec, Amat, bvec, meq = 1)
  weights <- sol$solution
  mu <- colMeans(R)

  exp_return <- sum(weights * mu) * 52  # annualized
  risk <- sqrt(t(weights) %*% cov_matrix %*% weights) * sqrt(52)  # annualized

  return(list(weights = weights, return = exp_return, risk = risk))
}
mvp_20 <- compute_mvp(returns_20)
mvp_gold <- compute_mvp(returns_gold)
mvp_crypto <- compute_mvp(returns_crypto)
mvp_full <- compute_mvp(returns_full)
mvp_table <- data.frame(
  Portfolio = c("20 Stocks", "20 + Gold", "20 + Gold + Crypto", "20 + Gold + Crypto + ESG"),
  Return = c(mvp_20$return, mvp_gold$return, mvp_crypto$return, mvp_full$return),
  Risk = c(mvp_20$risk, mvp_gold$risk, mvp_crypto$risk, mvp_full$risk)
) %>%
  mutate(
    Sharpe = (Return - rf_annual) / Risk
  )

library(knitr)
kable(mvp_table, caption = "Minimum Variance Portfolios (Annualized)", digits = 4)
Minimum Variance Portfolios (Annualized)
Portfolio Return Risk Sharpe
20 Stocks 0.0949 0.1420 0.5560
20 + Gold 0.0941 0.1062 0.7359
20 + Gold + Crypto 0.0889 0.1057 0.6906
20 + Gold + Crypto + ESG 0.0758 0.1044 0.5729
# Adding MVP points to efficient frontiers
mvp_points <- data.frame(
  Risk = c(mvp_20$risk, mvp_gold$risk, mvp_crypto$risk, mvp_full$risk),
  Return = c(mvp_20$return, mvp_gold$return, mvp_crypto$return, mvp_full$return),
  Group = c("20 Stocks", "20 Stocks + Gold", "Stocks + Gold + Crypto", "Stocks + Gold + Crypto + ESG")
)

# Plot all frontiers + MVP points
ggplot(all_eff_clean, aes(x = Risk, y = Return, color = Group)) +
  geom_line(size = 1.2) +
  geom_point(data = mvp_points, aes(x = Risk, y = Return, color = Group), size = 4, shape = 21, fill = "white", stroke = 1.5) +
  labs(title = "Efficient Frontier with MVP (Annualized)",
       x = "Annualized Risk (σ)", y = "Annualized Return") +
  theme_minimal()

compute_mvp <- function(returns_data) {
  R <- as.matrix(returns_data[,-1])
  cov_matrix <- cov(R)
  n_assets <- ncol(R)
  asset_names <- colnames(R)

  Dmat <- 2 * cov_matrix
  dvec <- rep(0, n_assets)
  Amat <- matrix(1, nrow = n_assets)
  bvec <- 1

  sol <- solve.QP(Dmat, dvec, Amat, bvec, meq = 1)
  weights <- sol$solution
  names(weights) <- asset_names

  mu <- colMeans(R)
  exp_return <- sum(weights * mu) * 52
  risk <- sqrt(t(weights) %*% cov_matrix %*% weights) * sqrt(52)

  return(list(weights = weights, return = exp_return, risk = risk))
}
mvp_20 <- compute_mvp(returns_20)
mvp_gold <- compute_mvp(returns_gold)
mvp_crypto <- compute_mvp(returns_crypto)
mvp_full <- compute_mvp(returns_full)
weights_20 <- data.frame(Asset = names(mvp_20$weights), Weight = round(mvp_20$weights, 4))
weights_gold <- data.frame(Asset = names(mvp_gold$weights), Weight = round(mvp_gold$weights, 4))
weights_crypto <- data.frame(Asset = names(mvp_crypto$weights), Weight = round(mvp_crypto$weights, 4))
weights_full <- data.frame(Asset = names(mvp_full$weights), Weight = round(mvp_full$weights, 4))
kable(weights_20, caption = "MVP Weights: 20 Stocks", digits = 4)
MVP Weights: 20 Stocks
Asset Weight
AAPL AAPL 0.0038
MSFT MSFT 0.1213
GOOGL GOOGL 0.0952
AMZN AMZN 0.0185
NVDA NVDA 0.0129
TSLA TSLA -0.0111
F F -0.0232
GM GM 0.0389
APTV APTV -0.0307
BWA BWA 0.0453
JPM JPM 0.2631
BAC BAC -0.1381
WFC WFC 0.0111
GS GS 0.0067
MS MS -0.0921
JNJ JNJ 0.4099
PFE PFE 0.0201
MRK MRK 0.1962
UNH UNH 0.0332
ABBV ABBV 0.0189
kable(weights_gold, caption = "MVP Weights: 20 Stocks + Gold", digits = 4)
MVP Weights: 20 Stocks + Gold
Asset Weight
AAPL AAPL 0.0094
MSFT MSFT 0.0265
GOOGL GOOGL 0.0729
AMZN AMZN -0.0098
NVDA NVDA -0.0048
TSLA TSLA -0.0003
F F -0.0072
GM GM 0.0313
APTV APTV -0.0349
BWA BWA -0.0147
JPM JPM 0.1898
BAC BAC -0.0275
WFC WFC 0.0065
GS GS -0.0057
MS MS -0.0927
JNJ JNJ 0.2224
PFE PFE 0.0013
MRK MRK 0.1073
UNH UNH 0.0422
ABBV ABBV 0.0031
GLD GLD 0.4849
kable(weights_crypto, caption = "MVP Weights: Stocks + Gold + Crypto", digits = 4)
MVP Weights: Stocks + Gold + Crypto
Asset Weight
AAPL AAPL 0.0034
MSFT MSFT 0.0302
GOOGL GOOGL 0.0769
AMZN AMZN -0.0072
NVDA NVDA -0.0014
TSLA TSLA 0.0015
F F -0.0112
GM GM 0.0341
APTV APTV -0.0302
BWA BWA -0.0174
JPM JPM 0.1811
BAC BAC -0.0177
WFC WFC 0.0086
GS GS -0.0023
MS MS -0.0932
JNJ JNJ 0.2183
PFE PFE -0.0010
MRK MRK 0.1084
UNH UNH 0.0453
ABBV ABBV 0.0024
GLD GLD 0.4909
BTC-USD BTC-USD -0.0195
kable(weights_full, caption = "MVP Weights: Stocks + Gold + Crypto + ESG", digits = 4)
MVP Weights: Stocks + Gold + Crypto + ESG
Asset Weight
AAPL AAPL -0.0342
MSFT MSFT -0.0076
GOOGL GOOGL 0.0531
AMZN AMZN -0.0259
NVDA NVDA -0.0225
TSLA TSLA -0.0015
F F -0.0192
GM GM 0.0257
APTV APTV -0.0381
BWA BWA -0.0210
JPM JPM 0.1670
BAC BAC -0.0263
WFC WFC -0.0037
GS GS -0.0235
MS MS -0.1080
JNJ JNJ 0.1804
PFE PFE -0.0073
MRK MRK 0.0872
UNH UNH 0.0268
ABBV ABBV -0.0058
GLD GLD 0.4598
BTC-USD BTC-USD -0.0214
ESGU ESGU 0.3661

c) Optimal risky portfolio

compute_orp <- function(returns_data, rf_rate) {
  R <- as.matrix(returns_data[, -1])
  mu <- colMeans(R)
  Σ <- cov(R)
  asset_names <- colnames(R)

  # Excess returns
  excess_mu <- mu - rf_rate / 52  # convert annual rf to weekly

  invΣ <- solve(Σ)
  numer <- invΣ %*% excess_mu
  denom <- sum(numer)

  weights <- as.vector(numer / denom)
  names(weights) <- asset_names

  # Compute performance (annualized)
  port_return <- sum(weights * mu) * 52
  port_risk <- sqrt(t(weights) %*% Σ %*% weights) * sqrt(52)
  sharpe <- (port_return - rf_rate) / port_risk

  return(list(weights = weights, return = port_return, risk = port_risk, sharpe = sharpe))
}
orp_20 <- compute_orp(returns_20, rf_annual)
orp_gold <- compute_orp(returns_gold, rf_annual)
orp_crypto <- compute_orp(returns_crypto, rf_annual)
orp_full <- compute_orp(returns_full, rf_annual)
orp_table <- data.frame(
  Portfolio = c("20 Stocks", "20 + Gold", "20 + Gold + Crypto", "20 + Gold + Crypto + ESG"),
  Return = c(orp_20$return, orp_gold$return, orp_crypto$return, orp_full$return),
  Risk = c(orp_20$risk, orp_gold$risk, orp_crypto$risk, orp_full$risk),
  Sharpe = c(orp_20$sharpe, orp_gold$sharpe, orp_crypto$sharpe, orp_full$sharpe)
)

kable(orp_table, caption = "Optimal Risky Portfolios (Annualized)", digits = 4)
Optimal Risky Portfolios (Annualized)
Portfolio Return Risk Sharpe
20 Stocks 1.1084 0.5282 2.0680
20 + Gold 0.6670 0.3066 2.1235
20 + Gold + Crypto 0.7301 0.3306 2.1603
20 + Gold + Crypto + ESG 0.9610 0.4151 2.2769
orp_points <- data.frame(
  Risk = c(orp_20$risk, orp_gold$risk, orp_crypto$risk, orp_full$risk),
  Return = c(orp_20$return, orp_gold$return, orp_crypto$return, orp_full$return),
  Group = c("20 Stocks", "20 Stocks + Gold", "Stocks + Gold + Crypto", "Stocks + Gold + Crypto + ESG")
)

ggplot(all_eff_clean, aes(x = Risk, y = Return, color = Group)) +
  geom_line(size = 1.2) +
  geom_point(data = mvp_points, aes(x = Risk, y = Return, fill = Group),
             shape = 21, size = 4, color = "black", stroke = 1.2, show.legend = FALSE) +
  geom_point(data = orp_points, aes(x = Risk, y = Return, fill = Group),
             shape = 24, size = 4, color = "black", stroke = 1.2, show.legend = FALSE) +
  scale_fill_manual(values = c("20 Stocks" = "blue", "20 Stocks + Gold" = "orange",
                               "Stocks + Gold + Crypto" = "green", "Stocks + Gold + Crypto + ESG" = "red")) +
  labs(title = "Efficient Frontiers with MVP (●) and ORP (▼)",
       x = "Annualized Risk", y = "Annualized Return") +
  theme_minimal()

# Data for points
mvp_points <- data.frame(
  Risk = c(mvp_20$risk, mvp_gold$risk, mvp_crypto$risk, mvp_full$risk),
  Return = c(mvp_20$return, mvp_gold$return, mvp_crypto$return, mvp_full$return),
  Group = c("20 Stocks", "20 + Gold", "20 + Gold + Crypto", "20 + Gold + Crypto + ESG")
)

orp_points <- data.frame(
  Risk = c(orp_20$risk, orp_gold$risk, orp_crypto$risk, orp_full$risk),
  Return = c(orp_20$return, orp_gold$return, orp_crypto$return, orp_full$return),
  Group = c("20 Stocks", "20 + Gold", "20 + Gold + Crypto", "20 + Gold + Crypto + ESG")
)

# CML = line from (0, rf) to (ORP risk, ORP return)
cml_data <- bind_rows(
  data.frame(Group = "20 Stocks", x = c(0, orp_20$risk), y = c(rf_annual, orp_20$return)),
  data.frame(Group = "20 + Gold", x = c(0, orp_gold$risk), y = c(rf_annual, orp_gold$return)),
  data.frame(Group = "20 + Gold + Crypto", x = c(0, orp_crypto$risk), y = c(rf_annual, orp_crypto$return)),
  data.frame(Group = "20 + Gold + Crypto + ESG", x = c(0, orp_full$risk), y = c(rf_annual, orp_full$return))
)
ggplot(all_eff_clean, aes(x = Risk, y = Return, color = Group)) +
  geom_line(size = 1.2) +
  # MVP point: Circle
  geom_point(data = mvp_points, aes(x = Risk, y = Return, fill = Group),
             shape = 21, size = 4, color = "black", stroke = 1.2, show.legend = FALSE) +
  # ORP point: Triangle
  geom_point(data = orp_points, aes(x = Risk, y = Return, fill = Group),
             shape = 24, size = 4, color = "black", stroke = 1.2, show.legend = FALSE) +
  # CML lines
  geom_line(data = cml_data, aes(x = x, y = y, color = Group), linetype = "dashed", size = 0.8) +
  scale_color_manual(values = c(
    "20 Stocks" = "blue",
    "20 + Gold" = "orange",
    "20 + Gold + Crypto" = "green",
    "20 + Gold + Crypto + ESG" = "red"
  )) +
  scale_fill_manual(values = c(
    "20 Stocks" = "blue",
    "20 + Gold" = "orange",
    "20 + Gold + Crypto" = "green",
    "20 + Gold + Crypto + ESG" = "red"
  )) +
  labs(title = "Efficient Frontiers with MVP (●), ORP (▼), and Capital Market Line",
       x = "Annualized Risk (σ)", y = "Annualized Return") +
  theme_minimal()

# Build per-group datasets
eff_20_clean$Group <- "20 Stocks"
eff_gold_clean$Group <- "20 + Gold"
eff_crypto_clean$Group <- "20 + Gold + Crypto"
eff_full_clean$Group <- "20 + Gold + Crypto + ESG"

# Points
mvp_df <- data.frame(
  Group = c("20 Stocks", "20 + Gold", "20 + Gold + Crypto", "20 + Gold + Crypto + ESG"),
  Return = c(mvp_20$return, mvp_gold$return, mvp_crypto$return, mvp_full$return),
  Risk = c(mvp_20$risk, mvp_gold$risk, mvp_crypto$risk, mvp_full$risk)
)

orp_df <- data.frame(
  Group = c("20 Stocks", "20 + Gold", "20 + Gold + Crypto", "20 + Gold + Crypto + ESG"),
  Return = c(orp_20$return, orp_gold$return, orp_crypto$return, orp_full$return),
  Risk = c(orp_20$risk, orp_gold$risk, orp_crypto$risk, orp_full$risk)
)

# CML lines (start = rf, end = ORP)
cml_df <- bind_rows(
  data.frame(Group = "20 Stocks", x = c(0, orp_20$risk), y = c(rf_annual, orp_20$return)),
  data.frame(Group = "20 + Gold", x = c(0, orp_gold$risk), y = c(rf_annual, orp_gold$return)),
  data.frame(Group = "20 + Gold + Crypto", x = c(0, orp_crypto$risk), y = c(rf_annual, orp_crypto$return)),
  data.frame(Group = "20 + Gold + Crypto + ESG", x = c(0, orp_full$risk), y = c(rf_annual, orp_full$return))
)
plot_frontier_group <- function(eff, mvp, orp, cml, group_name, color) {
  ggplot() +
    geom_line(data = eff, aes(x = Risk, y = Return), color = color, size = 1.3) +
    geom_point(data = mvp, aes(x = Risk, y = Return), shape = 21, size = 4, fill = color, color = "black") +
    geom_point(data = orp, aes(x = Risk, y = Return), shape = 24, size = 4, fill = color, color = "black") +
    geom_line(data = cml, aes(x = x, y = y), linetype = "dashed", color = color, linewidth = 1) +
    labs(title = paste("Efficient Frontier with MVP (●), ORP (▼) and CML:", group_name),
         x = "Annualized Risk (σ)", y = "Annualized Return") +
    theme_minimal()
}
plot_frontier_group(eff_20_clean,
                    filter(mvp_df, Group == "20 Stocks"),
                    filter(orp_df, Group == "20 Stocks"),
                    filter(cml_df, Group == "20 Stocks"),
                    "20 Stocks", "blue")

plot_frontier_group(eff_gold_clean,
                    filter(mvp_df, Group == "20 + Gold"),
                    filter(orp_df, Group == "20 + Gold"),
                    filter(cml_df, Group == "20 + Gold"),
                    "20 Stocks + Gold", "orange")

plot_frontier_group(eff_crypto_clean,
                    filter(mvp_df, Group == "20 + Gold + Crypto"),
                    filter(orp_df, Group == "20 + Gold + Crypto"),
                    filter(cml_df, Group == "20 + Gold + Crypto"),
                    "20 Stocks + Gold + Crypto", "green")

plot_frontier_group(eff_full_clean,
                    filter(mvp_df, Group == "20 + Gold + Crypto + ESG"),
                    filter(orp_df, Group == "20 + Gold + Crypto + ESG"),
                    filter(cml_df, Group == "20 + Gold + Crypto + ESG"),
                    "20 Stocks + Gold + Crypto + ESG", "red")

library(dplyr)
library(knitr)

orp_weights_20 <- data.frame(Asset = names(orp_20$weights), Weight = round(orp_20$weights, 4)) 
orp_weights_gold <- data.frame(Asset = names(orp_gold$weights), Weight = round(orp_gold$weights, 4))
orp_weights_crypto <- data.frame(Asset = names(orp_crypto$weights), Weight = round(orp_crypto$weights, 4))
orp_weights_full <- data.frame(Asset = names(orp_full$weights), Weight = round(orp_full$weights, 4))
kable(orp_weights_20, caption = "ORP Weights: 20 Stocks")
ORP Weights: 20 Stocks
Asset Weight
AAPL AAPL 0.1352
MSFT MSFT 0.0041
GOOGL GOOGL 0.1697
AMZN AMZN -0.3524
NVDA NVDA 0.6854
TSLA TSLA 0.1641
F F -0.1661
GM GM -0.0382
APTV APTV -0.7897
BWA BWA -0.2070
JPM JPM 1.0919
BAC BAC -1.1096
WFC WFC -0.1586
GS GS 0.9630
MS MS 0.3367
JNJ JNJ -0.5811
PFE PFE -0.5379
MRK MRK 0.2512
UNH UNH 0.2424
ABBV ABBV 0.8970
kable(orp_weights_gold, caption = "ORP Weights: 20 Stocks + Gold")
ORP Weights: 20 Stocks + Gold
Asset Weight
AAPL AAPL 0.0836
MSFT MSFT -0.0386
GOOGL GOOGL 0.1153
AMZN AMZN -0.2191
NVDA NVDA 0.3756
TSLA TSLA 0.0986
F F -0.0882
GM GM -0.0122
APTV APTV -0.4639
BWA BWA -0.1566
JPM JPM 0.6592
BAC BAC -0.5780
WFC WFC -0.0894
GS GS 0.5350
MS MS 0.1496
JNJ JNJ -0.3354
PFE PFE -0.3139
MRK MRK 0.1395
UNH UNH 0.1603
ABBV ABBV 0.4996
GLD GLD 0.4788
kable(orp_weights_crypto, caption = "ORP Weights: 20 + Gold + Crypto")
ORP Weights: 20 + Gold + Crypto
Asset Weight
AAPL AAPL 0.1215
MSFT MSFT -0.0631
GOOGL GOOGL 0.0959
AMZN AMZN -0.2462
NVDA NVDA 0.3795
TSLA TSLA 0.0948
F F -0.0707
GM GM -0.0303
APTV APTV -0.5158
BWA BWA -0.1502
JPM JPM 0.7353
BAC BAC -0.6651
WFC WFC -0.1068
GS GS 0.5483
MS MS 0.1669
JNJ JNJ -0.3461
PFE PFE -0.3197
MRK MRK 0.1354
UNH UNH 0.1506
ABBV ABBV 0.5331
GLD GLD 0.4448
BTC-USD BTC-USD 0.1079
kable(orp_weights_full, caption = "ORP Weights: 20 + Gold + Crypto + ESG")
ORP Weights: 20 + Gold + Crypto + ESG
Asset Weight
AAPL AAPL 0.4539
MSFT MSFT 0.2306
GOOGL GOOGL 0.2955
AMZN AMZN -0.1378
NVDA NVDA 0.6263
TSLA TSLA 0.1374
F F -0.0160
GM GM 0.0268
APTV APTV -0.5435
BWA BWA -0.1456
JPM JPM 0.9574
BAC BAC -0.7186
WFC WFC -0.0274
GS GS 0.8282
MS MS 0.3380
JNJ JNJ -0.1421
PFE PFE -0.3291
MRK MRK 0.3147
UNH UNH 0.3227
ABBV ABBV 0.7026
GLD GLD 0.6927
BTC-USD BTC-USD 0.1482
ESGU ESGU -3.0147

d) Optimal risky portfolio no short selling

library(quadprog)

compute_mvp_constrained <- function(returns_data) {
  R <- as.matrix(returns_data[, -1])  
  Sigma <- cov(R)                     # covariance matrix
  n_assets <- ncol(R)

  Dmat <- 2 * Sigma
  dvec <- rep(0, n_assets)

  # Constraints:
  # - sum(w) = 1  (equality)
  # - w_i >= 0    (inequality)
  Amat <- cbind(rep(1, n_assets), diag(n_assets))  # first column: sum(w)=1, rest: w_i >= 0
  bvec <- c(1, rep(0, n_assets))
  meq <- 1

  result <- solve.QP(Dmat, dvec, Amat, bvec, meq)
  weights <- result$solution
  names(weights) <- colnames(R)

  # Calculate return and risk (annualized)
  mu <- colMeans(R)
  port_return <- sum(weights * mu) * 52
  port_risk <- sqrt(t(weights) %*% Sigma %*% weights) * sqrt(52)

  list(
    weights = weights,
    return = port_return,
    risk = port_risk
  )
}
mvp_20_constrained     <- compute_mvp_constrained(returns_20)
mvp_gold_constrained   <- compute_mvp_constrained(returns_gold)
mvp_crypto_constrained <- compute_mvp_constrained(returns_crypto)
mvp_full_constrained   <- compute_mvp_constrained(returns_full)
library(dplyr)
library(knitr)

kable(data.frame(
  Asset = names(mvp_20_constrained$weights),
  Weight = round(mvp_20_constrained$weights, 4)
),
caption = "MVP Weights (No Shorting): 20 Stocks")
MVP Weights (No Shorting): 20 Stocks
Asset Weight
AAPL AAPL 0.0000
MSFT MSFT 0.1061
GOOGL GOOGL 0.0830
AMZN AMZN 0.0072
NVDA NVDA 0.0069
TSLA TSLA 0.0000
F F 0.0000
GM GM 0.0000
APTV APTV 0.0000
BWA BWA 0.0095
JPM JPM 0.0859
BAC BAC 0.0000
WFC WFC 0.0000
GS GS 0.0000
MS MS 0.0000
JNJ JNJ 0.4174
PFE PFE 0.0129
MRK MRK 0.1993
UNH UNH 0.0341
ABBV ABBV 0.0377
kable(data.frame(
  Asset = names(mvp_gold_constrained$weights),
  Weight = round(mvp_gold_constrained$weights, 4)
) ,
caption = "MVP Weights (No Shorting): 20 Stocks + Gold")
MVP Weights (No Shorting): 20 Stocks + Gold
Asset Weight
AAPL AAPL 0.0000
MSFT MSFT 0.0002
GOOGL GOOGL 0.0534
AMZN AMZN 0.0000
NVDA NVDA 0.0000
TSLA TSLA 0.0000
F F 0.0000
GM GM 0.0000
APTV APTV 0.0000
BWA BWA 0.0000
JPM JPM 0.0791
BAC BAC 0.0000
WFC WFC 0.0000
GS GS 0.0000
MS MS 0.0000
JNJ JNJ 0.2363
PFE PFE 0.0000
MRK MRK 0.1135
UNH UNH 0.0366
ABBV ABBV 0.0016
GLD GLD 0.4793
kable(data.frame(
  Asset = names(mvp_crypto_constrained$weights),
  Weight = round(mvp_crypto_constrained$weights, 4)
) ,
caption = "MVP Weights (No Shorting): 20 Stocks + Gold + Crypto")
MVP Weights (No Shorting): 20 Stocks + Gold + Crypto
Asset Weight
AAPL AAPL 0.0000
MSFT MSFT 0.0002
GOOGL GOOGL 0.0534
AMZN AMZN 0.0000
NVDA NVDA 0.0000
TSLA TSLA 0.0000
F F 0.0000
GM GM 0.0000
APTV APTV 0.0000
BWA BWA 0.0000
JPM JPM 0.0791
BAC BAC 0.0000
WFC WFC 0.0000
GS GS 0.0000
MS MS 0.0000
JNJ JNJ 0.2363
PFE PFE 0.0000
MRK MRK 0.1135
UNH UNH 0.0366
ABBV ABBV 0.0016
GLD GLD 0.4793
BTC-USD BTC-USD 0.0000
kable(data.frame(
  Asset = names(mvp_full_constrained$weights),
  Weight = round(mvp_full_constrained$weights, 4)
) ,
caption = "MVP Weights (No Shorting): 20 Stocks + Gold + Crypto + ESG")
MVP Weights (No Shorting): 20 Stocks + Gold + Crypto + ESG
Asset Weight
AAPL AAPL 0.0000
MSFT MSFT 0.0002
GOOGL GOOGL 0.0534
AMZN AMZN 0.0000
NVDA NVDA 0.0000
TSLA TSLA 0.0000
F F 0.0000
GM GM 0.0000
APTV APTV 0.0000
BWA BWA 0.0000
JPM JPM 0.0791
BAC BAC 0.0000
WFC WFC 0.0000
GS GS 0.0000
MS MS 0.0000
JNJ JNJ 0.2363
PFE PFE 0.0000
MRK MRK 0.1135
UNH UNH 0.0366
ABBV ABBV 0.0016
GLD GLD 0.4793
BTC-USD BTC-USD 0.0000
ESGU ESGU 0.0000
library(nloptr)
compute_orp_constrained_maxsharpe <- function(returns_data, rf_annual) {
  R <- as.matrix(returns_data[, -1])
  mu <- colMeans(R)
  Sigma <- cov(R)
  n_assets <- ncol(R)
  excess_mu <- mu - rf_annual / 52  # weekly excess return

  eval_f <- function(w) {
    port_ret <- sum(w * excess_mu)
    port_risk <- sqrt(as.numeric(t(w) %*% Sigma %*% w))
    -port_ret / port_risk  # negate Sharpe for minimization
  }

  eval_grad_f <- function(w) {
    port_ret <- sum(w * excess_mu)
    port_risk <- sqrt(as.numeric(t(w) %*% Sigma %*% w))
    grad_ret <- excess_mu
    grad_risk <- as.vector(Sigma %*% w) / port_risk  
    - (grad_ret * port_risk - port_ret * grad_risk) / (port_risk^2)
  }

  eval_g_eq <- function(w) sum(w) - 1
  eval_jac_g_eq <- function(w) rep(1, n_assets)

  result <- nloptr::nloptr(
    x0 = rep(1 / n_assets, n_assets),
    eval_f = eval_f,
    eval_grad_f = eval_grad_f,
    lb = rep(0, n_assets),
    ub = rep(1, n_assets),
    eval_g_eq = eval_g_eq,
    eval_jac_g_eq = eval_jac_g_eq,
    opts = list(
      "algorithm" = "NLOPT_LD_SLSQP",
      "xtol_rel" = 1e-8,
      "maxeval" = 10000
    )
  )

  w <- result$solution
  names(w) <- colnames(R)

  port_return <- sum(w * mu) * 52
  port_risk <- sqrt(as.numeric(t(w) %*% Sigma %*% w)) * sqrt(52)
  sharpe <- (port_return - rf_annual) / port_risk

  list(
    weights = w,
    return = port_return,
    risk = port_risk,
    sharpe = sharpe
  )
}
orp_20_constrained<- compute_orp_constrained_maxsharpe(returns_20, rf_annual)
orp_gold_constrained<- compute_orp_constrained_maxsharpe(returns_gold, rf_annual)
orp_crypto_constrained<- compute_orp_constrained_maxsharpe(returns_crypto, rf_annual)
orp_full_constrained<- compute_orp_constrained_maxsharpe(returns_full, rf_annual)
library(dplyr)
library(knitr)

# 1. ORP Weights: 20 Stocks
kable(data.frame(
  Asset = names(orp_20_constrained$weights),
  Weight = round(orp_20_constrained$weights, 4)
) ,
caption = "ORP Weights (No Shorting): 20 Stocks")
ORP Weights (No Shorting): 20 Stocks
Asset Weight
AAPL AAPL 0.0000
MSFT MSFT 0.0000
GOOGL GOOGL 0.0000
AMZN AMZN 0.0000
NVDA NVDA 0.4149
TSLA TSLA 0.0416
F F 0.0000
GM GM 0.0000
APTV APTV 0.0000
BWA BWA 0.0000
JPM JPM 0.0000
BAC BAC 0.0000
WFC WFC 0.0000
GS GS 0.0492
MS MS 0.0000
JNJ JNJ 0.0000
PFE PFE 0.0000
MRK MRK 0.0000
UNH UNH 0.0425
ABBV ABBV 0.4518
# 2. ORP Weights: 20 Stocks + Gold
kable(data.frame(
  Asset = names(orp_gold_constrained$weights),
  Weight = round(orp_gold_constrained$weights, 4)
),
caption = "ORP Weights (No Shorting): 20 Stocks + Gold")
ORP Weights (No Shorting): 20 Stocks + Gold
Asset Weight
AAPL AAPL 0.0000
MSFT MSFT 0.0000
GOOGL GOOGL 0.0000
AMZN AMZN 0.0000
NVDA NVDA 0.2876
TSLA TSLA 0.0295
F F 0.0000
GM GM 0.0000
APTV APTV 0.0000
BWA BWA 0.0000
JPM JPM 0.0000
BAC BAC 0.0000
WFC WFC 0.0000
GS GS 0.0394
MS MS 0.0000
JNJ JNJ 0.0000
PFE PFE 0.0000
MRK MRK 0.0000
UNH UNH 0.0390
ABBV ABBV 0.3181
GLD GLD 0.2864
# 3. ORP Weights: 20 Stocks + Gold + Crypto
kable(data.frame(
  Asset = names(orp_crypto_constrained$weights),
  Weight = round(orp_crypto_constrained$weights, 4)
),
caption = "ORP Weights (No Shorting): 20 + Gold + Crypto")
ORP Weights (No Shorting): 20 + Gold + Crypto
Asset Weight
AAPL AAPL 0.0000
MSFT MSFT 0.0000
GOOGL GOOGL 0.0000
AMZN AMZN 0.0000
NVDA NVDA 0.2826
TSLA TSLA 0.0239
F F 0.0000
GM GM 0.0000
APTV APTV 0.0000
BWA BWA 0.0000
JPM JPM 0.0000
BAC BAC 0.0000
WFC WFC 0.0000
GS GS 0.0158
MS MS 0.0000
JNJ JNJ 0.0000
PFE PFE 0.0000
MRK MRK 0.0000
UNH UNH 0.0328
ABBV ABBV 0.3290
GLD GLD 0.2633
BTC-USD BTC-USD 0.0527
# 4. ORP Weights: 20 Stocks + Gold + Crypto + ESG
kable(data.frame(
  Asset = names(orp_full_constrained$weights),
  Weight = round(orp_full_constrained$weights, 4)
),
caption = "ORP Weights (No Shorting): 20 + Gold + Crypto + ESG")
ORP Weights (No Shorting): 20 + Gold + Crypto + ESG
Asset Weight
AAPL AAPL 0.0000
MSFT MSFT 0.0000
GOOGL GOOGL 0.0000
AMZN AMZN 0.0000
NVDA NVDA 0.2826
TSLA TSLA 0.0239
F F 0.0000
GM GM 0.0000
APTV APTV 0.0000
BWA BWA 0.0000
JPM JPM 0.0000
BAC BAC 0.0000
WFC WFC 0.0000
GS GS 0.0158
MS MS 0.0000
JNJ JNJ 0.0000
PFE PFE 0.0000
MRK MRK 0.0000
UNH UNH 0.0328
ABBV ABBV 0.3290
GLD GLD 0.2633
BTC-USD BTC-USD 0.0527
ESGU ESGU 0.0000
compute_efficient_frontier_qp <- function(returns_data, n_points = 100, rf = rf_annual) {
  R <- as.matrix(returns_data[, -1])
  mu <- colMeans(R)
  Sigma <- cov(R)
  n_assets <- ncol(R)

  Dmat <- 2 * Sigma
  dvec <- rep(0, n_assets)
  Amat <- cbind(rep(1, n_assets), mu, diag(n_assets))  # constraints: sum(w)=1, mu'w = target, w ≥ 0

  min_return <- quantile(mu, 0.4)
  max_return <- max(mu) * 1.2
  target_returns <- seq(min_return, max_return, length.out = n_points)

  result <- data.frame(Return = numeric(0), Risk = numeric(0), Sharpe = numeric(0))

  for (i in 1:n_points) {
    bvec <- c(1, target_returns[i], rep(0, n_assets))

    sol <- tryCatch({
      solve.QP(Dmat, dvec, Amat, bvec, meq = 2)
    }, error = function(e) return(NULL))

    if (!is.null(sol)) {
      w <- sol$solution
      port_return <- sum(w * mu) * 52
      port_sd <- sqrt(t(w) %*% Sigma %*% w) * sqrt(52)
      sharpe <- (port_return - rf) / port_sd

      result <- rbind(result, data.frame(Return = port_return, Risk = port_sd, Sharpe = sharpe))
    }
  }

  result <- result[result$Return == cummax(result$Return), ]
  return(result)
}
eff_20_constrained <- compute_efficient_frontier_qp(returns_20)
eff_20_constrained$Group <- "20 Stocks"

eff_gold_constrained <- compute_efficient_frontier_qp(returns_gold)
eff_gold_constrained$Group <- "20 Stocks + Gold"

eff_crypto_constrained <- compute_efficient_frontier_qp(returns_crypto)
eff_crypto_constrained$Group <- "20 Stocks + Gold + Crypto"

eff_full_constrained <- compute_efficient_frontier_qp(returns_full)
eff_full_constrained$Group <- "20 Stocks + Gold + Crypto + ESG"

# Combine all into one frame
all_constrained_frontiers <- bind_rows(
  eff_20_constrained,
  eff_gold_constrained,
  eff_crypto_constrained,
  eff_full_constrained
)
ggplot(all_constrained_frontiers, aes(x = Risk, y = Return, color = Group)) +
  geom_line(size = 1.2) +
  labs(title = "Efficient Frontiers (No Shorting)",
       x = "Annualized Risk (σ)", y = "Annualized Return") +
  theme_minimal() +
  scale_color_manual(values = c("purple", "red", "blue", "orange"))

get_mvp_orp <- function(frontier_df) {
  mvp_index <- which.min(frontier_df$Risk)
  orp_index <- which.max(frontier_df$Sharpe)
  list(
    mvp = frontier_df[mvp_index, ],
    orp = frontier_df[orp_index, ]
  )
}
eff_20 <- compute_efficient_frontier_qp(returns_20);       eff_20$Group <- "20 Stocks"
eff_gold <- compute_efficient_frontier_qp(returns_gold);   eff_gold$Group <- "20 + Gold"
eff_crypto <- compute_efficient_frontier_qp(returns_crypto); eff_crypto$Group <- "20 + Gold + Crypto"
eff_full <- compute_efficient_frontier_qp(returns_full);   eff_full$Group <- "20 + Gold + Crypto + ESG"

# Extracting MVP and ORP
pts_20 <- get_mvp_orp(eff_20)
pts_gold <- get_mvp_orp(eff_gold)
pts_crypto <- get_mvp_orp(eff_crypto)
pts_full <- get_mvp_orp(eff_full)
plot_frontier_with_points <- function(frontier_df, mvp, orp, title, color = "black") {
  points_df <- rbind(
    mvp %>% mutate(Type = "MVP"),
    orp %>% mutate(Type = "ORP")
  )

  ggplot(frontier_df, aes(x = Risk, y = Return)) +
    geom_line(color = color, size = 1.2) +
    geom_point(data = points_df, aes(shape = Type), size = 4, fill = "white", color = color) +
    scale_shape_manual(values = c("MVP" = 21, "ORP" = 24),
                       name = "Portfolio Type") +
    labs(title = title,
         x = "Annualized Risk (σ)",
         y = "Annualized Return") +
    theme_minimal() +
    theme(legend.position = "right")
}
plot_frontier_with_points(eff_20, pts_20$mvp, pts_20$orp, "Efficient Frontier non shorting: 20 Stocks", "purple")

plot_frontier_with_points(eff_gold, pts_gold$mvp, pts_gold$orp, "Efficient Frontier non shorting: 20 Stocks + Gold", "red")

plot_frontier_with_points(eff_crypto, pts_crypto$mvp, pts_crypto$orp, "Efficient Frontier non shorting: 20 Stocks + Gold + Crypto", "blue")

plot_frontier_with_points(eff_full, pts_full$mvp, pts_full$orp, "Efficient Frontier non shorting: 20 Stocks + Gold + Crypto + ESG", "orange")

pts_20     <- get_mvp_orp(eff_20)
pts_gold   <- get_mvp_orp(eff_gold)
pts_crypto <- get_mvp_orp(eff_crypto)
pts_full   <- get_mvp_orp(eff_full)
# Combine all MVP and ORP into one frame
summary_table <- bind_rows(
  pts_20$mvp %>% mutate(Point = "MVP", Portfolio = "20 Stocks"),
  pts_20$orp %>% mutate(Point = "ORP", Portfolio = "20 Stocks"),
  pts_gold$mvp %>% mutate(Point = "MVP", Portfolio = "20 Stocks + Gold"),
  pts_gold$orp %>% mutate(Point = "ORP", Portfolio = "20 Stocks + Gold"),
  pts_crypto$mvp %>% mutate(Point = "MVP", Portfolio = "20 Stocks + Gold + Crypto"),
  pts_crypto$orp %>% mutate(Point = "ORP", Portfolio = "20 Stocks+ Gold + Crypto"),
  pts_full$mvp %>% mutate(Point = "MVP", Portfolio = "20 Stocks+ Gold + Crypto + ESG"),
  pts_full$orp %>% mutate(Point = "ORP", Portfolio = "20 Stocks+ Gold + Crypto + ESG")
) %>%
  select(Portfolio, Point, Return, Risk, Sharpe) %>%
  arrange(Portfolio, Point)

summary_table <- summary_table %>%
  mutate(across(c(Return, Risk, Sharpe), ~ round(., 4)))

kable(summary_table, caption = "MVP and ORP Performance Summary (No Shorting)")
MVP and ORP Performance Summary (No Shorting)
Portfolio Point Return Risk Sharpe
20 Stocks MVP 0.0881 0.1455 0.4956
20 Stocks ORP 0.3743 0.2664 1.3451
20 Stocks + Gold MVP 0.0907 0.1093 0.6836
20 Stocks + Gold ORP 0.2962 0.2034 1.3777
20 Stocks + Gold + Crypto MVP 0.0938 0.1094 0.7112
20 Stocks+ Gold + Crypto ORP 0.3050 0.2074 1.3931
20 Stocks+ Gold + Crypto + ESG MVP 0.0969 0.1097 0.7383
20 Stocks+ Gold + Crypto + ESG ORP 0.3071 0.2090 1.3931

e.1.) Optimal risky portfolio only 2 industries shorting allowed

# Defineing industry 
industries <- c(
  AAPL = "Technology", MSFT = "Technology", GOOGL = "Technology", AMZN = "Technology",
  NVDA = "Technology", TSLA = "Automotive", F = "Automotive", GM = "Automotive",
  APTV = "Automotive", BWA = "Automotive", 
  JPM = "Financial", BAC = "Financial", WFC = "Financial", GS = "Financial", MS = "Financial",
  JNJ = "Healthcare", PFE = "Healthcare", MRK = "Healthcare", UNH = "Healthcare", ABBV = "Healthcare"
)

# Drop Automotive and Healthcare
selected_tickers <- names(industries)[!(industries %in% c("Automotive", "Healthcare"))]
returns_10 <- returns_20[, c("date", selected_tickers)]
compute_orp_unconstrained <- function(returns_data, rf = rf_annual) {
  R <- as.matrix(returns_data[, -1])
  mu <- colMeans(R)
  Sigma <- cov(R)

  # Max Sharpe portfolio
  excess_mu <- mu - rf / 52  
  weights <- solve(Sigma) %*% excess_mu
  weights <- as.numeric(weights / sum(weights)) 

  # Portfolio stats
  port_return <- sum(weights * mu) * 52
  port_sd <- sqrt(t(weights) %*% Sigma %*% weights) * sqrt(52)
  sharpe <- (port_return - rf) / port_sd

  list(
    weights = setNames(round(weights, 4), colnames(R)),
    return = round(port_return, 4),
    risk = round(port_sd, 4),
    sharpe = round(sharpe, 4)
  )
}


orp_unconstrained_10 <- compute_orp_unconstrained(returns_10)
library(knitr)

orp_table <- data.frame(
  Asset = names(orp_unconstrained_10$weights),
  Weight = round(orp_unconstrained_10$weights, 4)
)

orp_table <- rbind(
  orp_table,
  data.frame(Asset = "Expected Return", Weight = round(orp_unconstrained_10$return, 4)),
  data.frame(Asset = "Risk (SD)", Weight = round(orp_unconstrained_10$risk, 4)),
  data.frame(Asset = "Sharpe Ratio", Weight = round(orp_unconstrained_10$sharpe, 4))
)

kable(orp_table, caption = "Optimal Risky Portfolio (Unconstrained, 10 Stocks)")
Optimal Risky Portfolio (Unconstrained, 10 Stocks)
Asset Weight
AAPL AAPL 0.2531
MSFT MSFT 0.0104
GOOGL GOOGL 0.0672
AMZN AMZN -0.3331
NVDA NVDA 0.6332
JPM JPM 0.9756
BAC BAC -1.3910
WFC WFC -0.1308
GS GS 0.6768
MS MS 0.2387
1 Expected Return 0.6318
11 Risk (SD) 0.4269
12 Sharpe Ratio 1.4428
compute_mvp_unconstrained <- function(returns_data) {
  R <- as.matrix(returns_data[, -1])  
  mu <- colMeans(R)
  Sigma <- cov(R)

  # Minimum variance
  n <- ncol(R)
  Dmat <- 2 * Sigma
  dvec <- rep(0, n)
  Amat <- matrix(1, nrow = n, ncol = 1)  # constraint: sum(w) = 1
  bvec <- 1

  sol <- solve.QP(Dmat, dvec, Amat, bvec, meq = 1)
  w <- sol$solution
  w <- as.numeric(w)

  port_return <- sum(w * mu) * 52
  port_sd <- sqrt(t(w) %*% Sigma %*% w) * sqrt(52)

  list(
    weights = setNames(round(w, 4), colnames(R)),
    return = round(port_return, 4),
    risk = round(port_sd, 4)
  )
}
mvp_unconstrained_10 <- compute_mvp_unconstrained(returns_10)
library(knitr)

sharpe <- (mvp_unconstrained_10$return - rf_annual) / mvp_unconstrained_10$risk

mvp_table <- data.frame(
  Asset = names(mvp_unconstrained_10$weights),
  Weight = round(mvp_unconstrained_10$weights, 4)
)

summary_row_mvp <- data.frame(
  Asset = c("Expected Return", "Risk (SD)", "Sharpe Ratio"),
  Weight = round(c(mvp_unconstrained_10$return,
                   mvp_unconstrained_10$risk,
                   sharpe), 4)
)

mvp_full_table <- rbind(mvp_table, summary_row_mvp)

kable(mvp_full_table, caption = "Minimum Variance Portfolio (Unconstrained, 10 Stocks)")
Minimum Variance Portfolio (Unconstrained, 10 Stocks)
Asset Weight
AAPL AAPL 0.2087
MSFT MSFT 0.4419
GOOGL GOOGL 0.1283
AMZN AMZN -0.0228
NVDA NVDA -0.1352
JPM JPM 0.5284
BAC BAC -0.2295
WFC WFC 0.0333
GS GS 0.2578
MS MS -0.2108
1 Expected Return 0.1491
2 Risk (SD) 0.1984
3 Sharpe Ratio 0.6711
compute_efficient_frontier_unconstrained_10 <- function(returns_data, n_points = 100, rf = rf_annual) {
  R <- as.matrix(returns_data[, -1])
  mu <- colMeans(R)
  Sigma <- cov(R)
  n_assets <- ncol(R)

  Dmat <- 2 * Sigma
  dvec <- rep(0, n_assets)
  Aeq <- cbind(rep(1, n_assets), mu)
  frontier <- data.frame(Return = numeric(), Risk = numeric(), Sharpe = numeric())
  weights_list <- list()

  min_return <- min(mu, 0.4)
  max_return <- max(mu) * 1.2
  target_returns <- seq(min_return, max_return, length.out = n_points)

  for (i in 1:n_points) {
    bvec <- c(1, target_returns[i])
    sol <- tryCatch({
      solve.QP(Dmat, dvec, Aeq, bvec, meq = 2)
    }, error = function(e) return(NULL))

    if (!is.null(sol)) {
      w <- sol$solution
      port_return <- sum(w * mu) * 52
      port_sd <- sqrt(t(w) %*% Sigma %*% w) * sqrt(52)
      sharpe <- (port_return - rf) / port_sd

      frontier <- rbind(frontier, data.frame(Return = port_return, Risk = port_sd, Sharpe = sharpe))
      weights_list[[length(weights_list) + 1]] <- w
    }
  }

  frontier$Weights <- weights_list
  return(frontier)
}
clean_efficient_curve_unconstrained_10 <- function(frontier_df) {
  df <- frontier_df[order(frontier_df$Risk), ]
  
  efficient <- df[1, , drop = FALSE]
  for (i in 2:nrow(df)) {
    if (df$Return[i] >= efficient$Return[nrow(efficient)]) {
      efficient <- rbind(efficient, df[i, , drop = FALSE])
    }
  }
  return(efficient)
}
extract_mvp_orp_unconstrained_10 <- function(frontier_df) {
  mvp <- frontier_df[which.min(frontier_df$Risk), ]
  orp <- frontier_df[which.max(frontier_df$Sharpe), ]
  mvp$Type <- "MVP"
  orp$Type <- "ORP"
  rbind(mvp, orp)
}
extract_mvp_orp_unconstrained_10 <- function(frontier_df) {
  mvp <- frontier_df[which.min(frontier_df$Risk), ]
  orp <- frontier_df[which.max(frontier_df$Sharpe), ]
  mvp$Type <- "MVP"
  orp$Type <- "ORP"
  rbind(mvp, orp)
}
# Compute frontier
frontier_unconstrained_10 <- compute_efficient_frontier_unconstrained_10(returns_10)

frontier_unconstrained_10_clean <- clean_efficient_curve_unconstrained_10(frontier_unconstrained_10)

# Extract key points
points_unconstrained_10 <- extract_mvp_orp_unconstrained_10(frontier_unconstrained_10_clean)
ggplot(frontier_unconstrained_10_clean, aes(x = Risk, y = Return)) +
  geom_line(color = "darkgreen", size = 1.2) +
  geom_point(data = points_unconstrained_10,
             aes(shape = Type),
             size = 4,
             fill = "white",
             color = "darkgreen") +
  scale_shape_manual(values = c("MVP" = 21, "ORP" = 24),
                     name = "Portfolio Type",
                     labels = c("MVP (Min Variance)", "ORP (Max Sharpe)")) +
  labs(title = "Efficient Frontier: 10-Stock Universe (Unconstrained)",
       x = "Annualized Risk (σ)",
       y = "Annualized Return") +
  theme_minimal() +
  theme(legend.position = "right")

e.2.) Optimal risky portfolio only 2 industries no shorting allowed

compute_mvp_constrained_10 <- function(returns_data) {
  R <- as.matrix(returns_data[, -1])  
  Sigma <- cov(R)
  n_assets <- ncol(R)

  Dmat <- 2 * Sigma
  dvec <- rep(0, n_assets)
  Amat <- cbind(rep(1, n_assets), diag(n_assets))  # sum of weights = 1 and w >= 0
  bvec <- c(1, rep(0, n_assets))

  sol <- solve.QP(Dmat, dvec, Amat, bvec, meq = 1)
  w <- sol$solution
  names(w) <- colnames(R)
  return(w)
}
library(knitr)

R <- as.matrix(returns_10[, -1])  
mvp_weights_constrained_10 <- compute_mvp_constrained_10(returns_10)
mvp_return <- as.numeric(sum(mvp_weights_constrained_10 * colMeans(R)) * 52)
mvp_risk <- as.numeric(sqrt(t(mvp_weights_constrained_10) %*% cov(R) %*% mvp_weights_constrained_10) * sqrt(52))
mvp_sharpe <- (mvp_return - rf_annual) / mvp_risk


mvp_weights_table <- data.frame(
  Asset = names(mvp_weights_constrained_10),
  Weight = round(mvp_weights_constrained_10, 4)
)


summary_rows <- data.frame(
  Asset = c("Expected Return", "Risk (SD)", "Sharpe Ratio"),
  Weight = round(c(mvp_return, mvp_risk, mvp_sharpe), 4)
)


mvp_full_table <- rbind(mvp_weights_table, summary_rows)


kable(mvp_full_table, caption = "MVP (10-Stock Portfolio, No Shorting) — Weights and Performance")
MVP (10-Stock Portfolio, No Shorting) — Weights and Performance
Asset Weight
AAPL AAPL 0.1588
MSFT MSFT 0.3433
GOOGL GOOGL 0.0946
AMZN AMZN 0.0000
NVDA NVDA 0.0000
JPM JPM 0.3452
BAC BAC 0.0000
WFC WFC 0.0000
GS GS 0.0581
MS MS 0.0000
1 Expected Return 0.1899
2 Risk (SD) 0.2120
3 Sharpe Ratio 0.8208
compute_orp_constrained_10 <- function(returns_data, rf = rf_annual, n_points = 100) {
  R <- as.matrix(returns_data[, -1])
  mu <- colMeans(R)
  Sigma <- cov(R)
  n_assets <- ncol(R)

  Dmat <- 2 * Sigma
  dvec <- rep(0, n_assets)
  Amat <- cbind(rep(1, n_assets), mu, diag(n_assets))  # sum(w)=1, target return, w≥0

  frontier <- data.frame(Return = numeric(), Risk = numeric(), Sharpe = numeric())
  weights_list <- list()

  min_target <- min(mu)
  max_target <- max(mu) * 1.2
  target_returns <- seq(min_target, max_target, length.out = n_points)

  for (i in 1:n_points) {
    bvec <- c(1, target_returns[i], rep(0, n_assets))
    sol <- tryCatch({
      solve.QP(Dmat, dvec, Amat, bvec, meq = 2)
    }, error = function(e) return(NULL))

    if (!is.null(sol)) {
      w <- sol$solution
      port_return <- sum(w * mu) * 52
      port_sd <- sqrt(t(w) %*% Sigma %*% w) * sqrt(52)
      sharpe <- (port_return - rf) / port_sd

      frontier <- rbind(frontier, data.frame(Return = port_return, Risk = port_sd, Sharpe = sharpe))
      weights_list[[length(weights_list) + 1]] <- w
    }
  }

  # ORP (max Sharpe)
  best_index <- which.max(frontier$Sharpe)
  orp_weights <- weights_list[[best_index]]

  list(
    weights = setNames(round(orp_weights, 4), colnames(R)),
    return = round(frontier$Return[best_index], 4),
    risk = round(frontier$Risk[best_index], 4),
    sharpe = round(frontier$Sharpe[best_index], 4)
  )
}
orp_constrained_10 <- compute_orp_constrained_10(returns_10)
library(knitr)

orp_table <- data.frame(
  Asset = names(orp_constrained_10$weights),
  Weight = orp_constrained_10$weights
)

orp_table <- rbind(
  orp_table,
  data.frame(Asset = "Expected Return", Weight = orp_constrained_10$return),
  data.frame(Asset = "Risk (SD)", Weight = orp_constrained_10$risk),
  data.frame(Asset = "Sharpe Ratio", Weight = orp_constrained_10$sharpe)
)

kable(orp_table, caption = "ORP (10-Stock, No Shorting) — Weights and Performance")
ORP (10-Stock, No Shorting) — Weights and Performance
Asset Weight
AAPL AAPL 0.1204
MSFT MSFT 0.0000
GOOGL GOOGL 0.0000
AMZN AMZN 0.0000
NVDA NVDA 0.6185
JPM JPM 0.0000
BAC BAC 0.0000
WFC WFC 0.0000
GS GS 0.2611
MS MS 0.0000
1 Expected Return 0.4677
11 Risk (SD) 0.3718
12 Sharpe Ratio 1.2149
compute_efficient_frontier_constrained_10 <- function(returns_data, n_points = 100, rf = rf_annual) {
  R <- as.matrix(returns_data[, -1])
  mu <- colMeans(R)
  Sigma <- cov(R)
  n_assets <- ncol(R)

  Dmat <- 2 * Sigma
  dvec <- rep(0, n_assets)
  Amat <- cbind(rep(1, n_assets), mu, diag(n_assets))  # constraints: sum(w)=1, mu'w = target, w ≥ 0

  frontier <- data.frame(Return = numeric(), Risk = numeric(), Sharpe = numeric())
  weights_list <- list()

  target_returns <- seq(min(mu), max(mu) * 1.2, length.out = n_points)

  for (i in 1:n_points) {
    bvec <- c(1, target_returns[i], rep(0, n_assets))
    sol <- tryCatch({
      solve.QP(Dmat, dvec, Amat, bvec, meq = 2)
    }, error = function(e) return(NULL))

    if (!is.null(sol)) {
      w <- sol$solution
      port_return <- sum(w * mu) * 52
      port_sd <- sqrt(t(w) %*% Sigma %*% w) * sqrt(52)
      sharpe <- (port_return - rf) / port_sd

      frontier <- rbind(frontier, data.frame(Return = port_return, Risk = port_sd, Sharpe = sharpe))
      weights_list[[length(weights_list) + 1]] <- w
    }
  }

  frontier$Weights <- weights_list
  return(frontier)
}
clean_efficient_curve_constrained_10 <- function(frontier_df) {
  df <- frontier_df[order(frontier_df$Risk), ]
  efficient <- df[1, , drop = FALSE]
  for (i in 2:nrow(df)) {
    if (df$Return[i] >= efficient$Return[nrow(efficient)]) {
      efficient <- rbind(efficient, df[i, , drop = FALSE])
    }
  }
  return(efficient)
}
extract_mvp_orp_constrained_10 <- function(frontier_df) {
  mvp <- frontier_df[which.min(frontier_df$Risk), ]
  orp <- frontier_df[which.max(frontier_df$Sharpe), ]
  mvp$Type <- "MVP"
  orp$Type <- "ORP"
  rbind(mvp, orp)
}
# Compute full frontier
frontier_constrained_10 <- compute_efficient_frontier_constrained_10(returns_10)

frontier_constrained_10_clean <- clean_efficient_curve_constrained_10(frontier_constrained_10)

# Extract MVP & ORP
points_constrained_10 <- extract_mvp_orp_constrained_10(frontier_constrained_10_clean)
ggplot(frontier_constrained_10_clean, aes(x = Risk, y = Return)) +
  geom_line(color = "steelblue", size = 1.2) +
  geom_point(data = points_constrained_10,
             aes(shape = Type),
             size = 4,
             fill = "white",
             color = "steelblue") +
  scale_shape_manual(values = c("MVP" = 21, "ORP" = 24),
                     name = "Portfolio Type",
                     labels = c("MVP (Min Variance)", "ORP (Max Sharpe)")) +
  labs(title = "Efficient Frontier: 10-Stock Universe (Constrained)",
       x = "Annualized Risk (σ)",
       y = "Annualized Return") +
  theme_minimal() +
  theme(legend.position = "right")

f) Index model and Treynor Black

# Use SPY as the market return
market_returns <- weekly_returns %>%
  select(date, Market = SPY)
# Remove date from market returns before merging
returns_all <- weekly_returns %>%
  select(-SPY)

returns_merged_all <- left_join(returns_all, market_returns, by = "date")
estimate_index_model_verbose <- function(stock, data) {
  df <- na.omit(data[, c("Market", stock)])
  model <- lm(df[[stock]] ~ df$Market)

  summary_model <- summary(model)

  alpha <- coef(model)[1]
  beta <- coef(model)[2]
  resid_var <- var(resid(model))
  r_squared <- summary_model$r.squared
  p_alpha <- coef(summary_model)[1, 4]
  p_beta <- coef(summary_model)[2, 4]

  return(data.frame(
    stock = stock,
    alpha = round(alpha, 5),
    beta = round(beta, 5),
    resid_var = round(resid_var, 5),
    R_squared = round(r_squared, 4),
    p_alpha = round(p_alpha, 5),
    p_beta = round(p_beta, 5)
  ))
}
regression_outputs <- bind_rows(
  lapply(colnames(returns_all)[-1], estimate_index_model_verbose, data = returns_merged_all)
)

rownames(regression_outputs) <- NULL

regression_outputs <- head(regression_outputs, -1)

kable(regression_outputs, caption = "Index Model Regressions for All 23 Assets")
Index Model Regressions for All 23 Assets
stock alpha beta resid_var R_squared p_alpha p_beta
AAPL 0.00174 1.17304 0.00078 0.5176 0.31789 0.00000
MSFT 0.00117 1.07762 0.00060 0.5410 0.44478 0.00000
GOOGL 0.00091 1.13828 0.00089 0.4683 0.62611 0.00000
AMZN -0.00013 1.29102 0.00139 0.4203 0.95456 0.00000
NVDA 0.00711 1.87842 0.00291 0.4236 0.03579 0.00000
TSLA 0.00434 2.12861 0.00710 0.2791 0.41090 0.00000
F -0.00288 1.54479 0.00237 0.3796 0.34389 0.00000
GM -0.00193 1.42188 0.00194 0.3867 0.48357 0.00000
APTV -0.00563 1.56970 0.00225 0.3993 0.05854 0.00000
BWA -0.00337 1.17960 0.00151 0.3585 0.16577 0.00000
JPM 0.00008 1.02674 0.00094 0.4041 0.96503 0.00000
BAC -0.00176 1.22232 0.00118 0.4337 0.41232 0.00000
WFC -0.00156 1.23030 0.00160 0.3648 0.53242 0.00000
GS 0.00083 1.18113 0.00077 0.5243 0.63037 0.00000
MS 0.00059 1.35582 0.00092 0.5490 0.75459 0.00000
JNJ -0.00045 0.37566 0.00053 0.1387 0.75628 0.00000
PFE -0.00182 0.53747 0.00117 0.1299 0.39558 0.00000
MRK 0.00010 0.42274 0.00078 0.1221 0.95636 0.00000
ABBV 0.00217 0.51142 0.00109 0.1273 0.29402 0.00000
UNH 0.00078 0.63797 0.00100 0.1973 0.69557 0.00000
GLD 0.00150 0.15413 0.00045 0.0313 0.25840 0.00425
BTC-USD 0.00520 1.61340 0.00679 0.1887 0.31298 0.00000
ESGU -0.00009 1.01266 0.00001 0.9834 0.66771 0.00000
tb_params <- regression_outputs %>%
  select(stock, alpha, beta, resid_var)
tb_params <- tb_params %>%
  mutate(
    # MVP (unconstrained)
    score_mvp = 1 / resid_var,
    weight_mvp_tb = score_mvp / sum(score_mvp),

    # ORP (constrained): only assets with alpha > 0
    score_orp = ifelse(alpha > 0, alpha / resid_var, 0),
    weight_orp_tb = score_orp / sum(score_orp)
  )
# Market stats (SPY assumed already cleaned)
r_M <- mean(returns_merged_all$Market, na.rm = TRUE) * 52
sd_M <- sd(returns_merged_all$Market, na.rm = TRUE) * sqrt(52)
rf <- rf_annual  # already in annualized decimal format
compute_tb_metrics <- function(w, alpha, beta, resid_var, r_f, r_M, sd_M) {
  w <- w / sum(abs(w))  

  alpha_A <- sum(w * alpha)
  beta_A  <- sum(w * beta)
  var_eA  <- sum((w^2) * resid_var)

  var_eA <- max(var_eA, 1e-4)

  tb_score <- alpha_A / var_eA
  tb_score <- min(tb_score, 10) 

  # Calculation for optimal weights for active vs. passive (market) portfolio
  w_A <- tb_score / ((r_M - r_f) / sd_M^2 + tb_score)
  w_M <- 1 - w_A
  
  # Computation of portfolio return, risk, Sharpe
  expected_return <- r_f + w_A * alpha_A + (w_A * beta_A + w_M) * (r_M - r_f)
  risk <- sqrt((w_A * beta_A + w_M)^2 * sd_M^2 + w_A^2 * var_eA)
  sharpe <- (expected_return - r_f) / risk

  return(c(
    Return = expected_return,
    Risk = risk,
    Sharpe = sharpe,
    ActiveWeight = w_A,
    MarketWeight = w_M
  ))
}
res_mvp <- compute_tb_metrics(
  tb_params$weight_mvp_tb,
  tb_params$alpha, tb_params$beta, tb_params$resid_var,
  rf, r_M, sd_M
)

res_orp <- compute_tb_metrics(
  tb_params$weight_orp_tb,
  tb_params$alpha, tb_params$beta, tb_params$resid_var,
  rf, r_M, sd_M
)
tb_summary <- data.frame(
  Portfolio = c("MVP (Treynor-Black)", "ORP (Treynor-Black, No Shorting)"),
  Expected_Return = c(res_mvp["Return"], res_orp["Return"]),
  Risk = c(res_mvp["Risk"], res_orp["Risk"]),
  Sharpe_Ratio = c(res_mvp["Sharpe"], res_orp["Sharpe"]),
  Active_Weight = c(res_mvp["ActiveWeight"], res_orp["ActiveWeight"]),
  Market_Weight = c(res_mvp["MarketWeight"], res_orp["MarketWeight"])
)

kable(tb_summary, digits = 4, caption = "Treynor-Black Portfolio Summary (MVP & ORP)")
Treynor-Black Portfolio Summary (MVP & ORP)
Portfolio Expected_Return Risk Sharpe_Ratio Active_Weight Market_Weight
MVP (Treynor-Black) 0.1345 0.1777 0.6673 -0.0928 1.0928
ORP (Treynor-Black, No Shorting) 0.1376 0.1798 0.6765 0.7269 0.2731
tb_weights <- tb_params %>%
  select(stock, weight_mvp_tb, weight_orp_tb) %>%
  rename(MVP_Weight = weight_mvp_tb, ORP_Weight = weight_orp_tb)

kable(tb_weights, digits = 4, caption = "Active Portfolio Weights (including Crypto, Gold, ESG)")
Active Portfolio Weights (including Crypto, Gold, ESG)
stock MVP_Weight ORP_Weight
AAPL 0.0106 0.1308
MSFT 0.0138 0.1143
GOOGL 0.0093 0.0599
AMZN 0.0060 0.0000
NVDA 0.0029 0.1432
TSLA 0.0012 0.0358
F 0.0035 0.0000
GM 0.0043 0.0000
APTV 0.0037 0.0000
BWA 0.0055 0.0000
JPM 0.0088 0.0050
BAC 0.0070 0.0000
WFC 0.0052 0.0000
GS 0.0108 0.0632
MS 0.0090 0.0376
JNJ 0.0157 0.0000
PFE 0.0071 0.0000
MRK 0.0106 0.0075
ABBV 0.0076 0.1167
UNH 0.0083 0.0457
GLD 0.0184 0.1954
BTC-USD 0.0012 0.0449
ESGU 0.8295 0.0000