Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

XIRR is laughably trivial with automatic differentiation in Haskell. Take as many iterations from the resulting [Double] as desired:

    type Cashflow = (Text, Day, Double)

    irr :: V.Vector Cashflow -> [Double]
    irr = fmap (flip findZero 0.01) npv
    
    npv :: V.Vector Cashflow -> (forall s. AD s ForwardDouble -> AD s ForwardDouble)
    npv cashflows = sum . flip discountedCashflows cashflows
      where
            discountedCashflows :: forall s. AD s ForwardDouble -> V.Vector Cashflow -> V.Vector (AD s ForwardDouble)
            discountedCashflows = fmap . presentValue

            presentValue :: forall s. AD s ForwardDouble -> Cashflow -> AD s ForwardDouble
            presentValue r (_,t,cf) = auto cf / ( (1 + r) ** numCompoundingPeriods t)

            numCompoundingPeriods t = (fromRational . toRational $ diffDays t t0) / 365.0

            t0 = maybe (toEnum 0) viewInvestmentDate $ cashflows V.!? 0

            viewInvestmentDate = view _2


Going to use "laughably trivial with automatic differentiation" as my new line to scare away PMs.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: