diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/exploration/dispersion.py | 34 | ||||
| -rw-r--r-- | python/notebooks/Dispersion.ipynb | 46 |
2 files changed, 59 insertions, 21 deletions
diff --git a/python/exploration/dispersion.py b/python/exploration/dispersion.py index d7fb8a73..575877ba 100644 --- a/python/exploration/dispersion.py +++ b/python/exploration/dispersion.py @@ -79,9 +79,43 @@ def get_tranche_data(index_type, engine): ), exp_percentage=lambda x: x.expected_loss / x.index_expected_loss, ) + df.set_index(["index", "series", "tenor", "attach"], append=True, inplace=True) return df +def create_gini_models(df): + # Takes the output of get_tranche_data + gini_model, gini_calc = {}, {} + for attach in df.index.get_level_values("attach").unique(): + gini_calc[attach] = df.loc(axis=0)[:, :, :, "5yr", attach] + gini_model[attach] = smf.ols( + "np.log(exp_percentage) ~ " + "np.log(gini_spread) + " + "np.log(index_duration) + " + "np.log(moneyness)", + data=gini_calc[attach], + ).fit() + gini_calc[attach]["predict"] = np.exp( + gini_model[attach].predict(gini_calc[attach]) + ) + gini_calc = pd.concat(gini_calc, sort=False).reset_index(level=0, drop=True) + normalization = gini_calc.groupby(["date", "index", "series", "tenor"])[ + "predict" + ].sum() + gini_calc = gini_calc.merge( + normalization, left_index=True, right_index=True, suffixes=["_preN", "_sum"] + ) + gini_calc["predict_N"] = gini_calc["predict_preN"] / gini_calc["predict_sum"] + gini_calc["mispricing"] = ( + (gini_calc["exp_percentage"] - gini_calc["predict_N"]) + * gini_calc["index_expected_loss"] + / (gini_calc["detach_adj"] - gini_calc["attach_adj"]) + / gini_calc["indexfactor"] + * 10000 + ) + return gini_model, gini_calc + + def gini(array): """Calculate the Gini coefficient of a numpy array.""" if np.amin(array) < 0: diff --git a/python/notebooks/Dispersion.ipynb b/python/notebooks/Dispersion.ipynb index 53fe6993..59e98647 100644 --- a/python/notebooks/Dispersion.ipynb +++ b/python/notebooks/Dispersion.ipynb @@ -48,11 +48,9 @@ "outputs": [], "source": [ "#Get Gini factor\n", - "risk = disp.get_tranche_data(index_type, serenitas_engine)\n", - "date_range = pd.bdate_range(end=value_date, freq='5B',periods=52*4)\n", - "risk = risk[(risk.index.isin(date_range))]\n", - "temp = risk.apply(lambda x: disp.get_gini_spreadstdev(x['index'], x.series, [x.tenor], x.name), axis=1)\n", - "risk[['gini_spread', 'std_spread']] = pd.DataFrame(temp.values.tolist(), columns=['gini_spread','std_spread'], index=temp.index)" + "date_range = pd.bdate_range(end=value_date, freq='5B',periods=52*.5)\n", + "risk = disp.get_tranche_data(index_type, date_range, serenitas_engine)\n", + "gini_model, gini_calc = disp.create_gini_models(risk)" ] }, { @@ -61,8 +59,7 @@ "metadata": {}, "outputs": [], "source": [ - "gini_calc = risk[(risk.index.isin(date_range)) & (risk.attach == 0)]\n", - "to_plot_gini = gini_calc[(gini_calc.tenor == '5yr')].groupby(['date', 'series']).nth(-1)\n", + "to_plot_gini = gini_calc.loc(axis=0)[:,:,:,'5yr',0].groupby(['date', 'series']).nth(-1)\n", "to_plot_gini['gini_spread'].unstack().plot()" ] }, @@ -72,10 +69,8 @@ "metadata": {}, "outputs": [], "source": [ - "##### model expected loss percentage instead of correlation -- equity\n", - "gini_calc = risk[(risk.attach == 0)]\n", - "gini_model = smf.ols(\"np.log(exp_percentage) ~ np.log(gini_spread) + np.log(duration) + np.log(moneyness)\", data=gini_calc).fit()\n", - "gini_model.summary()" + "today = gini_calc.loc(axis=0)[value_date,:,33,'5yr',:]\n", + "today[['exp_percentage', 'predict_N', 'predict_preN', 'mispricing']]" ] }, { @@ -84,7 +79,8 @@ "metadata": {}, "outputs": [], "source": [ - "plot_fit(gini_model, 'np.log(moneyness)')" + "to_plot = gini_calc.loc(axis=0)[:,:,:,'5yr',0]['mispricing']\n", + "to_plot.reset_index(['index','tenor','attach'], drop=True).unstack().plot()" ] }, { @@ -93,7 +89,7 @@ "metadata": {}, "outputs": [], "source": [ - "gini_calc['predict'] = np.exp(gini_model.predict(gini_calc))" + "plot_fit(gini_model[0], 'np.log(index_duration)')" ] }, { @@ -102,8 +98,15 @@ "metadata": {}, "outputs": [], "source": [ - "today = gini_calc[(gini_calc['index'] == index_type) & (gini_calc['series'] == 33)].loc[value_date]\n", - "today" + "#Run a particular gini scenario\n", + "scenario = gini_calc.loc(axis=0)[value_date,'HY',33,'5yr',0]\n", + "scenario['gini_spread'] = .6\n", + "scenario_disp = np.exp(gini_model[0].predict(scenario))\n", + "mispricing = (scenario['exp_percentage'] - scenario_disp) * \\\n", + " scenario['index_expected_loss'] / \\\n", + " (scenario['detach_adj'] - scenario['attach_adj']) / \\\n", + " scenario['indexfactor'] * 10000\n", + "mispricing" ] }, { @@ -114,7 +117,7 @@ "source": [ "#Let's use a GAM model instead?\n", "#only use the 5yr point for modeling\n", - "equity = gini_calc[(gini_calc.tenor=='5yr') & (gini_calc.series >= 23)]\n", + "equity = gini_calc.loc(axis=0)[:,:,[25,27,29,31,33],'5yr',0]\n", "X = np.array(equity[['gini_spread', 'duration', 'moneyness']])\n", "y = np.array(equity['exp_percentage'])\n", "\n", @@ -165,9 +168,8 @@ "metadata": {}, "outputs": [], "source": [ - "today = (equity.loc[max(equity.index)])\n", - "predict_HY33 = gam_model.predict(np.array(today[today.series==33][['gini_spread', 'duration', 'moneyness']]))\n", - "today[today.series==31][['exp_percentage']], predict_HY33" + "today = gini_calc.loc(axis=0)[value_date,'HY',33,'5yr',0]\n", + "predict_HY33 = gam_model.predict(np.array(today[['gini_spread', 'duration', 'moneyness']]))" ] }, { @@ -175,7 +177,9 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "today, predict_HY33" + ] } ], "metadata": { @@ -194,7 +198,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.0" + "version": "3.8.1-final" } }, "nbformat": 4, |
