<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Investment Performance Software</title>
	<atom:link href="http://www.investingintelligently.com/2006/07/27/investment-performance-software/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.investingintelligently.com/2006/07/27/investment-performance-software/</link>
	<description>Not just another (Canadian) financial blog</description>
	<lastBuildDate>Sat, 16 Oct 2010 15:22:19 -0700</lastBuildDate>
	<generator>http://wordpress.org/?v=</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Dave</title>
		<link>http://www.investingintelligently.com/2006/07/27/investment-performance-software/comment-page-1/#comment-8533</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Fri, 01 Jan 2010 03:36:54 +0000</pubDate>
		<guid isPermaLink="false">http://www.investingintelligently.com/2006/07/27/investment-performance-software/#comment-8533</guid>
		<description>Carlos, here it is. It uses NumPy.

&lt;pre&gt;from __future__ import division
import unittest, csv, string, datetime
from numpy import floor, reshape, size, array, arange
from dateutil.relativedelta import relativedelta
import sys

def xirr(cash_flows, dates, yld=0.1, maxiter=50):
    &quot;&quot;&quot;
    @param cash_flows list of cashflows
    @param dates list of datetime.date objects
    @param yld guess for rate of return
    @param maxiter maximum iterations
    &quot;&quot;&quot;
    assert len(dates) == len(cash_flows)
    for date in dates:
        assert type(date) == datetime.date

    date_ordinals = array([x.toordinal() for x in dates])
    cash_flows = array(cash_flows)

    #number of years in cash flow FIXME: use max and min date, not first and last in list
    func = int(floor(yearfrac(dates[0], dates[-1])))
    if func == 0:
        func = 1
    #matlab: tf = func*(dates(:,loop)-dates(1,loop))/(datemnth(dates(1,loop),12*func,0,0)-dates(1,loop));
    tf = func*(date_ordinals - date_ordinals[0]) / (dates[0] + relativedelta(months = +12*func) - dates[0]).days

    # Determine the best guess for yld
    min_result = sys.maxint
    best_yld = None
    for yld in arange(-0.9, 1, 0.1):
        if yld == 0:
            continue
        result_f = abs(sum(cash_flows / ((1 + yld)**tf)))
        if result_f &lt; min_result:
            min_result = result_f
            best_yld = yld

    yld = best_yld
    print &quot;Using guess yld=&quot;, yld

    func = 2
    k = 1
    #Newton&#039;s Method
    while abs(func) &gt; 1.e-6:
        #cash flow polynomial
        func = sum(cash_flows / ((1 + yld)**tf))
        #%(CF poly)&#039;
        f_prime = -sum((cash_flows/((1 + yld)**tf)) * (tf/(1 +yld)))
        if f_prime == 0:
            yld = None
            break

        delta = -func/f_prime
        yld = yld + delta
        k += 1
        if k == maxiter + 1:
            print &#039;Number of maximum iterations reached.&#039;
            print &#039;Please increase MAXITER or use different GUESS.&#039;
            yld = None
            break
    return yld

def yearfrac(date1, date2):
    wYears = int(floor(abs((date1 - date2).days) / 365.))
    date1W = datetime.date(date1.year + wYears, date1.month, date1.day)
    numerator = (date1W - date2).days
    try:
        denominator = (date1W - datetime.date(date1W.year + 1, date1W.month, date1W.day)).days
    #-----handle weird leap year case
    except ValueError:
        date1W = date1W + datetime.timedelta(1)
        denominator = (date1W - datetime.date(date1W.year + 1, date1W.month, date1W.day)).days
    yearFraction = numerator / float(denominator)
    return yearFraction + wYears&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Carlos, here it is. It uses NumPy.</p>
<pre>from __future__ import division
import unittest, csv, string, datetime
from numpy import floor, reshape, size, array, arange
from dateutil.relativedelta import relativedelta
import sys

def xirr(cash_flows, dates, yld=0.1, maxiter=50):
    """
    @param cash_flows list of cashflows
    @param dates list of datetime.date objects
    @param yld guess for rate of return
    @param maxiter maximum iterations
    """
    assert len(dates) == len(cash_flows)
    for date in dates:
        assert type(date) == datetime.date

    date_ordinals = array([x.toordinal() for x in dates])
    cash_flows = array(cash_flows)

    #number of years in cash flow FIXME: use max and min date, not first and last in list
    func = int(floor(yearfrac(dates[0], dates[-1])))
    if func == 0:
        func = 1
    #matlab: tf = func*(dates(:,loop)-dates(1,loop))/(datemnth(dates(1,loop),12*func,0,0)-dates(1,loop));
    tf = func*(date_ordinals - date_ordinals[0]) / (dates[0] + relativedelta(months = +12*func) - dates[0]).days

    # Determine the best guess for yld
    min_result = sys.maxint
    best_yld = None
    for yld in arange(-0.9, 1, 0.1):
        if yld == 0:
            continue
        result_f = abs(sum(cash_flows / ((1 + yld)**tf)))
        if result_f < min_result:
            min_result = result_f
            best_yld = yld

    yld = best_yld
    print "Using guess yld=", yld

    func = 2
    k = 1
    #Newton's Method
    while abs(func) > 1.e-6:
        #cash flow polynomial
        func = sum(cash_flows / ((1 + yld)**tf))
        #%(CF poly)'
        f_prime = -sum((cash_flows/((1 + yld)**tf)) * (tf/(1 +yld)))
        if f_prime == 0:
            yld = None
            break

        delta = -func/f_prime
        yld = yld + delta
        k += 1
        if k == maxiter + 1:
            print 'Number of maximum iterations reached.'
            print 'Please increase MAXITER or use different GUESS.'
            yld = None
            break
    return yld

def yearfrac(date1, date2):
    wYears = int(floor(abs((date1 - date2).days) / 365.))
    date1W = datetime.date(date1.year + wYears, date1.month, date1.day)
    numerator = (date1W - date2).days
    try:
        denominator = (date1W - datetime.date(date1W.year + 1, date1W.month, date1W.day)).days
    #-----handle weird leap year case
    except ValueError:
        date1W = date1W + datetime.timedelta(1)
        denominator = (date1W - datetime.date(date1W.year + 1, date1W.month, date1W.day)).days
    yearFraction = numerator / float(denominator)
    return yearFraction + wYears</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Carlos</title>
		<link>http://www.investingintelligently.com/2006/07/27/investment-performance-software/comment-page-1/#comment-8324</link>
		<dc:creator>Carlos</dc:creator>
		<pubDate>Wed, 29 Apr 2009 22:21:05 +0000</pubDate>
		<guid isPermaLink="false">http://www.investingintelligently.com/2006/07/27/investment-performance-software/#comment-8324</guid>
		<description>Dave: did you ever publish your XIRR function in Python?  Would love to have a look at it.  I&#039;m looking for an XIRR function in Python and all I have found is NumPy, but it looks like a PIA to install on my machine.

-Carlos</description>
		<content:encoded><![CDATA[<p>Dave: did you ever publish your XIRR function in Python?  Would love to have a look at it.  I&#8217;m looking for an XIRR function in Python and all I have found is NumPy, but it looks like a PIA to install on my machine.</p>
<p>-Carlos</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://www.investingintelligently.com/2006/07/27/investment-performance-software/comment-page-1/#comment-1263</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Wed, 16 Aug 2006 06:23:13 +0000</pubDate>
		<guid isPermaLink="false">http://www.investingintelligently.com/2006/07/27/investment-performance-software/#comment-1263</guid>
		<description>ralph: I am also using this type of &quot;black box&quot; method as you call it with the return being the only unknown. I basically use the XIRR function in Excel. I have now written this function in Python and it works and I will use that to calculate returns on an investment-by-investment basis as well as for the whole account.

I don&#039;t understand the problem you described whereby &quot;you’ve been investing for ten years but have built up the investment by adding to it each year, you could have the same average annualised return if the early years were excellent and the latter years poor, or vice versa.&quot;

Maybe the XIRR function solves the problem you describe (I think it does).

&lt;a href=&quot;http://www.gummy-stuff.org/XIRR-stuff.htm&quot; rel=&quot;nofollow&quot; rel=&quot;nofollow&quot;&gt;XIRR&lt;/a&gt;

&lt;a href=&quot;http://www.gummy-stuff.org/xirr.htm&quot; rel=&quot;nofollow&quot;&gt;More on XIRR&lt;/a&gt;

Anyways, yes I&#039;m doing this for fun. :-)</description>
		<content:encoded><![CDATA[<p>ralph: I am also using this type of &#8220;black box&#8221; method as you call it with the return being the only unknown. I basically use the XIRR function in Excel. I have now written this function in Python and it works and I will use that to calculate returns on an investment-by-investment basis as well as for the whole account.</p>
<p>I don&#8217;t understand the problem you described whereby &#8220;you’ve been investing for ten years but have built up the investment by adding to it each year, you could have the same average annualised return if the early years were excellent and the latter years poor, or vice versa.&#8221;</p>
<p>Maybe the XIRR function solves the problem you describe (I think it does).</p>
<p><a href="http://www.gummy-stuff.org/XIRR-stuff.htm" rel="nofollow" rel="nofollow">XIRR</a></p>
<p><a href="http://www.gummy-stuff.org/xirr.htm" rel="nofollow">More on XIRR</a></p>
<p>Anyways, yes I&#8217;m doing this for fun. <img src='http://www.investingintelligently.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
	<item>
		<title>By: ralph</title>
		<link>http://www.investingintelligently.com/2006/07/27/investment-performance-software/comment-page-1/#comment-1226</link>
		<dc:creator>ralph</dc:creator>
		<pubDate>Mon, 14 Aug 2006 13:31:28 +0000</pubDate>
		<guid isPermaLink="false">http://www.investingintelligently.com/2006/07/27/investment-performance-software/#comment-1226</guid>
		<description>I hope you are doing this for the fun of it! It&#039;s certainly not free (what&#039;s your hourly rate worth?)

I picked up a copy of Quicken 2006 for free (stuck on the front of a $6 investment magazine).

ps. Even Quicken doesn&#039;t calculate annualised returns perfectly. It gets very messy when you are adding to or selling part of an existing position - you have to track individual lots. You also can&#039;t just use arithmetic averaging of returns.

I think the easiest method to follow is to just pretend your portfolio is a big &#039;black box&#039;, and record all dollar amounts in and out and then iteratively calculate what annual rate of return applied to the model results in the same ending value as your real portfolio. However, unless you have kept a fairly constant amount invested over the total period, this figure is pretty meaningless. eg. If you&#039;ve been investing for ten years but have built up the investment by adding to it each year, you could have the same average annualised return if the early years were excellent and the latter years poor, or vice versa. But althought the average annualised returns are the same the end result is different! To adjust for this you&#039;d have to WEIGHT the return calculation based on the amount you had invested at any time... It all gets way too hard to be of use. You&#039;re better off concentrating on saving more in the early years, and minimising transaction and management costs once you have a reasonable amount invested (say &gt; 5x your annual salary).</description>
		<content:encoded><![CDATA[<p>I hope you are doing this for the fun of it! It&#8217;s certainly not free (what&#8217;s your hourly rate worth?)</p>
<p>I picked up a copy of Quicken 2006 for free (stuck on the front of a $6 investment magazine).</p>
<p>ps. Even Quicken doesn&#8217;t calculate annualised returns perfectly. It gets very messy when you are adding to or selling part of an existing position &#8211; you have to track individual lots. You also can&#8217;t just use arithmetic averaging of returns.</p>
<p>I think the easiest method to follow is to just pretend your portfolio is a big &#8216;black box&#8217;, and record all dollar amounts in and out and then iteratively calculate what annual rate of return applied to the model results in the same ending value as your real portfolio. However, unless you have kept a fairly constant amount invested over the total period, this figure is pretty meaningless. eg. If you&#8217;ve been investing for ten years but have built up the investment by adding to it each year, you could have the same average annualised return if the early years were excellent and the latter years poor, or vice versa. But althought the average annualised returns are the same the end result is different! To adjust for this you&#8217;d have to WEIGHT the return calculation based on the amount you had invested at any time&#8230; It all gets way too hard to be of use. You&#8217;re better off concentrating on saving more in the early years, and minimising transaction and management costs once you have a reasonable amount invested (say &gt; 5x your annual salary).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://www.investingintelligently.com/2006/07/27/investment-performance-software/comment-page-1/#comment-959</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Sat, 29 Jul 2006 20:30:07 +0000</pubDate>
		<guid isPermaLink="false">http://www.investingintelligently.com/2006/07/27/investment-performance-software/#comment-959</guid>
		<description>Yeah, Perl was pretty common to do things quickly back in the day (well it&#039;s still the quickest for anything to do with string processing AFAIK) but nowadays Python is gaining in popularity over Perl.</description>
		<content:encoded><![CDATA[<p>Yeah, Perl was pretty common to do things quickly back in the day (well it&#8217;s still the quickest for anything to do with string processing AFAIK) but nowadays Python is gaining in popularity over Perl.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kevin</title>
		<link>http://www.investingintelligently.com/2006/07/27/investment-performance-software/comment-page-1/#comment-958</link>
		<dc:creator>Kevin</dc:creator>
		<pubDate>Sat, 29 Jul 2006 20:25:29 +0000</pubDate>
		<guid isPermaLink="false">http://www.investingintelligently.com/2006/07/27/investment-performance-software/#comment-958</guid>
		<description>Python eh? I used to do a lot in Perl, mostly in Unix. Look foward to seeing what you can come up with!</description>
		<content:encoded><![CDATA[<p>Python eh? I used to do a lot in Perl, mostly in Unix. Look foward to seeing what you can come up with!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://www.investingintelligently.com/2006/07/27/investment-performance-software/comment-page-1/#comment-957</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Sat, 29 Jul 2006 18:48:47 +0000</pubDate>
		<guid isPermaLink="false">http://www.investingintelligently.com/2006/07/27/investment-performance-software/#comment-957</guid>
		<description>I&#039;m using Python because it is one of the fastest languages to code in. I might put this project up on sourceforge or on the new google code site once I get something working.</description>
		<content:encoded><![CDATA[<p>I&#8217;m using Python because it is one of the fastest languages to code in. I might put this project up on sourceforge or on the new google code site once I get something working.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kevin</title>
		<link>http://www.investingintelligently.com/2006/07/27/investment-performance-software/comment-page-1/#comment-954</link>
		<dc:creator>Kevin</dc:creator>
		<pubDate>Fri, 28 Jul 2006 22:44:17 +0000</pubDate>
		<guid isPermaLink="false">http://www.investingintelligently.com/2006/07/27/investment-performance-software/#comment-954</guid>
		<description>I think this is really interesting. I used to be a software developer before the big tech crash and love to use my knowledge to help me in my investments and tracking of them. What are you using to develop this?</description>
		<content:encoded><![CDATA[<p>I think this is really interesting. I used to be a software developer before the big tech crash and love to use my knowledge to help me in my investments and tracking of them. What are you using to develop this?</p>
]]></content:encoded>
	</item>
</channel>
</rss>

