
% Classical Minimum Distance (CMD) estimation of parameters in a model
% of fixed income returns with factor exposure

% Before executing this script, please install IPOPT via OPTI Toolbox: 
% https://github.com/jonathancurrie/OPTI

close all;
clc;
clear;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%% (0) ENVIRONMENT %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Root directory (Change file path according to local device)
dboxroot = '~\Downloads\wealth\cmd_replication_public';

% Data folder within Dropbox
dboxdtadir = fullfile(dboxroot, 'matlab\build\cmdinputs_top1bot99_20210615.csv');

% Output for .txt files
dboxtxtout = fullfile(dboxroot,'matlab\tex');

% Output for .txt files
dboxfigout = fullfile(dboxroot,'matlab\figs');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%% (1) LOAD DATA AND EXTRACT VARIABLES %%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

fulldata = readtable(fullfile(dboxdtadir));
% data = fulldata(fulldata.year < 2017, :);

% Try restricting to SCF time range only
data = fulldata(fulldata.year >= 1989 & fulldata.year < 2017, :);
scfdata = fulldata(fulldata.year >= 1989 & mod(fulldata.year - 1989, 3) == 0, :);

% Calibrated shares of fixed claims assets need to be scalars (we'll use
%   mean over time period)
sa1_niw = scfdata.mean_sa1_scf_niwrank(11);
sa1_intinc = scfdata.mean_sa1_scf_intincrank(11);
sa1_agi = scfdata.mean_sa1_scf_agirank(11);
sa1_nonintagi = scfdata.mean_sa1_scf_nonintagirank(11);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%% (2) COMPUTE OUTPUT USING PROGRAM %%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

cd '~\Downloads\cmd_replication_public\matlab';

iter = 200; % 200 bootstrap iterations for SEs

% NIW-ranked, r^I = UST 5 r^C = Baa
[~, ~, ~] = cmd_estimation_prgm(data, data.ln_y1_niwrank, data.ln_y2_niwrank, ...
                        data.ln_a_total_sz20, data.ln_r_ust5, data.ln_r_baa, ...
                        sa1_niw, ...
                        scfdata.ln_a1_scf_niwrank, scfdata.ln_a2_scf_niwrank, ...
                        scfdata.ln_r1_scf_niwrank, scfdata.ln_r2_scf_niwrank, iter, ...
                        'top1-niw-ust5-baa', dboxfigout, dboxtxtout);
                        
% Interest income-ranked, r^I = UST 5 r^C = Baa
[~, ~, ~] = cmd_estimation_prgm(data, data.ln_y1_fixincrank, data.ln_y2_fixincrank, ...
                        data.ln_a_total_sz20, data.ln_r_ust5, data.ln_r_baa, ...
                        sa1_intinc, ...
                        scfdata.ln_a1_scf_intincrank, scfdata.ln_a2_scf_intincrank, ...
                        scfdata.ln_r1_scf_intincrank, scfdata.ln_r2_scf_intincrank, iter, ...
                        'top1-intinc-ust5-baa', dboxfigout, dboxtxtout);
    
% Fiscal income including KGs-ranked, r^I = UST 5 r^C = Baa
[~, ~, ~] = cmd_estimation_prgm(data, data.ln_y1_fiincrank, data.ln_y2_fiincrank, ...
                        data.ln_a_total_sz20, data.ln_r_ust5, data.ln_r_baa, ...
                        sa1_agi, ...
                        scfdata.ln_a1_scf_agirank, scfdata.ln_a2_scf_agirank, ...
                        scfdata.ln_r1_scf_agirank, scfdata.ln_r2_scf_agirank, iter, ...
                        'top1-agi-ust5-baa', dboxfigout, dboxtxtout);

% Non-interest AGI, r^I = UST 5 r^C = Baa
[~, ~, ~] = cmd_estimation_prgm(data, data.ln_y1_nonintagirank, data.ln_y2_nonintagirank, ...
                        data.ln_a_total_sz20, data.ln_r_ust5, data.ln_r_baa, ...
                        sa1_nonintagi, ...
                        scfdata.ln_a1_scf_nonintagirank, scfdata.ln_a2_scf_nonintagirank, ...
                        scfdata.ln_r1_scf_nonintagirank, scfdata.ln_r2_scf_nonintagirank, iter, ...
                        'top1-nonintagi-ust5-baa', dboxfigout, dboxtxtout);
                              