Rolling Windows and Multiple Models for Expected Shortfall (ES) Backtesting by Du and Escanciano
This example shows the workflow for using the Du-Escanciano (DE) expected shortfall (ES) backtests for rolling window analyses and testing multiple VaR/ES models.
The rolling window workflow in this example is also used for the value-at-risk (VaR) backtests in varbacktest
and for the Acerbi-Szekely ES backtests in the esbacktest
and esbacktestbysim
classes.
The multiple-model workflow in this example is also used for the esbacktestbysim
class. For esbacktest
and varbacktest
, you can create a single object with multiple models and multiple VaR levels.
Rolling Window
The data in the ESBacktestDistributionData.mat
file has returns, VaR and ES data, and distribution information for three models: normal, and t with 5 degrees of freedom and t with 10 degrees of freedom. The data spans multiple years from January 1996 to July 2003, for a total of 1966 observations.
To run the test over a rolling window, one esbacktestbyde
object must be created for each year (or time period) of interest. In this example, each year from 1996 through 2002 is tested separately. You can test all VaR levels together, but to simplify the output, this example uses a single VaR level. You can also call any test, or the summary
report inside the processing loop, but this example calls only the runtests
function.
load ESBacktestDistributionData.mat rng('default'); % For reproducibility Years = 1996:2002; TargetVaRLevel = 0.99; t = table; for TargetYear = Years Ind = year(Dates)==TargetYear; VaRInd = VaRLevel==TargetVaRLevel; ebtde = esbacktestbyde(Returns(Ind),"t",... 'DegreesOfFreedom',10,... 'Location',0,... % Always 0 in this data set 'Scale',T10Scale(Ind),... 'VaRLevel',VaRLevel(VaRInd),... 'PortfolioID',strcat("S&P, ",string(TargetYear)),... 'VaRID',"t(10)"); t = [t; runtests(ebtde)]; end disp(t)
PortfolioID VaRID VaRLevel ConditionalDE UnconditionalDE ___________ _______ ________ _____________ _______________ "S&P, 1996" "t(10)" 0.99 reject reject "S&P, 1997" "t(10)" 0.99 accept reject "S&P, 1998" "t(10)" 0.99 accept accept "S&P, 1999" "t(10)" 0.99 reject accept "S&P, 2000" "t(10)" 0.99 accept accept "S&P, 2001" "t(10)" 0.99 accept accept "S&P, 2002" "t(10)" 0.99 reject accept
For a more advanced approach, you can use arrays of esbacktestbyde
objects and then call different functions on objects corresponding to different years as needed.
rng('default'); % For reproducibility NumYears = length(Years); ebtdeArray(NumYears) = esbacktestbyde; TargetVaRLevel = 0.99; for yy = 1:NumYears TargetYear = Years(yy); Ind = year(Dates)==TargetYear; VaRInd = VaRLevel==TargetVaRLevel; ebtdeArray(yy) = esbacktestbyde(Returns(Ind),"t",... 'DegreesOfFreedom',10,... 'Location',0,... % Always 0 in this data set 'Scale',T10Scale(Ind),... 'VaRLevel',VaRLevel(VaRInd),... 'PortfolioID',strcat("S&P, ",string(TargetYear)),... 'VaRID',"t(10)"); end disp(ebtdeArray)
1x7 esbacktestbyde array with properties: PortfolioData VaRData ESData Distribution PortfolioID VaRID VaRLevel
Display the summary for the year 2002.
disp(summary(ebtdeArray(Years==2002)))
PortfolioID VaRID VaRLevel ObservedLevel ExpectedSeverity ObservedSeverity Observations Failures Expected Ratio Missing ___________ _______ ________ _____________ ________________ ________________ ____________ ________ ________ ______ _______ "S&P, 2002" "t(10)" 0.99 0.98467 1.2169 1.1481 261 4 2.61 1.5326 0
Concatenate the conditional tests for all years.
condDEResults = table; for yy = 1:NumYears condDEResults = [condDEResults; conditionalDE(ebtdeArray(yy))]; end disp(condDEResults)
PortfolioID VaRID VaRLevel ConditionalDE PValue TestStatistic CriticalValue AutoCorrelation Observations CriticalValueMethod NumLags Scenarios TestLevel ___________ _______ ________ _____________ __________ _____________ _____________ _______________ ____________ ___________________ _______ _________ _________ "S&P, 1996" "t(10)" 0.99 reject 0.0084691 6.9315 3.8415 0.16265 262 "large-sample" 1 NaN 0.95 "S&P, 1997" "t(10)" 0.99 accept 0.85691 0.032512 3.8415 -0.011161 261 "large-sample" 1 NaN 0.95 "S&P, 1998" "t(10)" 0.99 accept 0.87949 0.022989 3.8415 -0.0093851 261 "large-sample" 1 NaN 0.95 "S&P, 1999" "t(10)" 0.99 reject 2.1168e-50 222.89 3.8415 0.92412 261 "large-sample" 1 NaN 0.95 "S&P, 2000" "t(10)" 0.99 accept 0.89052 0.018948 3.8415 -0.0085367 260 "large-sample" 1 NaN 0.95 "S&P, 2001" "t(10)" 0.99 accept 0.92088 0.0098664 3.8415 -0.0061484 261 "large-sample" 1 NaN 0.95 "S&P, 2002" "t(10)" 0.99 reject 3.5974e-05 17.073 3.8415 0.25576 261 "large-sample" 1 NaN 0.95
Multiple Models
Similar to the esbacktestbysim
object, the esbacktestbyde
object accepts only one distribution at a time. If you need to test different models side by side, then you must create different instances of the class.
In this example you run the test for a normal distribution assumption and t distributions with 5 and 10 degrees of freedom. You then concatenate the test results to generate a single report.
The data in the ESBacktestDistributionData.mat
file has returns, VaR and ES data, and distribution information for three models: normal, and t with 5 and 10 degrees of freedom. The data spans multiple years from January 1996 to July 2003, for a total of 1966 observations. For simplicity, this example uses only data from 1998.
load ESBacktestDistributionData.mat TargetYear = 1998; Ind = year(Dates)==TargetYear; rng('default'); % For reproducibility
Create an instance of an esbacktestbyde
object for the normal distribution.
ebtdeNormal = esbacktestbyde(Returns(Ind),"normal",... 'Mean',0,... 'StandardDeviation',NormalStd(Ind),... 'VaRLevel',VaRLevel,... 'PortfolioID',strcat("S&P, ",string(TargetYear)),... 'VaRID',"normal"); disp(ebtdeNormal)
esbacktestbyde with properties: PortfolioData: [261x1 double] VaRData: [261x3 double] ESData: [261x3 double] Distribution: [1x1 struct] PortfolioID: "S&P, 1998" VaRID: ["normal" "normal" "normal"] VaRLevel: [0.9500 0.9750 0.9900]
disp(ebtdeNormal.Distribution)
Name: "normal" Mean: 0 StandardDeviation: [261x1 double]
Create an instance of an esbacktestbyde
object for the t distribution with 10 degrees of freedom.
ebtdeT10 = esbacktestbyde(Returns(Ind),"t",... 'DegreesOfFreedom',10,... 'Location',0,... 'Scale',T10Scale(Ind),... 'VaRLevel',VaRLevel,... 'PortfolioID',strcat("S&P, ",string(TargetYear)),... 'VaRID',"t(10)"); disp(ebtdeT10)
esbacktestbyde with properties: PortfolioData: [261x1 double] VaRData: [261x3 double] ESData: [261x3 double] Distribution: [1x1 struct] PortfolioID: "S&P, 1998" VaRID: ["t(10)" "t(10)" "t(10)"] VaRLevel: [0.9500 0.9750 0.9900]
disp(ebtdeT10.Distribution)
Name: "t" DegreesOfFreedom: 10 Location: 0 Scale: [261x1 double]
Create an instance of an esbacktestbyde
object for the t distribution with 5 degrees of freedom.
ebtdeT5 = esbacktestbyde(Returns(Ind),"t",... 'DegreesOfFreedom',5,... 'Location',0,... 'Scale',T5Scale(Ind),... 'VaRLevel',VaRLevel,... 'PortfolioID',strcat("S&P, ",string(TargetYear)),... 'VaRID',"t(5)"); disp(ebtdeT5)
esbacktestbyde with properties: PortfolioData: [261x1 double] VaRData: [261x3 double] ESData: [261x3 double] Distribution: [1x1 struct] PortfolioID: "S&P, 1998" VaRID: ["t(5)" "t(5)" "t(5)"] VaRLevel: [0.9500 0.9750 0.9900]
disp(ebtdeT5.Distribution)
Name: "t" DegreesOfFreedom: 5 Location: 0 Scale: [261x1 double]
Run the tests and then concatenate the results.
testResults = [runtests(ebtdeNormal); runtests(ebtdeT10); runtests(ebtdeT5)]; disp(testResults)
PortfolioID VaRID VaRLevel ConditionalDE UnconditionalDE ___________ ________ ________ _____________ _______________ "S&P, 1998" "normal" 0.95 accept accept "S&P, 1998" "normal" 0.975 accept accept "S&P, 1998" "normal" 0.99 accept reject "S&P, 1998" "t(10)" 0.95 accept accept "S&P, 1998" "t(10)" 0.975 accept accept "S&P, 1998" "t(10)" 0.99 accept accept "S&P, 1998" "t(5)" 0.95 accept accept "S&P, 1998" "t(5)" 0.975 accept accept "S&P, 1998" "t(5)" 0.99 accept accept
Display the results for a VaR level of 0.99
.
TargetVaRLevel = 0.99; disp(testResults(testResults.VaRLevel == TargetVaRLevel,:))
PortfolioID VaRID VaRLevel ConditionalDE UnconditionalDE ___________ ________ ________ _____________ _______________ "S&P, 1998" "normal" 0.99 accept reject "S&P, 1998" "t(10)" 0.99 accept accept "S&P, 1998" "t(5)" 0.99 accept accept
See Also
esbacktestbyde
| esbacktest
| esbacktestbysim
| varbacktest
Related Topics
- VaR Backtesting Workflow
- Value-at-Risk Estimation and Backtesting
- Expected Shortfall (ES) Backtesting Workflow with No Model Distribution Information
- Expected Shortfall (ES) Backtesting Workflow Using Simulation
- Expected Shortfall Estimation and Backtesting
- Workflow for Expected Shortfall (ES) Backtesting by Du and Escanciano