EDML BLUE Ducth RMBS sample
%load_ext autoreload
%autoreload 2
from absbox import API,EnginePath
localAPI = API(EnginePath.DEV,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
from absbox import Generic,readBondsCf,DC
from lenses import lens
closingDate = "2024-10-28"
firstPay = "2025-01-28"
statedDate= "2063-07-02"
firstRedemptionDate = "2029-07-02"
cutoff = "2024-09-30"
totalPoolBal = 360_521_905
begReserveBal = 0.0035 * totalPoolBal
accs = (
("reserveAcc",{"type":("when",[("isPaidOff","A","B","C","D"),True]
,("fix",0)
,("target",("*",("poolBalance",),0.0035)))
,"balance":begReserveBal
,"interest":{"period":"QuarterEnd"
,"index":"EURIBOR3M"
,"spread":0.000
,"reset":"QuarterEnd"
,"rate": 0.00
,"lastSettleDate":closingDate} }),
("distAccInt",{}),
("distAccPrin",{}),
)
liqFacility = {
"cashAdvance":{"type": {"formula":("max", ("factor",("bondBalance","A","B"),0.005)
, ("factor",("originalBondBalance","A","B"),0.002))}
,"start": closingDate},
}
bonds = (
("A",{"balance":342_500_000 ,"rates":[0.036,0],"originBalance":342_500_000 ,"originRate":0.07
,"startDate":closingDate,"rateTypes":[("floor",0,("floater",(0.05, "EURIBOR3M",0.006,"QuarterEnd"),DC.DC_ACT_360.value)),("fix",0.0)]
,"bondType":"Sequential"
,"stepUps":[("once", firstRedemptionDate, 0),("once", firstRedemptionDate, 0.0105)]}),
("B",{"balance":9_000_000 ,"rates":[0.0395,0],"originBalance":9_000_000 ,"originRate":0.07
,"startDate":closingDate,"rateTypes":[("floor",0,("floater",(0.05, "EURIBOR3M",0.0095,"QuarterEnd"),DC.DC_ACT_360.value)),("fix",0.0)]
,"bondType":"Sequential"
,"stepUps":[("once", firstRedemptionDate, 0),("once", firstRedemptionDate, 0.01425)]}),
("C",{"balance":5_200_000 ,"rates":[0.044,0],"originBalance":5_200_000 ,"originRate":0.07
,"startDate":closingDate,"rateTypes":[("floor",0,("floater",(0.05, "EURIBOR3M",0.014,"QuarterEnd"),DC.DC_ACT_360.value)),("fix",0.0)]
,"bondType":"Sequential"
,"stepUps":[("once", firstRedemptionDate, 0),("once", firstRedemptionDate, 0.021)]}),
("D",{"balance":1_100_000 ,"rates":[0.0525,0],"originBalance":1_100_000 ,"originRate":0.07
,"startDate":closingDate,"rateTypes":[("floor",0,("floater",(0.05, "EURIBOR3M",0.0225,"QuarterEnd"),DC.DC_ACT_360.value)),("fix",0.0)]
,"bondType":"Sequential"
,"stepUps":[("once", firstRedemptionDate, 0),("once", firstRedemptionDate, 0.0325)]}),
("E",{"balance":2_700_000 ,"rates":[0.08,0],"originBalance":2_700_000 ,"originRate":0.07
,"startDate":closingDate,"rateTypes":[("floor",0,("floater",(0.05, "EURIBOR3M",0.05,"QuarterEnd"),DC.DC_ACT_360.value)),("fix",0.0)]
,"bondType":"Sequential"
,"stepUps":[("once", firstRedemptionDate, 0),("once", firstRedemptionDate, 0.05)]}),
("RS",{"balance":40_000_000 ,"rate":0.0,"originBalance":40_000_000 ,"originRate":0.00
,"startDate":closingDate,"rateType":("fix",0.0) ,"bondType":{"Equity":None}}),
)
rateSwap = {
"ElanSwap":
{
"updateDates":"MonthEnd"
,"pair":[("poolWaRate","elan-fix"),("EURIBOR3M",0.04)] # paying a float rate with spread ,and receiving a fix annualized rate
,"base":{"formula":("poolBalance","elan-fix")}
,"start":closingDate
,"balance":0
,"dayCount":DC.DC_ACT_360.value
},
"BlueSwap":{
"updateDates":"MonthEnd"
,"pair":[("poolWaRate","blue-fix"),("EURIBOR3M",0.04)] # paying a float rate with spread ,and receiving a fix annualized rate
,"base":{"formula":("poolBalance","blue-fix")}
,"start":closingDate
,"balance":0
,"dayCount":DC.DC_ACT_360.value
},
}
initAsset = ["Mortgage"
,{"originBalance": 360_521_905
,"originRate": ["fix",0.0595]
,"originTerm": int(29.6*12)
,"freq": "Monthly"
,"type": "Level"
,"originDate": "2015-08-30"} # (int(29.6*12) - int(20.5*12)) Months before cut off date
,{"currentBalance": 360_521_905
,"currentRate": 0.0595
,"remainTerm": int(20.5*12)
,"status": "Current"}
]
assetFloater = ["floater"
,0.03
,{"index":"EURIBOR3M"
,"spread":0.0015
,"reset":"MonthEnd"}]
stratSplit = [0.425,0.075,0.425,0.075]
assets = [ initAsset & lens.Fork(lens[1]['originBalance'], lens[2]['currentBalance']).set(r*totalPoolBal) for r in stratSplit ]
assets[1][1]['originRate'] = assetFloater
assets[3][1]['originRate'] = assetFloater
pool = {
"elan-fix":{'assets':[assets[0]]},
"elan-float":{'assets':[assets[1]]},
"blue-fix":{'assets':[assets[2]]},
"blue-float":{'assets':[assets[3]]},
}
ledgers = {
"ledger-A":{"balance":0},
"ledger-B":{"balance":0},
"ledger-C":{"balance":0},
"ledger-D":{"balance":0},
"ledger-E":{"balance":0}
}
waterfall = {
"amortizing":[
["transfer","reserveAcc","distAccInt"],
## Revenue Priority of Payments
["calcFee", "director_fee","service_fee_elan","service_fee_blue","portfolio_manager_fee","running_fee","issuer_admin_fee","paying_agent_fee"
,"issuer_account_fee","swap_collateral_fee","third_party_fee","rating_fee","cash_advance_fee","listing_fee"],
# a,#fee to "Directors"; Collection Foundations; Security Trustee
["payFee", "distAccInt" ,["director_fee",]],
# b,#servicer fee(EDML)/ portfolio mager fee(EDML)/ running fee(Elan)/Admin Fee/ Paying Agent Fee/Lising Agent/ issuer Account fee/swap collateral custodian
["payFee", "distAccInt" ,["service_fee_elan","service_fee_blue","portfolio_manager_fee","running_fee","issuer_admin_fee","paying_agent_fee"
,"issuer_account_fee","swap_collateral_fee",]],
# c,#third party;credit rating agency;cash advance fee;listing of notes
["payFee", "distAccInt" ,["third_party_fee","rating_fee","cash_advance_fee","listing_fee"]],
# d
["liqRepay",["bal","int"], "distAccInt", "cashAdvance"], #interest & principal of cash advance drawing; stand by drawing
# e
["settleSwap", "distAccInt", "ElanSwap"],#pay to swap
["settleSwap", "distAccInt", "BlueSwap"],#pay to swap
["calcInt", "A","B","C","D","E", ],
["payIntByIndex", "distAccInt", ["A"], 0 ], # pay interest to note A
["transfer", "distAccInt","distAccPrin" ,{"ds":("ledgerBalance","Debit","ledger-A")},"book", "CR", "ledger-A"], #
["if",["not"
,["all"
,[("ledgerBalance","Debit","ledger-B"),">",0]
,[("isMostSenior","B",("A",)), False]]],
["payIntByIndex", "distAccInt", ["B"],0 ],
],
["transfer", "distAccInt","distAccPrin" ,{"ds":("ledgerBalance","Debit","ledger-B")},"book", "CR", "ledger-B" ],
["payIntByIndex", "distAccInt", ["B"],0 ],
["if",["not",["all",
[("ledgerBalance","Debit","ledger-C"),">",0]
,[("isMostSenior","C",("A","B")),False]
]],
["payIntByIndex", "distAccInt", ["C"],0 ],
],
["transfer", "distAccInt","distAccPrin" ,{"ds":("ledgerBalance","Debit","ledger-C")}, "book", "CR", "ledger-C" ],
["payIntByIndex", "distAccInt", ["C"],0 ],
["if",['not',["all"
,[("ledgerBalance","Debit","ledger-D"),">",0]
,[("isMostSenior","D",("A","B","C")),False]
]],
["payIntByIndex", "distAccInt", ["D"],0 ],
],
["transfer", "distAccInt","distAccPrin" ,{"ds":("ledgerBalance","Debit","ledger-D")},"book", "CR", "ledger-D" ],
["payIntByIndex", "distAccInt", ["D"], 0 ],
["transfer", "distAccInt","reserveAcc",{"ds":("reserveGap","reserveAcc")}],
["if",['not',["all", [("ledgerBalance","Debit","ledger-E"),">",0], [("isMostSenior","E",("A","B","C","D")),False]]],
["payIntByIndex", "distAccInt", ["E"],0 ],
],
["transfer", "distAccInt","distAccPrin" ,{"ds":("ledgerBalance","Debit","ledger-E")},"book", "CR", "ledger-E" ],
["payIntByIndex", "distAccInt", ["E"],0 ],
#None,# pay fee and expenses to Blue Portfolio Manager
["if",["date",">=",firstRedemptionDate]
,["payIntByIndex", "distAccInt", ["A"],1 ]
,["payIntByIndex", "distAccInt", ["B"],1 ]
,["payIntByIndex", "distAccInt", ["C"],1 ]
,["payIntByIndex", "distAccInt", ["D"],1 ]
,["payIntByIndex", "distAccInt", ["E"],1 ]
],
#None,# Swap Counterparty Subordinated Payment
#None,# Cash Advance Facility Provider Subordinated Amounts
#["if",[("isPaidOff","A","B","C","D","E"),True],
["payIntResidual", "distAccInt", "RS"],
#],
## Principal Distribution
["transfer", "distAccInt","distAccPrin"],
#None,#
["payPrinBySeq","distAccPrin",["A","B","C","D","E","RS",]],
],
"endOfCollection":[
["bookBy"
,["PDL"
,"Debit"
,("curPoolCollection", None,"Losses")
,[(f"ledger-{_}",("bondBalance",_)) for _ in reversed(["A","B","C","D","E"])]
]
]
]
}
fees = (
#1. **Servicer Fees**: Fees and expenses due to the EDML Servicer under the EDML Servicing Agreement and any amount due to the Blue Sub-servicers under the Blue Sub-Servicing Letter, as well as any remaining amount due to the Blue Servicer under the Blue Servicing Agreement (page 189).
("service_fee_elan",{"type":{"annualPctFee":[("poolBalance","elan-float","elan-fix"),0.00208725]},"feeStart":"2024-10-28"}),
("service_fee_blue",{"type":{"annualPctFee":[("poolBalance","blue-float","blue-fix"),0.0013]},"feeStart":"2024-10-28"}),
#("structuring_fee",{"type":{"annualPctFee":[("poolBalance","blue-float","blue-fix"),0.0013]}}),
("annual_senior_servicing_cost",{"type":{"annualPctFee":[("poolBalance","blue-float","blue-fix"),0.0013]},"feeStart":"2024-10-28"}), # 150,000
("annual_senior_txn",{"type":{"fixFee":100},"feeStart":"2024-10-28"}), # 160,000
#2. **Portfolio Manager Fees**: Fees and expenses due to the EDML Portfolio Manager under the EDML Portfolio Management Agreement (page 189).
("portfolio_manager_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#3. **Running Fee**: A running fee for administrative and risk retention services of 0.08% per annum of the notional amount of the Blue Receivables is payable by the Issuer to the Elan Seller (page 94).
("running_fee",{"type":{"annualPctFee":[("poolBalance","blue-float","blue-fix"),0.0008]},"feeStart":"2024-10-28"}),
#4. **Issuer Administrator Fees**: Fees and expenses due to the Issuer Administrator under the Administration Agreement (page 189).
("issuer_admin_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#5. **Paying Agent and Reference Agent Fees**: Fees and expenses due to the Paying Agent and the Reference Agent under the Paying Agency Agreement (page 189).
("paying_agent_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#6. **Listing Agent Fees**: Fees and expenses due to the Listing Agent (page 189).
("listing_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#7. **Issuer Account Bank Fees**: Any amounts due to the Issuer Account Bank under the Issuer Account Agreement, including negative interest on the Issuer Accounts (page 189).
("issuer_account_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#8. **Swap Collateral Custodian Fees**: Fees and expenses due to the Swap Collateral Custodian under the Swap Collateral Custodian Agreement (page 189).
("swap_collateral_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#9. **Third Party Fees**: Amounts due to third parties, including the EU SR Repository, under obligations incurred in the Issuer's business, and any amounts due to Credit Rating Agencies, legal advisors, auditors, and accountants (page 194).
("third_party_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#10. **Cash Advance Facility Provider Fees**: Amounts due to the Cash Advance Facility Provider under the Cash Advance Facility Agreement (page 194).
("cash_advance_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#11. **Swap Counterparty Fees**: Amounts due to Swap Counterparties under the Swap Agreements, including Swap Termination Payments, but excluding Swap Counterparty Subordinated Payments (page 194).
("swap_counterparty_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#12. **Blue Portfolio Manager Fees**: Fees and expenses due to the Blue Portfolio Manager under the Blue Servicing Agreement (page 195).
("blue_portfolio_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#13. **Subordinated Payments**: Swap Counterparty Subordinated Payments and Cash Advance Facility Provider Subordinated Amounts (page 195).
("subordinated_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#14. **Director Fees**: An annual fee due to the Director in connection with the Issuer Management Agreement, with a minimum of Euro 3,500 (page 184).
("director_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
#15 missing
("rating_fee",{"type":{"fixFee":100},"feeStart":"2024-10-28"}),
)
BLUE_RMBS = Generic(
"EDML BLUE 2024 B.V"
,{"cutoff":cutoff
,"closing":closingDate
,"firstPay":firstPay
,"stated":statedDate
,"poolFreq":"QuarterEnd"
,"payFreq":["EveryNMonth","2025-01-28",3]}
,pool
,accs
,bonds
,fees
, waterfall
,[[["blue-fix","blue-float","elan-fix","elan-float"],"CollectedPrepayment","distAccPrin"]
,[["blue-fix","blue-float","elan-fix","elan-float"],"CollectedPrincipal","distAccPrin"]
,[["blue-fix","blue-float","elan-fix","elan-float"],"CollectedInterest","distAccInt"]
,[["blue-fix","blue-float","elan-fix","elan-float"],"CollectedRecoveries","distAccPrin"]
]
,liqFacility
,rateSwap
,None
,None # optional
,("PreClosing","Amortizing")
,None
,ledgers# optional
,None # optional
)
r = localAPI.run(BLUE_RMBS
,poolAssump = ("Pool",("Mortgage",{"CDR":0.0},None,None,None)
,None
,None)
,runAssump = [("rate",("EURIBOR3M",0.035)),("report",{"dates":["EveryNMonth","2025-01-27",3]})
,("inspect",("MonthEnd",("bondRate","D"))
,("MonthEnd",("poolWaRate","blue-fix"))
,("MonthEnd",("poolWaRate",)))
]
,read=True)
/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(
---------------------------------------------------------------------------
EngineError Traceback (most recent call last)
Cell In[4], line 1
----> 1 r = localAPI.run(BLUE_RMBS
2 ,poolAssump = ("Pool",("Mortgage",{"CDR":0.0},None,None,None)
3 ,None
4 ,None)
5 ,runAssump = [("rate",("EURIBOR3M",0.035)),("report",{"dates":["EveryNMonth","2025-01-27",3]})
6 ,("inspect",("MonthEnd",("bondRate","D"))
7 ,("MonthEnd",("poolWaRate","blue-fix"))
8 ,("MonthEnd",("poolWaRate",)))
9 ]
10 ,read=True)
File ~/checkouts/readthedocs.org/user_builds/absbox-doc/envs/stable/lib/python3.11/site-packages/absbox/client.py:358, in API.run(self, deal, poolAssump, runAssump, read, showWarning, rtn, debug)
355 if debug:
356 return req
--> 358 result = self._send_req(req, url)
360 if result is None or 'error' in result or 'Left' in result:
361 leftVal = result.get("Left","")
File ~/checkouts/readthedocs.org/user_builds/absbox-doc/envs/stable/lib/python3.11/site-packages/absbox/client.py:828, in API._send_req(self, _req, _url, timeout, headers)
826 raise AbsboxError("❌ Failed to get response from server")
827 if r.status_code != 200:
--> 828 raise EngineError(r)
829 try:
830 return json.loads(r.text)
EngineError: Error in $.liqProvider.cashAdvance.liqCredit: When parsing Types.SupportAvailType expected Object but got String.
from absbox import readInspect,readBondsCf,BondCfHeader,readFeesCf
readBondsCf(r['bonds'],popColumns=BondCfHeader.SIMPLE.value)
| Bond | A | B | C | D | E | RS | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Field | balance | interest | principal | balance | interest | principal | balance | interest | principal | balance | interest | principal | balance | interest | principal | balance | interest | principal |
| date | ||||||||||||||||||
| 2025-01-28 | 3.401614e+08 | 3291184.48 | 2338556.62 | 9000000.0 | 94568.74 | 0.0 | 5200000.0 | 60648.33 | 0.0 | 1100000 | 15232.01 | 0 | 2700000 | 56503.86 | 0 | 40000000.00 | 2261080.43 | 0.00 |
| 2025-04-28 | 3.377547e+08 | 3494314.22 | 2406782.90 | 9000000.0 | 100363.72 | 0.0 | 5200000.0 | 63867.22 | 0.0 | 1100000 | 15861.20 | 0 | 2700000 | 57636.30 | 0 | 40000000.00 | 2253530.83 | 0.00 |
| 2025-07-28 | 3.353145e+08 | 3508179.67 | 2440150.66 | 9000000.0 | 101480.08 | 0.0 | 5200000.0 | 64577.70 | 0.0 | 1100000 | 16037.69 | 0 | 2700000 | 58278.01 | 0 | 40000000.00 | 2242461.96 | 0.00 |
| 2025-10-28 | 3.328405e+08 | 3521144.77 | 2473993.34 | 9000000.0 | 102596.43 | 0.0 | 5200000.0 | 65288.17 | 0.0 | 1100000 | 16214.16 | 0 | 2700000 | 58919.73 | 0 | 40000000.00 | 2184520.01 | 0.00 |
| 2026-01-28 | 3.303322e+08 | 3495165.32 | 2508317.82 | 9000000.0 | 102596.43 | 0.0 | 5200000.0 | 65288.17 | 0.0 | 1100000 | 16214.16 | 0 | 2700000 | 58919.73 | 0 | 40000000.00 | 2169629.11 | 0.00 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2044-04-28 | 1.074794e+07 | 230082.00 | 6942464.40 | 9000000.0 | 133478.92 | 0.0 | 5200000.0 | 91833.25 | 0.0 | 1100000 | 24966.07 | 0 | 2700000 | 92024.90 | 0 | 40000000.00 | 28246.25 | 0.00 |
| 2044-07-28 | 3.706911e+06 | 139788.04 | 7041026.88 | 9000000.0 | 133478.92 | 0.0 | 5200000.0 | 91833.25 | 0.0 | 1100000 | 24966.07 | 0 | 2700000 | 92024.90 | 0 | 40000000.00 | 138.17 | 0.00 |
| 2044-10-28 | 0.000000e+00 | 48742.44 | 3706911.14 | 5565896.2 | 134947.03 | 3434103.8 | 5200000.0 | 92843.38 | 0.0 | 1100000 | 25240.73 | 0 | 2700000 | 60205.02 | 0 | 40000000.00 | 0.00 | 0.00 |
| 2045-01-28 | NaN | NaN | NaN | 0.0 | 83455.67 | 5565896.2 | 3523446.7 | 81554.46 | 1676553.3 | 1100000 | 16214.16 | 0 | 2700000 | 58919.73 | 0 | 40000000.00 | 0.00 | 0.00 |
| 2045-04-28 | NaN | NaN | NaN | NaN | NaN | NaN | 0.0 | 43275.52 | 3523446.7 | 0 | 15861.20 | 1100000 | 0 | 56488.50 | 2700000 | 39978095.02 | 0.00 | 21904.98 |
82 rows × 18 columns