Value at risk (VaR)¶
Value at risk (VaR) is a risk metric representing the maximum possible loss for a given holding horizon and specific level of confidence. It is mostly to used to estimate the lower bound of the portfolio returns given its realised returns.
Assume that the realised returns are normally distributed. VaR95 expects only 5% of observations breaches the threshold deduced by the portfolio volatility forecast
where \(Q_{0.05}\) is the 5% quantile of the standard normal distribution and \(\sigma_t\) is the volatility forecast of the portfolio deduced by the risk model, with information up to time \(t\).
The rolling-window VaR breach statistics is then defined as
where \(1[x]\) is the indicator function whether x is satisfied, and \(r_t\) is the observed return in the interval of \([t, t+1]\)
The expected rolling-window VaR breach statistics should be around 5% (or 1% for VaR99), while the risk model
overestimates the risk if it is below the expected percentage, and
underestimates the risk otherwise
Usage¶
Assume that you have market returns returns in a DataFrame, portfolio
weights weights in a DataFrame (it could be equally weighted, or market
cap weighted), and rolling risk models, which can be a RollingRiskModel
object, or just a dictionary of covariances. To compute the bias statistic
in a 21-day rolling window, you can use the following code snippet.
from fpm_risk_model.accuracy.value_at_risk import (
compute_value_at_risk_breach_statistics
)
compute_value_at_risk_breach_statistics(
X=returns,
weights=weights,
rolling_risk_model=rolling_risk_model,
window=30,
)
In the meantime, if you have the forecast portfolio volatility, named
forecast_vols, from vendor, you can directly pass it into the function
as well.
compute_value_at_risk_breach_statistics(
X=returns,
weights=weights,
forecast_vols=forecast_vols,
window=30,
)
Please refer to the below section for more information.
Reference¶
Alexander, Carol (2009). Market risk analysis, value at risk models. John Wiley & Sons.
Module¶
- fpm_risk_model.accuracy.value_at_risk.compute_value_at_risk_threshold(weights: DataFrame, rolling_risk_model: Optional[Union[RollingFactorRiskModel, Dict[Any, Any]]] = None, forecast_vols: Optional[Series] = None, threshold: Optional[float] = 0.95, cov_halflife: Optional[float] = None) Series¶
Compute the VaR threshold for the given weights.
Parameters¶
- weightsDataFrame
The portfolio weights for each instrument. The input index and columns are the date / time and instruments respectively. The weights should be normalized, i.e. sum to one for each time frame.
- rolling_risk_model: Union[RollingFactorRiskModel, Dict[Any, Any]]
A rolling risk model object or dictionary of covariances of which the keys and values are dates and covariances.
- forecast_vols: Optional[Series]
The forecast volatility of instruments.
- threshold: float
The threshold for the VaR. The value should be between 0 and 1. Default is 95%.
- cov_halflife: Optional[float]
Halflife in computing covariances.
- fpm_risk_model.accuracy.value_at_risk.compute_value_at_risk_breach_statistics(X: DataFrame, weights: DataFrame, rolling_risk_model: Optional[Union[RollingFactorRiskModel, Dict[Any, Any]]] = None, forecast_vols: Optional[Series] = None, threshold: Optional[float] = 0.95, cov_halflife: Optional[float] = None) Series¶
Compute the VaR breach statistics.
Parameters¶
- X: DataFrame
Instrument returns. The input index and columns are date / time and instruments respectively.
- weightsDataFrame
The portfolio weights for each instrument. The input index and columns are the date / time and instruments respectively. The weights should be normalized, i.e. sum to one for each time frame.
- rolling_risk_model: Union[RollingFactorRiskModel, Dict[Any, Any]]
A rolling risk model object or dictionary of covariances of which the keys and values are dates and covariances.
- forecast_vols: Optional[Series]
The forecast volatility of instruments.
- threshold: float
The threshold for the VaR. The value should be between 0 and 1. Default is 95%.
- cov_halflife: Optional[float]
Halflife in computing covariances.
- fpm_risk_model.accuracy.value_at_risk.compute_value_at_risk_rolling_breach_statistics(X: ndarray, weights: ndarray, window: int, rolling_risk_model: Optional[Union[RollingFactorRiskModel, Dict[Any, Any]]] = None, forecast_vols: Optional[Series] = None, threshold: Optional[float] = 0.95, min_periods: Optional[int] = None, cov_halflife: Optional[float] = None) Series¶
Compute the VaR breach statistics.
Parameters¶
- X: DataFrame
Instrument returns. The input index and columns are date / time and instruments respectively.
- weightsDataFrame
The portfolio weights for each instrument. The input index and columns are the date / time and instruments respectively. The weights should be normalized, i.e. sum to one for each time frame.
- window: int
The number of rolling time frames to compute the percentage of returns breaching the specified VaR.
- rolling_risk_model: Union[RollingFactorRiskModel, Dict[Any, Any]]
A rolling risk model object or dictionary of covariances of which the keys and values are dates and covariances.
- forecast_vols: Optional[Series]
The forecast volatility of instruments.
- threshold: Optional[float]
The threshold for the VaR. The value should be between 0 and 1. Default is 95%.
- cov_halflife: Optional[float]
Halflife in computing covariances.