Skip to main content
added 254 characters in body; edited title
Source Link

A first Python for me. User defined XIRR function. Any comments?: exception handling

This is my first attempt at Python. I started with some code from https://github.com/peliot/XIRR-and-XNPV (which aims to mimic the Excel function XIRR) and tried to 'improve' on it (and the Excel version). But I would like to know if in these few lines I already made beginner's mistakes. I'm particularly interested to learn whether there is a more elegant way to handle the exceptions (an 'improvement' of mine), because this looks a bit clunky. (This is not the only change compare to the original, so the other bits may be not completely correct either.)

Note that the function newton itself may also give rise to an immediate exception.

import datetime
from scipy import optimize  

def xnpv(rate, cashflows):
    t0 = min(cashflows, key = lambda t: t[0])[0]
    return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in cashflows]) 

def xirr(cashflows,guess=0.1):
    try:
        outc = optimize.newton(lambda r: xnpv(r, cashflows), guess,maxiter=100) 
                               maxiter=100)
        if outc.imag == 0:
            return outc
        else:
            raise
    except (RuntimeError, OverflowError):
        try:
            outc = optimize.newton(lambda r: xnpv(r, cashflows), -guess, 
                                   maxiter=100)
            if outc.imag == 0:
                return outc
            else:
                raise
        except (RuntimeError, OverflowError):
            return float("NaN")
        
#cftest = [(datetime.date(2001, 12, 5), -2000), (datetime.date(2007, 12, 5), -10), (datetime.date(2017, 12, 5), 20)]
cftest = [(datetime.date(2001, 12, 5), -2000), (datetime.date(2000, 12, 5), -1000), (datetime.date(2017, 12, 5), 2000)]
#cftest = [(datetime.date(2001, 12, 5), -2000), (datetime.date(2007, 12, 5), -1000), (datetime.date(2017, 12, 5), 20)]
print(cftest)
print(xirr(cftest))

A first Python for me. XIRR function. Any comments?

This is my first attempt at Python. I started with some code from https://github.com/peliot/XIRR-and-XNPV and tried to 'improve' on it. But I would like to know if in these few lines I already made beginner's mistakes. I'm particularly interested to learn whether there is a more elegant way to handle the exceptions, because this looks a bit clunky.

Note that newton itself may also give rise to an immediate exception.

import datetime
from scipy import optimize 
def xnpv(rate,cashflows):
    t0 = min(cashflows, key = lambda t: t[0])[0]
    return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in cashflows])
def xirr(cashflows,guess=0.1):
    try:
        outc = optimize.newton(lambda r: xnpv(r,cashflows),guess,maxiter=100)
        
        if outc.imag == 0:
            return outc
        else:
            raise
    except:
        try:
            outc = optimize.newton(lambda r: xnpv(r,cashflows),-guess,maxiter=100)
            if outc.imag == 0:
                return outc
            else:
                raise
        except:
            return float("NaN")
#cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2007, 12, 5),-10),(datetime.date(2017, 12, 5),20)]
cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2000, 12, 5),-1000),(datetime.date(2017, 12, 5),2000)]
#cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2007, 12, 5),-1000),(datetime.date(2017, 12, 5),20)]
print(cftest)
print(xirr(cftest))

User defined XIRR function: exception handling

This is my first attempt at Python. I started with some code from https://github.com/peliot/XIRR-and-XNPV (which aims to mimic the Excel function XIRR) and tried to 'improve' on it (and the Excel version). But I would like to know if in these few lines I already made beginner's mistakes. I'm particularly interested to learn whether there is a more elegant way to handle the exceptions (an 'improvement' of mine), because this looks a bit clunky. (This is not the only change compare to the original, so the other bits may be not completely correct either.)

Note that the function newton itself may also give rise to an immediate exception.

import datetime
from scipy import optimize 

def xnpv(rate, cashflows):
    t0 = min(cashflows, key = lambda t: t[0])[0]
    return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in cashflows]) 

def xirr(cashflows,guess=0.1):
    try:
        outc = optimize.newton(lambda r: xnpv(r, cashflows), guess, 
                               maxiter=100)
        if outc.imag == 0:
            return outc
        else:
            raise
    except (RuntimeError, OverflowError):
        try:
            outc = optimize.newton(lambda r: xnpv(r, cashflows), -guess, 
                                   maxiter=100)
            if outc.imag == 0:
                return outc
            else:
                raise
        except (RuntimeError, OverflowError):
            return float("NaN")
        
#cftest = [(datetime.date(2001, 12, 5), -2000), (datetime.date(2007, 12, 5), -10), (datetime.date(2017, 12, 5), 20)]
cftest = [(datetime.date(2001, 12, 5), -2000), (datetime.date(2000, 12, 5), -1000), (datetime.date(2017, 12, 5), 2000)]
#cftest = [(datetime.date(2001, 12, 5), -2000), (datetime.date(2007, 12, 5), -1000), (datetime.date(2017, 12, 5), 20)]
print(cftest)
print(xirr(cftest))
added 73 characters in body
Source Link

This is my first attempt at Python. I started with some code from https://github.com/peliot/XIRR-and-XNPV and tried to 'improve' on it. But I would like to know if in these few lines I already made beginner's mistakes. I'm particularly interested to learn whether there is a more elegant way to handle the exceptions, because this looks a bit clunky.

Note that newton itself may also give rise to an immediate exception.

import datetime
from scipy import optimize 
def xnpv(rate,cashflows):
    t0 = min(cashflows, key = lambda t: t[0])[0]
    return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in cashflows])
def xirr(cashflows,guess=0.1):
    try:
        outc = optimize.newton(lambda r: xnpv(r,cashflows),guess,maxiter=100)
        
        if outc.imag == 0:
            return outc
        else:
            raise
    except:
        try:
            outc = optimize.newton(lambda r: xnpv(r,cashflows),-guess,maxiter=100)
            if outc.imag == 0:
                return outc
            else:
                raise
        except:
            return float("NaN")
#cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2007, 12, 5),-10),(datetime.date(2017, 12, 5),20)]
cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2000, 12, 5),-1000),(datetime.date(2017, 12, 5),2000)]
#cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2007, 12, 5),-1000),(datetime.date(2017, 12, 5),20)]
print(cftest)
print(xirr(cftest))

This is my first attempt at Python. I started with some code from https://github.com/peliot/XIRR-and-XNPV and tried to 'improve' on it. But I would like to know if in these few lines I already made beginner's mistakes. I'm particularly interested to learn whether there is a more elegant way to handle the exceptions, because this looks a bit clunky.

import datetime
from scipy import optimize 
def xnpv(rate,cashflows):
    t0 = min(cashflows, key = lambda t: t[0])[0]
    return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in cashflows])
def xirr(cashflows,guess=0.1):
    try:
        outc = optimize.newton(lambda r: xnpv(r,cashflows),guess,maxiter=100)
        
        if outc.imag == 0:
            return outc
        else:
            raise
    except:
        try:
            outc = optimize.newton(lambda r: xnpv(r,cashflows),-guess,maxiter=100)
            if outc.imag == 0:
                return outc
            else:
                raise
        except:
            return float("NaN")
#cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2007, 12, 5),-10),(datetime.date(2017, 12, 5),20)]
cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2000, 12, 5),-1000),(datetime.date(2017, 12, 5),2000)]
#cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2007, 12, 5),-1000),(datetime.date(2017, 12, 5),20)]
print(cftest)
print(xirr(cftest))

This is my first attempt at Python. I started with some code from https://github.com/peliot/XIRR-and-XNPV and tried to 'improve' on it. But I would like to know if in these few lines I already made beginner's mistakes. I'm particularly interested to learn whether there is a more elegant way to handle the exceptions, because this looks a bit clunky.

Note that newton itself may also give rise to an immediate exception.

import datetime
from scipy import optimize 
def xnpv(rate,cashflows):
    t0 = min(cashflows, key = lambda t: t[0])[0]
    return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in cashflows])
def xirr(cashflows,guess=0.1):
    try:
        outc = optimize.newton(lambda r: xnpv(r,cashflows),guess,maxiter=100)
        
        if outc.imag == 0:
            return outc
        else:
            raise
    except:
        try:
            outc = optimize.newton(lambda r: xnpv(r,cashflows),-guess,maxiter=100)
            if outc.imag == 0:
                return outc
            else:
                raise
        except:
            return float("NaN")
#cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2007, 12, 5),-10),(datetime.date(2017, 12, 5),20)]
cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2000, 12, 5),-1000),(datetime.date(2017, 12, 5),2000)]
#cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2007, 12, 5),-1000),(datetime.date(2017, 12, 5),20)]
print(cftest)
print(xirr(cftest))
Source Link

A first Python for me. XIRR function. Any comments?

This is my first attempt at Python. I started with some code from https://github.com/peliot/XIRR-and-XNPV and tried to 'improve' on it. But I would like to know if in these few lines I already made beginner's mistakes. I'm particularly interested to learn whether there is a more elegant way to handle the exceptions, because this looks a bit clunky.

import datetime
from scipy import optimize 
def xnpv(rate,cashflows):
    t0 = min(cashflows, key = lambda t: t[0])[0]
    return sum([cf/(1+rate)**((t-t0).days/365.0) for (t,cf) in cashflows])
def xirr(cashflows,guess=0.1):
    try:
        outc = optimize.newton(lambda r: xnpv(r,cashflows),guess,maxiter=100)
        
        if outc.imag == 0:
            return outc
        else:
            raise
    except:
        try:
            outc = optimize.newton(lambda r: xnpv(r,cashflows),-guess,maxiter=100)
            if outc.imag == 0:
                return outc
            else:
                raise
        except:
            return float("NaN")
#cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2007, 12, 5),-10),(datetime.date(2017, 12, 5),20)]
cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2000, 12, 5),-1000),(datetime.date(2017, 12, 5),2000)]
#cftest = [(datetime.date(2001, 12, 5),-2000),(datetime.date(2007, 12, 5),-1000),(datetime.date(2017, 12, 5),20)]
print(cftest)
print(xirr(cftest))