# Load packages

# Core
library(tidyverse)
library(tidyquant)

Goal

Examine how each asset contributes to portfolio standard deviation. This is to ensure that our risk is not concentrated in any one asset.

1 Import stock prices

Choose your stocks from 2012-12-31 to present.

symbols <- c("AMZN", "META", "NFLX", "NVDA", "GOOGL")
prices <- tq_get(x    = symbols,
                 get  = "stock.prices", 
                 from = "2012-12-31")

2 Convert prices to returns (monthly)

asset_returns_tbl <- prices %>%
    
    group_by(symbol) %>%
    
    tq_transmute(select     = adjusted,
                 mutate_fun = periodReturn,
                 period     = "monthly",
                 type       = "log") %>%
    slice(-1) %>%
                 
    ungroup() %>%
    
    set_names(c("asset", "date", "returns"))

3 Calculate Component Contribution to Portfolio Volatility

# Transform data into wide form
asset_returns_wide_tbl <- asset_returns_tbl %>%

    pivot_wider(names_from = asset, values_from = returns) %>%

    column_to_rownames(var = "date")

asset_returns_wide_tbl
##                     AMZN         GOOGL          META          NFLX         NVDA
## 2013-01-31  0.0566799395  0.0660633448  0.1516789379  0.5792178352  0.000000000
## 2013-02-28 -0.0046435024  0.0584792943 -0.1282882816  0.1294686037  0.038221817
## 2013-03-28  0.0083654162 -0.0087879305 -0.0632427631  0.0063600533  0.013338804
## 2013-04-30 -0.0487507497  0.0375394049  0.0821454475  0.1323749474  0.070706183
## 2013-05-31  0.0588686246  0.0550324522 -0.1314243044  0.0460379624  0.054651855
## 2013-06-28  0.0310507506  0.0104477803  0.0215322519 -0.0693558290 -0.030167153
## 2013-07-31  0.0813355350  0.0083478368  0.3914336219  0.1468652518  0.028091940
## 2013-08-30 -0.0695574090 -0.0471075668  0.1151224983  0.1495075647  0.026270274
## 2013-09-30  0.1067688897  0.0336808725  0.1959921624  0.0853631921  0.053460310
## 2013-10-31  0.1521839116  0.1626135629 -0.0003983427  0.0420205612 -0.024066214
## 2013-11-29  0.0781496860  0.0277603415 -0.0658538575  0.1260456715  0.032035186
## 2013-12-31  0.0130490386  0.0560802341  0.1505889313  0.0064580000  0.026566929
## 2014-01-31 -0.1059765119  0.0523738047  0.1353367250  0.1059768648 -0.020177412
## 2014-02-28  0.0094619003  0.0289428459  0.0899635907  0.0849672590  0.162107368
## 2014-03-31 -0.0737086161 -0.0868642330 -0.1279129234 -0.2357724841 -0.025903795
## 2014-04-30 -0.1007565303 -0.0419808836 -0.0076654640 -0.0890406585  0.030788693
## 2014-05-30  0.0273091844  0.0664844319  0.0572141571  0.2603989261  0.032886267
## 2014-06-30  0.0383836202  0.0225206339  0.0611264206  0.0530626641 -0.024508545
## 2014-07-31 -0.0369768154 -0.0087954896  0.0766415921 -0.0414272975 -0.057729487
## 2014-08-29  0.0799468404  0.0048367480  0.0294319871  0.1221472546  0.110059905
## 2014-09-30 -0.0502010184  0.0103352524  0.0548688321 -0.0569909815 -0.052782698
## 2014-10-31 -0.0540982347 -0.0355314959 -0.0525993634 -0.1386420583  0.057399152
## 2014-11-28  0.1031187277 -0.0336483998  0.0355004072 -0.1250818519  0.074851930
## 2014-12-31 -0.0872368614 -0.0341226606  0.0041100398 -0.0144727545 -0.044863122
## 2015-01-30  0.1330922557  0.0129003351 -0.0274166300  0.2571876083 -0.043318765
## 2015-02-27  0.0697992426  0.0456004612  0.0395194123  0.0722680343  0.142698847
## 2015-03-31 -0.0214295755 -0.0141947047  0.0403306408 -0.1307827594 -0.052583080
## 2015-04-30  0.1253212736 -0.0107481153 -0.0428664815  0.2893246603  0.058909473
## 2015-05-29  0.0175090293 -0.0063066189  0.0053180135  0.1145792814  0.001459733
## 2015-06-30  0.0112589814 -0.0097295720  0.0798191166  0.0513462657 -0.095717262
## 2015-07-31  0.2111621090  0.1968016190  0.0917318669  0.1972314899 -0.007987946
## 2015-08-31 -0.0443525782 -0.0148319296 -0.0499449037  0.0062789518  0.123595645
## 2015-09-30 -0.0019516837 -0.0146948751  0.0052417109 -0.1079428863  0.092150607
## 2015-10-30  0.2010808743  0.1441989022  0.1259806348  0.0483934975  0.140555762
## 2015-11-30  0.0602956777  0.0339445487  0.0220173207  0.1292201068  0.115404955
## 2015-12-31  0.0165440008  0.0196778523  0.0040211452 -0.0753374900  0.038347587
## 2016-01-29 -0.1410054620 -0.0216460856  0.0696550820 -0.2194782802 -0.118048541
## 2016-02-29 -0.0605352209 -0.0597106846 -0.0482912490  0.0169504292  0.071923713
## 2016-03-31  0.0717834363  0.0617443718  0.0649943039  0.0902267716  0.127654487
## 2016-04-29  0.1053453760 -0.0748524466  0.0300437713 -0.1270821580 -0.002810410
## 2016-05-31  0.0915002899  0.0562641532  0.0104065101  0.1304025124  0.276388394
## 2016-06-30 -0.0099694639 -0.0624280289 -0.0388739210 -0.1144251460  0.006188222
## 2016-07-29  0.0586021229  0.1176170373  0.0811459483 -0.0025173508  0.194443369
## 2016-08-31  0.0135476418 -0.0018845645  0.0174363639  0.0657364217  0.073469152
## 2016-09-30  0.0848953908  0.0178305988  0.0169035701  0.0112245729  0.110693708
## 2016-10-31 -0.0583893058  0.0072370128  0.0209835966  0.2367092462  0.037805172
## 2016-11-30 -0.0509721927 -0.0429128622 -0.1008833876 -0.0650993149  0.260525064
## 2016-12-30 -0.0009330556  0.0211316779 -0.0288708571  0.0564934510  0.146436063
## 2017-01-31  0.0936394059  0.0344063074  0.1246262357  0.1280336724  0.022601840
## 2017-02-28  0.0258446800  0.0297178667  0.0392739568  0.0100411108 -0.071874841
## 2017-03-31  0.0479423007  0.0033910671  0.0469122605  0.0391855218  0.070843649
## 2017-04-28  0.0424566944  0.0866298992  0.0561212929  0.0292677885 -0.043433862
## 2017-05-31  0.0725778018  0.0654865504  0.0080211221  0.0689840448  0.326022070
## 2017-06-30 -0.0271286156 -0.0599207831 -0.0031742321 -0.0874853040  0.001453601
## 2017-07-31  0.0202278808  0.0168734838  0.1142295583  0.1954426244  0.117045114
## 2017-08-31 -0.0072953953  0.0102487575  0.0159430636 -0.0390093333  0.042639071
## 2017-09-29 -0.0198260355  0.0191612572 -0.0064171073  0.0373013834  0.053601279
## 2017-10-31  0.1395154056  0.0591373028  0.0523871227  0.0798772375  0.145700417
## 2017-11-30  0.0626577318  0.0030251988 -0.0161239423 -0.0461007257 -0.029244996
## 2017-12-29 -0.0062057845  0.0164917251 -0.0040719595  0.0230815823 -0.036583442
## 2018-01-31  0.2156265497  0.1153711595  0.0574260336  0.3422455062  0.239240829
## 2018-02-28  0.0415536279 -0.0685265569 -0.0469404886  0.0750957953 -0.014959357
## 2018-03-29 -0.0440034760 -0.0624006180 -0.1097192688  0.0135328146 -0.043969049
## 2018-04-30  0.0788803060 -0.0180572539  0.0736341303  0.0563153817 -0.029312493
## 2018-05-31  0.0397392430  0.0769005897  0.1088543381  0.1180176912  0.115145144
## 2018-06-29  0.0421636787  0.0261904200  0.0131574389  0.1073125782 -0.062544875
## 2018-07-31  0.0446635734  0.0832507900 -0.1186454451 -0.1483894202  0.033048479
## 2018-08-31  0.1243079079  0.0037250797  0.0180879545  0.0857957175  0.137075449
## 2018-09-28 -0.0048359814 -0.0202722585 -0.0662814853  0.0173902455  0.001210556
## 2018-10-31 -0.2258869989 -0.1014946112 -0.0801693259 -0.2149050241 -0.287373613
## 2018-11-30  0.0560700324  0.0173350444 -0.0765079559 -0.0532519750 -0.253667193
## 2018-12-31 -0.1180514843 -0.0600659860 -0.0701060960 -0.0667287371 -0.202283544
## 2019-01-31  0.1348080312  0.0745950421  0.2402517194  0.2377564232  0.073974041
## 2019-02-28 -0.0469930640  0.0005860656 -0.0319402489  0.0533383459  0.071594104
## 2019-03-29  0.0824420184  0.0437155813  0.0319402489 -0.0043098364  0.151870400
## 2019-04-30  0.0786806224  0.0185791219  0.1486248303  0.0384589452  0.007987331
## 2019-05-31 -0.0818753491 -0.0802526734 -0.0859589174 -0.0764150093 -0.288680283
## 2019-06-28  0.0646557767 -0.0216516170  0.0838885857  0.0676869455  0.192591699
## 2019-07-31 -0.0142806686  0.1178241282  0.0063528038 -0.1286120040  0.026972528
## 2019-08-30 -0.0496880810 -0.0229757770 -0.0450721182 -0.0948922909 -0.006207763
## 2019-09-30 -0.0229951159  0.0253862532 -0.0417379665 -0.0931610341  0.038414567
## 2019-10-31  0.0232034080  0.0303740414  0.0734377660  0.0713417093  0.143946589
## 2019-11-29  0.0134958216  0.0353467210  0.0508131951  0.0905829375  0.076031675
## 2019-12-31  0.0257863501  0.0267087557  0.0177448633  0.0279227475  0.082162645
## 2020-01-31  0.0834803026  0.0674022889 -0.0164067621  0.0643897941  0.004790938
## 2020-02-28 -0.0642332026 -0.0675069091 -0.0478817313  0.0670727184  0.133626880
## 2020-03-31  0.0344213022 -0.1420101228 -0.1431448395  0.0173805126 -0.024248341
## 2020-04-30  0.2381504762  0.1475576504  0.2047989739  0.1116390683  0.103279663
## 2020-05-29 -0.0128673719  0.0624755718  0.0949058790 -0.0002858819  0.194461708
## 2020-06-30  0.1218341331 -0.0108501926  0.0087580695  0.0807737255  0.068216599
## 2020-07-31  0.1372488933  0.0481166742  0.1107757624  0.0717317079  0.111189472
## 2020-08-31  0.0866005735  0.0908922991  0.1448210153  0.0799294267  0.231105548
## 2020-09-30 -0.0916533253 -0.1060268510 -0.1128923908 -0.0573784336  0.011895498
## 2020-10-30 -0.0364089187  0.0977571410  0.0046091699 -0.0497965496 -0.076501378
## 2020-11-30  0.0425228214  0.0821050467  0.0513371446  0.0309614228  0.066921810
## 2020-12-31  0.0276719582 -0.0010035791 -0.0138514776  0.0970871760 -0.025899906
## 2021-01-29 -0.0156985929  0.0417490133 -0.0558197489 -0.0155438392 -0.005011020
## 2021-02-26 -0.0359675607  0.1011702012 -0.0027521189  0.0120609342  0.054293336
## 2021-03-31  0.0003717151  0.0198860270  0.1338951686 -0.0324211662 -0.026723167
## 2021-04-30  0.1139202399  0.1319750315  0.0986905392 -0.0158244342  0.117297882
## 2021-05-28 -0.0730764715  0.0014223884  0.0111654943 -0.0209792775  0.079071028
## 2021-06-30  0.0651836137  0.0354053480  0.0561318624  0.0492815858  0.208332102
## 2021-07-30 -0.0332696301  0.0984923550  0.0244043152 -0.0203491346 -0.025494121
## 2021-08-31  0.0421339363  0.0713986318  0.0627652905  0.0950694939  0.138204162
## 2021-09-30 -0.0550034409 -0.0792264698 -0.1113883927  0.0698019104 -0.077484599
## 2021-10-29  0.0262547651  0.1021042415 -0.0477344467  0.1231245610  0.210395907
## 2021-11-30  0.0391473463 -0.0424181785  0.0027467088 -0.0727081801  0.245338307
## 2021-12-31 -0.0505062029  0.0206076928  0.0359899873 -0.0634444996 -0.105149342
## 2022-01-31 -0.1085098142 -0.0681922265 -0.0711186351 -0.3438762220 -0.183267304
## 2022-02-28  0.0263230079 -0.0018233817 -0.3950332245 -0.0794420172 -0.004133520
## 2022-03-31  0.0596239190  0.0292625372  0.0522973497 -0.0518377428  0.112576062
## 2022-04-29 -0.2711856801 -0.1978011431 -0.1036330441 -0.6769151054 -0.386065553
## 2022-05-31 -0.0333130879 -0.0030499316 -0.0346638903  0.0365177351  0.006716913
## 2022-06-30 -0.1238178226 -0.0431002531 -0.1830448709 -0.1213919016 -0.208219196
## 2022-07-29  0.2394860591  0.0653368173 -0.0134230113  0.2516130360  0.180791974
## 2022-08-31 -0.0625299224 -0.0721789007  0.0237875377 -0.0059759741 -0.185089174
## 2022-09-30 -0.1149865758 -0.1234704679 -0.1830210618  0.0517762558 -0.217576883
## 2022-10-31 -0.0981105335 -0.0119900012 -0.3759808898  0.2148866190  0.106044073
## 2022-11-30 -0.0593198454  0.0663157995  0.2372133274  0.0457052075  0.226462019
## 2022-12-30 -0.1391406409 -0.1350744189  0.0187892554 -0.0354794336 -0.146693652
## 2023-01-31  0.2051735029  0.1135551797  0.2134238500  0.1823328761  0.290330264
## 2023-02-28 -0.0902516639 -0.0930260848  0.1606982013 -0.0939461699  0.172531420
## 2023-03-31  0.0918019370  0.1413151736  0.1918602047  0.0699795345  0.179536531
## 2023-04-28  0.0206963031  0.0342100141  0.1256680688 -0.0460542525 -0.001008489
## 2023-05-31  0.1340765703  0.1351255225  0.0967012960  0.1805873321  0.310008200
## 2023-06-30  0.0779864104 -0.0261383286  0.0807399047  0.1084198950  0.111729812
## 2023-07-31  0.0251489708  0.1032530520  0.1045237781 -0.0034566798  0.099530394
## 2023-08-31  0.0318772770  0.0256624090 -0.0739485477 -0.0121241234  0.054674363
## 2023-09-29 -0.0821945627 -0.0397760079  0.0144945221 -0.1384715458 -0.126218838
## 2023-10-31  0.0458940197 -0.0532014762  0.0035245134  0.0864352180 -0.064546307
## 2023-11-30  0.0931972815  0.0658825274  0.0824120058  0.1408734072  0.137050335
## 2023-12-29  0.0392628771  0.0526165850  0.0787649944  0.0268736655  0.057262957
## 2024-01-31  0.0212288659  0.0029308039  0.0973218619  0.1472315750  0.217059180
## 2024-02-29  0.1300782611 -0.0117748867  0.2292254078  0.0665352594  0.251388450
## 2024-03-28  0.0202729146  0.0862345701 -0.0093266641  0.0072878139  0.132939733
## 2024-04-30 -0.0302797899  0.0755835392 -0.1211634354 -0.0979911057 -0.044746487
## 2024-05-31  0.0081949152  0.0579975030  0.0817845141  0.1529150450  0.238127472
## 2024-06-28  0.0910037984  0.0555803249  0.0780399543  0.0505386138  0.119508657
## 2024-07-31 -0.0329830511 -0.0600140899 -0.0600559751 -0.0714375604 -0.054220171
## 2024-08-30 -0.0464130352 -0.0487374989  0.0933880676  0.1099097581  0.019883146
## 2024-09-30  0.0429307038  0.0163309589  0.0945167054  0.0112292200  0.017277928
## 2024-10-31  0.0003755644  0.0312228754 -0.0085263633  0.0638447163  0.089122631
## 2024-11-29  0.1091142212 -0.0127038811  0.0118051295  0.1595497355  0.040520710
## 2024-12-31  0.0538418744  0.1148757734  0.0201028320  0.0050728010 -0.028993106
## 2025-01-31  0.0800742352  0.0748849616  0.1630193142  0.0915374451 -0.111926736
## 2025-02-28 -0.1130190481 -0.1807739532 -0.0309150196  0.0038828370  0.039598579
## 2025-03-31 -0.1095146233 -0.0951932419 -0.1469657547 -0.0502225296 -0.141937962
## 2025-04-30 -0.0311757737  0.0265457341 -0.0486340804  0.1935925475  0.004970099
## 2025-05-30  0.1058429765  0.0783361928  0.1650049154  0.0645899020  0.215623673
## 2025-06-30  0.0677922335  0.0270180736  0.1317316461  0.1036916319  0.156363856
## 2025-07-31  0.0649401278  0.0851844061  0.0467822661 -0.1441174565  0.118521186
## 2025-08-29 -0.0220690894  0.1038951429 -0.0459561912  0.0412703555 -0.020963769
## 2025-09-30 -0.0420508819  0.1334973732 -0.0051905924 -0.0077518692  0.068827324
## 2025-10-31  0.1063983418  0.1455576997 -0.1245959761 -0.0691108133  0.081830418
## 2025-11-14 -0.0398039586 -0.0171453222 -0.0618572811 -0.0059972363 -0.062772130
calculate_component_contribution <- function(.data, w) {
    
    covariance_matrix <- cov(.data)
    
    sd_portfolio <- sqrt(t(w) %*% covariance_matrix %*% w)
    
    component_contribution <- (t(w) %*% covariance_matrix * w) / sd_portfolio[1,1]
    
    component_percentages <- (component_contribution / sd_portfolio[1,1]) %>%
        round(3) %>%
        as_tibble()
    
    return(component_percentages)
}

asset_returns_wide_tbl %>% calculate_component_contribution(w = c(.25, .25, .2, .2, .1))
## # A tibble: 1 × 5
##    AMZN GOOGL  META  NFLX  NVDA
##   <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.244 0.175 0.189 0.275 0.116

6 Plot: Colum Chart of Component Contribution and Weight

Column Chart of Component Contribution and weight

plot_data <- asset_returns_wide_tbl %>% 
    
    calculate_component_contribution(w = c(.25, .25, .2, .2, .1)) %>%
    
    # Transform to long form
    
pivot_longer(cols = everything(),names_to = "Asset", values_to = "Contribution") %>%
    # Add weights
    add_column(weight = c(.25, .25, .2, .2, .1)) %>%
    
    # Transform to long
    pivot_longer(cols = c(Contribution, weight), names_to = "type", values_to = "value")
plot_data %>%
    
    ggplot(aes(x = Asset, y = value, fill = type)) +
    geom_col(position = "dodge") +
    scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
    scale_fill_tq() +
    theme(plot.title = element_text(hjust = .5)) +
    theme_tq()+
    labs(title = "Percent Contribution to Portfolio Volatility and Weight",
         y = "Percent", x = NULL)

Which of the assets in your portfolio the largest contributor to the portfolio volatility? Do you think your portfolio risk is concentrated in any one asset?

Answer: NFLX is the largest contributor to my portfolio’s volatility at a value of 27.5%. With that being said, I don’t believe my portfolio’s risk is concentrated in any one specific asset as all other assets have contributions ranging from 11.6% - 24.4%. Given that there are only 5 assets in this portfolio, these ranges are acceptable and fairly balanced in my honest opinion. Also, volatility isn’t necessarily a bad thing either as it presents potential for larger gains within a specific asset if handled correctly.