aboutsummaryrefslogtreecommitdiffstats
path: root/python/notebooks/tranches numbers.ipynb
diff options
context:
space:
mode:
Diffstat (limited to 'python/notebooks/tranches numbers.ipynb')
-rw-r--r--python/notebooks/tranches numbers.ipynb323
1 files changed, 323 insertions, 0 deletions
diff --git a/python/notebooks/tranches numbers.ipynb b/python/notebooks/tranches numbers.ipynb
new file mode 100644
index 00000000..71cb44f8
--- /dev/null
+++ b/python/notebooks/tranches numbers.ipynb
@@ -0,0 +1,323 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%matplotlib\n",
+ "import seaborn\n",
+ "seaborn.mpl.rcParams['figure.figsize'] = (12.0, 8.0)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "from ipywidgets import interact\n",
+ "from collections import OrderedDict"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "SQL_CON = \"postgresql://serenitas_user@debian/serenitasdb\"\n",
+ "runs = (pd.\n",
+ " read_sql(\"SELECT DISTINCT index, series, tenor from risk_numbers ORDER BY index, series\", SQL_CON).\n",
+ " itertuples(index=False, name='run'))\n",
+ "runs = OrderedDict([(\"%s %s %s\" % (r.index, r.series, r.tenor), (r.index, r.series, r.tenor)) for r in runs])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df = pd.read_sql(\"SELECT * FROM risk_numbers\", SQL_CON, index_col=['date', 'index', 'series', 'tenor'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "risk_numbers = ['skew', 'Dealer Deltas', 'Model Deltas', 'Forward Deltas', 'gammas', 'durations', 'thetas']\n",
+ "@interact(index=runs, what=risk_numbers)\n",
+ "def corrplot(index, what):\n",
+ " selection = df.xs(index, level=[1,2,3], drop_level=True)\n",
+ " cols = selection.attach.iloc[0]\n",
+ " cols = [\"{}-{}\".format(a,d) for a, d in zip(cols[:-2], cols[1:-1])]\n",
+ " selection = selection[what].apply(pd.Series)\n",
+ " selection.drop(selection.columns[-1], axis=1, inplace=True)\n",
+ " selection.columns = cols\n",
+ " selection.plot()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def get_tranche_quotes(index, series, tenor):\n",
+ " df = pd.read_sql(\"SELECT * FROM tranche_quotes WHERE index=%s and series=%s and tenor =%s\",\n",
+ " SQL_CON, params=(index, series, tenor), index_col='quotedate')\n",
+ " df.sort_index(inplace=True)\n",
+ " return df\n",
+ "def get_index_quotes(index, series, tenor):\n",
+ " df = pd.read_sql(\"SELECT * FROM index_quotes WHERE index=%s and series=%s and tenor=%s\",\n",
+ " SQL_CON, params = (index, series, tenor), index_col=['date'], parse_dates=['date'])\n",
+ " df.sort_index(inplace=True)\n",
+ " return df\n",
+ "ig25_tranches = get_tranche_quotes('IG', 25, '5yr')\n",
+ "ig25 = get_index_quotes('IG', 25, '5yr')\n",
+ "ig25_tranches = ig25_tranches[['attach', 'trancheupfrontmid','indexrefspread','tranchedelta']]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ig25_tranches = ig25_tranches.groupby([pd.TimeGrouper('D', level=0), 'attach']).last().dropna()\n",
+ "ig25_tranches = ig25_tranches.reset_index('attach', drop=False)\n",
+ "ig25 = ig25[['closeprice','duration','closespread']]\n",
+ "ig25_data = ig25_tranches.join(ig25)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ig25_data = ig25_data.assign(tranche_adjusted =\n",
+ " lambda x: x.trancheupfrontmid - \\\n",
+ " x.tranchedelta * (x.indexrefspread-x.closespread) * x.duration/100)\n",
+ "ig25_data = ig25_data.set_index('attach', append=True)\n",
+ "ig25_data.head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#compute the accrued\n",
+ "ig25_data['accrued'] = ig25_data.groupby(level='attach')['tranche_adjusted'].transform(lambda x: x.index.levels[0].to_series().diff().astype('timedelta64[D]')*1/360)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#compute the daily pnl\n",
+ "ig25_data['index_pnl'] = (ig25_data.groupby(level='attach')['closeprice'].\n",
+ " apply(lambda x:x.diff()))\n",
+ "ig25_data['tranche_pnl'] = (ig25_data.groupby(level='attach')['tranche_adjusted'].\n",
+ " apply(lambda x:-x.diff()))\n",
+ "for col in ['index_pnl', 'tranche_pnl']:\n",
+ " ig25_data[col] += ig25_data.accrued"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ig25_data.xs(3, level='attach').plot(x='index_pnl', y='tranche_pnl', kind='scatter')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import statsmodels.api as sm\n",
+ "import statsmodels.formula.api as smf\n",
+ "import numpy as np\n",
+ "model = smf.ols('tranche_pnl~0+index_pnl', data=ig25_data.xs(15, level='attach'))\n",
+ "results = model.fit()\n",
+ "results.summary()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def rolling_ols(df, formula, window=20):\n",
+ " r = []\n",
+ " for i in range(len(df)-window):\n",
+ " model = smf.ols(formula, data=df.iloc[i:(20+i),])\n",
+ " results = model.fit()\n",
+ " r.append(results.params)\n",
+ " r = pd.concat(r, axis=1).T\n",
+ " return r.set_index(df.index[20:])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "rols = rolling_ols(ig25_data, 'tranche_pnl~0+index_pnl+np.square(index_pnl)')\n",
+ "rols.columns = ['delta','gamma']\n",
+ "test = rols.join(ig25_data)[['delta','tranchedelta']]\n",
+ "test.plot()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ig25_data.closespread.apply(np.log).diff().std()*np.sqrt(250)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ig25 = get_index_quotes('IG', 25, '5yr')\n",
+ "ig25['closespread'].rolling(20).apply(lambda x: np.std(np.diff(np.log(x)))*np.sqrt(250)).plot()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ig25 = get_index_quotes('IG', 25, '5yr')\n",
+ "returns = ig25.closespread.pct_change().dropna()\n",
+ "returns.plot()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from arch import arch_model\n",
+ "am = arch_model(returns, mean='ARX', lags=1, vol='GARCH', o=1)\n",
+ "res = am.fit(update_freq=5)\n",
+ "res.summary()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "res.plot(annualize='D')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import math\n",
+ "annualized_vol = res.conditional_volatility * math.sqrt(252)\n",
+ "annualized_vol.plot()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "returns[returns.abs()>0.04].groupby(pd.TimeGrouper('M')).count()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "returns['2016-03']"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ig25.head()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ig25.index"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "pd.read_sql?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.1"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}