yellowbean / Hastructure

ABS/MBS cashflow engine written in Haskell, with API to Python and C/Java (on the way)
https://deal-bench.xyz
Other
16 stars 4 forks source link

Build Deal with support of mixed assets in pool #91

Closed yellowbean closed 10 months ago

yellowbean commented 1 year ago

Building mixed pool with different asset type.

Propose solution

yellowbean commented 1 year ago

Actually ,there is an alternative ,with AssetUnion which will contain all the assets available.

The tricky part is ,a mortgage asset will return MortgageFlow object while a lease will return a LeanseFlow which has different fields .

If there are multiple pools in a deal ,each pool has only one type of asset, then how to aggregate up some stats ?

how to calculate the prepayment rate? is the denominator using sum of all pool balances or just using single pool balance ?

yellowbean commented 1 year ago

https://github.com/yellowbean/Hastructure/blob/e6ea64aa8e0ccbc1d8feb05840e301e89add870a/src/Deal/DealBase.hs#L48

The TestDeal a was heavily used almost everywhere in the code base.

a is a Asset type class. https://github.com/yellowbean/Hastructure/blob/e6ea64aa8e0ccbc1d8feb05840e301e89add870a/src/Asset.hs#L49C17-L49C23

the a represent asset type like Mortgage, Loan, which means, a Deal has a pool ( a list of ) Mortgage or a list of Loan A deal can only has one type of asset in the pool.

data TestDeal a = TestDeal {         <-- "a" is a type variable
  name :: String
  ,status :: DealStatus
  ,dates :: DateDesp
  ,accounts :: Map.Map AccountName A.Account
  ,fees :: Map.Map FeeName F.Fee
  ,bonds :: Map.Map BondName L.Bond
  ,pool ::  P.Pool a           <-- "a" passed into `Pool`, and eventually become a list inside of pool

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
                   ,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
                   }deriving (Show,Generic)

It works well so far, but faces difficulties , how to make TestDeal a support multiple assets in the pool ?

proposed in change of TestDeal like this

data TestDeal a = TestDeal {         <-- "a" is a type variable
  name :: String
  ,status :: DealStatus
  ,dates :: DateDesp
  ,accounts :: Map.Map AccountName A.Account
  ,fees :: Map.Map FeeName F.Fee
  ,bonds :: Map.Map BondName L.Bond
  ,pool ::  Map.Map String (P.Pool a)       <--- make a pool become a map , with `values` to hold pools with different asset type

like:

But it won't work as the a in TestDeal a says all the types of a are same. if passing 3 type variables, then the TestDeal only accept 3 asset types ,it's not scalable.

data TestDeal a b c = TestDeal {         <-- "a" is a type variable
 .....
  ,pool :: ......

Any suggestions ?

yellowbean commented 12 months ago

Option 1 : Use AssetUnion as asset type to fit into Pool Option 2 : Use ExtentialType as asset type to fit into Pool https://wiki.haskell.org/Existential_type

yellowbean commented 11 months ago

Now go with option 1

yellowbean commented 10 months ago

cee3658