Struct loan_ec::EconomicCapitalAttributes
source · pub struct EconomicCapitalAttributes {
pub cf: Vec<Complex<f64>>,
pub el_vec: Vec<f64>,
pub var_vec: Vec<f64>,
pub num_w: usize,
pub lambda: f64,
}
Expand description
Holds the attributes for the entire portfolio.
Fields§
§cf: Vec<Complex<f64>>
Holds the characteristic function for the portfolio (without multiplying by the systemic variables). The only use case for this element is when used as an input into get_experiment_full_cf.
el_vec: Vec<f64>
The expected value (first moment) vector of length num_w for the portfolio.
var_vec: Vec<f64>
The second moment vector of length num_w for the portfolio (p_j E[l^2]w_j).
num_w: usize
The number of systemic random variables.
lambda: f64
The total liquidity risk for the portfolio. This is the sum of r*balance over the portfolio.
Implementations§
source§impl EconomicCapitalAttributes
impl EconomicCapitalAttributes
Implements economic capital structure
sourcepub fn new(num_u: usize, num_w: usize) -> EconomicCapitalAttributes
pub fn new(num_u: usize, num_w: usize) -> EconomicCapitalAttributes
Creates a new (base) economic capital struct
Examples
extern crate loan_ec;
let num_u:usize=100;
let num_w:usize=3;
let ec_attributes=loan_ec::EconomicCapitalAttributes::new(num_u, num_w);
sourcepub fn process_loan<U>(
&mut self,
loan: &Loan,
u_domain: &[Complex<f64>],
log_lpm_cf: U
)where
U: Fn(&Complex<f64>, &Loan) -> Complex<f64> + Sync + Send,
pub fn process_loan<U>(
&mut self,
loan: &Loan,
u_domain: &[Complex<f64>],
log_lpm_cf: U
)where
U: Fn(&Complex<f64>, &Loan) -> Complex<f64> + Sync + Send,
Adds a new loan to the portfolio. Mutates el_vec, var_vec, cf, and lambda.
Arguments
loan
- An instance of the Loan struct.u_domain
- The vector of complex values provided to the characteristic function. Is typically generated by the fang_oost repository. See the example.log_lpm_cf
- The result from calling get_log_lpm_cf.
Examples
extern crate loan_ec;
extern crate fang_oost;
extern crate rayon;
extern crate num_complex;
use rayon::prelude::*;
use num_complex::Complex;
let num_u:usize=100;
let num_w:usize=1;
let x_min=-5000.0;
let x_max=0.0;
let mut ec_attributes=loan_ec::EconomicCapitalAttributes::new(num_u, num_w);
let loan=loan_ec::Loan{
pd: 0.05,
lgd: 0.5,
lgd_variance: 0.2,
balance: 1.0,
r: 0.0,
weight: vec![1.0],
num: 10000.0
};
let u_domain: Vec<Complex<f64>> = fang_oost::get_u_domain(num_u, x_min, x_max).collect();
let lambda=1000.0;
let q=0.0001;
let liquid_fn = loan_ec::get_liquidity_risk_fn(lambda, q);
//the exponent is negative because l represents a loss
let lgd_fn = |u: &Complex<f64>, l: f64, _lgd_v: f64| (-u * l).exp();
let log_lpm_cf = loan_ec::get_log_lpm_cf(&lgd_fn, &liquid_fn);
ec_attributes.process_loan(&loan, &u_domain, &log_lpm_cf);
sourcepub fn experiment_loan<U>(
&self,
loan: &Loan,
u_domain: &[Complex<f64>],
log_lpm_cf: U
) -> EconomicCapitalAttributeswhere
U: Fn(&Complex<f64>, &Loan) -> Complex<f64> + Sync + Send,
pub fn experiment_loan<U>(
&self,
loan: &Loan,
u_domain: &[Complex<f64>],
log_lpm_cf: U
) -> EconomicCapitalAttributeswhere
U: Fn(&Complex<f64>, &Loan) -> Complex<f64> + Sync + Send,
Performs marginal analytics for a potential loan to the portfolio. The typical use case is for pricing a new loan that could potentially be added to the portfolio. For a loan is already in the portfolio, the process_loan method should be used.
Arguments
loan
- An instance of the Loan struct. This is the loan to experiment on.u_domain
- The vector of complex values provided to the characteristic function. Is typically generated by the fang_oost repository. See the example.log_lpm_cf
- The result from calling get_log_lpm_cf.
Examples
extern crate loan_ec;
extern crate fang_oost;
extern crate rayon;
extern crate num_complex;
use rayon::prelude::*;
use num_complex::Complex;
let num_u:usize=100;
let num_w:usize=1;
let x_min=-5000.0;
let x_max=0.0;
let q=0.0001;
let lambda=1000.0;
let mut ec_attributes=loan_ec::EconomicCapitalAttributes::new(num_u, num_w);
let loan=loan_ec::Loan{
pd: 0.05,
lgd: 0.5,
lgd_variance: 0.2,
balance: 1.0,
r: 0.0,
weight: vec![1.0],
num: 10000.0
};
let liquid_fn = loan_ec::get_liquidity_risk_fn(lambda, q);
let u_domain: Vec<Complex<f64>> = fang_oost::get_u_domain(num_u, x_min, x_max).collect();
let lgd_fn = |u: &Complex<f64>, l: f64, _lgd_v: f64| (-u * l).exp();
let log_lpm_cf = loan_ec::get_log_lpm_cf(&lgd_fn, &liquid_fn);
ec_attributes.process_loan(&loan, &u_domain, &log_lpm_cf);
let loan_ec::EconomicCapitalAttributes{
cf, el_vec, var_vec, lambda, num_w
}=ec_attributes.experiment_loan(
&loan, &u_domain,
&log_lpm_cf
);
sourcepub fn experiment_risk_contribution<U, V, T>(
&self,
loan: &Loan,
u_domain: &[Complex<f64>],
log_lpm_cf: U,
lambda0: f64,
q: f64,
mgf_systemic: V,
el_sys: &[f64],
var_sys: &[f64],
risk_measure_fn: T
) -> f64where
U: Fn(&Complex<f64>, &Loan) -> Complex<f64> + Sync + Send,
V: Fn(&[Complex<f64>]) -> Complex<f64> + Sync + Send,
T: Fn(&[Complex<f64>]) -> f64 + Sync + Send,
pub fn experiment_risk_contribution<U, V, T>(
&self,
loan: &Loan,
u_domain: &[Complex<f64>],
log_lpm_cf: U,
lambda0: f64,
q: f64,
mgf_systemic: V,
el_sys: &[f64],
var_sys: &[f64],
risk_measure_fn: T
) -> f64where
U: Fn(&Complex<f64>, &Loan) -> Complex<f64> + Sync + Send,
V: Fn(&[Complex<f64>]) -> Complex<f64> + Sync + Send,
T: Fn(&[Complex<f64>]) -> f64 + Sync + Send,
Finds the risk contribution of a new loan. This provides a simpler API than obtaining the results from experiment_loan and running them through the risk_contribution function.
Arguments
loan
- An instance of the Loan struct.
This is the loan to experiment on.u_domain
- The vector of complex values provided to the characteristic function. Is typically generated by the fang_oost repository. See the example.log_lpm_cf
- The result from calling get_log_lpm_cf.lambda0
- Base loss (in dollars) from a liquidity event. A positive number.q
- Probability of liquidity event (scaled by the total portfolio loss).mgf_systemic
- Moment generating function for the systemic random variables. Typically a function of el_sys and var_sys.el_sys
- The vector of expected values for the systemic random variables. This is typically a vector of ones.var_sys
- The vector of variances for the systemic random variables.risk_measure_fn
- Function which computes the risk measure for the portfolio, e.g. VaR.
Examples
extern crate loan_ec;
extern crate fang_oost;
extern crate rayon;
extern crate num_complex;
use rayon::prelude::*;
use num_complex::Complex;
extern crate cf_dist_utils;
let num_u:usize=100;
let num_w:usize=1;
let x_min=-5000.0;
let x_max=0.0;
let mut ec_attributes=loan_ec::EconomicCapitalAttributes::new(num_u, num_w);
let loan=loan_ec::Loan{
pd: 0.05,
lgd: 0.5,
lgd_variance: 0.2,
balance: 1.0,
r: 0.0,
weight: vec![1.0],
num: 10000.0
};
let lambda0=1000.0;
let q=0.0001;
let liquid_fn = loan_ec::get_liquidity_risk_fn(lambda0, q);
let u_domain: Vec<Complex<f64>> = fang_oost::get_u_domain(num_u, x_min, x_max).collect();
let lgd_fn = |u: &Complex<f64>, l: f64, _lgd_v: f64| (-u * l).exp();
let log_lpm_cf = loan_ec::get_log_lpm_cf(&lgd_fn, &liquid_fn);
ec_attributes.process_loan(&loan, &u_domain, &log_lpm_cf);
let systemic_expectation = vec![1.0];
let v = vec![0.4];
let quantile=0.01;
let systemic_mgf=|u_weights: &[Complex<f64>]| -> Complex<f64> {
u_weights
.iter()
.zip(&v)
.map(|(u, v_inst)| -(1.0 - v_inst * u).ln() / v_inst)
.sum::<Complex<f64>>()
.exp()
};
let max_iterations = 100;
let tolerance = 0.0001;
let risk_measure_fn = |final_cf: &[Complex<f64>]| {
let (_es, var) = cf_dist_utils::get_expected_shortfall_and_value_at_risk_discrete_cf(
quantile,
x_min,
x_max,
max_iterations,
tolerance,
final_cf,
);
var
};
let rc = ec_attributes.experiment_risk_contribution(
&loan,
&u_domain,
&log_lpm_cf,
lambda0,
q,
&systemic_mgf,
&systemic_expectation,
&v,
&risk_measure_fn,
);
sourcepub fn get_portfolio_expectation(&self, el_sys: &[f64]) -> f64
pub fn get_portfolio_expectation(&self, el_sys: &[f64]) -> f64
Gets the expected value of the portfolio without liquidity risk. This should be called after processing all the loans in the portfolio. The result of this function can be used as the third argument in expectation_liquidity to obtain the expectation with liquidity risk. The result of this function can be used as the third argument in variance_liquidity to obtain the variance with liquidity risk.
Arguments
el_sys
- The vector of expected values for the systemic random variables. This is typically a vector of ones.
Examples
extern crate loan_ec;
extern crate fang_oost;
extern crate rayon;
extern crate num_complex;
use rayon::prelude::*;
use num_complex::Complex;
extern crate cf_dist_utils;
let num_u:usize=100;
let num_w:usize=1;
let x_min=-5000.0;
let x_max=0.0;
let expectation=vec![1.0];
let lambda=1000.0;
let q=0.0001;
let liquid_fn = loan_ec::get_liquidity_risk_fn(lambda, q);
//the exponent is negative because l represents a loss
let lgd_fn = |u: &Complex<f64>, l: f64, _lgd_v: f64| (-u * l).exp();
let log_lpm_cf = loan_ec::get_log_lpm_cf(&lgd_fn, &liquid_fn);
let mut ec_attributes=loan_ec::EconomicCapitalAttributes::new(num_u, num_w);
let loan=loan_ec::Loan{
pd: 0.05,
lgd: 0.5,
lgd_variance: 0.2,
balance: 1.0,
r: 0.0,
weight: vec![1.0],
num: 10000.0
};
let u_domain: Vec<Complex<f64>> = fang_oost::get_u_domain(num_u, x_min, x_max).collect();
ec_attributes.process_loan(&loan, &u_domain, &log_lpm_cf);
let expectation_portfolio=ec_attributes.get_portfolio_expectation(&expectation);
sourcepub fn get_portfolio_variance(&self, el_sys: &[f64], var_sys: &[f64]) -> f64
pub fn get_portfolio_variance(&self, el_sys: &[f64], var_sys: &[f64]) -> f64
Gets the variance of the portfolio without liquidity risk. This should be called after processing all the loans in the portfolio. The result of this function can be used as the fourth argument in variance_liquidity to obtain the variance with liquidity risk.
Arguments
el_sys
- The vector of expected values for the systemic random variables. This is typically a vector of ones.var_sys
- The vector of variances for the systemic random variables.
Examples
extern crate loan_ec;
extern crate fang_oost;
extern crate rayon;
extern crate num_complex;
use num_complex::Complex;
use rayon::prelude::*;
let num_u:usize=100;
let num_w:usize=1;
let x_min=-5000.0;
let x_max=0.0;
let systemic_expectation = vec![1.0];
let v = vec![0.4];
let mut ec_attributes=loan_ec::EconomicCapitalAttributes::new(num_u, num_w);
let loan=loan_ec::Loan{
pd: 0.05,
lgd: 0.5,
lgd_variance: 0.2,
balance: 1.0,
r: 0.0,
weight: vec![1.0],
num: 10000.0
};
let lambda=1000.0;
let q=0.0001;
let liquid_fn = loan_ec::get_liquidity_risk_fn(lambda, q);
//the exponent is negative because l represents a loss
let lgd_fn = |u: &Complex<f64>, l: f64, _lgd_v: f64| (-u * l).exp();
let log_lpm_cf = loan_ec::get_log_lpm_cf(&lgd_fn, &liquid_fn);
let u_domain: Vec<Complex<f64>> = fang_oost::get_u_domain(num_u, x_min, x_max).collect();
ec_attributes.process_loan(&loan, &u_domain, &log_lpm_cf);
let variance_portfolio=ec_attributes.get_portfolio_variance(&systemic_expectation, &v);
sourcepub fn get_experiment_full_cf<U>(
&self,
cf: &[Complex<f64>],
mgf: &U
) -> Vec<Complex<f64>>where
U: Fn(&[Complex<f64>]) -> Complex<f64> + Sync + Send,
pub fn get_experiment_full_cf<U>(
&self,
cf: &[Complex<f64>],
mgf: &U
) -> Vec<Complex<f64>>where
U: Fn(&[Complex<f64>]) -> Complex<f64> + Sync + Send,
Merges the loan exponents with the systemic variables moment generating function to obtain the discrete characteristic function for the portfolio. This should be called after obtaining the cf element from an experiment. If only the risk contribution is required, consider using the experiment_risk_contribution method instead.
sourcepub fn get_full_cf<U>(&self, mgf_systemic: &U) -> Vec<Complex<f64>>where
U: Fn(&[Complex<f64>]) -> Complex<f64> + Sync + Send,
pub fn get_full_cf<U>(&self, mgf_systemic: &U) -> Vec<Complex<f64>>where
U: Fn(&[Complex<f64>]) -> Complex<f64> + Sync + Send,
Gets the discrete characteristic function for the portfolio. This should be called after processing all the loans in the portfolio.
Arguments
mgf_systemic
- Moment generating function for the systemic random variables. Typically a function of el_sys and var_sys.
Examples
extern crate loan_ec;
extern crate fang_oost;
extern crate rayon;
extern crate num_complex;
use rayon::prelude::*;
use num_complex::Complex;
extern crate cf_dist_utils;
let num_u:usize=100;
let num_w:usize=1;
let x_min=-5000.0;
let x_max=0.0;
let systemic_expectation = vec![1.0];
let v = vec![0.4];
let lambda=1000.0;
let q=0.0001;
let liquid_fn = loan_ec::get_liquidity_risk_fn(lambda, q);
//the exponent is negative because l represents a loss
let lgd_fn = |u: &Complex<f64>, l: f64, _lgd_v: f64| (-u * l).exp();
let log_lpm_cf = loan_ec::get_log_lpm_cf(&lgd_fn, &liquid_fn);
let mut ec_attributes=loan_ec::EconomicCapitalAttributes::new(num_u, num_w);
let systemic_mgf=|u_weights: &[Complex<f64>]| -> Complex<f64> {
u_weights
.iter()
.zip(&v)
.map(|(u, v_inst)| -(1.0 - v_inst * u).ln() / v_inst)
.sum::<Complex<f64>>()
.exp()
};
let loan=loan_ec::Loan{
pd: 0.05,
lgd: 0.5,
lgd_variance: 0.2,
balance: 1.0,
r: 0.0,
weight: vec![1.0],
num: 10000.0
};
let u_domain: Vec<Complex<f64>> = fang_oost::get_u_domain(num_u, x_min, x_max).collect();
ec_attributes.process_loan(&loan, &u_domain, &log_lpm_cf);
let cf=ec_attributes.get_full_cf(&systemic_mgf);