Skip to content

Commit 7da8e9c

Browse files
committed
add UT & multiple pool collection sample
1 parent 5fedf59 commit 7da8e9c

File tree

3 files changed

+91
-4
lines changed

3 files changed

+91
-4
lines changed

absbox/tests/regression/deals.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
from absbox import Generic
2+
import toolz as tz
3+
from lenses import lens
4+
25

36
test01 = Generic(
47
"TEST01- preclosing"
@@ -96,3 +99,7 @@
9699
,None
97100
,"Amortizing"
98101
)
102+
103+
test03 = tz.pipe(test01 & lens.pool
104+
105+
)

absbox/tests/regression/main.py

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@
22
from lenses import lens
33
import toolz as tz
44
import pytest
5+
import re, math
56

67
from absbox.tests.regression.deals import *
78

89
from absbox import API,EnginePath,readInspect,PickApiFrom
910

11+
def closeTo(a,b,r=2):
12+
assert math.floor(a * 10**r)/10**r == math.floor(b * 10**r)/10**r
1013

14+
def filterTxn(rs, f, rg):
15+
return [ r for r in rs if re.match(rg, r[f])]
1116

1217
@pytest.fixture
1318
def setup_api():
14-
15-
1619
api = API(EnginePath.DEV,check=False,lang='english')
17-
18-
1920
return api
2021

2122
@pytest.mark.pool
@@ -24,5 +25,78 @@ def test_01(setup_api):
2425
assert r['pool']['flow'].keys() == {"PoolConsol"}
2526
assert r['pool']['flow']['PoolConsol'].to_records()[0][0]== '2021-04-15'
2627

28+
@pytest.mark.collect
29+
def test_collect_01(setup_api):
30+
r = setup_api.run(test01 , read=True , runAssump = [])
31+
assert r['pool']['flow']['PoolConsol'].to_records()[0][0]== '2021-04-15'
32+
assert r['pool']['flow']['PoolConsol'].loc[:'2021-04-15']["Interest"].values.sum() == filterTxn( r['accounts']['acc01'].loc[:'2021-04-15'].to_dict('records'), 'memo', ".*CollectedInterest.*")[0]['change']
33+
assert r['pool']['flow']['PoolConsol'].loc[:'2021-04-15']["Principal"].values.sum() == filterTxn( r['accounts']['acc01'].loc[:'2021-04-15'].to_dict('records'), 'memo', ".*CollectedPrincipal.*")[0]['change']
34+
assert r['pool']['flow']['PoolConsol'].loc[:'2021-04-15']["Prepayment"].values.sum() == 0.00
35+
assert r['pool']['flow']['PoolConsol'].loc[:'2021-04-15']["Default"].values.sum() == 0.00
36+
assert r['pool']['flow']['PoolConsol'].loc[:'2021-04-15']["Recovery"].values.sum() == 0.00
37+
38+
# two accounts with Principal and Interest
39+
testSepAcc = tz.pipe( test01 & lens.accounts.modify( lambda xs: tuple(tz.cons( ('acc02',{"balance":0}), xs )))
40+
,lambda d : d & lens.collection[0][1].set("acc02")
41+
)
42+
43+
r = setup_api.run(testSepAcc , read=True , runAssump = [])
44+
assert r['pool']['flow']['PoolConsol'].loc[:'2021-04-15']["Interest"].values.sum() == filterTxn( r['accounts']['acc02'].loc[:'2021-04-15'].to_dict('records'), 'memo', ".*CollectedInterest.*")[0]['change']
45+
assert r['pool']['flow']['PoolConsol'].loc[:'2021-04-15']["Principal"].values.sum() == filterTxn( r['accounts']['acc01'].loc[:'2021-04-15'].to_dict('records'), 'memo', ".*CollectedPrincipal.*")[0]['change']
46+
47+
# three accounts with Principal( 30% 70%) and Interest
48+
test2SepAcc = tz.pipe( test01 & lens.accounts.modify( lambda xs: tuple(tz.cons( ('acc02',{"balance":0}), xs )))
49+
& lens.accounts.modify( lambda xs: tuple(tz.cons( ('acc03',{"balance":0}), xs )))
50+
,lambda d : d & lens.collection.set([["CollectedInterest","acc02"]
51+
,["CollectedPrincipal",[0.7,"acc01"],[0.3,"acc03"]]
52+
,["CollectedPrepayment","acc01"]
53+
,["CollectedRecoveries","acc01"]]
54+
)
55+
)
56+
r = setup_api.run(test2SepAcc , read=True , runAssump = [])
57+
assert r['pool']['flow']['PoolConsol'].loc[:'2021-04-15']["Interest"].values.sum() == filterTxn( r['accounts']['acc02'].loc[:'2021-04-15'].to_dict('records'), 'memo', ".*CollectedInterest.*")[0]['change']
58+
principalCollectedAtPeriod0 = r['pool']['flow']['PoolConsol'].loc[:'2021-04-15']["Principal"].values.sum()
59+
closeTo(principalCollectedAtPeriod0 *0.7
60+
, filterTxn( r['accounts']['acc01'].loc[:'2021-04-15'].to_dict('records'), 'memo', ".*CollectedPrincipal.*")[0]['change']
61+
, 2 )
62+
closeTo(principalCollectedAtPeriod0*0.3
63+
, filterTxn( r['accounts']['acc03'].loc[:'2021-04-15'].to_dict('records'), 'memo', ".*CollectedPrincipal.*")[0]['change']
64+
, 2)
2765

66+
# multiple pool with ratio split collection
67+
testMultiplePool = test01 & lens.accounts.set((("acc01",{"balance":0}),("acc02",{"balance":0}),("acc03",{"balance":0}))) \
68+
& lens.pool.set({"PoolA":{'assets':[["Mortgage"
69+
,{"originBalance":1320.0,"originRate":["fix",0.045],"originTerm":30
70+
,"freq":"Monthly","type":"Level","originDate":"2021-02-01"}
71+
,{"currentBalance":1320.0
72+
,"currentRate":0.08
73+
,"remainTerm":30
74+
,"status":"current"}]]},
75+
"PoolB":{'assets':[["Mortgage"
76+
,{"originBalance":880.0,"originRate":["fix",0.045],"originTerm":30
77+
,"freq":"Monthly","type":"Level","originDate":"2021-02-01"}
78+
,{"currentBalance":880.0
79+
,"currentRate":0.08
80+
,"remainTerm":30
81+
,"status":"current"}]]}}) \
82+
& lens.collection.set([[["PoolA",],"CollectedInterest","acc01"]
83+
,[["PoolB",],"CollectedInterest","acc03"]
84+
,[["PoolA","PoolB"],"CollectedPrincipal",[0.7,"acc02"],[0.3,"acc03"]]
85+
])
86+
r = setup_api.run(testMultiplePool , read=True , runAssump = [])
2887

88+
# acc01 get all interest from pool A
89+
closeTo(r['pool']['flow']['PoolA'].loc[:'2021-04-15']["Interest"].values.sum()
90+
, filterTxn( r['accounts']['acc01'].loc[:'2021-04-15'].to_dict('records'), 'memo', ".*CollectedInterest.*")[0]['change'])
91+
# acc03 get all interest from pool B
92+
closeTo(r['pool']['flow']['PoolB'].loc[:'2021-04-15']["Interest"].values.sum()
93+
, filterTxn( r['accounts']['acc03'].loc[:'2021-04-15'].to_dict('records'), 'memo', ".*CollectedInterest.*")[0]['change'])
94+
# acc02 get 70% of principal from pool A and Pool B
95+
closeTo((r['pool']['flow']['PoolA'].loc[:'2021-04-15']["Principal"].values.sum() +\
96+
r['pool']['flow']['PoolB'].loc[:'2021-04-15']["Principal"].values.sum())*0.7
97+
, filterTxn( r['accounts']['acc02'].loc[:'2021-04-15'].to_dict('records'), 'memo', ".*CollectedPrincipal.*")[0]['change'])
98+
# acc03 get all interest from pool B and 30% of principal from pool A and Pool B
99+
closeTo((r['pool']['flow']['PoolA'].loc[:'2021-04-15']["Principal"].values.sum() +\
100+
r['pool']['flow']['PoolB'].loc[:'2021-04-15']["Principal"].values.sum())*0.3
101+
, filterTxn( r['accounts']['acc03'].loc[:'2021-04-15'].to_dict('records'), 'memo', ".*CollectedPrincipal.*")[0]['change'])
102+

docs/source/modeling.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1776,6 +1776,12 @@ exmaple:
17761776
# 100% of prepayment will be allocated to acc01
17771777
,["CollectedRecoveries","acc01"]]
17781778
1779+
# multiple pools
1780+
[[["PoolA",],"CollectedInterest","acc01"]
1781+
,[["PoolB",],"CollectedInterest","acc03"]
1782+
,[["PoolA","PoolB"],"CollectedPrincipal",[0.7,"acc02"],[0.3,"acc03"]]
1783+
]
1784+
17791785
Collect Proceeds from multiple pools
17801786
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17811787

0 commit comments

Comments
 (0)