Skip to content

Commit 71a791c

Browse files
committed
parameterised the tweaks
1 parent d933ccc commit 71a791c

File tree

2 files changed

+43
-10
lines changed

2 files changed

+43
-10
lines changed

absbox/rootFinder.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
from .local.interface import mkTag
22
from .validation import vStr,vBool,vNum
3+
from .local.component import mkDs
34

45
def mkTweak(x):
56
match x:
67
case "stressDefault":
7-
return mkTag(("StressPoolDefault"))
8+
return mkTag(("StressPoolDefault", [1.0, 500]))
9+
case ("stressDefault",l,h):
10+
return mkTag(("StressPoolDefault", [l, h]))
811
case "stressPrepayment":
9-
return mkTag(("StressPoolPrepayment"))
12+
return mkTag(("StressPoolPrepayment", [1.0, 500]))
13+
case ("stressPrepayment", l, h):
14+
return mkTag(("StressPoolPrepayment", [l, h]))
1015
case ("maxSpread", bn):
11-
return mkTag(("MaxSpreadTo", vStr(bn)))
16+
return mkTag(("MaxSpreadTo", [ vStr(bn), (1.0, 500)]))
17+
case ("maxSpread", bn, l, h):
18+
return mkTag(("MaxSpreadTo", [ vStr(bn), (l, h)]))
1219
case ("splitBalance", bn1 ,bn2):
13-
return mkTag(("SplitFixedBalance", [vStr(bn1), vStr(bn2)]))
20+
return mkTag(("SplitFixedBalance", [vStr(bn1), vStr(bn2), (1.0, 500)]))
21+
case ("splitBalance", bn1, bn2, l, h):
22+
return mkTag(("SplitFixedBalance", [vStr(bn1), vStr(bn2), (l, h)]))
1423
case _:
1524
raise RuntimeError(f"failed to match {x}:mkTweak")
1625

@@ -26,5 +35,7 @@ def mkStop(x):
2635
return mkTag(("BondPricingEqOriginBal", [vStr(bn), vBool(f1), vBool(f2)] ))
2736
case ("bondMetTargetIrr", bn, irr):
2837
return mkTag(("BondMetTargetIrr", [vStr(bn), vNum(irr)]))
38+
case ("byFormula", ds, target):
39+
return mkTag(("BalanceFormula", [mkDs(ds), vNum(target)]))
2940
case _:
30-
raise RuntimeError(f"failed to match {x}:mkStop")
41+
raise RuntimeError(f"failed to match {x}:mkStop")

absbox/tests/regression/test_main.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .assets import *
1111

1212
from absbox import API,EnginePath,readInspect,PickApiFrom,readBondsCf
13+
from absbox.exception import AbsboxError
1314

1415
config_file_path = Path(__file__).resolve().parent.parent / 'config.json'
1516

@@ -225,9 +226,8 @@ def test_first_loss(setup_api):
225226
,None)
226227
,None
227228
,None)
228-
,read=True
229-
)
230-
closeTo(r0[0], 31.601002929896755, r=6)
229+
,read=True)
230+
closeTo(r0[0], 31.601832129896755, r=6)
231231

232232
@pytest.mark.analytics
233233
def test_irr_01(setup_api):
@@ -274,7 +274,19 @@ def test_rootfind_stressppy(setup_api):
274274
r = setup_api.runRootFinder(test01, poolPerf ,[pricing]
275275
,("stressPrepayment",("bondMetTargetIrr", "B", 0.25))
276276
)
277-
assert r[1][1]['PoolLevel'][0]['MortgageAssump'][1] == {'PrepaymentCPR': 0.38642105474696914 }
277+
assert r[1][1]['PoolLevel'][0]['MortgageAssump'][1] == {'PrepaymentCPR': 0.38640740263106543 }
278+
279+
assert r[0] == 386.40740263106545, "scale factor is off {r[0]}"
280+
281+
r = setup_api.runRootFinder(test01, poolPerf ,[pricing]
282+
,(("stressPrepayment", 1,400),("bondMetTargetIrr", "B", 0.25))
283+
)
284+
assert r[1][1]['PoolLevel'][0]['MortgageAssump'][1] == {'PrepaymentCPR': 0.38640737599372227 }
285+
286+
with pytest.raises(AbsboxError):
287+
r = setup_api.runRootFinder(test01, poolPerf ,[pricing]
288+
,(("stressPrepayment", 1,35),("bondMetTargetIrr", "B", 0.25))
289+
)
278290

279291
@pytest.mark.analytics
280292
def test_rootfind_stressdef(setup_api):
@@ -285,7 +297,7 @@ def test_rootfind_stressdef(setup_api):
285297
r = setup_api.runRootFinder(test01, poolPerf ,[pricing]
286298
,("stressDefault",("bondMetTargetIrr", "B", 0.10))
287299
)
288-
assert r[1][1]['PoolLevel'][0]['MortgageAssump'][0] == {'DefaultCDR': 0.07603587859615266}
300+
assert r[1][1]['PoolLevel'][0]['MortgageAssump'][0] == {'DefaultCDR': 0.0760391873750556 }
289301

290302
@pytest.mark.bond
291303
def test_pac_01(setup_api):
@@ -458,4 +470,14 @@ def test_revolving_01(setup_api):
458470
assert r['pool']['flow']['PoolConsol'].Principal.sum().round(2) == sum(totalPrins).round(2), "Breakdown cashflow should tieout with aggregated pool cashflow"
459471

460472

473+
# @pytest.mark.analytics
474+
# def test_rootfinder_by_formula(setup_api):
475+
# poolPerf = ("Pool",("Mortgage",{"CDR":0.002},{"CPR":0.001},{"Rate":0.1,"Lag":18},None)
476+
# ,None
477+
# ,None)
478+
# r = setup_api.runRootFinder(test01, poolPerf ,[]
479+
# ,("stressPrepayment",("byFormula", ("bondTxnAmt", "<PayInt:B>","B") , 500))
480+
# )
481+
# assert r[1][1]['PoolLevel'][0]['MortgageAssump'][1] == {'PrepaymentCPR': 0.38642105474696914 }
482+
461483

0 commit comments

Comments
 (0)