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).
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 structu_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” function should be used.
Arguments
loan
- An instance of the Loan structu_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 can be called instead of experiment loan to provide a simpler API than obtaining the analytics from “experiment_loan” and running them through the “risk_contribution” function.
Arguments
loan
- An instance of the Loan structu_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. Likely to be 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.
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.
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_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. Likely to be 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);