from absbox import API,EnginePath,Generic
import pandas as pd
localAPI = API(EnginePath.DEV,lang='english',check=False)
Connecting engine server -> https://absbox.org/api/dev
/home/docs/checkouts/readthedocs.org/user_builds/absbox-doc/envs/stable/lib/python3.11/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'absbox.org'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
✅Connected, local lib:0.52.3, server:0.52.3

A Lease Deal Example with root finder

Lease Asset

  • with daily rate of 2

  • payable at each 5 of the month

  • 24 payments, starting from 2021-3-1

l1 = ["Lease"
         ,{"rental": ("byDay", 2.0, ["DayOfMonth",5]),"originTerm": 24,"originDate": "2021-03-01"}
         ,{"currentBalance":1,"status":"Current","remainTerm":24}]

Deal Structure

  • With starting equity tranche 99.5%

  • Distribution day: each 20 of the month

lease01 = Generic(
    "lease01"
    ,{"cutoff":"2021-03-01","closing":"2021-06-15","firstPay":"2021-07-26"
     ,"payFreq":["DayOfMonth",20],"poolFreq":"MonthEnd","stated":"2030-01-01"}
    ,{'assets':[l1]}
    ,(("acc01",{"balance":0}),)
    ,(("A1",{"balance":10
             ,"rate":0.07
             ,"originBalance":10
             ,"originRate":0.07
             ,"startDate":"2020-01-03"
             ,"rateType":{"Fixed":0.08}
             ,"bondType":{"Sequential":None}})
      ,("B",{"balance":1990
             ,"rate":0.0
             ,"originBalance":1990
             ,"originRate":0.00
             ,"startDate":"2020-01-03"
             ,"rateType":{"Fixed":0.00}
             ,"bondType":{"Equity":None}
             }))
    ,(("trusteeFee",{"type":{"fixFee":30},"feeStart":"2021-06-15"}),)
    ,{"amortizing":[
         ["payFee","acc01",['trusteeFee']]
         ,["accrueAndPayInt","acc01",["A1"]]
         ,["payPrin","acc01",["A1"]]
         ,["payPrin","acc01",["B"]]
         ,["payIntResidual","acc01","B"]
     ],
     "cleanUp":[
         ["payIntResidual","acc01","B"]
     ]}
    ,[["CollectedRental","acc01"]]
    ,None
    ,None
    ,None
    ,None
    ,("PreClosing","Amortizing")
    )

Pool Performance

  • using a decreasing rental vector. For first extenstion, the lease rental will be reduced by 25%

  • pricing IRR of the tranche B

baseRental = ('byRateVec',-0.25,-0.22,-0.1)

poolPerf = ("Pool",("Lease", None, ('days', 25), baseRental, ("byExtTimes", 3))
                                       ,None
                                       ,None
                                       )

pricing = ("pricing",{"IRR":{"B":("holding",[("2021-06-15",-1000)],1000)}})

r = localAPI.run(lease01
            ,runAssump=[pricing]
            ,poolAssump = poolPerf
            ,read=True)

r['pricing']['summary']
/home/docs/checkouts/readthedocs.org/user_builds/absbox-doc/envs/stable/lib/python3.11/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'absbox.org'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
IRR
B 0.153709

MultiScenario

Using lens / dict comprehension to build multiple scenario

from lenses import lens

scenMap = {
    "low":('byRateVec',-0.20,-0.20,-0.1),
    "base":baseRental,
    "high":('byRateVec',-0.30,-0.25,-0.1),
}

poolPerfMap = {k: poolPerf & lens[1][3].set(v)
    for k,v in scenMap.items()
}

Use runByScenarios to run sensitivity run and view the IRR of tranche B

r = localAPI.runByScenarios(lease01
            ,runAssump=[pricing]
            ,poolAssump = poolPerfMap
            ,read=True)

pd.DataFrame.from_dict({k: v['pricing']['summary'].IRR for k,v in r.items() },orient='index').transpose()
/home/docs/checkouts/readthedocs.org/user_builds/absbox-doc/envs/stable/lib/python3.11/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'absbox.org'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
base high low
B 0.153709 0.095739 0.20203

Structuring deal with target IRR

  • using runRootFinder to constantly splitBalance between A1 and B, till Irr of B equals to target.

There are lots of potential of runRootFinder to serve deal structuring purpose.

Let me know what is missing ! :)

targetIrrs = (0.2,0.225,0.25)

r0 = [ localAPI.runRootFinder(lease01, poolPerf ,[pricing]
         ,(("splitBalance", "A1" ,"B", 0.01, 0.99)
         ,("bondMetTargetIrr", "B", irr))
       )
       for irr in targetIrrs 
     ]

[ {k:v['bndBalance'] 
   for k,v in _r[1][0]['RDeal']['bonds'].items()}|{"irr":t} 
     for t,_r in zip(targetIrrs,r0) ]
/home/docs/checkouts/readthedocs.org/user_builds/absbox-doc/envs/stable/lib/python3.11/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'absbox.org'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
/home/docs/checkouts/readthedocs.org/user_builds/absbox-doc/envs/stable/lib/python3.11/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'absbox.org'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
/home/docs/checkouts/readthedocs.org/user_builds/absbox-doc/envs/stable/lib/python3.11/site-packages/urllib3/connectionpool.py:1097: InsecureRequestWarning: Unverified HTTPS request is being made to host 'absbox.org'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
[{'A1': 1447.99, 'B': 552.01, 'irr': 0.2},
 {'A1': 1602.03, 'B': 397.97, 'irr': 0.225},
 {'A1': 1695.53, 'B': 304.47, 'irr': 0.25}]