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. The “cf” element holds the characteristic function for the portfolio. The “el_vec” element holds the expected value (first moment) vector of length num_w for the portfolio. The “var_vec” element holds the second moment vector of length num_w for the portfolio p_j E[l^2]w_j. The “num_w” element holds the number of systemic random variables. The “lambda” element holds the total liquidity risk for the portfolio (derived from each loan).
Fields§
§cf: Vec<Complex<f64>>
§el_vec: Vec<f64>
§var_vec: Vec<f64>
§num_w: usize
§lambda: f64
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.
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(256, 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.
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. The “lambda0” argument is the base loss in a liquidity event, independent of loan’s liquidity. The “q” argument is the scalar to adjust the probability of a liquidity event. Proportional to the probability of a liquidity event. The “mgf_systemic” argument is the moment generating function is 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 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);
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 lambda0=1000.0;
let q=0.0001;
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, expectation_systemic: &[f64]) -> f64
pub fn get_portfolio_expectation(&self, expectation_systemic: &[f64]) -> f64
Gets the expected value of the portfolio without liquidity risk. This should be called after processing all the loans in the portfolio.
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,
expectation_systemic: &[f64],
variance_systemic: &[f64]
) -> f64
pub fn get_portfolio_variance(
&self,
expectation_systemic: &[f64],
variance_systemic: &[f64]
) -> f64
Gets the variance of the portfolio without liquidity risk. This should be called after processing all the loans in the portfolio.
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: &U) -> Vec<Complex<f64>>where
U: Fn(&[Complex<f64>]) -> Complex<f64> + Sync + Send,
pub fn get_full_cf<U>(&self, mgf: &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.
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);