├── .gitignore ├── 0 data ├── 0_fetch.R ├── 1_process.R ├── 2_analysis.R └── Kenneth French │ └── F-F_Research_Data_5_Factors_2x3_daily.csv ├── 1 covariance estimation ├── Matlab │ ├── COMFORT-DCC │ │ ├── consolidate.R │ │ ├── lib │ │ │ ├── CD2ab.p │ │ │ ├── CM2step_COMFORT_IID.p │ │ │ ├── COMFORT_IID.p │ │ │ ├── COMFORTestimation.m │ │ │ ├── CorrmatEstimator.p │ │ │ ├── DCCengine.p │ │ │ ├── DCCestimate.p │ │ │ ├── EGEGinv.p │ │ │ ├── EGEGinvFREECOMFORT.p │ │ │ ├── EVzb.p │ │ │ ├── Evz.p │ │ │ ├── FREECOMFORTestimation.p │ │ │ ├── FREElike2005.p │ │ │ ├── FREEungarch.p │ │ │ ├── GARCH11.p │ │ │ ├── GARCHinitParams.p │ │ │ ├── GARCHsetup.p │ │ │ ├── GARCHweights.p │ │ │ ├── GIGmoment.m │ │ │ ├── GammaEstimatorFREECOMFORT.p │ │ │ ├── GaussianCCModel.p │ │ │ ├── Gpdf.p │ │ │ ├── GstepARp.p │ │ │ ├── GstepEstimator.p │ │ │ ├── GstepMomentsToParams.p │ │ │ ├── IIDGstep.p │ │ │ ├── IIDmugam.p │ │ │ ├── LookUpTableGARCH.p │ │ │ ├── LookUpTableGIG.p │ │ │ ├── LowerLevelParametersAndPrint.p │ │ │ ├── MARCMARSfilename.p │ │ │ ├── MNIGpdf.p │ │ │ ├── MVSLpdf.p │ │ │ ├── MVStpdf.p │ │ │ ├── Mstep.p │ │ │ ├── MstepFREE.p │ │ │ ├── PLaplaceEM.p │ │ │ ├── RU_COMFORT.p │ │ │ ├── SkewnessInit.p │ │ │ ├── SymPDcorrmatrix.p │ │ │ ├── SymPDcovmatrix.p │ │ │ ├── VCengine.p │ │ │ ├── _COMFORT_All.m │ │ │ ├── _GIGmoment.p │ │ │ ├── _RunCOMFORT.m │ │ │ ├── ab2CD.p │ │ │ ├── atau2tau.p │ │ │ ├── b1opt.p │ │ │ ├── b2opt.p │ │ │ ├── besselk_ln.p │ │ │ ├── besselk_ratio.p │ │ │ ├── besselk_watson_ln.p │ │ │ ├── besselkb.p │ │ │ ├── bfilter.p │ │ │ ├── brange.p │ │ │ ├── cDCCengine.p │ │ │ ├── cDCCestimate.p │ │ │ ├── calcPredictedCov.m │ │ │ ├── cexp.p │ │ │ ├── clog.p │ │ │ ├── cval.p │ │ │ ├── cvarlimghyp.p │ │ │ ├── doitGpdf.p │ │ │ ├── doitGstepEstimator.p │ │ │ ├── einschrk.p │ │ │ ├── f_ru.p │ │ │ ├── f_ru2.p │ │ │ ├── f_var.p │ │ │ ├── f_variance.p │ │ │ ├── f_variance_constraints.p │ │ │ ├── fact.p │ │ │ ├── ghyppdf.p │ │ │ ├── initGARCH.p │ │ │ ├── initparams.p │ │ │ ├── klambda.p │ │ │ ├── like2005.p │ │ │ ├── likeCM2step_COMFORT_IID.p │ │ │ ├── likeGstep.p │ │ │ ├── likeGstepARp.p │ │ │ ├── likeMALap.p │ │ │ ├── likeNIG.p │ │ │ ├── likeStud_t.p │ │ │ ├── loglikDCC.p │ │ │ ├── loglikVC.p │ │ │ ├── loglikcDCC.p │ │ │ ├── loglikweights.p │ │ │ ├── logpdf.p │ │ │ ├── logpdf2.p │ │ │ ├── logpdf3.p │ │ │ ├── meanvariance01.p │ │ │ ├── minvariance01.p │ │ │ ├── my_num2str.p │ │ │ ├── mylogbesselkApprox.p │ │ │ ├── myvech.p │ │ │ ├── netreturnsPatrick.p │ │ │ ├── netreturns_Marc.p │ │ │ ├── newGstep.p │ │ │ ├── normalGARCHPL.p │ │ │ ├── quickbesselk.p │ │ │ ├── setType.m │ │ │ ├── setseed.p │ │ │ ├── tsplot.p │ │ │ └── ungarch.p │ │ ├── main.m │ │ ├── runRanges.m │ │ ├── runRanges_tests.m │ │ ├── run_euler.sh │ │ ├── run_pc.sh │ │ ├── splitIntoIntervals.m │ │ ├── splitIntoIntervals_tests.m │ │ ├── submit_120.sh │ │ ├── submit_24.sh │ │ └── worklist.csv │ ├── DCC1step_1000 │ │ ├── consolidate.R │ │ ├── copy_from_euler.sh │ │ ├── copy_to_euler.sh │ │ ├── lib │ │ │ ├── CD2ab.m │ │ │ ├── DCC1step.m │ │ │ ├── DCCengine.m │ │ │ ├── DCCestimate.m │ │ │ ├── SymPDcorrmatrix.m │ │ │ ├── SymPDcovmatrix.m │ │ │ ├── ab2CD.m │ │ │ ├── einschrk.m │ │ │ ├── loglikDCC.m │ │ │ ├── normalGARCHPL.m │ │ │ └── ungarch.m │ │ ├── main.m │ │ ├── run_euler.sh │ │ ├── submit_120.sh │ │ └── zip.sh │ ├── DCC1step_126 │ │ ├── consolidate.R │ │ ├── lib │ │ │ ├── CD2ab.m │ │ │ ├── DCC1step.m │ │ │ ├── DCCengine.m │ │ │ ├── DCCestimate.m │ │ │ ├── SymPDcorrmatrix.m │ │ │ ├── SymPDcovmatrix.m │ │ │ ├── ab2CD.m │ │ │ ├── einschrk.m │ │ │ ├── loglikDCC.m │ │ │ ├── normalGARCHPL.m │ │ │ └── ungarch.m │ │ ├── main.m │ │ └── run_pc.sh │ └── DCC1step_252 │ │ ├── DCC1step_original.zip │ │ ├── consolidate.R │ │ ├── lib │ │ ├── CD2ab.m │ │ ├── DCC1step.m │ │ ├── DCCengine.m │ │ ├── DCCestimate.m │ │ ├── SymPDcorrmatrix.m │ │ ├── SymPDcovmatrix.m │ │ ├── ab2CD.m │ │ ├── einschrk.m │ │ ├── loglikDCC.m │ │ ├── normalGARCHPL.m │ │ └── ungarch.m │ │ └── main.m ├── R │ ├── CAPM │ │ ├── capm.R │ │ └── consolidate.R │ ├── DCC-GARCH │ │ ├── consolidate.R │ │ ├── main.R │ │ ├── submit.sh │ │ └── zip.sh │ ├── merge.R │ └── sub-sampling analysis │ │ ├── sub-sampling analysis.R │ │ ├── sub-sampling coefficients and variance.pdf │ │ └── sub-sampling runtimes.pdf └── analysis │ ├── analysis.R │ ├── output │ ├── beta_SP500_stocks.pdf │ ├── covariance_SP500_stocks_with_market.pdf │ └── variance_Fama-French_market.pdf │ └── runtimes │ ├── log_COMFORT-DCC.txt │ ├── log_DCC1step_sp100.txt │ ├── log_DCC1step_sp500_1000.txt │ └── runtimes.R ├── 2 backtest ├── backtest.R ├── results │ ├── eq_CAPM-252_portfolio_characteristics.tex │ ├── eq_CAPM_portfolio_characteristics.tex │ ├── eq_CDCC-1000_portfolio_characteristics.tex │ ├── eq_COMFORT-DCC_portfolio_characteristics.tex │ ├── eq_DCC-1000_portfolio_characteristics.tex │ ├── eq_DCC-252_portfolio_characteristics.tex │ ├── eq_DCC_portfolio_characteristics.tex │ ├── eq_avg_beta_deciles_1_10_CAPM-252.tex │ ├── eq_avg_beta_deciles_1_10_CAPM.tex │ ├── eq_avg_beta_deciles_1_10_CDCC-1000.tex │ ├── eq_avg_beta_deciles_1_10_COMFORT-DCC.tex │ ├── eq_avg_beta_deciles_1_10_DCC-1000.tex │ ├── eq_avg_beta_deciles_1_10_DCC-252.tex │ ├── eq_avg_beta_deciles_1_10_DCC.tex │ ├── eq_avg_ret_per_decile.tex │ ├── eq_beta_std_dev.tex │ ├── eq_cum_ret_deciles_CAPM-252.tex │ ├── eq_cum_ret_deciles_CAPM.tex │ ├── eq_cum_ret_deciles_CDCC-1000.tex │ ├── eq_cum_ret_deciles_COMFORT-DCC.tex │ ├── eq_cum_ret_deciles_DCC-1000.tex │ ├── eq_cum_ret_deciles_DCC-252.tex │ ├── eq_cum_ret_deciles_DCC.tex │ ├── eq_cum_ret_high-low.tex │ ├── eq_univariate_portfolio_analysis.tex │ ├── vw_CAPM-252_portfolio_characteristics.tex │ ├── vw_CAPM_portfolio_characteristics.tex │ ├── vw_CDCC-1000_portfolio_characteristics.tex │ ├── vw_COMFORT-DCC_portfolio_characteristics.tex │ ├── vw_DCC-1000_portfolio_characteristics.tex │ ├── vw_DCC-252_portfolio_characteristics.tex │ ├── vw_DCC_portfolio_characteristics.tex │ ├── vw_avg_beta_deciles_1_10_CAPM-252.tex │ ├── vw_avg_beta_deciles_1_10_CAPM.tex │ ├── vw_avg_beta_deciles_1_10_CDCC-1000.tex │ ├── vw_avg_beta_deciles_1_10_COMFORT-DCC.tex │ ├── vw_avg_beta_deciles_1_10_DCC-1000.tex │ ├── vw_avg_beta_deciles_1_10_DCC-252.tex │ ├── vw_avg_beta_deciles_1_10_DCC.tex │ ├── vw_avg_ret_per_decile.tex │ ├── vw_beta_std_dev.tex │ ├── vw_cum_ret_deciles_CAPM-252.tex │ ├── vw_cum_ret_deciles_CAPM.tex │ ├── vw_cum_ret_deciles_CDCC-1000.tex │ ├── vw_cum_ret_deciles_COMFORT-DCC.tex │ ├── vw_cum_ret_deciles_DCC-1000.tex │ ├── vw_cum_ret_deciles_DCC-252.tex │ ├── vw_cum_ret_deciles_DCC.tex │ ├── vw_cum_ret_high-low.tex │ └── vw_univariate_portfolio_analysis.tex └── tpls │ ├── tpl_beta_std_dev.tex │ ├── tpl_portfolio_characteristics.tex │ └── tpl_univariate_portfolio.tex ├── DCC-GARCH_deciles.png ├── README.md ├── functions.R ├── models_performance.png └── report ├── Modeling Conditional Betas with Application in Asset Allocation.pdf ├── Modeling Conditional Betas with Application in Asset Allocation.tex ├── _compile_report.sh ├── _preamble.tex ├── _references.bib ├── _variables.tex ├── abstract.pdf ├── abstract.tex ├── erroneous_covariances.tex ├── executive_summary.pdf ├── executive_summary.tex ├── scratchpad.pdf ├── scratchpad.tex ├── sec_abstract_text.tex ├── sec_executive_summary.tex ├── sec_statutory_declaration.tex ├── sec_titlepage.tex ├── uzh_logo_e_pos-eps-converted-to.pdf └── uzh_logo_e_pos.eps /.gitignore: -------------------------------------------------------------------------------- 1 | WRDS_pwd.txt 2 | .Rhistory 3 | parallel-log.txt 4 | out 5 | TRUE 6 | report/*.aux 7 | report/*.bbl 8 | report/*.blg 9 | report/*.lof 10 | report/*.lot 11 | report/*.log 12 | report/*.out 13 | report/*.synctex.gz 14 | report/*.toc 15 | CRSP -------------------------------------------------------------------------------- /0 data/0_fetch.R: -------------------------------------------------------------------------------- 1 | library(RPostgres) 2 | library(plyr) 3 | library(data.table) 4 | library(readr) 5 | 6 | # break on warnings 7 | options(warn=2) 8 | 9 | 10 | # sample period 11 | # from <- '1963-07-01' 12 | from <- '1996-01-01' 13 | to <- '2017-12-31' 14 | 15 | 16 | # connect to WRDS database 17 | wrds <- dbConnect(Postgres(), host='wrds-pgdata.wharton.upenn.edu', port=9737, dbname='wrds', sslmode='require', user='rbeeli', password=read_file('WRDS_pwd.txt')) 18 | 19 | 20 | # query S&P 500 single stock returns including delisting information, market cap and volume 21 | res <- dbSendQuery(wrds, paste0( 22 | "select b.permno, b.date, b.ret, d.dlret, d.dlstcd, (ABS(b.prc) * (b.shrout * 1000)) as cap, GREATEST(b.vol, 0) as vol, ABS(b.prc) as prc, (b.shrout * 1000) as shrout 23 | from crsp.dsp500list a 24 | join crsp.dsf b on b.permno=a.permno 25 | left join crsp.dse d on d.permno=b.permno and d.date=b.date and d.dlstcd is not null 26 | where b.date >= a.start and b.date <= a.ending 27 | and b.date >= '", from, "' and b.date <= '", to, "' 28 | order by b.date")) 29 | sp500StocksData <- dbFetch(res, n=-1) 30 | dbClearResult(res) 31 | 32 | # query S&P 500 index returns 33 | # vwretd - Value-Weighted Return (includes distributions) 34 | # ewretd - Equal-Weighted Return (includes distributions) 35 | res <- dbSendQuery(wrds, paste0( 36 | "select caldt as date, vwretd, ewretd 37 | from crsp.dsp500 38 | where caldt >= '", from, "' and caldt <= '", to, "'")) 39 | sp500IndexData <- dbFetch(res, n=-1) 40 | dbClearResult(res) 41 | 42 | # close connection 43 | dbDisconnect(wrds) 44 | rm(res) 45 | rm(wrds) 46 | 47 | # write to CSV files 48 | fwrite(sp500IndexData, 'CRSP/sp500_index.csv', sep=';') 49 | fwrite(sp500StocksData, 'CRSP/sp500_stocks.csv', sep=';') 50 | 51 | 52 | 53 | 54 | # https://wrds-www.wharton.upenn.edu/pages/support/wrds-cloud/r-wrds-cloud/accessing-wrds-data-r/ 55 | # 56 | # res <- dbSendQuery(wrds, "select distinct table_schema 57 | # from information_schema.tables 58 | # where table_type ='VIEW' 59 | # or table_type ='FOREIGN TABLE' 60 | # order by table_schema") 61 | # data <- dbFetch(res, n=-1) 62 | # dbClearResult(res) 63 | # data 64 | # 65 | # 66 | # res <- dbSendQuery(wrds, "select distinct table_name 67 | # from information_schema.columns 68 | # where table_schema like 'crsp%' 69 | # order by table_name") 70 | # data <- dbFetch(res, n=-1) 71 | # dbClearResult(res) 72 | # data 73 | # 74 | # res <- dbSendQuery(wrds, "select column_name, data_type 75 | # from information_schema.columns 76 | # where table_schema like 'crsp' and table_name='msenames'") 77 | # data <- dbFetch(res, n=-1) 78 | # dbClearResult(res) 79 | # data -------------------------------------------------------------------------------- /0 data/2_analysis.R: -------------------------------------------------------------------------------- 1 | library(data.table) 2 | 3 | data.stocks <- fread('CRSP/sp100_stock_returns.csv', header=T) 4 | data.stocks.raw <- fread('CRSP/sp100_stocks.csv', header=T) 5 | 6 | 7 | # show data rows before and after a delisting has occured 8 | has.dlret <- which(!is.na(data.stocks.raw$dlret)) 9 | 10 | for (i in has.dlret) { 11 | date <- data.stocks.raw[i, ]$date 12 | stock.permno <- data.stocks.raw[i, ]$permno 13 | stock.data <- data.stocks.raw[data.stocks.raw[, permno==stock.permno], ] 14 | date.idx <- which(stock.data$date == date) 15 | 16 | range <- (date.idx-1):(date.idx+1) 17 | print(stock.data[range, ]) 18 | print('----------------------------') 19 | } 20 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/consolidate.R: -------------------------------------------------------------------------------- 1 | library(data.table) 2 | library(matrixStats) 3 | 4 | source('../../../functions.R') 5 | 6 | consolidated.path <- './consolidated' 7 | out.path <- './out' 8 | 9 | 10 | path.out.make <- function(file) { 11 | paste0(out.path, '/', file) 12 | } 13 | 14 | path.consolidated.make <- function(file) { 15 | paste0(consolidated.path, '/', file) 16 | } 17 | 18 | 19 | # available dates 20 | returns <- fread('../../../0 data/CRSP/sp500_stock_ex_returns_demeaned_scaled.csv', header=T, sep=';') 21 | 22 | # read files of interest 23 | files <- list.files(path.out.make(''), pattern='*.csv') 24 | stocks.cols <- paste0('x', colnames(returns[, !c('date', 'market')])) 25 | 26 | covs.1stepahead <- matrix(NA, nrow=nrow(returns), ncol=length(stocks.cols), dimnames=list(c(), stocks.cols)) 27 | vars.1stepahead.market <- matrix(NA, nrow=nrow(returns), ncol=length(stocks.cols), dimnames=list(c(), stocks.cols)) 28 | vars.1stepahead.stocks <- matrix(NA, nrow=nrow(returns), ncol=length(stocks.cols), dimnames=list(c(), stocks.cols)) 29 | 30 | for (file in files) { 31 | file.path <- path.out.make(file) 32 | 33 | name <- regmatches(file, regexpr('x[0-9]{5}', file)) 34 | 35 | if (file.info(file.path)$size == 0) { 36 | cat('File ', file, ' empty. Skipping. \n') 37 | next 38 | } 39 | 40 | cat('Processing file ', name, '... \n') 41 | 42 | vars.covs.stocks.market <- fread(path.out.make(file), header=T, sep=';') 43 | 44 | vars.market <- vars.covs.stocks.market$var_market 45 | vars.stock <- vars.covs.stocks.market$var_stock 46 | covs.stocks <- vars.covs.stocks.market$cov 47 | 48 | idxs.date <- which(returns$date %in% vars.covs.stocks.market$date) 49 | 50 | 51 | # covariances stocks 52 | covs.1stepahead[idxs.date, name] <- covs.stocks 53 | 54 | # variances market 55 | vars.1stepahead.market[idxs.date, name] <- vars.market 56 | 57 | # variances stocks 58 | vars.1stepahead.stocks[idxs.date, name] <- vars.stock 59 | } 60 | 61 | # add date as first column 62 | covs.1stepahead <- cbind(data.table(date=returns$date), covs.1stepahead) 63 | vars.1stepahead.market <- cbind(data.table(date=returns$date), vars.1stepahead.market) 64 | vars.1stepahead.stocks <- cbind(data.table(date=returns$date), vars.1stepahead.stocks) 65 | 66 | # market variance average and median 67 | vars.1stepahead.market$average <- rowMeans(vars.1stepahead.market[, ..stocks.cols], na.rm=T) 68 | vars.1stepahead.market$median <- rowMedians(as.matrix(vars.1stepahead.market[, ..stocks.cols]), na.rm=T) 69 | 70 | 71 | 72 | # remove rows with NAs 73 | na.rows <- which(rowSums(is.na(covs.1stepahead[, ..stocks.cols])) == length(stocks.cols)) 74 | 75 | covs.1stepahead <- covs.1stepahead[-na.rows, ] 76 | vars.1stepahead.market <- vars.1stepahead.market[-na.rows, ] 77 | vars.1stepahead.stocks <- vars.1stepahead.stocks[-na.rows, ] 78 | 79 | 80 | 81 | # write consolidated data to disk 82 | if (!dir.exists(consolidated.path)) 83 | dir.create(consolidated.path) 84 | 85 | # covs.1stepahead.csv 86 | fwrite(covs.1stepahead, path.consolidated.make('covs.1stepahead.csv'), sep=';') 87 | 88 | # vars.1stepahead.market.csv 89 | fwrite(vars.1stepahead.market, path.consolidated.make('vars.1stepahead.market.csv'), sep=';') 90 | 91 | # vars.1stepahead.stocks.csv 92 | fwrite(vars.1stepahead.stocks, path.consolidated.make('vars.1stepahead.stocks.csv'), sep=';') 93 | 94 | 95 | 96 | 97 | # plot some data 98 | matplot(vars.1stepahead.market[, sample(colnames(vars.1stepahead.market), 20), with=F], type='l', main='Market variances') 99 | 100 | matplot(vars.1stepahead.market[, c('average', 'median')], type='l', col=c('red', 'black'), main='Average and median market variance') 101 | legend('topleft', legend=c('average', 'median'), fill=c('red', 'black'), border='white') 102 | 103 | matplot(covs.1stepahead[, sample(colnames(covs.1stepahead), 20), with=F], type='l', main='Stock/market covariances') 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/CD2ab.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/CD2ab.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/CM2step_COMFORT_IID.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/CM2step_COMFORT_IID.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/COMFORT_IID.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/COMFORT_IID.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/CorrmatEstimator.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/CorrmatEstimator.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/DCCengine.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/DCCengine.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/DCCestimate.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/DCCestimate.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/EGEGinv.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/EGEGinv.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/EGEGinvFREECOMFORT.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/EGEGinvFREECOMFORT.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/EVzb.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/EVzb.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/Evz.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/Evz.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/FREECOMFORTestimation.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/FREECOMFORTestimation.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/FREElike2005.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/FREElike2005.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/FREEungarch.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/FREEungarch.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/GARCH11.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/GARCH11.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/GARCHinitParams.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/GARCHinitParams.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/GARCHsetup.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/GARCHsetup.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/GARCHweights.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/GARCHweights.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/GIGmoment.m: -------------------------------------------------------------------------------- 1 | function [EXalpha EXalphaprime]=GIGmoment(alpha,lambda,chi,psi) 2 | %function computes alpha moment of the GIG(lambda,chi,psi) r.v. and the 3 | %derivative of alpha moment w.r.t. alpha 4 | %USES: derivest.m to get EXalphaprime 5 | 6 | if lambda>0 7 | if chi>=0 && psi>0 8 | paramsOK=1; 9 | else 10 | paramsOK=0; 11 | end 12 | elseif lambda==0 13 | if chi>0 && psi>0 14 | paramsOK=1; 15 | else 16 | paramsOK=0; 17 | end 18 | elseif lambda<0 19 | if chi>0 && psi>=0 20 | paramsOK=1; 21 | else 22 | paramsOK=0; 23 | end 24 | end 25 | if paramsOK==1 26 | if abs(chi)<1e-12 && abs(psi-2)<1e-12 %MALap limiting case 27 | if alpha==1 28 | EXalpha=lambda; 29 | elseif alpha==2 30 | EXalpha=lambda.^2+lambda; 31 | elseif alpha==-1 32 | if lambda>1 33 | EXalpha=1./(lambda-1); 34 | else 35 | EXalpha=realmax; %moment does not exist. 36 | end 37 | else 38 | error('the moment is not supported for this distribution MALap') 39 | end 40 | elseif abs(chi+2*lambda)<1e-12 && abs(psi)<1e-12 %limiting case: Stud_t or NCT 41 | if alpha==1 %v/2 /(v/2) 42 | if lambda<-1 && chi>0 43 | EXalpha=-0.5*chi./(lambda+1); 44 | elseif lambda>-1 && chi<0 %never the case b/c chi>=0 for any GIG r.v. 45 | EXalpha=-0.5*chi./(lambda+1); 46 | else 47 | EXalpha=NaN; 48 | end 49 | elseif alpha==2 50 | if lambda < -2 51 | a = -lambda; b = 0.5*chi; 52 | %EXalpha=(b.^2 + (a-2).* b.^2 )./( (a-1).^(2) .* (a-2) ); 53 | EXalpha=(b.^2)./( (a-1) .* (a-2) ); %E(X^2) 54 | %EXalpha=(b.^2)./( (a-1).^2 .* (a-2) ); %Var(X) = E(X^2)-(EX)^2 55 | else 56 | EXalpha=realmax; 57 | end 58 | elseif alpha==-1 59 | EXalpha = -0.5 .* lambda .* chi; 60 | elseif alpha==0.5 61 | if lambda < -0.5 62 | a = -lambda; b = 0.5*chi; 63 | EXalpha = b.^(0.5)./(a-0.5); 64 | else 65 | EXalpha=realmax; 66 | end 67 | else 68 | error('the moment is not supported for this distribution Stud_t') 69 | end 70 | elseif abs(lambda+0.5)<1e-12 %special case NIG! 71 | if alpha==1 72 | EXalpha=sqrt(chi./psi); 73 | elseif alpha==-1 74 | EXalpha=sqrt(psi./chi)+1./chi; 75 | elseif alpha==2 76 | EXalpha=(chi./psi).*(1+1./sqrt(chi.*psi)); 77 | else 78 | error('the moment is not supported for this distribution NIG') 79 | end 80 | elseif abs(psi)<1e-21 81 | EXalpha = 0.5.^alpha * chi.^alpha * gamma(-lambda-alpha)/gamma(-lambda); 82 | else 83 | %EXalpha=(chi/psi).^(alpha/2).*(quickbesselk(lambda+alpha,sqrt(chi*psi))/(quickbesselk(lambda,sqrt(chi*psi)))); 84 | EXalpha=(chi/psi).^(alpha/2).*exp(mylogbesselkApprox(lambda+alpha,sqrt(chi*psi))-mylogbesselkApprox(lambda,sqrt(chi*psi))); 85 | nanID=isnan(EXalpha); infID=abs(EXalpha)==Inf; 86 | 87 | if sum(nanID)>0 88 | %EXalpha(logical(nanID))=(chi(nanID)/psi(nanID)).^(alpha(nanID)/2).*besselratio(lambda(nanID),sqrt(chi(nanID)*psi(nanID)),3,alpha(nanID)); 89 | EXalpha(logical(nanID))=(chi(nanID)/psi(nanID)).^(alpha(nanID)/2).*besselk_ratio(lambda(nanID),sqrt(chi(nanID)*psi(nanID)),3,alpha(nanID)); 90 | nanID=isnan(EXalpha); 91 | if sum(nanID)>0 92 | EXalpha(logical(nanID))=mean(EXalpha(logical(1-nanID))); 93 | end 94 | end 95 | 96 | if sum(infID)>0 97 | %EXalpha(logical(infID))=(chi(infID)/psi(infID)).^(alpha(infID)/2).*besselratio(lambda(infID),sqrt(chi(infID)*psi(infID)),3,alpha(infID)); 98 | EXalpha(logical(infID))=(chi(infID)/psi(infID)).^(alpha(infID)/2).*besselk_ratio(lambda(infID),sqrt(chi(infID)*psi(infID)),3,alpha(infID)); 99 | infID=abs(EXalpha)==Inf; 100 | if sum(infID)>0 101 | EXalpha(logical(infID))=mean(EXalpha(logical(1-infID))); 102 | end 103 | end 104 | end 105 | else 106 | error('Wrong parametrization of the GIG r.v.') 107 | end 108 | if nargout>1 109 | [der,errest,finaldelta] = derivest(@(alpha1)GIGmoment(alpha1,lambda,chi,psi),alpha); 110 | tol=1e-12; 111 | if errest>tol 112 | [derf,errestf,finaldelta] = derivest(@(alpha1)GIGmoment(alpha1,lambda,chi,psi),alpha,'Style','forward'); 113 | end 114 | if errest>tol 115 | [derb,errestb,finaldelta] = derivest(@(alpha1)GIGmoment(alpha1,lambda,chi,psi),alpha,'Style','backward'); 116 | end 117 | if errest>tol 118 | if errestbtol 125 | [derU,errestU,finaldeltaU] = derivest(@(alpha1)GIGmoment(alpha1,lambda,chi,psi),alpha+0.1); 126 | [derL,errestL,finaldeltaL] = derivest(@(alpha1)GIGmoment(alpha1,lambda,chi,psi),alpha-0.1); 127 | derUL=(derU+derL)./2; 128 | if sum(abs(derUL-der)>0.001)>0 129 | breakpoint=1; 130 | end 131 | end 132 | EXalphaprime(1)=der; 133 | EXalphaprime(2)=errest; 134 | EXalphaprime(3)=finaldelta; 135 | 136 | end 137 | 138 | function[logK] = mylogbesselkApprox(v,z) 139 | if abs(z) < 1e-24 && abs(v) < 1e-24 140 | logK = log(-log(abs(z))); %see eq. 9.5 in Paolella (2007) 141 | elseif abs(z) < 1e-24 && abs(v) >= 1e-24 142 | logK = log(gamma(v)) + (abs(v)-1) * log(2) + ( -abs(v) ) * log(abs(z)) ; %see eq. 9.6 in Paolella (2007) 143 | else 144 | logK=log(quickbesselk(v,z)); 145 | if (~isreal(logK) || sum(isnan(logK))>0 || sum(isinf(logK))>0 ), %try Watson expansion 146 | logK=0.5*log(pi)-0.5*log(2*z)-z + log(Evz(v,z,[],[])); 147 | end 148 | end 149 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/GammaEstimatorFREECOMFORT.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/GammaEstimatorFREECOMFORT.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/GaussianCCModel.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/GaussianCCModel.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/Gpdf.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/Gpdf.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/GstepARp.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/GstepARp.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/GstepEstimator.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/GstepEstimator.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/GstepMomentsToParams.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/GstepMomentsToParams.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/IIDGstep.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/IIDGstep.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/IIDmugam.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/IIDmugam.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/LookUpTableGARCH.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/LookUpTableGARCH.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/LookUpTableGIG.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/LookUpTableGIG.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/LowerLevelParametersAndPrint.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/LowerLevelParametersAndPrint.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/MARCMARSfilename.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/MARCMARSfilename.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/MNIGpdf.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/MNIGpdf.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/MVSLpdf.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/MVSLpdf.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/MVStpdf.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/MVStpdf.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/Mstep.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/Mstep.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/MstepFREE.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/MstepFREE.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/PLaplaceEM.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/PLaplaceEM.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/RU_COMFORT.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/RU_COMFORT.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/SkewnessInit.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/SkewnessInit.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/SymPDcorrmatrix.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/SymPDcorrmatrix.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/SymPDcovmatrix.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/SymPDcovmatrix.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/VCengine.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/VCengine.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/_GIGmoment.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/_GIGmoment.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/_RunCOMFORT.m: -------------------------------------------------------------------------------- 1 | function []=RunCOMFORT() 2 | %Program to run the COMFORT estimation 3 | 4 | % Y_t = mu + gamma * G_t + sqrt(G_t) * H_t^1/2 * Z_t 5 | % (G_t | Y_1,...,Y_{t-1}) ~ GIG(lambda, chi, psi) (IID) 6 | % Z_t ~ N(0,I_K) 7 | % H_t = S_t * Gamma_t * S_t 8 | % S_t=diag(s_{t,1},...,s_{t,K}); s_{t,k} ~ GARCH-type 9 | tic 10 | 11 | 12 | N=30; % number of assets 13 | winsize = 1000; %size of the rolling window try DCC-GARCH with 1000 window size too 14 | 15 | type = setType(N,winsize); 16 | disp([' WINDOW SIZE = ',num2str(winsize),'; NUMBER OF ASSETS = ',num2str(N),';']) 17 | 18 | 19 | %%%%%%%%%%%%%%%%%%%%%%%%%%FILE NAME%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20 | name=MARCMARSfilename(type); 21 | temp=clock; 22 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 23 | disp(['%MODEL : ',name]) 24 | disp(['%DATE : ',num2str(temp(3)),'/',num2str(temp(2)),'/',num2str(temp(1)),' ',num2str(temp(4)),':',num2str(temp(5))]) 25 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') 26 | 27 | %%%%%%%%%%%%%%%%%%%%%%%%%%DATA%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | load('DJ30_1990_2016_companies_with_complete_price_data_LOGRETMAT_CORRECTED.mat') 29 | mdata=100.*LOGRETMAT(:, 2:end); 30 | 31 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%RUN ESTIMATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 32 | if 1==1 33 | [COMFORTportfolio, GARCH, GIG, CC, COMFORTparams, name] = COMFORT_All(mdata, winsize,[],[],type) 34 | % save COMFORTestimates 35 | end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/ab2CD.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/ab2CD.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/atau2tau.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/atau2tau.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/b1opt.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/b1opt.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/b2opt.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/b2opt.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/besselk_ln.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/besselk_ln.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/besselk_ratio.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/besselk_ratio.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/besselk_watson_ln.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/besselk_watson_ln.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/besselkb.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/besselkb.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/bfilter.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/bfilter.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/brange.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/brange.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/cDCCengine.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/cDCCengine.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/cDCCestimate.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/cDCCestimate.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/calcPredictedCov.m: -------------------------------------------------------------------------------- 1 | function [predictedCov] = calcPredictedCov(COMFORTparams) 2 | % Based on paper: 3 | % COMFORT: A common market factor non-Gaussian returns model 4 | % Paolella, Polak (2015) 5 | % Journal of Econometrics 6 | 7 | lambda = COMFORTparams.GIGparNext(1); 8 | chi = COMFORTparams.GIGparNext(2); 9 | psi = COMFORTparams.GIGparNext(3); 10 | gamma = COMFORTparams.gam; 11 | 12 | % Equation (43): E[G] (alpha=1) 13 | [E_G] = GIGmoment(1, lambda, chi, psi); 14 | 15 | % Equation (43): E[G^2] (alpha=2) 16 | [E_G2] = GIGmoment(2, lambda, chi, psi); 17 | 18 | % Var(G) = E[G^2] - (E[G])^2 19 | Var_G = E_G2 - E_G^2; 20 | 21 | % Equation (10): Cov[Y] = E[G]*H + Var(G)*(gamma*gamma') 22 | predictedCov = E_G * COMFORTparams.Hnext + Var_G * (gamma * gamma'); 23 | end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/cexp.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/cexp.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/clog.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/clog.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/cval.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/cval.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/cvarlimghyp.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/cvarlimghyp.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/doitGpdf.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/doitGpdf.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/doitGstepEstimator.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/doitGstepEstimator.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/einschrk.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/einschrk.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/f_ru.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/f_ru.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/f_ru2.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/f_ru2.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/f_var.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/f_var.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/f_variance.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/f_variance.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/f_variance_constraints.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/f_variance_constraints.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/fact.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/fact.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/ghyppdf.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/ghyppdf.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/initGARCH.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/initGARCH.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/initparams.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/initparams.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/klambda.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/klambda.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/like2005.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/like2005.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/likeCM2step_COMFORT_IID.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/likeCM2step_COMFORT_IID.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/likeGstep.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/likeGstep.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/likeGstepARp.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/likeGstepARp.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/likeMALap.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/likeMALap.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/likeNIG.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/likeNIG.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/likeStud_t.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/likeStud_t.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/loglikDCC.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/loglikDCC.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/loglikVC.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/loglikVC.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/loglikcDCC.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/loglikcDCC.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/loglikweights.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/loglikweights.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/logpdf.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/logpdf.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/logpdf2.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/logpdf2.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/logpdf3.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/logpdf3.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/meanvariance01.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/meanvariance01.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/minvariance01.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/minvariance01.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/my_num2str.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/my_num2str.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/mylogbesselkApprox.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/mylogbesselkApprox.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/myvech.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/myvech.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/netreturnsPatrick.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/netreturnsPatrick.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/netreturns_Marc.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/netreturns_Marc.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/newGstep.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/newGstep.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/normalGARCHPL.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/normalGARCHPL.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/quickbesselk.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/quickbesselk.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/setType.m: -------------------------------------------------------------------------------- 1 | function [type] = setType(Nassets,winsize) 2 | % function which sets the type variable. The type variable controls which 3 | % COMFORT model is estimated: 4 | %type.model. 5 | %.Corrmodel = {'CCC', 'Clust', '1stepRSDC', '2stepRSDC', 'VC', 'DCC','cDCC'}... old not checked: {'newDCCcorrY','newDCC_G_gamma_gamma','newDCCmds','newDCCcorrYdiff','newDCCFisherMDS'} 6 | %.distribution = {'MGHyp', 'MALap', 'MLap', 'Normal', 'NIGPsi1', 'SNIGPsi1', 'Stud_t', 'SStud_t', 'NCT'} MLap or S-prefix is for the symmetric version of the distribution (elliptical model) 7 | %.GARCHtype = {'GARCH', 'A-PARCH','GJR'} 8 | %.mixGARCH_SV = {1,0} 9 | %.SV_ARp = {1,2,3,4,5} if .mixGARCH_SV==1 then .SV_ARp is the AR(p) of SV. 10 | %.FREECOMFORT={0,1} % FREE-COMFORT stands for Fast Reduced Estimation 11 | % COMFORT with all the GARCHes dynamics with the same parameters (see FREECOMFORTestimation function below for the detail descrpition in the comments). 12 | % .FREECOMFORT = 0 the regular comfort 13 | % .FREECOMFORT = 1 the free-comfort 14 | 15 | 16 | % estimation using ECME method or an adhoc three step approach 17 | %.estimation = {'EM','3step'} 18 | % starting values for the estimation: last window estimates (use in a 19 | % rolling window exercise, or adhoc three step estimates). 20 | %.startingvalue = {'lastEstimate','3step'} 21 | 22 | 23 | type.model.FREECOMFORT=0; % FREE-COMFORT model vs COMFORT model 24 | type.model.IID=0; % conditional dynamics or IID (1 for IID model) 25 | type.model.estimation='EM'; % 'EM' or '3step' ('3step' works only for COMFORT model) 26 | type.model.mixGARCH_SV =0; % 1 mixGARCH-SV vs. 0 iid G model (FREE-COMFORT works only with mixGARCH_SV=0; 27 | type.model.distribution = 'MALap'; % 'MALap', 'NIGPsi1', 'Stud_t', 'MLap', 'SNIGPsi1', 'SStud_t' 28 | type.model.Corrmodel = 'DCC'; %(FREE-COMFORT works with CCC only); COMFORT: 'CCC', 'DCC', 'cDCC', 'VC' 29 | type.model.GARCHtype = 'GARCH'; %'GARCH' 'GJR' 30 | type.model.for=0; % boolean variable to use or not for loops in the code. 31 | 32 | 33 | 34 | [type] = LowerLevelParametersAndPrint(type,Nassets,winsize); 35 | end 36 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/setseed.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/setseed.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/tsplot.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/tsplot.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/lib/ungarch.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/COMFORT-DCC/lib/ungarch.p -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/main.m: -------------------------------------------------------------------------------- 1 | fprintf(2, 'MAIN> Started at %s \n', datestr(datetime(), 'dd.mm.yyyy HH:MM:ss')); 2 | 3 | if ~exist('workerId', 'var') 4 | error('Input variable `workerId` not defined.'); 5 | end 6 | 7 | fprintf(2, 'MAIN> Worker-ID: %s \n', workerId); 8 | 9 | if exist('isShellMode', 'var') 10 | fprintf(2, 'MAIN> Starting program in Shell mode... \n'); 11 | 12 | % load stock excess returns data 13 | returns = readtable('sp500_stock_ex_returns_demeaned_scaled.csv', 'ReadVariableNames',true); 14 | fprintf(2, 'MAIN> Returns data file read. \n'); 15 | else 16 | fprintf(2, 'MAIN> Starting program in IDE mode... \n'); 17 | 18 | % load stock excess returns data 19 | returns = readtable('../../../0 data/CRSP/sp500_stock_ex_returns_demeaned_scaled.csv', 'ReadVariableNames',true); 20 | fprintf(2, 'MAIN> Returns data file read. \n'); 21 | end 22 | 23 | % import COMFORT codes 24 | addpath(genpath('lib')); 25 | 26 | % estimation range 27 | windowSize = 1000; 28 | from = find(returns.date == '1996-01-02'); 29 | to = find(returns.date == '2013-12-31'); 30 | steps = to - from + 1; 31 | memoryless = true; 32 | 33 | % extract data 34 | range = (from - windowSize + 1):to; 35 | dates = returns{range, 'date'}; 36 | marketData = returns{range, 'market'}; 37 | stocksData = returns(range, 3:size(returns, 2)); 38 | dateFrom = returns{from, 'date'}; 39 | dateTo = returns{to, 'date'}; 40 | 41 | % free memory 42 | clear returns; 43 | 44 | % get stocks assigned to this worker 45 | worklist = readtable('worklist.csv', 'Delimiter', ';'); 46 | worklist = worklist(strcmp(worklist.Var2, workerId), 'Var1'); 47 | 48 | % estimate covariance of stock and market 49 | for row=1:size(worklist, 1) 50 | sStart = tic; 51 | 52 | % returns series of stock 53 | stockName = strcat('x', int2str(worklist{row, 1})); 54 | stockIdx = find(strcmp(stockName, stocksData.Properties.VariableNames')); 55 | stockData = stocksData{:, stockIdx}; 56 | 57 | % find ranges of non NaN values 58 | [ranges] = runRanges(~isnan(stockData'), true); 59 | 60 | % estimate covariance of every run range of stock 61 | noRanges = size(ranges, 1); 62 | for i=1:noRanges 63 | fprintf(2, 'MAIN> Estimating stock %s range %i/%i... \n', stockName, i, noRanges); 64 | 65 | % range of non NaN values 66 | from = ranges(i, 1); 67 | to = ranges(i, 2); 68 | rangeValues = from:to; 69 | 70 | if length(rangeValues) < windowSize 71 | fprintf(2, 'MAIN> Range %i to %i skipped (smaller than window size %i) \n', from, to, windowSize); 72 | continue; 73 | end 74 | 75 | % create output file to block other workers of calculating the same range 76 | outfile = sprintf('out/covs_%s_%s_%s_range_%i_%i.csv', stockName, dateFrom, dateTo, from, to); 77 | 78 | if exist(outfile, 'file') == 2 79 | fprintf(2, 'MAIN> Range %i to %i skipped (output file exists already) \n', from, to); 80 | continue; 81 | end 82 | 83 | % create empty output file 84 | fclose(fopen(outfile, 'w')); 85 | 86 | fprintf(2, 'MAIN> Output file `%s` created. \n', outfile); 87 | fprintf(2, 'MAIN> Range %i to %i \n', from, to); 88 | 89 | % create [Tx2] matrix with market and stock returns for bivariate estimation 90 | COMFORTdata = [marketData(rangeValues, :) stockData(rangeValues, :)]; 91 | 92 | % estimate bivariate COMFORT model 93 | Nassets = size(COMFORTdata, 2); 94 | COMFORTtype = setType(Nassets, windowSize); 95 | [GARCH, GIG, CC, COMFORTparams] = COMFORTestimation(windowSize, COMFORTdata, COMFORTtype, [], memoryless); 96 | 97 | predictedCovs = cellfun(@(x) calcPredictedCov(x), COMFORTparams, 'UniformOutput', false); 98 | 99 | wndDates = dates(from + windowSize - 1:to); 100 | wndVarMarket = cellfun(@(x) x(1,1), predictedCovs); 101 | wndVarStock = cellfun(@(x) x(2,2), predictedCovs); 102 | wndCovStock = cellfun(@(x) x(1,2), predictedCovs); 103 | 104 | % write to CSV file 105 | outputTbl = table(wndDates, wndVarMarket, wndVarStock, wndCovStock); 106 | outputTbl.Properties.VariableNames = { 'date' 'var_market' 'var_stock' 'cov' }; 107 | writetable(outputTbl, outfile, 'Delimiter', ';'); 108 | end 109 | 110 | sEnd = toc(sStart); 111 | sEndStr = datestr(datenum(0,0,0,0,0,sEnd), 'HH:MM:SS'); 112 | 113 | fprintf(2, 'MAIN> Stock %s estimated in %s \n', stockName, sEndStr); 114 | fprintf(2, 'MAIN> ----------------------------------------- \n'); 115 | end 116 | 117 | fprintf(2, 'MAIN> Finished at %s \n', datestr(datetime(), 'dd.mm.yyyy HH:MM:ss')); 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/runRanges.m: -------------------------------------------------------------------------------- 1 | % Returns a [Tx2] matrix with run ranges, whereas 2 | % every row consists of the start and end indices. 3 | % The passed runs vector needs to consist of 0s and 1s. 4 | function [ranges] = runRanges(runs, ignoreZeroes) 5 | 6 | changes = diff(runs) ~= 0; 7 | 8 | starts = [1 find(changes)+1]; 9 | ends = [find(changes) length(runs)]; 10 | 11 | ranges = [starts; ends]'; 12 | 13 | % remove ranges of zero runs 14 | if ignoreZeroes 15 | if runs(1) == 0 16 | ranges(1:2:end, :) = []; 17 | else 18 | ranges(2:2:end, :) = []; 19 | end 20 | end 21 | 22 | end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/runRanges_tests.m: -------------------------------------------------------------------------------- 1 | disp('----------- testAllRuns -------------'); 2 | 3 | testAllRuns(isnan([NaN NaN NaN])); 4 | testAllRuns(isnan([1 2 3])); 5 | testAllRuns(isnan([NaN 1 2 3])); 6 | testAllRuns(isnan([NaN NaN 1 2 3])); 7 | testAllRuns(isnan([NaN 1 2 3 NaN])); 8 | testAllRuns(isnan([NaN NaN 1 2 3 NaN NaN])); 9 | testAllRuns(isnan([1 2 3 NaN NaN NaN 1 2 3])); 10 | 11 | disp('----------- testOneRuns -------------'); 12 | 13 | testOneRuns(isnan([NaN NaN NaN])); 14 | testOneRuns(isnan([1 2 3])); 15 | testOneRuns(isnan([NaN 1 2 3])); 16 | testOneRuns(isnan([NaN NaN 1 2 3])); 17 | testOneRuns(isnan([NaN 1 2 3 NaN])); 18 | testOneRuns(isnan([NaN NaN 1 2 3 NaN NaN])); 19 | testOneRuns(isnan([1 2 3 NaN NaN NaN 1 2 3])); 20 | 21 | 22 | function testAllRuns(vec) 23 | [ranges] = runRanges(vec, false); 24 | disp(vec); 25 | disp(ranges); 26 | disp('------------------------'); 27 | end 28 | 29 | function testOneRuns(vec) 30 | [ranges] = runRanges(vec, true); 31 | disp(vec); 32 | disp(ranges); 33 | disp('------------------------'); 34 | end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/run_euler.sh: -------------------------------------------------------------------------------- 1 | for i in {1..47}; 2 | do 3 | matlab -nosplash -nojvm -nosoftwareopengl -nodesktop -singleCompThread -logfile "logs/main_$i.log" -r "isShellMode=true; shellID=$i; workerId='EULER'; try, main; end, quit" & 4 | done -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/run_pc.sh: -------------------------------------------------------------------------------- 1 | for i in {1..10}; 2 | do 3 | matlab -nosplash -nojvm -nosoftwareopengl -nodesktop -singleCompThread -logfile "logs/main_$i.log" -r "isShellMode=true; shellID=$i; workerId='PC'; try, main; end, quit" & 4 | done -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/splitIntoIntervals.m: -------------------------------------------------------------------------------- 1 | function [intervals] = splitIntoIntervals(from, toInc, intervalSize) 2 | 3 | numberOfIntervals = ceil((toInc - from + 1) / intervalSize); 4 | intervals = NaN(numberOfIntervals, 2); 5 | 6 | for i=1:numberOfIntervals 7 | intervals(i, 1) = from + (i - 1) * intervalSize; 8 | intervals(i, 2) = min(from + i * intervalSize - 1, toInc); 9 | end 10 | 11 | end 12 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/splitIntoIntervals_tests.m: -------------------------------------------------------------------------------- 1 | splitIntoIntervals(0, 10, 5) 2 | splitIntoIntervals(1, 10, 5) 3 | splitIntoIntervals(0, 9, 5) 4 | splitIntoIntervals(1, 9, 5) -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/submit_120.sh: -------------------------------------------------------------------------------- 1 | bsub -R "rusage[mem=2048]" -n 48 -W 120:00 "module load new matlab/9.3 && mkdir -p logs && mkdir -p out && ./run_euler.sh" -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/COMFORT-DCC/submit_24.sh: -------------------------------------------------------------------------------- 1 | bsub -R "rusage[mem=2048]" -n 48 -W 24:00 "module load new matlab/9.3 && mkdir -p logs && mkdir -p out && ./run_euler.sh" -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/consolidate.R: -------------------------------------------------------------------------------- 1 | library(data.table) 2 | 3 | source('../../../functions.R') 4 | 5 | consolidated.path <- './consolidated' 6 | out.path <- './out' 7 | returns.path <- '../../../0 data/CRSP/sp500_stock_ex_returns.csv' 8 | 9 | 10 | path.out.make <- function(date, file) { 11 | paste0(out.path, '/', date, '/', file) 12 | } 13 | 14 | path.consolidated.make <- function(file) { 15 | paste0(consolidated.path, '/', file) 16 | } 17 | 18 | 19 | # load excess returns data 20 | returns <- fread(returns.path, header=T, sep=';') 21 | head(returns[, 1:20], n=3) 22 | 23 | 24 | # extract all computed dates 25 | dates.all <- list.dirs(path=out.path, full.names=F, recursive=F) 26 | dates <- Filter(function(x) nchar(x) == 10, dates.all) # ignore pending entries 27 | dates <- sort(dates) 28 | 29 | 30 | # read files of interest 31 | stocks.cols <- colnames(returns)[-c(1:2)] 32 | 33 | covs.estimated <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), stocks.cols)) 34 | covs.1stepahead <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), stocks.cols)) 35 | 36 | vars.estimated.market <- matrix(NA, nrow=length(dates), ncol=1, dimnames=list(c(), c('median'))) 37 | vars.1stepahead.market <- matrix(NA, nrow=length(dates), ncol=1, dimnames=list(c(), c('median'))) 38 | 39 | for (i in 1:length(dates)) { 40 | date <- dates[i] 41 | 42 | 43 | # covariances 44 | tmp.covs.stocks <- first.col.2.rownames(fread(path.out.make(date, 'covs.stocks.csv'), header=T, sep=';', data.table=F)) 45 | tmp.covs.cols <- gsub('x', '', colnames(tmp.covs.stocks)) 46 | 47 | # covs.estimated 48 | covs.estimated[i, tmp.covs.cols] <- unlist(tmp.covs.stocks['estimated', ]) 49 | 50 | # covs.1stepahead 51 | covs.1stepahead[i, tmp.covs.cols] <- unlist(tmp.covs.stocks['1stepahead', ]) 52 | 53 | 54 | # variances 55 | tmp.vars.market <- first.col.2.rownames(fread(path.out.make(date, 'vars.market.csv'), header=T, sep=';', data.table=F)) 56 | 57 | # vars.estimated 58 | vars.estimated.market[i, 'median'] <- median(unlist(tmp.vars.market['estimated', ]), na.rm=T) 59 | 60 | # vars.1stepahead 61 | vars.1stepahead.market[i, 'median'] <- median(unlist(tmp.vars.market['1stepahead', ]), na.rm=T) 62 | 63 | 64 | # log progress 65 | if (i %% 50 == 0) 66 | cat(date, format(round(100.0 * i / length(dates), 1), nsmall=1), '% \n') 67 | } 68 | 69 | 70 | # add date as first column 71 | covs.estimated <- cbind(data.table(date=dates), covs.estimated) 72 | covs.1stepahead <- cbind(data.table(date=dates), covs.1stepahead) 73 | vars.estimated.market <- cbind(data.table(date=dates), vars.estimated.market) 74 | vars.1stepahead.market <- cbind(data.table(date=dates), vars.1stepahead.market) 75 | 76 | 77 | 78 | # write consolidated data to disk 79 | if (!dir.exists(consolidated.path)) 80 | dir.create(consolidated.path) 81 | 82 | # covs.estimated.csv 83 | fwrite(covs.estimated, path.consolidated.make('covs.estimated.csv'), sep=';') 84 | 85 | # covs.1stepahead.csv 86 | fwrite(covs.1stepahead, path.consolidated.make('covs.1stepahead.csv'), sep=';') 87 | 88 | # vars.estimated.market.csv 89 | fwrite(vars.estimated.market, path.consolidated.make('vars.estimated.market.csv'), sep=';') 90 | 91 | # vars.1stepahead.market.csv 92 | fwrite(vars.1stepahead.market, path.consolidated.make('vars.1stepahead.market.csv'), sep=';') 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/copy_from_euler.sh: -------------------------------------------------------------------------------- 1 | scp -pr kpetrova@euler.ethz.ch:/cluster/home/kpetrova/thesis/DCC1step_1000/out.zip out.zip 2 | 3 | pause -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/copy_to_euler.sh: -------------------------------------------------------------------------------- 1 | scp -r main.m submit_24.sh submit_120.sh run_euler.sh zip.sh lib "../../../0 data/CRSP/sp500_stock_ex_returns_demeaned_scaled.csv" "kpetrova@euler.ethz.ch:/cluster/home/kpetrova/thesis/DCC1step_1000/" 2 | 3 | pause -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/lib/CD2ab.m: -------------------------------------------------------------------------------- 1 | function [ab,Vout] = CD2ab(CD,Vin) 2 | %a=C*D;b=D-CD so 02 || n2>2, warning('CD2ab programmed wrong'), end 5 | ab(1) = CD(1).*CD(2); ab(2) = CD(2)-CD(1).*CD(2); 6 | if nargout>1 % now adjust the standard errors 7 | J=[CD(2), CD(1); -CD(2), (1-CD(1))]; Vout=J * Vin *J; 8 | end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/lib/DCC1step.m: -------------------------------------------------------------------------------- 1 | function [mu, Sigma] = DCC1step(data, profile) 2 | % INPUT: data is a T X d matrix of asset log returns 3 | % Output: 4 | % mu: the mean of returns, 1 x d vector 5 | % sigma: one step ahead prediction of the asset covariance matrix 6 | % computed using the Gaussian DCC-GARCH model 7 | 8 | %profile = 10; 9 | [T,d] = size(data); 10 | 11 | mu = mean(data); 12 | data_demean = data - repmat(mu,T,1); 13 | garchP = zeros(3,d); 14 | sigmamat = zeros(T,d); 15 | GARCHresid = zeros(T,d); 16 | 17 | for n = 1:d 18 | garchP(:,n) = normalGARCHPL(data_demean(:,n),[],profile); 19 | [GARCHresid(:,n),sigmamat(:,n)] = ungarch(data_demean(:,n), garchP(:,n)); 20 | end 21 | 22 | %DCC: Q_t=S*(1-a-b)+a*eps_{t-1}eps'_{t-1} +b*Q_{t-1} 23 | initvec = []; 24 | S = []; 25 | Gamma0 = []; 26 | [a,b,Smat,~,Gamma0] = DCCestimate(GARCHresid,initvec,S,Gamma0); 27 | Rmat = zeros(d,d,T); 28 | S = Smat; 29 | Q = Gamma0; 30 | 31 | for t=1:T 32 | if t>1 33 | Q = DCCengine(GARCHresid(t-1,:),a,b,S,Q); 34 | Corrmat = diag(sqrt(diag(Q)).^(-1))*Q*diag(sqrt(diag(Q)).^(-1)); 35 | Corrmat = SymPDcorrmatrix(Corrmat); 36 | else 37 | Corrmat = S; Q=S; Corrmat=SymPDcorrmatrix(Corrmat); 38 | end 39 | 40 | Rmat(:,:,t)=Corrmat; 41 | end 42 | 43 | Q_f = (1-a-b)*Rmat(:,:,1)+a*GARCHresid(end,:)'*GARCHresid(end,:)+b*Rmat(:,:,end); 44 | R_f = diag(diag(Q_f).^(-0.5))*Q_f*diag(diag(Q_f).^(-0.5)); 45 | H_f = diag(sigmamat(end,:))*Rmat(:,:,end)*diag(sigmamat(end,:)); 46 | 47 | % Recombine GARCH11 and Correlation matrix forecast 48 | D_f = diag(sqrt(garchP(1,:)+garchP(2,:).*GARCHresid(end,:).^2+garchP(3,:).*diag(H_f)')); 49 | Sigma = D_f * R_f * D_f; 50 | Sigma = SymPDcovmatrix(Sigma); 51 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/lib/DCCengine.m: -------------------------------------------------------------------------------- 1 | function Q=DCCengine(resid_t,a,b,S,Qin) 2 | Mmat = resid_t'*resid_t; Mmat=SymPDcovmatrix(Mmat); 3 | Q=(1-a-b) * S + a * Mmat + b * Qin; 4 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/lib/DCCestimate.m: -------------------------------------------------------------------------------- 1 | function [a,b,Smat,ll,Gamma0] = DCCestimate(resid,initvec,S,Gamma0) 2 | 3 | % C D 4 | bound.lo = [0.001 0 ]; 5 | bound.hi = [1-(1e-04) 1-(1e-04) ]; 6 | bound.which = [1 1 ]; 7 | 8 | if isempty(initvec), initvec=[0.05 0.93]; end 9 | if isempty(S), S=corr(resid); end 10 | 11 | S = SymPDcorrmatrix(S); 12 | 13 | if isempty(Gamma0), Gamma0=S; end 14 | 15 | Gamma0 = SymPDcorrmatrix(Gamma0); 16 | 17 | opt = optimset('Display', 'off', 'TolFun', 1e-6, 'TolX', 1e-6, 'MaxFunEvals', 5000, 'LargeScale', 'Off'); 18 | [pout,~] = fminunc(@(param) loglikDCC(param,resid,S,Gamma0,bound), einschrk(ab2CD(initvec), bound), opt); 19 | 20 | param = CD2ab(einschrk(real(pout), bound, 1)); 21 | a = param(1); 22 | b = param(2); 23 | Smat = S; 24 | 25 | ll = -1 * loglikDCC(ab2CD(param), resid, S, Gamma0, []); 26 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/lib/SymPDcorrmatrix.m: -------------------------------------------------------------------------------- 1 | function A=SymPDcorrmatrix(A,tol) 2 | [n,m]=size(A); 3 | if ~(n==m), error('Input matrix has to be a square matrix '), end 4 | if nargin<2, tol=1e-04; end 5 | if sum(any(abs((A)-eye(n))>=1+(1e-02)))>0, warning('This is not a correlation matrix'); end 6 | numCol = find( any( abs((A)-eye(n)) >= ( 1-(1e-16) ) ) ); 7 | numRow = find( any( abs((A)-eye(n))' >= ( 1-(1e-16) ) ) ); 8 | if ~isempty(numCol) || ~isempty(numRow) 9 | A(numRow,numCol) = sign(A(numRow,numCol)) * ( 1-(1e-16) ); 10 | % the off-diagonal entries in (-1 1) 11 | warning('Some of the correlations were corrected'); 12 | end 13 | A = A - diag(diag(A)) + eye(n,m); % ones on the diagonal 14 | A = ( A + A' )/2; % symmetric matrix 15 | [V,D] = eig(A); seig = diag(D); bad = find(seig < tol); % PD 16 | if ~isempty(bad), seig(bad) = tol; D = diag(seig); A = V * D * V';end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/lib/SymPDcovmatrix.m: -------------------------------------------------------------------------------- 1 | function A=SymPDcovmatrix(A,tol) 2 | [n,m]=size(A); 3 | if ~(n==m), error('Input matrix has to be a square matrix '), end 4 | if nargin<2, tol=1e-04; end 5 | A=(A+A')/2; 6 | try 7 | [V,D]=eig(A); seig=diag(D); bad=find(seig 9 | %bp=1; 10 | end 11 | if ~isempty(bad), seig(bad)=tol; D=diag(seig); A=V*D*V';end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/lib/ab2CD.m: -------------------------------------------------------------------------------- 1 | function [CD, Vout] =ab2CD(ab,Vin) 2 | %C=a/(a+b);D=a+b so 02 || n2>2, warning('ab2CD programed wrong'), end %#ok<*WNTAG> 5 | CD(1) = ab(1) ./ (ab(1) + ab(2)); CD(2) = ab(1) + ab(2); 6 | if nargout>1 % now adjust the standard errors 7 | J=[1./(ab(1) + ab(2)) - ab(1)./(ab(1) + ab(2)).^2, -ab(1)/(ab(1) + ab(2)).^2 ; 1,1]; 8 | Vout=J * Vin * J; 9 | end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/lib/einschrk.m: -------------------------------------------------------------------------------- 1 | function [pout,Vout]=einschrk(pin,bound,Vin) 2 | % [pout,Vout]=einschrk(pin,bound,Vin) 3 | % if Vin specified, then pout is untransformed, otherwise pout is transformed 4 | % M. Paolella, 1997 5 | 6 | welche=bound.which; 7 | if all(welche==0) % no bounds! 8 | pout=pin; 9 | if nargin==3, Vout=Vin; end 10 | return 11 | end 12 | 13 | lo=bound.lo; hi=bound.hi; 14 | if nargin < 3 15 | trans=sqrt((hi-pin) ./ (pin-lo)); 16 | pout=(1-welche).* pin + welche .* trans; 17 | Vout=[]; 18 | else 19 | trans=(hi+lo.*pin.^2) ./ (1+pin.^2); 20 | pout=(1-welche).* pin + welche .* trans; 21 | % now adjust the standard errors 22 | trans=2*pin.*(lo-hi) ./ (1+pin.^2).^2; 23 | d=(1-welche) + welche .* trans; % either unity or delta method. 24 | J=diag(d); 25 | Vout = J * Vin * J; 26 | end 27 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/lib/loglikDCC.m: -------------------------------------------------------------------------------- 1 | function loglik=loglikDCC(param,resid,S,Q,bound) 2 | 3 | if ~isempty(bound), param=einschrk(real(param),bound,999); end 4 | 5 | a = param(1) * param(2); 6 | b = param(2) - param(1) * param(2); 7 | 8 | [T,d] = size(resid); ll=zeros(T,1); 9 | for t=1:T 10 | if t>1 11 | Q = DCCengine(resid(t-1,:),a,b,S,Q); 12 | Corrmat = diag(sqrt(diag(Q)).^(-1))*Q*diag(sqrt(diag(Q)).^(-1)); 13 | Corrmat = SymPDcorrmatrix(Corrmat); 14 | else 15 | Corrmat=S; Q=S; Corrmat=SymPDcorrmatrix(Corrmat); 16 | end 17 | 18 | detGamma=det(Corrmat); Gammainv=Corrmat\eye(d); 19 | ll(t) = - 0.5 *(log(abs(detGamma)) + resid(t,:) * Gammainv * resid(t,:)'); 20 | end 21 | loglik= - sum(ll); -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/lib/normalGARCHPL.m: -------------------------------------------------------------------------------- 1 | function [param,stderr,loglik,resmat]=normalGARCHPL(ret,initvec,profile,B) 2 | % normal-GARCH(1,1) estimation of a mean-zero process 3 | % INPUT 4 | % ret is the T X 1 zero-mean time series. 5 | % or T X d matrix of returns. If d>1, the log liks are pooled! 6 | % This could be used as a shrinkage target. 7 | % 8 | % initvec is starting values of the 3 GARCH parameters, 9 | % pass [] to use default. 10 | % 11 | % Call with profile = 0 (default) for usual normal GARCH estimation. 12 | % Call with profile>=1 to do profile likelihood in c_0, with 13 | % the size of the grid for c_0 equal to *profile* parameter. 14 | % Then, loglik is a vector, and resmat a matrix of the 3 GARCH coef 15 | % 16 | % B is number of bootstrap replications to determine the std error 17 | % of the parameters. Pass B=0 (default) to use approximation from Hessian. 18 | % Current set up: Only use if d=1 and profile>0 19 | % 20 | % To set the exponent of the GARCH equation, manually do so below 21 | % via parameter delta. Default is 2. 22 | % 23 | % Example. If ret is the vector of percentage log returns, use: 24 | % [param,stderr,loglik,resmat] = normalGARCHPL(ret,[],10); 25 | % param, stderr 26 | % % optionally can look at: [loglik,resmat] 27 | % Use [param,stderr,loglik,resmat] = normalGARCHPL(ret,[],10,200); 28 | % to get better std errors via the (parametric) bootstrap. 29 | global y bound delta; 30 | delta=2; y=ret; [T,d]=size(y); 31 | if nargin<4 || isempty(B), B=0; end 32 | if d==1, B=0; end % could easily relax this later... 33 | UseBootstrap=B>0; 34 | if nargin<2, initvec=[]; end 35 | if or(nargin<3,isempty(profile)), profile=0; end 36 | fmintol=1e-5; maxit=200; 37 | opt = optimset('LargeScale','off','display','off', 'Maxiter',... 38 | maxit,'TolFun',fmintol,'TolX',fmintol); 39 | if profile>0 40 | if isempty(initvec), initvec=[0.02 0.9]; end 41 | lb=1e-5; ub=1-lb; 42 | % c_1 d_1 43 | bound.lo= [lb 0 ]; 44 | bound.hi= [ub ub ]; 45 | bound.which= [1 1 ]; 46 | clen=profile; % 100 is what I usually use 47 | resmat=zeros(clen,3); 48 | loglik=zeros(clen,1); best=-Inf; 49 | cvec=linspace(0,1.2*max(var(y)),clen); 50 | for i=1:clen 51 | c=cvec(i); 52 | [pout,fval]=fminunc(@(param) proflik(param,c),einschrk(initvec,bound),opt); 53 | hess=eye(length(pout)); V=pinv(hess)/(T*d); 54 | [parami,~]=einschrk(pout,bound,V); 55 | loglik(i)=-fval*(T*d); 56 | resmat(i,1)=c; resmat(i,2)=parami(1); resmat(i,3)=parami(2); 57 | if loglik(i)>best, best=loglik(i); param=[c parami]; end 58 | end 59 | thebestinitvec=param; 60 | [param,stderrHESS] = normalGARCHPL(y,thebestinitvec,0); 61 | if any(abs(imag(stderrHESS))>0), stderrHESS=NaN(1,3); end 62 | if nargout>1, stderr=stderrHESS; end 63 | if nargout>1 && UseBootstrap 64 | Pmat=NaN(B,3); qq=param(1:2); pp=param(3); 65 | for b=1:B 66 | YY=simg(T,qq,pp,delta); Pmat(b,:) = normalGARCHPL(YY,param,0); 67 | end 68 | stderr=std(Pmat); 69 | end 70 | else % no use of profile (and also not bootstrap) 71 | if nargout>=4, resmat=[]; end 72 | if isempty(initvec), initvec=[0.02 0.02 0.9]; end 73 | lb=1e-5; ub=1-lb; 74 | if initvec(1)<=lb; initvec(1)=0.001; end 75 | if initvec(2)<=lb; initvec(2)=0.001; end 76 | if initvec(2)>=ub; initvec(2)=0.99; end 77 | if initvec(3)<=lb; initvec(3)=0.001; end 78 | if initvec(3)>=ub; initvec(3)=0.99; end 79 | % c_0 c_1 d_1 80 | bound.lo= [lb lb 0 ]; 81 | bound.hi= [1.2*max(var(y)) ub ub ]; 82 | bound.which= [1 1 1 ]; 83 | [pout,fval,~,~,~,hess]=fminunc(@(param) like2005(param),einschrk(initvec,bound),opt); 84 | V=pinv(hess)/(T*d); [param,V]=einschrk(pout,bound,V); 85 | stderr=sqrt(diag(V))'; loglik=-fval*(T*d); 86 | end 87 | 88 | function loglik=proflik(param,c) 89 | global y bound zvec sigvec 90 | theparam = einschrk(real(param),bound,999); 91 | param=[c theparam]; d=size(y,2); partloglik=zeros(1,d); 92 | logK=log(sqrt(2*pi)); 93 | for i=1:d 94 | [zvec,sigvec]=ungarch(y(:,i),param); 95 | ll=-0.5*(zvec.^2)-logK-log(sigvec); partloglik(i)=-mean(ll); 96 | end 97 | loglik=mean(partloglik); 98 | 99 | function loglik=like2005(param) 100 | global y bound zvec sigvec 101 | param = einschrk(real(param),bound,999); 102 | d=size(y,2); partloglik=zeros(1,d); logK=log(sqrt(2*pi)); 103 | for i=1:d 104 | [zvec,sigvec]=ungarch(y(:,i),param); 105 | ll =-0.5*(zvec.^2)-logK-log(sigvec); partloglik(i)=-mean(ll); 106 | end 107 | loglik=mean(partloglik); 108 | 109 | function y=simg(nobs,qq,pp,delta) 110 | % Input 111 | % qq is the ARCH component, pp is GARCH part, i.e., 112 | % qq= [omega alpha]; pp = [beta] 113 | % delta is the exponent in the GARCH equation, default of 2. 114 | % Output y is a Gaussian garch(1,1) series 115 | if nargin<6, delta=2; end 116 | warm=500; use=nobs+warm; 117 | s = rng; rng('shuffle'); z=randn(use+1,1); % get the z vector 118 | rng(s); 119 | h=zeros(use+1,1); e=zeros(use+1,1); omega=qq(1); qv=qq(2); pv=pp; 120 | h(1)=omega; e(1)=h(1)*z(1); 121 | for i=2:use+1 122 | h(i)=omega+ qv*( abs(e(i-1)) )^delta + pv*h(i-1); 123 | e(i)=( (h(i))^(1/delta) ) * z(i); 124 | end 125 | e=e(2:end); y=e(warm+1:use); 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/lib/ungarch.m: -------------------------------------------------------------------------------- 1 | function [eout,sigvec]=ungarch(epsi,garchin) 2 | global delta 3 | int=garchin(1); qterms=garchin(2); pterms=garchin(3); 4 | e=(abs(epsi)).^delta; 5 | lambda=( ( 2^(delta/2) ) / sqrt(pi) ) * gamma((delta+1)/2); 6 | 7 | % sinit = E[sigvec_0^delta], einit = E|e_0^delta| = lambda * sinit. 8 | sinit=mean((abs(epsi)).^delta); einit=lambda*sinit; 9 | 10 | % do the recursion in sigvec^delta 11 | sigvec=zeros(length(e),1); sigvec(1)=int+qterms*einit+pterms*sinit; 12 | 13 | for i=2:length(e), sigvec(i)=int + qterms*e(i-1) + pterms*sigvec(i-1); end 14 | if any(sigvec<=0), error('hello'), end 15 | 16 | sigvec=sigvec.^(1/delta); 17 | eout=epsi./sigvec; 18 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/main.m: -------------------------------------------------------------------------------- 1 | rng shuffle 2 | 3 | addpath(genpath('lib')); % import DCC-GARCH estimation and prediction functions 4 | 5 | isEuler = false; 6 | 7 | % load returns data 8 | if (isfile('sp500_stock_ex_returns_demeaned_scaled.csv')) 9 | isEuler = true; 10 | returns = readtable('sp500_stock_ex_returns_demeaned_scaled.csv', 'ReadVariableNames',true); 11 | else 12 | returns = readtable('../../../0 data/CRSP/sp500_stock_ex_returns_demeaned_scaled.csv', 'ReadVariableNames',true); 13 | end 14 | 15 | % extract data 16 | dates = returns{:, 1}; 17 | marketData = returns{:, 2}; 18 | stockData = returns(:, 3:end); 19 | 20 | windowSize = 1000; 21 | subwindowSize = 1; 22 | 23 | if (isEuler) 24 | from = find(returns.date == '2003-12-26'); 25 | to = find(returns.date == '2013-12-31'); 26 | else 27 | from = find(returns.date == '1996-01-02'); 28 | to = find(returns.date == '2003-12-24'); 29 | end 30 | 31 | steps = to - from + 1; 32 | profile = 10; 33 | 34 | increments = from:to; 35 | for i=increments(randperm(length(increments))) 36 | tic; 37 | 38 | date = dates(i); 39 | 40 | fprintf('step %i of %i (%s) - ', i - from + 1, steps, date); 41 | 42 | % output directories 43 | outDir1 = sprintf('out/%s_pending', date); 44 | outDir2 = sprintf('out/%s', date); 45 | 46 | % delete _pending folder if it exists already 47 | if 7 == exist(outDir1, 'dir') 48 | rmdir(outDir1, 's'); 49 | end 50 | 51 | % skip if final output directory already exists 52 | if 7 == exist(outDir2, 'dir') 53 | % already computed - ignore this step 54 | fprintf('ignoring %s - already computed \n', date); 55 | 56 | if 7 == exist(outDir1, 'dir') 57 | rmdir(outDir1, 's'); 58 | end 59 | 60 | continue; 61 | end 62 | 63 | % create `pending` output directory 64 | [status,msg] = mkdir(outDir1); 65 | if status ~= 1 66 | fprintf('ERROR: Failed to create directory %s with message: %s \n', outDir1, msg); 67 | continue; 68 | end 69 | 70 | % extract window data 71 | windowStocksData = stockData((i - windowSize + 1):i, :); 72 | windowMarketData = marketData((i - windowSize + 1):i, :); 73 | 74 | % determine which columns have enough data (no NaNs) 75 | cols = arrayfun(@(x) x == size(windowStocksData, 1), sum(~isnan(windowStocksData{:,:}), 1)); 76 | 77 | % create matrix with columns which have no NaNs 78 | colIdxs = transpose(1:size(windowStocksData, 2)) .* transpose(cols); 79 | colIdxs = colIdxs(colIdxs > 0); 80 | windowStocksData = windowStocksData(:, colIdxs); 81 | stockCols = size(windowStocksData, 2); 82 | 83 | % fit DCC-GARCH in sub-samples 84 | fitSteps = ceil(stockCols / subwindowSize); 85 | 86 | varsMarket = array2table(nan(2, fitSteps), 'RowNames', cellstr({"estimated" "1stepahead"})); 87 | covsStocks = array2table(nan(2, stockCols), 'RowNames', cellstr({"estimated" "1stepahead"})); 88 | covsStocks.Properties.VariableNames = windowStocksData.Properties.VariableNames; 89 | 90 | for stepIdx = 1:fitSteps 91 | stepFrom = (stepIdx - 1) * subwindowSize + 1; 92 | stepTo = min(stepFrom + subwindowSize - 1, stockCols); 93 | stepData = [windowMarketData windowStocksData{:, stepFrom:stepTo}]; 94 | 95 | [~, SigmaT] = DCC1step(stepData, profile); 96 | 97 | % variance of univariate GARCH (sigma_m^2) 98 | varsMarket{2, stepIdx} = SigmaT(1, 1); 99 | 100 | % DCC conditional covariance (sigma_im^2) 101 | covsStocks{2, stepFrom:stepTo} = SigmaT(1, 2:end); 102 | 103 | if mod(stepIdx, 10) == 0 104 | fprintf(' %i of %i steps \n', stepIdx, fitSteps); 105 | end 106 | end 107 | 108 | % make sure all columns were fitted 109 | assert(sum(isnan(varsMarket{2, :})) == 0) 110 | assert(sum(isnan(covsStocks{2, :})) == 0) 111 | 112 | % save covariance matrix to output directory 113 | writetable(varsMarket, sprintf('%s/vars.market.csv', outDir1), 'Delimiter', ';', 'WriteRowNames', true); 114 | writetable(covsStocks, sprintf('%s/covs.stocks.csv', outDir1), 'Delimiter', ';', 'WriteRowNames', true); 115 | 116 | % rename directory (remove `_pending`) 117 | if 7 == exist(outDir2, 'dir') 118 | rmdir(outDir2, 's'); 119 | end 120 | 121 | % remove `_pending` suffix from output directory 122 | movefile(outDir1, outDir2); 123 | 124 | toc 125 | end 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/run_euler.sh: -------------------------------------------------------------------------------- 1 | for i in {1..47}; 2 | do 3 | matlab -nosplash -nojvm -nosoftwareopengl -nodesktop -logfile "logs/main_$i.log" -r "try, main; end, quit" & 4 | done -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/submit_120.sh: -------------------------------------------------------------------------------- 1 | bsub -R "rusage[mem=2048]" -n 48 -W 120:00 "module load new matlab/9.3 && mkdir -p out && mkdir -p logs && ./run_euler.sh" -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_1000/zip.sh: -------------------------------------------------------------------------------- 1 | zip -r -q out.zip out -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/consolidate.R: -------------------------------------------------------------------------------- 1 | library(data.table) 2 | 3 | source('../../../functions.R') 4 | 5 | consolidated.path <- './consolidated' 6 | out.path <- './out' 7 | returns.path <- '../../../0 data/CRSP/sp500_stock_ex_returns.csv' 8 | 9 | 10 | path.out.make <- function(date, file) { 11 | paste0(out.path, '/', date, '/', file) 12 | } 13 | 14 | path.consolidated.make <- function(file) { 15 | paste0(consolidated.path, '/', file) 16 | } 17 | 18 | 19 | # load excess returns data 20 | returns <- fread(returns.path, header=T, sep=';') 21 | head(returns[, 1:20], n=3) 22 | 23 | 24 | # extract all computed dates 25 | dates.all <- list.dirs(path=out.path, full.names=F, recursive=F) 26 | dates <- Filter(function(x) nchar(x) == 10, dates.all) # ignore pending entries 27 | dates <- sort(dates) 28 | 29 | 30 | # read files of interest 31 | stocks.cols <- colnames(returns)[-c(1:2)] 32 | 33 | covs.estimated <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), stocks.cols)) 34 | covs.1stepahead <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), stocks.cols)) 35 | 36 | vars.estimated.market <- matrix(NA, nrow=length(dates), ncol=1, dimnames=list(c(), c('median'))) 37 | vars.1stepahead.market <- matrix(NA, nrow=length(dates), ncol=1, dimnames=list(c(), c('median'))) 38 | 39 | for (i in 1:length(dates)) { 40 | date <- dates[i] 41 | 42 | 43 | # covariances 44 | tmp.covs.stocks <- first.col.2.rownames(fread(path.out.make(date, 'covs.stocks.csv'), header=T, sep=';', data.table=F)) 45 | tmp.covs.cols <- gsub('x', '', colnames(tmp.covs.stocks)) 46 | 47 | # covs.estimated 48 | covs.estimated[i, tmp.covs.cols] <- unlist(tmp.covs.stocks['estimated', ]) 49 | 50 | # covs.1stepahead 51 | covs.1stepahead[i, tmp.covs.cols] <- unlist(tmp.covs.stocks['1stepahead', ]) 52 | 53 | 54 | # variances 55 | tmp.vars.market <- first.col.2.rownames(fread(path.out.make(date, 'vars.market.csv'), header=T, sep=';', data.table=F)) 56 | 57 | # vars.estimated 58 | vars.estimated.market[i, 'median'] <- median(unlist(tmp.vars.market['estimated', ]), na.rm=T) 59 | 60 | # vars.1stepahead 61 | vars.1stepahead.market[i, 'median'] <- median(unlist(tmp.vars.market['1stepahead', ]), na.rm=T) 62 | 63 | 64 | # log progress 65 | if (i %% 50 == 0) 66 | cat(date, format(round(100.0 * i / length(dates), 1), nsmall=1), '% \n') 67 | } 68 | 69 | 70 | # add date as first column 71 | covs.estimated <- cbind(data.table(date=dates), covs.estimated) 72 | covs.1stepahead <- cbind(data.table(date=dates), covs.1stepahead) 73 | vars.estimated.market <- cbind(data.table(date=dates), vars.estimated.market) 74 | vars.1stepahead.market <- cbind(data.table(date=dates), vars.1stepahead.market) 75 | 76 | 77 | 78 | # write consolidated data to disk 79 | if (!dir.exists(consolidated.path)) 80 | dir.create(consolidated.path) 81 | 82 | # covs.estimated.csv 83 | fwrite(covs.estimated, path.consolidated.make('covs.estimated.csv'), sep=';') 84 | 85 | # covs.1stepahead.csv 86 | fwrite(covs.1stepahead, path.consolidated.make('covs.1stepahead.csv'), sep=';') 87 | 88 | # vars.estimated.market.csv 89 | fwrite(vars.estimated.market, path.consolidated.make('vars.estimated.market.csv'), sep=';') 90 | 91 | # vars.1stepahead.market.csv 92 | fwrite(vars.1stepahead.market, path.consolidated.make('vars.1stepahead.market.csv'), sep=';') 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/lib/CD2ab.m: -------------------------------------------------------------------------------- 1 | function [ab,Vout] = CD2ab(CD,Vin) 2 | %a=C*D;b=D-CD so 02 || n2>2, warning('CD2ab programmed wrong'), end 5 | ab(1) = CD(1).*CD(2); ab(2) = CD(2)-CD(1).*CD(2); 6 | if nargout>1 % now adjust the standard errors 7 | J=[CD(2), CD(1); -CD(2), (1-CD(1))]; Vout=J * Vin *J; 8 | end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/lib/DCC1step.m: -------------------------------------------------------------------------------- 1 | function [mu, Sigma] = DCC1step(data, profile) 2 | % INPUT: data is a T X d matrix of asset log returns 3 | % Output: 4 | % mu: the mean of returns, 1 x d vector 5 | % sigma: one step ahead prediction of the asset covariance matrix 6 | % computed using the Gaussian DCC-GARCH model 7 | 8 | %profile = 10; 9 | [T,d] = size(data); 10 | 11 | mu = mean(data); 12 | data_demean = data - repmat(mu,T,1); 13 | garchP = zeros(3,d); 14 | sigmamat = zeros(T,d); 15 | GARCHresid = zeros(T,d); 16 | 17 | for n = 1:d 18 | garchP(:,n) = normalGARCHPL(data_demean(:,n),[],profile); 19 | [GARCHresid(:,n),sigmamat(:,n)] = ungarch(data_demean(:,n), garchP(:,n)); 20 | end 21 | 22 | %DCC: Q_t=S*(1-a-b)+a*eps_{t-1}eps'_{t-1} +b*Q_{t-1} 23 | initvec = []; 24 | S = []; 25 | Gamma0 = []; 26 | [a,b,Smat,~,Gamma0] = DCCestimate(GARCHresid,initvec,S,Gamma0); 27 | Rmat = zeros(d,d,T); 28 | S = Smat; 29 | Q = Gamma0; 30 | 31 | for t=1:T 32 | if t>1 33 | Q = DCCengine(GARCHresid(t-1,:),a,b,S,Q); 34 | Corrmat = diag(sqrt(diag(Q)).^(-1))*Q*diag(sqrt(diag(Q)).^(-1)); 35 | Corrmat = SymPDcorrmatrix(Corrmat); 36 | else 37 | Corrmat = S; Q=S; Corrmat=SymPDcorrmatrix(Corrmat); 38 | end 39 | 40 | Rmat(:,:,t)=Corrmat; 41 | end 42 | 43 | Q_f = (1-a-b)*Rmat(:,:,1)+a*GARCHresid(end,:)'*GARCHresid(end,:)+b*Rmat(:,:,end); 44 | R_f = diag(diag(Q_f).^(-0.5))*Q_f*diag(diag(Q_f).^(-0.5)); 45 | H_f = diag(sigmamat(end,:))*Rmat(:,:,end)*diag(sigmamat(end,:)); 46 | 47 | % Recombine GARCH11 and Correlation matrix forecast 48 | D_f = diag(sqrt(garchP(1,:)+garchP(2,:).*GARCHresid(end,:).^2+garchP(3,:).*diag(H_f)')); 49 | Sigma = D_f * R_f * D_f; 50 | Sigma = SymPDcovmatrix(Sigma); 51 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/lib/DCCengine.m: -------------------------------------------------------------------------------- 1 | function Q=DCCengine(resid_t,a,b,S,Qin) 2 | Mmat = resid_t'*resid_t; Mmat=SymPDcovmatrix(Mmat); 3 | Q=(1-a-b) * S + a * Mmat + b * Qin; 4 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/lib/DCCestimate.m: -------------------------------------------------------------------------------- 1 | function [a,b,Smat,ll,Gamma0] = DCCestimate(resid,initvec,S,Gamma0) 2 | 3 | % C D 4 | bound.lo = [0.001 0 ]; 5 | bound.hi = [1-(1e-04) 1-(1e-04) ]; 6 | bound.which = [1 1 ]; 7 | 8 | if isempty(initvec), initvec=[0.05 0.93]; end 9 | if isempty(S), S=corr(resid); end 10 | 11 | S = SymPDcorrmatrix(S); 12 | 13 | if isempty(Gamma0), Gamma0=S; end 14 | 15 | Gamma0 = SymPDcorrmatrix(Gamma0); 16 | 17 | opt = optimset('Display', 'off', 'TolFun', 1e-6, 'TolX', 1e-6, 'MaxFunEvals', 5000, 'LargeScale', 'Off'); 18 | [pout,~] = fminunc(@(param) loglikDCC(param,resid,S,Gamma0,bound), einschrk(ab2CD(initvec), bound), opt); 19 | 20 | param = CD2ab(einschrk(real(pout), bound, 1)); 21 | a = param(1); 22 | b = param(2); 23 | Smat = S; 24 | 25 | ll = -1 * loglikDCC(ab2CD(param), resid, S, Gamma0, []); 26 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/lib/SymPDcorrmatrix.m: -------------------------------------------------------------------------------- 1 | function A=SymPDcorrmatrix(A,tol) 2 | [n,m]=size(A); 3 | if ~(n==m), error('Input matrix has to be a square matrix '), end 4 | if nargin<2, tol=1e-04; end 5 | if sum(any(abs((A)-eye(n))>=1+(1e-02)))>0, warning('This is not a correlation matrix'); end 6 | numCol = find( any( abs((A)-eye(n)) >= ( 1-(1e-16) ) ) ); 7 | numRow = find( any( abs((A)-eye(n))' >= ( 1-(1e-16) ) ) ); 8 | if ~isempty(numCol) || ~isempty(numRow) 9 | A(numRow,numCol) = sign(A(numRow,numCol)) * ( 1-(1e-16) ); 10 | % the off-diagonal entries in (-1 1) 11 | warning('Some of the correlations were corrected'); 12 | end 13 | A = A - diag(diag(A)) + eye(n,m); % ones on the diagonal 14 | A = ( A + A' )/2; % symmetric matrix 15 | [V,D] = eig(A); seig = diag(D); bad = find(seig < tol); % PD 16 | if ~isempty(bad), seig(bad) = tol; D = diag(seig); A = V * D * V';end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/lib/SymPDcovmatrix.m: -------------------------------------------------------------------------------- 1 | function A=SymPDcovmatrix(A,tol) 2 | [n,m]=size(A); 3 | if ~(n==m), error('Input matrix has to be a square matrix '), end 4 | if nargin<2, tol=1e-04; end 5 | A=(A+A')/2; 6 | try 7 | [V,D]=eig(A); seig=diag(D); bad=find(seig 9 | %bp=1; 10 | end 11 | if ~isempty(bad), seig(bad)=tol; D=diag(seig); A=V*D*V';end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/lib/ab2CD.m: -------------------------------------------------------------------------------- 1 | function [CD, Vout] =ab2CD(ab,Vin) 2 | %C=a/(a+b);D=a+b so 02 || n2>2, warning('ab2CD programed wrong'), end %#ok<*WNTAG> 5 | CD(1) = ab(1) ./ (ab(1) + ab(2)); CD(2) = ab(1) + ab(2); 6 | if nargout>1 % now adjust the standard errors 7 | J=[1./(ab(1) + ab(2)) - ab(1)./(ab(1) + ab(2)).^2, -ab(1)/(ab(1) + ab(2)).^2 ; 1,1]; 8 | Vout=J * Vin * J; 9 | end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/lib/einschrk.m: -------------------------------------------------------------------------------- 1 | function [pout,Vout]=einschrk(pin,bound,Vin) 2 | % [pout,Vout]=einschrk(pin,bound,Vin) 3 | % if Vin specified, then pout is untransformed, otherwise pout is transformed 4 | % M. Paolella, 1997 5 | 6 | welche=bound.which; 7 | if all(welche==0) % no bounds! 8 | pout=pin; 9 | if nargin==3, Vout=Vin; end 10 | return 11 | end 12 | 13 | lo=bound.lo; hi=bound.hi; 14 | if nargin < 3 15 | trans=sqrt((hi-pin) ./ (pin-lo)); 16 | pout=(1-welche).* pin + welche .* trans; 17 | Vout=[]; 18 | else 19 | trans=(hi+lo.*pin.^2) ./ (1+pin.^2); 20 | pout=(1-welche).* pin + welche .* trans; 21 | % now adjust the standard errors 22 | trans=2*pin.*(lo-hi) ./ (1+pin.^2).^2; 23 | d=(1-welche) + welche .* trans; % either unity or delta method. 24 | J=diag(d); 25 | Vout = J * Vin * J; 26 | end 27 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/lib/loglikDCC.m: -------------------------------------------------------------------------------- 1 | function loglik=loglikDCC(param,resid,S,Q,bound) 2 | 3 | if ~isempty(bound), param=einschrk(real(param),bound,999); end 4 | 5 | a = param(1) * param(2); 6 | b = param(2) - param(1) * param(2); 7 | 8 | [T,d] = size(resid); ll=zeros(T,1); 9 | for t=1:T 10 | if t>1 11 | Q = DCCengine(resid(t-1,:),a,b,S,Q); 12 | Corrmat = diag(sqrt(diag(Q)).^(-1))*Q*diag(sqrt(diag(Q)).^(-1)); 13 | Corrmat = SymPDcorrmatrix(Corrmat); 14 | else 15 | Corrmat=S; Q=S; Corrmat=SymPDcorrmatrix(Corrmat); 16 | end 17 | 18 | detGamma=det(Corrmat); Gammainv=Corrmat\eye(d); 19 | ll(t) = - 0.5 *(log(abs(detGamma)) + resid(t,:) * Gammainv * resid(t,:)'); 20 | end 21 | loglik= - sum(ll); -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/lib/normalGARCHPL.m: -------------------------------------------------------------------------------- 1 | function [param,stderr,loglik,resmat]=normalGARCHPL(ret,initvec,profile,B) 2 | % normal-GARCH(1,1) estimation of a mean-zero process 3 | % INPUT 4 | % ret is the T X 1 zero-mean time series. 5 | % or T X d matrix of returns. If d>1, the log liks are pooled! 6 | % This could be used as a shrinkage target. 7 | % 8 | % initvec is starting values of the 3 GARCH parameters, 9 | % pass [] to use default. 10 | % 11 | % Call with profile = 0 (default) for usual normal GARCH estimation. 12 | % Call with profile>=1 to do profile likelihood in c_0, with 13 | % the size of the grid for c_0 equal to *profile* parameter. 14 | % Then, loglik is a vector, and resmat a matrix of the 3 GARCH coef 15 | % 16 | % B is number of bootstrap replications to determine the std error 17 | % of the parameters. Pass B=0 (default) to use approximation from Hessian. 18 | % Current set up: Only use if d=1 and profile>0 19 | % 20 | % To set the exponent of the GARCH equation, manually do so below 21 | % via parameter delta. Default is 2. 22 | % 23 | % Example. If ret is the vector of percentage log returns, use: 24 | % [param,stderr,loglik,resmat] = normalGARCHPL(ret,[],10); 25 | % param, stderr 26 | % % optionally can look at: [loglik,resmat] 27 | % Use [param,stderr,loglik,resmat] = normalGARCHPL(ret,[],10,200); 28 | % to get better std errors via the (parametric) bootstrap. 29 | global y bound delta; 30 | delta=2; y=ret; [T,d]=size(y); 31 | if nargin<4 || isempty(B), B=0; end 32 | if d==1, B=0; end % could easily relax this later... 33 | UseBootstrap=B>0; 34 | if nargin<2, initvec=[]; end 35 | if or(nargin<3,isempty(profile)), profile=0; end 36 | fmintol=1e-5; maxit=200; 37 | opt = optimset('LargeScale','off','display','off', 'Maxiter',... 38 | maxit,'TolFun',fmintol,'TolX',fmintol); 39 | if profile>0 40 | if isempty(initvec), initvec=[0.02 0.9]; end 41 | lb=1e-5; ub=1-lb; 42 | % c_1 d_1 43 | bound.lo= [lb 0 ]; 44 | bound.hi= [ub ub ]; 45 | bound.which= [1 1 ]; 46 | clen=profile; % 100 is what I usually use 47 | resmat=zeros(clen,3); 48 | loglik=zeros(clen,1); best=-Inf; 49 | cvec=linspace(0,1.2*max(var(y)),clen); 50 | for i=1:clen 51 | c=cvec(i); 52 | [pout,fval]=fminunc(@(param) proflik(param,c),einschrk(initvec,bound),opt); 53 | hess=eye(length(pout)); V=pinv(hess)/(T*d); 54 | [parami,~]=einschrk(pout,bound,V); 55 | loglik(i)=-fval*(T*d); 56 | resmat(i,1)=c; resmat(i,2)=parami(1); resmat(i,3)=parami(2); 57 | if loglik(i)>best, best=loglik(i); param=[c parami]; end 58 | end 59 | thebestinitvec=param; 60 | [param,stderrHESS] = normalGARCHPL(y,thebestinitvec,0); 61 | if any(abs(imag(stderrHESS))>0), stderrHESS=NaN(1,3); end 62 | if nargout>1, stderr=stderrHESS; end 63 | if nargout>1 && UseBootstrap 64 | Pmat=NaN(B,3); qq=param(1:2); pp=param(3); 65 | for b=1:B 66 | YY=simg(T,qq,pp,delta); Pmat(b,:) = normalGARCHPL(YY,param,0); 67 | end 68 | stderr=std(Pmat); 69 | end 70 | else % no use of profile (and also not bootstrap) 71 | if nargout>=4, resmat=[]; end 72 | if isempty(initvec), initvec=[0.02 0.02 0.9]; end 73 | lb=1e-5; ub=1-lb; 74 | if initvec(1)<=lb; initvec(1)=0.001; end 75 | if initvec(2)<=lb; initvec(2)=0.001; end 76 | if initvec(2)>=ub; initvec(2)=0.99; end 77 | if initvec(3)<=lb; initvec(3)=0.001; end 78 | if initvec(3)>=ub; initvec(3)=0.99; end 79 | % c_0 c_1 d_1 80 | bound.lo= [lb lb 0 ]; 81 | bound.hi= [1.2*max(var(y)) ub ub ]; 82 | bound.which= [1 1 1 ]; 83 | [pout,fval,~,~,~,hess]=fminunc(@(param) like2005(param),einschrk(initvec,bound),opt); 84 | V=pinv(hess)/(T*d); [param,V]=einschrk(pout,bound,V); 85 | stderr=sqrt(diag(V))'; loglik=-fval*(T*d); 86 | end 87 | 88 | function loglik=proflik(param,c) 89 | global y bound zvec sigvec 90 | theparam = einschrk(real(param),bound,999); 91 | param=[c theparam]; d=size(y,2); partloglik=zeros(1,d); 92 | logK=log(sqrt(2*pi)); 93 | for i=1:d 94 | [zvec,sigvec]=ungarch(y(:,i),param); 95 | ll=-0.5*(zvec.^2)-logK-log(sigvec); partloglik(i)=-mean(ll); 96 | end 97 | loglik=mean(partloglik); 98 | 99 | function loglik=like2005(param) 100 | global y bound zvec sigvec 101 | param = einschrk(real(param),bound,999); 102 | d=size(y,2); partloglik=zeros(1,d); logK=log(sqrt(2*pi)); 103 | for i=1:d 104 | [zvec,sigvec]=ungarch(y(:,i),param); 105 | ll =-0.5*(zvec.^2)-logK-log(sigvec); partloglik(i)=-mean(ll); 106 | end 107 | loglik=mean(partloglik); 108 | 109 | function y=simg(nobs,qq,pp,delta) 110 | % Input 111 | % qq is the ARCH component, pp is GARCH part, i.e., 112 | % qq= [omega alpha]; pp = [beta] 113 | % delta is the exponent in the GARCH equation, default of 2. 114 | % Output y is a Gaussian garch(1,1) series 115 | if nargin<6, delta=2; end 116 | warm=500; use=nobs+warm; 117 | s = rng; rng('shuffle'); z=randn(use+1,1); % get the z vector 118 | rng(s); 119 | h=zeros(use+1,1); e=zeros(use+1,1); omega=qq(1); qv=qq(2); pv=pp; 120 | h(1)=omega; e(1)=h(1)*z(1); 121 | for i=2:use+1 122 | h(i)=omega+ qv*( abs(e(i-1)) )^delta + pv*h(i-1); 123 | e(i)=( (h(i))^(1/delta) ) * z(i); 124 | end 125 | e=e(2:end); y=e(warm+1:use); 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/lib/ungarch.m: -------------------------------------------------------------------------------- 1 | function [eout,sigvec]=ungarch(epsi,garchin) 2 | global delta 3 | int=garchin(1); qterms=garchin(2); pterms=garchin(3); 4 | e=(abs(epsi)).^delta; 5 | lambda=( ( 2^(delta/2) ) / sqrt(pi) ) * gamma((delta+1)/2); 6 | 7 | % sinit = E[sigvec_0^delta], einit = E|e_0^delta| = lambda * sinit. 8 | sinit=mean((abs(epsi)).^delta); einit=lambda*sinit; 9 | 10 | % do the recursion in sigvec^delta 11 | sigvec=zeros(length(e),1); sigvec(1)=int+qterms*einit+pterms*sinit; 12 | 13 | for i=2:length(e), sigvec(i)=int + qterms*e(i-1) + pterms*sigvec(i-1); end 14 | if any(sigvec<=0), error('hello'), end 15 | 16 | sigvec=sigvec.^(1/delta); 17 | eout=epsi./sigvec; 18 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/main.m: -------------------------------------------------------------------------------- 1 | rng shuffle 2 | 3 | addpath(genpath('lib')); % import DCC-GARCH estimation and prediction functions 4 | 5 | % load returns data 6 | returns = readtable('sp500_stock_ex_returns_demeaned_scaled.csv', 'ReadVariableNames',true); 7 | 8 | % extract data 9 | dates = returns{:, 1}; 10 | marketData = returns{:, 2}; 11 | stockData = returns(:, 3:end); 12 | 13 | windowSize = 126; 14 | subwindowSize = 1; 15 | from = find(returns.date == '1996-01-02'); 16 | to = find(returns.date == '2013-12-31'); 17 | steps = to - from + 1; 18 | profile = 10; 19 | 20 | increments = from:to; 21 | for i=increments(randperm(length(increments))) 22 | tic; 23 | 24 | date = dates(i); 25 | 26 | fprintf('step %i of %i (%s) - ', i - from + 1, steps, date); 27 | 28 | % output directories 29 | outDir1 = sprintf('out/%s_pending', date); 30 | outDir2 = sprintf('out/%s', date); 31 | 32 | % delete _pending folder if it exists already 33 | if 7 == exist(outDir1, 'dir') 34 | rmdir(outDir1, 's'); 35 | end 36 | 37 | % skip if final output directory already exists 38 | if 7 == exist(outDir2, 'dir') 39 | % already computed - ignore this step 40 | fprintf('ignoring %s - already computed \n', date); 41 | 42 | if 7 == exist(outDir1, 'dir') 43 | rmdir(outDir1, 's'); 44 | end 45 | 46 | continue; 47 | end 48 | 49 | % create `pending` output directory 50 | [status,msg] = mkdir(outDir1); 51 | if status ~= 1 52 | fprintf('ERROR: Failed to create directory %s with message: %s \n', outDir1, msg); 53 | continue; 54 | end 55 | 56 | % extract window data 57 | windowStocksData = stockData((i - windowSize + 1):i, :); 58 | windowMarketData = marketData((i - windowSize + 1):i, :); 59 | 60 | % determine which columns have enough data (no NaNs) 61 | cols = arrayfun(@(x) x == size(windowStocksData, 1), sum(~isnan(windowStocksData{:,:}), 1)); 62 | 63 | % create matrix with columns which have no NaNs 64 | colIdxs = transpose(1:size(windowStocksData, 2)) .* transpose(cols); 65 | colIdxs = colIdxs(colIdxs > 0); 66 | windowStocksData = windowStocksData(:, colIdxs); 67 | stockCols = size(windowStocksData, 2); 68 | 69 | % fit DCC-GARCH in sub-samples 70 | fitSteps = ceil(stockCols / subwindowSize); 71 | 72 | varsMarket = array2table(nan(2, fitSteps), 'RowNames', cellstr({"estimated" "1stepahead"})); 73 | covsStocks = array2table(nan(2, stockCols), 'RowNames', cellstr({"estimated" "1stepahead"})); 74 | covsStocks.Properties.VariableNames = windowStocksData.Properties.VariableNames; 75 | 76 | for stepIdx = 1:fitSteps 77 | stepFrom = (stepIdx - 1) * subwindowSize + 1; 78 | stepTo = min(stepFrom + subwindowSize - 1, stockCols); 79 | stepData = [windowMarketData windowStocksData{:, stepFrom:stepTo}]; 80 | 81 | [~, SigmaT] = DCC1step(stepData, profile); 82 | 83 | % variance of univariate GARCH (sigma_m^2) 84 | varsMarket{2, stepIdx} = SigmaT(1, 1); 85 | 86 | % DCC conditional covariance (sigma_im^2) 87 | covsStocks{2, stepFrom:stepTo} = SigmaT(1, 2:end); 88 | 89 | if mod(stepIdx, 10) == 0 90 | fprintf(' %i of %i steps \n', stepIdx, fitSteps); 91 | end 92 | end 93 | 94 | % make sure all columns were fitted 95 | assert(sum(isnan(varsMarket{2, :})) == 0) 96 | assert(sum(isnan(covsStocks{2, :})) == 0) 97 | 98 | % save covariance matrix to output directory 99 | writetable(varsMarket, sprintf('%s/vars.market.csv', outDir1), 'Delimiter', ';', 'WriteRowNames', true); 100 | writetable(covsStocks, sprintf('%s/covs.stocks.csv', outDir1), 'Delimiter', ';', 'WriteRowNames', true); 101 | 102 | % rename directory (remove `_pending`) 103 | if 7 == exist(outDir2, 'dir') 104 | rmdir(outDir2, 's'); 105 | end 106 | 107 | % remove `_pending` suffix from output directory 108 | movefile(outDir1, outDir2); 109 | 110 | toc 111 | end 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_126/run_pc.sh: -------------------------------------------------------------------------------- 1 | for i in {1..10}; 2 | do 3 | matlab -nosplash -nojvm -nosoftwareopengl -nodesktop -logfile "logs/$i" -r "try, main; end, quit" & 4 | done -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/DCC1step_original.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/Matlab/DCC1step_252/DCC1step_original.zip -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/consolidate.R: -------------------------------------------------------------------------------- 1 | library(data.table) 2 | 3 | source('../../../functions.R') 4 | 5 | consolidated.path <- './consolidated' 6 | out.path <- './out' 7 | returns.path <- '../../../0 data/CRSP/sp500_stock_ex_returns.csv' 8 | 9 | 10 | path.out.make <- function(date, file) { 11 | paste0(out.path, '/', date, '/', file) 12 | } 13 | 14 | path.consolidated.make <- function(file) { 15 | paste0(consolidated.path, '/', file) 16 | } 17 | 18 | 19 | # load excess returns data 20 | returns <- fread(returns.path, header=T, sep=';') 21 | head(returns[, 1:20], n=3) 22 | 23 | 24 | # extract all computed dates 25 | dates.all <- list.dirs(path=out.path, full.names=F, recursive=F) 26 | dates <- Filter(function(x) nchar(x) == 10, dates.all) # ignore pending entries 27 | dates <- sort(dates) 28 | 29 | 30 | # read files of interest 31 | stocks.cols <- colnames(returns)[-c(1:2)] 32 | 33 | covs.estimated <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), stocks.cols)) 34 | covs.1stepahead <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), stocks.cols)) 35 | 36 | vars.estimated.market <- matrix(NA, nrow=length(dates), ncol=1, dimnames=list(c(), c('median'))) 37 | vars.1stepahead.market <- matrix(NA, nrow=length(dates), ncol=1, dimnames=list(c(), c('median'))) 38 | 39 | for (i in 1:length(dates)) { 40 | date <- dates[i] 41 | 42 | 43 | # covariances 44 | tmp.covs.stocks <- first.col.2.rownames(fread(path.out.make(date, 'covs.stocks.csv'), header=T, sep=';', data.table=F)) 45 | tmp.covs.cols <- gsub('x', '', colnames(tmp.covs.stocks)) 46 | 47 | # covs.estimated 48 | covs.estimated[i, tmp.covs.cols] <- unlist(tmp.covs.stocks['estimated', ]) 49 | 50 | # covs.1stepahead 51 | covs.1stepahead[i, tmp.covs.cols] <- unlist(tmp.covs.stocks['1stepahead', ]) 52 | 53 | 54 | # variances 55 | tmp.vars.market <- first.col.2.rownames(fread(path.out.make(date, 'vars.market.csv'), header=T, sep=';', data.table=F)) 56 | 57 | # vars.estimated 58 | vars.estimated.market[i, 'median'] <- median(unlist(tmp.vars.market['estimated', ]), na.rm=T) 59 | 60 | # vars.1stepahead 61 | vars.1stepahead.market[i, 'median'] <- median(unlist(tmp.vars.market['1stepahead', ]), na.rm=T) 62 | 63 | 64 | # log progress 65 | if (i %% 50 == 0) 66 | cat(date, format(round(100.0 * i / length(dates), 1), nsmall=1), '% \n') 67 | } 68 | 69 | 70 | # add date as first column 71 | covs.estimated <- cbind(data.table(date=dates), covs.estimated) 72 | covs.1stepahead <- cbind(data.table(date=dates), covs.1stepahead) 73 | vars.estimated.market <- cbind(data.table(date=dates), vars.estimated.market) 74 | vars.1stepahead.market <- cbind(data.table(date=dates), vars.1stepahead.market) 75 | 76 | 77 | 78 | # write consolidated data to disk 79 | if (!dir.exists(consolidated.path)) 80 | dir.create(consolidated.path) 81 | 82 | # covs.estimated.csv 83 | fwrite(covs.estimated, path.consolidated.make('covs.estimated.csv'), sep=';') 84 | 85 | # covs.1stepahead.csv 86 | fwrite(covs.1stepahead, path.consolidated.make('covs.1stepahead.csv'), sep=';') 87 | 88 | # vars.estimated.market.csv 89 | fwrite(vars.estimated.market, path.consolidated.make('vars.estimated.market.csv'), sep=';') 90 | 91 | # vars.1stepahead.market.csv 92 | fwrite(vars.1stepahead.market, path.consolidated.make('vars.1stepahead.market.csv'), sep=';') 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/lib/CD2ab.m: -------------------------------------------------------------------------------- 1 | function [ab,Vout] = CD2ab(CD,Vin) 2 | %a=C*D;b=D-CD so 02 || n2>2, warning('CD2ab programmed wrong'), end 5 | ab(1) = CD(1).*CD(2); ab(2) = CD(2)-CD(1).*CD(2); 6 | if nargout>1 % now adjust the standard errors 7 | J=[CD(2), CD(1); -CD(2), (1-CD(1))]; Vout=J * Vin *J; 8 | end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/lib/DCC1step.m: -------------------------------------------------------------------------------- 1 | function [mu, Sigma] = DCC1step(data, profile) 2 | % INPUT: data is a T X d matrix of asset log returns 3 | % Output: 4 | % mu: the mean of returns, 1 x d vector 5 | % sigma: one step ahead prediction of the asset covariance matrix 6 | % computed using the Gaussian DCC-GARCH model 7 | 8 | %profile = 10; 9 | [T,d] = size(data); 10 | 11 | mu = mean(data); 12 | data_demean = data - repmat(mu,T,1); 13 | garchP = zeros(3,d); 14 | sigmamat = zeros(T,d); 15 | GARCHresid = zeros(T,d); 16 | 17 | for n = 1:d 18 | garchP(:,n) = normalGARCHPL(data_demean(:,n),[],profile); 19 | [GARCHresid(:,n),sigmamat(:,n)] = ungarch(data_demean(:,n), garchP(:,n)); 20 | end 21 | 22 | %DCC: Q_t=S*(1-a-b)+a*eps_{t-1}eps'_{t-1} +b*Q_{t-1} 23 | initvec = []; 24 | S = []; 25 | Gamma0 = []; 26 | [a,b,Smat,~,Gamma0] = DCCestimate(GARCHresid,initvec,S,Gamma0); 27 | Rmat = zeros(d,d,T); 28 | S = Smat; 29 | Q = Gamma0; 30 | 31 | for t=1:T 32 | if t>1 33 | Q = DCCengine(GARCHresid(t-1,:),a,b,S,Q); 34 | Corrmat = diag(sqrt(diag(Q)).^(-1))*Q*diag(sqrt(diag(Q)).^(-1)); 35 | Corrmat = SymPDcorrmatrix(Corrmat); 36 | else 37 | Corrmat = S; Q=S; Corrmat=SymPDcorrmatrix(Corrmat); 38 | end 39 | 40 | Rmat(:,:,t)=Corrmat; 41 | end 42 | 43 | Q_f = (1-a-b)*Rmat(:,:,1)+a*GARCHresid(end,:)'*GARCHresid(end,:)+b*Rmat(:,:,end); 44 | R_f = diag(diag(Q_f).^(-0.5))*Q_f*diag(diag(Q_f).^(-0.5)); 45 | H_f = diag(sigmamat(end,:))*Rmat(:,:,end)*diag(sigmamat(end,:)); 46 | 47 | % Recombine GARCH11 and Correlation matrix forecast 48 | D_f = diag(sqrt(garchP(1,:)+garchP(2,:).*GARCHresid(end,:).^2+garchP(3,:).*diag(H_f)')); 49 | Sigma = D_f * R_f * D_f; 50 | Sigma = SymPDcovmatrix(Sigma); 51 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/lib/DCCengine.m: -------------------------------------------------------------------------------- 1 | function Q=DCCengine(resid_t,a,b,S,Qin) 2 | Mmat = resid_t'*resid_t; Mmat=SymPDcovmatrix(Mmat); 3 | Q=(1-a-b) * S + a * Mmat + b * Qin; 4 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/lib/DCCestimate.m: -------------------------------------------------------------------------------- 1 | function [a,b,Smat,ll,Gamma0] = DCCestimate(resid,initvec,S,Gamma0) 2 | 3 | % C D 4 | bound.lo = [0.001 0 ]; 5 | bound.hi = [1-(1e-04) 1-(1e-04) ]; 6 | bound.which = [1 1 ]; 7 | 8 | if isempty(initvec), initvec=[0.05 0.93]; end 9 | if isempty(S), S=corr(resid); end 10 | 11 | S = SymPDcorrmatrix(S); 12 | 13 | if isempty(Gamma0), Gamma0=S; end 14 | 15 | Gamma0 = SymPDcorrmatrix(Gamma0); 16 | 17 | opt = optimset('Display', 'off', 'TolFun', 1e-6, 'TolX', 1e-6, 'MaxFunEvals', 5000, 'LargeScale', 'Off'); 18 | [pout,~] = fminunc(@(param) loglikDCC(param,resid,S,Gamma0,bound), einschrk(ab2CD(initvec), bound), opt); 19 | 20 | param = CD2ab(einschrk(real(pout), bound, 1)); 21 | a = param(1); 22 | b = param(2); 23 | Smat = S; 24 | 25 | ll = -1 * loglikDCC(ab2CD(param), resid, S, Gamma0, []); 26 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/lib/SymPDcorrmatrix.m: -------------------------------------------------------------------------------- 1 | function A=SymPDcorrmatrix(A,tol) 2 | [n,m]=size(A); 3 | if ~(n==m), error('Input matrix has to be a square matrix '), end 4 | if nargin<2, tol=1e-04; end 5 | if sum(any(abs((A)-eye(n))>=1+(1e-02)))>0, warning('This is not a correlation matrix'); end 6 | numCol = find( any( abs((A)-eye(n)) >= ( 1-(1e-16) ) ) ); 7 | numRow = find( any( abs((A)-eye(n))' >= ( 1-(1e-16) ) ) ); 8 | if ~isempty(numCol) || ~isempty(numRow) 9 | A(numRow,numCol) = sign(A(numRow,numCol)) * ( 1-(1e-16) ); 10 | % the off-diagonal entries in (-1 1) 11 | warning('Some of the correlations were corrected'); 12 | end 13 | A = A - diag(diag(A)) + eye(n,m); % ones on the diagonal 14 | A = ( A + A' )/2; % symmetric matrix 15 | [V,D] = eig(A); seig = diag(D); bad = find(seig < tol); % PD 16 | if ~isempty(bad), seig(bad) = tol; D = diag(seig); A = V * D * V';end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/lib/SymPDcovmatrix.m: -------------------------------------------------------------------------------- 1 | function A=SymPDcovmatrix(A,tol) 2 | [n,m]=size(A); 3 | if ~(n==m), error('Input matrix has to be a square matrix '), end 4 | if nargin<2, tol=1e-04; end 5 | A=(A+A')/2; 6 | try 7 | [V,D]=eig(A); seig=diag(D); bad=find(seig 9 | %bp=1; 10 | end 11 | if ~isempty(bad), seig(bad)=tol; D=diag(seig); A=V*D*V';end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/lib/ab2CD.m: -------------------------------------------------------------------------------- 1 | function [CD, Vout] =ab2CD(ab,Vin) 2 | %C=a/(a+b);D=a+b so 02 || n2>2, warning('ab2CD programed wrong'), end %#ok<*WNTAG> 5 | CD(1) = ab(1) ./ (ab(1) + ab(2)); CD(2) = ab(1) + ab(2); 6 | if nargout>1 % now adjust the standard errors 7 | J=[1./(ab(1) + ab(2)) - ab(1)./(ab(1) + ab(2)).^2, -ab(1)/(ab(1) + ab(2)).^2 ; 1,1]; 8 | Vout=J * Vin * J; 9 | end -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/lib/einschrk.m: -------------------------------------------------------------------------------- 1 | function [pout,Vout]=einschrk(pin,bound,Vin) 2 | % [pout,Vout]=einschrk(pin,bound,Vin) 3 | % if Vin specified, then pout is untransformed, otherwise pout is transformed 4 | % M. Paolella, 1997 5 | 6 | welche=bound.which; 7 | if all(welche==0) % no bounds! 8 | pout=pin; 9 | if nargin==3, Vout=Vin; end 10 | return 11 | end 12 | 13 | lo=bound.lo; hi=bound.hi; 14 | if nargin < 3 15 | trans=sqrt((hi-pin) ./ (pin-lo)); 16 | pout=(1-welche).* pin + welche .* trans; 17 | Vout=[]; 18 | else 19 | trans=(hi+lo.*pin.^2) ./ (1+pin.^2); 20 | pout=(1-welche).* pin + welche .* trans; 21 | % now adjust the standard errors 22 | trans=2*pin.*(lo-hi) ./ (1+pin.^2).^2; 23 | d=(1-welche) + welche .* trans; % either unity or delta method. 24 | J=diag(d); 25 | Vout = J * Vin * J; 26 | end 27 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/lib/loglikDCC.m: -------------------------------------------------------------------------------- 1 | function loglik=loglikDCC(param,resid,S,Q,bound) 2 | 3 | if ~isempty(bound), param=einschrk(real(param),bound,999); end 4 | 5 | a = param(1) * param(2); 6 | b = param(2) - param(1) * param(2); 7 | 8 | [T,d] = size(resid); ll=zeros(T,1); 9 | for t=1:T 10 | if t>1 11 | Q = DCCengine(resid(t-1,:),a,b,S,Q); 12 | Corrmat = diag(sqrt(diag(Q)).^(-1))*Q*diag(sqrt(diag(Q)).^(-1)); 13 | Corrmat = SymPDcorrmatrix(Corrmat); 14 | else 15 | Corrmat=S; Q=S; Corrmat=SymPDcorrmatrix(Corrmat); 16 | end 17 | 18 | detGamma=det(Corrmat); Gammainv=Corrmat\eye(d); 19 | ll(t) = - 0.5 *(log(abs(detGamma)) + resid(t,:) * Gammainv * resid(t,:)'); 20 | end 21 | loglik= - sum(ll); -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/lib/normalGARCHPL.m: -------------------------------------------------------------------------------- 1 | function [param,stderr,loglik,resmat]=normalGARCHPL(ret,initvec,profile,B) 2 | % normal-GARCH(1,1) estimation of a mean-zero process 3 | % INPUT 4 | % ret is the T X 1 zero-mean time series. 5 | % or T X d matrix of returns. If d>1, the log liks are pooled! 6 | % This could be used as a shrinkage target. 7 | % 8 | % initvec is starting values of the 3 GARCH parameters, 9 | % pass [] to use default. 10 | % 11 | % Call with profile = 0 (default) for usual normal GARCH estimation. 12 | % Call with profile>=1 to do profile likelihood in c_0, with 13 | % the size of the grid for c_0 equal to *profile* parameter. 14 | % Then, loglik is a vector, and resmat a matrix of the 3 GARCH coef 15 | % 16 | % B is number of bootstrap replications to determine the std error 17 | % of the parameters. Pass B=0 (default) to use approximation from Hessian. 18 | % Current set up: Only use if d=1 and profile>0 19 | % 20 | % To set the exponent of the GARCH equation, manually do so below 21 | % via parameter delta. Default is 2. 22 | % 23 | % Example. If ret is the vector of percentage log returns, use: 24 | % [param,stderr,loglik,resmat] = normalGARCHPL(ret,[],10); 25 | % param, stderr 26 | % % optionally can look at: [loglik,resmat] 27 | % Use [param,stderr,loglik,resmat] = normalGARCHPL(ret,[],10,200); 28 | % to get better std errors via the (parametric) bootstrap. 29 | global y bound delta; 30 | delta=2; y=ret; [T,d]=size(y); 31 | if nargin<4 || isempty(B), B=0; end 32 | if d==1, B=0; end % could easily relax this later... 33 | UseBootstrap=B>0; 34 | if nargin<2, initvec=[]; end 35 | if or(nargin<3,isempty(profile)), profile=0; end 36 | fmintol=1e-5; maxit=200; 37 | opt = optimset('LargeScale','off','display','off', 'Maxiter',... 38 | maxit,'TolFun',fmintol,'TolX',fmintol); 39 | if profile>0 40 | if isempty(initvec), initvec=[0.02 0.9]; end 41 | lb=1e-5; ub=1-lb; 42 | % c_1 d_1 43 | bound.lo= [lb 0 ]; 44 | bound.hi= [ub ub ]; 45 | bound.which= [1 1 ]; 46 | clen=profile; % 100 is what I usually use 47 | resmat=zeros(clen,3); 48 | loglik=zeros(clen,1); best=-Inf; 49 | cvec=linspace(0,1.2*max(var(y)),clen); 50 | for i=1:clen 51 | c=cvec(i); 52 | [pout,fval]=fminunc(@(param) proflik(param,c),einschrk(initvec,bound),opt); 53 | hess=eye(length(pout)); V=pinv(hess)/(T*d); 54 | [parami,~]=einschrk(pout,bound,V); 55 | loglik(i)=-fval*(T*d); 56 | resmat(i,1)=c; resmat(i,2)=parami(1); resmat(i,3)=parami(2); 57 | if loglik(i)>best, best=loglik(i); param=[c parami]; end 58 | end 59 | thebestinitvec=param; 60 | [param,stderrHESS] = normalGARCHPL(y,thebestinitvec,0); 61 | if any(abs(imag(stderrHESS))>0), stderrHESS=NaN(1,3); end 62 | if nargout>1, stderr=stderrHESS; end 63 | if nargout>1 && UseBootstrap 64 | Pmat=NaN(B,3); qq=param(1:2); pp=param(3); 65 | for b=1:B 66 | YY=simg(T,qq,pp,delta); Pmat(b,:) = normalGARCHPL(YY,param,0); 67 | end 68 | stderr=std(Pmat); 69 | end 70 | else % no use of profile (and also not bootstrap) 71 | if nargout>=4, resmat=[]; end 72 | if isempty(initvec), initvec=[0.02 0.02 0.9]; end 73 | lb=1e-5; ub=1-lb; 74 | if initvec(1)<=lb; initvec(1)=0.001; end 75 | if initvec(2)<=lb; initvec(2)=0.001; end 76 | if initvec(2)>=ub; initvec(2)=0.99; end 77 | if initvec(3)<=lb; initvec(3)=0.001; end 78 | if initvec(3)>=ub; initvec(3)=0.99; end 79 | % c_0 c_1 d_1 80 | bound.lo= [lb lb 0 ]; 81 | bound.hi= [1.2*max(var(y)) ub ub ]; 82 | bound.which= [1 1 1 ]; 83 | [pout,fval,~,~,~,hess]=fminunc(@(param) like2005(param),einschrk(initvec,bound),opt); 84 | V=pinv(hess)/(T*d); [param,V]=einschrk(pout,bound,V); 85 | stderr=sqrt(diag(V))'; loglik=-fval*(T*d); 86 | end 87 | 88 | function loglik=proflik(param,c) 89 | global y bound zvec sigvec 90 | theparam = einschrk(real(param),bound,999); 91 | param=[c theparam]; d=size(y,2); partloglik=zeros(1,d); 92 | logK=log(sqrt(2*pi)); 93 | for i=1:d 94 | [zvec,sigvec]=ungarch(y(:,i),param); 95 | ll=-0.5*(zvec.^2)-logK-log(sigvec); partloglik(i)=-mean(ll); 96 | end 97 | loglik=mean(partloglik); 98 | 99 | function loglik=like2005(param) 100 | global y bound zvec sigvec 101 | param = einschrk(real(param),bound,999); 102 | d=size(y,2); partloglik=zeros(1,d); logK=log(sqrt(2*pi)); 103 | for i=1:d 104 | [zvec,sigvec]=ungarch(y(:,i),param); 105 | ll =-0.5*(zvec.^2)-logK-log(sigvec); partloglik(i)=-mean(ll); 106 | end 107 | loglik=mean(partloglik); 108 | 109 | function y=simg(nobs,qq,pp,delta) 110 | % Input 111 | % qq is the ARCH component, pp is GARCH part, i.e., 112 | % qq= [omega alpha]; pp = [beta] 113 | % delta is the exponent in the GARCH equation, default of 2. 114 | % Output y is a Gaussian garch(1,1) series 115 | if nargin<6, delta=2; end 116 | warm=500; use=nobs+warm; 117 | s = rng; rng('shuffle'); z=randn(use+1,1); % get the z vector 118 | rng(s); 119 | h=zeros(use+1,1); e=zeros(use+1,1); omega=qq(1); qv=qq(2); pv=pp; 120 | h(1)=omega; e(1)=h(1)*z(1); 121 | for i=2:use+1 122 | h(i)=omega+ qv*( abs(e(i-1)) )^delta + pv*h(i-1); 123 | e(i)=( (h(i))^(1/delta) ) * z(i); 124 | end 125 | e=e(2:end); y=e(warm+1:use); 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/lib/ungarch.m: -------------------------------------------------------------------------------- 1 | function [eout,sigvec]=ungarch(epsi,garchin) 2 | global delta 3 | int=garchin(1); qterms=garchin(2); pterms=garchin(3); 4 | e=(abs(epsi)).^delta; 5 | lambda=( ( 2^(delta/2) ) / sqrt(pi) ) * gamma((delta+1)/2); 6 | 7 | % sinit = E[sigvec_0^delta], einit = E|e_0^delta| = lambda * sinit. 8 | sinit=mean((abs(epsi)).^delta); einit=lambda*sinit; 9 | 10 | % do the recursion in sigvec^delta 11 | sigvec=zeros(length(e),1); sigvec(1)=int+qterms*einit+pterms*sinit; 12 | 13 | for i=2:length(e), sigvec(i)=int + qterms*e(i-1) + pterms*sigvec(i-1); end 14 | if any(sigvec<=0), error('hello'), end 15 | 16 | sigvec=sigvec.^(1/delta); 17 | eout=epsi./sigvec; 18 | -------------------------------------------------------------------------------- /1 covariance estimation/Matlab/DCC1step_252/main.m: -------------------------------------------------------------------------------- 1 | addpath(genpath('lib')); % Import DCC-GARCH functions for 1-steap ahead prediction 2 | 3 | % load returns data 4 | returns = readtable('../../../0 data/CRSP/sp500_stock_ex_returns_demeaned_scaled.csv', 'ReadVariableNames',true); 5 | 6 | % extract data 7 | dates = returns{:, 1}; 8 | marketData = returns{:, 2}; 9 | stockData = returns(:, 3:end); 10 | 11 | windowSize = 252; 12 | subwindowSize = 1; 13 | from = find(returns.date == '2013-12-31') + 1; 14 | to = size(returns, 1); 15 | steps = to - from + 1; 16 | profile = 10; 17 | 18 | tic; 19 | 20 | parfor i=from:to 21 | tic; 22 | 23 | date = dates(i); 24 | 25 | fprintf('step %i of %i (%s) - ', i - from + 1, steps, date); 26 | 27 | % output directories 28 | outDir1 = sprintf('out/%s_pending', date); 29 | outDir2 = sprintf('out/%s', date); 30 | 31 | % delete _pending folder if it exists already 32 | if 7 == exist(outDir1, 'dir') 33 | rmdir(outDir1, 's'); 34 | end 35 | 36 | % skip if final output directory already exists 37 | if 7 == exist(outDir2, 'dir') 38 | % already computed - ignore this step 39 | fprintf('ignoring %s - already computed \n', date); 40 | 41 | if 7 == exist(outDir1, 'dir') 42 | rmdir(outDir1, 's'); 43 | end 44 | 45 | continue; 46 | end 47 | 48 | % create `pending` output directory 49 | [status,msg] = mkdir(outDir1); 50 | if status ~= 1 51 | fprintf('ERROR: Failed to create directory %s with message: %s \n', outDir1, msg); 52 | continue; 53 | end 54 | 55 | % extract window data 56 | windowStocksData = stockData((i - windowSize + 1):i, :); 57 | windowMarketData = marketData((i - windowSize + 1):i, :); 58 | 59 | % determine which columns have enough data (no NaNs) 60 | cols = arrayfun(@(x) x == size(windowStocksData, 1), sum(~isnan(windowStocksData{:,:}), 1)); 61 | 62 | % create matrix with columns which have no NaNs 63 | colIdxs = transpose(1:size(windowStocksData, 2)) .* transpose(cols); 64 | colIdxs = colIdxs(colIdxs > 0); 65 | windowStocksData = windowStocksData(:, colIdxs); 66 | stockCols = size(windowStocksData, 2); 67 | 68 | % fit DCC-GARCH in sub-samples 69 | fitSteps = ceil(stockCols / subwindowSize); 70 | 71 | varsMarket = array2table(nan(2, fitSteps), 'RowNames', cellstr({"estimated" "1stepahead"})); 72 | covsStocks = array2table(nan(2, stockCols), 'RowNames', cellstr({"estimated" "1stepahead"})); 73 | covsStocks.Properties.VariableNames = windowStocksData.Properties.VariableNames; 74 | 75 | for stepIdx = 1:fitSteps 76 | stepFrom = (stepIdx - 1) * subwindowSize + 1; 77 | stepTo = min(stepFrom + subwindowSize - 1, stockCols); 78 | stepData = [windowMarketData windowStocksData{:, stepFrom:stepTo}]; 79 | 80 | [~, SigmaT] = DCC1step(stepData, profile); 81 | 82 | % variance of univariate GARCH (sigma_m^2) 83 | varsMarket{2, stepIdx} = SigmaT(1, 1); 84 | 85 | % DCC conditional covariance (sigma_im^2) 86 | covsStocks{2, stepFrom:stepTo} = SigmaT(1, 2:end); 87 | 88 | if mod(stepIdx, 10) == 0 89 | fprintf(' %i of %i steps \n', stepIdx, fitSteps); 90 | end 91 | end 92 | 93 | % make sure all columns were fitted 94 | assert(sum(isnan(varsMarket{2, :})) == 0) 95 | assert(sum(isnan(covsStocks{2, :})) == 0) 96 | 97 | % save covariance matrix to output directory 98 | writetable(varsMarket, sprintf('%s/vars.market.csv', outDir1), 'Delimiter', ';', 'WriteRowNames', true); 99 | writetable(covsStocks, sprintf('%s/covs.stocks.csv', outDir1), 'Delimiter', ';', 'WriteRowNames', true); 100 | 101 | % rename directory (remove `_pending`) 102 | if 7 == exist(outDir2, 'dir') 103 | rmdir(outDir2, 's'); 104 | end 105 | 106 | % remove `_pending` suffix from output directory 107 | movefile(outDir1, outDir2); 108 | 109 | toc 110 | end 111 | 112 | fprintf('Total '); 113 | toc 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /1 covariance estimation/R/CAPM/capm.R: -------------------------------------------------------------------------------- 1 | library(data.table) 2 | library(rmgarch) 3 | library(doParallel) 4 | 5 | # load excess returns data 6 | fitData <- fread('../../../0 data/CRSP/sp500_stock_ex_returns.csv', header=T, sep=';') 7 | head(fitData[, 1:10], n=3) 8 | 9 | dates <- as.vector(fitData$date) 10 | market <- as.matrix(fitData[, 'market']) * 100 # percentage returns to avoid numerical issues 11 | stocks <- as.matrix(fitData[, !c('date', 'market')]) * 100 # percentage returns to avoid numerical issues 12 | stocks.cols <- colnames(stocks) 13 | 14 | head(dates, n=3) 15 | head(market, n=3) 16 | head(stocks[, 1:10], n=3) 17 | 18 | 19 | # rolling window configuration 20 | windowSize <- 252 21 | from <- which(dates %in% '1996-01-02') 22 | to <- which(dates %in% '2013-12-31') 23 | steps <- to - from + 1 24 | 25 | 26 | # function to compute estimated and forecasted covariances 27 | computeStep <- function(i) { 28 | # latest date for window 29 | date <- dates[i] 30 | 31 | # output directories 32 | outDir1 <- paste0('out/', date, '_pending') 33 | outDir2 <- paste0('out/', date) 34 | 35 | # delete _pending folder if it exists already 36 | if (dir.exists(outDir1)) 37 | unlink(outDir1, recursive=T, force=T) 38 | 39 | # skip if final output directory already exists 40 | if (dir.exists(outDir2)) { 41 | # already computed - ignore this step 42 | cat('ignoring ', date, '- already computed \n') 43 | 44 | if (dir.exists(outDir1)) 45 | unlink(outDir1, recursive=T, force=T) 46 | 47 | return(T) 48 | } 49 | 50 | dir.create(outDir1, recursive=T, showWarnings=F) 51 | 52 | # start timer 53 | cat(paste('step', i - from + 1, 'of', steps, '(', date, ')')) 54 | 55 | # extract window data 56 | fit.market <- market[(i - windowSize + 1):i, ] 57 | fit.stocks <- stocks[(i - windowSize + 1):i, ] 58 | 59 | # omit columns in window with NA values 60 | fit.stocks <- fit.stocks[, colSums(is.na(fit.stocks)) == 0] 61 | 62 | # Fama-French market excess returns variances 63 | vars.market <- matrix(NA, nrow=2, ncol=1, dimnames=list(c('estimated', '1stepahead'), c('median'))) 64 | 65 | # market to stocks covariances 66 | covs <- matrix(NA, nrow=2, ncol=ncol(fit.stocks), dimnames=list(c('estimated', '1stepahead'), colnames(fit.stocks))) 67 | 68 | # stock variances 69 | vars.stocks <- matrix(NA, nrow=2, ncol=ncol(fit.stocks), dimnames=list(c('estimated', '1stepahead'), colnames(fit.stocks))) 70 | 71 | for (step in 1:ncol(fit.stocks)) { 72 | # calculate covariance matrix 73 | estimated.covs <- cov(cbind(fit.market, fit.stocks[, step])) 74 | 75 | # save results 76 | vars.market['estimated', 'median'] <- estimated.covs[1, 1] 77 | vars.market['1stepahead', 'median'] <- estimated.covs[1, 1] 78 | 79 | vars.stocks['estimated', step] <- estimated.covs[2, 2] 80 | vars.stocks['1stepahead', step] <- estimated.covs[2, 2] 81 | 82 | covs['estimated', step] <- estimated.covs[1, 2] 83 | covs['1stepahead', step] <- estimated.covs[1, 2] 84 | } 85 | 86 | fwrite(as.data.frame(vars.market), paste0(outDir1, '/vars.market.csv'), sep=';', row.names=T) 87 | fwrite(as.data.frame(vars.stocks), paste0(outDir1, '/vars.stocks.csv'), sep=';', row.names=T) 88 | fwrite(as.data.frame(covs), paste0(outDir1, '/covs.stocks.csv'), sep=';', row.names=T) 89 | 90 | # rename directory (remove `_pending`) 91 | if (dir.exists(outDir2)) 92 | unlink(outDir2, recursive=T, force=T) 93 | 94 | file.rename(outDir1, outDir2) 95 | 96 | return(T) 97 | } 98 | 99 | 100 | # create parallel cluster 101 | cl <- makeCluster(detectCores(), outfile='parallel-log.txt') 102 | registerDoParallel(cl, cores=detectCores()) 103 | 104 | predictedCovs <- foreach(i=from:to, .packages=c('rmgarch', 'data.table'), .verbose=F) %dopar% { 105 | computeStep(i) 106 | } 107 | 108 | stopCluster(cl) 109 | 110 | 111 | # for (i in from:to) { 112 | # computeStep(i) 113 | # } 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /1 covariance estimation/R/CAPM/consolidate.R: -------------------------------------------------------------------------------- 1 | library(data.table) 2 | 3 | source('../../../functions.R') 4 | 5 | consolidated.path <- './consolidated' 6 | out.path <- './out' 7 | returns.path <- '../../../0 data/CRSP/sp500_stock_ex_returns.csv' 8 | 9 | 10 | path.out.make <- function(date, file) { 11 | paste0(out.path, '/', date, '/', file) 12 | } 13 | 14 | path.consolidated.make <- function(file) { 15 | paste0(consolidated.path, '/', file) 16 | } 17 | 18 | 19 | # load excess returns data 20 | returns <- fread(returns.path, header=T, sep=';') 21 | head(returns[, 1:20], n=3) 22 | 23 | 24 | # extract all computed dates 25 | dates.all <- list.dirs(path=out.path, full.names=F, recursive=F) 26 | dates <- Filter(function(x) nchar(x) == 10, dates.all) # ignore pending entries 27 | dates <- sort(dates) 28 | 29 | 30 | # read files of interest 31 | covs.cols <- colnames(returns)[-c(1:2)] 32 | 33 | covs.estimated <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), covs.cols)) 34 | covs.1stepahead <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), covs.cols)) 35 | 36 | vars.estimated.stocks <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), covs.cols)) 37 | vars.1stepahead.stocks <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), covs.cols)) 38 | 39 | vars.estimated.market <- matrix(NA, nrow=length(dates), ncol=1, dimnames=list(c(), c('median'))) 40 | vars.1stepahead.market <- matrix(NA, nrow=length(dates), ncol=1, dimnames=list(c(), c('median'))) 41 | 42 | for (i in 1:length(dates)) { 43 | date <- dates[i] 44 | 45 | 46 | # covariances 47 | tmp.covs.stocks <- first.col.2.rownames(fread(path.out.make(date, 'covs.stocks.csv'), header=T, sep=';', data.table=F)) 48 | tmp.covs.cols <- colnames(tmp.covs.stocks) 49 | 50 | # covs.estimated 51 | covs.estimated[i, tmp.covs.cols] <- unlist(tmp.covs.stocks['estimated', ]) 52 | 53 | # covs.1stepahead 54 | covs.1stepahead[i, tmp.covs.cols] <- unlist(tmp.covs.stocks['1stepahead', ]) 55 | 56 | 57 | 58 | # stock variances 59 | tmp.vars.stocks <- first.col.2.rownames(fread(path.out.make(date, 'vars.stocks.csv'), header=T, sep=';', data.table=F)) 60 | tmp.vars.cols <- colnames(tmp.vars.stocks) 61 | 62 | # vars.estimated.stocks 63 | vars.estimated.stocks[i, tmp.vars.cols] <- unlist(tmp.vars.stocks['estimated', ]) 64 | 65 | # vars.1stepahead.stocks 66 | vars.1stepahead.stocks[i, tmp.vars.cols] <- unlist(tmp.vars.stocks['1stepahead', ]) 67 | 68 | 69 | # market variances 70 | tmp.vars.market <- fread(path.out.make(date, 'vars.market.csv'), header=T, sep=';', data.table=F) 71 | 72 | # vars.estimated.market 73 | vars.estimated.market[i, 'median'] <- tmp.vars.market[1, 'median'] 74 | 75 | # vars.1stepahead.market 76 | vars.1stepahead.market[i, 'median'] <-tmp.vars.market[2, 'median'] 77 | 78 | 79 | # log progress 80 | if (i %% 50 == 0) 81 | cat(date, format(round(100.0 * i / length(dates), 1), nsmall=1), '% \n') 82 | } 83 | 84 | # add date as first column 85 | covs.estimated <- cbind(data.table(date=dates), covs.estimated) 86 | covs.1stepahead <- cbind(data.table(date=dates), covs.1stepahead) 87 | vars.estimated.stocks <- cbind(data.table(date=dates), vars.estimated.stocks) 88 | vars.1stepahead.stocks <- cbind(data.table(date=dates), vars.1stepahead.stocks) 89 | vars.estimated.market <- cbind(data.table(date=dates), vars.estimated.market) 90 | vars.1stepahead.market <- cbind(data.table(date=dates), vars.1stepahead.market) 91 | 92 | 93 | # write consolidated data to disk 94 | if (!dir.exists(consolidated.path)) 95 | dir.create(consolidated.path) 96 | 97 | # covs.estimated.csv 98 | fwrite(covs.estimated, path.consolidated.make('covs.estimated.csv'), sep=';') 99 | 100 | # covs.1stepahead.csv 101 | fwrite(covs.1stepahead, path.consolidated.make('covs.1stepahead.csv'), sep=';') 102 | 103 | # vars.estimated.stocks.csv 104 | fwrite(vars.estimated.stocks, path.consolidated.make('vars.estimated.stocks.csv'), sep=';') 105 | 106 | # vars.1stepahead.stocks.csv 107 | fwrite(vars.1stepahead.stocks, path.consolidated.make('vars.1stepahead.stocks.csv'), sep=';') 108 | 109 | # vars.estimated.market.csv 110 | fwrite(vars.estimated.market, path.consolidated.make('vars.estimated.market.csv'), sep=';') 111 | 112 | # vars.1stepahead.market.csv 113 | fwrite(vars.1stepahead.market, path.consolidated.make('vars.1stepahead.market.csv'), sep=';') 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /1 covariance estimation/R/DCC-GARCH/consolidate.R: -------------------------------------------------------------------------------- 1 | library(data.table) 2 | 3 | source('../../../functions.R') 4 | 5 | consolidated.path <- './consolidated' 6 | out.path <- './out' 7 | returns.path <- '../../../0 data/CRSP/ex_returns.csv' 8 | 9 | 10 | path.out.make <- function(date, file) { 11 | paste0(out.path, '/', date, '/', file) 12 | } 13 | 14 | path.consolidated.make <- function(file) { 15 | paste0(consolidated.path, '/', file) 16 | } 17 | 18 | 19 | # load excess returns data 20 | returns <- fread(returns.path, header=T, sep=';') 21 | head(returns[, 1:20], n=3) 22 | 23 | 24 | # extract all computed dates 25 | dates.all <- list.dirs(path=out.path, full.names=F, recursive=F) 26 | dates <- Filter(function(x) nchar(x) == 10, dates.all) # ignore pending entries 27 | dates <- sort(dates) 28 | 29 | 30 | # read files of interest 31 | covs.cols <- colnames(returns)[-c(1:2)] 32 | 33 | covs.estimated <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), covs.cols)) 34 | covs.1stepahead <- matrix(NA, nrow=length(dates), ncol=ncol(returns) - 2, dimnames=list(c(), covs.cols)) 35 | 36 | vars.estimated.market <- matrix(NA, nrow=length(dates), ncol=1, dimnames=list(c(), c('market'))) 37 | vars.1stepahead.market <- matrix(NA, nrow=length(dates), ncol=1, dimnames=list(c(), c('market'))) 38 | 39 | infos <- matrix(NA, nrow=length(dates), ncol=2, dimnames=list(c(), c('errors', 'runtime'))) 40 | infocriterias.akaike <- matrix(NA, nrow=length(dates), ncol=500, dimnames=list(c(), 1:500)) 41 | infocriterias.bayes <- matrix(NA, nrow=length(dates), ncol=500, dimnames=list(c(), 1:500)) 42 | 43 | coefs.dcc.market.cols <- c( 44 | 'dcca1', 'dccb1', 45 | '[market].mu', '[market].omega', '[market].alpha1', '[market].beta1') 46 | coefs.dcc.market <- matrix(NA, nrow=length(dates), ncol=2 + 1 * 4, dimnames=list(c(), coefs.dcc.market.cols)) 47 | 48 | # [PERMNO].mu, [PERMNO].omega, [PERMNO].alpha1, [PERMNO].beta1 49 | coefs.stocks.cols <- c(apply(as.matrix(covs.cols), 1, function(x) c(paste0('[', x, '].mu'), paste0('[', x, '].omega'), paste0('[', x, '].alpha1'), paste0('[', x, '].beta1')))) 50 | coefs.stocks <- matrix(NA, nrow=length(dates), ncol=length(coefs.stocks.cols), dimnames=list(c(), coefs.stocks.cols)) 51 | 52 | for (i in 1:length(dates)) { 53 | date <- dates[i] 54 | 55 | 56 | # covariances 57 | tmp.covs.stocks <- first.col.2.rownames(fread(path.out.make(date, 'covs.stocks.csv'), header=T, sep=';', data.table=F)) 58 | tmp.covs.cols <- colnames(tmp.covs.stocks) 59 | 60 | # covs.estimated 61 | covs.estimated[i, tmp.covs.cols] <- unlist(tmp.covs.stocks['estimated', ]) 62 | 63 | # covs.1stepahead 64 | covs.1stepahead[i, tmp.covs.cols] <- unlist(tmp.covs.stocks['1stepahead', ]) 65 | 66 | 67 | # variances 68 | tmp.vars.market <- first.col.2.rownames(fread(path.out.make(date, 'vars.market.csv'), header=T, sep=';', data.table=F)) 69 | 70 | # vars.estimated 71 | vars.estimated.market[i, 'market'] <- median(unlist(tmp.vars.market['estimated', ]), na.rm=T) 72 | 73 | # vars.1stepahead 74 | vars.1stepahead.market[i, 'market'] <- median(unlist(tmp.vars.market['1stepahead', ]), na.rm=T) 75 | 76 | 77 | # coefs.dcc.market 78 | tmp.coefs.dcc.market <- fread(path.out.make(date, 'coefs.dcc.market.csv'), header=T, sep=';', data.table=F) 79 | coefs.dcc.market[i, ] <- colMeans(tmp.coefs.dcc.market) 80 | 81 | # coefs.stocks 82 | tmp.coefs.stocks <- fread(path.out.make(date, 'coefs.stocks.csv'), header=T, sep=';', data.table=F) 83 | coefs.stocks[i, colnames(tmp.coefs.stocks)] <- unlist(tmp.coefs.stocks[1, ]) 84 | 85 | 86 | # info 87 | tmp.info <- fread(path.out.make(date, 'info.csv'), header=T, sep=';', data.table=F) 88 | infos[i, ] <- unlist(tmp.info[1, ]) 89 | 90 | # infocriteris 91 | tmp.ic <- fread(path.out.make(date, 'infocriterias.csv'), header=T, sep=';', data.table=F) 92 | infocriterias.akaike[i, 1:nrow(tmp.ic)] <- unlist(tmp.ic[, 'Akaike']) 93 | infocriterias.bayes[i, 1:nrow(tmp.ic)] <- unlist(tmp.ic[, 'Bayes']) 94 | 95 | 96 | # log progress 97 | if (i %% 50 == 0) 98 | cat(date, format(round(100.0 * i / length(dates), 1), nsmall=1), '% \n') 99 | } 100 | 101 | # add date as first column 102 | covs.estimated <- cbind(data.table(date=dates), covs.estimated) 103 | covs.1stepahead <- cbind(data.table(date=dates), covs.1stepahead) 104 | vars.estimated.market <- cbind(data.table(date=dates), vars.estimated.market) 105 | vars.1stepahead.market <- cbind(data.table(date=dates), vars.1stepahead.market) 106 | infos <- cbind(data.table(date=dates), infos) 107 | coefs.dcc.market <- cbind(data.table(date=dates), coefs.dcc.market) 108 | coefs.stocks <- cbind(data.table(date=dates), coefs.stocks) 109 | infocriterias.akaike <- cbind(data.table(date=dates), infocriterias.akaike) 110 | infocriterias.bayes <- cbind(data.table(date=dates), infocriterias.bayes) 111 | 112 | 113 | # write consolidated data to disk 114 | if (!dir.exists(consolidated.path)) 115 | dir.create(consolidated.path) 116 | 117 | # covs.estimated.csv 118 | fwrite(covs.estimated, path.consolidated.make('covs.estimated.csv'), sep=';') 119 | 120 | # covs.1stepahead.csv 121 | fwrite(covs.1stepahead, path.consolidated.make('covs.1stepahead.csv'), sep=';') 122 | 123 | # vars.estimated.market.csv 124 | fwrite(vars.estimated.market, path.consolidated.make('vars.estimated.market.csv'), sep=';') 125 | 126 | # vars.1stepahead.market.csv 127 | fwrite(vars.1stepahead.market, path.consolidated.make('vars.1stepahead.market.csv'), sep=';') 128 | 129 | # infos.csv 130 | fwrite(infos, path.consolidated.make('infos.csv'), sep=';') 131 | 132 | # coefs.dcc.market.csv 133 | fwrite(coefs.dcc.market, path.consolidated.make('coefs.dcc.market.csv'), sep=';') 134 | 135 | # coefs.stocks.csv 136 | fwrite(coefs.stocks, path.consolidated.make('coefs.stocks.csv'), sep=';') 137 | 138 | # infocriterias.akaike.csv 139 | fwrite(infocriterias.akaike, path.consolidated.make('infocriterias.akaike.csv'), sep=';') 140 | 141 | # infocriterias.bayes.csv 142 | fwrite(infocriterias.bayes, path.consolidated.make('infocriterias.bayes.csv'), sep=';') 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /1 covariance estimation/R/DCC-GARCH/submit.sh: -------------------------------------------------------------------------------- 1 | bsub -R "rusage[mem=1024]" -n 48 -W 24:00 "Rscript main.R > log.txt" -------------------------------------------------------------------------------- /1 covariance estimation/R/DCC-GARCH/zip.sh: -------------------------------------------------------------------------------- 1 | zip -r -q out.zip out -------------------------------------------------------------------------------- /1 covariance estimation/R/merge.R: -------------------------------------------------------------------------------- 1 | out1.path <- 'out' 2 | out2.path <- 'out.euler/out' 3 | merged.path <- 'out.merged' 4 | 5 | 6 | # extract all computed dates 7 | out1.dirs <- list.dirs(path=out1.path, full.names=F, recursive=F) 8 | out2.dirs <- list.dirs(path=out2.path, full.names=F, recursive=F) 9 | 10 | # ignore pending entries 11 | out1.dirs <- Filter(function(dir) nchar(dir) == 10, out1.dirs) 12 | out2.dirs <- Filter(function(dir) nchar(dir) == 10, out2.dirs) 13 | 14 | # ignore empty folders 15 | out1.dirs <- Filter(function(dir) length(list.files(paste0(out1.path, '/', dir), all.files=T, full.names=F, no..=T)) > 0, out1.dirs) 16 | out2.dirs <- Filter(function(dir) length(list.files(paste0(out2.path, '/', dir), all.files=T, full.names=F, no..=T)) > 0, out2.dirs) 17 | out1.dirs <- out1.dirs[!out1.dirs %in% out2.dirs] # no overlapping dates 18 | 19 | # create output directory 20 | if (dir.exists(merged.path)) 21 | unlink(merged.path, recursive=T, force=T) 22 | dir.create(merged.path, recursive=T, showWarnings=T) 23 | 24 | # start merge process... 25 | cat(length(out1.dirs), 'entries in', out1.path, '\n') 26 | cat(length(out2.dirs), 'entries in', out2.path, '\n') 27 | cat('Merging to', merged.path, '...\n') 28 | 29 | 30 | cat('Processing folder', out1.path, '... \n') 31 | for (i in 1:length(out1.dirs)) { 32 | out1.dir <- out1.dirs[i] 33 | 34 | from <- paste0(out1.path, '/', out1.dir) 35 | to <- paste0(merged.path, '/', out1.dir) 36 | 37 | file.rename(from, to) 38 | 39 | # log progress 40 | if (i %% 200 == 0) 41 | cat(format(round(100.0 * i / length(out1.dirs), 1), nsmall=1), '% \n') 42 | } 43 | 44 | rm(out1.dir) 45 | rm(from) 46 | rm(to) 47 | 48 | 49 | cat('Processing folder', out2.path, '... \n') 50 | for (i in 1:length(out2.dirs)) { 51 | out2.dir <- out2.dirs[i] 52 | 53 | from <- paste0(out2.path, '/', out2.dir) 54 | to <- paste0(merged.path, '/', out2.dir) 55 | 56 | file.rename(from, to) 57 | 58 | # log progress 59 | if (i %% 200 == 0) 60 | cat(format(round(100.0 * i / length(out2.dirs), 1), nsmall=1), '% \n') 61 | } 62 | 63 | rm(out2.dir) 64 | rm(from) 65 | rm(to) 66 | 67 | 68 | cat('Finished.\n') 69 | 70 | -------------------------------------------------------------------------------- /1 covariance estimation/R/sub-sampling analysis/sub-sampling analysis.R: -------------------------------------------------------------------------------- 1 | library(data.table) 2 | library(rmgarch) 3 | library(doParallel) 4 | library(tictoc) 5 | library(graphics) 6 | 7 | returns <- fread('../../../0 data/CRSP/excess_returns.csv', header=T) 8 | 9 | # remove date 10 | returns <- as.matrix(returns[, -c(1)]) 11 | 12 | # demean data 13 | returns <- sweep(returns, 2, apply(returns, 2, function(x) mean(x, na.rm=T))) 14 | 15 | # scale to avoid numerical optimization issues (convergence) 16 | returns <- returns * 1000 17 | 18 | 19 | 20 | for (wnd in 1:5) { 21 | 22 | # get one random window 23 | pos <- as.integer(runif(1, min=1, max=nrow(returns) - 1000)) 24 | data <- as.matrix(returns[pos:(pos + 252 - 1), ]) 25 | 26 | # omit columns with NAs 27 | data <- data[, colSums(is.na(data)) == 0] 28 | 29 | 30 | # extract market and one fixed asset time series 31 | market <- data[, 1] 32 | assetX <- data[, ncol(data)] 33 | 34 | data <- data[, 2:(ncol(data)-1)] 35 | 36 | 37 | 38 | # DCC-GARCH model 39 | uspec2 <- ugarchspec(mean.model=list(armaOrder=c(0, 0), include.mean=F), variance.model=list(model="sGARCH", garchOrder=c(1, 1), variance.targeting=F), distribution.model="norm") 40 | 41 | steps.calc <- function(n, size) { 42 | ceiling(n / size) 43 | } 44 | 45 | stepSizes <- c(8, 16, 32, 48, 64, 96, 128) 46 | coefsA1 <- matrix(NA, ncol=steps.calc(ncol(data), min(stepSizes)), nrow=length(stepSizes)) 47 | coefsA2 <- matrix(NA, ncol=steps.calc(ncol(data), min(stepSizes)), nrow=length(stepSizes)) 48 | vars <- matrix(NA, ncol=steps.calc(ncol(data), min(stepSizes)), nrow=length(stepSizes)) 49 | covars <- matrix(NA, ncol=steps.calc(ncol(data), min(stepSizes)), nrow=length(stepSizes)) 50 | times <- rep(0, length(stepSizes)) 51 | 52 | for (i in 1:length(stepSizes)) { 53 | stepSize <- stepSizes[i] 54 | steps <- steps.calc(ncol(data), stepSize) 55 | 56 | cat(sprintf("\nstep size: %i (%i steps) \n", stepSize, steps)) 57 | 58 | tic('time') 59 | 60 | for (step in 1:steps) { 61 | cat(sprintf("%i ", step)) 62 | 63 | from <- (step - 1) * stepSize + 1 64 | to <- min(from + stepSize - 1, ncol(data)) 65 | 66 | fitData <- cbind(market, assetX, data[, from:to]) 67 | 68 | # fit 69 | spec <- dccspec(uspec=multispec(replicate(ncol(fitData), uspec2)), dccOrder=c(1, 1), distribution="mvnorm") 70 | fit <- dccfit(data=fitData, spec=spec, solver=c('hybrid', 'solnp'), fit.control=list(eval.se=F, scale=F)) 71 | # nlminb 72 | 73 | coefsA1[i, step] <- coef(fit)['[Joint]dcca1'] 74 | coefsA2[i, step] <- coef(fit)['[Joint]dccb1'] 75 | 76 | # one-step ahead forecast 77 | forecast <- dccforecast(fit, n.ahead=1, n.roll=0) 78 | 79 | 80 | # returns the time-varying NxN covariance matrix in array format 81 | H <- rcov(forecast)[[1]][,,1] 82 | 83 | vars[i, step] <- H[1,1] # DCC variance 84 | covars[i, step] <- H[1,2] # DCC covariance 85 | 86 | # R <- rcor(forecast)[[1]][,,1] 87 | # forecast@model$sigma[1,1]^2 # univariate GARCH variance 88 | } 89 | 90 | time <- toc() 91 | time 92 | 93 | times[i] <- time$toc - time$tic 94 | 95 | cat('\n') 96 | } 97 | 98 | 99 | 100 | cols <- 2:(2+length(stepSizes)) 101 | leg <- apply(as.matrix(stepSizes), 1, function(x) paste0('sub-sample size=', x)) 102 | 103 | 104 | par(mfrow=c(2,2)) 105 | matplot(t(coefsA1), type='o', ylim=c(0, 1), col=cols, main=expression('DCC coefficient a'[1]), ylab=expression('a'[1]), xlab="step") 106 | legend('topleft', legend=leg, col=cols, fill=cols, cex=1, pt.cex=1.2, box.lty=0, bg='transparent', inset=0) 107 | 108 | matplot(t(coefsA2), type='o', ylim=c(0, 1), col=cols, main=expression('DCC coefficient a'[2]), ylab=expression('a'[2]), xlab="step") 109 | legend('bottomleft', legend=leg, col=cols, fill=cols, cex=1, pt.cex=1.2, box.lty=0, bg='transparent', inset=0) 110 | 111 | matplot(t(vars), type='o', ylim=c(0, 65), col=cols, main='market variance', xlab="step") 112 | legend('bottomleft', legend=leg, col=cols, fill=cols, cex=1, pt.cex=1.2, box.lty=0, bg='transparent', inset=0) 113 | 114 | matplot(t(covars), type='o', ylim=c(0, 65), col=cols, main='market-assetX covariance', xlab="step") 115 | legend('bottomleft', legend=leg, col=cols, fill=cols, cex=1, pt.cex=1.2, box.lty=0, bg='transparent', inset=0) 116 | 117 | par(mfrow=c(1,1)) 118 | plot(stepSizes, times/60, type='l', ylim=c(0, max(times/60)), col=cols, xlab='number of assets (columns) in sub-sample', ylab="runtime in minutes", main="runtimes per 252x472 window of different step sizes") 119 | 120 | } 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /1 covariance estimation/R/sub-sampling analysis/sub-sampling coefficients and variance.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/R/sub-sampling analysis/sub-sampling coefficients and variance.pdf -------------------------------------------------------------------------------- /1 covariance estimation/R/sub-sampling analysis/sub-sampling runtimes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/R/sub-sampling analysis/sub-sampling runtimes.pdf -------------------------------------------------------------------------------- /1 covariance estimation/analysis/analysis.R: -------------------------------------------------------------------------------- 1 | library(data.table) 2 | library(grDevices) 3 | library(tikzDevice) 4 | 5 | source('../../functions.R') 6 | 7 | out.dir <- 'output/' 8 | 9 | covs.stocks.DCC1step <- remove.colnames.prefixes(fread('../Matlab/DCC1step/consolidated/covs.1stepahead.csv', header=T, sep=';'), 'x') 10 | vars.market.DCC1step <- remove.colnames.prefixes(fread('../Matlab/DCC1step/consolidated/vars.1stepahead.market.csv', header=T, sep=';'), 'x') 11 | covs.stocks.COMFORT.memless <- remove.colnames.prefixes(fread('../Matlab/COMFORT-DCC/consolidated/covs.1stepahead.csv', header=T, sep=';'), 'x') 12 | vars.market.COMFORT.memless <- remove.colnames.prefixes(fread('../Matlab/COMFORT-DCC/consolidated/vars.1stepahead.market.csv', header=T, sep=';'), 'x') 13 | 14 | dates <- intersect(covs.stocks.COMFORT.memless$date, covs.stocks.DCC1step$date) 15 | 16 | covs.stocks.DCC1step <- covs.stocks.DCC1step[which(covs.stocks.DCC1step$date %in% dates), ] 17 | vars.market.DCC1step <- vars.market.DCC1step[which(vars.market.DCC1step$date %in% dates), ] 18 | 19 | covs.stocks.COMFORT.memless <- covs.stocks.COMFORT.memless[which(covs.stocks.COMFORT.memless$date %in% dates), ] 20 | vars.market.COMFORT.memless <- vars.market.COMFORT.memless[which(vars.market.COMFORT.memless$date %in% dates), ] 21 | 22 | covs.stocks.DCC1step <- covs.stocks.DCC1step[, !"date", with=F] 23 | vars.market.DCC1step <- vars.market.DCC1step[, !"date", with=F] 24 | 25 | covs.stocks.COMFORT.memless <- covs.stocks.COMFORT.memless[, !"date", with=F] 26 | vars.market.COMFORT.memless <- vars.market.COMFORT.memless[, !"date", with=F] 27 | 28 | 29 | plot.idxs <- which(colSums(!is.na(covs.stocks.COMFORT.memless)) > 0) 30 | plot.cols <- colnames(covs.stocks.COMFORT.memless)[plot.idxs] 31 | 32 | stocks.estimation.errors <- c('59176', '59408', '66800', '68144', 33 | '71563', '82775', '84129', '86314') 34 | 35 | plot.cols <- stocks.estimation.errors 36 | 37 | 38 | pdf(paste0(out.dir, 'beta_SP500_stocks.pdf')) 39 | 40 | par(mfrow=c(1,1)) 41 | par(mar=c(5, 3, 3, 2.1)) 42 | 43 | labels <- sapply(dates, function(d) format(as.Date(d), '%m.%Y')) 44 | years <- unique(labels) 45 | years.month <- paste0('01.', years) 46 | at <- c(seq(from=1, to=nrow(covs.stocks.DCC1step)-1, by=nrow(covs.stocks.DCC1step) / 10), nrow(covs.stocks.DCC1step)) 47 | labels <- labels[at] 48 | 49 | for (p in plot.cols) { 50 | beta.DCC1step <- as.matrix(covs.stocks.DCC1step[, ..p]) / as.matrix(vars.market.DCC1step$median) 51 | beta.COMFORT.median <- as.matrix(covs.stocks.COMFORT.memless[, ..p]) / as.matrix(vars.market.COMFORT.memless$median) 52 | p.data <- cbind(beta.DCC1step, beta.COMFORT.median) 53 | 54 | cols <- c('red', adjustcolor('blue', alpha.f=.4)) 55 | matplot(p.data, type='l', xaxt='n', lty=1, lwd=0.25, xaxs='i', col=cols, main=paste0('Beta of S&P 500 stock #', p, ' with market')) 56 | axis(1, at=at, labels=labels, cex.axis=.7, tck=-0.03) 57 | grid(length(labels)-1, NA, lty=1, col=adjustcolor('gray', alpha.f=.4)) 58 | legend('topleft', legend=c('DCC-GARCH', 'COMFORT-DCC'), col=cols, lty=1, cex=.7, bg="transparent", bty='n') 59 | } 60 | 61 | dev.off() 62 | 63 | 64 | 65 | 66 | 67 | 68 | pdf(paste0(out.dir, 'covariance_SP500_stocks_with_market.pdf')) 69 | 70 | par(mfrow=c(1,1)) 71 | par(mar=c(5, 3, 3, 2.1)) 72 | 73 | labels <- sapply(dates, function(d) format(as.Date(d), '%m.%Y')) 74 | years <- unique(labels) 75 | years.month <- paste0('01.', years) 76 | at <- c(seq(from=1, to=nrow(covs.stocks.DCC1step)-1, by=nrow(covs.stocks.DCC1step) / 10), nrow(covs.stocks.DCC1step)) 77 | labels <- labels[at] 78 | 79 | stocks <- c() 80 | 81 | for (p in plot.cols) { 82 | data.plot.DCC1step <- as.matrix(covs.stocks.DCC1step[, ..p]) 83 | data.plot.COMFORT.memless <- as.matrix(covs.stocks.COMFORT.memless[, ..p]) 84 | 85 | cols <- c( adjustcolor('blue', alpha.f=.8), adjustcolor('red', alpha.f=.6)) 86 | matplot(cbind(data.plot.DCC1step, data.plot.COMFORT.memless), type='l', xaxt='n', ylab='', lty=1, lwd=0.25, xaxs='i', 87 | col=cols, main=paste0('Covariance of S&P 500 stock #', p, ' with market')) 88 | axis(1, at=at, labels=labels, cex.axis=.7, tck=-0.03) 89 | legend('topleft', legend=c('DCC-GARCH', 'COMFORT-DCC'), col=cols, lty=1, cex=.8, bg="transparent", bty='n') 90 | legend('top', legend=c(paste0('PERMNO ', p)), bty='n') 91 | 92 | # action <- readline(prompt="Consider stock? (0=yes, X=no) ") 93 | # if (as.integer(action) == 1) { 94 | # stocks <- c(stocks, p) 95 | # } 96 | } 97 | 98 | dev.off() 99 | 100 | 101 | 102 | # .tex output 103 | tikz(file=paste0(out.dir, 'erroneous_covariances.tex'), width=6, height=7.5) 104 | 105 | par.orig <- par(no.readonly=T) 106 | 107 | par(mfrow=c(4, 2), mar=c(0, 0, 0, 0)) 108 | 109 | labels <- sapply(dates, function(d) format(as.Date(d), '%m.%Y')) 110 | years <- unique(labels) 111 | years.month <- paste0('01.', years) 112 | at <- c(seq(from=1, to=nrow(covs.stocks.DCC1step)-1, by=nrow(covs.stocks.DCC1step) / 10), nrow(covs.stocks.DCC1step)) 113 | labels <- labels[at] 114 | 115 | stocks <- c() 116 | 117 | 118 | for (p in plot.cols) { 119 | data.plot.DCC1step <- as.matrix(covs.stocks.DCC1step[, ..p]) 120 | data.plot.COMFORT.memless <- as.matrix(covs.stocks.COMFORT.memless[, ..p]) 121 | 122 | cols <- c( adjustcolor('blue', alpha.f=.8), adjustcolor('red', alpha.f=.6)) 123 | matplot(cbind(data.plot.DCC1step, data.plot.COMFORT.memless), type='l', xaxt='n', yaxt='n', ylab='', lty=1, lwd=0.25, col=cols, xaxs='i') 124 | legend('topleft', legend=c('DCC-GARCH', 'COMFORT-DCC'), col=cols, lty=1, cex=1, bg="transparent", bty='n') 125 | legend('top', legend=c(paste0('PERMNO ', p)), bty='n', cex=1.1) 126 | } 127 | 128 | dev.off() 129 | 130 | par(par.orig) 131 | 132 | 133 | 134 | pdf(paste0(out.dir, 'variance_Fama-French_market.pdf')) 135 | 136 | par(mfrow=c(1,1)) 137 | par(mar=c(5, 3, 3, 2.1)) 138 | 139 | labels <- sapply(dates, function(d) format(as.Date(d), '%m.%Y')) 140 | years <- unique(labels) 141 | years.month <- paste0('01.', years) 142 | at <- c(seq(from=1, to=nrow(data.plot.DCC1step)-1, by=nrow(data.plot.DCC1step) / 10), nrow(data.plot.DCC1step)) 143 | labels <- labels[at] 144 | 145 | data.plot.DCC1step <- as.matrix(vars.market.DCC1step[, 'median']) 146 | data.plot.COMFORT.memless <- as.matrix(vars.market.COMFORT.memless[, 'median']) 147 | 148 | cols <- c('red', adjustcolor('blue', alpha.f=.4), adjustcolor('black', alpha.f=.4)) 149 | 150 | # plot full ylim 151 | matplot(cbind(data.plot.DCC1step, data.plot.COMFORT.memless), type='l', xaxt='n', main=paste0('Variance of market (Fama-French)'), 152 | lty=1, lwd=0.25, xaxs='i', col=cols) 153 | axis(1, at=at, labels=labels, cex.axis=.7, tck=-0.03) 154 | grid(length(labels)-1, NA, lty=1, col=adjustcolor('gray', alpha.f=.4)) 155 | legend('topleft', legend=c('DCC-GARCH', 'COMFORT memoryless'), col=cols, lty=1, cex=.7, bg="transparent", bty='n') 156 | 157 | dev.off() 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /1 covariance estimation/analysis/output/beta_SP500_stocks.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/analysis/output/beta_SP500_stocks.pdf -------------------------------------------------------------------------------- /1 covariance estimation/analysis/output/covariance_SP500_stocks_with_market.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/analysis/output/covariance_SP500_stocks_with_market.pdf -------------------------------------------------------------------------------- /1 covariance estimation/analysis/output/variance_Fama-French_market.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/1 covariance estimation/analysis/output/variance_Fama-French_market.pdf -------------------------------------------------------------------------------- /1 covariance estimation/analysis/runtimes/runtimes.R: -------------------------------------------------------------------------------- 1 | library(readr) 2 | library(stringr) 3 | library(stargazer) 4 | 5 | 6 | log <- read_file('log_COMFORT-DCC.txt') 7 | matches <- str_match_all(log, 'estimated in ([0-9]+) min ([0-9]+) sec')[[1]] 8 | 9 | mins <- as.numeric(matches[, 2]) 10 | secs <- as.numeric(matches[, 3]) 11 | 12 | total_secs <- data.frame(runtime=secs + mins * 60) 13 | stargazer(total_secs, type='text') 14 | stargazer(total_secs) 15 | 16 | 17 | 18 | 19 | log <- read_file('log_DCC1step_sp100.txt') 20 | matches <- str_match_all(log, 'Elapsed time is ([0-9]+)\\.[0-9]+ seconds')[[1]] 21 | 22 | secs <- as.numeric(matches[, 2]) 23 | 24 | total_secs <- data.frame(runtime=secs <- secs / 98) # per stock 25 | 26 | 27 | stargazer(total_secs, type='text') 28 | stargazer(total_secs) 29 | 30 | 31 | 32 | 33 | log <- read_file('log_DCC1step_sp500_1000.txt') 34 | matches <- str_match_all(log, 'Elapsed time is ([0-9]+)\\.[0-9]+ seconds')[[1]] 35 | 36 | secs <- as.numeric(matches[, 2]) 37 | 38 | total_secs <- data.frame(runtime=secs <- secs / 500) # per stock 39 | 40 | 41 | stargazer(total_secs, type='text') 42 | stargazer(total_secs) 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /2 backtest/results/eq_CAPM-252_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.62 & 0.38 && 29,600 & 0.055 && 3.2 & 9.5 \\ 5 | 2 & 0.69 & 0.53 && 30,741 & 0.059 && 4.7 & 9.8 \\ 6 | 3 & 0.73 & 0.64 && 31,019 & 0.063 && 5.4 & 10.0 \\ 7 | 4 & 0.92 & 0.74 && 30,391 & 0.066 && 6.1 & 9.7 \\ 8 | 5 & 0.72 & 0.83 && 30,735 & 0.067 && 6.3 & 9.9 \\ 9 | 6 & 0.81 & 0.92 && 28,791 & 0.071 && 6.1 & 9.7 \\ 10 | 7 & 0.94 & 1.02 && 26,156 & 0.068 && 5.7 & 9.0 \\ 11 | 8 & 1.25 & 1.14 && 23,827 & 0.062 && 5.4 & 8.6 \\ 12 | 9 & 1.27 & 1.30 && 31,160 & 0.053 && 4.7 & 11.7 \\ 13 | 10 (High) & 1.15 & 1.73 && 30,935 & 0.049 && 3.7 & 12.0 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/eq_CAPM_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.62 & 0.38 && 29,600 & 0.055 && 3.2 & 9.5 \\ 5 | 2 & 0.69 & 0.53 && 30,741 & 0.059 && 4.7 & 9.8 \\ 6 | 3 & 0.73 & 0.64 && 31,019 & 0.063 && 5.4 & 10.0 \\ 7 | 4 & 0.92 & 0.74 && 30,391 & 0.066 && 6.1 & 9.7 \\ 8 | 5 & 0.72 & 0.83 && 30,735 & 0.067 && 6.3 & 9.9 \\ 9 | 6 & 0.81 & 0.92 && 28,791 & 0.071 && 6.1 & 9.7 \\ 10 | 7 & 0.94 & 1.02 && 26,156 & 0.068 && 5.7 & 9.0 \\ 11 | 8 & 1.25 & 1.14 && 23,827 & 0.062 && 5.4 & 8.6 \\ 12 | 9 & 1.27 & 1.30 && 31,160 & 0.053 && 4.7 & 11.7 \\ 13 | 10 (High) & 1.15 & 1.73 && 30,935 & 0.049 && 3.7 & 12.0 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/eq_CDCC-1000_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.42 & 0.38 && 31,076 & 0.056 && 7.1 & 10.1 \\ 5 | 2 & 0.64 & 0.53 && 29,933 & 0.062 && 14.6 & 9.8 \\ 6 | 3 & 0.77 & 0.64 && 29,680 & 0.066 && 18.2 & 9.7 \\ 7 | 4 & 0.97 & 0.73 && 30,606 & 0.069 && 20.5 & 10.0 \\ 8 | 5 & 0.89 & 0.82 && 28,475 & 0.070 && 21.5 & 9.5 \\ 9 | 6 & 0.86 & 0.92 && 27,283 & 0.071 && 21.2 & 9.5 \\ 10 | 7 & 0.90 & 1.03 && 26,277 & 0.067 && 20.2 & 9.4 \\ 11 | 8 & 1.08 & 1.15 && 25,663 & 0.061 && 17.9 & 9.5 \\ 12 | 9 & 1.16 & 1.34 && 27,680 & 0.057 && 13.6 & 10.6 \\ 13 | 10 (High) & 1.20 & 2.07 && 31,034 & 0.058 && 7.1 & 12.0 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/eq_COMFORT-DCC_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.42 & 0.38 && 31,076 & 0.056 && 7.1 & 10.1 \\ 5 | 2 & 0.64 & 0.53 && 29,933 & 0.062 && 14.6 & 9.8 \\ 6 | 3 & 0.77 & 0.64 && 29,680 & 0.066 && 18.2 & 9.7 \\ 7 | 4 & 0.97 & 0.73 && 30,606 & 0.069 && 20.5 & 10.0 \\ 8 | 5 & 0.89 & 0.82 && 28,475 & 0.070 && 21.5 & 9.5 \\ 9 | 6 & 0.86 & 0.92 && 27,283 & 0.071 && 21.2 & 9.5 \\ 10 | 7 & 0.90 & 1.03 && 26,277 & 0.067 && 20.2 & 9.4 \\ 11 | 8 & 1.08 & 1.15 && 25,663 & 0.061 && 17.9 & 9.5 \\ 12 | 9 & 1.16 & 1.34 && 27,680 & 0.057 && 13.6 & 10.6 \\ 13 | 10 (High) & 1.20 & 2.07 && 31,034 & 0.058 && 7.1 & 12.0 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/eq_DCC-1000_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.48 & 0.34 && 30,443 & 0.055 && 7.6 & 10.0 \\ 5 | 2 & 0.57 & 0.49 && 30,163 & 0.062 && 15.2 & 9.8 \\ 6 | 3 & 0.86 & 0.60 && 29,580 & 0.067 && 18.3 & 9.7 \\ 7 | 4 & 0.85 & 0.69 && 29,890 & 0.069 && 20.2 & 9.9 \\ 8 | 5 & 0.83 & 0.78 && 28,368 & 0.070 && 21.1 & 9.5 \\ 9 | 6 & 0.93 & 0.88 && 27,837 & 0.068 && 20.8 & 9.7 \\ 10 | 7 & 0.90 & 0.98 && 27,557 & 0.064 && 19.8 & 9.6 \\ 11 | 8 & 0.92 & 1.11 && 26,724 & 0.061 && 17.5 & 9.8 \\ 12 | 9 & 1.31 & 1.29 && 28,213 & 0.059 && 13.3 & 10.9 \\ 13 | 10 (High) & 1.25 & 1.75 && 28,008 & 0.062 && 7.0 & 11.1 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/eq_DCC-252_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.49 & 0.32 && 29,525 & 0.056 && 9.2 & 9.5 \\ 5 | 2 & 0.72 & 0.50 && 30,120 & 0.060 && 18.4 & 9.6 \\ 6 | 3 & 0.66 & 0.60 && 31,060 & 0.063 && 22.0 & 10.1 \\ 7 | 4 & 0.85 & 0.70 && 30,973 & 0.065 && 24.0 & 10.0 \\ 8 | 5 & 1.10 & 0.79 && 30,318 & 0.066 && 24.9 & 9.9 \\ 9 | 6 & 0.69 & 0.89 && 28,536 & 0.066 && 24.5 & 9.6 \\ 10 | 7 & 0.91 & 0.99 && 27,085 & 0.064 && 23.3 & 9.3 \\ 11 | 8 & 1.21 & 1.12 && 25,867 & 0.062 && 20.3 & 9.3 \\ 12 | 9 & 1.27 & 1.31 && 29,802 & 0.056 && 15.5 & 11.3 \\ 13 | 10 (High) & 1.20 & 1.80 && 30,023 & 0.055 && 8.1 & 11.5 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/eq_DCC_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.49 & 0.32 && 29,525 & 0.056 && 9.2 & 9.5 \\ 5 | 2 & 0.72 & 0.50 && 30,120 & 0.060 && 18.4 & 9.6 \\ 6 | 3 & 0.66 & 0.60 && 31,060 & 0.063 && 22.0 & 10.1 \\ 7 | 4 & 0.85 & 0.70 && 30,973 & 0.065 && 24.0 & 10.0 \\ 8 | 5 & 1.10 & 0.79 && 30,318 & 0.066 && 24.9 & 9.9 \\ 9 | 6 & 0.69 & 0.89 && 28,536 & 0.066 && 24.5 & 9.6 \\ 10 | 7 & 0.91 & 0.99 && 27,085 & 0.064 && 23.3 & 9.3 \\ 11 | 8 & 1.21 & 1.12 && 25,867 & 0.062 && 20.3 & 9.3 \\ 12 | 9 & 1.27 & 1.31 && 29,802 & 0.056 && 15.5 & 11.3 \\ 13 | 10 (High) & 1.20 & 1.80 && 30,023 & 0.055 && 8.1 & 11.5 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/eq_avg_ret_per_decile.tex: -------------------------------------------------------------------------------- 1 | % Created by tikzDevice version 0.12 on 2019-01-25 14:58:49 2 | % !TEX encoding = UTF-8 Unicode 3 | \begin{tikzpicture}[x=1pt,y=1pt] 4 | \definecolor{fillColor}{RGB}{255,255,255} 5 | \path[use as bounding box,fill=fillColor,fill opacity=0.00] (0,0) rectangle (433.62,289.08); 6 | \begin{scope} 7 | \path[clip] ( 49.20, 61.20) rectangle (408.42,239.88); 8 | \definecolor{drawColor}{RGB}{233,48,48} 9 | 10 | \path[draw=drawColor,line width= 0.8pt,line join=round,line cap=round] ( 49.20,145.66) -- 11 | ( 89.11,155.16) -- 12 | (129.03,159.73) -- 13 | (168.94,183.87) -- 14 | (208.85,158.63) -- 15 | (248.77,170.73) -- 16 | (288.68,186.51) -- 17 | (328.59,226.17) -- 18 | (368.51,228.60) -- 19 | (408.42,212.87); 20 | \end{scope} 21 | \begin{scope} 22 | \path[clip] ( 0.00, 0.00) rectangle (433.62,289.08); 23 | \definecolor{drawColor}{RGB}{0,0,0} 24 | 25 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20, 61.20) -- 26 | (408.42, 61.20) -- 27 | (408.42,239.88) -- 28 | ( 49.20,239.88) -- 29 | ( 49.20, 61.20); 30 | \end{scope} 31 | \begin{scope} 32 | \path[clip] ( 49.20, 61.20) rectangle (408.42,239.88); 33 | \definecolor{drawColor}{RGB}{0,115,213} 34 | 35 | \path[draw=drawColor,line width= 0.8pt,dash pattern=on 4pt off 4pt ,line join=round,line cap=round] ( 49.20,129.61) -- 36 | ( 89.11,158.63) -- 37 | (129.03,150.95) -- 38 | (168.94,175.32) -- 39 | (208.85,206.55) -- 40 | (248.77,154.88) -- 41 | (288.68,182.52) -- 42 | (328.59,221.47) -- 43 | (368.51,228.63) -- 44 | (408.42,220.10); 45 | \definecolor{drawColor}{RGB}{55,155,38} 46 | 47 | \path[draw=drawColor,line width= 0.8pt,dash pattern=on 1pt off 3pt ,line join=round,line cap=round] ( 49.20,128.79) -- 48 | ( 89.11,139.35) -- 49 | (129.03,176.37) -- 50 | (168.94,174.91) -- 51 | (208.85,173.36) -- 52 | (248.77,186.02) -- 53 | (288.68,181.54) -- 54 | (328.59,183.55) -- 55 | (368.51,233.26) -- 56 | (408.42,226.03); 57 | \definecolor{drawColor}{RGB}{255,143,0} 58 | 59 | \path[draw=drawColor,line width= 0.8pt,dash pattern=on 1pt off 3pt on 4pt off 3pt ,line join=round,line cap=round] ( 49.20,120.82) -- 60 | ( 89.11,148.74) -- 61 | (129.03,165.27) -- 62 | (168.94,190.75) -- 63 | (208.85,180.46) -- 64 | (248.77,176.09) -- 65 | (288.68,182.11) -- 66 | (328.59,204.40) -- 67 | (368.51,215.12) -- 68 | (408.42,219.25); 69 | \end{scope} 70 | \begin{scope} 71 | \path[clip] ( 0.00, 0.00) rectangle (433.62,289.08); 72 | \definecolor{drawColor}{RGB}{0,0,0} 73 | 74 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20, 61.20) -- (408.42, 61.20); 75 | 76 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20, 61.20) -- ( 49.20, 55.20); 77 | 78 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 89.11, 61.20) -- ( 89.11, 55.20); 79 | 80 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (129.03, 61.20) -- (129.03, 55.20); 81 | 82 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (168.94, 61.20) -- (168.94, 55.20); 83 | 84 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (208.85, 61.20) -- (208.85, 55.20); 85 | 86 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (248.77, 61.20) -- (248.77, 55.20); 87 | 88 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (288.68, 61.20) -- (288.68, 55.20); 89 | 90 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (328.59, 61.20) -- (328.59, 55.20); 91 | 92 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (368.51, 61.20) -- (368.51, 55.20); 93 | 94 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (408.42, 61.20) -- (408.42, 55.20); 95 | 96 | \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale= 0.85] at ( 49.20, 39.60) {1}; 97 | 98 | \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale= 0.85] at ( 89.11, 39.60) {2}; 99 | 100 | \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale= 0.85] at (129.03, 39.60) {3}; 101 | 102 | \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale= 0.85] at (168.94, 39.60) {4}; 103 | 104 | \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale= 0.85] at (208.85, 39.60) {5}; 105 | 106 | \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale= 0.85] at (248.77, 39.60) {6}; 107 | 108 | \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale= 0.85] at (288.68, 39.60) {7}; 109 | 110 | \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale= 0.85] at (328.59, 39.60) {8}; 111 | 112 | \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale= 0.85] at (368.51, 39.60) {9}; 113 | 114 | \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale= 0.85] at (408.42, 39.60) {10}; 115 | 116 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20, 67.82) -- ( 49.20,239.88); 117 | 118 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20, 67.82) -- ( 43.20, 67.82); 119 | 120 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20,118.41) -- ( 43.20,118.41); 121 | 122 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20,169.00) -- ( 43.20,169.00); 123 | 124 | \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20,219.59) -- ( 43.20,219.59); 125 | 126 | \node[text=drawColor,anchor=base east,inner sep=0pt, outer sep=0pt, scale= 0.85] at ( 37.20, 64.89) {0\%}; 127 | 128 | \node[text=drawColor,anchor=base east,inner sep=0pt, outer sep=0pt, scale= 0.85] at ( 37.20,115.48) {0.4\%}; 129 | 130 | \node[text=drawColor,anchor=base east,inner sep=0pt, outer sep=0pt, scale= 0.85] at ( 37.20,166.07) {0.8\%}; 131 | 132 | \node[text=drawColor,anchor=base east,inner sep=0pt, outer sep=0pt, scale= 0.85] at ( 37.20,216.66) {1.2\%}; 133 | \end{scope} 134 | \begin{scope} 135 | \path[clip] ( 49.20, 61.20) rectangle (408.42,239.88); 136 | \definecolor{drawColor}{RGB}{233,48,48} 137 | 138 | \path[draw=drawColor,line width= 0.8pt,line join=round,line cap=round] ( 56.40,230.28) -- ( 70.80,230.28); 139 | \definecolor{drawColor}{RGB}{0,115,213} 140 | 141 | \path[draw=drawColor,line width= 0.8pt,dash pattern=on 4pt off 4pt ,line join=round,line cap=round] ( 56.40,220.68) -- ( 70.80,220.68); 142 | \definecolor{drawColor}{RGB}{55,155,38} 143 | 144 | \path[draw=drawColor,line width= 0.8pt,dash pattern=on 1pt off 3pt ,line join=round,line cap=round] ( 56.40,211.08) -- ( 70.80,211.08); 145 | \definecolor{drawColor}{RGB}{255,143,0} 146 | 147 | \path[draw=drawColor,line width= 0.8pt,dash pattern=on 1pt off 3pt on 4pt off 3pt ,line join=round,line cap=round] ( 56.40,201.48) -- ( 70.80,201.48); 148 | \definecolor{drawColor}{RGB}{0,0,0} 149 | 150 | \node[text=drawColor,anchor=base west,inner sep=0pt, outer sep=0pt, scale= 0.80] at ( 78.00,227.53) {CAPM-252}; 151 | 152 | \node[text=drawColor,anchor=base west,inner sep=0pt, outer sep=0pt, scale= 0.80] at ( 78.00,217.93) {DCC-252}; 153 | 154 | \node[text=drawColor,anchor=base west,inner sep=0pt, outer sep=0pt, scale= 0.80] at ( 78.00,208.33) {DCC-1000}; 155 | 156 | \node[text=drawColor,anchor=base west,inner sep=0pt, outer sep=0pt, scale= 0.80] at ( 78.00,198.73) {CDCC-1000}; 157 | \end{scope} 158 | \end{tikzpicture} 159 | -------------------------------------------------------------------------------- /2 backtest/results/eq_beta_std_dev.tex: -------------------------------------------------------------------------------- 1 | 1 & 0.17 & 0.16 & 0.15 & 0.15 \\ 2 | 2 & 0.16 & 0.16 & 0.15 & 0.15 \\ 3 | 3 & 0.16 & 0.16 & 0.14 & 0.15 \\ 4 | 4 & 0.15 & 0.16 & 0.14 & 0.15 \\ 5 | 5 & 0.15 & 0.17 & 0.15 & 0.16 \\ 6 | 6 & 0.15 & 0.18 & 0.17 & 0.17 \\ 7 | 7 & 0.16 & 0.20 & 0.18 & 0.19 \\ 8 | 8 & 0.17 & 0.22 & 0.20 & 0.21 \\ 9 | 9 & 0.16 & 0.24 & 0.22 & 0.23 \\ 10 | 10 & 0.18 & 0.35 & 0.33 & 0.89 \\ -------------------------------------------------------------------------------- /2 backtest/results/eq_univariate_portfolio_analysis.tex: -------------------------------------------------------------------------------- 1 | 1 (Low) & 0.62 & 0.38 && 0.49 & 0.32 && 0.48 & 0.34 && 0.42 & 0.38 \\ 2 | 2 & 0.69 & 0.53 && 0.72 & 0.50 && 0.57 & 0.49 && 0.64 & 0.53 \\ 3 | 3 & 0.73 & 0.64 && 0.66 & 0.60 && 0.86 & 0.60 && 0.77 & 0.64 \\ 4 | 4 & 0.92 & 0.74 && 0.85 & 0.70 && 0.85 & 0.69 && 0.97 & 0.73 \\ 5 | 5 & 0.72 & 0.83 && 1.10 & 0.79 && 0.83 & 0.78 && 0.89 & 0.82 \\ 6 | 6 & 0.81 & 0.92 && 0.69 & 0.89 && 0.93 & 0.88 && 0.86 & 0.92 \\ 7 | 7 & 0.94 & 1.02 && 0.91 & 0.99 && 0.90 & 0.98 && 0.90 & 1.03 \\ 8 | 8 & 1.25 & 1.14 && 1.21 & 1.12 && 0.92 & 1.11 && 1.08 & 1.15 \\ 9 | 9 & 1.27 & 1.30 && 1.27 & 1.31 && 1.31 & 1.29 && 1.16 & 1.34 \\ 10 | 10 (High) & 1.15 & 1.73 && 1.20 & 1.80 && 1.25 & 1.75 && 1.20 & 2.07 \\ 11 | \midrule 12 | High$-$Low & \makecell{0.53 \\ (0.85)} & && \makecell{0.71 \\ (1.24)} & && \makecell{0.77 \\ (1.28)} & && \makecell{0.78 \\ (1.28)} & \\ 13 | \midrule 14 | FF5 $\upalpha$ & \makecell{0.52 \\ (1.36)} & && \makecell{0.62 \\ (1.62)} & && \makecell{0.57 \\ (1.53)} & && \makecell{0.62 \\ (1.63)} & \\ 15 | \midrule 16 | CAPM $\upalpha$ & \makecell{-0.27 \\ (-0.68)} & && \makecell{-0.08 \\ (-0.20)} & && \makecell{-0.01 \\ (-0.03)} & && \makecell{-0.02 \\ (-0.05)} & \\ 17 | \midrule 18 | SR & 0.11 & && 0.18 & && 0.20 & && 0.20 & \\ -------------------------------------------------------------------------------- /2 backtest/results/vw_CAPM-252_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.84 & 0.39 && 29,600 & 0.055 && 3.2 & 9.5 \\ 5 | 2 & 0.79 & 0.53 && 30,741 & 0.059 && 4.7 & 9.8 \\ 6 | 3 & 1.10 & 0.64 && 31,019 & 0.063 && 5.4 & 10.0 \\ 7 | 4 & 1.17 & 0.74 && 30,391 & 0.066 && 6.1 & 9.7 \\ 8 | 5 & 1.03 & 0.83 && 30,735 & 0.067 && 6.3 & 9.9 \\ 9 | 6 & 1.12 & 0.92 && 28,791 & 0.071 && 6.1 & 9.7 \\ 10 | 7 & 1.15 & 1.02 && 26,156 & 0.068 && 5.7 & 9.0 \\ 11 | 8 & 1.47 & 1.14 && 23,827 & 0.062 && 5.4 & 8.6 \\ 12 | 9 & 1.35 & 1.31 && 31,160 & 0.053 && 4.7 & 11.7 \\ 13 | 10 (High) & 2.03 & 1.70 && 30,935 & 0.049 && 3.7 & 12.0 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/vw_CAPM_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.84 & 0.39 && 29,600 & 0.055 && 3.2 & 9.5 \\ 5 | 2 & 0.79 & 0.53 && 30,741 & 0.059 && 4.7 & 9.8 \\ 6 | 3 & 1.10 & 0.64 && 31,019 & 0.063 && 5.4 & 10.0 \\ 7 | 4 & 1.17 & 0.74 && 30,391 & 0.066 && 6.1 & 9.7 \\ 8 | 5 & 1.03 & 0.83 && 30,735 & 0.067 && 6.3 & 9.9 \\ 9 | 6 & 1.12 & 0.92 && 28,791 & 0.071 && 6.1 & 9.7 \\ 10 | 7 & 1.15 & 1.02 && 26,156 & 0.068 && 5.7 & 9.0 \\ 11 | 8 & 1.47 & 1.14 && 23,827 & 0.062 && 5.4 & 8.6 \\ 12 | 9 & 1.35 & 1.31 && 31,160 & 0.053 && 4.7 & 11.7 \\ 13 | 10 (High) & 2.03 & 1.70 && 30,935 & 0.049 && 3.7 & 12.0 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/vw_CDCC-1000_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.54 & 0.39 && 31,076 & 0.056 && 7.1 & 10.1 \\ 5 | 2 & 0.92 & 0.53 && 29,933 & 0.062 && 14.6 & 9.8 \\ 6 | 3 & 0.88 & 0.64 && 29,680 & 0.066 && 18.2 & 9.7 \\ 7 | 4 & 1.17 & 0.73 && 30,606 & 0.069 && 20.5 & 10.0 \\ 8 | 5 & 1.03 & 0.82 && 28,475 & 0.070 && 21.5 & 9.5 \\ 9 | 6 & 1.33 & 0.92 && 27,283 & 0.071 && 21.2 & 9.5 \\ 10 | 7 & 1.32 & 1.03 && 26,277 & 0.067 && 20.2 & 9.4 \\ 11 | 8 & 1.39 & 1.15 && 25,663 & 0.061 && 17.9 & 9.5 \\ 12 | 9 & 1.34 & 1.34 && 27,680 & 0.057 && 13.6 & 10.6 \\ 13 | 10 (High) & 1.85 & 2.26 && 31,034 & 0.058 && 7.1 & 12.0 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/vw_COMFORT-DCC_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.54 & 0.39 && 31,076 & 0.056 && 7.1 & 10.1 \\ 5 | 2 & 0.92 & 0.53 && 29,933 & 0.062 && 14.6 & 9.8 \\ 6 | 3 & 0.88 & 0.64 && 29,680 & 0.066 && 18.2 & 9.7 \\ 7 | 4 & 1.17 & 0.73 && 30,606 & 0.069 && 20.5 & 10.0 \\ 8 | 5 & 1.03 & 0.82 && 28,475 & 0.070 && 21.5 & 9.5 \\ 9 | 6 & 1.33 & 0.92 && 27,283 & 0.071 && 21.2 & 9.5 \\ 10 | 7 & 1.32 & 1.03 && 26,277 & 0.067 && 20.2 & 9.4 \\ 11 | 8 & 1.39 & 1.15 && 25,663 & 0.061 && 17.9 & 9.5 \\ 12 | 9 & 1.34 & 1.34 && 27,680 & 0.057 && 13.6 & 10.6 \\ 13 | 10 (High) & 1.85 & 2.26 && 31,034 & 0.058 && 7.1 & 12.0 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/vw_DCC-1000_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.66 & 0.35 && 30,443 & 0.055 && 7.6 & 10.0 \\ 5 | 2 & 0.73 & 0.49 && 30,163 & 0.062 && 15.2 & 9.8 \\ 6 | 3 & 1.04 & 0.59 && 29,580 & 0.067 && 18.3 & 9.7 \\ 7 | 4 & 1.11 & 0.69 && 29,890 & 0.069 && 20.2 & 9.9 \\ 8 | 5 & 1.22 & 0.78 && 28,368 & 0.070 && 21.1 & 9.5 \\ 9 | 6 & 1.35 & 0.88 && 27,837 & 0.068 && 20.8 & 9.7 \\ 10 | 7 & 1.32 & 0.98 && 27,557 & 0.064 && 19.8 & 9.6 \\ 11 | 8 & 1.06 & 1.11 && 26,724 & 0.061 && 17.5 & 9.8 \\ 12 | 9 & 1.72 & 1.29 && 28,213 & 0.059 && 13.3 & 10.9 \\ 13 | 10 (High) & 2.10 & 1.71 && 28,008 & 0.062 && 7.0 & 11.1 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/vw_DCC-252_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.61 & 0.33 && 29,525 & 0.056 && 9.2 & 9.5 \\ 5 | 2 & 0.86 & 0.50 && 30,120 & 0.060 && 18.4 & 9.6 \\ 6 | 3 & 0.98 & 0.60 && 31,060 & 0.063 && 22.0 & 10.1 \\ 7 | 4 & 1.21 & 0.70 && 30,973 & 0.065 && 24.0 & 10.0 \\ 8 | 5 & 1.42 & 0.79 && 30,318 & 0.066 && 24.9 & 9.9 \\ 9 | 6 & 1.09 & 0.89 && 28,536 & 0.066 && 24.5 & 9.6 \\ 10 | 7 & 1.39 & 0.99 && 27,085 & 0.064 && 23.3 & 9.3 \\ 11 | 8 & 1.38 & 1.12 && 25,867 & 0.062 && 20.3 & 9.3 \\ 12 | 9 & 1.24 & 1.31 && 29,802 & 0.056 && 15.5 & 11.3 \\ 13 | 10 (High) & 2.37 & 1.75 && 30,023 & 0.055 && 8.1 & 11.5 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/vw_DCC_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & 0.61 & 0.33 && 29,525 & 0.056 && 9.2 & 9.5 \\ 5 | 2 & 0.86 & 0.50 && 30,120 & 0.060 && 18.4 & 9.6 \\ 6 | 3 & 0.98 & 0.60 && 31,060 & 0.063 && 22.0 & 10.1 \\ 7 | 4 & 1.21 & 0.70 && 30,973 & 0.065 && 24.0 & 10.0 \\ 8 | 5 & 1.42 & 0.79 && 30,318 & 0.066 && 24.9 & 9.9 \\ 9 | 6 & 1.09 & 0.89 && 28,536 & 0.066 && 24.5 & 9.6 \\ 10 | 7 & 1.39 & 0.99 && 27,085 & 0.064 && 23.3 & 9.3 \\ 11 | 8 & 1.38 & 1.12 && 25,867 & 0.062 && 20.3 & 9.3 \\ 12 | 9 & 1.24 & 1.31 && 29,802 & 0.056 && 15.5 & 11.3 \\ 13 | 10 (High) & 2.37 & 1.75 && 30,023 & 0.055 && 8.1 & 11.5 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/results/vw_beta_std_dev.tex: -------------------------------------------------------------------------------- 1 | 1 & 0.16 & 0.16 & 0.15 & 0.15 \\ 2 | 2 & 0.16 & 0.16 & 0.15 & 0.15 \\ 3 | 3 & 0.16 & 0.16 & 0.14 & 0.15 \\ 4 | 4 & 0.15 & 0.16 & 0.14 & 0.15 \\ 5 | 5 & 0.15 & 0.17 & 0.15 & 0.16 \\ 6 | 6 & 0.15 & 0.18 & 0.17 & 0.17 \\ 7 | 7 & 0.16 & 0.20 & 0.18 & 0.19 \\ 8 | 8 & 0.17 & 0.22 & 0.20 & 0.20 \\ 9 | 9 & 0.15 & 0.24 & 0.22 & 0.22 \\ 10 | 10 & 0.20 & 0.36 & 0.34 & 1.61 \\ -------------------------------------------------------------------------------- /2 backtest/results/vw_univariate_portfolio_analysis.tex: -------------------------------------------------------------------------------- 1 | 1 (Low) & 0.84 & 0.39 && 0.61 & 0.33 && 0.66 & 0.35 && 0.54 & 0.39 \\ 2 | 2 & 0.79 & 0.53 && 0.86 & 0.50 && 0.73 & 0.49 && 0.92 & 0.53 \\ 3 | 3 & 1.10 & 0.64 && 0.98 & 0.60 && 1.04 & 0.59 && 0.88 & 0.64 \\ 4 | 4 & 1.17 & 0.74 && 1.21 & 0.70 && 1.11 & 0.69 && 1.17 & 0.73 \\ 5 | 5 & 1.03 & 0.83 && 1.42 & 0.79 && 1.22 & 0.78 && 1.03 & 0.82 \\ 6 | 6 & 1.12 & 0.92 && 1.09 & 0.89 && 1.35 & 0.88 && 1.33 & 0.92 \\ 7 | 7 & 1.15 & 1.02 && 1.39 & 0.99 && 1.32 & 0.98 && 1.32 & 1.03 \\ 8 | 8 & 1.47 & 1.14 && 1.38 & 1.12 && 1.06 & 1.11 && 1.39 & 1.15 \\ 9 | 9 & 1.35 & 1.31 && 1.24 & 1.31 && 1.72 & 1.29 && 1.34 & 1.34 \\ 10 | 10 (High) & 2.03 & 1.70 && 2.37 & 1.75 && 2.10 & 1.71 && 1.85 & 2.26 \\ 11 | \midrule 12 | High$-$Low & \makecell{1.18 \\ (1.89)} & && \makecell{1.75 \\ (2.88)} & && \makecell{1.43 \\ (2.32)} & && \makecell{1.30 \\ (2.13)} & \\ 13 | \midrule 14 | FF5 $\upalpha$ & \makecell{1.32 \\ (2.84)} & && \makecell{1.84 \\ (3.54)} & && \makecell{1.38 \\ (2.82)} & && \makecell{1.30 \\ (2.72)} & \\ 15 | \midrule 16 | CAPM $\upalpha$ & \makecell{0.37 \\ (0.77)} & && \makecell{0.96 \\ (1.89)} & && \makecell{0.65 \\ (1.30)} & && \makecell{0.51 \\ (1.05)} & \\ 17 | \midrule 18 | SR & 0.32 & && 0.51 & && 0.41 & && 0.37 & \\ -------------------------------------------------------------------------------- /2 backtest/tpls/tpl_beta_std_dev.tex: -------------------------------------------------------------------------------- 1 | 1 & SD101 & SD201 & SD301 & SD401 \\ 2 | 2 & SD102 & SD202 & SD302 & SD402 \\ 3 | 3 & SD103 & SD203 & SD303 & SD403 \\ 4 | 4 & SD104 & SD204 & SD304 & SD404 \\ 5 | 5 & SD105 & SD205 & SD305 & SD405 \\ 6 | 6 & SD106 & SD206 & SD306 & SD406 \\ 7 | 7 & SD107 & SD207 & SD307 & SD407 \\ 8 | 8 & SD108 & SD208 & SD308 & SD408 \\ 9 | 9 & SD109 & SD209 & SD309 & SD409 \\ 10 | 10 & SD110 & SD210 & SD310 & SD410 \\ -------------------------------------------------------------------------------- /2 backtest/tpls/tpl_portfolio_characteristics.tex: -------------------------------------------------------------------------------- 1 | \begin{tabular}{@{}lccccccccc@{}} 2 | \toprule 3 | Decile & $\textit{RET}$ & $\beta$ && $\textit{SIZE}$ & $\textit{ILLIQ}$ && $\textit{TURN}$ (\%) & Market share (\%) \\ \midrule 4 | 1 (Low) & RET01 & BE01 && SI01 & IL01 && TU01 & SH01 \\ 5 | 2 & RET02 & BE02 && SI02 & IL02 && TU02 & SH02 \\ 6 | 3 & RET03 & BE03 && SI03 & IL03 && TU03 & SH03 \\ 7 | 4 & RET04 & BE04 && SI04 & IL04 && TU04 & SH04 \\ 8 | 5 & RET05 & BE05 && SI05 & IL05 && TU05 & SH05 \\ 9 | 6 & RET06 & BE06 && SI06 & IL06 && TU06 & SH06 \\ 10 | 7 & RET07 & BE07 && SI07 & IL07 && TU07 & SH07 \\ 11 | 8 & RET08 & BE08 && SI08 & IL08 && TU08 & SH08 \\ 12 | 9 & RET09 & BE09 && SI09 & IL09 && TU09 & SH09 \\ 13 | 10 (High) & RET10 & BE10 && SI10 & IL10 && TU10 & SH10 \\ 14 | \bottomrule 15 | \end{tabular} -------------------------------------------------------------------------------- /2 backtest/tpls/tpl_univariate_portfolio.tex: -------------------------------------------------------------------------------- 1 | 1 (Low) & RC01 & BC01 && RD01 & BD01 && RD1k01 & BD1k01 && RCD01 & BCD01 \\ 2 | 2 & RC02 & BC02 && RD02 & BD02 && RD1k02 & BD1k02 && RCD02 & BCD02 \\ 3 | 3 & RC03 & BC03 && RD03 & BD03 && RD1k03 & BD1k03 && RCD03 & BCD03 \\ 4 | 4 & RC04 & BC04 && RD04 & BD04 && RD1k04 & BD1k04 && RCD04 & BCD04 \\ 5 | 5 & RC05 & BC05 && RD05 & BD05 && RD1k05 & BD1k05 && RCD05 & BCD05 \\ 6 | 6 & RC06 & BC06 && RD06 & BD06 && RD1k06 & BD1k06 && RCD06 & BCD06 \\ 7 | 7 & RC07 & BC07 && RD07 & BD07 && RD1k07 & BD1k07 && RCD07 & BCD07 \\ 8 | 8 & RC08 & BC08 && RD08 & BD08 && RD1k08 & BD1k08 && RCD08 & BCD08 \\ 9 | 9 & RC09 & BC09 && RD09 & BD09 && RD1k09 & BD1k09 && RCD09 & BCD09 \\ 10 | 10 (High) & RC10 & BC10 && RD10 & BD10 && RD1k10 & BD1k10 && RCD10 & BCD10 \\ 11 | \midrule 12 | High$-$Low & \makecell{RCHLr \\ RCHLt} & && \makecell{RDHLr \\ RDHLt} & && \makecell{RD1kHLr \\ RD1kHLt} & && \makecell{RCDHLr \\ RCDHLt} & \\ 13 | \midrule 14 | FF5 $\upalpha$ & \makecell{RCav \\ RCat} & && \makecell{RDav \\ RDat} & && \makecell{RD1kav \\ RD1kat} & && \makecell{RCDav \\ RCDat} & \\ 15 | \midrule 16 | CAPM $\upalpha$ & \makecell{RCa2v \\ RCa2t} & && \makecell{RDa2v \\ RDa2t} & && \makecell{RD1ka2v \\ RD1ka2t} & && \makecell{RCDa2v \\ RCDa2t} & \\ 17 | \midrule 18 | SR & SR_C_ & && SR_D_ & && SR_D1k_ & && SR_CD_ & \\ -------------------------------------------------------------------------------- /DCC-GARCH_deciles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/DCC-GARCH_deciles.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | The beta measure was introduced by the renowned capital asset pricing model (CAPM) of Sharpe (1964) and Lintner (1965). It relates the expected returns of a security to the market portfolio returns. The resulting measure is the sensitivity of the security returns to changes in the market portfolio returns. The traditional estimation method uses ordinary least squares (OLS) for estimating a linear regression of security excess returns against market excess returns, resulting in an unconditional beta coefficient. The economic intuition behind the CAPM is attractive and easily understood, but Fama and French (2004) showcase poor empirical performance of the model compared to the expectations of the theoretical framework. 4 | 5 | More advanced estimation methods accounting for heteroscedasticity, volatility-clustering and time-dependency exist, e.g. GARCH-based models. 6 | 7 | A time-varying conditional beta measure using a DCC-GARCH construct is estimated in Bali, Engle and Tang (2016). It is supposed to have a significant positive relation to the cross-section of daily stock returns. A market neutral investment strategy taking a long position in stocks of the highest conditional beta decile and a short position in stocks of the lowest conditional beta decile yields alphas in the range of 0.60% to 0.80% per month; 0.25% to 0.48% per month by incorporating daily transaction costs. 8 | 9 | Paolella and Polak (2015) developed the more realistic, statistically advanced COMFORT model. It utilizes a flexible fat-tailed distribution and combines univariate GARCH-type dynamics with a relatively simple, yet flexible, stochastic volatility dynamic structure. The resulting hybrid GARCH-SV model is able to capture stochastic (co-)jumps in the volatility series and across assets. 10 | 11 | This thesis replicates the results obtained by Bali, Engle and Tang (2016) using their Gaussian DCC-GARCH construct on daily stock returns data, with a focus on the market neutral investment strategy results. Subsequently, the DCC-GARCH filter is replaced with the COMFORT model, with the hope and expectation of more significant beta estimations, resulting in a significantly better performance of the investment strategy, namely lower risk with equal or even higher returns 12 | 13 | # Model performance 14 | 15 | ![Performance of models investigated](models_performance.png) 16 | 17 | # DCC-GARCH cross-section of stock returns 18 | 19 | ![DCC-GARCH cross-section of stock returns](DCC-GARCH_deciles.png) 20 | 21 | # References 22 | 23 | Bali, Turan G. and Engle, Robert F. and Tang, Yi (2016). Dynamic Conditional Beta is Alive and Well in the Cross-Section of Daily Stock Returns. Management Science. 1-20. 24 | 25 | Lintner, J. (1965). The Valuation of Risk Assets and the Selection of Risky Investments in Stock Portfolios and Capital Budgets. The Review of Economics and Statistics, 47(1), 13-37. 26 | 27 | Paolella, M. S. and Polak, P. (2015). COMFORT: A common market factor non-gaussian returns model. Journal of Econometrics, 187(2), 593 - 605. 28 | 29 | Sharpe, W. (1964). Capital Asset Prices: A Theory of Market Equilibrium under Conditions of Risk. The Journal of Finance, 19(3), 425-442. -------------------------------------------------------------------------------- /functions.R: -------------------------------------------------------------------------------- 1 | # removes the given prefix from all colnames of given matrix 2 | remove.colnames.prefixes <- function(tbl, prefix) { 3 | colnames(tbl) <- unname(sapply(colnames(tbl), function(x) sub(prefix, '', x))) 4 | return(tbl) 5 | } 6 | 7 | # return rows of matrix which have same dates (column `date`) 8 | merge.by.date <- function(dates, mat) { 9 | if (length(which(!dates %in% mat$date)) > 0) { 10 | stop('Not all dates in matrix') 11 | } 12 | 13 | mat[which(mat$date %in% dates), ] 14 | } 15 | 16 | # applies the first column as rownames of the dataframe and removes it 17 | first.col.2.rownames <- function(dataframe) { 18 | rownames(dataframe) <- dataframe[, 1] 19 | dataframe <- dataframe[, -c(1)] 20 | return(dataframe) 21 | } 22 | 23 | # check if two matrices are equal 24 | matequal <- function(x, y) { 25 | is.matrix(x) && is.matrix(y) && dim(x) == dim(y) && all(x == y) 26 | } 27 | 28 | # converts daily returns to monthly returns by compounding them 21 times. 29 | return.d2m <- function(daily) { 30 | (1 + daily) ^ 21 - 1 31 | } 32 | 33 | # converts monthly returns to daily returns by taking the 1/21th root. 34 | return.m2d <- function(monthly) { 35 | (1 + monthly) ^ (1/21) - 1 36 | } 37 | 38 | 39 | # Sortino ratio 40 | sortino.ratio <- function(returns, MAR, scale) { 41 | ex.rets <- returns - MAR 42 | downside.risk <- sqrt(sum(1/length(ex.rets) * ex.rets[which(ex.rets < 0)]^2)) 43 | ratio <- mean(ex.rets) / downside.risk 44 | return(ratio * sqrt(scale)) 45 | } 46 | 47 | # Sharpe ratio 48 | sharpe.ratio <- function(returns, rf, scale) { 49 | return(mean(returns - rf) / sd(returns - rf) * sqrt(scale)) 50 | } 51 | 52 | 53 | 54 | 55 | 56 | # repeat given vector as column n times, returns a matrix 57 | rep.col <- function(x, n) { 58 | matrix(rep(x, each=n), ncol=n, byrow=T) 59 | } 60 | 61 | rep.row <- function(x, n){ 62 | matrix(rep(x,each=n), nrow=n) 63 | } 64 | 65 | 66 | 67 | # returns table without the given columns 68 | cols.omit <- function(dt, cols.omit) { 69 | if (is.null(dt)) 70 | return(NULL) 71 | 72 | cols <- colnames(dt) 73 | cols.select <- cols[!cols %in% cols.omit] 74 | 75 | return(dt[, cols.select, with=F]) 76 | } 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /models_performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/models_performance.png -------------------------------------------------------------------------------- /report/Modeling Conditional Betas with Application in Asset Allocation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/report/Modeling Conditional Betas with Application in Asset Allocation.pdf -------------------------------------------------------------------------------- /report/_compile_report.sh: -------------------------------------------------------------------------------- 1 | arara "Modeling Conditional Betas with Application in Asset Allocation.tex" 2 | read -------------------------------------------------------------------------------- /report/_preamble.tex: -------------------------------------------------------------------------------- 1 | % packages 2 | \usepackage[paper=a4paper, left=4cm, right=3cm, top=3cm, bottom=3cm]{geometry} 3 | \usepackage[utf8]{inputenc} 4 | \usepackage{booktabs,makecell,graphicx,epstopdf,xcolor,color,amsmath,titlesec,cancel,tikz} 5 | \usepackage{upgreek,listings,color} 6 | \usepackage[absolute,overlay]{textpos} 7 | 8 | % content variables 9 | \input{_variables.tex} 10 | 11 | % PDF properties 12 | \usepackage[pdftex, 13 | pdfauthor={\myAuthor}, 14 | pdftitle={\myTitle}, 15 | pdfsubject={Bachelor thesis}, 16 | pdfkeywords={\myKeywords}, 17 | pdfproducer={}, 18 | pdfcreator={}]{hyperref} 19 | 20 | % link colors 21 | \hypersetup{colorlinks, linkcolor={black}, citecolor={blue!50!black}, urlcolor={blue!80!black}} 22 | 23 | % line spacing 24 | \usepackage[onehalfspacing,doublespacing]{setspace} 25 | 26 | % first line indention 27 | \setlength{\parindent}{0cm} 28 | 29 | % bibliography 30 | \usepackage{apacite} 31 | \bibliographystyle{apacite} 32 | 33 | 34 | % section titles format 35 | \titlespacing*{\section}{0pt}{0ex}{0ex} 36 | \titlespacing*{\subsection}{0pt}{0ex}{-1ex} 37 | \titlespacing*{\subsubsection}{0pt}{0ex}{-1ex} 38 | 39 | % footnotes format 40 | \usepackage[bottom,hang,flushmargin]{footmisc} 41 | \renewcommand{\hangfootparskip}{0ex} 42 | \renewcommand{\hangfootparindent}{1em} 43 | 44 | % list of figures format 45 | \makeatletter 46 | \renewcommand*\l@figure{\@dottedtocline{1}{0em}{2.3em}} % Default: 1.5em/2.3em 47 | \let\l@table\l@figure 48 | \makeatother 49 | 50 | % captions format 51 | \usepackage{float,threeparttable} 52 | \usepackage[labelfont=bf]{caption} 53 | 54 | % code synatax highlighting format (listings package) 55 | \lstset{ 56 | backgroundcolor=\color{white}, 57 | basicstyle=\ttfamily\footnotesize, % the size of the fonts that are used for the code 58 | breakatwhitespace=false, % sets if automatic breaks should only happen at whitespace 59 | breaklines=true, % sets automatic line breaking 60 | captionpos=b, % sets the caption-position to bottom 61 | frame=single, % adds a frame around the code 62 | keepspaces=true % keeps spaces in text, useful for keeping indentation of code (possibly needs columns=flexible) 63 | } 64 | 65 | 66 | 67 | % custom commands 68 | \newcommand{\PLACEHOLDER}{\textbf{\textcolor{red}{XXXX}}} 69 | \newcommand{\REVISE}[1]{\textbf{\textcolor{orange}{#1}}} 70 | \newcommand{\VAR}[0]{\textrm{Var}} 71 | \newcommand{\COV}[0]{\textrm{Cov}} 72 | \newcommand{\EE}[0]{\textrm{E}} 73 | \newcommand{\PP}[0]{\textrm{P}} 74 | \newcommand{\ra}[1]{\renewcommand{\arraystretch}{#1}} 75 | 76 | %\newcommand{\TBLIMP}[1]{} 77 | \newcommand{\TBLIMP}[1]{\input{#1}} 78 | 79 | %\newcommand{\FIGIMP}[1]{} 80 | \newcommand{\FIGIMP}[1]{\input{#1}} 81 | -------------------------------------------------------------------------------- /report/_references.bib: -------------------------------------------------------------------------------- 1 | % Encoding: UTF-8 2 | 3 | @Article{BET:16, 4 | author = {Bali, Turan G. and Engle, Robert F. and Tang, Yi}, 5 | title = {{D}ynamic {C}onditional {B}eta {I}s {A}live and {W}ell in the {C}ross {S}ection of {D}aily {S}tock {R}eturns}, 6 | journal = {Management Science}, 7 | volume = {63}, 8 | number = {11}, 9 | pages = {3760-3779}, 10 | year = {2017}, 11 | } 12 | 13 | @Article{PAP:15, 14 | author = {Paolella, Marc S. and Polak, Pawel}, 15 | title = {{COMFORT}: {A} common market factor non-{G}aussian returns model}, 16 | journal = {Journal of Econometrics}, 17 | year = {2015}, 18 | volume = {187}, 19 | number = {2}, 20 | pages = {593-605}, 21 | issn = {0304-4076}, 22 | } 23 | 24 | @Article{PAP:15.1, 25 | author = {Paolella, Marc S. and Polak, Pawel}, 26 | year = {2015}, 27 | month = {01}, 28 | pages = {}, 29 | title = {{P}ortfolio {S}election with {A}ctive {R}isk {M}onitoring}, 30 | journal = {SSRN Electronic Journal}, 31 | doi = {10.2139/ssrn.2616284} 32 | } 33 | 34 | @Article{SHU:97, 35 | author = {Shumway, Tyler}, 36 | title = {The {D}elisting {B}ias in {CRSP} {D}ata}, 37 | journal = {The Journal of Finance}, 38 | year = {1997}, 39 | volume = {52}, 40 | number = {1}, 41 | pages = {327--340}, 42 | } 43 | 44 | @Misc{KFD:18, 45 | author = {French, Kenneth R.}, 46 | title = {Kenneth {R}. {F}rench {D}ata {L}ibrary}, 47 | year = {2018}, 48 | url = {http://mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html}, 49 | urldate = {August 18, 2018} 50 | } 51 | 52 | @Book{BEM:16, 53 | author = {Bali, Turan G. and Engle, Robert F. and Murray, Scott}, 54 | title = {{E}mpirical {A}sset {P}ricing: {T}he {C}ross {S}ection of {S}tock {R}eturns}, 55 | publisher = {John Wiley \& Sons, Inc.}, 56 | year = {2016}, 57 | address = {Hoboken, New Jersey} 58 | } 59 | 60 | @Article{HUDSON:15, 61 | author = "Hudson, Robert S. and Gregoriou, Andros", 62 | title = "{C}alculating and comparing security returns is harder than you think: {A} comparison between logarithmic and simple returns", 63 | journal = "International Review of Financial Analysis", 64 | volume = "38", 65 | pages = "151 - 162", 66 | year = "2015", 67 | issn = "1057-5219", 68 | doi = "10.1016/j.irfa.2014.10.008" 69 | } 70 | 71 | @Article{JL:65, 72 | ISSN = {00346535, 15309142}, 73 | author = {Lintner, John}, 74 | journal = {{T}he {R}eview of {E}conomics and {S}tatistics}, 75 | number = {1}, 76 | pages = {13--37}, 77 | publisher = {The MIT Press}, 78 | title = {The Valuation of Risk Assets and the Selection of Risky Investments in Stock Portfolios and Capital Budgets}, 79 | volume = {47}, 80 | year = {1965} 81 | } 82 | 83 | @Article{WS:64, 84 | title = {{C}APITAL {A}SSET {P}RICES: {A} {T}HEORY OF {M}ARKET {E}QUILIBRIUM UNDER {C}ONDITIONS OF {R}ISK}, 85 | author = {Sharpe, William}, 86 | year = {1964}, 87 | journal = {Journal of Finance}, 88 | volume = {19}, 89 | number = {3}, 90 | pages = {425-442} 91 | } 92 | 93 | @Article{FF:04, 94 | Author = {Fama, Eugene F. and French, Kenneth R.}, 95 | Title = {{T}he {C}apital {A}sset {P}ricing {M}odel: {T}heory and {E}vidence}, 96 | Journal = {Journal of Economic Perspectives}, 97 | Volume = {18}, 98 | Number = {3}, 99 | Year = {2004}, 100 | Month = {September}, 101 | Pages = {25-46}, 102 | DOI = {10.1257/0895330042162430} 103 | } 104 | 105 | @Article{EN:02, 106 | author = {Engle, Robert F.}, 107 | title = {{D}ynamic {C}onditional {C}orrelation}, 108 | journal = {Journal of Business \& Economic Statistics}, 109 | volume = {20}, 110 | number = {3}, 111 | pages = {339-350}, 112 | year = {2002}, 113 | publisher = {Taylor & Francis}, 114 | DOI = {10.1198/073500102288618487}, 115 | } 116 | 117 | @Book{FO:15, 118 | title = {{A}pplied {R}egression {A}nalysis and {G}eneralized {L}inear {M}odels}, 119 | author = {Fox, John}, 120 | publisher = {SAGE Publ.}, 121 | year = {2015}, 122 | edition = {3rd} 123 | } 124 | 125 | @Article{EJP:03, 126 | title = {{T}he {I}mpact of {J}umps in {V}olatility and {R}eturns}, 127 | author = {Eraker, Bjørn and Johannes, Michael and Polson, Nicholas}, 128 | year = {2003}, 129 | journal = {Journal of Finance}, 130 | volume = {58}, 131 | number = {3}, 132 | pages = {1269-1300} 133 | } 134 | 135 | @Article{YA:02, 136 | author = "Amihud, Yakov", 137 | title = "{I}lliquidity and stock returns: cross-section and time-series effects", 138 | journal = "Journal of Financial Markets", 139 | volume = "5", 140 | number = "1", 141 | pages = "31 - 56", 142 | year = "2002", 143 | issn = "1386-4181" 144 | } 145 | 146 | @Article{FA:15, 147 | author = "Fama, Eugene F. and French, Kenneth R.", 148 | title = "{A} five-factor asset pricing model", 149 | journal = "Journal of Financial Economics", 150 | volume = "116", 151 | number = "1", 152 | pages = "1 - 22", 153 | year = "2015", 154 | issn = "0304-405X" 155 | } 156 | 157 | @Misc{API:WRDS, 158 | author = {{The Wharton School}}, 159 | title = {{W}harton {R}esearch {D}ata {S}ervices {API}}, 160 | year = {2018}, 161 | url = {https://wrds-web.wharton.upenn.edu/wrds/}, 162 | urldate = {2018-08-12} 163 | } 164 | 165 | @Article{ES:01, 166 | author = "Engle, Robert F. and Sheppard, Kevin", 167 | title = "{T}heoretical and {E}mpirical properties of {D}ynamic {C}onditional {C}orrelation {M}ultivariate {GARCH}", 168 | institution = "National Bureau of Economic Research", 169 | type = "Working Paper", 170 | series = "Working Paper Series", 171 | number = "8554", 172 | year = "2001" 173 | } 174 | 175 | @Book{QRM:15, 176 | author = {McNeil, Alexander J. and Frey, Rdiger and Embrechts, Paul}, 177 | title = {Quantitative Risk Management: Concepts, Techniques and Tools}, 178 | year = {2015}, 179 | publisher = {Princeton University Press} 180 | } 181 | 182 | @Book{KOTZ:01, 183 | author = {Kotz, Samuel and Kozubowski, Tomasz and Podgorski, Krzysztof}, 184 | year = {2001}, 185 | month = {01}, 186 | pages = {}, 187 | title = {The Laplace Distribution and Generalizations: A Revisit with Applications to Communications, Economics, Engineering, and Finance}, 188 | doi = {10.1007/978-1-4612-0173-1} 189 | } -------------------------------------------------------------------------------- /report/_variables.tex: -------------------------------------------------------------------------------- 1 | \def \myTitle{Modeling Conditional Betas with Application in Asset Allocation} 2 | \def \myAuthor{Rino R. Beeli} 3 | \def \myDate{January 26, 2019} 4 | \def \myKeywords{{{cross-section of stock returns}, {DCC-GARCH}, {COMFORT}, {asset allocation}, {alpha}, {CAPM}, {Dynamic Conditional Beta}, {Beta}}} 5 | 6 | \def \indexName{S\&P 500} 7 | \def \periodFrom{January 1996} 8 | \def \periodTo{December 2013} -------------------------------------------------------------------------------- /report/abstract.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/report/abstract.pdf -------------------------------------------------------------------------------- /report/abstract.tex: -------------------------------------------------------------------------------- 1 | % arara: pdflatex 2 | 3 | \documentclass{article} 4 | 5 | \input{_variables.tex} 6 | 7 | \title{\myTitle} 8 | \author{\myAuthor} 9 | \date{\myDate} 10 | 11 | 12 | \begin{document} 13 | 14 | \maketitle 15 | 16 | \vspace{5mm} 17 | 18 | 19 | \begin{abstract} 20 | \noindent 21 | \input{sec_abstract_text.tex} 22 | \end{abstract} 23 | 24 | \end{document} -------------------------------------------------------------------------------- /report/executive_summary.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/report/executive_summary.pdf -------------------------------------------------------------------------------- /report/executive_summary.tex: -------------------------------------------------------------------------------- 1 | % arara: pdflatex 2 | 3 | \documentclass[11pt,a4paper]{article} 4 | \input{_preamble.tex} 5 | 6 | 7 | 8 | \begin{document} 9 | 10 | %% -------------------------------------------------- 11 | %% Title page 12 | %% -------------------------------------------------- 13 | \input{sec_titlepage.tex} 14 | 15 | 16 | \setlength{\parskip}{0.4cm} 17 | 18 | 19 | 20 | %% -------------------------------------------------- 21 | %% Executive summary 22 | %% -------------------------------------------------- 23 | \newpage 24 | \input{sec_executive_summary.tex} 25 | 26 | 27 | %% -------------------------------------------------- 28 | %% References 29 | %% -------------------------------------------------- 30 | \newpage 31 | \bibliography{_references} 32 | 33 | 34 | 35 | \end{document} -------------------------------------------------------------------------------- /report/scratchpad.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/report/scratchpad.pdf -------------------------------------------------------------------------------- /report/scratchpad.tex: -------------------------------------------------------------------------------- 1 | % arara: pdflatex 2 | 3 | \documentclass[11pt,a4paper]{article} 4 | \input{_preamble.tex} 5 | 6 | 7 | \begin{document} 8 | 9 | \input{sec_titlepage.tex} 10 | 11 | \end{document} -------------------------------------------------------------------------------- /report/sec_abstract_text.tex: -------------------------------------------------------------------------------- 1 | Empirical evidence shows that market betas vary substantially over time, hence time-varying beta models are of interest in the field of financial modeling. This thesis reexamines the findings of Bali et al. (2017) of a positive link between the dynamic conditional beta and the cross section of daily stock returns. Their investment strategy takes a long position in stocks in the highest beta decile and a short position in stocks in the lowest beta decile, and produces average returns and alphas in the range of 0.60\%–0.80\% per month. We are able to replicate their findings based on the DCC-GARCH construct and show that the value-weighted High-Low difference portfolio yields even higher monthly excess returns and alphas in the range of 1.7\%–1.9\% on our sample data. Replacing DCC-GARCH with the so-called COMFORT model, which is statistically more advanced and accounts for major stylized facts of financial asset returns, does not increase performance, nor does it result in lower portfolio risk due to model estimation errors and a longer estimation window. -------------------------------------------------------------------------------- /report/sec_executive_summary.tex: -------------------------------------------------------------------------------- 1 | \section*{Executive Summary} 2 | 3 | \begin{doublespacing} 4 | 5 | The beta measure was introduced by the renowned Capital Asset Pricing Model (CAPM) of \citeA{WS:64} and \citeA{JL:65}. It is a cornerstone in asset pricing theory and still widely used in practice, despite earning a lot of critique because of its poor empirical performance. The measure is the sensitivity of the security returns to changes in the market portfolio returns. The economic intuition behind the CAPM is attractive and easily understood, but \citeA{FF:04} showcase poor empirical performance of the model compared to the expectations of the theoretical framework. 6 | 7 | More advanced estimation methods which account for heteroscedasticity, volatility-clustering and time-dependency exist, e.g. GARCH-based models. \citeA{BET:16} estimate stock betas using a time-varying conditional correlation model in conjunction with a GARCH model, also called DCC-GARCH, which was introduced by \citeA{EN:02}. 8 | 9 | \citeA{BET:16} find a significant positive relation between conditional betas and the cross section of daily stock returns using the DCC-GARCH model for beta estimation. They estimate betas for all stocks in their sample for each day using a moving window. Based on the estimated betas, the cross-section of stock returns is predicted using beta deciles. They show that stocks in the lowest beta decile have significantly lower returns on the next trading day compared to stocks in the highest beta decile. The difference portfolio of \citeA{BET:16}, which takes a long position in stocks in the highest beta decile and a short position in stocks in the lowest beta decile, produces average returns and alphas in the range of 0.60\%–0.80\% per month. The strategy was backtested using all U.S.-based common stocks trading on the NYSE, AMEX, and NASDAQ exchanges with a stock price of \$5/share or more and with a market capitalization greater than \$10 million. The sample period starts in July 1963 and ends in December 2013. 10 | 11 | The replication of this finding is the first objective of this thesis. We are able to replicate their findings with our sample data based on the DCC-GARCH construct and show that the value-weighted High-Low beta portfolio yields even higher monthly excess returns and alphas in the range of 1.7\%–1.9\%. After incorporating the estimated transaction costs of 35 basis points, the strategy yields monthly excess returns and alphas in the range of 1.35\%–1.55\%, which is almost twice the monthly excess return \citeA{BET:16} achieved in their study. We use a more recent time period and a different sample to test the strategy. Our sample covers all \indexName{} constituents and covers the period from \periodFrom{} to \periodTo{}. Additionally, we used an exponential moving average on the covariance estimates, which increased performance and lowered the portfolio turnover rate, allowing the strategy to be implemented at lower costs. 12 | 13 | The second objective of this thesis is to replace the DCC-GARCH construct used by \citeA{BET:16} with the so-called COMFORT model developed by \citeA{PAP:15}. The more realistic, statistically advanced COMFORT model allows to model all major stylized facts of financial returns, including volatility clustering, dynamics in the dependency structure, asymmetry, and heavy tails. It supports various extensions which account for time-varying correlation dynamics and a hybrid GARCH-SV extension for modeling shocks across assets, which are an additional source of dynamics in the correlations. The COMFORT-DCC model used throughout this thesis uses a fat-tailed, multivariate asymmetric Laplace distribution (MALap) in conjunction with the Dynamic Conditional Correlation model of \citeA{ES:01} for the correlation dynamics; the hybrid GARCH-SV extension is not employed. The superior capabilities of the COMFORT-DCC model should enable it to outperform the DCC-GARCH model in terms of more significant beta estimates and a significantly better performance of the investment strategy, but the empirical results show that neither does the performance increase, nor do we find lower portfolio risk. 14 | 15 | There are various reasons why the COMFORT-DCC model does not outperform the DCC-GARCH construct in our setting. Covariance estimation errors impair our High-Low portfolio analysis, because reliable and consistent beta estimates are crucial for our study---any extreme values due to estimation errors directly bias our results. Our analysis shows that especially the highest beta values are prone to estimation errors and therefore worsen the performance of the High-Low portfolio. Also, the COMFORT-DCC model was estimated each day with a window size of 1000 days, which is approximately four times bigger than the window size used by \citeA{BET:16}. The DCC-GARCH model with a window size of 1000 days performs still better than the COMFORT-DCC model, leading to the conclusion that the window size alone is not the deciding factor for the worse performance. Furthermore, the bivariate estimation method introduces an additional degree of freedom compared to a full-sample estimation approach for the mixing factor, because the model assumes that the mixing factor estimates used in COMFORT-DCC are the same for all asset returns. This additional degree of freedom likely introduces less precise/more random COMFORT-DCC model estimates. 16 | 17 | The replication findings show promising results regarding the investment strategy used by \citeA{BET:16}, it outperforms the market and has higher risk-adjusted returns. Further studies of the COMFORT-DCC model with more reliable model estimates, different model extensions, and different estimation approaches are required in order to outperform the DCC-GARCH construct in our setting. In case of success, the resulting investment strategy would be highly interesting to investors. 18 | 19 | 20 | \end{doublespacing} 21 | -------------------------------------------------------------------------------- /report/sec_statutory_declaration.tex: -------------------------------------------------------------------------------- 1 | \section*{Statutory Declaration} 2 | 3 | \begin{doublespacing} 4 | I, Rino Beeli, hereby declare that my thesis with title 5 | 6 | \vspace{4mm}\begin{center}\textit{\myTitle}\end{center}\vspace{4mm} 7 | 8 | \noindent 9 | has been composed by myself autonomously and that no means other than those declared were 10 | used. In every single case, I have marked parts that were taken out of published or unpublished 11 | work, either verbatim or in a paraphrased manner, as such through a quotation. \\ 12 | 13 | \noindent 14 | This thesis has not been handed in or published before in the same or similar form. 15 | \vspace{1cm} 16 | 17 | \noindent 18 | \begin{tabular}{@{}p{2.5in}p{0.2in}p{2.5in}@{}} 19 | Zurich, \myDate & & \dotfill 20 | \end{tabular} 21 | \end{doublespacing} -------------------------------------------------------------------------------- /report/sec_titlepage.tex: -------------------------------------------------------------------------------- 1 | % Geometry 2 | \newgeometry{top=1.5in,bottom=1in,right=1in,left=1in} 3 | 4 | \begin{titlepage} 5 | \begin{onehalfspacing} 6 | \thispagestyle{empty} 7 | \centering 8 | 9 | 10 | 11 | % Bachelor thesis 12 | \begin{textblock*}{4.8cm}(8.2cm,6.8cm) 13 | \LARGE\textbf{Bachelor Thesis} 14 | \end{textblock*} 15 | 16 | 17 | % University of Zurich 18 | {\Large\textsc{University of Zurich \\ Department of Banking and Finance}} 19 | 20 | 21 | \vspace{4cm} 22 | 23 | 24 | % Title 25 | {\huge \textbf{ \myTitle }\par} 26 | 27 | 28 | \vspace{3cm} 29 | 30 | 31 | % Author 32 | {\large \textbf{Author} \par} 33 | \vspace{.2cm} 34 | {\LARGE \myAuthor \par} 35 | \vspace{.4cm} 36 | {\large Freilagerstrasse 92 \par} 37 | \vspace{.1cm} 38 | {\large 8047 Zurich \par} 39 | \vspace{.1cm} 40 | {\large rino.beeli@uzh.ch \par} 41 | \vspace{.1cm} 42 | {\large 15-709-371 \par} 43 | 44 | 45 | \vspace{1.6cm} 46 | 47 | 48 | % Supervisor 49 | {\large \textbf{Supervisor} \par} 50 | \vspace{.2cm} 51 | {\Large Prof. Dr. Marc S. Paolella \par} 52 | \vspace{.2cm} 53 | {\large Department of Banking and Finance \par} 54 | \vspace{.2cm} 55 | {\large University of Zurich \par} 56 | 57 | 58 | \vspace{2.5cm} 59 | 60 | 61 | % Date of Submission 62 | {\large \myDate \par} 63 | 64 | 65 | \end{onehalfspacing} 66 | \end{titlepage} 67 | 68 | 69 | \clearpage 70 | \newpage 71 | 72 | \restoregeometry 73 | \setcounter{page}{1} 74 | \pagenumbering{Roman} -------------------------------------------------------------------------------- /report/uzh_logo_e_pos-eps-converted-to.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbeeli/dynamic_conditional_beta/e6f8287a495bb424ea41adf7ebb23164951a9385/report/uzh_logo_e_pos-eps-converted-to.pdf --------------------------------------------------------------------------------