Liquidate Pools

We build an waterfall action which will be executed when running date between “2022-09-01” and “2022-11-01”. The action will sell all assets with 1:1 on performing balance and save proceeds to account liqAcc

sellBothPool = ["If", ["all", ['>',"2022-09-01"], ['<',"2022-11-01"] ]
               ,["sellAsset", ["Current|Defaulted", 1.0, 0], "liqAcc"]
               ]

insert this action to deal

from lenses import lens

from absbox import API,mkDeal,EnginePath

localAPI = API(EnginePath.DEV,check=False)

deal_data = {
    "name":"Multiple Pools with Mixed Asset"
    ,"dates":{"cutoff":"2021-06-01"
              ,"closing":"2021-07-15"
              ,"firstPay":"2021-08-26"
              ,"payFreq":["DayOfMonth",20]
              ,"poolFreq":"MonthEnd"
              ,"stated":"2030-01-01"}
    ,"pool":{"PoolA":{'assets':[["Mortgage"
                        ,{"originBalance":2200,"originRate":["fix",0.045],"originTerm":30
                          ,"freq":"Monthly","type":"Level","originDate":"2021-02-01"}
                          ,{"currentBalance":2200
                          ,"currentRate":0.08
                          ,"remainTerm":30
                          ,"status":"current"}]]},
             "PoolB":{'assets':[["Loan"
                              ,{"originBalance": 80000
                                ,"originRate": ["floater",0.045,{"index":"SOFR3M"
                                                                ,"spread":0.01
                                                                ,"reset":"QuarterEnd"}]
                                ,"originTerm": 60
                                ,"freq": "Monthly"
                                ,"type": "i_p"
                                ,"originDate": "2021-02-01"}
                              ,{"currentBalance": 65000
                                ,"currentRate": 0.06
                                ,"remainTerm": 60
                                ,"status": "Current"}]]}
            }
    ,"accounts":{"acc01":{"balance":0}
                ,"acc02":{"balance":0}
                ,"liqAcc":{"balance":0}}
    ,"bonds":{"A1":{"balance":1000
                 ,"rate":0.07
                 ,"originBalance":1000
                 ,"originRate":0.07
                 ,"startDate":"2020-01-03"
                 ,"rateType":{"Fixed":0.08}
                 ,"bondType":{"Sequential":None}}
             ,"B":{"balance":1000
                     ,"rate":0.0
                     ,"originBalance":1000
                     ,"originRate":0.07
                     ,"startDate":"2020-01-03"
                     ,"rateType":{"Fixed":0.00}
                     ,"bondType":{"Equity":None}}}
    ,"fees":{}
    ,"collect":[[["PoolA"],"CollectedCash","acc01"]
               ,[["PoolB"],"CollectedCash","acc02"]]
    ,"waterfall":{"Amortizing":[
         ["accrueAndPayInt","acc01",["A1"]]
         ,["payPrin","acc01",["A1"]]
         ,["payPrin","acc01",["B"]]
         ,sellBothPool
         ,["payPrinResidual","acc01",["B"]]
     ]}
    ,"status":("PreClosing","Amortizing")
}


deal = mkDeal(deal_data)
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
myAssump = {"poolAssump" : ("ByName"
                                ,{"PoolA":
                                      (("Mortgage",{"CDR":0.02} ,None, None, None)
                                       ,None
                                       ,None)
                                ,"PoolB":
                                  (("Loan",{"CDR":0.01} ,None, None, None)
                                   ,None
                                   ,None)}
                                )
             ,"runAssump" : [("interest",("LIBOR6M",0.04)
                                       ,("SOFR3M",0.04))
                           ,("inspect",("MonthEnd",("poolBalance","PoolB"))
                                      ,("MonthEnd",("poolBalance","PoolA")))
                            ]
             ,"read":True}
r = localAPI.run(deal,**myAssump)
/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(
Warning Message from server:Bond B is not paid off
Account acc02 has cash to be distributed
Account liqAcc has cash to be distributed

Now when sell assets in the pool, the balance equals to the liquidation proceeds

r['pool']['flow']['PoolB'].loc["2022-08-31"].Balance + r['pool']['flow']['PoolA'].loc["2022-08-31"].Balance
np.float64(64935.41)
r['accounts']['liqAcc']
balance change memo
date
2022-09-20 64935.41 64935.41 <Liquidation:>
2022-10-20 64935.41 0.00 <Liquidation:>

Sell A Pool Only

Notice there are two pools in the deal, user has the option to sell one of them

sellAPool = ["If", ["all", ['>',"2022-09-01"], ['<',"2022-10-01"] ]
               ,["sellAsset", ["Current|Defaulted", 1.0, 0], "liqAcc", ['PoolA']]
               ]

Let’s swap the waterfall action with the one selling PoolA only

sellPoolADeal = deal & lens.waterfall['Amortizing'][3].set(sellAPool)
## it's fancy lens' way to do it , you can do it a straight forwad way like:

## deal.waterfall['Amortizing'][3] = sellAPool 
## which will change the data in-place
r = localAPI.run(sellPoolADeal,**myAssump)
/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(
Warning Message from server:Bond B is not paid off
Account acc02 has cash to be distributed
Account liqAcc has cash to be distributed

Now , the selling only have proceeds from pool A

r['accounts']['liqAcc']
balance change memo
date
2022-09-20 905.23 905.23 <Liquidation:PoolA>

Now , once the pool has been liquidated, no more cash will be collected after 2022-9-20

r["pool"]['flow']['PoolA'].tail(5)
Balance Principal Interest Prepayment Default Recovery Loss WAC BorrowerNum PrepayPenalty CumPrincipal CumPrepay CumDelinq CumDefault CumRecovery CumLoss
Date
2022-04-30 1199.32 70.81 8.46 0 2.18 0 2.18 0.08 None None 759.85 0 0 30.23 0 30.23
2022-05-31 1126.18 71.16 7.98 0 1.98 0 1.98 0.08 None None 831.01 0 0 32.21 0 32.21
2022-06-30 1052.74 71.51 7.49 0 1.93 0 1.93 0.08 None None 902.52 0 0 34.14 0 34.14
2022-07-31 979.13 71.87 7.00 0 1.74 0 1.74 0.08 None None 974.39 0 0 35.88 0 35.88
2022-08-31 905.23 72.23 6.51 0 1.67 0 1.67 0.08 None None 1046.62 0 0 37.55 0 37.55
r["pool"]['flow']['PoolB'].tail(5)
Balance Principal Interest Prepayment Default Recovery Loss WAC CumPrincipal CumPrepay CumDelinq CumDefault CumRecovery CumLoss
Date
2025-10-31 62022.65 0.00 254.88 0 51.25 0 51.25 0.05 0.00 0 0 2818.27 0 2818.27
2025-11-30 61969.74 0.00 263.15 0 52.91 0 52.91 0.05 0.00 0 0 2871.18 0 2871.18
2025-12-31 61918.58 0.00 254.45 0 51.16 0 51.16 0.05 0.00 0 0 2922.34 0 2922.34
2026-01-31 61865.75 0.00 262.71 0 52.83 0 52.83 0.05 0.00 0 0 2975.17 0 2975.17
2026-02-28 0.00 61812.97 262.49 0 52.78 0 52.78 0.05 61812.97 0 0 3027.95 0 3027.95

Sell Both Pool Explicitly

sellABPool = ["If", ["all", ['>',"2022-09-01"], ['<',"2022-10-01"] ]
               ,["sellAsset", ["Current|Defaulted", 1.0, 0], "liqAcc", ['PoolA','PoolB']]
               ]
sellPoolABDeal = deal & lens.waterfall['Amortizing'][3].set(sellABPool)
r = localAPI.run(sellPoolABDeal,**myAssump)
/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(
Warning Message from server:Bond B is not paid off
Account acc02 has cash to be distributed
Account liqAcc has cash to be distributed
r['accounts']['liqAcc']
balance change memo
date
2022-09-20 64935.41 64935.41 <Liquidation:PoolA,PoolB>
r["pool"]['flow']['PoolB'].tail(5)
Balance Principal Interest Prepayment Default Recovery Loss WAC CumPrincipal CumPrepay CumDelinq CumDefault CumRecovery CumLoss
Date
2022-04-30 64245.61 0 272.82 0 54.86 0 54.86 0.05 0 0 0 595.31 0 595.31
2022-05-31 64192.57 0 263.80 0 53.04 0 53.04 0.05 0 0 0 648.35 0 648.35
2022-06-30 64137.80 0 272.36 0 54.77 0 54.77 0.05 0 0 0 703.12 0 703.12
2022-07-31 64084.85 0 263.36 0 52.95 0 52.95 0.05 0 0 0 756.07 0 756.07
2022-08-31 64030.18 0 271.90 0 54.67 0 54.67 0.05 0 0 0 810.74 0 810.74
r["pool"]['flow']['PoolA'].tail(5)
Balance Principal Interest Prepayment Default Recovery Loss WAC BorrowerNum PrepayPenalty CumPrincipal CumPrepay CumDelinq CumDefault CumRecovery CumLoss
Date
2022-04-30 1199.32 70.81 8.46 0 2.18 0 2.18 0.08 None None 759.85 0 0 30.23 0 30.23
2022-05-31 1126.18 71.16 7.98 0 1.98 0 1.98 0.08 None None 831.01 0 0 32.21 0 32.21
2022-06-30 1052.74 71.51 7.49 0 1.93 0 1.93 0.08 None None 902.52 0 0 34.14 0 34.14
2022-07-31 979.13 71.87 7.00 0 1.74 0 1.74 0.08 None None 974.39 0 0 35.88 0 35.88
2022-08-31 905.23 72.23 6.51 0 1.67 0 1.67 0.08 None None 1046.62 0 0 37.55 0 37.55

Sell Pool and Buy again

Liquidate Pool A and buy asset to Pool A again

revol_asset = ["Mortgage"
                ,{"originBalance":2200,"originRate":["fix",0.045],"originTerm":30
                  ,"freq":"Monthly","type":"Level","originDate":"2021-02-01"}
                  ,{"currentBalance":2200
                  ,"currentRate":0.08
                  ,"remainTerm":30
                  ,"status":"current"}]

poolToBy = (["constant",revol_asset]
             ,("Pool",("Mortgage",{"CDR":0.07},None,None,None)
                       ,None
                       ,None))

withBuyAssump = myAssump  & lens['runAssump'].modify(lambda xs: xs+[ ("revolving",{"poolOne":poolToBy})])
buyAsset = ["If", ["all", ['>',"2022-11-01"], ['<',"2022-12-01"] ]
               ,["buyAsset2", ["Current|Defaulted", 0.5, 0], "liqAcc",None, "poolOne",'PoolA']]

sellAndBuyDeal = sellPoolADeal & lens.waterfall['Amortizing'].call_mut("insert",3,buyAsset)


r = localAPI.run(sellAndBuyDeal,**withBuyAssump)
/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(
Warning Message from server:Account acc01 has cash to be distributed
Account acc02 has cash to be distributed
r['pool']['flow']['PoolA'].tail(5)
Balance Principal Interest Prepayment Default Recovery Loss WAC BorrowerNum PrepayPenalty CumPrincipal CumPrepay CumDelinq CumDefault CumRecovery CumLoss
Date
2025-01-20 224.52 55.20 1.86 0 1.72 0 1.72 0.08 None None 1424.76 0.0 0.0 161.18 0.0 161.18
2025-02-20 167.91 55.24 1.48 0 1.37 0 1.37 0.08 None None 1480.00 0.0 0.0 162.55 0.0 162.55
2025-03-20 111.69 55.29 1.11 0 0.93 0 0.93 0.08 None None 1535.29 0.0 0.0 163.48 0.0 163.48
2025-04-20 55.68 55.33 0.73 0 0.68 0 0.68 0.08 None None 1590.62 0.0 0.0 164.16 0.0 164.16
2025-05-20 0.00 55.35 0.36 0 0.33 0 0.33 0.08 None None 1645.97 0.0 0.0 164.49 0.0 164.49
r['accounts']['liqAcc']
balance change memo
date
2022-09-20 905.23 905.23 <Liquidation:PoolA>
2022-11-20 0.00 -905.23 <PurchaseAsset:poolOne,1810.46>
r['accounts']['acc01'].loc["2022-11-20":"2023-03-20"]
balance change memo
date
2022-11-30 0.00 0.00 <PoolPoolA:CollectedCash>
2022-12-31 66.38 66.38 <PoolPoolA:CollectedCash>
2023-01-20 0.00 -66.38 <PayPrin:B>
2023-01-31 65.97 65.97 <PoolPoolA:CollectedCash>
2023-02-20 0.00 -65.97 <PayPrin:B>
2023-02-28 65.57 65.57 <PoolPoolA:CollectedCash>
2023-03-20 0.00 -65.57 <PayPrin:B>