Skip to content

Commit

Permalink
Fix weight avg balance for bond group
Browse files Browse the repository at this point in the history
  • Loading branch information
yellowbean committed Jul 14, 2024
1 parent 9616b4a commit 17f082e
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 35 deletions.
8 changes: 2 additions & 6 deletions src/Deal/DealAction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,6 @@ testTrigger t d trigger@Trigger{trgStatus=st,trgCurable=curable,trgCondition=con
trigger { trgStatus = newSt
, trgStmt = Stmt.appendStmt tStmt newTxn}

-- updateTrigger :: Ast.Asset a => TestDeal a -> Date -> Trigger -> Trigger
-- updateTrigger t d trigger@Trigger{ trgStatus=st,trgCurable=cure,trgCondition=cond}
-- | testTrigger t d trigger = trigger {trgStatus = True}
-- | otherwise = trigger

pricingAssets :: PricingMethod -> [ACM.AssetUnion] -> Date -> Amount
pricingAssets (BalanceFactor currentfactor defaultfactor) assets d = 0
Expand Down Expand Up @@ -187,7 +183,7 @@ calcDueFee t calcDay f@(F.Fee fn (F.AnnualRateFee feeBase r) fs fd Nothing fa lp

-- ^ annualized % fee base on pool balance/amount
calcDueFee t@TestDeal{pool = pool} calcDay f@(F.Fee fn (F.AnnualRateFee feeBase _r) fs fd (Just _fdDay) fa lpd _)
= f{ F.feeDue=fd+newDue, F.feeDueDate = Just calcDay } -- `debug` ("Fee DUE new Due "++show calcDay ++show baseBal ++show(newDue))
= f{ F.feeDue=fd+newDue, F.feeDueDate = Just calcDay } -- `debug` ("Fee DUE new Due "++show newDue++"oldDue"++show fd)
where
accrueStart = _fdDay
baseBal = case feeBase of
Expand All @@ -206,7 +202,7 @@ calcDueFee t@TestDeal{pool = pool} calcDay f@(F.Fee fn (F.AnnualRateFee feeBase
-- CurrentBondBalance -> Map.foldr (\v a-> a + weightAvgBalance accrueStart calcDay (getTxns (L.bndStmt v)) ) 0.0 (bonds t)
-- CurrentBondBalanceOf bns -> sum $ (\v -> weightAvgBalance accrueStart calcDay (getTxns (L.bndStmt v))) <$> viewDealBondsByNames t bns
r = toRational $ queryDealRate t _r
newDue = mulBR baseBal r
newDue = mulBR baseBal r -- `debug` ("Fee Name"++fn ++"Date"++ show [accrueStart, calcDay] ++ "base bal"++ show baseBal++"new rate"++show r)

-- ^ % fee base on pool balance/amount
calcDueFee t calcDay f@(F.Fee fn (F.PctFee (PoolCurCollection its mPns) r ) fs fd fdDay fa lpd _)
Expand Down
14 changes: 8 additions & 6 deletions src/Liability.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ import qualified Data.Map as Map
import Debug.Trace
import InterestRate (UseRate(getIndexes))
import Control.Lens hiding (Index)
import Control.Lens.TH
import Language.Haskell.TH.Lens (_BytesPrimL)
import Stmt (getTxnAmt)
import Data.Char (GeneralCategory(NotAssigned))
import qualified Stmt as L
-- import Deal.DealBase (UnderlyingDeal(futureCf))

debug = flip trace
Expand Down Expand Up @@ -332,11 +334,11 @@ backoutDueIntByYield d b@(Bond _ _ (OriginalInfo obal odate _ _) (InterestByYiel
Nothing -> []


weightAverageBalance :: Date -> Date -> Bond -> Balance
weightAverageBalance sd ed b@(Bond _ _ (OriginalInfo ob bd _ _ ) _ _ currentBalance _ _ _ _ _ _ _ stmt)
= S.weightAvgBalance'
0
(sd,)
-- weightAverageBalance :: Date -> Date -> Bond -> Balance
weightAverageBalance sd ed b@(Bond _ _ (OriginalInfo ob bd _ _ ) _ _ currentBalance _ _ _ _ _ _ _ Nothing)
= mulBR currentBalance (yearCountFraction DC_ACT_365F (max bd sd) ed)
weightAverageBalance sd ed b@(Bond _ _ (OriginalInfo ob bd _ _ ) _ _ currentBalance _ _ _ _ _ _ _ (Just stmt))
= L.weightAvgBalance' (max bd sd) ed (view S.statementTxns stmt)

-- TO BE Deprecate, it was implemented in Cashflow Frame
-- weightAverageBalance :: Date -> Date -> Bond -> Balance
Expand All @@ -358,7 +360,7 @@ weightAverageBalance sd ed b@(Bond _ _ (OriginalInfo ob bd _ _ ) _ _ currentBal
-- Nothing -> []
-- Just (S.Statement _txns) -> _txns-- map getTxnBalance _txns
weightAverageBalance sd ed bg@(BondGroup bMap)
= sum $ weightAverageBalance sd ed <$> Map.elems bMap `debug` (">>>"++ show (weightAverageBalance sd ed <$> Map.elems bMap))
= sum $ weightAverageBalance sd ed <$> Map.elems bMap -- `debug` (">>>"++ show (weightAverageBalance sd ed <$> Map.elems bMap))

calcZspread :: (Rational,Date) -> Int -> (Float, (Rational,Rational),Rational) -> Bond -> Ts -> Spread
calcZspread _ _ _ b@Bond{bndStmt = Nothing} _ = error "No Cashflow for bond"
Expand Down
44 changes: 27 additions & 17 deletions src/Stmt.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module Stmt
,TxnComment(..),QueryByComment(..)
,weightAvgBalanceByDates,weightAvgBalance,weightAvgBalance',sumTxn, consolTxn
,getFlow,FlowDirection(..), aggByTxnComment,scaleByFactor
,scaleTxn,isEmptyTxn
,scaleTxn,isEmptyTxn, statementTxns
)
where

Expand Down Expand Up @@ -97,7 +97,7 @@ getTxnAmt (ExpTxn _ _ t _ _ ) = t
getTxnAmt (SupportTxn _ _ t _ _ _ _) = t
getTxnAmt (IrsTxn _ _ t _ _ _ _ ) = t
getTxnAmt (EntryTxn _ _ t _) = t
getTxnAmt (TrgTxn {} ) = 0.0
getTxnAmt TrgTxn {} = 0.0

getTxnAsOf :: [Txn] -> Date -> Maybe Txn
getTxnAsOf txns d = find (\x -> getDate x <= d) $ reverse txns
Expand Down Expand Up @@ -125,6 +125,19 @@ sliceStmt :: Date -> Date -> Statement -> Statement
sliceStmt sd ed (Statement txns)
= Statement $ sliceBy II sd ed txns

viewBalanceAsOf :: Date -> [Txn] -> Balance
viewBalanceAsOf d [] = 0.0
viewBalanceAsOf d txns
| d < begDate = getTxnBegBalance fstTxn
| d > endDate = getTxnBalance lstTxn
| otherwise = getTxnBalance $ fromJust $ getTxnAsOf txns d
where
fstTxn = head txns
lstTxn = last txns
begDate = getDate fstTxn
endDate = getDate lstTxn


weightAvgBalanceByDates :: [Date] -> [Txn] -> [Balance]
weightAvgBalanceByDates ds txns
= (\(_sd,_ed) -> weightAvgBalance _sd _ed txns) <$> intervals -- `debug` ("interval"++ show intervals++ show txns)
Expand All @@ -141,19 +154,16 @@ weightAvgBalance sd ed txns
ds = [sd] ++ map getDate _txns ++ [ed]
dsFactor = getIntervalFactors ds -- `debug` ("DS>>>"++show ds)

weightAvgBalance' :: Balance -> (Date,Balance) -> [Date] -> [Txn] -> Balance
weightAvgBalance' accBal (_,b) _ [] = accBal
weightAvgBalance' accBal (_,b) [] txns = accBal
weightAvgBalance' accBal (lastDate,lastBal) (sd:ds) txns
= weightAvgBalance' newAccBal (sd, nextBegBalance restTxns) ds restTxns
where
(_txns,restTxns) = splitBy sd Exc txns
nextBegBalance [] = 0
nextBegBalance rTxns = getTxnBalance $ head rTxns
_txnDs = getDate <$> _txns
bals = lastBal:(getTxnBalance <$> _txns)
dsFactor = getIntervalFactors ([lastDate]++_txnDs ++ [sd])
newAccBal = accBal + sum (zipWith mulBR bals dsFactor)
weightAvgBalance' :: Date -> Date -> [Txn] -> Balance
weightAvgBalance' sd ed [] = 0.0
weightAvgBalance' sd ed txns
= let
-- txns = sliceBy EE sd ed txns
viewDs = sort $ [sd,ed] ++ (getDate <$> (sliceBy EE sd ed txns))
balances = flip viewBalanceAsOf txns <$> viewDs
factors = getIntervalFactors viewDs
in
sum $ zipWith mulBR balances factors -- `debug` ("Factors"++show factors++"Balances"++show balances)

data Statement = Statement [Txn]
deriving (Show, Generic, Eq, Ord, Read)
Expand All @@ -163,8 +173,8 @@ appendStmt (Just stmt@(Statement txns)) txn = Just $ Statement (txns++[txn])
appendStmt Nothing txn = Just $ Statement [txn]


statmentTxns :: Lens' Statement [Txn]
statmentTxns = lens getter setter
statementTxns :: Lens' Statement [Txn]
statementTxns = lens getter setter
where
getter (Statement txns) = txns
setter (Statement _) txns = Statement txns
Expand Down
53 changes: 47 additions & 6 deletions test/UT/StmtTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,57 @@ txnTest =
weightAvgBalance
(toDate "20221101")
(toDate "20221201")
[(AccTxn (toDate "20221115") 100 20 Empty)
,(AccTxn (toDate "20221125") 90 (negate 10) Empty)
[AccTxn (toDate "20221115") 100 20 Empty
,AccTxn (toDate "20221125") 90 (negate 10) Empty
]
,testCase "Weight Average Balance " $
assertEqual "Weight Average Balacne by dates"
[ 7.26, 5.64 ] $
weightAvgBalanceByDates
[(toDate "20221101"),(toDate "20221201"),(toDate "20221225")]
[(AccTxn (toDate "20221115") 100 20 Empty)
,(AccTxn (toDate "20221125") 90 (negate 10) Empty)
,(AccTxn (toDate "20221215") 80 (negate 10) Empty)]
[toDate "20221101",toDate "20221201",toDate "20221225"]
[AccTxn (toDate "20221115") 100 20 Empty
,AccTxn (toDate "20221125") 90 (negate 10) Empty
,AccTxn (toDate "20221215") 80 (negate 10) Empty]
, let
testTxns = [AccTxn (toDate "20221115") 100 20 Empty
,AccTxn (toDate "20221125") 90 (negate 10) Empty
,AccTxn (toDate "20221215") 80 (negate 10) Empty]
in
testCase "Get Txn As Of" $
assertEqual "Get Txn Asof 1"
Nothing $
getTxnAsOf testTxns (toDate "20221101")
, let
testTxns = [AccTxn (toDate "20221115") 100 20 Empty
,AccTxn (toDate "20221125") 90 (negate 10) Empty
,AccTxn (toDate "20221215") 80 (negate 10) Empty]
in
testCase "Get Txn As Of" $
assertEqual "Get Txn Asof 2"
[(Just (AccTxn (toDate "20221115") 100 20 Empty))
, (Just (AccTxn (toDate "20221215") 80 (negate 10) Empty))
, (Just (AccTxn (toDate "20221115") 100 20 Empty))
] $
[(getTxnAsOf testTxns (toDate "20221115"))
,(getTxnAsOf testTxns (toDate "20221216"))
,(getTxnAsOf testTxns (toDate "20221120"))
]
,testCase "weight Average Balance ' " $
assertEqual "Weight Average Balacne '"
14.74 $
weightAvgBalance' (toDate "20221101") (toDate "20230101")
[BondTxn (toDate "20221115") 100 20 10 0.02 30 0 0 Nothing Empty
,BondTxn (toDate "20221215") 50 50 10 0.02 30 0 0 Nothing Empty]
,testCase "weight Average Balance 2 ' " $
assertEqual "Weight Average Balacne '"
12.03 $
weightAvgBalance' (toDate "20221110") (toDate "20230101")
[(BondTxn (toDate "20221115") 100 20 10 0.02 30 0 0 Nothing Empty)
,(BondTxn (toDate "20221215") 50 50 10 0.02 30 0 0 Nothing Empty)]
,testCase "weight Average Balance 3 ' " $
assertEqual "Weight Average Balacne '"
8.86 $
weightAvgBalance' (toDate "20220101") (toDate "20220201")
[(BondTxn (toDate "20220115") 100 20 10 0.02 30 0 0 Nothing Empty) ]
]

0 comments on commit 17f082e

Please sign in to comment.