3.7. Bounds Module

class aggregate.bounds.Bounds(distribution_spec)[source]

Implement IME 2022 pricing bounds methodology.

Typical usage: First, create a Portfolio or Aggregate object a. Then

bd = cd.Bounds(a)
bd.tvar_cloud('line', premium=, a=, n_tps=, s=, kind=)
p_star = bd.p_star('line', premium)
bd.cloud_view(axes, ...)
Parameters

distribution_spec – A Portfolio or Portfolio.density_df dataframe or pd.Series (must have loss as index) If DataFrame or Series values interpreted as desnsity, sum to 1. F, S, exgta all computed using Portfolio methdology If DataFrame line –> p_{line}

__init__(distribution_spec)[source]
cloud_view(*, axs=None, n_resamples=0, scale='linear', alpha=0.05, pricing=True, distortions='ordered', title='', lim=(-0.025, 1.025), check=False, add_average=True)[source]

Visualize the distortion cloud with n_resamples. Execute after computing weights.

Parameters
  • axs

  • n_resamples – if random sample

  • scale – linear or return

  • alpha – opacity

  • pricing – restrict to p_max = 0, ensuring g(s)<1 when s<1

  • distortions – ‘ordered’ shows the usual calibrated distortions, else list of dicts name:distortion.

  • title – optional title (applied to all plots)

  • lim – axis limits

  • check – construct and plot Distortions to check working ; reduces n_resamples to 5

Returns

compute_weight(premium, p0, p1, b=inf, kind='interp')[source]

compute the weight for a single TVaR p0 < p1 value pair

Parameters
  • line

  • premium

  • tp

  • b

Returns

compute_weights(line, premium, n_tps, b=inf, kind='interp')[source]

Compute the weights of the extreme distortions

Applied to min(line, b) (allows to work for net)

Note: independent of the asset level

Parameters
  • line – within port, or total

  • premium – target premium for the line

  • n_tps – number of tvar p points (tps)number of tvar p points (tps)number of tvar p points (tps)number of tvar p points (tps).

  • b – loss bound: compute weights for min(line, b); generally used for net losses only.

Returns

distortion(pl, pu)[source]

Return the BiTVaR with probabilities pl and pu

make_ps(n, mode)[source]

If add_one then you want n = 2**m + 1 to ensure nicely spaced points.

Mode: making s points (always uniform) or tvar p points (use t_mode). self.t_mode == ‘u’: make uniform s points against which to evaluate g from 0 to 1 self.t_mode == ‘gl’: make Gauss-Legndre p points at which TVaRs are evaluated from 0 inclusive to 1 exclusive with more around 1

Parameters

n

Returns

make_tvar_function(line, b=inf)[source]

Change in 0.14.0 with new tvar methodology, this function reflects the b limit, it is the TVaR of min(X, b)

Make unlimited TVaR function for line, self.tvar_unlimited_function, and set self.Fb.

  • Portfolio or Aggregate: get from object

  • DataFrame: make from p_{line} column

  • Series: make from Series

In the last two cases, uses aggregate.utilties.make_var_tvar_function.

Includes determining sup and putting in value for zero. If sup is largest value in index, sup set to inf.

You generally want to apply with a limit, call self.tvar_with_bounds.

Parameters
  • line – only used for portfolio objects, to specify line (or ‘total’)

  • b – bound on the losses, e.g., to model limited liability insurer

Returns

p_star(line, premium, b=inf, kind='interp')[source]

Compute p* so TVaR @ p* of min(X, b) = premium

In this case the cap b has an impact (think of integrating q(p) over p to 1, q is impacted by b)

premium <= b is required (no rip off condition)

If b < inf then must solve TVaR(p) - (1 - F(b)) / (1 - p)[TVaR(F(b)) - b] = premium Let k = (1 - F(b)) [TVaR(F(b)) - b], so solving

f(p) = TVaR(p) - k / (1 - p) - premium == 0

using NR

Parameters
  • line

  • premium – target premium

  • b – bound

  • kind – now ignored

Returns

ped_distortion(n, solver='rs')[source]

make the approximating distortion from the first n Principal Extreme Distortions (PED)s using rs or ip solutions

Parameters

n

Returns

principal_extreme_distortion_analysis(gs, pricing=False)[source]

Find the principal extreme distortion analysis to solve for gs = g(s), s=self.cloud_df.index

Assumes that tvar_cloud has been called and that cloud_df exists len(gs) = len(cloud_df)

E.g., call

b = Bounds(port) b.t_mode = ‘u’ # set premium and asset level a b.tvar_cloud(‘total’, premium, a) # make gs b.principal_extreme_distortion_analysis(gs)

Parameters
  • gs – either g(s) evaluated on s = cloud_df.index or the name of a calibrated distortion in distribution_spec.dists (created by a call to calibrate_distortions)

  • pricing – if try, try just using pricing distortions

Returns

quick_price(distortion, a)[source]

price total to assets a using distortion

requires distribution_spec has a density_df dataframe with a p_total or p_total

TODO: add ability to price other lines :param distortion: :param a: :return:

tvar_array(line, n_tps=257, b=inf, kind='interp')[source]

Compute tvars at n equally spaced points, tps.

Parameters
  • line

  • n_tps – number of tvar p points, default 257 (assuming add-one mode)

  • b – cap on losses applied before computing TVaRs (e.g., adjust losses for finite assets b). Use np.inf for unlimited losses.

  • kind – now ignored.

Returns

tvar_cloud(line, premium, a, n_tps, s, kind='interp')[source]

weight down tvar functions to the extremal convex measures

asset level a acts like an agg stop on what is being priced, i.e. we are working with min(X, a)

Parameters
  • line

  • premium

  • a

  • n_tps

  • s

  • b – bound, applies to min(line, b)

Returns

tvar_hinges(s)[source]

make the tvar hinge functions by evaluating each tvar_p(s) = min(1, s/(1-p) for p in tps, at EP points s

all arguments in [0,1] x [0,1]

Parameters

s

Returns

tvar_with_bound(p, b=inf, kind='interp')[source]

Compute tvar taking bound into account. Assumes tvar_unfunction setup.

Warning: b must equal the b used when calibrated. The issue is computing F which varies with the type of underlying portfolio. This is fragile. Added storing b and checking equal. For backwards comp. need to keep b argument

Parameters
  • p

  • b

  • kind – now ignored

Returns

class aggregate.bounds.Bounds(distribution_spec)[source]

Implement IME 2022 pricing bounds methodology.

Typical usage: First, create a Portfolio or Aggregate object a. Then

bd = cd.Bounds(a)
bd.tvar_cloud('line', premium=, a=, n_tps=, s=, kind=)
p_star = bd.p_star('line', premium)
bd.cloud_view(axes, ...)
Parameters

distribution_spec – A Portfolio or Portfolio.density_df dataframe or pd.Series (must have loss as index) If DataFrame or Series values interpreted as desnsity, sum to 1. F, S, exgta all computed using Portfolio methdology If DataFrame line –> p_{line}

cloud_view(*, axs=None, n_resamples=0, scale='linear', alpha=0.05, pricing=True, distortions='ordered', title='', lim=(-0.025, 1.025), check=False, add_average=True)[source]

Visualize the distortion cloud with n_resamples. Execute after computing weights.

Parameters
  • axs

  • n_resamples – if random sample

  • scale – linear or return

  • alpha – opacity

  • pricing – restrict to p_max = 0, ensuring g(s)<1 when s<1

  • distortions – ‘ordered’ shows the usual calibrated distortions, else list of dicts name:distortion.

  • title – optional title (applied to all plots)

  • lim – axis limits

  • check – construct and plot Distortions to check working ; reduces n_resamples to 5

Returns

compute_weight(premium, p0, p1, b=inf, kind='interp')[source]

compute the weight for a single TVaR p0 < p1 value pair

Parameters
  • line

  • premium

  • tp

  • b

Returns

compute_weights(line, premium, n_tps, b=inf, kind='interp')[source]

Compute the weights of the extreme distortions

Applied to min(line, b) (allows to work for net)

Note: independent of the asset level

Parameters
  • line – within port, or total

  • premium – target premium for the line

  • n_tps – number of tvar p points (tps)number of tvar p points (tps)number of tvar p points (tps)number of tvar p points (tps).

  • b – loss bound: compute weights for min(line, b); generally used for net losses only.

Returns

distortion(pl, pu)[source]

Return the BiTVaR with probabilities pl and pu

make_ps(n, mode)[source]

If add_one then you want n = 2**m + 1 to ensure nicely spaced points.

Mode: making s points (always uniform) or tvar p points (use t_mode). self.t_mode == ‘u’: make uniform s points against which to evaluate g from 0 to 1 self.t_mode == ‘gl’: make Gauss-Legndre p points at which TVaRs are evaluated from 0 inclusive to 1 exclusive with more around 1

Parameters

n

Returns

make_tvar_function(line, b=inf)[source]

Change in 0.14.0 with new tvar methodology, this function reflects the b limit, it is the TVaR of min(X, b)

Make unlimited TVaR function for line, self.tvar_unlimited_function, and set self.Fb.

  • Portfolio or Aggregate: get from object

  • DataFrame: make from p_{line} column

  • Series: make from Series

In the last two cases, uses aggregate.utilties.make_var_tvar_function.

Includes determining sup and putting in value for zero. If sup is largest value in index, sup set to inf.

You generally want to apply with a limit, call self.tvar_with_bounds.

Parameters
  • line – only used for portfolio objects, to specify line (or ‘total’)

  • b – bound on the losses, e.g., to model limited liability insurer

Returns

p_star(line, premium, b=inf, kind='interp')[source]

Compute p* so TVaR @ p* of min(X, b) = premium

In this case the cap b has an impact (think of integrating q(p) over p to 1, q is impacted by b)

premium <= b is required (no rip off condition)

If b < inf then must solve TVaR(p) - (1 - F(b)) / (1 - p)[TVaR(F(b)) - b] = premium Let k = (1 - F(b)) [TVaR(F(b)) - b], so solving

f(p) = TVaR(p) - k / (1 - p) - premium == 0

using NR

Parameters
  • line

  • premium – target premium

  • b – bound

  • kind – now ignored

Returns

ped_distortion(n, solver='rs')[source]

make the approximating distortion from the first n Principal Extreme Distortions (PED)s using rs or ip solutions

Parameters

n

Returns

principal_extreme_distortion_analysis(gs, pricing=False)[source]

Find the principal extreme distortion analysis to solve for gs = g(s), s=self.cloud_df.index

Assumes that tvar_cloud has been called and that cloud_df exists len(gs) = len(cloud_df)

E.g., call

b = Bounds(port) b.t_mode = ‘u’ # set premium and asset level a b.tvar_cloud(‘total’, premium, a) # make gs b.principal_extreme_distortion_analysis(gs)

Parameters
  • gs – either g(s) evaluated on s = cloud_df.index or the name of a calibrated distortion in distribution_spec.dists (created by a call to calibrate_distortions)

  • pricing – if try, try just using pricing distortions

Returns

quick_price(distortion, a)[source]

price total to assets a using distortion

requires distribution_spec has a density_df dataframe with a p_total or p_total

TODO: add ability to price other lines :param distortion: :param a: :return:

tvar_array(line, n_tps=257, b=inf, kind='interp')[source]

Compute tvars at n equally spaced points, tps.

Parameters
  • line

  • n_tps – number of tvar p points, default 257 (assuming add-one mode)

  • b – cap on losses applied before computing TVaRs (e.g., adjust losses for finite assets b). Use np.inf for unlimited losses.

  • kind – now ignored.

Returns

tvar_cloud(line, premium, a, n_tps, s, kind='interp')[source]

weight down tvar functions to the extremal convex measures

asset level a acts like an agg stop on what is being priced, i.e. we are working with min(X, a)

Parameters
  • line

  • premium

  • a

  • n_tps

  • s

  • b – bound, applies to min(line, b)

Returns

tvar_hinges(s)[source]

make the tvar hinge functions by evaluating each tvar_p(s) = min(1, s/(1-p) for p in tps, at EP points s

all arguments in [0,1] x [0,1]

Parameters

s

Returns

tvar_with_bound(p, b=inf, kind='interp')[source]

Compute tvar taking bound into account. Assumes tvar_unfunction setup.

Warning: b must equal the b used when calibrated. The issue is computing F which varies with the type of underlying portfolio. This is fragile. Added storing b and checking equal. For backwards comp. need to keep b argument

Parameters
  • p

  • b

  • kind – now ignored

Returns

aggregate.bounds.plot_lee(port, ax, c, lw=1)[source]

Lee diagram by hand

aggregate.bounds.plot_max_min(self, ax)[source]

Extracted from bounds, self=Bounds object

aggregate.bounds.similar_risks_example()[source]

Interesting beta risks and how to use similar_risks_graphs_sa.

Returns

aggregate.bounds.similar_risks_graphs_sa(axd, bounds, port, pnew, roe, prem, p_reg=1)[source]

stand-alone ONLY WORKS FOR BOUNDED PORTFOLIOS (use for beta mixture examples) Updated version in CaseStudy axd from mosaic bounds = Bounds class from port (calibrated to some base)it pnew = new portfolio input new beta(a,b) portfolio, using existing bounds object

sample: see similar_risks_sample()

Provenance : from make_port in Examples_2022_post_publish