Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.24.1 #136

Merged
merged 5 commits into from
Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Analytics.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ calcDuration d ps pricingCurve
-- ^ calculate present value of input amount in future with given a curve and PV date
pv :: Ts -> Date -> Date -> Amount -> Amount
pv pc today d amt =
realToFrac $ (realToFrac amt) * (1 / factor) -- `debug` ("DF:"++show factor++" PV AMT"++show amt)
realToFrac $ (realToFrac amt) * (1 / factor) -- `debug` ("DF:"++show factor++" PV AMT"++show amt)
where
distance::Double = fromIntegral $ daysBetween today d
discount_rate = fromRational $ getValByDate pc Exc d -- `debug` ("Get val by ts"++show pc ++">>d"++ show d)
Expand All @@ -54,10 +54,10 @@ pv pc today d amt =
-- ^ calculate present value in the future using constant rate
pv2 :: IRate -> Date -> Date -> Amount -> Amount
pv2 discount_rate today d amt =
mulBI amt $ 1/denominator -- `debug` ("days between->"++show d ++show today++">>>"++show distance )
realToFrac $ (realToFrac amt) * (1/denominator) -- `debug` ("pv: cash"++ show amt++" deno"++ show denominator++">> rate"++show discount_rate)
where
denominator = (1+discount_rate) ^^ (fromInteger (div distance 365))
distance = daysBetween today d
denominator::Double = (1 + realToFrac discount_rate) ** (distance / 365)
distance::Double = fromIntegral $ daysBetween today d -- `debug` ("days betwwen"++ show (daysBetween today d)++">>"++ show d ++ ">>today>>"++ show today)

-- ^ calcualte present value given a series of amount with dates
pv3 :: Ts -> Date -> [Date] -> [Amount] -> Balance
Expand Down
8 changes: 8 additions & 0 deletions src/Asset.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module Asset (Pool(..),aggPool
,calcRecoveriesFromDefault
,priceAsset,applyHaircut,buildPrepayRates,buildDefaultRates
,poolFutureCf,poolFutureTxn,poolIssuanceStat
,poolFutureScheduleCf
) where

import qualified Data.Time as T
Expand Down Expand Up @@ -96,6 +97,7 @@ class (Show a,IR.UseRate a) => Asset a where

data Pool a = Pool {assets :: [a] -- ^ a list of assets in the pool
,futureCf :: Maybe CF.CashFlowFrame -- ^ projected cashflow from the assets in the pool
,futureScheduleCf :: Maybe CF.CashFlowFrame -- ^ projected un-stressed cashflow
,asOfDate :: Date -- ^ include cashflow after this date
,issuanceStat :: Maybe (Map.Map CutoffFields Balance) -- ^ cutoff balance of pool
,extendPeriods :: Maybe DatePattern -- ^ dates for extend pool collection
Expand All @@ -107,6 +109,12 @@ poolFutureCf = lens getter setter
getter p = futureCf p
setter p mNewCf = p {futureCf = mNewCf}

poolFutureScheduleCf :: Asset a => Lens' (Pool a) (Maybe CF.CashFlowFrame)
poolFutureScheduleCf = lens getter setter
where
getter p = futureScheduleCf p
setter p mNewCf = p {futureScheduleCf = mNewCf}

poolFutureTxn :: Asset a => Lens' (Pool a) [CF.TsRow]
poolFutureTxn = lens getter setter
where
Expand Down
2 changes: 1 addition & 1 deletion src/AssetClass/Mortgage.hs
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ instance Ast.Asset Mortgage where


calcCashflow s@(ScheduleMortgageFlow beg_date flows _) d _ = CF.CashFlowFrame flows
calcCashflow m@(AdjustRateMortgage _origin _arm _bal _rate _term _mbn _status) d mRates = error "TBD"
calcCashflow m@(AdjustRateMortgage _origin _arm _bal _rate _term _mbn _status) d mRates = error "to be implement on adjust rate mortgage"

getCurrentBal (Mortgage _ _bal _ _ _ _) = _bal
getCurrentBal (AdjustRateMortgage _ _ _bal _ _ _ _) = _bal
Expand Down
64 changes: 39 additions & 25 deletions src/Cashflow.hs
Original file line number Diff line number Diff line change
Expand Up @@ -244,17 +244,17 @@
= updateFlowBalance (b1 - mflowAmortAmount bn2) bn2
appendTs _1 _2 = error $ "appendTs failed with "++ show _1 ++ ">>" ++ show _2

addTsCF :: TsRow -> TsRow -> TsRow
-- ^ add up TsRow from same entity
addTsCF :: TsRow -> TsRow -> TsRow
addTsCF (CashFlow d1 a1 ) (CashFlow _ a2 ) = CashFlow d1 (a1 + a2)
addTsCF (BondFlow d1 b1 p1 i1 ) (BondFlow _ b2 p2 i2 ) = BondFlow d1 (min b1 b2) (p1 + p2) (i1 + i2)
addTsCF (MortgageFlow d1 b1 p1 i1 prep1 def1 rec1 los1 rat1 mbn1 pn1 st1) (MortgageFlow d2 b2 p2 i2 prep2 def2 rec2 los2 rat2 mbn2 pn2 st2)
addTsCF m1@(MortgageFlow d1 b1 p1 i1 prep1 def1 rec1 los1 rat1 mbn1 pn1 st1) m2@(MortgageFlow d2 b2 p2 i2 prep2 def2 rec2 los2 rat2 mbn2 pn2 st2)
= let
bn = min <$> mbn1 <*> mbn2
p = (+) <$> pn1 <*> pn2
st = maxStats st1 st2
in
MortgageFlow d1 (min b1 b2) (p1 + p2) (i1 + i2) (prep1 + prep2) (def1 + def2) (rec1 + rec2) (los1+los2) (fromRational (weightedBy [b1,b2] (toRational <$> [rat1,rat2]))) bn p st
MortgageFlow d1 (min b1 b2) (p1 + p2) (i1 + i2) (prep1 + prep2) (def1 + def2) (rec1 + rec2) (los1+los2) (fromRational (weightedBy [b1,b2] (toRational <$> [rat1,rat2]))) bn p st
addTsCF (MortgageDelinqFlow d1 b1 p1 i1 prep1 delinq1 def1 rec1 los1 rat1 mbn1 pn1 st1) (MortgageDelinqFlow d2 b2 p2 i2 prep2 delinq2 def2 rec2 los2 rat2 mbn2 pn2 st2)
= let
bn = min <$> mbn1 <*> mbn2
Expand All @@ -268,11 +268,10 @@
addTsCF (LeaseFlow d1 b1 r1) (LeaseFlow d2 b2 r2) = LeaseFlow d1 (min b1 b2) (r1 + r2)

sumTs :: [TsRow] -> Date -> TsRow
sumTs trs d = tsSetDate (foldr1 addTs trs) d
sumTs trs = tsSetDate (foldr1 addTs trs)


sumTsCF :: [TsRow] -> Date -> TsRow
-- ^ group cashflow from same entity by a single date
sumTsCF :: [TsRow] -> Date -> TsRow
sumTsCF trs = tsSetDate (foldl1 addTsCF trs) -- `debug` ("Summing"++show trs++">>"++ show (tsSetDate (foldr1 addTsCF trs) d))

tsTotalCash :: TsRow -> Balance
Expand Down Expand Up @@ -406,23 +405,28 @@
combine :: CashFlowFrame -> CashFlowFrame -> CashFlowFrame
combine (CashFlowFrame txn1) (CashFlowFrame txn2) = CashFlowFrame $ combineTss [] txn1 txn2

buildCollectedCF :: [[TsRow]] -> [Date] -> [TsRow] -> [[TsRow]]
buildCollectedCF [] [] [] = []
buildCollectedCF trs ds [] = trs
buildCollectedCF trs [d] _trs = trs ++ [cutBy Inc Past d _trs]
buildCollectedCF trs (d:ds) _trs =
case newFlow of
[] -> if null (last trs) then
buildCollectedCF (trs++[[]]) ds _trs
else
buildCollectedCF (trs++[[((viewTsRow d) . last .last) trs]]) ds _trs -- `debug` ("viewing trs"++ show trs)
newFlow -> buildCollectedCF (trs++[newFlow]) ds remains
where
(newFlow, remains) = splitBy d Inc _trs


aggTsByDates :: [TsRow] -> [Date] -> [TsRow]
aggTsByDates trs ds =
map
(\(x,_d) -> sumTsCF x _d)
(uncurry sumTsCF)
(filter
(\(y,__d) -> not (null y))
(zip (reduceFn [] ds trs) ds))
where
reduceFn accum _ [] = accum
reduceFn accum [cutoffDay] _trs =
accum ++ [cutBy Inc Past cutoffDay _trs]
reduceFn accum (cutoffDay:cutoffDays) _trs =
case newAcc of
[] -> reduceFn (accum++[[ ((viewTsRow cutoffDay) . last . last) accum]]) cutoffDays _trs -- `debug` ("Adding empty")
newFlow -> reduceFn (accum++[newAcc]) cutoffDays rest -- `debug` ("Adding "++show(newAcc)++" cutoffDay "++show(cutoffDay))
where
(newAcc, rest) = splitBy cutoffDay Inc _trs
(zip (buildCollectedCF [] ds trs) ds))


mflowPrincipal :: TsRow -> Balance
Expand Down Expand Up @@ -561,17 +565,27 @@

viewTsRow :: Date -> TsRow -> TsRow
-- ^ take a snapshot of a record
viewTsRow _d (MortgageDelinqFlow a b c d e f g h i j k l m) = MortgageDelinqFlow _d b 0 0 0 0 0 0 0 0 k l m
viewTsRow _d (MortgageFlow a b c d e f g h i j k l) = MortgageFlow _d b 0 0 0 0 0 0 0 j k l
viewTsRow _d (LoanFlow a b c d e f g i j k) = LoanFlow _d b 0 0 0 0 0 0 0 k
viewTsRow _d (MortgageDelinqFlow a b c d e f g h i j k l m) = MortgageDelinqFlow _d b 0 0 0 0 0 0 0 j k l m
viewTsRow _d (MortgageFlow a b c d e f g h i j k l) = MortgageFlow _d b 0 0 0 0 0 0 i j k l
viewTsRow _d (LoanFlow a b c d e f g i j k) = LoanFlow _d b 0 0 0 0 0 0 j k
viewTsRow _d (LeaseFlow a b c ) = LeaseFlow _d b 0
viewTsRow _d (FixedFlow a b c d e f ) = FixedFlow _d b 0 0 0 0


buildBegTsRow :: Date -> TsRow -> TsRow
-- ^ given a cashflow,build a new cf row with begin balance
buildBegTsRow d tr
= tsSetBalance (mflowBalance tr + mflowAmortAmount tr) (emptyTsRow d tr)
buildBegTsRow :: Date -> TsRow -> TsRow
buildBegTsRow d tr =
let
r = tsSetBalance (mflowBalance tr + mflowAmortAmount tr) (emptyTsRow d tr)
rate = mflowRate tr
in
tsSetRate rate r

tsSetRate :: IRate -> TsRow -> TsRow
tsSetRate _r (MortgageDelinqFlow a b c d e f g h i j k l m) = MortgageDelinqFlow a b c d e f g h i _r k l m
tsSetRate _r (MortgageFlow a b c d e f g h i j k l) = MortgageFlow a b c d e f g h _r j k l
tsSetRate _r (LoanFlow a b c d e f g i j k) = LoanFlow a b c d e f g i _r k


insertBegTsRow :: Date -> CashFlowFrame -> CashFlowFrame
insertBegTsRow d (CashFlowFrame []) = CashFlowFrame []
Expand All @@ -594,8 +608,8 @@
totalRecovery :: CashFlowFrame -> Balance
totalRecovery (CashFlowFrame rs) = sum $ mflowRecovery <$> rs

mergePoolCf :: CashFlowFrame -> CashFlowFrame -> CashFlowFrame
-- ^ merge two cashflow frame but no patching beg balance
mergePoolCf :: CashFlowFrame -> CashFlowFrame -> CashFlowFrame
mergePoolCf cf (CashFlowFrame []) = cf
mergePoolCf (CashFlowFrame []) cf = cf
mergePoolCf cf1@(CashFlowFrame txns1) cf2@(CashFlowFrame txns2) -- first day of left is earlier than right one
Expand Down Expand Up @@ -636,7 +650,7 @@
lookupSource tr NewDelinquencies = mflowDelinq tr
lookupSource tr NewDefaults = mflowDefault tr
lookupSource tr NewLosses = mflowLoss tr
lookupSource tr x = error ("Failed to lookup source"++ show x)

Check warning on line 653 in src/Cashflow.hs

View workflow job for this annotation

GitHub Actions / build

Pattern match is redundant

Check warning on line 653 in src/Cashflow.hs

View workflow job for this annotation

GitHub Actions / build

Pattern match is redundant


setPrepaymentPenalty :: Balance -> TsRow -> TsRow
Expand Down
Loading
Loading