model_clo_insight.engines.solvers module¶
Module which contains the core optimization methods for the hypo pool generation
- monitor_metric(riskscore_max, run_mode, shell_pool, wal, coef_sdr, risk_score_tbl, IDT_sp, WARF_sp, force_high, force_low)¶
Computes the 2 metrics used in the CDO Monitor computation
BDR: Break Even Default Rate
SDR: Scenario Default Rate (analagous to the DBRSM CLO Asset Model hurdle rate output)
- Parameters
riskscore_max (float) – max DBRSM risk score of the pool
run_mode (str) – Expected portfolio default rate (EPDR) or WA Rating Factor (SP_WARF)
shell_pool (list[clo_internal_objects.Obligor]) – pool where obligor & industry percentages have been previously solved for a given Dscore
wal (float) – Target portfolio weighted average life
coef_sdr (list) – Scenario even default rate (SDR) coefficients for the transaction
risk_score_tbl (dict[int, float]) – lookup table for DBRSM Risk Score
IDT_sp (ndarray) – idealized default 2-D table; sourced from transaction documents
WARF_sp (ndarray) – WARF-equivalent 1-D table; sourced from transaction documents
force_high (tuple) – (rating_number, pct) for higher rtg prior to solving for risk score, force this on pool
force_low (tuple) – (rating_number, pct) for lower rtg prior to solving for risk score, force this on pool
- Returns
Monitor SDR, SDR diagnostics dictionary
- Return type
- monitor_objective_function(riskscore_max, run_mode, target_sdr, shell_pool, wal, coef_sdr, risk_score_tbl, IDT_sp, WARF_sp, force_high, force_low)¶
Used as the objective funtion in the optimizers
- Parameters
riskscore_max (float) – max DBRSM risk score of the pool; this is what gets iterated over when monitor_objective_function is hooked up to the optimizer
target_sdr (float) – target Monitor SDR metric that the optimizer attempts to reach by iterating over the
shell_pool (list[clo_internal_objects.Obligor]) – pool where obligor & industry percentages have been previously solved for a given Dscore
wal (float) – Target portfolio weighted average life
coef_sdr (list) – Scenario even default rate (SDR) coefficients for the transaction
risk_score_tbl (dict[int, float]) – lookup table for DBRSM Risk Score
IDT_sp (ndarray) – idealized default 2-D table; sourced from transaction documents
WARF_sp (ndarray) – WARF-equivalent 1-D table; sourced from transaction documents
force_high (tuple) – (rating_number, pct) for higher rtg prior to solving for risk score, force this on pool
force_low (tuple) – (rating_number, pct) for lower rtg prior to solving for risk score, force this on pool
- Returns
difference between the actual dscore and the target, solver attempts to minimize this
- Return type
- monitor_pool(riskscore_max, shell_pool, wal, risk_score_tbl, IDT_sp, force_high, force_low, is_compute_pd=True)¶
Applies rating mixture to pool based on riskcore_max, then PD based on lookup tables. Need this to compute expected PD and PD dispersion metrics for the monitor calculation
- Parameters
riskscore_max (float) – max DBRSM risk score of the pool
shell_pool (list[clo_internal_objects.Obligor]) – pool where obligor & industry percentages have been previously solved for a given Dscore
wal (float) – Target portfolio weighted average life
risk_score_tbl (dict[int, float]) – lookup table for DBRSM Risk Score
IDT_sp (ndarray) – idealized default 2-D table; sourced from transaction documents
force_high (tuple) – (rating_number, pct) for higher rtg prior to solving for risk score, force this on pool
force_low (tuple) – (rating_number, pct) for lower rtg prior to solving for risk score, force this on pool
is_compute_pd (bool) – if True, compute the PD for each obligor via IDT lookup
- Returns
hypo pool w/ PD overlay
- Return type
- solve_dscore_ob_base(dscore_min, ob_base, ind_base, riskscore_max, ob_exceptions, ind_exceptions, ob_floor, ind_floor, risk_score_tbl, tables, force_high, force_low, is_simple_industry, n_simple_industry)¶
Solver for a pool based on dscore.
Solves for a pool dscore by forcing ob & ind conc limit exceptions, spinning down the base ob & ind exceptions until the dscore is in compliance. Should not be run directly, but from hypo_pool_master etc.
General Algorithm 1) Construct initial pool using build_pool and calculate dscore 2) If actual dscore > dscore limit, pool is compliant so no need to solve 3) Check lower bound ob base ob/ind max to ensure the solver can find a solution 4) Run numpy’s bisection algo by changing the base ob/ind max at a constant ratio (their initial ratio)
- Parameters
dscore_min (float) – maximum diversity score limit for the pool
ob_base (float) – base max obligor concentration limitation
ind_base (float) – base max industry concentration limitation
riskscore_max (float) – max DBRSM risk score of the pool
ob_exceptions (list[objects.ConcLimitException]) – obligor concentration limitations
ind_exceptions (list[objects.ConcLimitException]) – industry concentration limitations
ob_floor (float) – lowest level that the base obligor concentration limitation is allowed to spin down to
ind_floor (float) – lowest level that the base industry concentration limitation is allowed to spin down to
risk_score_tbl (dict[int, float]) – lookup table for DBRSM Risk Score
tables (dict[str, np.ndarray]) – Lookup tables for Dscore and industry codes
force_high (tuple) – high rating (rating integer, percentage) to lock prior to solving for belly ratings (ratings not in the front end or in the back end of the yield curve)
force_low (tuple) – low rating (rating integer, percentage) to lock prior to solving for belly ratings (ratings not in the front end or in the back end of the yield curve)
is_simple_industry (bool) – if true, industry allocation is done on a repeating sequence. Hypo only iterates on obligor in this case.
n_simple_industry (int) – if is_simple_industry is True, this is the number of industries to repeat in sequence
- Returns
results dictionary
- Return type
Results Dictionary Keys:
is_solve: True if solver found solution, False otherwise
dscore: diversity score calculated on the actual pool
ob_base: base obligor concentration limitation that the solver found
ind_base: base industry concentration limitation that the solver found
obligors: OrderedDict[objects.Obligor] pool of Obligors.
- solve_dscore_ob_ex_partial(dscore_min, ob_base, ind_base, riskscore_max, ob_exceptions, ind_exceptions, ob_ex_partial, ob_floor, risk_score_tbl, tables, force_high, force_low, is_simple_industry, n_simple_industry)¶
Used when an obligor exception is removed in the outer layer algorithm. This solves for a fractional amount of that exception to be included back in the pool such the the target dscore is met
Iterates over the smallest obligor concentration limitation exception
- Parameters
dscore_min (float) – target diversity score for the pool
ob_base (float) – base max obligor concentration limitation
ind_base (float) – base max industry concentration limitation
riskscore_max (float) – max DBRSM risk score of the pool
ob_exceptions (list[objects.ConcLimitException]) – obligor concentration limitations
ind_exceptions (list[objects.ConcLimitException]) – industry concentration limitations
ob_ex_partial (float) – the current smalled obligor concentration limitation exception; gets controlled by solver
ob_floor (float) – lowest level that the base obligor concentration limitation is allowed to spin down to
risk_score_tbl (dict[int, float]) – lookup table for DBRSM Risk Score
tables (dict[str, np.ndarray]) – Lookup tables for Dscore and industry codes
force_high (tuple) – high rating (rating integer, percentage) to lock prior to solving for belly ratings (ratings not in the front end or in the back end of the yield curve)
force_low (tuple) – low rating (rating integer, percentage) to lock prior to solving for belly ratings (ratings not in the front end or in the back end of the yield curve)
is_simple_industry (bool) – if true, industry allocation is done on a repeating sequence. Hypo only iterates on obligor in this case.
n_simple_industry (int) – if is_simple_industry is True, this is the number of industries to repeat in sequence
- Returns
results dictionary
- Return type
- solver_wrap_base_ob(ob_base, ind_mult, target_dscore, riskscore_max, ob_exceptions, ind_exceptions, ind_floor, risk_score_tbl, tables, force_high, force_low, is_simple_industry, n_simple_industry)¶
Objective function passed to the solver algorithm
Iterates over base obligor concentration limitation
Base industry concentration expressed as a multiple of base obligor
- Parameters
ob_base (float) – base max obligor concentration limitation, this gets controlled by the solver
ind_mult (float) – multiplier to reduce the base max ind by a constant proportion to the base max ob
target_dscore (float) – target diversity score limit for the pool
riskscore_max (float) – max DBRSM risk score of the pool
ob_exceptions (list[objects.ConcLimitException]) – obligor concentration limitations
ind_exceptions (list[objects.ConcLimitException]) – industry concentration limitations
ind_floor (float) – minimum that the base industry pct can go; overrides the ind_mult * ob_max if that is too low
risk_score_tbl (dict[int, float]) – lookup table for DBRSM Risk Score
tables (dict[str, np.ndarray]) – Lookup tables for Dscore and industry codes
force_high (tuple) – high rating (rating integer, percentage) to lock prior to solving for belly ratings (ratings not in the front end or in the back end of the yield curve)
force_low (tuple) – low rating (rating integer, percentage) to lock prior to solving for belly ratings (ratings not in the front end or in the back end of the yield curve)
is_simple_industry (bool) – if true, industry allocation is done on a repeating sequence. Hypo only iterates on obligor in this case.
n_simple_industry (int) – if is_simple_industry is True, this is the number of industries to repeat in sequence
- Returns
difference between the actual dscore and the target, solver attempts to minimize this
- Return type
- solver_wrap_ob_ex_partial(ob_ex_partial, ob_base, ind_base, target_dscore, riskscore_max, ob_exceptions, ind_exceptions, risk_score_tbl, tables, force_high, force_low, is_simple_industry, n_simple_industry)¶
Objective function passed to the solver algorithm
Iterates over smallest obligor concentration exception limitation percentage
- Parameters
ob_ex_partial (float) – the current smallest obligor concentration limitation exception; gets controlled by solver
ob_base (float) – base max obligor concentration limitation,
ob_base – base max industry concentration limitation
target_dscore (float) – target diversity score limit for the pool
riskscore_max (float) – max DBRSM risk score of the pool
ob_exceptions (list[clo_internal_objects.ConcLimitException]) – obligor concentration limitations
ind_exceptions (list[clo_internal_objects.ConcLimitException]) – industry concentration limitations
risk_score_tbl (dict[int, float]) – lookup table for DBRSM Risk Score
tables (dict[str, np.ndarray]) – Lookup tables for Dscore and industry codes
force_high (tuple) – high rating (rating integer, percentage) to lock prior to solving for belly ratings (ratings not in the front end or in the back end of the yield curve)
force_low (tuple) – low rating (rating integer, percentage) to lock prior to solving for belly ratings (ratings not in the front end or in the back end of the yield curve)
is_simple_industry (bool) – if true, industry allocation is done on a repeating sequence. Hypo only iterates on obligor in this case.
n_simple_industry (int) – if is_simple_industry is True, this is the number of industries to repeat in sequence
- Returns
difference between the actual dscore and the target, solver attempts to minimize this
- Return type