{ "cells": [ { "cell_type": "markdown", "id": "5765bcff", "metadata": {}, "source": [ "MBS Example queries\n", "==========================\n", "\n", "Load iris\n", "----------" ] }, { "cell_type": "code", "execution_count": 1, "id": "04f0d4f4", "metadata": {}, "outputs": [], "source": [ "load_ext iris" ] }, { "cell_type": "markdown", "id": "7e9e9098", "metadata": {}, "source": [ "Import libraries\n", "------------------" ] }, { "cell_type": "code", "execution_count": 3, "id": "93228e85", "metadata": {}, "outputs": [], "source": [ "import py1010\n", "import tenFrame as tf\n", "import pandas as pd\n", "import numpy as np\n", "session = py1010.Session(\"1010data URL\", \"USERNAME\", \"PASSWORD\", py1010.POSSESS)" ] }, { "cell_type": "markdown", "id": "bc674356", "metadata": {}, "source": [ "MBS query examples\n", "--------------------------\n", "[Example 1: Agency pools](#Example-1:-Agency-pools)\n", "\n", "[Example 2: Historical cohort](#Example-2:-Historical-cohort)\n", "\n", "[Example 3: Cohort and S curve](#Example-3:-Cohort-and-S-curve)\n", "\n", "[Example 4: CPR by occupancy type](#Example-4:-CPR-by-occupancy-type)\n", "\n", "[Example 5: GNMA prepayment and buyout CPR](#Example-5:-GNMA-prepayment-and-buyout-CPR)\n", "\n", "[Example 6: Loan level FHLMC CPR](#Example-6:-Loan-level-FHLMC-CPR)\n" ] }, { "cell_type": "markdown", "id": "cfd6cbcd", "metadata": {}, "source": [ "Example 1: Agency pools\n", "-----------------------------\n", "\n", "This example computes the number of Agency Pools for each agency/gse (FNMA/FHLMC/GNMA) that have loans in each state for each month. The results show the outstanding balance of those loans and the number of loans. For instance, in Sept of 2022, there were 106,117 Freddie Mac Pools that had at least one active loan in CA, there was an approximately $510 billion balance and 1.578 million loans." ] }, { "cell_type": "code", "execution_count": 4, "id": "ec2748da", "metadata": {}, "outputs": [ { "ename": "TentenException", "evalue": "('function run failed, returned 1 (Table is no longer accessible: pub.fin.embs.combined.stnd_pool.sec)', 1)", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTentenException\u001b[0m Traceback (most recent call last)", "\u001b[0;32m/var/folders/5v/clfmrnm52rl5p8570x__xm140000gq/T/ipykernel_12008/279990301.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mgeo\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgeo\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmerge\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"pub.fin.embs.combined.stnd_pool.sec\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mon\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"issueid\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mgeo\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgeo\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgeo\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolltype\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"LOAN\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mgeo\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgeo\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgroupby\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"value\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"agency\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"effdt\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0magg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m\"value\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m\"cnt\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"rpb\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m\"sum\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"loans\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m\"sum\"\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0mgeo2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgeo\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgeo\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrpb_sum\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mgeo\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgroupby\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"value\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"agency\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrpb_sum\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0madjoin\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'rpb_sum_max'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;31m# Hide that last column.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/tenFrame/tenFrame.py\u001b[0m in \u001b[0;36magg\u001b[0;34m(self, agg_info, newOp, breaks, columnparams, rollup, breakelts, **kwargs)\u001b[0m\n\u001b[1;32m 3727\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'cbreaks'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moneorlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcbreaks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjoin\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mframe\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3728\u001b[0m \u001b[0mbreaks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0moneorlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbreaks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjoin\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mframe\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3729\u001b[0;31m rv = self._core_agg(agg_info, breaks=breaks, columnparams=columnparams,\n\u001b[0m\u001b[1;32m 3730\u001b[0m rollup=rollup, breakelts=breakelts, **kwargs)\n\u001b[1;32m 3731\u001b[0m \u001b[0;31m## Aggregation clears grouping!! In the return value only?\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/tenFrame/tenFrame.py\u001b[0m in \u001b[0;36m_core_agg\u001b[0;34m(self, agg_info, breaks, select, order, columnparams, rollup, breakelts, forcetab, noself, failonU, adjoin, *args, **kwargs)\u001b[0m\n\u001b[1;32m 3988\u001b[0m \u001b[0meverorder\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0morder\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3989\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mtab_gfun\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# still unforced\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3990\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msegbybreaks\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbreaks\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3991\u001b[0m \u001b[0mtab_gfun\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"gfun\"\u001b[0m \u001b[0;31m# that right? what about things sharing names?\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3992\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtab_gfun\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"gfun\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/tenFrame/tenFrame.py\u001b[0m in \u001b[0;36msegbybreaks\u001b[0;34m(self, breaks)\u001b[0m\n\u001b[1;32m 4088\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4089\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 4090\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnumsegs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m<=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4091\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4092\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# presumably offline.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/tenFrame/tenFrame.py\u001b[0m in \u001b[0;36mnumsegs\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 5156\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5157\u001b[0m \u001b[0mtab\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbasetableinfo\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 5158\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mtab\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'segs'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5159\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5160\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_numsegs_metadata\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/tenFrame/tenFrame.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, index)\u001b[0m\n\u001b[1;32m 7199\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0monline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7200\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Values not available offline\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 7201\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcolumn\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7202\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7203\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__getattr__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/tenFrame/tenFrame.py\u001b[0m in \u001b[0;36mcolumn\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 6967\u001b[0m type to be 'i'.\"\"\"\n\u001b[1;32m 6968\u001b[0m \u001b[0;31m# returns a py1010 Column object!\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 6969\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mframe\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6970\u001b[0m \u001b[0;31m# FOR SERVER: return a mock Column\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6971\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0monline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/opt/anaconda3/lib/python3.9/site-packages/tenFrame/tenFrame.py\u001b[0m in \u001b[0;36mrun\u001b[0;34m(self, force)\u001b[0m\n\u001b[1;32m 2347\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdirty\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mforce\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0monline\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2348\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrefreshquery\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2349\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquery_\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2350\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdirty\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2351\u001b[0m \u001b[0;31m# refresh column info. the metadata came back as part of the run.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32mpy1010.pyx\u001b[0m in \u001b[0;36mpy1010.logit.f\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpy1010.pyx\u001b[0m in \u001b[0;36mpy1010.logit.f\u001b[0;34m()\u001b[0m\n", "\u001b[0;32mpy1010.pyx\u001b[0m in \u001b[0;36mpy1010.except_zero.f\u001b[0;34m()\u001b[0m\n", "\u001b[0;31mTentenException\u001b[0m: ('function run failed, returned 1 (Table is no longer accessible: pub.fin.embs.combined.stnd_pool.sec)', 1)" ] } ], "source": [ "geo = tf.TenFrame(session, \"pub.fin.embs.combined.stnd_pool.geo\")\n", "geo = geo[(geo.rectype == \"G\") & (geo.value != \"ZZ\")]\n", "geo = geo.merge(\"pub.fin.embs.combined.stnd_pool.sec\", on=\"issueid\")\n", "geo = geo[geo.colltype == \"LOAN\"]\n", "geo = geo.groupby([\"value\", \"agency\", \"effdt\"]).agg({\"value\": \"cnt\", \"rpb\": \"sum\", \"loans\": \"sum\"})\n", "geo2 = geo[geo.rpb_sum == geo.groupby([\"value\", \"agency\"]).rpb_sum.max(adjoin=True)['rpb_sum_max']]\n", "# Hide that last column.\n", "rv = geo2 = geo2[[\"value\", \"agency\", \"effdt\", \"value_cnt\", \"rpb_sum\", \"loans_sum\"]]\n", "geo2 = geo2.sort_values(by=[\"agency\", \"value\", \"effdt\"], ascending=True)\n", "geo2" ] }, { "cell_type": "markdown", "id": "71b75086", "metadata": {}, "source": [ "Example 2: Historical cohort\n", "----------------------------------\n", "This example shows the historical cohort (product, origination year, coupon) prepayment speeds (CPR) for the largest 10 cohorts (determined by the largest monthly outstanding balance for each cohort).\n", "\n", "**_Note:_** g_tshift() is a 1010data function that returns the value of the first row that is a specified time period before (or after) the current row within a given group." ] }, { "cell_type": "code", "execution_count": 6, "id": "158b236d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "