diff options
Diffstat (limited to 'python/exploration/dispersion.py')
| -rw-r--r-- | python/exploration/dispersion.py | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/python/exploration/dispersion.py b/python/exploration/dispersion.py index b33f2796..c9f219cf 100644 --- a/python/exploration/dispersion.py +++ b/python/exploration/dispersion.py @@ -67,6 +67,13 @@ def get_tranche_data(conn, index_type, tenor="5yr"): (x.detach - x.cumulativeloss) / df.indexfactor, 1 ), moneyness=lambda x: (x.detach_adj + x.attach_adj) / 2 / x.index_expected_loss, + att_moneyness=lambda x: x.attach_adj / x.index_expected_loss, + det_moneyness=lambda x: x.detach_adj / x.index_expected_loss, + ) + df = df.assign( + thickness=(df.detach_adj - df.attach_adj), + tranche_loss_per=(df.exp_percentage * df.index_expected_loss) + / (df.detach_adj - df.attach_adj), ) df = df.set_index(["date", "index", "series", "version", "tenor", "attach"]) series = tuple(df.index.get_level_values("series").unique()) @@ -112,7 +119,42 @@ def create_models(conn, df) -> (pd.DataFrame, float): return (df, model) -def create_models_separate(df): +def create_models_v2(conn, df) -> (pd.DataFrame, float): + # Takes the output of get_tranche_data + attach_max = df.index.get_level_values("attach").max() + bottom_stack = df[df.index.get_level_values("attach") != attach_max] + model = smf.ols( + "logit(tranche_loss_per) ~ " + "np.log(index_duration) + " + "np.log(moneyness) * gini + " + "np.log(index_expected_loss)* gini + " + "expit(att_moneyness) +" + "expit(det_moneyness)", + data=bottom_stack, + ) + f = model.fit() + df.loc[ + df.index.get_level_values("attach") != attach_max, "predict_tranche_loss" + ] = expit(f.predict(bottom_stack)) + df.loc[df.index.get_level_values("attach") != attach_max, "predict"] = ( + df.predict_tranche_loss * df.thickness / df.index_expected_loss + ) + + def aux(s): + temp = s.values + temp[-1] = 1 - temp[:-1].sum() + return temp + + df["predict"] = df.groupby(["index", "series", "date"])["predict"].transform(aux) + df = df.assign( + mispricing=(df.exp_percentage - df.predict) + * df.index_expected_loss + / (df.detach_adj - df.attach_adj) + ) + return (df, model) + + +def create_separate_models(df): # Takes the output of get_tranche_data model, calc = {}, {} df = df.assign( @@ -124,9 +166,10 @@ def create_models_separate(df): calc[attach] = df.loc(axis=0)[:, :, :, "5yr", attach] model[attach] = smf.ols( "logit(tranche_loss_per) ~ " - "np.log(moneyness)* logit(gini) + " - "np.log(index_expected_loss)* logit(gini) + " + "I(np.log(index_expected_loss)**2) + " "np.log(index_duration) + " + "np.log(moneyness) * logit(gini) + " + "np.log(index_expected_loss)* logit(gini) + " "I(np.log(moneyness)**2) + I(np.log(moneyness)**3)", data=calc[attach], ).fit() @@ -147,9 +190,8 @@ def create_models_separate(df): (calc["exp_percentage"] - calc["predict_N"]) * calc["index_expected_loss"] / (calc["detach_adj"] - calc["attach_adj"]) - * 100 ) - return model, calc + return (calc, model) if __name__ == "__main__": |
