%% KRG Stress Test Example
% The user performs stress testing by computing historical trading costs
% given historical market impact parameters.
%
% The trade list data is used to estimate historical liquidation costs,
% back test trading strategies, and assist portfolio managers in stock
% screening.
%
% The trade data must contain the following to estimate market impact
% costs:
%
% 1) Symbol
% 2) Side
% 3) Size or Shares & ADV
% 4) Volatility
% 5) TradeTime or POV Rate
% 6) Price in Local Currency
% 7) MI Code (Optional, default = 1)
% 8) FX Rate Local to Target Currency
%
% The user specifies a Data Range from 5/1/2015 through 7/31/2015.

%   Copyright 2016-2020 The MathWorks, Inc.

% Load example data
load KRGExampleData TradeDataStressTest

% Specify Date Range
startDate = '5/1/2015';
endDate = '7/31/2015';

% Load the market impact data provided by the Kissell Research Group
f = ftp('ftp.kissellresearch.com','username','password');
cd(f,'MI_Parameters');
mget(f,'MI_Encrypted_Parameters.csv');

% Create KRG object
miData = readtable('MI_Encrypted_Parameters.csv','Format','auto','delimiter',',','ReadRowNames',false,'ReadVariableNames',true);
k = krg(miData,datetime('today'),1,250);

% Number of Stocks
numStocks = length(TradeDataStressTest.Symbol);    

% DateRange expressed in datenum
dateRange = (datenum(startDate):datenum(endDate))';

% Number of Dates in Date Range
numDates = length(dateRange);

% Number of rows in output data
outLength = numStocks*numDates;

% preallocate output table
symbols = TradeDataStressTest.Symbol(:,ones(1,numDates));
sides = TradeDataStressTest.Side(:,ones(1,numDates));
dates = dateRange(:,ones(1,numStocks))';
o = table(symbols(:),sides(:),dates(:),NaN(outLength,1),NaN(outLength,1),'VariableNames',{'Symbol','Side','Date','MI','MIDollar'});

% MI cost is always positive and based on Positive Shares Quantities
TradeDataStressTest.Shares = abs(TradeDataStressTest.Shares);

% ADV factor in TradeTime is different than tradetime2pov calc.
TradeDataStressTest.TradeTime = TradeDataStressTest.TradeTime .* TradeDataStressTest.ADV;
TradeDataStressTest.POV = krg.tradetime2pov(TradeDataStressTest.TradeTime,TradeDataStressTest.Shares);

% Compute Historical Market Impact Costs
kk = 1;
for ii = dateRange(1):dateRange(end)
  
  for jj = 1:numStocks
    
    % Set market impact date and code for parameter specification
    k.MiCode = TradeDataStressTest.MICode(jj);
    k.MiDate = ii;

    % Calculate market impact in basis points and convert to currency
    o.MI(kk) = marketImpact(k,TradeDataStressTest(jj,:));
    o.MIDollar(kk) = (TradeDataStressTest.Shares(jj) * TradeDataStressTest.Price(jj)) * o.MI(kk) /10000 * TradeDataStressTest.FXRate(jj);
 
    % Increment output index
    kk = kk + 1;
    
  end
    
end




