Skip to content

Commit

Permalink
fix bug when generate reports with bond group
Browse files Browse the repository at this point in the history
  • Loading branch information
yellowbean committed Jun 26, 2024
1 parent 2e4039f commit f72d2fd
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 107 deletions.
6 changes: 0 additions & 6 deletions src/Asset.hs
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,6 @@ class (Show a,IR.UseRate a) => Asset a where









-- | apply ExtraStress on prepayment/default rates
applyExtraStress :: Maybe A.ExtraStress -> [Date] -> [Rate] -> [Rate] -> ([Rate],[Rate])
applyExtraStress Nothing _ ppy def = (ppy,def)
Expand Down
10 changes: 8 additions & 2 deletions src/AssetClass/AssetBase.hs
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,16 @@ data Mortgage = Mortgage OriginalInfo Balance IRate RemainTerms (Maybe BorrowerN
| ScheduleMortgageFlow Date [CF.TsRow] DatePattern
deriving (Show,Generic,Eq,Ord)

data ProjectedCashflow = ProjectedFlowFixed Date [CF.TsRow] DatePattern
| ProjectedFlowMixFloater Date [CF.TsRow] DatePattern (Rate, IRate) [(Rate, Spread, Index)]

type FixRatePortion = (Rate, IRate)
type FloatRatePortion = (Rate, Spread, Index)


data ProjectedCashflow = ProjectedFlowFixed CF.CashFlowFrame DatePattern
| ProjectedFlowMixFloater CF.CashFlowFrame DatePattern FixRatePortion [FloatRatePortion]
deriving (Show,Generic,Eq,Ord)


data Receivable = Invoice OriginalInfo Status
| DUMMY4
deriving (Show,Generic,Eq,Ord)
Expand Down
147 changes: 50 additions & 97 deletions src/AssetClass/ProjectedCashFlow.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ module AssetClass.ProjectedCashFlow
where

import qualified Data.Time as T
import qualified Cashflow as CF
import qualified Assumptions as A
import Asset as Ast
import Types
Expand All @@ -31,8 +30,6 @@ import qualified Cashflow as CF
import AssetClass.AssetBase
import AssetClass.AssetCashflow

import qualified Assumptions as A

import Cashflow (extendTxns,TsRow(..),mflowBalance)

import Debug.Trace
Expand Down Expand Up @@ -71,14 +68,13 @@ projectScheduleFlow trs b_factor lastBal [] _ _ (r:rs) (l:ls) (recovery_lag,reco



projCfwithAssumption :: (CF.CashFlowFrame, DatePattern) -> A.AssetPerfAssumption -> Date -> Maybe [RateAssumption] -> CF.CashFlowFrame
projCfwithAssumption (cf@(CF.CashFlowFrame (begBal, begDate, accInt) flows), dp)
projFixCfwithAssumption :: (CF.CashFlowFrame, DatePattern) -> A.AssetPerfAssumption -> Date -> CF.CashFlowFrame
projFixCfwithAssumption (cf@(CF.CashFlowFrame (begBal, begDate, accInt) flows), dp)
pAssump@(A.MortgageAssump mDefault mPrepay mRecovery mEs)
asOfDay
mRates
= CF.CashFlowFrame (cb,asOfDay,Nothing) futureTxns
where
curveDatesLength = recoveryLag + length flows
curveDatesLength = recoveryLag + length flows
endDate = CF.getDate (last flows)
(ppyRates,defRates,recoveryRate,recoveryLag) = buildAssumptionPpyDefRecRate (begDate:cfDates) pAssump
extraDates = genSerialDates dp Exc endDate recoveryLag
Expand All @@ -93,125 +89,83 @@ projCfwithAssumption (cf@(CF.CashFlowFrame (begBal, begDate, accInt) flows), dp)

cb = (CF.mflowBegBalance . head) futureTxns

projIndexCashflows :: ([Date],[Balance],[Principal],Index,Spread) -> Maybe [RateAssumption] -> CF.CashFlowFrame
projIndexCashflows (ds,bals,principals,index,spd) (Just ras) =
projIndexCashflows :: ([Date],[Balance],[Principal],Index,Spread) -> DatePattern -> A.AssetPerfAssumption -> Maybe [RateAssumption] -> CF.CashFlowFrame
projIndexCashflows (ds,bals,principals,index,spd) dp pAssump (Just ras) =
let
mIndexToApply = A.getRateAssumption ras index
indexRates = A.lookupRate0 ras index <$> ds

rates = (spd +) <$> indexRates
interestFlow = zipWith (flip mulBIR) rates bals
flowSize = length bals
scheduleCf = CF.CashFlowFrame (head bals, head ds, Nothing) $
zipWith12 MortgageFlow
ds
bals
principals
interestFlow
(replicate flowSize 0 )
(replicate flowSize 0 )
(replicate flowSize 0 )
(replicate flowSize 0 )
rates
(replicate flowSize Nothing)
(replicate flowSize Nothing)
(replicate flowSize Nothing)
in
CF.CashFlowFrame (head bals, head ds, Nothing) $
zipWith12 MortgageFlow
ds
bals
principals
interestFlow
(replicate flowSize 0 )
(replicate flowSize 0 )
(replicate flowSize 0 )
(replicate flowSize 0 )
rates
(replicate flowSize Nothing)
(replicate flowSize Nothing)
(replicate flowSize Nothing)




-- projMortgageFlow :: (Date,[Balance]) -> A.AssetPerfAssumption -> Maybe [RateAssumption] -> ([Balance],[Balance],[Balance])
-- projMortgageFlow (begDate,bals) pAssump mRates =
-- let
-- curveDatesLength = recoveryLag + length bals
-- extraPeriods = recoveryLag
-- endDate = last ds
-- extraDates = genSerialDates dp Exc endDate recoveryLag
-- cfDates = ds ++ extraDates
-- begBal = head bals
-- (ppyRates,defRates,recoveryRate,recoveryLag) = buildAssumptionPpyDefRecRate (begDate:cfDates) pAssump
--
-- txns = projectScheduleFlow [] 1.0 begBal flows defRates ppyRates
-- (replicate curveDatesLength 0.0)
-- (replicate curveDatesLength 0.0)
-- (recoveryLag,recoveryRate)
--
-- (futureTxns,historyM) = CF.cutoffTrs asOfDay txns
--
-- cb = (CF.mflowBegBalance . head) futureTxns
-- in
-- (cb, futureTxns, historyM)

projFixCfwithAssumption (scheduleCf, dp) pAssump (head ds)


seperateCashflows :: ProjectedCashflow -> Maybe A.AssetPerfAssumption -> Maybe [RateAssumption] -> (CF.CashFlowFrame, [CF.CashFlowFrame])
seperateCashflows (ProjectedFlowMixFloater begDate flows _ (fixPct,fixRate) floaterList)
(Just pAssump)
mRates
seperateCashflows (ProjectedFlowMixFloater pflow@(CF.CashFlowFrame (begBal, begDate, accuredInt) flows) dp (fixPct,fixRate) floaterList)
(Just pAssump)
mRates
= let
begBal = CF.mflowBegBalance $ head flows
totalBals = begBal: (CF.mflowBalance <$> flows)
ds = CF.mflowDate <$> flows

(ppyRates,defRates,recoveryRate,recoveryLag) = buildAssumptionPpyDefRecRate (begDate:ds) pAssump


flowSize = length ds
-- fix rate cashflow
fixedBals = (flip mulBR) fixPct <$> totalBals
fixedPrincipalFlow = replicate flowSize 0 -- flip mulBR fixPct <$> CF.mflowPrincipal <$> flows
fixedInterestFlow = replicate flowSize 0 -- flip mulBIR fixRate <$> fixedBals
fixedCashFlow = CF.CashFlowFrame (head fixedBals, begDate, Nothing) []
-- zipWith12 CF.MortgageFlow $
-- ds $
-- init fixedBals $
-- fixedPrincipalFlow $
-- fixedInterestFlow $
-- replicate flowSize 0 $
-- replicate flowSize 0 $
-- replicate flowSize 0 $
-- replicate flowSize 0 $
-- replicate flowSize fixRate $
-- replicate flowSize Nothing $
-- replicate flowSize Nothing $
-- replicate flowSize Nothing

floatBals = zipWith (-) totalBals fixedBals
fixedPrincipalFlow = flip mulBR fixPct <$> CF.mflowPrincipal <$> flows
fixedInterestFlow = flip mulBIR fixRate <$> fixedBals
fixedCashFlow = projFixCfwithAssumption (pflow, dp) pAssump begDate
-- float rate cashflow
totalFloatBalFlow = zipWith (-) totalBals fixedBals
floatPrincipalFlow = zipWith (-) (CF.mflowPrincipal <$> flows) fixedPrincipalFlow

-- rs = (head <$> floaterList)
-- floaterSize = length rs
-- indexes = last <$> floaterList
-- spds = (\(a,b,c) -> b) <$> floaterList
-- floatBalsBreakDown = zipWith mulBR floatBals rs
-- floatPrincipalFlowBreakDown = zipWith mulBR floatPrincipalFlow rs
-- floatedCashFlow = \x -> projIndexCashflows x mRates <$> zip5
-- (repeat ds)
-- floatBalsBreakDown
-- floatPrincipalFlowBreakDown
-- indexes
-- spds
in
-- (fixedCashFlow, floatedCashFlow)
(fixedCashFlow, [CF.CashFlowFrame (0, begDate, Nothing) []])
floaterSize = length rs
rs = (\(a,b,c) -> a) <$> floaterList -- portion of each floater
spds = (\(a,b,c) -> b) <$> floaterList -- spreads
indexes = (\(a,b,c) -> c) <$> floaterList -- indexes

floatBalsBreakDown = (\r -> flip mulBR r <$> totalFloatBalFlow ) <$> rs
floatPrincipalFlowBreakDown = (\r -> flip mulBR r <$> floatPrincipalFlow) <$> rs
floatedCashFlow = (\x -> projIndexCashflows x dp pAssump mRates) <$> zip5
(replicate floaterSize ds)
floatBalsBreakDown
floatPrincipalFlowBreakDown
indexes
spds
in
(fixedCashFlow, floatedCashFlow)



instance Ast.Asset ProjectedCashflow where

getCurrentBal (ProjectedFlowFixed _ cf _ ) = CF.mflowBalance (head cf)
getCurrentBal (ProjectedFlowMixFloater _ cf _ _ _ ) = CF.mflowBegBalance (head cf)
getCurrentBal (ProjectedFlowFixed cf@(CF.CashFlowFrame (begBal,_,_) _) _) = begBal
getCurrentBal (ProjectedFlowMixFloater cf@(CF.CashFlowFrame (begBal,_,_) _) _ _ _) = begBal

getOriginBal (ProjectedFlowFixed _ cf _ ) = CF.mflowBegBalance (head cf)
getOriginBal (ProjectedFlowMixFloater _ cf _ _ _ ) = CF.mflowBegBalance (head cf)
getOriginBal x = getCurrentBal x

isDefaulted f = error ""
getOriginDate f = error ""
getOriginInfo f = error ""

calcCashflow f@(ProjectedFlowFixed begDate flows _) d _
= CF.CashFlowFrame ( (CF.mflowBalance . head) flows, begDate, Nothing ) flows
calcCashflow f@(ProjectedFlowFixed cf _) d _ = cf

calcCashflow f@(ProjectedFlowMixFloater {}) d mRate
calcCashflow f@(ProjectedFlowMixFloater cf _ fxPortion floatPortion) d mRate
= let
(fixedCashFlow, floatedCashFlow) = seperateCashflows f Nothing mRate
in
Expand All @@ -234,7 +188,6 @@ instance Ast.Asset ProjectedCashflow where

instance IR.UseRate ProjectedCashflow where
isAdjustbleRate _ = False

getIndex _ = Nothing
getIndexes _ = Nothing
getResetDates _ = []
2 changes: 1 addition & 1 deletion src/Deal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ run t@TestDeal{accounts=accMap,fees=feeMap,triggers=mTrgMap,bonds=bndMap,status=
bndMap

issuanceProceeds = L.bndBalance bnd
newAcc = Map.adjust (A.deposit issuanceProceeds d (Tag ("Issuance Proceeds:"++newBndName)))
newAcc = Map.adjust (A.deposit issuanceProceeds d (IssuanceProceeds newBndName))
accName
accMap
in
Expand Down
2 changes: 1 addition & 1 deletion src/Reports.hs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ buildBalanceSheet t@TestDeal{ pool = pool, bonds = bndMap , fees = feeMap , liqP
--tranches

bndM = [ Item bndName bndBal | (bndName,bndBal) <- Map.toList $ Map.map L.getCurBalance (bonds t) ]
bndAccPayable = [ Item ("Accured Int:"++bndName) bndAccBal | (bndName,bndAccBal) <- Map.toList (Map.map (L.bndDueInt . (calcDueInt t d Nothing Nothing)) bndMap)]
bndAccPayable = [ Item ("Accured Int:"++bndName) bndAccBal | (bndName,bndAccBal) <- Map.toList (Map.map (L.totalDueInt . (calcDueInt t d Nothing Nothing)) bndMap)]
feeToPay = [ Item ("Fee Due:"++feeName) feeDueBal | (feeName,feeDueBal) <- Map.toList (Map.map (F.feeDue . (calcDueFee t d)) feeMap)]
liqProviderToPay = [ Item ("Liquidity Provider:"++liqName) liqBal | (liqName,liqBal) <- Map.toList (Map.map (CE.liqBalance . (CE.accrueLiqProvider d)) (fromMaybe Map.empty liqMap))]
swapToPay = [ Item ("Swap:"++rsName) (negate rsNet) | (rsName,rsNet) <- Map.toList (Map.map (HE.rsNetCash . (HE.accrueIRS d)) (fromMaybe Map.empty rsMap))
Expand Down
1 change: 1 addition & 0 deletions src/Stmt.hs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ getFlow comment =
SwapOutSettle -> Outflow
PurchaseAsset -> Outflow
SupportDraw -> Noneflow
IssuanceProceeds _ -> Inflow
TxnComments cmts ->
let
directionList = getFlow <$> cmts
Expand Down
4 changes: 4 additions & 0 deletions src/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ data TxnComment = PayInt [BondName]
| SwapInSettle
| SwapOutSettle
| PurchaseAsset
| IssuanceProceeds String
| TxnDirection BookDirection
| TxnComments [TxnComment]
deriving (Eq, Show, Ord ,Read, Generic)
Expand Down Expand Up @@ -794,6 +795,7 @@ instance ToJSON TxnComment where
toJSON (TxnDirection dr) = String $ T.pack $ "<TxnDirection:"++show dr++">"
toJSON SupportDraw = String $ T.pack $ "<SupportDraw:>"
toJSON (FundWith b bal) = String $ T.pack $ "<FundWith:"++b++","++show bal++">"
toJSON (IssuanceProceeds nb) = String $ T.pack $ "<IssuanceProceeds:"++nb++">"
toJSON (Tag cmt) = String $ T.pack $ "<Tag:"++cmt++">"

instance FromJSON TxnComment where
Expand Down Expand Up @@ -849,6 +851,8 @@ parseTxn t = case tagName of
sv = T.splitOn (T.pack ",") $ T.pack contents
in
return $ FundWith (T.unpack (head sv)) (read (T.unpack (sv!!1))::Balance)
-- toJSON (IssuanceProceeds nb) = String $ T.pack $ "<IssuanceProceeds:"++nb++">"
"IssuanceProceeds" -> return $ IssuanceProceeds contents
"Tag" -> return $ Tag contents
where
pat = "<(\\S+):(\\S+)>"::String
Expand Down

0 comments on commit f72d2fd

Please sign in to comment.